Compare commits
1 Commits
main
...
extension-
Author | SHA1 | Date |
---|---|---|
Behdad Esfahbod | 8eb8494e8d |
|
@ -1,21 +1,8 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
meson --cross-file=.ci/win32-cross-file.txt \
|
||||
--wrap-mode=default \
|
||||
-Dtests=disabled \
|
||||
-Dcairo=enabled \
|
||||
-Dcairo:fontconfig=disabled \
|
||||
-Dcairo:freetype=disabled \
|
||||
-Dcairo:dwrite=disabled \
|
||||
-Dcairo:tests=disabled \
|
||||
-Dglib=enabled \
|
||||
-Dfreetype=disabled \
|
||||
-Dgdi=enabled \
|
||||
-Ddirectwrite=enabled \
|
||||
win32build \
|
||||
$@
|
||||
|
||||
meson --cross-file=.ci/win32-cross-file.txt win32build --wrap-mode=forcefallback -Dtests=disabled \
|
||||
-Dglib=enabled -Dfreetype=enabled -Dgdi=enabled -Dcairo=enabled --buildtype=release $@
|
||||
ninja -Cwin32build -j3 # building with all the cores won't work fine with CricleCI for some reason
|
||||
|
||||
rm -rf win32build/harfbuzz-win32
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
meson --cross-file=.ci/win64-cross-file.txt \
|
||||
--wrap-mode=default \
|
||||
-Dtests=disabled \
|
||||
-Dcairo=enabled \
|
||||
-Dcairo:fontconfig=disabled \
|
||||
-Dcairo:freetype=disabled \
|
||||
-Dcairo:dwrite=disabled \
|
||||
-Dcairo:tests=disabled \
|
||||
-Dglib=enabled \
|
||||
-Dfreetype=disabled \
|
||||
-Dgdi=enabled \
|
||||
-Ddirectwrite=enabled \
|
||||
win64build \
|
||||
$@
|
||||
|
||||
ninja -Cwin64build -j3 # building with all the cores won't work fine with CricleCI for some reason
|
||||
|
||||
rm -rf win64build/harfbuzz-win64
|
||||
mkdir win64build/harfbuzz-win64
|
||||
cp win64build/util/hb-*.exe win64build/harfbuzz-win64
|
||||
find win64build -name '*.dll' -exec cp {} win64build/harfbuzz-win64 \;
|
||||
x86_64-w64-mingw32-strip win64build/harfbuzz-win64/*.{dll,exe}
|
||||
rm -f harfbuzz-win64.zip
|
||||
(cd win64build && zip -r ../harfbuzz-win64.zip harfbuzz-win64)
|
||||
echo "harfbuzz-win64.zip is ready."
|
|
@ -3,6 +3,8 @@
|
|||
set -x
|
||||
set -o errexit -o nounset
|
||||
|
||||
TAG="$(git describe --exact-match --match "[0-9]*" HEAD 2>/dev/null || true)"
|
||||
|
||||
DOCSDIR=build-docs
|
||||
REVISION=$(git rev-parse --short HEAD)
|
||||
|
||||
|
@ -14,20 +16,19 @@ cp ../build/docs/html/* .
|
|||
#cp ../build/docs/CNAME .
|
||||
|
||||
git init
|
||||
git branch -m main
|
||||
git config user.name "CI"
|
||||
git config user.email "harfbuzz-admin@googlegroups.com"
|
||||
git config user.name "Travis CI"
|
||||
git config user.email "travis@harfbuzz.org"
|
||||
set +x
|
||||
echo "git remote add upstream \"https://\$GH_TOKEN@github.com/harfbuzz/harfbuzz.github.io.git\""
|
||||
git remote add upstream "https://$GH_TOKEN@github.com/harfbuzz/harfbuzz.github.io.git"
|
||||
set -x
|
||||
git fetch upstream
|
||||
git reset upstream/main
|
||||
git reset upstream/master
|
||||
|
||||
touch .
|
||||
git add -A .
|
||||
|
||||
if [[ $(git status -s) ]]; then
|
||||
git commit -m "Rebuild docs for https://github.com/harfbuzz/harfbuzz/commit/$REVISION"
|
||||
git push -q upstream HEAD:main
|
||||
git push -q upstream HEAD:master
|
||||
fi
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
|
||||
|
@ -8,13 +7,11 @@ if [[ -z $GITHUB_TOKEN ]]; then
|
|||
exit
|
||||
fi
|
||||
|
||||
if ! hash ghr 2> /dev/null; then
|
||||
_GHR_VER=v0.14.0
|
||||
_GHR=ghr_${_GHR_VER}_linux_amd64
|
||||
mkdir -p $HOME/.local/bin
|
||||
curl -sfL https://github.com/tcnksm/ghr/releases/download/$_GHR_VER/$_GHR.tar.gz |
|
||||
tar xz -C $HOME/.local/bin --strip-components=1 $_GHR/ghr
|
||||
fi
|
||||
mkdir -p $HOME/.local/bin
|
||||
export _GHR_VER=v0.13.0
|
||||
export _GHR=ghr_${_GHR_VER}_linux_amd64
|
||||
curl -sfL https://github.com/tcnksm/ghr/releases/download/$_GHR_VER/$_GHR.tar.gz |
|
||||
tar xz -C $HOME/.local/bin --strip-components=1 $_GHR/ghr
|
||||
|
||||
ghr -replace \
|
||||
-u $CIRCLE_PROJECT_USERNAME \
|
||||
|
|
|
@ -4,23 +4,46 @@ executors:
|
|||
win32-executor:
|
||||
docker:
|
||||
- image: cimg/base:edge-20.04
|
||||
win64-executor:
|
||||
docker:
|
||||
- image: cimg/base:edge-20.04
|
||||
autotools-executor:
|
||||
docker:
|
||||
- image: cimg/base:edge-20.04
|
||||
|
||||
jobs:
|
||||
|
||||
macos-aat-fonts:
|
||||
macos-10_13_6-aat-fonts:
|
||||
macos:
|
||||
xcode: "12.5.1"
|
||||
xcode: "10.1.0"
|
||||
steps:
|
||||
- checkout
|
||||
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 icu4c graphite2 gobject-introspection ninja
|
||||
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 ninja
|
||||
- run: pip3 install meson --upgrade
|
||||
- run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson setup build -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled -Dchafa=disabled -Ddocs=disabled
|
||||
- run: meson build
|
||||
- run: meson compile -Cbuild
|
||||
- run: meson test -Cbuild --print-errorlogs
|
||||
- store_artifacts:
|
||||
path: build/meson-logs/
|
||||
|
||||
macos-10_14_4-aat-fonts:
|
||||
macos:
|
||||
xcode: "11.1.0"
|
||||
steps:
|
||||
- checkout
|
||||
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 icu4c graphite2 ninja
|
||||
- run: pip3 install meson --upgrade
|
||||
- run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson build -Dcoretext=enabled
|
||||
- run: meson compile -Cbuild
|
||||
- run: meson test -Cbuild --print-errorlogs
|
||||
- store_artifacts:
|
||||
path: build/meson-logs/
|
||||
|
||||
macos-10_15_3-aat-fonts:
|
||||
macos:
|
||||
xcode: "11.4.0"
|
||||
steps:
|
||||
- checkout
|
||||
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config ragel freetype glib cairo python3 icu4c graphite2 gobject-introspection gtk-doc ninja
|
||||
- run: pip3 install meson --upgrade
|
||||
- run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson build -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled
|
||||
- run: meson compile -Cbuild
|
||||
- run: meson test -Cbuild --print-errorlogs
|
||||
- store_artifacts:
|
||||
|
@ -31,12 +54,14 @@ jobs:
|
|||
executor: autotools-executor
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y git ninja-build binutils libtool autoconf automake make gcc g++ pkg-config ragel gtk-doc-tools gobject-introspection libfreetype6-dev libglib2.0-dev libgirepository1.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip
|
||||
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y git ninja-build binutils libtool autoconf automake make gcc g++ pkg-config ragel gtk-doc-tools gobject-introspection libfontconfig1-dev libfreetype6-dev libglib2.0-dev libgirepository1.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip cmake
|
||||
- run: pip3 install fonttools meson --upgrade
|
||||
- run: ./autogen.sh
|
||||
- run: make -j2 distcheck
|
||||
- run: make -j32
|
||||
- run: make distcheck
|
||||
- run: rm harfbuzz-* && make distdir
|
||||
- run: cd harfbuzz-* && meson build && ninja -j2 -Cbuild test
|
||||
- run: cd harfbuzz-* && meson build && ninja -Cbuild test
|
||||
- run: cd harfbuzz-* && cmake -Bcmakebuild -H. && cmake --build cmakebuild
|
||||
- run: make dist
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
|
@ -53,14 +78,14 @@ jobs:
|
|||
|
||||
fedora-valgrind:
|
||||
docker:
|
||||
- image: fedora:36
|
||||
- image: fedora
|
||||
steps:
|
||||
- checkout
|
||||
- run: dnf install -y pkg-config ragel valgrind gcc gcc-c++ meson git glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python python-pip || true
|
||||
- run: meson setup build --buildtype=debugoptimized
|
||||
- run: meson compile -Cbuild -j9
|
||||
- run: meson build --buildtype=debugoptimized
|
||||
- run: ninja -Cbuild -j9
|
||||
# TOOD: increase timeouts and remove --no-suite=slow
|
||||
- run: RUN_VALGRIND=1 meson test -Cbuild --no-suite=slow --wrap='valgrind --leak-check=full --error-exitcode=1' --print-errorlogs --num-processes=$(($(nproc)/2 + 1))
|
||||
- run: RUN_VALGRIND=1 meson test -Cbuild --no-suite=slow --wrap='valgrind --leak-check=full --error-exitcode=1' --print-errorlogs
|
||||
|
||||
alpine:
|
||||
docker:
|
||||
|
@ -68,63 +93,56 @@ jobs:
|
|||
steps:
|
||||
- checkout
|
||||
- run: apk update && apk add ragel gcc g++ glib-dev freetype-dev cairo-dev git py3-pip ninja
|
||||
- run: pip3 install meson==0.56.0
|
||||
- run: meson setup build --buildtype=minsize
|
||||
- run: meson compile -Cbuild -j9
|
||||
- run: pip3 install meson==0.47.0
|
||||
- run: meson build --buildtype=minsize
|
||||
- run: ninja -Cbuild -j9
|
||||
- run: meson test -Cbuild --print-errorlogs
|
||||
|
||||
asan-ubsan:
|
||||
archlinux:
|
||||
docker:
|
||||
- image: ubuntu:20.04
|
||||
- image: archlinux/base
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
|
||||
- run: pip3 install meson==0.56.0
|
||||
- run: CC=clang CXX=clang++ meson setup build --default-library=static -Db_sanitize=address,undefined --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true
|
||||
- run: pacman --noconfirm -Syu freetype2 meson git clang cairo icu gettext gobject-introspection gcc gcc-libs glib2 graphite pkg-config ragel python python-pip base-devel gtk-doc
|
||||
- run: pip install flake8 fonttools
|
||||
- run: flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
|
||||
- run: meson build -Dgraphite=enabled -Dauto_features=enabled -Dexperimental_api=true
|
||||
- run: meson compile -Cbuild -j9
|
||||
- run: meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
|
||||
- run: meson test -Cbuild --print-errorlogs
|
||||
- run: meson dist -Cbuild
|
||||
- run: clang -c src/harfbuzz.cc -DHB_NO_MT
|
||||
- run: clang -c src/hb-*.cc -DHB_NO_MT -DHB_TINY -DHB_NO_OT_FONT
|
||||
|
||||
tsan:
|
||||
sanitizers:
|
||||
docker:
|
||||
- image: ubuntu:20.04
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
|
||||
- run: pip3 install meson==0.56.0
|
||||
- run: CC=clang CXX=clang++ meson setup build --default-library=static -Db_sanitize=thread --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true
|
||||
- run: meson compile -Cbuild -j9
|
||||
- run: meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
|
||||
|
||||
msan:
|
||||
docker:
|
||||
- image: ubuntu:20.04
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y python3 python3-pip ninja-build clang lld git binutils pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
|
||||
- run: pip3 install meson==0.56.0
|
||||
- run: apt update || true; DEBIAN_FRONTEND=noninteractive apt install -y wget gnupg
|
||||
#- run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
#- run: echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal main" > /etc/apt/sources.list.d/llvmdev.list
|
||||
#- run: echo "deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal main" > /etc/apt/sources.list.d/llvmdevsrc.list
|
||||
#- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y clang lld git binutils meson pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev
|
||||
# asan+ubsan
|
||||
- run: rm -rf build && meson build --default-library=static -Db_sanitize=address,undefined --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true
|
||||
- run: ninja -Cbuild -j8 && meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
|
||||
# tsan
|
||||
- run: rm -rf build && meson build --default-library=static -Db_sanitize=thread --buildtype=debugoptimized --wrap-mode=nodownload -Dexperimental_api=true
|
||||
- run: ninja -Cbuild -j8 && meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
|
||||
# msan, needs --force-fallback-for=glib,freetype2 also which doesn't work yet but runs fuzzer cases at least
|
||||
- run: CC=clang CXX=clang++ meson setup build --default-library=static -Db_sanitize=memory --buildtype=debugoptimized --wrap-mode=nodownload -Dauto_features=disabled -Dtests=enabled -Dexperimental_api=true
|
||||
- run: meson compile -Cbuild -j9
|
||||
- run: meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
|
||||
|
||||
clang-cxx2a:
|
||||
docker:
|
||||
- image: ubuntu:20.04
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true
|
||||
- run: DEBIAN_FRONTEND=noninteractive apt install -y clang lld git binutils
|
||||
- run: clang -c src/harfbuzz-subset.cc -DHB_NO_MT -Werror -std=c++2a
|
||||
- run: rm -rf build && meson build --default-library=static -Db_sanitize=memory --buildtype=debugoptimized --wrap-mode=nodownload -Dauto_features=disabled -Dtests=enabled -Dexperimental_api=true
|
||||
- run: ninja -Cbuild -j8 && meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
|
||||
# test -std=c++2a and -Weverything of nightly clang builds
|
||||
- run: clang -c src/harfbuzz.cc src/hb-subset*.cc -DHB_NO_MT -Werror -std=c++2a
|
||||
- run: clang -c src/hb-*.cc -DHB_NO_MT -Werror -Weverything -Wno-old-style-cast -Wno-documentation -Wno-documentation-unknown-command -Wno-c++98-compat -Wno-cast-qual -Wno-c++98-compat-pedantic -Wno-sign-conversion -Wno-padded -Wno-shorten-64-to-32 -Wno-reserved-id-macro -Wno-float-conversion -Wno-format-pedantic -Wno-shadow -Wno-conversion -Wno-zero-as-null-pointer-constant -Wno-missing-field-initializers -Wno-used-but-marked-unused -Wno-unused-macros -Wno-comma -Wno-float-equal -Wno-disabled-macro-expansion -Wno-weak-vtables -Wno-unused-parameter -Wno-covered-switch-default -Wno-unreachable-code -Wno-unused-template -DHB_WITH_WIN1256
|
||||
|
||||
crossbuild-win32:
|
||||
executor: win32-executor
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build python3 python3-pip git g++-mingw-w64-i686 zip
|
||||
- run: pip3 install meson==0.60.0
|
||||
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build binutils gcc g++ pkg-config ragel gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-pip git g++-mingw-w64-i686 zip
|
||||
- run: pip3 install meson==0.56.0 --upgrade
|
||||
- run: .ci/build-win32.sh
|
||||
- store_artifacts:
|
||||
path: harfbuzz-win32.zip
|
||||
|
@ -142,40 +160,18 @@ jobs:
|
|||
mv harfbuzz-win32{,-$CIRCLE_TAG}.zip
|
||||
.ci/publish_release_artifact.sh harfbuzz-win32-$CIRCLE_TAG.zip
|
||||
|
||||
crossbuild-win64:
|
||||
executor: win64-executor
|
||||
steps:
|
||||
- checkout
|
||||
- run: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build python3 python3-pip git g++-mingw-w64-x86-64 zip
|
||||
- run: pip3 install meson==0.60.0
|
||||
- run: bash .ci/build-win64.sh
|
||||
- store_artifacts:
|
||||
path: harfbuzz-win64.zip
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths: harfbuzz-win64.zip
|
||||
|
||||
publish-win64:
|
||||
executor: win64-executor
|
||||
steps:
|
||||
- checkout
|
||||
- attach_workspace:
|
||||
at: .
|
||||
- run: |
|
||||
mv harfbuzz-win64{,-$CIRCLE_TAG}.zip
|
||||
.ci/publish_release_artifact.sh harfbuzz-win64-$CIRCLE_TAG.zip
|
||||
|
||||
|
||||
workflows:
|
||||
version: 2
|
||||
|
||||
build:
|
||||
jobs:
|
||||
- macos-aat-fonts
|
||||
- distcheck:
|
||||
filters: # must have filter or won't work as a dependency
|
||||
- macos-10_13_6-aat-fonts
|
||||
- macos-10_14_4-aat-fonts
|
||||
- macos-10_15_3-aat-fonts
|
||||
- distcheck: # will be dropped with autotools removal
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
only: /^\d+.\d+.\d+$/
|
||||
- publish-dist:
|
||||
requires:
|
||||
- distcheck
|
||||
|
@ -186,18 +182,12 @@ workflows:
|
|||
ignore: /.*/
|
||||
- fedora-valgrind
|
||||
- alpine
|
||||
- asan-ubsan
|
||||
- tsan
|
||||
- msan
|
||||
- clang-cxx2a
|
||||
#- archlinux
|
||||
- sanitizers
|
||||
- crossbuild-win32:
|
||||
filters: # must have filter or won't work as a dependency
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
- crossbuild-win64:
|
||||
filters: # must have filter or won't work as a dependency
|
||||
tags:
|
||||
only: /.*/
|
||||
only: /^\d+.\d+.\d+$/
|
||||
- publish-win32:
|
||||
requires:
|
||||
- crossbuild-win32
|
||||
|
@ -206,11 +196,3 @@ workflows:
|
|||
only: /^\d+\.\d+\.\d+$/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
- publish-win64:
|
||||
requires:
|
||||
- crossbuild-win64
|
||||
filters:
|
||||
tags:
|
||||
only: /^\d+\.\d+\.\d+$/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
comment: false
|
||||
comment: off
|
||||
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
patch:
|
||||
default:
|
||||
informational: true
|
||||
threshold: 1%
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
|
@ -1,25 +0,0 @@
|
|||
name: arm
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
arm-none-eabi:
|
||||
runs-on: ubuntu-22.04
|
||||
container:
|
||||
image: devkitpro/devkitarm:latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Configure CMake
|
||||
run: |
|
||||
cmake -S . -B build \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${DEVKITPRO}/cmake/3DS.cmake
|
||||
- name: Build
|
||||
run: make CXX_FLAGS="-w -DHB_NO_MT"
|
||||
working-directory: build
|
|
@ -1,28 +0,0 @@
|
|||
name: CIFuzz
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
Fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Build Fuzzers
|
||||
id: build
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'harfbuzz'
|
||||
dry-run: false
|
||||
- name: Run Fuzzers
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'harfbuzz'
|
||||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v3
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out/artifacts
|
|
@ -1,27 +0,0 @@
|
|||
name: configs-ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: install dependencies
|
||||
run: sudo apt-get install gcc
|
||||
- name: HB_DISABLE_DEPRECATED
|
||||
run: g++ -std=c++11 -c src/harfbuzz.cc -DHB_DISABLE_DEPRECATED
|
||||
- name: HB_MINI
|
||||
run: g++ -std=c++11 -c src/harfbuzz.cc -DHB_MINI
|
||||
- name: HB_LEAN
|
||||
run: g++ -std=c++11 -c src/harfbuzz.cc -DHB_LEAN
|
||||
- name: HB_TINY
|
||||
run: g++ -std=c++11 -c src/harfbuzz.cc -DHB_TINY
|
|
@ -4,39 +4,36 @@ on:
|
|||
schedule:
|
||||
- cron: '0 10 * * *' # Daily at 10:00 UTC
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
latest:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- run: sudo apt-get install gcc clang wget git curl pkg-config libfreetype6-dev libglib2.0-dev libicu-dev libgraphite2-dev
|
||||
|
||||
- name: Download Coverity
|
||||
run: |
|
||||
wget -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=$TOKEN&project=HarfBuzz" -O cov-analysis-linux64.tar.gz
|
||||
wget -q https://scan.coverity.com/download/cxx/linux64 --post-data "token=$TOKEN&project=behdad/harfbuzz" -O cov-analysis-linux64.tar.gz
|
||||
mkdir cov-analysis-linux64
|
||||
tar xzf cov-analysis-linux64.tar.gz --strip 1 -C cov-analysis-linux64
|
||||
env:
|
||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||
|
||||
|
||||
# ideally we should've used meson and ninja here but it complains about coverage or something
|
||||
- run: cov-analysis-linux64/bin/cov-build --dir cov-int clang src/hb-*.cc -DHAVE_FREETYPE -DHAVE_GRAPHITE2 -DHAVE_GLIB -DHAVE_ICU `pkg-config --cflags freetype2 graphite2 glib-2.0 icu-uc` -DHAVE_ROUNDF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H -DHAVE_GETPAGESIZE -DHB_EXPERIMENTAL_API -c
|
||||
- run: cov-analysis-linux64/bin/cov-build --dir cov-int clang src/hb-*.cc -DHAVE_FREETYPE -DHAVE_GRAPHITE2 -DHAVE_GLIB -DHAVE_ICU `pkg-config --cflags freetype2 graphite2 glib-2.0 icu-uc` -DHAVE_INTEL_ATOMIC_PRIMITIVES -DHAVE_ROUNDF -DHAVE_SYS_MMAN_H -DHAVE_UNISTD_H -DHAVE_GETPAGESIZE -DHB_EXPERIMENTAL_API -c
|
||||
|
||||
- run: tar czvf harfbuzz.tgz cov-int
|
||||
|
||||
|
||||
- name: submit to coverity
|
||||
run: |
|
||||
curl \
|
||||
--form project=HarfBuzz \
|
||||
--form project=behdad/harfbuzz \
|
||||
--form token=$TOKEN \
|
||||
--form email=harfbuzz-bots-chatter@googlegroups.com \
|
||||
--form file=@harfbuzz.tgz \
|
||||
--form version=trunk \
|
||||
--form description="`git rev-parse --short HEAD`" \
|
||||
https://scan.coverity.com/builds?project=HarfBuzz
|
||||
https://scan.coverity.com/builds?project=behdad-harfbuzz
|
||||
env:
|
||||
TOKEN: ${{ secrets.COVERITY_SCAN_TOKEN }}
|
||||
|
|
|
@ -2,70 +2,53 @@ name: linux-ci
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags: ["*.*.*"]
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install \
|
||||
gcc \
|
||||
gobject-introspection \
|
||||
gtk-doc-tools \
|
||||
libcairo2-dev \
|
||||
libfreetype6-dev \
|
||||
libgirepository1.0-dev \
|
||||
libglib2.0-dev \
|
||||
libgraphite2-dev \
|
||||
libicu-dev \
|
||||
ninja-build \
|
||||
pkg-config \
|
||||
python3 \
|
||||
python3-setuptools
|
||||
- name: Install Python Dependencies
|
||||
run: sudo pip3 install fonttools meson==0.56.0 gcovr==5.0
|
||||
- name: Setup Meson
|
||||
run: |
|
||||
ccache --version
|
||||
meson setup build \
|
||||
-Dauto_features=enabled \
|
||||
-Dchafa=disabled \
|
||||
-Dgraphite=enabled \
|
||||
-Doptimization=2 \
|
||||
-Db_coverage=true \
|
||||
-Ddoc_tests=true \
|
||||
-Dragel_subproject=true
|
||||
- name: Build
|
||||
run: meson compile -Cbuild
|
||||
- name: Test
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: sudo apt-get install pkg-config gcc ragel gcovr gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python3 python3-setuptools ninja-build gobject-introspection libgirepository1.0-dev
|
||||
- run: sudo pip3 install fonttools
|
||||
- run: sudo pip3 install git+https://github.com/mesonbuild/meson
|
||||
- name: run
|
||||
run: meson build -Db_coverage=true --auto-features=enabled -Dgraphite=enabled -Doptimization=2
|
||||
- name: ci
|
||||
run: meson test --print-errorlogs -Cbuild
|
||||
- name: Generate Documentations
|
||||
|
||||
- name: generate documentations
|
||||
run: ninja -Cbuild harfbuzz-doc
|
||||
- name: Deploy Documentations
|
||||
if: github.ref_type == 'tag'
|
||||
- name: deploy documentations
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||
run: .ci/deploy-docs.sh
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
REVISION: ${{ github.sha }}
|
||||
- name: Generate Coverage
|
||||
run: ninja -Cbuild coverage-xml
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
|
||||
# waiting for https://github.com/rhysd/github-action-benchmark/issues/36 to happen
|
||||
# - name: benchmark
|
||||
# run: build/perf/perf --benchmark_format=json > perf/result.json
|
||||
# - name: store benchmark result
|
||||
# uses: rhysd/github-action-benchmark@b2ee598
|
||||
# if: github.event_name != 'pull_request'
|
||||
# with:
|
||||
# name: C++ Benchmark
|
||||
# tool: 'googlecpp'
|
||||
# output-file-path: perf/result.json
|
||||
# gh-pages-branch: gh-pages
|
||||
# github-token: ${{ secrets.PERSONAL_GITHUB_TOKEN }}
|
||||
# auto-push: true
|
||||
# alert-threshold: '150%'
|
||||
# comment-on-alert: true
|
||||
# fail-on-alert: true
|
||||
|
||||
- name: cov
|
||||
run: ninja -Cbuild coverage
|
||||
- uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: build/meson-logs/coverage.xml
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
name: macos-ci
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
key: ${{ github.job }}-${{ runner.os }}-${{ runner.arch }}
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
export HOMEBREW_NO_AUTO_UPDATE=1
|
||||
export HOMEBREW_NO_INSTALL_CLEANUP=1
|
||||
brew install \
|
||||
cairo \
|
||||
freetype \
|
||||
glib \
|
||||
gobject-introspection \
|
||||
graphite2 \
|
||||
icu4c \
|
||||
meson \
|
||||
ninja \
|
||||
pkg-config
|
||||
- name: Install Python Dependencies
|
||||
run: pip3 install fonttools gcovr==5.0
|
||||
- name: Setup Meson
|
||||
run: |
|
||||
export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig"
|
||||
ccache --version
|
||||
meson setup build \
|
||||
-Dauto_features=enabled \
|
||||
-Ddocs=disabled \
|
||||
-Dchafa=disabled \
|
||||
-Dcoretext=enabled \
|
||||
-Dgraphite=enabled \
|
||||
-Doptimization=2 \
|
||||
-Db_coverage=true \
|
||||
- name: Build
|
||||
run: meson compile -Cbuild
|
||||
- name: Test
|
||||
run: meson test --print-errorlogs -Cbuild
|
||||
- name: Generate Coverage
|
||||
run: ninja -Cbuild coverage-xml
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: build/meson-logs/coverage.xml
|
|
@ -2,24 +2,18 @@ name: msvc
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
msvc:
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2019, windows-latest]
|
||||
os: [windows-2016, windows-latest]
|
||||
include:
|
||||
- name: msvc-2019-x86
|
||||
os: windows-2019
|
||||
- name: msvc-2017-x86
|
||||
os: windows-2016
|
||||
ARCH: x86
|
||||
- name: msvc-2019-amd64
|
||||
os: windows-latest
|
||||
|
@ -27,35 +21,30 @@ jobs:
|
|||
name: ${{ matrix.name }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup Ccache
|
||||
uses: hendrikmuhs/ccache-action@v1.2
|
||||
with:
|
||||
variant: sccache
|
||||
key: ${{ github.job }}-${{ matrix.os }}-${{ matrix.ARCH }}
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Setup MSVC
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch : ${{ matrix.ARCH }}
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
pip install --upgrade meson ninja fonttools
|
||||
- name: Setup Meson
|
||||
run: |
|
||||
sccache --version
|
||||
meson setup build `
|
||||
--wrap-mode=forcefallback `
|
||||
--buildtype=release `
|
||||
-Dglib=enabled `
|
||||
-Dfreetype=enabled `
|
||||
-Dgdi=enabled `
|
||||
-Ddirectwrite=enabled
|
||||
- name: Build
|
||||
run: meson compile -Cbuild
|
||||
- name: Test
|
||||
run: meson test --print-errorlogs --suite=harfbuzz -Cbuild
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch : ${{ matrix.ARCH }}
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
pip install --upgrade meson ninja fonttools
|
||||
- name: Build
|
||||
run: |
|
||||
# This dir contains a pkg-config which meson will happily use and later fail, so remove it
|
||||
$env:path = ($env:path.Split(';') | Where-Object { $_ -ne 'C:\Strawberry\perl\bin' }) -join ';'
|
||||
|
||||
meson setup build `
|
||||
--wrap-mode=default `
|
||||
--buildtype=release `
|
||||
-Dglib=enabled `
|
||||
-Dfreetype=enabled `
|
||||
-Dgdi=enabled `
|
||||
-Ddirectwrite=enabled
|
||||
|
||||
meson compile -C build
|
||||
- name: Test
|
||||
run: |
|
||||
meson test --print-errorlogs --suite=harfbuzz -C build
|
||||
|
|
|
@ -2,19 +2,13 @@ name: msys2
|
|||
|
||||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
msys2:
|
||||
runs-on: windows-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- MSYSTEM: MINGW32
|
||||
|
@ -23,51 +17,46 @@ jobs:
|
|||
MSYS2_ARCH: x86_64
|
||||
name: ${{ matrix.MSYSTEM }}
|
||||
|
||||
env:
|
||||
# XXX: For some reason enabling jit debugging "fixes" random python crashes
|
||||
# see https://github.com/msys2/MINGW-packages/issues/11864
|
||||
MSYS: "winjitdebug"
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Setup MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.MSYSTEM }}
|
||||
update: true
|
||||
install: >-
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-cairo
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-freetype
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc-libs
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-gettext
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-glib2
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-gobject-introspection
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-graphite2
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-icu
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-meson
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-ninja
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-pkg-config
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-python
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-python-pip
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
pip install --upgrade fonttools
|
||||
- name: Setup Meson
|
||||
run: |
|
||||
meson setup build \
|
||||
--wrap-mode=nodownload \
|
||||
--auto-features=enabled \
|
||||
-Ddocs=disabled \
|
||||
-Ddirectwrite=enabled \
|
||||
-Dgdi=enabled \
|
||||
-Dgraphite=enabled \
|
||||
-Dchafa=disabled
|
||||
- name: Build
|
||||
run: meson compile -Cbuild
|
||||
- name: Test
|
||||
run: meson test --print-errorlogs --suite=harfbuzz -Cbuild
|
||||
- uses: actions/checkout@v2
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.MSYSTEM }}
|
||||
update: true
|
||||
install: >-
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-cairo
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-freetype
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-gcc-libs
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-gettext
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-glib2
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-gobject-introspection
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-graphite2
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-icu
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-meson
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-ninja
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-pkg-config
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-python
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-python-pip
|
||||
mingw-w64-${{ matrix.MSYS2_ARCH }}-ragel
|
||||
- name: Install Python Dependencies
|
||||
run: |
|
||||
pip install --upgrade fonttools
|
||||
- name: Build
|
||||
run: |
|
||||
meson build \
|
||||
--wrap-mode=nodownload \
|
||||
--auto-features=enabled \
|
||||
-Ddirectwrite=enabled \
|
||||
-Dgdi=enabled \
|
||||
-Dgraphite=enabled
|
||||
ninja -C build
|
||||
- name: Test
|
||||
run: |
|
||||
meson test \
|
||||
--print-errorlogs \
|
||||
--suite=harfbuzz \
|
||||
-C build
|
||||
|
|
28
BUILD.md
28
BUILD.md
|
@ -1,29 +1,27 @@
|
|||
On Linux, install the development packages for FreeType, Cairo, and GLib. For
|
||||
example, on Ubuntu / Debian, you would do:
|
||||
On Linux, install the development packages for FreeType,
|
||||
Cairo, and GLib. For example, on Ubuntu / Debian, you would do:
|
||||
|
||||
$ sudo apt-get install meson pkg-config ragel gtk-doc-tools gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev
|
||||
sudo apt-get install meson pkg-config ragel gtk-doc-tools gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev
|
||||
|
||||
whereas on Fedora, RHEL, CentOS, and other Red Hat based systems you would do:
|
||||
|
||||
$ sudo dnf install meson pkgconfig gtk-doc gcc gcc-c++ freetype-devel glib2-devel cairo-devel
|
||||
sudo dnf install meson pkgconfig gtk-doc gcc gcc-c++ freetype-devel glib2-devel cairo-dev
|
||||
|
||||
and on ArchLinux and Manjaro:
|
||||
|
||||
$ sudo pacman -Suy meson pkg-config ragel gcc freetype2 glib2 cairo
|
||||
sudo pacman -Suy meson pkg-config ragel gcc freetype2 glib2 cairo
|
||||
|
||||
then use meson to build the project like `meson build && meson test -Cbuild`.
|
||||
|
||||
On macOS, `brew install pkg-config ragel gtk-doc freetype glib cairo meson`
|
||||
then use meson like above.
|
||||
On macOS, `brew install pkg-config ragel gtk-doc freetype glib cairo meson` then use
|
||||
meson like above.
|
||||
|
||||
On Windows, meson can build the project like above if a working MSVC's cl.exe
|
||||
(`vcvarsall.bat`) or gcc/clang is already on your path, and if you use
|
||||
something like `meson build --wrap-mode=default` it fetches and compiles most
|
||||
of the dependencies also. It is recommended to install CMake either manually
|
||||
or via the Visual Studio installer when building with MSVC, using meson.
|
||||
On Windows, meson can build the project like above if a working MSVC's cl.exe (`vcvarsall.bat`)
|
||||
or gcc/clang is already on your path, and if you use something like `meson build --wrap-mode=default`
|
||||
it fetches and compiles most of the dependencies also.
|
||||
|
||||
Our CI configurations is also a good source of learning how to build HarfBuzz.
|
||||
|
||||
There is also amalgam source provided with HarfBuzz which reduces whole process
|
||||
of building HarfBuzz like `g++ src/harfbuzz.cc -fno-exceptions` but there is
|
||||
not guarantee provided with buildability and reliability of features you get.
|
||||
There is also amalgam source provided with HarfBuzz which reduces whole process of building
|
||||
HarfBuzz like `g++ src/harfbuzz.cc -fno-exceptions` but there is not guarantee provided
|
||||
with buildability and reliability of features you get.
|
||||
|
|
138
CMakeLists.txt
138
CMakeLists.txt
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 2.8.0)
|
||||
project(harfbuzz)
|
||||
|
||||
message(WARN "HarfBuzz has a Meson port and tries to migrate all the other build systems to it, please consider using it as we might remove our cmake port soon.")
|
||||
|
@ -37,10 +37,6 @@ option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF)
|
|||
option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
|
||||
option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
|
||||
option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
|
||||
if (TARGET freetype)
|
||||
set (HB_HAVE_FREETYPE ON)
|
||||
add_definitions(-DHAVE_FREETYPE=1)
|
||||
endif ()
|
||||
if (APPLE)
|
||||
option(HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON)
|
||||
set (CMAKE_MACOSX_RPATH ON)
|
||||
|
@ -80,7 +76,6 @@ include (FindPythonInterp)
|
|||
## Functions and headers
|
||||
include (CheckFunctionExists)
|
||||
include (CheckIncludeFile)
|
||||
include (CheckIncludeFiles)
|
||||
macro (check_funcs) # Similar to AC_CHECK_FUNCS of autotools
|
||||
foreach (func_name ${ARGN})
|
||||
string(TOUPPER ${func_name} definition_to_add)
|
||||
|
@ -107,19 +102,6 @@ if (${HAVE_STDBOOL_H})
|
|||
add_definitions(-DHAVE_STDBOOL_H)
|
||||
endif ()
|
||||
|
||||
# These will be used while making pkg-config .pc files
|
||||
set(PC_REQUIRES_PRIV "")
|
||||
set(PC_LIBS_PRIV "")
|
||||
|
||||
if (NOT MSVC)
|
||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
add_definitions("-DHAVE_PTHREAD")
|
||||
list(APPEND THIRD_PARTY_LIBS Threads::Threads)
|
||||
list(APPEND PC_LIBS_PRIV -pthread)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (MSVC)
|
||||
add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
|
||||
|
@ -194,7 +176,7 @@ set (project_headers ${HB_BASE_headers})
|
|||
set (subset_project_headers ${HB_SUBSET_headers})
|
||||
|
||||
## Find and include needed header folders and libraries
|
||||
if (HB_HAVE_FREETYPE AND NOT TARGET freetype)
|
||||
if (HB_HAVE_FREETYPE)
|
||||
include (FindFreetype)
|
||||
if (NOT FREETYPE_FOUND)
|
||||
message(FATAL_ERROR "HB_HAVE_FREETYPE was set, but we failed to find it. Maybe add a CMAKE_PREFIX_PATH= to your Freetype2 install prefix")
|
||||
|
@ -213,10 +195,6 @@ if (HB_HAVE_FREETYPE AND NOT TARGET freetype)
|
|||
check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var)
|
||||
endif ()
|
||||
|
||||
if (HB_HAVE_FREETYPE)
|
||||
list(APPEND PC_REQUIRES_PRIV "freetype2 >= 12.0.6")
|
||||
endif ()
|
||||
|
||||
if (HB_HAVE_GRAPHITE2)
|
||||
add_definitions(-DHAVE_GRAPHITE2)
|
||||
|
||||
|
@ -229,8 +207,6 @@ if (HB_HAVE_GRAPHITE2)
|
|||
|
||||
list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
|
||||
|
||||
list(APPEND PC_REQUIRES_PRIV "graphite2 >= 1.2.0")
|
||||
|
||||
mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
|
||||
endif ()
|
||||
|
||||
|
@ -251,8 +227,6 @@ if (HB_HAVE_GLIB)
|
|||
|
||||
list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
|
||||
|
||||
list(APPEND PC_REQUIRES_PRIV "glib-2.0 >= 2.19.1")
|
||||
|
||||
mark_as_advanced(GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR)
|
||||
endif ()
|
||||
|
||||
|
@ -285,28 +259,24 @@ if (APPLE AND HB_HAVE_CORETEXT)
|
|||
find_library(COREFOUNDATION CoreFoundation)
|
||||
if (COREFOUNDATION)
|
||||
list(APPEND THIRD_PARTY_LIBS ${COREFOUNDATION})
|
||||
list(APPEND PC_LIBS_PRIV "-framework CoreFoundation")
|
||||
endif ()
|
||||
mark_as_advanced(COREFOUNDATION)
|
||||
|
||||
find_library(CORETEXT CoreText)
|
||||
if (CORETEXT)
|
||||
list(APPEND THIRD_PARTY_LIBS ${CORETEXT})
|
||||
list(APPEND PC_LIBS_PRIV "-framework CoreText")
|
||||
endif ()
|
||||
mark_as_advanced(CORETEXT)
|
||||
|
||||
find_library(COREGRAPHICS CoreGraphics)
|
||||
if (COREGRAPHICS)
|
||||
list(APPEND THIRD_PARTY_LIBS ${COREGRAPHICS})
|
||||
list(APPEND PC_LIBS_PRIV "-framework CoreGraphics")
|
||||
endif ()
|
||||
mark_as_advanced(COREGRAPHICS)
|
||||
else ()
|
||||
find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
|
||||
if (APPLICATION_SERVICES_FRAMEWORK)
|
||||
list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
|
||||
list(APPEND PC_LIBS_PRIV "-framework ApplicationServices")
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
|
||||
|
@ -317,27 +287,18 @@ if (WIN32 AND HB_HAVE_GDI)
|
|||
add_definitions(-DHAVE_GDI)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h)
|
||||
list(APPEND THIRD_PARTY_LIBS gdi32)
|
||||
list(APPEND PC_LIBS_PRIV -lgdi32)
|
||||
endif ()
|
||||
|
||||
if (WIN32 AND HB_HAVE_UNISCRIBE)
|
||||
add_definitions(-DHAVE_UNISCRIBE)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
|
||||
list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
|
||||
list(APPEND PC_LIBS_PRIV -lusp10 -lgdi32 -lrpcrt4)
|
||||
endif ()
|
||||
|
||||
if (WIN32 AND HB_HAVE_DIRECTWRITE)
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
check_include_files("windows.h;dwrite_1.h" HAVE_DWRITE_1_H LANGUAGE CXX)
|
||||
else ()
|
||||
check_include_files("windows.h;dwrite_1.h" HAVE_DWRITE_1_H)
|
||||
endif ()
|
||||
if (NOT HAVE_DWRITE_1_H)
|
||||
message(FATAL_ERROR "DirectWrite was enabled explicitly, but required header is missing")
|
||||
endif ()
|
||||
add_definitions(-DHAVE_DIRECTWRITE)
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
|
||||
list(APPEND THIRD_PARTY_LIBS dwrite rpcrt4)
|
||||
endif ()
|
||||
|
||||
if (HB_HAVE_GOBJECT)
|
||||
|
@ -445,16 +406,41 @@ if (HB_HAVE_GOBJECT)
|
|||
)
|
||||
endif ()
|
||||
|
||||
## Atomic ops availability detection
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c"
|
||||
" void memory_barrier (void) { __sync_synchronize (); }
|
||||
int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); }
|
||||
int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); }
|
||||
void mutex_unlock (int *m) { __sync_lock_release (m); }
|
||||
int main () { return 0; }
|
||||
")
|
||||
try_compile(HB_HAVE_INTEL_ATOMIC_PRIMITIVES
|
||||
${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives
|
||||
${PROJECT_BINARY_DIR}/try_compile_intel_atomic_primitives.c)
|
||||
if (HB_HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
add_definitions(-DHAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
endif ()
|
||||
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c"
|
||||
" #include <atomic.h>
|
||||
/* This requires Solaris Studio 12.2 or newer: */
|
||||
#include <mbarrier.h>
|
||||
void memory_barrier (void) { __machine_rw_barrier (); }
|
||||
int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); }
|
||||
void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); }
|
||||
int main () { return 0; }
|
||||
")
|
||||
try_compile(HB_HAVE_SOLARIS_ATOMIC_OPS
|
||||
${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops
|
||||
${PROJECT_BINARY_DIR}/try_compile_solaris_atomic_ops.c)
|
||||
if (HB_HAVE_SOLARIS_ATOMIC_OPS)
|
||||
add_definitions(-DHAVE_SOLARIS_ATOMIC_OPS)
|
||||
endif ()
|
||||
|
||||
|
||||
## Define harfbuzz library
|
||||
add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers})
|
||||
target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
|
||||
target_include_directories(harfbuzz PUBLIC
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz>")
|
||||
if (HB_HAVE_FREETYPE AND TARGET freetype)
|
||||
target_link_libraries(harfbuzz freetype)
|
||||
endif ()
|
||||
|
||||
|
||||
## Define harfbuzz-icu library
|
||||
|
@ -472,7 +458,6 @@ endif ()
|
|||
## Define harfbuzz-subset library
|
||||
if (HB_BUILD_SUBSET)
|
||||
add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
|
||||
list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-subset.h)
|
||||
add_dependencies(harfbuzz-subset harfbuzz)
|
||||
target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
|
||||
|
||||
|
@ -489,9 +474,7 @@ if (UNIX OR MINGW)
|
|||
link_libraries(-Bsymbolic-functions)
|
||||
endif ()
|
||||
|
||||
# As of CMake 3.0.0, the compiler id for Apple-provided Clang is now "AppleClang";
|
||||
# thus we use MATCHES instead of STREQUAL to include either regular Clang or AppleClang
|
||||
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
||||
# Make sure we don't link to libstdc++
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
|
||||
set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm
|
||||
|
@ -566,7 +549,7 @@ if (HB_HAVE_INTROSPECTION)
|
|||
# We need to account for the varying output directories
|
||||
# when we build using Visual Studio projects
|
||||
if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
|
||||
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
|
||||
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
|
||||
else ()
|
||||
set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
|
||||
endif ()
|
||||
|
@ -720,44 +703,6 @@ if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
|
|||
endif ()
|
||||
endif ()
|
||||
|
||||
# get these variables in the required format
|
||||
list(REMOVE_DUPLICATES PC_REQUIRES_PRIV)
|
||||
string(REPLACE ";" ", " PC_REQUIRES_PRIV "${PC_REQUIRES_PRIV}")
|
||||
list(REMOVE_DUPLICATES PC_LIBS_PRIV)
|
||||
string(REPLACE ";" " " PC_LIBS_PRIV "${PC_LIBS_PRIV}")
|
||||
|
||||
# Macro to write pkg-config .pc configuration files
|
||||
macro ( make_pkgconfig_pc_file name )
|
||||
file(READ "${PROJECT_SOURCE_DIR}/src/${name}.pc.in" FSTR)
|
||||
|
||||
string(REPLACE "%prefix%" "${CMAKE_INSTALL_PREFIX}" FSTR ${FSTR})
|
||||
string(REPLACE "%exec_prefix%" "\${prefix}" FSTR ${FSTR})
|
||||
|
||||
if (IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
string(REPLACE "%includedir%" "${CMAKE_INSTALL_INCLUDEDIR}" FSTR ${FSTR})
|
||||
else ()
|
||||
string(REPLACE "%includedir%" "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}" FSTR ${FSTR})
|
||||
endif ()
|
||||
|
||||
if (IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
|
||||
string(REPLACE "%libdir%" "${CMAKE_INSTALL_LIBDIR}" FSTR ${FSTR})
|
||||
else ()
|
||||
string(REPLACE "%libdir%" "\${prefix}/${CMAKE_INSTALL_LIBDIR}" FSTR ${FSTR})
|
||||
endif ()
|
||||
|
||||
string(REPLACE "%VERSION%" "${HB_VERSION}" FSTR ${FSTR})
|
||||
string(REPLACE "%requires_private%" "${PC_REQUIRES_PRIV}" FSTR ${FSTR})
|
||||
string(REPLACE "%libs_private%" "${PC_LIBS_PRIV}" FSTR ${FSTR})
|
||||
|
||||
file(WRITE "${PROJECT_BINARY_DIR}/${name}.pc" ${FSTR})
|
||||
|
||||
install(
|
||||
FILES "${PROJECT_BINARY_DIR}/${name}.pc"
|
||||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
|
||||
COMPONENT pkgconfig
|
||||
)
|
||||
endmacro ( make_pkgconfig_pc_file )
|
||||
|
||||
if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
|
||||
install(TARGETS harfbuzz
|
||||
EXPORT harfbuzzConfig
|
||||
|
@ -766,7 +711,6 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
|
|||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
FRAMEWORK DESTINATION Library/Frameworks
|
||||
)
|
||||
make_pkgconfig_pc_file("harfbuzz")
|
||||
install(EXPORT harfbuzzConfig
|
||||
NAMESPACE harfbuzz::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/harfbuzz
|
||||
|
@ -778,13 +722,6 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
|
|||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
FRAMEWORK DESTINATION Library/Frameworks
|
||||
)
|
||||
make_pkgconfig_pc_file("harfbuzz-icu")
|
||||
endif ()
|
||||
if (HB_BUILD_SUBSET)
|
||||
install(TARGETS harfbuzz-subset
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
make_pkgconfig_pc_file("harfbuzz-subset")
|
||||
endif ()
|
||||
if (HB_BUILD_UTILS)
|
||||
if (WIN32 AND BUILD_SHARED_LIBS)
|
||||
|
@ -813,10 +750,9 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
|
|||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
)
|
||||
make_pkgconfig_pc_file("harfbuzz-gobject")
|
||||
if (HB_HAVE_INTROSPECTION)
|
||||
if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
|
||||
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
|
||||
set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIGURATION>")
|
||||
else ()
|
||||
set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
|
||||
endif ()
|
||||
|
|
28
CONFIG.md
28
CONFIG.md
|
@ -100,16 +100,15 @@ This is very rarely what you need. Make sure you understand exactly what you
|
|||
are doing.
|
||||
|
||||
Defining `HB_NO_FALLBACK_SHAPE` however is pretty harmless. That removes the
|
||||
(unused) "fallback" shaper. This is defined by the `HB_TINY` profile already
|
||||
(more below).
|
||||
(unused) "fallback" shaper.
|
||||
|
||||
|
||||
## Thread-safety
|
||||
|
||||
By default HarfBuzz builds as a thread-safe library. The exception is that
|
||||
the `HB_TINY` predefined configuration (more below) disables thread-safety.
|
||||
the `HB_TINY` predefined configuring (more below) disables thread-safety.
|
||||
|
||||
If you do *not* need thread-safety in the library (eg. you always call into
|
||||
If you do /not/ need thread-safety in the library (eg. you always call into
|
||||
HarfBuzz from the same thread), you can disable thread-safety by defining
|
||||
`HB_NO_MT`. As noted already, this is enabled by `HB_TINY`.
|
||||
|
||||
|
@ -136,23 +135,16 @@ The pre-defined configurations are:
|
|||
Most of the time, one of the pre-defined configuration is exactly what one needs.
|
||||
Sometimes, however, the pre-defined configuration cuts out features that might
|
||||
be desired in the library. Unfortunately there is no quick way to undo those
|
||||
configurations from the command-line.
|
||||
|
||||
However, configuration can still be overridden from a file. To do that, add your
|
||||
override instructions (mostly `undef` instructions) to a header file and define
|
||||
the macro `HB_CONFIG_OVERRIDE_H` to the string containing to that header file's
|
||||
name. HarfBuzz will then include that file at the appropriate place during
|
||||
configuration.
|
||||
|
||||
Up until HarfBuzz 3.1.2 the the configuration override header file's name was
|
||||
fixed and called `config-override.h`, and was activated by defining the macro
|
||||
`HAVE_CONFIG_OVERRIDE_H`. That still works.
|
||||
configurations from the command-line. But one can add a header file called
|
||||
`config-override.h` to undefine certain `HB_NO_*` symbols as desired. Then
|
||||
define `HAVE_CONFIG_OVERRIDE_H` to make `hb-config.hh` include your configuration
|
||||
overrides at the end.
|
||||
|
||||
|
||||
## Notes
|
||||
|
||||
Note that the config option `HB_NO_CFF`, which is enabled by `HB_LEAN` and
|
||||
`HB_TINY` does *not* mean that the resulting library won't work with CFF fonts.
|
||||
`HB_TINY` does /not/ mean that the resulting library won't work with CFF fonts.
|
||||
The library can shape valid CFF fonts just fine, with or without this option.
|
||||
This option disables (among other things) the code to calculate glyph extents
|
||||
for CFF fonts, which many clients might not need.
|
||||
This option disables (among other things) the code to calculate glyph exntents
|
||||
for CFF fonts.
|
||||
|
|
22
COPYING
22
COPYING
|
@ -2,23 +2,19 @@ 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-2022 Google, Inc.
|
||||
Copyright © 2015-2020 Ebrahim Byagowi
|
||||
Copyright © 2019,2020 Facebook, Inc.
|
||||
Copyright © 2012,2015 Mozilla Foundation
|
||||
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)
|
||||
Copyright © 2009 Keith Stribley
|
||||
Copyright © 2011 Martin Hosken and SIL International
|
||||
Copyright © 2009 Martin Hosken and SIL International
|
||||
Copyright © 2007 Chris Wilson
|
||||
Copyright © 2005,2006,2020,2021,2022,2023 Behdad Esfahbod
|
||||
Copyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023 Red Hat, Inc.
|
||||
Copyright © 1998-2005 David Turner and Werner Lemberg
|
||||
Copyright © 2016 Igalia S.L.
|
||||
Copyright © 2022 Matthias Clasen
|
||||
Copyright © 2018,2021 Khaled Hosny
|
||||
Copyright © 2018,2019,2020 Adobe, Inc
|
||||
Copyright © 2013-2015 Alexei Podtelezhnikov
|
||||
Copyright © 2006 Behdad Esfahbod
|
||||
Copyright © 2005 David Turner
|
||||
Copyright © 2004,2007,2008,2009,2010 Red Hat, Inc.
|
||||
Copyright © 1998-2004 David Turner and Werner Lemberg
|
||||
|
||||
For full copyright notices consult the individual files in the package.
|
||||
|
||||
|
|
25
Makefile.am
25
Makefile.am
|
@ -4,7 +4,7 @@ NULL =
|
|||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
SUBDIRS = src util test perf docs
|
||||
SUBDIRS = src util test docs
|
||||
|
||||
EXTRA_DIST = \
|
||||
autogen.sh \
|
||||
|
@ -19,12 +19,29 @@ EXTRA_DIST = \
|
|||
replace-enum-strings.cmake \
|
||||
meson.build \
|
||||
meson_options.txt \
|
||||
subprojects/cairo.wrap \
|
||||
subprojects/expat.wrap \
|
||||
subprojects/fontconfig.wrap \
|
||||
subprojects/freetype2.wrap \
|
||||
subprojects/glib.wrap \
|
||||
subprojects/libffi.wrap \
|
||||
subprojects/proxy-libintl.wrap \
|
||||
subprojects/zlib.wrap \
|
||||
subprojects/google-benchmark.wrap \
|
||||
subprojects/ragel.wrap \
|
||||
subprojects/packagefiles/ragel/meson.build \
|
||||
perf/meson.build \
|
||||
perf/perf-draw.hh \
|
||||
perf/perf-extents.hh \
|
||||
perf/perf-shaping.hh \
|
||||
perf/perf.cc \
|
||||
perf/fonts/Amiri-Regular.ttf \
|
||||
perf/fonts/NotoNastaliqUrdu-Regular.ttf \
|
||||
perf/fonts/NotoSansDevanagari-Regular.ttf \
|
||||
perf/fonts/Roboto-Regular.ttf \
|
||||
perf/texts/en-thelittleprince.txt \
|
||||
perf/texts/en-words.txt \
|
||||
perf/texts/fa-monologue.txt \
|
||||
perf/texts/fa-thelittleprince.txt \
|
||||
meson-cc-tests/intel-atomic-primitives-test.c \
|
||||
meson-cc-tests/solaris-atomic-operations.c \
|
||||
mingw-configure.sh \
|
||||
$(NULL)
|
||||
|
||||
|
|
791
NEWS
791
NEWS
|
@ -1,787 +1,3 @@
|
|||
Overview of changes leading to 7.1.0
|
||||
Friday, March 3, 2023
|
||||
====================================
|
||||
- New experimental hb_shape_justify() API that uses font variations to expand
|
||||
or shrink the text to a given advance. (Behdad Esfahbod)
|
||||
- Various build and bug fixes. (Behdad Esfahbod, Garret Rieger, Qunxin Liu)
|
||||
|
||||
- New API:
|
||||
+hb_font_set_variation()
|
||||
|
||||
Overview of changes leading to 7.0.1
|
||||
Monday, February 20, 2023
|
||||
====================================
|
||||
- Various build and bug fixes.
|
||||
|
||||
|
||||
Overview of changes leading to 7.0.0
|
||||
Saturday, February 11, 2023
|
||||
====================================
|
||||
- New hb-paint API that is designed mainly to paint “COLRv1” glyphs, but can be
|
||||
also used as a unified API to paint any of the glyph representations
|
||||
supported by HarfBuzz (B/W outlines, color layers, or color bitmaps).
|
||||
(Behdad Esfahbod, Matthias Clasen)
|
||||
- New hb-cairo API for integrating with cairo graphics library. This is provided
|
||||
as a separate harfbuzz-cairo library. (Behdad Esfahbod, Matthias Clasen)
|
||||
- Support for instancing “CFF2” table. (Behdad Esfahbod)
|
||||
- Support font emboldening. (Behdad Esfahbod)
|
||||
- Support feature ranges with AAT shaping. (Behdad Esfahbod)
|
||||
- Experimental support to cubic curves in “glyf” table, see
|
||||
https://github.com/harfbuzz/boring-expansion-spec/blob/main/glyf1-cubicOutlines.md
|
||||
for spec. (Behdad Esfahbod)
|
||||
- Various subsetter improvements. (Garret Rieger, Qunxin Liu, Behdad Esfahbod)
|
||||
- Various documentation improvements.
|
||||
(Behdad Esfahbod, Matthias Clasen, Khaled Hosny)
|
||||
- Significantly reduced memory use during shaping. (Behdad Esfahbod)
|
||||
- Greatly reduced memory use during subsetting “CFF” table. (Behdad Esfahbod)
|
||||
- New command line utility, hb-info, for querying various font information.
|
||||
(Behdad Esfahbod, Matthias Clasen)
|
||||
- New hb-shape/hb-view options: --glyphs, --color-palette, --font-bold,
|
||||
--font-grade, and --named-instance. (Behdad Esfahbod)
|
||||
- Miscellaneous fixes and improvements.
|
||||
(Amir Masoud Abdol, Andres Salomon, Behdad Esfahbod, Chun-wei Fan,
|
||||
Garret Rieger, Jens Kutilek, Khaled Hosny, Konstantin Käfer, Matthias Clasen,
|
||||
Nirbheek Chauhan, Pedro J. Estébanez, Qunxin Liu, Sergei Trofimovich)
|
||||
|
||||
- New API:
|
||||
+HB_FONT_NO_VAR_NAMED_INSTANCE
|
||||
+HB_PAINT_IMAGE_FORMAT_BGRA
|
||||
+HB_PAINT_IMAGE_FORMAT_PNG
|
||||
+HB_PAINT_IMAGE_FORMAT_SVG
|
||||
+hb_cairo_font_face_create_for_face
|
||||
+hb_cairo_font_face_create_for_font
|
||||
+hb_cairo_font_face_get_face
|
||||
+hb_cairo_font_face_get_font
|
||||
+hb_cairo_font_face_get_scale_factor
|
||||
+hb_cairo_font_face_set_font_init_func
|
||||
+hb_cairo_font_face_set_scale_factor
|
||||
+hb_cairo_font_init_func_t
|
||||
+hb_cairo_glyphs_from_buffer
|
||||
+hb_cairo_scaled_font_get_font
|
||||
+hb_color_line_get_color_stops
|
||||
+hb_color_line_get_color_stops_func_t
|
||||
+hb_color_line_get_extend
|
||||
+hb_color_line_get_extend_func_t
|
||||
+hb_color_line_t
|
||||
+hb_color_stop_t
|
||||
+hb_draw_funcs_get_empty
|
||||
+hb_draw_funcs_get_user_data
|
||||
+hb_draw_funcs_set_user_data
|
||||
+hb_face_collect_nominal_glyph_mapping
|
||||
+hb_font_draw_glyph
|
||||
+hb_font_draw_glyph_func_t
|
||||
+hb_font_funcs_set_draw_glyph_func
|
||||
+hb_font_funcs_set_paint_glyph_func
|
||||
+hb_font_get_synthetic_bold
|
||||
+hb_font_get_var_named_instance
|
||||
+hb_font_paint_glyph
|
||||
+hb_font_paint_glyph_func_t
|
||||
+hb_font_set_synthetic_bold
|
||||
+hb_map_keys
|
||||
+hb_map_next
|
||||
+hb_map_update
|
||||
+hb_map_values
|
||||
+hb_ot_color_glyph_has_paint
|
||||
+hb_ot_color_has_paint
|
||||
+hb_ot_layout_script_select_language2
|
||||
+hb_ot_name_id_predefined_t
|
||||
+hb_paint_color
|
||||
+hb_paint_color_func_t
|
||||
+hb_paint_composite_mode_t
|
||||
+hb_paint_custom_palette_color
|
||||
+hb_paint_custom_palette_color_func_t
|
||||
+hb_paint_extend_t
|
||||
+hb_paint_funcs_create
|
||||
+hb_paint_funcs_destroy
|
||||
+hb_paint_funcs_get_empty
|
||||
+hb_paint_funcs_get_user_data
|
||||
+hb_paint_funcs_is_immutable
|
||||
+hb_paint_funcs_make_immutable
|
||||
+hb_paint_funcs_reference
|
||||
+hb_paint_funcs_set_color_func
|
||||
+hb_paint_funcs_set_custom_palette_color_func
|
||||
+hb_paint_funcs_set_image_func
|
||||
+hb_paint_funcs_set_linear_gradient_func
|
||||
+hb_paint_funcs_set_pop_clip_func
|
||||
+hb_paint_funcs_set_pop_group_func
|
||||
+hb_paint_funcs_set_pop_transform_func
|
||||
+hb_paint_funcs_set_push_clip_glyph_func
|
||||
+hb_paint_funcs_set_push_clip_rectangle_func
|
||||
+hb_paint_funcs_set_push_group_func
|
||||
+hb_paint_funcs_set_push_transform_func
|
||||
+hb_paint_funcs_set_radial_gradient_func
|
||||
+hb_paint_funcs_set_sweep_gradient_func
|
||||
+hb_paint_funcs_set_user_data
|
||||
+hb_paint_funcs_t
|
||||
+hb_paint_image
|
||||
+hb_paint_image_func_t
|
||||
+hb_paint_linear_gradient
|
||||
+hb_paint_linear_gradient_func_t
|
||||
+hb_paint_pop_clip
|
||||
+hb_paint_pop_clip_func_t
|
||||
+hb_paint_pop_group
|
||||
+hb_paint_pop_group_func_t
|
||||
+hb_paint_pop_transform
|
||||
+hb_paint_pop_transform_func_t
|
||||
+hb_paint_push_clip_glyph
|
||||
+hb_paint_push_clip_glyph_func_t
|
||||
+hb_paint_push_clip_rectangle
|
||||
+hb_paint_push_clip_rectangle_func_t
|
||||
+hb_paint_push_group
|
||||
+hb_paint_push_group_func_t
|
||||
+hb_paint_push_transform
|
||||
+hb_paint_push_transform_func_t
|
||||
+hb_paint_radial_gradient
|
||||
+hb_paint_radial_gradient_func_t
|
||||
+hb_paint_sweep_gradient
|
||||
+hb_paint_sweep_gradient_func_t
|
||||
+hb_set_is_inverted
|
||||
+hb_subset_input_keep_everything
|
||||
|
||||
- Deprecated API:
|
||||
+hb_font_funcs_set_glyph_shape_func
|
||||
+hb_font_get_glyph_shape_func_t
|
||||
+hb_font_get_glyph_shape
|
||||
|
||||
|
||||
Overview of changes leading to 6.0.0
|
||||
Friday, December 16, 2022
|
||||
====================================
|
||||
- A new API have been added to pre-process the face and speed up future
|
||||
subsetting operations on that face. Provides up to a 95% reduction in
|
||||
subsetting times when the same face is subset more than once.
|
||||
|
||||
For more details and benchmarks, see:
|
||||
https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md
|
||||
|
||||
(Garret Rieger, Behdad Esfahbod)
|
||||
|
||||
- Shaping have been speedup by skipping entire lookups when the buffer contents
|
||||
don't intersect with the lookup. Shows up to a 10% speedup in shaping some
|
||||
fonts. (Behdad Esfahbod)
|
||||
|
||||
- A new experimental feature, “Variable Composites” (enabled by passing
|
||||
-Dexperimental_api=true to meson), is also featured in this release.
|
||||
This technology enables drastic compression of fonts in the Chinese,
|
||||
Japanese, Korean, and other writing systems, by reusing the OpenType Font
|
||||
Variations technology for encoding “smart components” into the font.
|
||||
|
||||
The specification for these extensions to the font format can be found in:
|
||||
https://github.com/harfbuzz/boring-expansion-spec/blob/glyf1/glyf1.md
|
||||
|
||||
A test variable-font with ~7160 Hangul syllables derived from the
|
||||
NotoSerifKR-VF font has been built, with existing OpenType technology, as
|
||||
well as with the new Variable Composites (VarComposites) technology. The
|
||||
VarComposites font is over 90% smaller than the OpenType version of the font!
|
||||
Both fonts can be obtained from the “smarties” repository:
|
||||
https://github.com/behdad/smarties/tree/3.0/fonts/hangul/serif
|
||||
|
||||
When building HarfBuzz with experimental features enabled, you can test
|
||||
the “smarties” font with a sample character like this:
|
||||
|
||||
$ hb-view butchered-hangul-serif-smarties-variable.ttf -u AE01 --variations=wght=700
|
||||
|
||||
(Behdad Esfahbod)
|
||||
|
||||
- The HarfBuzz subsetter can now drop axes by pinning them to specific values
|
||||
(also referred to as instancing). There are a couple of restrictions
|
||||
currently:
|
||||
|
||||
- Only works with TrueType (“glyf”) based fonts. “CFF2” fonts are not yet
|
||||
supported.
|
||||
- Only supports the case where all axes in a font are pinned.
|
||||
|
||||
(Garret Rieger, Qunxin Liu)
|
||||
|
||||
- Miscellaneous fixes and improvements.
|
||||
|
||||
(Behdad Esfahbod, Christoph Reiter, David Corbett, Eli Schwartz, Garret
|
||||
Rieger, Joel Auterson, Jordan Petridis, Khaled Hosny, Lorenz Wildberg,
|
||||
Marco Rebhan, Martin Storsjö, Matthias Clasen, Qunxin Liu, Satadru Pramanik)
|
||||
|
||||
|
||||
- New API
|
||||
+hb_subset_input_pin_axis_location()
|
||||
+hb_subset_input_pin_axis_to_default()
|
||||
+hb_subset_preprocess()
|
||||
|
||||
|
||||
Overview of changes leading to 5.3.1
|
||||
Wednesday, October 19, 2022
|
||||
====================================
|
||||
- Subsetter repacker fixes. (Garret Rieger)
|
||||
- Adjust Grapheme clusters for Katakana voiced sound marks. (Behdad Esfahbod)
|
||||
- New “hb-subset” option “--preprocess-face”. (Garret Rieger)
|
||||
|
||||
|
||||
Overview of changes leading to 5.3.0
|
||||
Saturday, October 8, 2022
|
||||
"Women, Life, Freedom" #MahsaAmini
|
||||
====================================
|
||||
- Don’t add glyphs from dropped MATH or COLR tables to the subset glyphs.
|
||||
(Khaled Hosny)
|
||||
- Map “rlig” to appropriate AAT feature selectors. (Jonathan Kew)
|
||||
- Update USE data files to latest version. (David Corbett)
|
||||
- Check “CBDT” extents first before outline tables, to help with fonts that
|
||||
also include an empty “glyf” table. (Khaled Hosny)
|
||||
- More work towards variable font instancing in the subsetter. (Qunxin Liu)
|
||||
- Subsetter repacker improvements. (Garret Rieger)
|
||||
- New API:
|
||||
+hb_ot_layout_lookup_get_optical_bound()
|
||||
+hb_face_builder_sort_tables()
|
||||
|
||||
|
||||
Overview of changes leading to 5.2.0
|
||||
Saturday, September 17, 2022
|
||||
====================================
|
||||
- Fix regressions in hb-ft font functions for FT_Face’s with transformation
|
||||
matrix. (Behdad Esfahbod)
|
||||
- The experimental hb-repacker API now supports splitting several GPOS subtable
|
||||
types when needed. (Garret Rieger)
|
||||
- The HarfBuzz extensions to OpenType font format are now opt-in behind
|
||||
build-time flags. (Behdad Esfahbod)
|
||||
- The experimental hb-subset variable fonts instantiation API can now
|
||||
instantiate more font tables and arbitrary axis locations. (Qunxin Liu)
|
||||
- Unicode 15 support. (David Corbett)
|
||||
- Various documentation improvements. (Behdad Esfahbod, Matthias Clasen)
|
||||
- The hb-view command line tool now detects WezTerm inline images support.
|
||||
(Wez Furlong)
|
||||
- Fix FreeType and ICU dependency lookup with meson. (Xavier Claessens)
|
||||
|
||||
- New API:
|
||||
+HB_SCRIPT_KAWI
|
||||
+HB_SCRIPT_NAG_MUNDARI
|
||||
|
||||
|
||||
Overview of changes leading to 5.1.0
|
||||
Sunday, July 31, 2022
|
||||
====================================
|
||||
- More extensive buffer tracing messages. (Behdad Esfahbod)
|
||||
- Fix hb-ft regression in bitmap fonts rendering. (Behdad Esfahbod)
|
||||
- Support extension promotion of lookups in hb-subset-repacker. (Garret Rieger)
|
||||
- A new HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL for scripts that use elongation
|
||||
(e.g. Arabic) to signify where it is safe to insert tatweel glyph without
|
||||
interrupting shaping. (Behdad Esfahbod)
|
||||
- Add “--safe-to-insert-tatweel” to “hb-shape” tool. (Behdad Esfahbod)
|
||||
|
||||
- New API
|
||||
+HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL
|
||||
+HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL
|
||||
|
||||
|
||||
Overview of changes leading to 5.0.1
|
||||
Saturday, July 23, 2022
|
||||
====================================
|
||||
- Fix version 2 “avar” table with hb-ft. (Behdad Esfahbod)
|
||||
|
||||
|
||||
Overview of changes leading to 5.0.0
|
||||
Saturday, July 23, 2022
|
||||
====================================
|
||||
- Support fonts with more than 65535 glyphs in “GDEF”, “GSUB”, and “GPOS”
|
||||
tables. This is part of https://github.com/be-fonts/boring-expansion-spec to
|
||||
extend OpenType in a backward-compatible way.
|
||||
(Behdad Esfahbod, Garret Rieger)
|
||||
- Complete support for more than 65535 glyphs in “glyf” table that started in
|
||||
4.0.0 release. Part of boring-expansion-spec. (Behdad Esfahbod)
|
||||
- Support version 2 of “avar” table. Part of boring-expansion-spec.
|
||||
(Behdad Esfahbod)
|
||||
- Fix mark attachment on multiple substitutions in some cases.
|
||||
(Behdad Esfahbod)
|
||||
- Fix application of “calt”, “rclt”, and “ccmp” features to better match
|
||||
Uniscribe behaviour with some Arabic fonts. (Behdad Esfahbod)
|
||||
- Improvement to interaction between multiple cursive attachments.
|
||||
(Behdad Esfahbod)
|
||||
- Improve multiple mark interactions in Hebrew. (Behdad Esfahbod)
|
||||
- Implement language-specific forms in AAT shaping. (Behdad Esfahbod)
|
||||
- Fix variation of “VORG” table. (Behdad Esfahbod)
|
||||
- Support for specific script tags to be retained in the subsetter, and add
|
||||
“--layout-scripts” option to “hb-subset” tool. (Garret Rieger)
|
||||
- Accept space as delimiter for --features/--variations in command line tools.
|
||||
- Improve subsetting of “COLR” table. (Qunxin Liu)
|
||||
- Improved fuzzing coverage for ot-math API. (Frédéric Wang)
|
||||
- Fix “kern” table version 2 (AAT) sanitization on 32-bit systems.
|
||||
(Behdad Esfahbod)
|
||||
- Allow negative glyph advances from “graphite2” shaper. (Stephan Bergmann)
|
||||
- Implement loading (color) bitmap fonts with hb-ft. (Behdad Esfahbod)
|
||||
- Fix regression in hb-ft when changing font size. (Behdad Esfahbod)
|
||||
- Fix build on GCC < 7. (Kleis Auke Wolthuizen)
|
||||
- Dynamically load dwrite.dll on windows if “directwrite” shaper is enabled.
|
||||
(Luca Bacci)
|
||||
- Provide a single-file harfbuzz-subset.cc file for easier alternate building
|
||||
of hb-subset library, similar to harfbuzz.cc. (Khaled Hosny)
|
||||
|
||||
- New API
|
||||
+HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG
|
||||
+hb_language_matches()
|
||||
|
||||
|
||||
Overview of changes leading to 4.4.1
|
||||
Wednesday, June 29, 2022
|
||||
====================================
|
||||
- Fix test failure with some compilers.
|
||||
- Fix Telugu and Kannada kerning regression.
|
||||
|
||||
|
||||
Overview of changes leading to 4.4.0
|
||||
Monday, June 27, 2022
|
||||
====================================
|
||||
- Caching of variable fonts shaping, in particular when using HarfBuzz’s own
|
||||
font loading functions (ot). Bringing performance of variable shaping in par
|
||||
with non-variable fonts shaping. (Behdad Esfahbod)
|
||||
- Caching of format 2 “Contextual Substitution” and “Chained Contexts
|
||||
Substitution” lookups. Resulting in up to 20% speedup of lookup-heavy fonts
|
||||
like Gulzar or Noto Nastaliq Urdu. (Behdad Esfahbod)
|
||||
- Improved ANSI output from hb-view. (Behdad Esfahbod)
|
||||
- Support for shaping legacy, pre-OpenType Windows 3.1-era, Arabic fonts that
|
||||
relied on a fixed PUA encoding. (Khaled Hosny, Behdad Esfahbod)
|
||||
- Sinhala script is now shaped by the USE shaper instead of “indic” one.
|
||||
(Behdad Esfahbod, David Corbett)
|
||||
- Thai shaper improvements. (David Corbett)
|
||||
- hb-ot-name API supports approximate BCP-47 language matching, for example
|
||||
asking for “en_US” in a font that has only “en” names will return them.
|
||||
(Behdad Esfahbod)
|
||||
- Optimized TrueType glyph shape loading. (Behdad Esfahbod)
|
||||
- Fix subsetting of HarfBuzz faces created via hb_face_create_for_tables().
|
||||
(Garret Rieger)
|
||||
- Add 32 bit var store support to the subsetter. (Garret Rieger)
|
||||
|
||||
- New API
|
||||
+HB_BUFFER_FLAG_DEFINED
|
||||
+HB_BUFFER_SERIALIZE_FLAG_DEFINED
|
||||
+hb_font_changed()
|
||||
+hb_font_get_serial()
|
||||
+hb_ft_hb_font_changed()
|
||||
+hb_set_hash()
|
||||
+hb_map_copy()
|
||||
+hb_map_hash()
|
||||
|
||||
|
||||
Overview of changes leading to 4.3.0
|
||||
Friday, May 20, 2022
|
||||
====================================
|
||||
- Major speed up in loading and subsetting fonts, especially in
|
||||
handling CFF table. Subsetting some fonts is now 3 times faster.
|
||||
(Behdad Esfahbod, Garret Rieger)
|
||||
- Speed up blending CFF2 table. (Behdad Esfahbod)
|
||||
- Speed up hb_ot_tags_from_language(). (Behdad Esfahbod, David Corbett)
|
||||
- Fix USE classification of U+10A38 to fix multiple marks on single Kharoshthi
|
||||
base. (David Corbett)
|
||||
- Fix parsing of empty CFF Index. (Behdad Esfahbod)
|
||||
- Fix subsetting CPAL table with partial palette overlaps. (Garret Rieger)
|
||||
|
||||
- New API
|
||||
+hb_map_is_equal() (Behdad Esfahbod)
|
||||
|
||||
|
||||
Overview of changes leading to 4.2.1
|
||||
Sunday, April 24, 2022
|
||||
====================================
|
||||
- Make sure hb_blob_create_from_file_or_fail() always returns nullptr in case
|
||||
of failure and not empty blob sometimes. (Khaled Hosny)
|
||||
- Add --passthrough-tables option to hb-subset. (Cosimo Lupo)
|
||||
- Reinstate a pause after basic features in Khmer shaper, fixing a regression
|
||||
introduced in previous release. (Behdad Esfahbod)
|
||||
- Better handling of Regional_Indicator when shaped with RTL-native scripts,
|
||||
reverting earlier fix that caused regressions in AAT shaping. (Behdad Esfahbod)
|
||||
|
||||
|
||||
Overview of changes leading to 4.2.0
|
||||
Wednesday, March 30, 2022
|
||||
====================================
|
||||
- Source code reorganization, splitting large hb-ot-layout files into smaller,
|
||||
per-subtable ones under OT/Layout/*. Code for more tables will follow suit in
|
||||
later releases. (Garret Rieger, Behdad Esfahbod)
|
||||
- Revert Indic shaper change in previous release that broke some fonts and
|
||||
instead make per-syllable restriction of “GSUB” application limited to
|
||||
script-specific Indic features, while applying them and discretionary
|
||||
features in one go. (Behdad Esfahbod)
|
||||
- Fix decoding of private in gvar table. (Behdad Esfahbod)
|
||||
- Fix handling of contextual lookups that delete too many glyphs. (Behdad Esfahbod)
|
||||
- Make “morx” deleted glyphs don’t block “GPOS” application. (Behdad Esfahbod)
|
||||
- Various build fixes. (Chun-wei Fan, Khaled Hosny)
|
||||
|
||||
- New API
|
||||
+hb_set_next_many() (Andrew John)
|
||||
|
||||
|
||||
Overview of changes leading to 4.1.0
|
||||
Wednesday, March 23, 2022
|
||||
====================================
|
||||
- Various OSS-Fuzz fixes. (Behdad Esfahbod)
|
||||
- Make fallback vertical-origin match FreeType’s. (Behdad Esfahbod)
|
||||
- Treat visible viramas like dependent vowels in USE shaper. (David Corbett)
|
||||
- Apply presentation forms features and discretionary features in one go in
|
||||
Indic shaper, which seems to match Uniscribe and CoreText behaviour.
|
||||
(Behdad Esfahbod, David Corbett)
|
||||
- Various bug fixes.
|
||||
|
||||
- New API
|
||||
+hb_set_add_sorted_array() (Andrew John)
|
||||
|
||||
|
||||
Overview of changes leading to 4.0.1
|
||||
Friday, March 11, 2022
|
||||
====================================
|
||||
- Update OpenType to AAT mappings for “hist” and “vrtr” features.
|
||||
(Florian Pircher)
|
||||
- Update IANA Language Subtag Registry to 2022-03-02. (David Corbett)
|
||||
- Update USE shaper to allow any non-numeric tail in a symbol cluster, and
|
||||
remove obsolete data overrides. (David Corbett)
|
||||
- Fix handling of baseline variations to return correctly scaled values.
|
||||
(Matthias Clasen)
|
||||
- A new experimental hb_subset_repack_or_fail() to repack an array of objects,
|
||||
eliminating offset overflows. The API is not available unless HarfBuzz is
|
||||
built with experimental APIs enabled. (Qunxin Liu)
|
||||
|
||||
- New experimental API
|
||||
+hb_link_t
|
||||
+hb_object_t
|
||||
+hb_subset_repack_or_fail()
|
||||
|
||||
|
||||
Overview of changes leading to 4.0.0
|
||||
Tuesday, March 1, 2022
|
||||
====================================
|
||||
- New public API to create subset plan and gather information on things like
|
||||
glyph mappings in the final subset. The plan can then be passed on to perform
|
||||
the subsetting operation. (Garret Rieger)
|
||||
- Draw API for extracting glyph shapes have been extended and finalized and is
|
||||
no longer an experimental API. The draw API supports glyf, CFF and CFF2
|
||||
glyph outlines tables, and applies variation settings set on the font as well
|
||||
as synthetic slant. The new public API is not backward compatible with the
|
||||
previous, non-public, experimental API. (Behdad Esfahbod)
|
||||
- The hb-view tool will use HarfBuzz draw API to render the glyphs instead of
|
||||
cairo-ft when compiled with Cairo 1.17.5 or newer, setting HB_DRAW
|
||||
environment variable to 1 or 0 will force using or not use the draw API,
|
||||
respectively. (Behdad Esfahbod)
|
||||
- The hb-shape and hb-view tools now default to using HarfBuzz’s own font
|
||||
loading functions (ot) instead of FreeType ones (ft). They also have a new
|
||||
option, --font-slant, to apply synthetic slant to the font. (Behdad Esfahbod)
|
||||
- HarfBuzz now supports more than 65535 (the OpenType limit) glyph shapes and
|
||||
metrics. See https://github.com/be-fonts/boring-expansion-spec/issues/6 and
|
||||
https://github.com/be-fonts/boring-expansion-spec/issues/7 for details.
|
||||
(Behdad Esfahbod)
|
||||
- New API to get the dominant horizontal baseline tag for a given script.
|
||||
(Behdad Esfahbod)
|
||||
- New API to get the baseline positions from the font, and synthesize missing
|
||||
ones. As well as new API to get font metrics and synthesize missing ones.
|
||||
(Matthias Clasen)
|
||||
- Improvements to finding dependencies on Windows when building with Visual
|
||||
Studio. (Chun-wei Fan)
|
||||
- New buffer flag, HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT, that must be set
|
||||
during shaping for HB_GLYPH_FLAG_UNSAFE_TO_CONCAT flag to be reliably
|
||||
produced. This is to limit the performance hit of producing this flag to when
|
||||
it is actually needed. (Behdad Esfahbod)
|
||||
- Documentation improvements. (Matthias Clasen)
|
||||
|
||||
- New API
|
||||
- General:
|
||||
+HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT
|
||||
+hb_var_num_t
|
||||
|
||||
- Draw:
|
||||
+hb_draw_funcs_t
|
||||
+hb_draw_funcs_create()
|
||||
+hb_draw_funcs_reference()
|
||||
+hb_draw_funcs_destroy()
|
||||
+hb_draw_funcs_is_immutable()
|
||||
+hb_draw_funcs_make_immutable()
|
||||
+hb_draw_move_to_func_t
|
||||
+hb_draw_funcs_set_move_to_func()
|
||||
+hb_draw_line_to_func_t
|
||||
+hb_draw_funcs_set_line_to_func()
|
||||
+hb_draw_quadratic_to_func_t
|
||||
+hb_draw_funcs_set_quadratic_to_func()
|
||||
+hb_draw_cubic_to_func_t
|
||||
+hb_draw_funcs_set_cubic_to_func()
|
||||
+hb_draw_close_path_func_t
|
||||
+hb_draw_funcs_set_close_path_func()
|
||||
+hb_draw_state_t
|
||||
+HB_DRAW_STATE_DEFAULT
|
||||
+hb_draw_move_to()
|
||||
+hb_draw_line_to()
|
||||
+hb_draw_quadratic_to()
|
||||
+hb_draw_cubic_to()
|
||||
+hb_draw_close_path()
|
||||
+hb_font_get_glyph_shape_func_t
|
||||
+hb_font_funcs_set_glyph_shape_func()
|
||||
+hb_font_get_glyph_shape()
|
||||
|
||||
- OpenType layout
|
||||
+HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL
|
||||
+HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL
|
||||
+hb_ot_layout_get_horizontal_baseline_tag_for_script()
|
||||
+hb_ot_layout_get_baseline_with_fallback()
|
||||
|
||||
- Metrics:
|
||||
+hb_ot_metrics_get_position_with_fallback()
|
||||
|
||||
- Subset:
|
||||
+hb_subset_plan_t
|
||||
+hb_subset_plan_create_or_fail()
|
||||
+hb_subset_plan_reference()
|
||||
+hb_subset_plan_destroy()
|
||||
+hb_subset_plan_set_user_data()
|
||||
+hb_subset_plan_get_user_data()
|
||||
+hb_subset_plan_execute_or_fail()
|
||||
+hb_subset_plan_unicode_to_old_glyph_mapping()
|
||||
+hb_subset_plan_new_to_old_glyph_mapping()
|
||||
+hb_subset_plan_old_to_new_glyph_mapping()
|
||||
|
||||
|
||||
Overview of changes leading to 3.4.0
|
||||
Sunday, February 13, 2022
|
||||
====================================
|
||||
- Perform sanity checks on shaping results is now part of “harfbuzz” library
|
||||
and can be enabled by setting the buffer flag HB_BUFFER_FLAG_VERIFY.
|
||||
(Behdad Esfahbod)
|
||||
- Arabic Mark Transient Reordering Algorithm have been updated to revision 6.
|
||||
(Khaled Hosny)
|
||||
- ISO 15924 code for mathematical notation, ‘Zmth’, now maps to the OpenType
|
||||
‘math’ tag. (Alexis King)
|
||||
- It is now possible to get at once all math kerning values for a given glyph
|
||||
at a given corner. (Alexis King)
|
||||
- Fix locale_t portability issues on systems the typedef’s it to a void
|
||||
pointer. (Behdad Esfahbod)
|
||||
|
||||
- New API:
|
||||
+HB_BUFFER_FLAG_VERIFY
|
||||
+HB_OT_TAG_MATH_SCRIPT
|
||||
+HB_SCRIPT_MATH
|
||||
+hb_ot_math_kern_entry_t
|
||||
+hb_ot_math_get_glyph_kernings()
|
||||
|
||||
- Deprecated API
|
||||
+HB_OT_MATH_SCRIPT
|
||||
|
||||
|
||||
Overview of changes leading to 3.3.2
|
||||
Sunday, February 6, 2022
|
||||
====================================
|
||||
- Revert splitting of pair positioning values introduced in 3.3.0 as it proved
|
||||
problematic. (Behdad Esfahbod)
|
||||
|
||||
|
||||
Overview of changes leading to 3.3.1
|
||||
Monday, January 31, 2022
|
||||
====================================
|
||||
- Fix heap-use-after-free in harfbuzz-subset introduced in previous release.
|
||||
(Garret Rieger)
|
||||
|
||||
|
||||
Overview of changes leading to 3.3.0
|
||||
Monday, January 31, 2022
|
||||
====================================
|
||||
- Improved documentation. (Matthias Clasen)
|
||||
- Internal code cleanup, using C++ standard library more. (Behdad Esfahbod)
|
||||
- The low 16-bits of face index will be used by hb_face_create() to select a
|
||||
face inside a font collection file format, while the high 16-bits will be
|
||||
used by hb_font_create() to load the named instance. (Behdad Esfahbod)
|
||||
- Glyph positions and other font metrics now apply synthetic slant set by
|
||||
hb_font_set_synthetic_slant(), for improved positioning for synthetically
|
||||
slanted fonts. (Behdad Esfahbod)
|
||||
- Fixed unintentional locale dependency in hb_variation_to_string() for decimal
|
||||
point representation. (Matthias Clasen)
|
||||
- When applying pair positioning (kerning) the positioning value is split
|
||||
between the two sides of the pair for improved cursor positioning between
|
||||
such pairs. (Behdad Esfahbod)
|
||||
- Introduced new HB_GLYPH_FLAG_UNSAFE_TO_CONCAT, to be used in conjunction
|
||||
with HB_GLYPH_FLAG_UNSAFE_TO_BREAK for optimizing re-shaping during line
|
||||
breaking. Check the documentation for further details. (Behdad Esfahbod)
|
||||
- Improved handling of macrolanguages when mapping BCP 47 codes to OpenType
|
||||
tags. (David Corbett)
|
||||
|
||||
- New API:
|
||||
+HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
|
||||
+hb_segment_properties_overlay()
|
||||
+hb_buffer_create_similar()
|
||||
+hb_font_set_synthetic_slant()
|
||||
+hb_font_get_synthetic_slant()
|
||||
+hb_font_get_var_coords_design()
|
||||
|
||||
|
||||
Overview of changes leading to 3.2.0
|
||||
Friday, November 26, 2021
|
||||
====================================
|
||||
“harfbuzz” library improvements:
|
||||
- Fixed shaping of Apple Color Emoji flags in right-to-left context. (Behdad Esfahbod)
|
||||
- Fixed positioning of CFF fonts in HB_TINY profile. (Behdad Esfahbod)
|
||||
- OpenType 1.9 language tags update. (David Corbett)
|
||||
- Add HB_NO_VERTICAL config option.
|
||||
- Add HB_CONFIG_OVERRIDE_H for easier configuration. (Behdad Esfahbod)
|
||||
|
||||
“harfbuzz-subset” library improvements:
|
||||
- Improved packing of cmap, loca, and Ligature tables. (Garret Rieger)
|
||||
- Significantly improved overflow-resolution strategy in the repacker. (Garret Rieger)
|
||||
|
||||
|
||||
Overview of changes leading to 3.1.2
|
||||
Friday, November 26, 2021
|
||||
====================================
|
||||
- hb-shape / hb-view: revert treating text on the commandline as single
|
||||
paragraph (was introduced in 3.0.0); add new --single-par to do that.
|
||||
(Behdad Esfahbod)
|
||||
- Subsetter bug fixes. (Garret Rieger, Qunxin Liu, Behdad Esfahbod)
|
||||
|
||||
|
||||
Overview of changes leading to 3.1.1
|
||||
Wednesday, November 8, 2021
|
||||
====================================
|
||||
- Work around GCC cast-align error/warning on some platforms. (Behdad Esfahbod)
|
||||
- Documentation improvements. (Matthias Clasen)
|
||||
|
||||
|
||||
Overview of changes leading to 3.1.0
|
||||
Wednesday, November 3, 2021
|
||||
====================================
|
||||
- Better offset-overflow handling in the subsetter library. (Garret Rieger)
|
||||
- Improved Unicode 14 properties in the USE shaper, and various other USE
|
||||
shaper fixes. (David Corbett)
|
||||
- MATH and COLR v1 tables subsetting support, and various other subsetter fixes.
|
||||
(Qunxin Liu)
|
||||
- Support for Pwo Karen / Ason Chin medial la. (Simon Cozens)
|
||||
- Apply GPOS positioning when substituting with morx table, if kerx is missing.
|
||||
(Behdad Esfahbod)
|
||||
- Apply calt and clig features across syllable boundaries in Indic shaper.
|
||||
(Behdad Esfahbod)
|
||||
- meson option for enabling Graphite 2 has been renamed to graphite2.
|
||||
- Build and documentation fixes.
|
||||
|
||||
- New API:
|
||||
+hb_buffer_set_not_found_glyph()
|
||||
+hb_buffer_get_not_found_glyph()
|
||||
|
||||
|
||||
Overview of changes leading to 3.0.0
|
||||
Friday, September 17, 2021
|
||||
====================================
|
||||
- Unicode 14.0 support (David Corbett).
|
||||
- The hb-subset API and the harfbuzz-subset library's ABI are now declared
|
||||
stable. The harfbuzz-subset library would not have been possible without the
|
||||
work of Garret Rieger and Qunxin Liu from Google Fonts, and the earlier work
|
||||
of Michiharu Ariza from Adobe.
|
||||
- The hb-style API is now stable and no longer experimental.
|
||||
|
||||
- New API:
|
||||
+hb_style_tag_t
|
||||
+hb_style_get_value()
|
||||
+hb_subset_input_t
|
||||
+hb_subset_flags_t
|
||||
+hb_subset_sets_t
|
||||
+hb_subset_input_create_or_fail()
|
||||
+hb_subset_input_reference()
|
||||
+hb_subset_input_destroy()
|
||||
+hb_subset_input_set_user_data()
|
||||
+hb_subset_input_get_user_data()
|
||||
+hb_subset_input_unicode_set()
|
||||
+hb_subset_input_glyph_set()
|
||||
+hb_subset_input_set()
|
||||
+hb_subset_input_get_flags()
|
||||
+hb_subset_input_set_flags()
|
||||
+hb_subset_or_fail()
|
||||
|
||||
- Removed old unstable harfbuzz-subset API:
|
||||
-hb_subset_input_nameid_set()
|
||||
-hb_subset_input_namelangid_set()
|
||||
-hb_subset_input_layout_features_set()
|
||||
-hb_subset_input_no_subset_tables_set()
|
||||
-hb_subset_input_drop_tables_set()
|
||||
-hb_subset_input_set_drop_hints()
|
||||
-hb_subset_input_get_drop_hints()
|
||||
-hb_subset_input_set_desubroutinize()
|
||||
-hb_subset_input_get_desubroutinize()
|
||||
-hb_subset_input_set_retain_gids()
|
||||
-hb_subset_input_get_retain_gids()
|
||||
-hb_subset_input_set_name_legacy()
|
||||
-hb_subset_input_get_name_legacy()
|
||||
-hb_subset_input_set_overlaps_flag()
|
||||
-hb_subset_input_get_overlaps_flag()
|
||||
-hb_subset_input_set_notdef_outline()
|
||||
-hb_subset_input_get_notdef_outline()
|
||||
-hb_subset_input_set_no_prune_unicode_ranges()
|
||||
-hb_subset_input_get_no_prune_unicode_ranges()
|
||||
-hb_subset()
|
||||
|
||||
|
||||
Overview of changes leading to 2.9.1
|
||||
Tuesday, September 7, 2021
|
||||
====================================
|
||||
- Final subset API is in place and if no issues are discovered, it will be the
|
||||
stable subset API of HarfBuzz 3.0.0. Old API is kept to ease transition, but
|
||||
will be removed in 3.0.0.
|
||||
- Various fuzzer-found bug fixes.
|
||||
- hb_buffer_append() now handles the pre- and post-context which previously
|
||||
were left unchanged in the destination buffer.
|
||||
- hb-view / hb-shape now accept following new arguments:
|
||||
o --unicodes-before/after: takes a list of hex numbers that represent Unicode
|
||||
codepoints.
|
||||
- Undeprecated API:
|
||||
hb_set_invert()
|
||||
|
||||
|
||||
Overview of changes leading to 2.9.0
|
||||
Wednesday, August 18, 2021
|
||||
History Repeats Itself (Afghanistan)
|
||||
====================================
|
||||
- Subsetter API is being stabilized, with the first stable API to happen in
|
||||
3.0.0 release (https://github.com/harfbuzz/harfbuzz/issues/3078).
|
||||
- Support multiple variation axes with same tag, aka HOI.
|
||||
- The “coretext” testing shaper now passes font variations to CoreText.
|
||||
- hb-shape/hb-view does not break line at new lines unless text is read from
|
||||
file.
|
||||
- hb-view and hb-subset has a --batch now, similar to hb-shape.
|
||||
- The --batch mode now uses ; as argument separator instead of : used previously.
|
||||
- The --batch in hb-shape does not expect 0th argument anymore. That is, the
|
||||
lines read are interpreted as argv[1:], instead of argv[0:].
|
||||
- The --batch option has been undocumented. We are ready to document it; send
|
||||
feedback if you find it useful.
|
||||
- hb-subset got arguments revamps. Added much-requested --gids-file, --glyphs,
|
||||
--glyphs-file, --unicodes-file, supporting ranges in --unicodes.
|
||||
- Various bug fixes.
|
||||
|
||||
|
||||
Overview of changes leading to 2.8.2
|
||||
Tuesday, July 8, 2021
|
||||
====================================
|
||||
- Shaping LTR digits for RTL scripts now makes the native direction of the
|
||||
digits LTR, applying shaping and positioning rules on the same glyph order as
|
||||
Uniscribe. (Jonathan Kew, Khaled Hosny).
|
||||
- Subsetting COLR v1 and CPAL tables is now supported. (Garret Rieger, Qunxin Liu)
|
||||
- Various fixes and improvements to the subsetter. (Garret Rieger, Qunxin Liu, Behdad)
|
||||
- When applying morx table, mark glyph widths should not be zeroed. (Jonathan Kew)
|
||||
- GPOS is preferred over kerx, if GSUB was applied. (Behdad)
|
||||
- Regional_Indicator pairs are grouped together when clustering. (Behdad)
|
||||
- New API:
|
||||
+hb_blob_create_or_fail()
|
||||
+hb_blob_create_from_file_or_fail()
|
||||
+hb_set_copy()
|
||||
|
||||
|
||||
Overview of changes leading to 2.8.1
|
||||
Tuesday, May 4, 2021
|
||||
====================================
|
||||
- Subsetter now fully supports GSUB/GPOS/GDEF tables (including variations); as
|
||||
such, layout tables are retained by subsetter by default. (Garret Rieger, Qunxin Liu)
|
||||
- Build scripts no longer check for FontConfig as HarfBuzz does not use it.
|
||||
- hb-view supports iTerm2 and kitty inline image protocols (Khaled Hosny),
|
||||
it can also use Chafa for terminal graphics if available (Hans Petter Jansson).
|
||||
|
||||
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
|
||||
====================================
|
||||
|
@ -789,7 +5,6 @@ Sunday, December 27, 2020
|
|||
tarball.
|
||||
- Documentation updates.
|
||||
|
||||
|
||||
Overview of changes leading to 2.7.3
|
||||
Wednesday, December 23, 2020
|
||||
====================================
|
||||
|
@ -986,7 +201,7 @@ Friday, May 24, 2019
|
|||
code-base changes. We now require C++11. Support for gcc 4.8 and earlier has been
|
||||
dropped.
|
||||
- New hb-config.hh facility for compiling smaller library for embedded and web usecases.
|
||||
- New Unicode Character Database implementation that is half the size of previously-used
|
||||
- New Unicode Character Databse implementation that is half the size of previously-used
|
||||
UCDN.
|
||||
- Subsetter improvements.
|
||||
- Improved documentation, thanks to Nathan Willis.
|
||||
|
@ -1834,7 +1049,7 @@ Thursday, February 25, 2016
|
|||
due to bug in glyph class of ASCII double-quote character. This should
|
||||
address "regression" introduced in 1.2.0 when we switched mark zeroing
|
||||
in most shapers from BY_UNICODE_LATE to BY_GDEF_LATE.
|
||||
This fourth release in a week should finally stabilize things...
|
||||
This fourth release in a week should finally stablize things...
|
||||
|
||||
- hb-ot-font's get_glyph() implementation saw some optimizations. Though,
|
||||
might be really hard to measure in real-world situations.
|
||||
|
@ -2882,7 +2097,7 @@ o Changed API:
|
|||
- hb_buffer_create() takes zero arguments now.
|
||||
Use hb_buffer_pre_allocate() to pre-allocate.
|
||||
|
||||
- hb_buffer_add_utf*() now accept -1 for length parameters,
|
||||
- hb_buffer_add_utf*() now accept -1 for length parameteres,
|
||||
meaning "nul-terminated".
|
||||
|
||||
- hb_direction_t enum values changed.
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
This is HarfBuzz, a text shaping library.
|
||||
|
||||
For bug reports, mailing list, and other information please visit:
|
||||
|
||||
http://harfbuzz.org/
|
||||
|
||||
For license information, see https://github.com/harfbuzz/harfbuzz/blob/master/COPYING
|
||||
|
||||
For build information, see https://github.com/harfbuzz/harfbuzz/blob/master/BUILD.md
|
||||
|
||||
For custom configurations, see https://github.com/harfbuzz/harfbuzz/blob/master/CONFIG.md
|
||||
|
||||
For test execution, see https://github.com/harfbuzz/harfbuzz/blob/master/TESTING.md
|
||||
|
||||
Documentation: https://harfbuzz.github.io
|
84
README.md
84
README.md
|
@ -1,17 +1,14 @@
|
|||
[![Linux CI Status](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg)](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg)
|
||||
[![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main)
|
||||
[![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/master)
|
||||
[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)
|
||||
[![Coverity Scan Build Status](https://scan.coverity.com/projects/15166/badge.svg)](https://scan.coverity.com/projects/harfbuzz)
|
||||
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://www.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=github.com&utm_medium=referral&utm_content=harfbuzz/harfbuzz&utm_campaign=Badge_Grade)
|
||||
[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/main/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
|
||||
[![Coverity Code Health](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz)
|
||||
[![Codacy Code Health](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
|
||||
[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/master/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
|
||||
[![Coverals Code Coverage](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
|
||||
[![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions)
|
||||
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
|
||||
|
||||
# HarfBuzz
|
||||
|
||||
HarfBuzz is a text shaping engine. It primarily supports [OpenType][1], but also
|
||||
[Apple Advanced Typography][2]. HarfBuzz is used in Android, Chrome,
|
||||
ChromeOS, Firefox, GNOME, GTK+, KDE, LibreOffice, OpenJDK, PlayStation, Qt,
|
||||
XeTeX, and other places.
|
||||
This is HarfBuzz, a text shaping library.
|
||||
|
||||
For bug reports, mailing list, and other information please visit:
|
||||
|
||||
|
@ -19,66 +16,14 @@ For bug reports, mailing list, and other information please visit:
|
|||
|
||||
For license information, see [COPYING](COPYING).
|
||||
|
||||
## Documentation
|
||||
|
||||
For user manual as well as API documentation, check: https://harfbuzz.github.io
|
||||
|
||||
## Download
|
||||
|
||||
For tarball releases of HarfBuzz, look [here][3]. At the same place you
|
||||
will also find Win32/Win64 binary bundles that include libharfbuzz DLL,
|
||||
hb-view.exe, hb-shape.exe, and all dependencies.
|
||||
|
||||
The canonical source tree is available on [github][4].
|
||||
|
||||
The API that comes with `hb.h` will not change incompatibly. Other, peripheral,
|
||||
headers are more likely to go through minor modifications, but again, we do our
|
||||
best to never change API in an incompatible way. We will never break the ABI.
|
||||
|
||||
If you are not sure whether Pango or HarfBuzz is right for you, read [Pango vs
|
||||
HarfBuzz][5].
|
||||
|
||||
## Development
|
||||
|
||||
For build information, see [BUILD.md](BUILD.md).
|
||||
|
||||
For custom configurations, see [CONFIG.md](CONFIG.md).
|
||||
|
||||
For testing and profiling, see [TESTING.md](TESTING.md).
|
||||
For test execution, see [TESTING.md](TESTING.md).
|
||||
|
||||
To get a better idea of where HarfBuzz stands in the text rendering stack you
|
||||
may want to read [State of Text Rendering][6], though, that document is many
|
||||
years old. Here are a few presentation slides about HarfBuzz at the
|
||||
Internationalization and Unicode Conference over the years:
|
||||
Documentation: https://harfbuzz.github.io
|
||||
|
||||
* November 2014, [Unicode, OpenType, and HarfBuzz: Closing the Circle][7],
|
||||
* October 2012, [HarfBuzz, The Free and Open Text Shaping Engine][8],
|
||||
* October 2009, [HarfBuzz: the Free and Open Shaping Engine][9].
|
||||
|
||||
Both development and user support discussion around HarfBuzz happens on the
|
||||
[github][4].
|
||||
|
||||
To report bugs or submit patches please use [github][4] issues and
|
||||
pull-requests.
|
||||
|
||||
For a comparison of old vs new HarfBuzz memory consumption see [this][10].
|
||||
|
||||
<!--See past and upcoming [HarfBuzz Hackfests](https://freedesktop.org/wiki/Software/HarfBuzz/Hackfests/)!-->
|
||||
|
||||
## Name
|
||||
|
||||
HarfBuzz (حرفباز) is my Persian translation of “[OpenType][1]”,
|
||||
transliterated using the Latin script. It sports a second meaning, but that
|
||||
ain’t translatable.
|
||||
|
||||
> Background: Originally there was this font format called TrueType. People and
|
||||
> companies started calling their type engines all things ending in Type:
|
||||
> FreeType, CoolType, ClearType, etc. And then came OpenType, which is the
|
||||
> successor of TrueType. So, for my OpenType implementation, I decided to stick
|
||||
> with the concept but use the Persian translation. Which is fitting given that
|
||||
> Persian is written in the Arabic script, and OpenType is an extension of
|
||||
> TrueType that adds support for complex script rendering, and HarfBuzz is an
|
||||
> implementation of OpenType complex text shaping.
|
||||
|
||||
<details>
|
||||
<summary>Packaging status of HarfBuzz</summary>
|
||||
|
@ -86,14 +31,3 @@ ain’t translatable.
|
|||
[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)
|
||||
|
||||
</details>
|
||||
|
||||
[1]: https://docs.microsoft.com/en-us/typography/opentype/spec/
|
||||
[2]: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html
|
||||
[3]: https://github.com/harfbuzz/harfbuzz/releases
|
||||
[4]: https://github.com/harfbuzz/harfbuzz
|
||||
[5]: http://mces.blogspot.com/2009/11/pango-vs-harfbuzz.html
|
||||
[6]: http://behdad.org/text/
|
||||
[7]: https://goo.gl/FSIQuC
|
||||
[8]: https://goo.gl/2wSRu
|
||||
[9]: http://behdad.org/download/Presentations/slippy/harfbuzz_slides.pdf
|
||||
[10]: https://goo.gl/woyty
|
||||
|
|
|
@ -29,12 +29,6 @@ for reference.
|
|||
- 32bit: `../mingw-configure.sh i686`
|
||||
- 64bit: `../mingw-configure.sh x86_64`
|
||||
|
||||
c) Build as usual:
|
||||
- make
|
||||
|
||||
d) Configure your wine to find system mingw libraries. See:
|
||||
https://fedoraproject.org/wiki/MinGW/Configure_wine
|
||||
|
||||
Now you can use `hb-shape` by `(cd win32build/util && wine hb-shape.exe)`
|
||||
but if you like to shape with the Microsoft Uniscribe:
|
||||
|
||||
|
@ -51,8 +45,3 @@ but if you like to shape with the Microsoft Uniscribe:
|
|||
5. `WINEDLLOVERRIDES="usp10=n" wine hb-shape.exe fontname.ttf -u 0061,0062,0063 --shaper=uniscribe`
|
||||
|
||||
(`0061,0062,0063` means `abc`, use test/shaping/hb-unicode-decode to generate ones you need)
|
||||
|
||||
When you have built that, you can test HarfBuzz's native shaper against Uniscribe
|
||||
following these instructions:
|
||||
|
||||
https://github.com/harfbuzz/harfbuzz/issues/3671
|
||||
|
|
55
RELEASING.md
55
RELEASING.md
|
@ -1,37 +1,44 @@
|
|||
# HarfBuzz release walk-through checklist:
|
||||
HarfBuzz release walk-through checklist:
|
||||
|
||||
- [ ] Open gitk and review changes since last release.
|
||||
1. Open gitk and review changes since last release.
|
||||
|
||||
- [ ] Print all public API changes:
|
||||
`git diff $(git describe | sed 's/-.*//').. src/*.h`
|
||||
* `git diff $(git describe | sed 's/-.*//').. src/*.h` prints all public API
|
||||
changes.
|
||||
|
||||
- [ ] Document them in NEWS.
|
||||
All API and API semantic changes should be clearly marked as API additions, API changes, or API deletions.
|
||||
Document them in NEWS. All API and API semantic changes should be clearly
|
||||
marked as API additions, API changes, or API deletions. Document
|
||||
deprecations. Ensure all new API / deprecations are in listed correctly in
|
||||
docs/harfbuzz-sections.txt. If release added new API, add entry for new
|
||||
API index at the end of docs/harfbuzz-docs.xml.
|
||||
|
||||
- [ ] Document deprecations.
|
||||
Ensure all new API / deprecations are in listed correctly in docs/harfbuzz-sections.txt.
|
||||
If release added new API, add entry for new API index at the end of docs/harfbuzz-docs.xml.
|
||||
If there's a backward-incompatible API change (including deletions for API
|
||||
used anywhere), that's a release blocker. Do NOT release.
|
||||
|
||||
If there's a backward-incompatible API change (including deletions for API used anywhere), that's a release blocker.
|
||||
Do NOT release.
|
||||
2. Based on severity of changes, decide whether it's a minor or micro release
|
||||
number bump,
|
||||
|
||||
- [ ] Based on severity of changes, decide whether it's a minor or micro release number bump.
|
||||
3. Search for REPLACEME on the repository and replace it with the chosen version
|
||||
for the release.
|
||||
|
||||
- [ ] Search for 'XSince: REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'.
|
||||
4. Make sure you have correct date and new version at the top of NEWS file.
|
||||
|
||||
- [ ] Make sure you have correct date and new version at the top of NEWS file.
|
||||
5. Bump version in line 3 of meson.build and configure.ac.
|
||||
Do a `meson test -Cbuild` so it both checks the tests and updates
|
||||
hb-version.h (use `git diff` to see if is really updated).
|
||||
|
||||
- [ ] Bump version in line 3 of meson.build and configure.ac.
|
||||
6. Commit NEWS, meson.build, configure.ac, and src/hb-version.h, as well as any REPLACEME
|
||||
changes you made. The commit message is simply the release number. Eg. "1.4.7"
|
||||
|
||||
- [ ] Do a `meson test -Cbuild` so it both checks the tests and updates hb-version.h (use `git diff` to see if is really updated).
|
||||
|
||||
- [ ] Commit NEWS, meson.build, configure.ac, and src/hb-version.h, as well as any REPLACEME changes you made.
|
||||
The commit message is simply the release number, e. g. "1.4.7"
|
||||
|
||||
- [ ] Do a `meson dist -Cbuild` that runs the tests against the latest committed changes.
|
||||
7. Do a `meson dist -Cbuild` that runs the tests against the latest commited changes.
|
||||
If doesn't pass, something fishy is going on, reset the repo and start over.
|
||||
|
||||
- [ ] Tag the release and sign it: e.g. `git tag -s 1.4.7 -m 1.4.7`.
|
||||
Enter your GPG password.
|
||||
8. Tag the release and sign it: Eg. "git tag -s 1.4.7 -m 1.4.7". Enter your
|
||||
GPG password.
|
||||
|
||||
- [ ] Push the commit and tag out: `git push --follow-tags`.
|
||||
9. Build win32 bundle. See [README.mingw.md](README.mingw.md).
|
||||
|
||||
10. Push the commit and tag out: "git push --follow-tags".
|
||||
|
||||
11. Go to GitHub release page [here](https://github.com/harfbuzz/harfbuzz/releases),
|
||||
edit the tag, upload win32 bundle and NEWS entry and save.
|
||||
No need to upload source tarball as we rely to GitHub's automatic tar.gz generation.
|
||||
|
|
20
SECURITY.md
20
SECURITY.md
|
@ -1,20 +0,0 @@
|
|||
# Security Policy
|
||||
|
||||
If you have discovered a security vulnerability in this project, please report it
|
||||
privately. **Do not disclose it as a public issue.** This gives me time to work with you
|
||||
to fix the issue before public exposure, reducing the chance that the exploit will be
|
||||
used before a patch is released.
|
||||
|
||||
You may submit the report in the following ways:
|
||||
|
||||
- send an email to behdad@behdad.org and harfbuzz-admin@googlegroups.com; and/or
|
||||
- send me a [private vulnerability report](https://github.com/harfbuzz/harfbuzz/security/advisories/new)
|
||||
|
||||
Please provide the following information in your report:
|
||||
|
||||
- A description of the vulnerability and its impact
|
||||
- How to reproduce the issue
|
||||
|
||||
This project is mostly maintained by two developers, working on a reasonable effort
|
||||
basis. As such, we ask that you give us 90 days to work on a fix before public
|
||||
disclosure.
|
12
TESTING.md
12
TESTING.md
|
@ -39,9 +39,17 @@ ninja -C build
|
|||
|
||||
## Test with the Fuzzer
|
||||
|
||||
FOr fuzzing, see `test/fuzzing/README.md`.
|
||||
```shell
|
||||
CXXFLAGS="-fsanitize=address,fuzzer-no-link" meson fuzzbuild --default-library=static -Dfuzzer_ldflags="-fsanitize=address,fuzzer" -Dexperimental_api=true
|
||||
ninja -Cfuzzbuild test/fuzzing/hb-{shape,draw,subset,set}-fuzzer
|
||||
fuzzbuild/test/fuzzing/hb-subset-fuzzer test/fuzzing/fonts
|
||||
```
|
||||
|
||||
## Profiling
|
||||
|
||||
For profiling, see `perf/README.md`.
|
||||
```
|
||||
meson build --reconfigure
|
||||
meson compile -C build
|
||||
build/perf/perf
|
||||
```
|
||||
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
API issues:
|
||||
===========
|
||||
|
||||
- API to accept a list of languages?
|
||||
|
||||
- Remove hb_ot_shape_glyphs_closure()?
|
||||
|
||||
|
||||
API additions
|
||||
=============
|
||||
|
||||
- Language to/from script.
|
||||
|
||||
- Add hb-cairo glue
|
||||
|
||||
- Add sanitize API.
|
||||
|
||||
- Add query / enumeration API for aalt-like features?
|
||||
|
||||
- Add segmentation API
|
||||
|
||||
- Add hb-fribidi glue?
|
||||
|
||||
|
||||
hb-view / hb-shape enhancements:
|
||||
===============================
|
||||
|
||||
- Add --width, --height, --auto-size, --ink-box, --align, etc?
|
98
configure.ac
98
configure.ac
|
@ -1,6 +1,6 @@
|
|||
AC_PREREQ([2.64])
|
||||
AC_INIT([HarfBuzz],
|
||||
[7.1.0],
|
||||
[2.7.4],
|
||||
[https://github.com/harfbuzz/harfbuzz/issues/new],
|
||||
[harfbuzz],
|
||||
[http://harfbuzz.org/])
|
||||
|
@ -45,7 +45,7 @@ AC_SUBST(HB_VERSION)
|
|||
|
||||
# Libtool version
|
||||
m4_define([hb_version_int],
|
||||
m4_eval(60000 + hb_version_major*100 + hb_version_minor*10 + hb_version_micro))
|
||||
m4_eval(hb_version_major*10000 + hb_version_minor*100 + hb_version_micro))
|
||||
HB_LIBTOOL_VERSION_INFO=hb_version_int:0:hb_version_int
|
||||
AC_SUBST(HB_LIBTOOL_VERSION_INFO)
|
||||
|
||||
|
@ -68,8 +68,8 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
|
|||
])
|
||||
|
||||
# Functions and headers
|
||||
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale uselocale)
|
||||
AC_CHECK_HEADERS(unistd.h sys/mman.h stdbool.h xlocale.h)
|
||||
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty)
|
||||
AC_CHECK_HEADERS(unistd.h sys/mman.h stdbool.h)
|
||||
|
||||
# Compiler flags
|
||||
AC_CANONICAL_HOST
|
||||
|
@ -194,10 +194,6 @@ AC_ARG_WITH(cairo,
|
|||
have_cairo=false
|
||||
if test "x$with_cairo" = "xyes" -o "x$with_cairo" = "xauto"; then
|
||||
PKG_CHECK_MODULES(CAIRO, cairo >= 1.8.0, have_cairo=true, :)
|
||||
save_libs=$LIBS
|
||||
LIBS="$LIBS $CAIRO_LIBS"
|
||||
AC_CHECK_FUNCS(cairo_user_font_face_set_render_color_glyph_func)
|
||||
LIBS=$save_libs
|
||||
fi
|
||||
if test "x$with_cairo" = "xyes" -a "x$have_cairo" != "xtrue"; then
|
||||
AC_MSG_ERROR([cairo support requested but not found])
|
||||
|
@ -218,21 +214,21 @@ AM_CONDITIONAL(HAVE_CAIRO_FT, $have_cairo_ft)
|
|||
|
||||
dnl ==========================================================================
|
||||
|
||||
AC_ARG_WITH(chafa,
|
||||
[AS_HELP_STRING([--with-chafa=@<:@yes/no/auto@:>@],
|
||||
[Use chafa @<:@default=auto@:>@])],,
|
||||
[with_chafa=auto])
|
||||
have_chafa=false
|
||||
if test "x$with_chafa" = "xyes" -o "x$with_chafa" = "xauto"; then
|
||||
PKG_CHECK_MODULES(CHAFA, chafa >= 1.6.0, have_chafa=true, :)
|
||||
AC_ARG_WITH(fontconfig,
|
||||
[AS_HELP_STRING([--with-fontconfig=@<:@yes/no/auto@:>@],
|
||||
[Use fontconfig @<:@default=auto@:>@])],,
|
||||
[with_fontconfig=auto])
|
||||
have_fontconfig=false
|
||||
if test "x$with_fontconfig" = "xyes" -o "x$with_fontconfig" = "xauto"; then
|
||||
PKG_CHECK_MODULES(FONTCONFIG, fontconfig, have_fontconfig=true, :)
|
||||
fi
|
||||
if test "x$with_chafa" = "xyes" -a "x$have_chafa" != "xtrue"; then
|
||||
AC_MSG_ERROR([chafa support requested but not found])
|
||||
if test "x$with_fontconfig" = "xyes" -a "x$have_fontconfig" != "xtrue"; then
|
||||
AC_MSG_ERROR([fontconfig support requested but not found])
|
||||
fi
|
||||
if $have_chafa; then
|
||||
AC_DEFINE(HAVE_CHAFA, 1, [Have chafa terminal graphics library])
|
||||
if $have_fontconfig; then
|
||||
AC_DEFINE(HAVE_FONTCONFIG, 1, [Have fontconfig library])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_CHAFA, $have_chafa)
|
||||
AM_CONDITIONAL(HAVE_FONTCONFIG, $have_fontconfig)
|
||||
|
||||
dnl ==========================================================================
|
||||
|
||||
|
@ -308,7 +304,7 @@ if $have_freetype; then
|
|||
AC_DEFINE(HAVE_FREETYPE, 1, [Have FreeType 2 library])
|
||||
save_libs=$LIBS
|
||||
LIBS="$LIBS $FREETYPE_LIBS"
|
||||
AC_CHECK_FUNCS(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var FT_Get_Transform)
|
||||
AC_CHECK_FUNCS(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var)
|
||||
LIBS=$save_libs
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_FREETYPE, $have_freetype)
|
||||
|
@ -366,13 +362,17 @@ AC_ARG_WITH(directwrite,
|
|||
have_directwrite=false
|
||||
AC_LANG_PUSH([C++])
|
||||
if test "x$with_directwrite" = "xyes" -o "x$with_directwrite" = "xauto"; then
|
||||
AC_CHECK_HEADERS(dwrite_1.h, have_directwrite=true)
|
||||
AC_CHECK_HEADERS(dwrite.h, have_directwrite=true)
|
||||
fi
|
||||
AC_LANG_POP([C++])
|
||||
if test "x$with_directwrite" = "xyes" -a "x$have_directwrite" != "xtrue"; then
|
||||
AC_MSG_ERROR([directwrite support requested but not found])
|
||||
fi
|
||||
if $have_directwrite; then
|
||||
DIRECTWRITE_CXXFLAGS=
|
||||
DIRECTWRITE_LIBS=
|
||||
AC_SUBST(DIRECTWRITE_CXXFLAGS)
|
||||
AC_SUBST(DIRECTWRITE_LIBS)
|
||||
AC_DEFINE(HAVE_DIRECTWRITE, 1, [Have DirectWrite library])
|
||||
fi
|
||||
AM_CONDITIONAL(HAVE_DIRECTWRITE, $have_directwrite)
|
||||
|
@ -417,6 +417,45 @@ AM_CONDITIONAL(HAVE_CORETEXT, $have_coretext)
|
|||
|
||||
dnl ===========================================================================
|
||||
|
||||
AC_CACHE_CHECK([for Intel atomic primitives], hb_cv_have_intel_atomic_primitives, [
|
||||
hb_cv_have_intel_atomic_primitives=false
|
||||
AC_TRY_LINK([
|
||||
void memory_barrier (void) { __sync_synchronize (); }
|
||||
int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); }
|
||||
int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); }
|
||||
void mutex_unlock (int *m) { __sync_lock_release (m); }
|
||||
], [], hb_cv_have_intel_atomic_primitives=true
|
||||
)
|
||||
])
|
||||
if $hb_cv_have_intel_atomic_primitives; then
|
||||
AC_DEFINE(HAVE_INTEL_ATOMIC_PRIMITIVES, 1, [Have Intel __sync_* atomic primitives])
|
||||
fi
|
||||
|
||||
dnl ===========================================================================
|
||||
|
||||
AC_CACHE_CHECK([for Solaris atomic operations], hb_cv_have_solaris_atomic_ops, [
|
||||
hb_cv_have_solaris_atomic_ops=false
|
||||
AC_TRY_LINK([
|
||||
#include <atomic.h>
|
||||
/* This requires Solaris Studio 12.2 or newer: */
|
||||
#include <mbarrier.h>
|
||||
void memory_barrier (void) { __machine_rw_barrier (); }
|
||||
int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); }
|
||||
void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); }
|
||||
], [], hb_cv_have_solaris_atomic_ops=true
|
||||
)
|
||||
])
|
||||
if $hb_cv_have_solaris_atomic_ops; then
|
||||
AC_DEFINE(HAVE_SOLARIS_ATOMIC_OPS, 1, [Have Solaris __machine_*_barrier and atomic_* operations])
|
||||
fi
|
||||
|
||||
if test "$os_win32" = no && ! $have_pthread; then
|
||||
AC_CHECK_HEADERS(sched.h)
|
||||
AC_SEARCH_LIBS(sched_yield,rt,AC_DEFINE(HAVE_SCHED_YIELD, 1, [Have sched_yield]))
|
||||
fi
|
||||
|
||||
dnl ===========================================================================
|
||||
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
src/Makefile
|
||||
|
@ -425,16 +464,13 @@ util/Makefile
|
|||
test/Makefile
|
||||
test/api/Makefile
|
||||
test/fuzzing/Makefile
|
||||
test/shape/Makefile
|
||||
test/shape/data/Makefile
|
||||
test/shape/data/aots/Makefile
|
||||
test/shape/data/in-house/Makefile
|
||||
test/shape/data/text-rendering-tests/Makefile
|
||||
test/shaping/Makefile
|
||||
test/shaping/data/Makefile
|
||||
test/shaping/data/aots/Makefile
|
||||
test/shaping/data/in-house/Makefile
|
||||
test/shaping/data/text-rendering-tests/Makefile
|
||||
test/subset/Makefile
|
||||
test/subset/data/Makefile
|
||||
test/subset/data/repack_tests/Makefile
|
||||
test/threads/Makefile
|
||||
perf/Makefile
|
||||
docs/Makefile
|
||||
docs/version.xml
|
||||
])
|
||||
|
@ -468,7 +504,7 @@ Font callbacks (the more the merrier):
|
|||
|
||||
Tools used for command-line utilities:
|
||||
Cairo: ${have_cairo}
|
||||
Chafa: ${have_chafa}
|
||||
Fontconfig: ${have_fontconfig}
|
||||
|
||||
Additional shapers:
|
||||
Graphite2: ${have_graphite2}
|
||||
|
|
|
@ -29,7 +29,7 @@ SCANGOBJ_OPTIONS=
|
|||
# Extra options to supply to gtkdoc-scan.
|
||||
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
|
||||
SCAN_OPTIONS=--rebuild-types --deprecated-guards="HB_DISABLE_DEPRECATED" \
|
||||
--ignore-decorators='HB_EXTERN|HB_DEPRECATED|HB_DEPRECATED_FOR()'
|
||||
--ignore-decorators='HB_EXTERN|HB_DEPRECATED'
|
||||
|
||||
# Header files or dirs to ignore when scanning. Use base file/dir names
|
||||
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
|
||||
|
@ -83,7 +83,7 @@ content_files= \
|
|||
usermanual-integration.xml \
|
||||
version.xml
|
||||
|
||||
# SGML files where gtk-doc abbreviations (#GtkWidget) are expanded
|
||||
# SGML files where gtk-doc abbrevations (#GtkWidget) are expanded
|
||||
# These files must be listed here *and* in content_files
|
||||
# e.g. expand_content_files=running.sgml
|
||||
expand_content_files=
|
||||
|
|
|
@ -1,259 +0,0 @@
|
|||
digraph {
|
||||
graph [outputorder=edgefirst];
|
||||
node [shape="record", fontname="Noto Sans Mono SemiBold", fontsize=15];
|
||||
edge [fontname="Verdana", fontsize=12,labeldistance=7.5 ];
|
||||
fontname="Verdana";
|
||||
ranksep=0.02; nodesep=0.5;
|
||||
|
||||
subgraph {
|
||||
ranksep="0.02 equally";
|
||||
preprocessing[style=filled,fillcolor="lightgreen",fontname="Verdana",label="Glyph pre-processing"];
|
||||
orthographic[style=filled,fillcolor="lightblue",fontname="Verdana",label="Orthographic Unit Shaping"];
|
||||
reordering[style=filled, fillcolor="lightcoral",fontname="Verdana",label="Reordering group (USE)"];
|
||||
topographic[style=filled,fillcolor="lightgoldenrod",fontname="Verdana",label="Topographical Features‡"];
|
||||
typographic[style=filled,fillcolor="lightpink",fontname="Verdana",label="Typographic Presentation"];
|
||||
positioning[style=filled,fillcolor="lightsalmon",fontname="Verdana",label="Positioning"];
|
||||
preprocessing->reordering->orthographic->topographic->typographic->positioning;
|
||||
}
|
||||
|
||||
decision1 [shape="diamond", label="Script\ndirection?",fontname="Verdana"];
|
||||
rvrn->decision1;
|
||||
|
||||
ltrfeatures [label="{ltra|ltrm}", fillcolor="lightgreen",style="filled"];
|
||||
{
|
||||
rtlfeatures [label="{rtla|rtlm¹}", fillcolor="lightgreen",style="filled"];
|
||||
}
|
||||
{
|
||||
rank=same;
|
||||
fracfeatures [label="frac²|numr³|dnom⁴", fillcolor="lightpink",style="filled"];
|
||||
fracnotes [fontname="Verdana",shape=plaintext,label=<<table border="0" cellborder="0" cellspacing="0">
|
||||
<tr><td align="left">¹ rtlm is scoped to characters with a Unicode mirroring property</td></tr>
|
||||
<tr><td align="left">² frac is scoped to numr + the slash + dnom</td></tr>
|
||||
<tr><td align="left">³ numr is scoped to all decimal numbers before a U+2044 FRACTION SLASH.</td></tr>
|
||||
<tr><td align="left">⁴ dnom is scoped to all decimal numbers after a U+2044 FRACTION SLASH.</td></tr>
|
||||
</table>
|
||||
>];
|
||||
|
||||
}
|
||||
rand [fillcolor="lightpink",style="filled"];
|
||||
|
||||
decision1 -> ltrfeatures [label="Left-to-right"];
|
||||
decision1 -> rtlfeatures [label="Right-to-left"];
|
||||
|
||||
decision1 -> fracfeatures [label="Other"];
|
||||
|
||||
ltrfeatures -> fracfeatures;
|
||||
rtlfeatures -> fracfeatures;
|
||||
fracfeatures->rand;
|
||||
|
||||
decision2 [shape="diamond", label="Script?",fontname="Verdana"];
|
||||
|
||||
{rank=same; HARF [label="{Harf|HARF}"]; notes;}
|
||||
rand -> trak -> HARF -> decision2;
|
||||
|
||||
commonfeatures [shape=none,label=<<table border="0" cellspacing="0">
|
||||
<tr>
|
||||
<td border="1" bgcolor="lightsalmon">abvm</td>
|
||||
<td border="1" bgcolor="lightsalmon">blwm</td>
|
||||
<td border="1" bgcolor="lightgreen">ccmp</td>
|
||||
<td border="1" bgcolor="lightgreen">locl</td>
|
||||
<td border="1" bgcolor="lightsalmon">mark</td>
|
||||
<td border="1" bgcolor="lightsalmon">mkmk</td>
|
||||
<td border="1" bgcolor="lightpink">rlig</td>
|
||||
</tr>
|
||||
</table>>
|
||||
];
|
||||
|
||||
decision3 [shape="diamond", label="Script\ndirection?",fontname="Verdana"];
|
||||
|
||||
BUZZ [label="{Buzz|BUZZ}"];
|
||||
BUZZ -> commonfeatures -> decision3;
|
||||
|
||||
horizontalfeatures [
|
||||
shape=none,label=<<table border="0" cellspacing="0">
|
||||
<tr><td border="1" bgcolor="lightpink">calt <font face="Verdana">(not Hangul)</font></td></tr>
|
||||
<tr><td border="1" bgcolor="lightpink">clig <font face="Verdana">(not Khmer)</font></td></tr>
|
||||
<tr><td border="1" bgcolor="lightsalmon">curs</td></tr>
|
||||
<tr><td border="1" bgcolor="lightsalmon">dist</td></tr>
|
||||
<tr><td border="1" bgcolor="lightsalmon">kern</td></tr>
|
||||
<tr><td border="1" bgcolor="lightpink">liga <font face="Verdana">(not Khmer)</font></td></tr>
|
||||
<tr><td border="1" bgcolor="lightpink">rclt</td></tr>
|
||||
</table>>
|
||||
];
|
||||
vert [label="vert",style=filled,fillcolor="lightpink"];
|
||||
|
||||
decision3 -> horizontalfeatures [label="Horizontal"];
|
||||
decision3 -> vert [label="Vertical"];
|
||||
|
||||
discretionary [label="User-selected\ndiscretionary\nfeatures",fontname="Verdana"];
|
||||
|
||||
horizontalfeatures -> discretionary;
|
||||
vert -> discretionary;
|
||||
|
||||
decision2->stch;
|
||||
|
||||
BUZZ;
|
||||
|
||||
subgraph shapers {
|
||||
subgraph cluster_arabic {
|
||||
bgcolor="lightyellow"
|
||||
label="Arabic, Syriac";
|
||||
stch [ style="filled", fillcolor="lightgreen",label="stch"];
|
||||
ccmplocl [ style="filled", label="ccmp|locl", fillcolor="lightgreen"];
|
||||
arabicfeatures [label="isol|fina|fin2|fin3|medi|med2|init", style="filled", fillcolor="lightgoldenrod"];
|
||||
arabicfeatures2 [label="rclt|calt", style="filled",fillcolor="lightpink"];
|
||||
rlig[style="filled",fillcolor="lightpink"];
|
||||
mset [fillcolor="lightpink",style="filled"]
|
||||
stch->ccmplocl->arabicfeatures->rlig->arabicfeatures2->mset;
|
||||
}
|
||||
mset->BUZZ:n;
|
||||
|
||||
subgraph cluster_hangul {
|
||||
bgcolor="lightyellow"
|
||||
label="Hangul";
|
||||
hangulfeatures [label="ljmo|vjmo|tjmo", style="filled",fillcolor="lightgoldenrod"]
|
||||
}
|
||||
hangulfeatures->BUZZ:n;
|
||||
|
||||
subgraph cluster_indic {
|
||||
label="Indic";
|
||||
bgcolor="lightyellow"
|
||||
// Preprocessing
|
||||
loclccmpindic [label="locl†|ccmp†",style=filled,fillcolor="lightgreen"];
|
||||
node[style=filled,fillcolor="lightgreen"];
|
||||
nukt [label="nukt†"];
|
||||
akhn [label="akhn†"];
|
||||
loclccmpindic->indic_reorder_1->nukt->akhn;
|
||||
indic_reorder_1[label="Initial reordering", fontname="Verdana",fillcolor="lightgrey",shape=ellipse,style=filled]
|
||||
|
||||
// Orthographic
|
||||
node[style=filled,fillcolor="lightblue"]
|
||||
rphf [label="rphf⁵"];
|
||||
rkpf [label="rkpf†"];
|
||||
pref [label="pref⁶"];
|
||||
blwf [label="blwf⁷"];
|
||||
abvf [label="abvf⁸"];
|
||||
half [label="half⁹"];
|
||||
pstf [label="pstf⁸"];
|
||||
vatu [label="vatu†"];
|
||||
cjct [label="cjct†"];
|
||||
akhn ->rphf -> rkpf -> pref -> blwf -> abvf -> half -> pstf -> vatu -> cjct;
|
||||
// Typographic presentation
|
||||
indic_typographic[style=filled,fillcolor="lightpink",label="init|pres|abvs|blws|psts|haln"]
|
||||
indic_reorder_2[label="Final reordering",fillcolor="lightgrey",fontname="Verdana", shape=ellipse,style=filled]
|
||||
cjct->indic_reorder_2->indic_typographic;
|
||||
|
||||
notes2 [fontname="Verdana",shape=plaintext,style="",label=<<table border="0" cellborder="0" cellspacing="0">
|
||||
<tr><td align="right">⁵ rphf is scoped to pre-base ra+halant sequences</td></tr>
|
||||
<tr><td align="right">⁶ pref is scoped to the two glyphs after the base; outputs are reordered</td></tr>
|
||||
<tr><td align="right">⁷ blwf is usually scoped to the whole syllable, except in Telugu and Kannada where it is post-base</td></tr>
|
||||
<tr><td align="right">⁸ abvf and pstf are scoped to post-base</td></tr>
|
||||
<tr><td align="right">⁹ half is scoped to pre-base</td></tr>
|
||||
</table>
|
||||
>];
|
||||
indic_typographic -> notes2 [style=invis];
|
||||
}
|
||||
|
||||
|
||||
subgraph cluster_khmer {
|
||||
label="Khmer";
|
||||
bgcolor="lightyellow"
|
||||
|
||||
khmerbasic [style=filled,fillcolor="lightgreen",label="locl†|ccmp†|pref†|bwlf†|abvf†|pstf†|cfar†"]
|
||||
khmerother [style=filled,fillcolor="lightpink",label="pres|abvs|blws|psts"]
|
||||
khmerbasic -> khmerother -> khmerclig;
|
||||
khmerclig [label="clig",style=filled,fillcolor="lightpink"];
|
||||
}
|
||||
|
||||
subgraph cluster_myanmar {
|
||||
label="Myanmar";
|
||||
bgcolor="lightyellow"
|
||||
loclccmpmyanmar [label="locl†|ccmp†",style=filled,fillcolor="lightgreen"];
|
||||
rphfmymr [label="rphf†",style=filled,fillcolor="lightblue"]
|
||||
prefmymr [label="pref†",style=filled,fillcolor="lightblue"]
|
||||
blwfmymr [label="blwf†",style=filled,fillcolor="lightblue"]
|
||||
pstfmymr [label="pstf†",style=filled,fillcolor="lightblue"]
|
||||
myanmarother [label="pres|abvs|blws|psts",style=filled,fillcolor="lightpink"];
|
||||
reorder_myanmar[label="Reordering", shape=ellipse,style=filled,fontname="Verdana"]
|
||||
loclccmpmyanmar -> reorder_myanmar-> rphfmymr -> prefmymr -> blwfmymr -> pstfmymr -> myanmarother;
|
||||
}
|
||||
|
||||
subgraph cluster_use {
|
||||
label="Universal Shaping Engine"
|
||||
bgcolor="lightyellow"
|
||||
use_preprocessing [style=filled, label="locl†|ccmp†|nukt†|akhn†", fillcolor="lightgreen"];
|
||||
// Reoredering
|
||||
rphfuse [label="rphf¹⁰", style=filled, fillcolor="lightcoral"];
|
||||
prefuse [label="pref¹¹", style=filled, fillcolor="lightcoral"];
|
||||
// Orthographic
|
||||
orthographicuse [label="rkrf†|abvf†|blwf†|half†|pstf†|vatu†|cjct†", style="filled", fillcolor="lightblue"];
|
||||
topographicaluse [label="isol|init|medi|fina", style="filled", fillcolor="lightgoldenrod"];
|
||||
typographicaluse [label="abvs|blws|haln|pres|psts", style="filled", fillcolor="lightpink"];
|
||||
reorder_use[label="Reordering", shape=ellipse,style=filled,fontname="Verdana"]
|
||||
use_preprocessing -> rphfuse -> prefuse->orthographicuse ->reorder_use -> topographicaluse -> typographicaluse;
|
||||
notes3 [fontname="Verdana",shape=plaintext,label=<<table border="0" cellborder="0" cellspacing="0">
|
||||
<tr><td align="left">¹⁰ Outputs are reordered as category R</td></tr>
|
||||
<tr><td align="left">¹¹ Outputs are reordered to before base</td></tr>
|
||||
</table>
|
||||
>];
|
||||
typographicaluse -> notes3 [style=invis];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
indic_typographic->BUZZ:n;
|
||||
typographicaluse->BUZZ:n;
|
||||
khmerclig -> BUZZ:n;
|
||||
myanmarother -> BUZZ:n;
|
||||
|
||||
|
||||
decision2->hangulfeatures;
|
||||
decision2->loclccmpindic;
|
||||
decision2->khmerbasic;
|
||||
decision2->loclccmpmyanmar;
|
||||
decision2->use_preprocessing;
|
||||
decision2->BUZZ [label=" Hebrew, Thai,\n Lao, other"];
|
||||
|
||||
notes [fontname="Verdana",shape=box,label=<<table border="0" cellborder="0" cellspacing="0">
|
||||
<tr><td align="left">
|
||||
<b>Indic</b> scripts are: Bengali, Devanagari,
|
||||
Gujarati, Gurmukhi, Kannada,
|
||||
Malayalam, Oriya, Tamil,
|
||||
Telugu
|
||||
</td></tr>
|
||||
|
||||
<tr><td align="left">
|
||||
<b>USE</b> scripts are:
|
||||
Adlam, Ahom, Balinese, Batak, Bhaiksuki, Brahmi, Buginese,
|
||||
Buhid, Chakma, Cham, Chorasmian, Dives Akuru, Dogra, Duployan,
|
||||
</td></tr>
|
||||
<tr><td align="left">
|
||||
Egyptian hieroglyphs, Elymaic, Grantha, Gunjala Ggondi, Hanifi Rohingya,
|
||||
Hanunoo, Javanese, Kaithi, Kayah li, Kharoshthi, Khojki,
|
||||
</td></tr>
|
||||
<tr><td align="left">
|
||||
Khudawadi, Lepcha, Limbu, Mahajani, Makasar, Mandaic, Manichaean,
|
||||
Marchen, Masaram Gondi, Medefaidrin, Meetei Mayek, Miao, Modi,
|
||||
</td></tr>
|
||||
<tr><td align="left">
|
||||
Mongolian, Multani, Nandinagari, Newa, Nko, Nyiakeng Puachue Hmong,
|
||||
Old Sogdian, Pahawh Hmong, Phags Pa, Psalter Pahlavi, Rejang,
|
||||
</td></tr>
|
||||
<tr><td align="left">
|
||||
Saurashtra, Sharada, Siddham, Sinhala, Sogdian, Soyombo, Sundanese,
|
||||
Syloti Nagri, Tagalog, Tagbanwa, Tai Le, Tai Tham, Tai Viet,
|
||||
</td></tr>
|
||||
<tr><td align="left">
|
||||
Takri, Tibetan, Tifinagh, Tirhuta, Wancho, Zanabazar square,
|
||||
</td></tr>
|
||||
|
||||
</table>>]
|
||||
|
||||
|
||||
footnote[fontname="Verdana",label=<<table border="0" cellborder="0" cellspacing="0">
|
||||
<tr><td align="left">† Feature is scoped to each syllable</td></tr>
|
||||
<tr><td align="left">‡ All topographic features are scoped based on topographic position</td></tr>
|
||||
</table>>];
|
||||
notes3->footnote[style=invis];
|
||||
|
||||
}
|
|
@ -49,16 +49,13 @@
|
|||
<ulink role="online-location" url="http://[SERVER]/libharfbuzz/index.html">http://[SERVER]/libharfbuzz/</ulink>.-->
|
||||
</releaseinfo>
|
||||
</partinfo>
|
||||
|
||||
|
||||
<title>Reference manual</title>
|
||||
<chapter id="core-api">
|
||||
<title>Core API</title>
|
||||
<xi:include href="xml/hb-blob.xml"/>
|
||||
<xi:include href="xml/hb-buffer.xml"/>
|
||||
<xi:include href="xml/hb-common.xml"/>
|
||||
<xi:include href="xml/hb-features.xml"/>
|
||||
<xi:include href="xml/hb-draw.xml"/>
|
||||
<xi:include href="xml/hb-paint.xml"/>
|
||||
<xi:include href="xml/hb-deprecated.xml"/>
|
||||
<xi:include href="xml/hb-face.xml"/>
|
||||
<xi:include href="xml/hb-font.xml"/>
|
||||
|
@ -98,99 +95,71 @@
|
|||
<xi:include href="xml/hb-uniscribe.xml"/>
|
||||
<xi:include href="xml/hb-gdi.xml"/>
|
||||
<xi:include href="xml/hb-directwrite.xml"/>
|
||||
<xi:include href="xml/hb-cairo.xml"/>
|
||||
</chapter>
|
||||
|
||||
<chapter id="style-api">
|
||||
<title>Style API</title>
|
||||
<xi:include href="xml/hb-style.xml"/>
|
||||
</chapter>
|
||||
|
||||
<chapter id="subset-api">
|
||||
<title>Subset API</title>
|
||||
<xi:include href="xml/hb-subset.xml"/>
|
||||
</chapter>
|
||||
|
||||
|
||||
<!--chapter id="object-tree">
|
||||
<title>Object Hierarchy</title>
|
||||
<xi:include href="xml/tree_index.sgml"/>
|
||||
</chapter-->
|
||||
|
||||
<index id="api-index-full"><title>API Index</title><xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="deprecated-api-index"><title>Index of deprecated API</title><xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="deprecated-api-index" role="deprecated"><title>Index of deprecated API</title><xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include></index>
|
||||
|
||||
<index id="api-index-7-1-0"><title>Index of new symbols in 7.1.0</title><xi:include href="xml/api-index-7.1.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-7-0-0"><title>Index of new symbols in 7.0.0</title><xi:include href="xml/api-index-7.0.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-6-0-0"><title>Index of new symbols in 6.0.0</title><xi:include href="xml/api-index-6.0.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-5-3-0"><title>Index of new symbols in 5.3.0</title><xi:include href="xml/api-index-5.3.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-5-0-0"><title>Index of new symbols in 5.0.0</title><xi:include href="xml/api-index-5.0.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-4-4-0"><title>Index of new symbols in 4.4.0</title><xi:include href="xml/api-index-4.4.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-4-3-0"><title>Index of new symbols in 4.3.0</title><xi:include href="xml/api-index-4.3.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-4-2-0"><title>Index of new symbols in 4.2.0</title><xi:include href="xml/api-index-4.2.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-4-1-0"><title>Index of new symbols in 4.1.0</title><xi:include href="xml/api-index-4.1.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-4-0-0"><title>Index of new symbols in 4.0.0</title><xi:include href="xml/api-index-4.0.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-3-4-0"><title>Index of new symbols in 3.4.0</title><xi:include href="xml/api-index-3.4.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-3-3-0"><title>Index of new symbols in 3.3.0</title><xi:include href="xml/api-index-3.3.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-3-1-0"><title>Index of new symbols in 3.1.0</title><xi:include href="xml/api-index-3.1.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-3-0-0"><title>Index of new symbols in 3.0.0</title><xi:include href="xml/api-index-3.0.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-9-1"><title>Index of new symbols in 2.9.1</title><xi:include href="xml/api-index-2.9.1.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-9-0"><title>Index of new symbols in 2.9.0</title><xi:include href="xml/api-index-2.9.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-8-2"><title>Index of new symbols in 2.8.2</title><xi:include href="xml/api-index-2.8.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-7-3"><title>Index of new symbols in 2.7.3</title><xi:include href="xml/api-index-2.7.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-6-8"><title>Index of new symbols in 2.6.8</title><xi:include href="xml/api-index-2.6.8.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-6-5"><title>Index of new symbols in 2.6.5</title><xi:include href="xml/api-index-2.6.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-6-3"><title>Index of new symbols in 2.6.3</title><xi:include href="xml/api-index-2.6.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-6-0"><title>Index of new symbols in 2.6.0</title><xi:include href="xml/api-index-2.6.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-5-0"><title>Index of new symbols in 2.5.0</title><xi:include href="xml/api-index-2.5.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-4-0"><title>Index of new symbols in 2.4.0</title><xi:include href="xml/api-index-2.4.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-3-0"><title>Index of new symbols in 2.3.0</title><xi:include href="xml/api-index-2.3.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-2-0"><title>Index of new symbols in 2.2.0</title><xi:include href="xml/api-index-2.2.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-1-0"><title>Index of new symbols in 2.1.0</title><xi:include href="xml/api-index-2.1.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-0-0"><title>Index of new symbols in 2.0.0</title><xi:include href="xml/api-index-2.0.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-9-0"><title>Index of new symbols in 1.9.0</title><xi:include href="xml/api-index-1.9.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-8-6"><title>Index of new symbols in 1.8.6</title><xi:include href="xml/api-index-1.8.6.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-8-5"><title>Index of new symbols in 1.8.5</title><xi:include href="xml/api-index-1.8.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-8-1"><title>Index of new symbols in 1.8.1</title><xi:include href="xml/api-index-1.8.1.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-8-0"><title>Index of new symbols in 1.8.0</title><xi:include href="xml/api-index-1.8.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-7-7"><title>Index of new symbols in 1.7.7</title><xi:include href="xml/api-index-1.7.7.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-7-2"><title>Index of new symbols in 1.7.2</title><xi:include href="xml/api-index-1.7.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-6-0"><title>Index of new symbols in 1.6.0</title><xi:include href="xml/api-index-1.6.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-5-0"><title>Index of new symbols in 1.5.0</title><xi:include href="xml/api-index-1.5.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-4-3"><title>Index of new symbols in 1.4.3</title><xi:include href="xml/api-index-1.4.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-4-2"><title>Index of new symbols in 1.4.2</title><xi:include href="xml/api-index-1.4.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-4-0"><title>Index of new symbols in 1.4.0</title><xi:include href="xml/api-index-1.4.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-3-3"><title>Index of new symbols in 1.3.3</title><xi:include href="xml/api-index-1.3.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-2-3"><title>Index of new symbols in 1.2.3</title><xi:include href="xml/api-index-1.2.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-1-3"><title>Index of new symbols in 1.1.3</title><xi:include href="xml/api-index-1.1.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-1-2"><title>Index of new symbols in 1.1.2</title><xi:include href="xml/api-index-1.1.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-0-5"><title>Index of new symbols in 1.0.5</title><xi:include href="xml/api-index-1.0.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-42"><title>Index of new symbols in 0.9.42</title><xi:include href="xml/api-index-0.9.42.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-41"><title>Index of new symbols in 0.9.41</title><xi:include href="xml/api-index-0.9.41.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-39"><title>Index of new symbols in 0.9.39</title><xi:include href="xml/api-index-0.9.39.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-38"><title>Index of new symbols in 0.9.38</title><xi:include href="xml/api-index-0.9.38.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-33"><title>Index of new symbols in 0.9.33</title><xi:include href="xml/api-index-0.9.33.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-31"><title>Index of new symbols in 0.9.31</title><xi:include href="xml/api-index-0.9.31.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-30"><title>Index of new symbols in 0.9.30</title><xi:include href="xml/api-index-0.9.30.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-28"><title>Index of new symbols in 0.9.28</title><xi:include href="xml/api-index-0.9.28.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-26"><title>Index of new symbols in 0.9.26</title><xi:include href="xml/api-index-0.9.26.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-22"><title>Index of new symbols in 0.9.22</title><xi:include href="xml/api-index-0.9.22.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-21"><title>Index of new symbols in 0.9.21</title><xi:include href="xml/api-index-0.9.21.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-20"><title>Index of new symbols in 0.9.20</title><xi:include href="xml/api-index-0.9.20.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-11"><title>Index of new symbols in 0.9.11</title><xi:include href="xml/api-index-0.9.11.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-10"><title>Index of new symbols in 0.9.10</title><xi:include href="xml/api-index-0.9.10.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-8"><title>Index of new symbols in 0.9.8</title><xi:include href="xml/api-index-0.9.8.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-7"><title>Index of new symbols in 0.9.7</title><xi:include href="xml/api-index-0.9.7.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-5"><title>Index of new symbols in 0.9.5</title><xi:include href="xml/api-index-0.9.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-2"><title>Index of new symbols in 0.9.2</title><xi:include href="xml/api-index-0.9.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-6-0"><title>Index of new symbols in 0.6.0</title><xi:include href="xml/api-index-0.6.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-7-3" role="2.7.3"><title>Index of new symbols in 2.7.3</title><xi:include href="xml/api-index-2.7.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-6-8" role="2.6.8"><title>Index of new symbols in 2.6.8</title><xi:include href="xml/api-index-2.6.8.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-6-5" role="2.6.5"><title>Index of new symbols in 2.6.5</title><xi:include href="xml/api-index-2.6.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-6-3" role="2.6.3"><title>Index of new symbols in 2.6.3</title><xi:include href="xml/api-index-2.6.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-6-0" role="2.6.0"><title>Index of new symbols in 2.6.0</title><xi:include href="xml/api-index-2.6.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-5-0" role="2.5.0"><title>Index of new symbols in 2.5.0</title><xi:include href="xml/api-index-2.5.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-4-0" role="2.4.0"><title>Index of new symbols in 2.4.0</title><xi:include href="xml/api-index-2.4.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-3-0" role="2.3.0"><title>Index of new symbols in 2.3.0</title><xi:include href="xml/api-index-2.3.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-2-0" role="2.2.0"><title>Index of new symbols in 2.2.0</title><xi:include href="xml/api-index-2.2.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-1-0" role="2.1.0"><title>Index of new symbols in 2.1.0</title><xi:include href="xml/api-index-2.1.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-2-0-0" role="2.0.0"><title>Index of new symbols in 2.0.0</title><xi:include href="xml/api-index-2.0.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-9-0" role="1.9.0"><title>Index of new symbols in 1.9.0</title><xi:include href="xml/api-index-1.9.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-8-6" role="1.8.6"><title>Index of new symbols in 1.8.6</title><xi:include href="xml/api-index-1.8.6.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-8-5" role="1.8.5"><title>Index of new symbols in 1.8.5</title><xi:include href="xml/api-index-1.8.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-8-1" role="1.8.1"><title>Index of new symbols in 1.8.1</title><xi:include href="xml/api-index-1.8.1.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-8-0" role="1.8.0"><title>Index of new symbols in 1.8.0</title><xi:include href="xml/api-index-1.8.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-7-7" role="1.7.7"><title>Index of new symbols in 1.7.7</title><xi:include href="xml/api-index-1.7.7.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-7-5" role="1.7.5"><title>Index of new symbols in 1.7.5</title><xi:include href="xml/api-index-1.7.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-7-2" role="1.7.2"><title>Index of new symbols in 1.7.2</title><xi:include href="xml/api-index-1.7.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-6-0" role="1.6.0"><title>Index of new symbols in 1.6.0</title><xi:include href="xml/api-index-1.6.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-5-0" role="1.5.0"><title>Index of new symbols in 1.5.0</title><xi:include href="xml/api-index-1.5.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-4-3" role="1.4.3"><title>Index of new symbols in 1.4.3</title><xi:include href="xml/api-index-1.4.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-4-2" role="1.4.2"><title>Index of new symbols in 1.4.2</title><xi:include href="xml/api-index-1.4.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-4-0" role="1.4.0"><title>Index of new symbols in 1.4.0</title><xi:include href="xml/api-index-1.4.0.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-3-3" role="1.3.3"><title>Index of new symbols in 1.3.3</title><xi:include href="xml/api-index-1.3.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-2-3" role="1.2.3"><title>Index of new symbols in 1.2.3</title><xi:include href="xml/api-index-1.2.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-1-3" role="1.1.3"><title>Index of new symbols in 1.1.3</title><xi:include href="xml/api-index-1.1.3.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-1-2" role="1.1.2"><title>Index of new symbols in 1.1.2</title><xi:include href="xml/api-index-1.1.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-1-0-5" role="1.0.5"><title>Index of new symbols in 1.0.5</title><xi:include href="xml/api-index-1.0.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-42" role="0.9.42"><title>Index of new symbols in 0.9.42</title><xi:include href="xml/api-index-0.9.42.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-41" role="0.9.41"><title>Index of new symbols in 0.9.41</title><xi:include href="xml/api-index-0.9.41.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-39" role="0.9.39"><title>Index of new symbols in 0.9.39</title><xi:include href="xml/api-index-0.9.39.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-38" role="0.9.38"><title>Index of new symbols in 0.9.38</title><xi:include href="xml/api-index-0.9.38.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-33" role="0.9.33"><title>Index of new symbols in 0.9.33</title><xi:include href="xml/api-index-0.9.33.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-31" role="0.9.31"><title>Index of new symbols in 0.9.31</title><xi:include href="xml/api-index-0.9.31.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-30" role="0.9.30"><title>Index of new symbols in 0.9.30</title><xi:include href="xml/api-index-0.9.30.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-28" role="0.9.28"><title>Index of new symbols in 0.9.28</title><xi:include href="xml/api-index-0.9.28.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-26" role="0.9.26"><title>Index of new symbols in 0.9.26</title><xi:include href="xml/api-index-0.9.26.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-22" role="0.9.22"><title>Index of new symbols in 0.9.22</title><xi:include href="xml/api-index-0.9.22.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-21" role="0.9.21"><title>Index of new symbols in 0.9.21</title><xi:include href="xml/api-index-0.9.21.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-20" role="0.9.20"><title>Index of new symbols in 0.9.20</title><xi:include href="xml/api-index-0.9.20.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-11" role="0.9.11"><title>Index of new symbols in 0.9.11</title><xi:include href="xml/api-index-0.9.11.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-10" role="0.9.10"><title>Index of new symbols in 0.9.10</title><xi:include href="xml/api-index-0.9.10.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-8" role="0.9.8"><title>Index of new symbols in 0.9.8</title><xi:include href="xml/api-index-0.9.8.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-7" role="0.9.7"><title>Index of new symbols in 0.9.7</title><xi:include href="xml/api-index-0.9.7.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-5" role="0.9.5"><title>Index of new symbols in 0.9.5</title><xi:include href="xml/api-index-0.9.5.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-9-2" role="0.9.2"><title>Index of new symbols in 0.9.2</title><xi:include href="xml/api-index-0.9.2.xml"><xi:fallback /></xi:include></index>
|
||||
<index id="api-index-0-6-0" role="0.6.0"><title>Index of new symbols in 0.6.0</title><xi:include href="xml/api-index-0.6.0.xml"><xi:fallback /></xi:include></index>
|
||||
|
||||
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
|
||||
</part>
|
||||
|
||||
<note>
|
||||
<para>
|
||||
The current HarfBuzz codebase is stable
|
||||
The current HarfBuzz codebase is versioned 2.x.x and is stable
|
||||
and under active maintenance. This is what is used in latest
|
||||
versions of Firefox, GNOME, ChromeOS, Chrome, LibreOffice,
|
||||
XeTeX, Android, and KDE, among other places.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
<SECTION>
|
||||
<SUBSECTION Private>
|
||||
HB_H_IN
|
||||
HB_OT_H_IN
|
||||
|
@ -22,38 +21,35 @@ hb_aat_layout_has_tracking
|
|||
<SECTION>
|
||||
<FILE>hb-blob</FILE>
|
||||
hb_blob_create
|
||||
hb_blob_create_or_fail
|
||||
hb_blob_create_from_file
|
||||
hb_blob_create_from_file_or_fail
|
||||
hb_blob_create_sub_blob
|
||||
hb_blob_copy_writable_or_fail
|
||||
hb_blob_get_empty
|
||||
hb_blob_reference
|
||||
hb_blob_destroy
|
||||
hb_blob_set_user_data
|
||||
hb_blob_get_user_data
|
||||
hb_blob_make_immutable
|
||||
hb_blob_is_immutable
|
||||
hb_blob_get_data
|
||||
hb_blob_get_data_writable
|
||||
hb_blob_get_empty
|
||||
hb_blob_get_length
|
||||
hb_blob_get_user_data
|
||||
hb_blob_is_immutable
|
||||
hb_blob_make_immutable
|
||||
hb_blob_reference
|
||||
hb_blob_set_user_data
|
||||
hb_blob_t
|
||||
hb_memory_mode_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-buffer</FILE>
|
||||
HB_SEGMENT_PROPERTIES_DEFAULT
|
||||
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT
|
||||
hb_buffer_create
|
||||
hb_buffer_allocation_successful
|
||||
hb_buffer_create_similar
|
||||
hb_buffer_get_empty
|
||||
hb_buffer_reference
|
||||
hb_buffer_get_empty
|
||||
hb_buffer_destroy
|
||||
hb_buffer_set_user_data
|
||||
hb_buffer_get_user_data
|
||||
hb_buffer_reset
|
||||
hb_buffer_clear_contents
|
||||
hb_buffer_pre_allocate
|
||||
hb_buffer_allocation_successful
|
||||
hb_buffer_add
|
||||
hb_buffer_add_codepoints
|
||||
hb_buffer_add_utf32
|
||||
|
@ -80,14 +76,13 @@ hb_buffer_get_segment_properties
|
|||
hb_buffer_guess_segment_properties
|
||||
hb_buffer_set_unicode_funcs
|
||||
hb_buffer_get_unicode_funcs
|
||||
hb_buffer_set_user_data
|
||||
hb_buffer_get_user_data
|
||||
hb_buffer_get_glyph_infos
|
||||
hb_glyph_info_get_glyph_flags
|
||||
hb_buffer_get_glyph_positions
|
||||
hb_buffer_has_positions
|
||||
hb_buffer_set_invisible_glyph
|
||||
hb_buffer_get_invisible_glyph
|
||||
hb_buffer_set_not_found_glyph
|
||||
hb_buffer_get_not_found_glyph
|
||||
hb_buffer_set_invisible_glyph
|
||||
hb_buffer_set_replacement_codepoint
|
||||
hb_buffer_get_replacement_codepoint
|
||||
hb_buffer_normalize_glyphs
|
||||
|
@ -104,13 +99,10 @@ hb_buffer_serialize_format_to_string
|
|||
hb_buffer_serialize_list_formats
|
||||
hb_segment_properties_equal
|
||||
hb_segment_properties_hash
|
||||
hb_segment_properties_overlay
|
||||
hb_buffer_diff
|
||||
hb_buffer_message_func_t
|
||||
hb_buffer_set_message_func
|
||||
HB_SEGMENT_PROPERTIES_DEFAULT
|
||||
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT
|
||||
hb_buffer_t
|
||||
hb_glyph_info_get_glyph_flags
|
||||
hb_glyph_info_t
|
||||
hb_glyph_flags_t
|
||||
hb_glyph_position_t
|
||||
|
@ -121,30 +113,22 @@ hb_segment_properties_t
|
|||
hb_buffer_serialize_format_t
|
||||
hb_buffer_serialize_flags_t
|
||||
hb_buffer_diff_flags_t
|
||||
hb_buffer_message_func_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-common</FILE>
|
||||
HB_TAG
|
||||
HB_UNTAG
|
||||
hb_tag_from_string
|
||||
hb_tag_to_string
|
||||
hb_direction_from_string
|
||||
hb_direction_to_string
|
||||
HB_DIRECTION_REVERSE
|
||||
HB_DIRECTION_IS_BACKWARD
|
||||
HB_DIRECTION_IS_FORWARD
|
||||
HB_DIRECTION_IS_HORIZONTAL
|
||||
HB_DIRECTION_IS_VALID
|
||||
HB_DIRECTION_IS_VERTICAL
|
||||
hb_script_from_iso15924_tag
|
||||
hb_script_to_iso15924_tag
|
||||
hb_script_from_string
|
||||
hb_script_to_iso15924_tag
|
||||
hb_script_get_horizontal_direction
|
||||
hb_language_from_string
|
||||
hb_language_to_string
|
||||
hb_language_get_default
|
||||
hb_language_matches
|
||||
hb_feature_from_string
|
||||
hb_feature_to_string
|
||||
hb_variation_from_string
|
||||
|
@ -161,9 +145,17 @@ hb_position_t
|
|||
hb_tag_t
|
||||
hb_script_t
|
||||
hb_user_data_key_t
|
||||
HB_TAG
|
||||
HB_TAG_NONE
|
||||
HB_TAG_MAX
|
||||
HB_TAG_MAX_SIGNED
|
||||
HB_UNTAG
|
||||
HB_DIRECTION_REVERSE
|
||||
HB_DIRECTION_IS_BACKWARD
|
||||
HB_DIRECTION_IS_FORWARD
|
||||
HB_DIRECTION_IS_HORIZONTAL
|
||||
HB_DIRECTION_IS_VALID
|
||||
HB_DIRECTION_IS_VERTICAL
|
||||
HB_LANGUAGE_INVALID
|
||||
HB_FEATURE_GLOBAL_END
|
||||
HB_FEATURE_GLOBAL_START
|
||||
|
@ -171,7 +163,6 @@ HB_FEATURE_GLOBAL_START
|
|||
HB_BEGIN_DECLS
|
||||
HB_END_DECLS
|
||||
hb_var_int_t
|
||||
hb_var_num_t
|
||||
int16_t
|
||||
int32_t
|
||||
int64_t
|
||||
|
@ -180,120 +171,12 @@ uint16_t
|
|||
uint32_t
|
||||
uint64_t
|
||||
uint8_t
|
||||
<SUBSECTION Private>
|
||||
HB_EXTERN
|
||||
HB_DEPRECATED
|
||||
HB_DEPRECATED_FOR
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-features</FILE>
|
||||
HB_HAS_CAIRO
|
||||
HB_HAS_CORETEXT
|
||||
HB_HAS_DIRECTWRITE
|
||||
HB_HAS_FREETYPE
|
||||
HB_HAS_GDI
|
||||
HB_HAS_GLIB
|
||||
HB_HAS_GOBJECT
|
||||
HB_HAS_GRAPHITE
|
||||
HB_HAS_ICU
|
||||
HB_HAS_UNISCRIBE
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-draw</FILE>
|
||||
hb_draw_funcs_create
|
||||
hb_draw_funcs_get_empty
|
||||
hb_draw_funcs_reference
|
||||
hb_draw_funcs_destroy
|
||||
hb_draw_funcs_set_user_data
|
||||
hb_draw_funcs_get_user_data
|
||||
hb_draw_funcs_make_immutable
|
||||
hb_draw_funcs_is_immutable
|
||||
hb_draw_move_to_func_t
|
||||
hb_draw_funcs_set_move_to_func
|
||||
hb_draw_line_to_func_t
|
||||
hb_draw_funcs_set_line_to_func
|
||||
hb_draw_quadratic_to_func_t
|
||||
hb_draw_funcs_set_quadratic_to_func
|
||||
hb_draw_cubic_to_func_t
|
||||
hb_draw_funcs_set_cubic_to_func
|
||||
hb_draw_close_path_func_t
|
||||
hb_draw_funcs_set_close_path_func
|
||||
hb_draw_move_to
|
||||
hb_draw_line_to
|
||||
hb_draw_quadratic_to
|
||||
hb_draw_cubic_to
|
||||
hb_draw_close_path
|
||||
HB_DRAW_STATE_DEFAULT
|
||||
hb_draw_funcs_t
|
||||
hb_draw_state_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-paint</FILE>
|
||||
hb_paint_funcs_t
|
||||
hb_paint_funcs_create
|
||||
hb_paint_funcs_get_empty
|
||||
hb_paint_funcs_reference
|
||||
hb_paint_funcs_destroy
|
||||
hb_paint_funcs_set_user_data
|
||||
hb_paint_funcs_get_user_data
|
||||
hb_paint_funcs_make_immutable
|
||||
hb_paint_funcs_is_immutable
|
||||
|
||||
hb_paint_push_transform_func_t
|
||||
hb_paint_funcs_set_push_transform_func
|
||||
hb_paint_pop_transform_func_t
|
||||
hb_paint_funcs_set_pop_transform_func
|
||||
hb_paint_push_clip_glyph_func_t
|
||||
hb_paint_funcs_set_push_clip_glyph_func
|
||||
hb_paint_push_clip_rectangle_func_t
|
||||
hb_paint_funcs_set_push_clip_rectangle_func
|
||||
hb_paint_pop_clip_func_t
|
||||
hb_paint_funcs_set_pop_clip_func
|
||||
hb_paint_color_func_t
|
||||
hb_paint_funcs_set_color_func
|
||||
HB_PAINT_IMAGE_FORMAT_PNG
|
||||
HB_PAINT_IMAGE_FORMAT_SVG
|
||||
HB_PAINT_IMAGE_FORMAT_BGRA
|
||||
hb_paint_image_func_t
|
||||
hb_paint_funcs_set_image_func
|
||||
hb_color_line_t
|
||||
hb_color_stop_t
|
||||
hb_color_line_get_color_stops_func_t
|
||||
hb_color_line_get_color_stops
|
||||
hb_paint_extend_t
|
||||
hb_color_line_get_extend_func_t
|
||||
hb_color_line_get_extend
|
||||
hb_paint_linear_gradient_func_t
|
||||
hb_paint_funcs_set_linear_gradient_func
|
||||
hb_paint_radial_gradient_func_t
|
||||
hb_paint_funcs_set_radial_gradient_func
|
||||
hb_paint_sweep_gradient_func_t
|
||||
hb_paint_funcs_set_sweep_gradient_func
|
||||
hb_paint_composite_mode_t
|
||||
hb_paint_push_group_func_t
|
||||
hb_paint_funcs_set_push_group_func
|
||||
hb_paint_pop_group_func_t
|
||||
hb_paint_funcs_set_pop_group_func
|
||||
hb_paint_custom_palette_color_func_t
|
||||
hb_paint_funcs_set_custom_palette_color_func
|
||||
|
||||
hb_paint_push_transform
|
||||
hb_paint_pop_transform
|
||||
hb_paint_push_clip_glyph
|
||||
hb_paint_push_clip_rectangle
|
||||
hb_paint_pop_clip
|
||||
hb_paint_color
|
||||
hb_paint_image
|
||||
hb_paint_linear_gradient
|
||||
hb_paint_radial_gradient
|
||||
hb_paint_sweep_gradient
|
||||
hb_paint_push_group
|
||||
hb_paint_pop_group
|
||||
hb_paint_custom_palette_color
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-deprecated</FILE>
|
||||
HB_BUFFER_FLAGS_DEFAULT
|
||||
|
@ -302,7 +185,6 @@ HB_SCRIPT_CANADIAN_ABORIGINAL
|
|||
hb_font_funcs_set_glyph_func
|
||||
hb_font_get_glyph_func_t
|
||||
HB_MATH_GLYPH_PART_FLAG_EXTENDER
|
||||
HB_OT_MATH_SCRIPT
|
||||
hb_ot_layout_table_choose_script
|
||||
hb_ot_layout_table_find_script
|
||||
hb_ot_tag_from_language
|
||||
|
@ -311,6 +193,7 @@ HB_OT_VAR_NO_AXIS_INDEX
|
|||
hb_ot_var_axis_t
|
||||
hb_ot_var_find_axis
|
||||
hb_ot_var_get_axes
|
||||
hb_set_invert
|
||||
hb_unicode_eastasian_width_func_t
|
||||
hb_unicode_eastasian_width
|
||||
hb_unicode_funcs_set_eastasian_width_func
|
||||
|
@ -338,6 +221,8 @@ hb_coretext_font_get_ct_font
|
|||
<FILE>hb-directwrite</FILE>
|
||||
hb_directwrite_face_create
|
||||
hb_directwrite_face_get_font_face
|
||||
<SUBSECTION Private>
|
||||
hb_directwrite_shape_experimental_width
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -346,29 +231,27 @@ hb_face_count
|
|||
hb_face_t
|
||||
hb_face_create
|
||||
hb_face_create_for_tables
|
||||
hb_face_get_empty
|
||||
hb_face_reference
|
||||
hb_face_destroy
|
||||
hb_face_set_user_data
|
||||
hb_face_get_user_data
|
||||
hb_face_make_immutable
|
||||
hb_face_is_immutable
|
||||
hb_face_get_empty
|
||||
hb_face_get_table_tags
|
||||
hb_face_set_glyph_count
|
||||
hb_face_get_glyph_count
|
||||
hb_face_set_index
|
||||
hb_face_get_index
|
||||
hb_face_set_upem
|
||||
hb_face_get_upem
|
||||
hb_face_get_user_data
|
||||
hb_face_is_immutable
|
||||
hb_face_make_immutable
|
||||
hb_face_reference
|
||||
hb_face_reference_blob
|
||||
hb_face_reference_table
|
||||
hb_face_set_glyph_count
|
||||
hb_face_set_index
|
||||
hb_face_set_upem
|
||||
hb_face_set_user_data
|
||||
hb_face_collect_unicodes
|
||||
hb_face_collect_nominal_glyph_mapping
|
||||
hb_face_collect_variation_selectors
|
||||
hb_face_collect_variation_unicodes
|
||||
hb_face_builder_create
|
||||
hb_face_builder_add_table
|
||||
hb_face_builder_sort_tables
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -376,126 +259,110 @@ hb_face_builder_sort_tables
|
|||
hb_font_add_glyph_origin_for_direction
|
||||
hb_font_create
|
||||
hb_font_create_sub_font
|
||||
hb_font_get_empty
|
||||
hb_font_reference
|
||||
hb_font_destroy
|
||||
hb_font_set_user_data
|
||||
hb_font_get_user_data
|
||||
hb_font_make_immutable
|
||||
hb_font_is_immutable
|
||||
hb_font_set_face
|
||||
hb_font_funcs_create
|
||||
hb_font_funcs_destroy
|
||||
hb_font_funcs_get_empty
|
||||
hb_font_funcs_get_user_data
|
||||
hb_font_funcs_is_immutable
|
||||
hb_font_funcs_make_immutable
|
||||
hb_font_funcs_reference
|
||||
hb_font_funcs_set_glyph_contour_point_func
|
||||
hb_font_funcs_set_glyph_extents_func
|
||||
hb_font_funcs_set_glyph_from_name_func
|
||||
hb_font_funcs_set_glyph_h_advance_func
|
||||
hb_font_funcs_set_glyph_h_advances_func
|
||||
hb_font_funcs_set_glyph_h_kerning_func
|
||||
hb_font_funcs_set_glyph_h_origin_func
|
||||
hb_font_funcs_set_glyph_name_func
|
||||
hb_font_funcs_set_glyph_v_advance_func
|
||||
hb_font_funcs_set_glyph_v_advances_func
|
||||
hb_font_funcs_set_glyph_v_origin_func
|
||||
hb_font_funcs_set_nominal_glyph_func
|
||||
hb_font_funcs_set_nominal_glyphs_func
|
||||
hb_font_funcs_set_user_data
|
||||
hb_font_funcs_set_variation_glyph_func
|
||||
hb_font_funcs_t
|
||||
hb_font_get_empty
|
||||
hb_font_get_face
|
||||
hb_font_get_glyph
|
||||
hb_font_get_glyph_advance_for_direction
|
||||
hb_font_get_glyph_advance_func_t
|
||||
hb_font_get_glyph_advances_for_direction
|
||||
hb_font_get_glyph_advances_func_t
|
||||
hb_font_get_glyph_contour_point
|
||||
hb_font_get_glyph_contour_point_for_origin
|
||||
hb_font_get_glyph_contour_point_func_t
|
||||
hb_font_get_glyph_extents
|
||||
hb_font_get_glyph_extents_for_origin
|
||||
hb_font_get_glyph_extents_func_t
|
||||
hb_font_get_glyph_from_name
|
||||
hb_font_get_glyph_from_name_func_t
|
||||
hb_font_get_glyph_h_advance
|
||||
hb_font_get_glyph_v_advance
|
||||
hb_font_get_glyph_h_advance_func_t
|
||||
hb_font_get_glyph_h_advances
|
||||
hb_font_get_glyph_v_advances
|
||||
hb_font_get_glyph_h_advances_func_t
|
||||
hb_font_get_glyph_h_kerning
|
||||
hb_font_get_glyph_kerning_for_direction
|
||||
hb_font_get_glyph_h_kerning_func_t
|
||||
hb_font_get_glyph_h_origin
|
||||
hb_font_get_glyph_v_origin
|
||||
hb_font_get_glyph_origin_for_direction
|
||||
hb_font_get_glyph_h_origin_func_t
|
||||
hb_font_get_glyph_kerning_for_direction
|
||||
hb_font_get_glyph_kerning_func_t
|
||||
hb_font_get_glyph_name
|
||||
hb_font_get_glyph_shape
|
||||
hb_font_draw_glyph
|
||||
hb_font_paint_glyph
|
||||
hb_font_get_glyph_name_func_t
|
||||
hb_font_get_glyph_origin_for_direction
|
||||
hb_font_get_glyph_origin_func_t
|
||||
hb_font_get_glyph_v_advance
|
||||
hb_font_get_glyph_v_advance_func_t
|
||||
hb_font_get_glyph_v_advances
|
||||
hb_font_get_glyph_v_advances_func_t
|
||||
hb_font_get_glyph_v_origin
|
||||
hb_font_get_glyph_v_origin_func_t
|
||||
hb_font_get_nominal_glyph
|
||||
hb_font_get_nominal_glyph_func_t
|
||||
hb_font_get_nominal_glyphs
|
||||
hb_font_get_variation_glyph
|
||||
hb_font_set_parent
|
||||
hb_font_get_nominal_glyphs_func_t
|
||||
hb_font_get_parent
|
||||
hb_font_set_ppem
|
||||
hb_font_get_ppem
|
||||
hb_font_set_ptem
|
||||
hb_font_get_ptem
|
||||
hb_font_set_scale
|
||||
hb_font_get_scale
|
||||
hb_font_get_synthetic_bold
|
||||
hb_font_set_synthetic_bold
|
||||
hb_font_set_synthetic_slant
|
||||
hb_font_get_synthetic_slant
|
||||
hb_font_set_variations
|
||||
hb_font_set_variation
|
||||
HB_FONT_NO_VAR_NAMED_INSTANCE
|
||||
hb_font_set_var_named_instance
|
||||
hb_font_get_var_named_instance
|
||||
hb_font_set_var_coords_design
|
||||
hb_font_get_var_coords_design
|
||||
hb_font_set_var_coords_normalized
|
||||
hb_font_get_user_data
|
||||
hb_font_get_variation_glyph
|
||||
hb_font_get_variation_glyph_func_t
|
||||
hb_font_get_var_coords_normalized
|
||||
hb_font_glyph_from_string
|
||||
hb_font_glyph_to_string
|
||||
hb_font_get_serial
|
||||
hb_font_changed
|
||||
hb_font_is_immutable
|
||||
hb_font_make_immutable
|
||||
hb_font_reference
|
||||
hb_font_set_face
|
||||
hb_font_set_funcs
|
||||
hb_font_set_funcs_data
|
||||
hb_font_set_parent
|
||||
hb_font_set_ppem
|
||||
hb_font_set_ptem
|
||||
hb_font_set_scale
|
||||
hb_font_set_user_data
|
||||
hb_font_set_variations
|
||||
hb_font_set_var_coords_design
|
||||
hb_font_set_var_coords_normalized
|
||||
hb_font_set_var_named_instance
|
||||
hb_font_subtract_glyph_origin_for_direction
|
||||
hb_font_funcs_create
|
||||
hb_font_funcs_get_empty
|
||||
hb_font_funcs_reference
|
||||
hb_font_funcs_destroy
|
||||
hb_font_funcs_set_user_data
|
||||
hb_font_funcs_get_user_data
|
||||
hb_font_funcs_make_immutable
|
||||
hb_font_funcs_is_immutable
|
||||
hb_font_get_glyph_contour_point_func_t
|
||||
hb_font_funcs_set_glyph_contour_point_func
|
||||
hb_font_get_glyph_extents_func_t
|
||||
hb_font_funcs_set_glyph_extents_func
|
||||
hb_font_get_glyph_from_name_func_t
|
||||
hb_font_funcs_set_glyph_from_name_func
|
||||
hb_font_get_glyph_advance_func_t
|
||||
hb_font_get_glyph_h_advance_func_t
|
||||
hb_font_funcs_set_glyph_h_advance_func
|
||||
hb_font_get_glyph_v_advance_func_t
|
||||
hb_font_funcs_set_glyph_v_advance_func
|
||||
hb_font_get_glyph_advances_func_t
|
||||
hb_font_get_glyph_h_advances_func_t
|
||||
hb_font_funcs_set_glyph_h_advances_func
|
||||
hb_font_get_glyph_v_advances_func_t
|
||||
hb_font_funcs_set_glyph_v_advances_func
|
||||
hb_font_get_glyph_kerning_func_t
|
||||
hb_font_get_glyph_h_kerning_func_t
|
||||
hb_font_funcs_set_glyph_h_kerning_func
|
||||
hb_font_get_glyph_origin_func_t
|
||||
hb_font_get_glyph_h_origin_func_t
|
||||
hb_font_funcs_set_glyph_h_origin_func
|
||||
hb_font_get_glyph_v_origin_func_t
|
||||
hb_font_funcs_set_glyph_v_origin_func
|
||||
hb_font_get_glyph_name_func_t
|
||||
hb_font_funcs_set_glyph_name_func
|
||||
hb_font_get_glyph_shape_func_t
|
||||
hb_font_funcs_set_glyph_shape_func
|
||||
hb_font_draw_glyph_func_t
|
||||
hb_font_funcs_set_draw_glyph_func
|
||||
hb_font_paint_glyph_func_t
|
||||
hb_font_funcs_set_paint_glyph_func
|
||||
hb_font_get_nominal_glyph_func_t
|
||||
hb_font_funcs_set_nominal_glyph_func
|
||||
hb_font_get_nominal_glyphs_func_t
|
||||
hb_font_funcs_set_nominal_glyphs_func
|
||||
hb_font_get_variation_glyph_func_t
|
||||
hb_font_funcs_set_variation_glyph_func
|
||||
hb_font_funcs_t
|
||||
hb_font_t
|
||||
hb_reference_table_func_t
|
||||
hb_font_funcs_set_font_h_extents_func
|
||||
hb_font_funcs_set_font_v_extents_func
|
||||
hb_font_get_extents_for_direction
|
||||
hb_font_get_font_extents_func_t
|
||||
hb_font_get_font_h_extents_func_t
|
||||
hb_font_funcs_set_font_h_extents_func
|
||||
hb_font_get_font_v_extents_func_t
|
||||
hb_font_funcs_set_font_v_extents_func
|
||||
hb_font_get_h_extents
|
||||
hb_font_get_v_extents
|
||||
hb_font_get_extents_for_direction
|
||||
hb_font_extents_t
|
||||
hb_glyph_extents_t
|
||||
<SUBSECTION Private>
|
||||
hb_font_get_var_coords_design
|
||||
hb_font_draw_glyph
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -512,7 +379,6 @@ hb_ft_font_unlock_face
|
|||
hb_ft_font_set_load_flags
|
||||
hb_ft_font_get_load_flags
|
||||
hb_ft_font_set_funcs
|
||||
hb_ft_hb_font_changed
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -544,33 +410,27 @@ hb_icu_script_to_script
|
|||
|
||||
<SECTION>
|
||||
<FILE>hb-map</FILE>
|
||||
hb_map_create
|
||||
hb_map_allocation_successful
|
||||
hb_map_copy
|
||||
hb_map_clear
|
||||
hb_map_get_empty
|
||||
hb_map_reference
|
||||
hb_map_destroy
|
||||
hb_map_set_user_data
|
||||
hb_map_get_user_data
|
||||
hb_map_set
|
||||
hb_map_get
|
||||
hb_map_del
|
||||
hb_map_has
|
||||
hb_map_get_population
|
||||
hb_map_is_empty
|
||||
hb_map_is_equal
|
||||
hb_map_hash
|
||||
hb_map_update
|
||||
hb_map_next
|
||||
hb_map_keys
|
||||
hb_map_values
|
||||
HB_MAP_VALUE_INVALID
|
||||
hb_map_allocation_successful
|
||||
hb_map_clear
|
||||
hb_map_create
|
||||
hb_map_del
|
||||
hb_map_destroy
|
||||
hb_map_get
|
||||
hb_map_get_empty
|
||||
hb_map_get_population
|
||||
hb_map_get_user_data
|
||||
hb_map_has
|
||||
hb_map_is_empty
|
||||
hb_map_reference
|
||||
hb_map_set
|
||||
hb_map_set_user_data
|
||||
hb_map_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-color</FILE>
|
||||
hb_color_t
|
||||
HB_COLOR
|
||||
hb_color_get_alpha
|
||||
hb_color_get_blue
|
||||
|
@ -580,19 +440,16 @@ hb_ot_color_glyph_get_layers
|
|||
hb_ot_color_glyph_reference_png
|
||||
hb_ot_color_glyph_reference_svg
|
||||
hb_ot_color_has_layers
|
||||
hb_ot_color_has_paint
|
||||
hb_ot_color_glyph_has_paint
|
||||
hb_ot_color_has_palettes
|
||||
hb_ot_color_has_png
|
||||
hb_ot_color_has_svg
|
||||
hb_ot_color_layer_t
|
||||
hb_ot_color_palette_color_get_name_id
|
||||
hb_ot_color_palette_flags_t
|
||||
hb_ot_color_palette_get_colors
|
||||
hb_ot_color_palette_get_count
|
||||
hb_ot_color_palette_get_flags
|
||||
hb_ot_color_palette_get_name_id
|
||||
hb_color_t
|
||||
hb_ot_color_layer_t
|
||||
hb_ot_color_palette_flags_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -602,63 +459,25 @@ hb_ot_font_set_funcs
|
|||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-name</FILE>
|
||||
hb_ot_name_id_t
|
||||
HB_OT_NAME_ID_INVALID
|
||||
hb_ot_name_entry_t
|
||||
hb_ot_name_list_names
|
||||
hb_ot_name_get_utf16
|
||||
hb_ot_name_get_utf32
|
||||
hb_ot_name_get_utf8
|
||||
hb_ot_name_id_t
|
||||
hb_ot_name_id_predefined_t
|
||||
hb_ot_name_entry_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-layout</FILE>
|
||||
hb_ot_tag_to_language
|
||||
hb_ot_tag_to_script
|
||||
hb_ot_tags_from_script_and_language
|
||||
hb_ot_tags_to_script_and_language
|
||||
hb_ot_layout_collect_lookups
|
||||
hb_ot_layout_collect_features
|
||||
hb_ot_layout_feature_get_characters
|
||||
hb_ot_layout_feature_get_lookups
|
||||
hb_ot_layout_feature_get_name_ids
|
||||
hb_ot_layout_feature_with_variations_get_lookups
|
||||
hb_ot_layout_get_attach_points
|
||||
hb_ot_layout_get_horizontal_baseline_tag_for_script
|
||||
hb_ot_layout_get_baseline
|
||||
hb_ot_layout_get_baseline_with_fallback
|
||||
hb_ot_layout_get_glyph_class
|
||||
hb_ot_layout_get_glyphs_in_class
|
||||
hb_ot_layout_get_ligature_carets
|
||||
hb_ot_layout_get_size_params
|
||||
hb_ot_layout_has_glyph_classes
|
||||
hb_ot_layout_has_positioning
|
||||
hb_ot_layout_has_substitution
|
||||
hb_ot_layout_language_find_feature
|
||||
hb_ot_layout_language_get_feature_indexes
|
||||
hb_ot_layout_language_get_feature_tags
|
||||
hb_ot_layout_language_get_required_feature
|
||||
hb_ot_layout_lookup_collect_glyphs
|
||||
hb_ot_layout_lookup_get_glyph_alternates
|
||||
hb_ot_layout_lookup_get_optical_bound
|
||||
hb_ot_layout_lookup_substitute_closure
|
||||
hb_ot_layout_lookups_substitute_closure
|
||||
hb_ot_layout_lookup_would_substitute
|
||||
hb_ot_layout_script_find_language
|
||||
hb_ot_layout_script_get_language_tags
|
||||
hb_ot_layout_script_select_language
|
||||
hb_ot_layout_script_select_language2
|
||||
hb_ot_layout_table_find_feature_variations
|
||||
hb_ot_layout_table_get_feature_tags
|
||||
hb_ot_layout_table_get_script_tags
|
||||
hb_ot_layout_table_get_lookup_count
|
||||
hb_ot_layout_table_select_script
|
||||
hb_ot_shape_plan_collect_lookups
|
||||
hb_ot_layout_language_get_required_feature_index
|
||||
HB_OT_MAX_TAGS_PER_LANGUAGE
|
||||
HB_OT_MAX_TAGS_PER_SCRIPT
|
||||
HB_OT_TAG_DEFAULT_LANGUAGE
|
||||
HB_OT_TAG_DEFAULT_SCRIPT
|
||||
hb_ot_tag_to_language
|
||||
hb_ot_tag_to_script
|
||||
hb_ot_tags_from_script_and_language
|
||||
hb_ot_tags_to_script_and_language
|
||||
HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX
|
||||
HB_OT_LAYOUT_NO_FEATURE_INDEX
|
||||
HB_OT_LAYOUT_NO_SCRIPT_INDEX
|
||||
|
@ -669,46 +488,83 @@ HB_OT_TAG_GPOS
|
|||
HB_OT_TAG_GSUB
|
||||
HB_OT_TAG_JSTF
|
||||
hb_ot_layout_baseline_tag_t
|
||||
hb_ot_layout_collect_lookups
|
||||
hb_ot_layout_collect_features
|
||||
hb_ot_layout_feature_get_characters
|
||||
hb_ot_layout_feature_get_lookups
|
||||
hb_ot_layout_feature_get_name_ids
|
||||
hb_ot_layout_feature_with_variations_get_lookups
|
||||
hb_ot_layout_get_attach_points
|
||||
hb_ot_layout_get_baseline
|
||||
hb_ot_layout_get_glyph_class
|
||||
hb_ot_layout_get_glyphs_in_class
|
||||
hb_ot_layout_get_ligature_carets
|
||||
hb_ot_layout_get_size_params
|
||||
hb_ot_layout_glyph_class_t
|
||||
hb_ot_layout_has_glyph_classes
|
||||
hb_ot_layout_has_positioning
|
||||
hb_ot_layout_has_substitution
|
||||
hb_ot_layout_language_find_feature
|
||||
hb_ot_layout_language_get_feature_indexes
|
||||
hb_ot_layout_language_get_feature_tags
|
||||
hb_ot_layout_language_get_required_feature
|
||||
hb_ot_layout_lookup_collect_glyphs
|
||||
hb_ot_layout_lookup_get_glyph_alternates
|
||||
hb_ot_layout_lookup_substitute_closure
|
||||
hb_ot_layout_lookups_substitute_closure
|
||||
hb_ot_layout_lookup_would_substitute
|
||||
hb_ot_layout_script_find_language
|
||||
hb_ot_layout_script_get_language_tags
|
||||
hb_ot_layout_script_select_language
|
||||
hb_ot_layout_table_find_feature_variations
|
||||
hb_ot_layout_table_get_feature_tags
|
||||
hb_ot_layout_table_get_script_tags
|
||||
hb_ot_layout_table_get_lookup_count
|
||||
hb_ot_layout_table_select_script
|
||||
hb_ot_shape_plan_collect_lookups
|
||||
hb_ot_layout_language_get_required_feature_index
|
||||
<SUBSECTION Private>
|
||||
Xhb_ot_layout_lookup_enumerate_sequences
|
||||
Xhb_ot_layout_lookup_position
|
||||
Xhb_ot_layout_lookup_substitute
|
||||
hb_ot_layout_glyph_sequence_t
|
||||
hb_ot_layout_glyph_sequence_func_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-math</FILE>
|
||||
HB_OT_TAG_MATH
|
||||
HB_OT_MATH_SCRIPT
|
||||
hb_ot_math_constant_t
|
||||
hb_ot_math_kern_t
|
||||
hb_ot_math_glyph_variant_t
|
||||
hb_ot_math_glyph_part_flags_t
|
||||
hb_ot_math_glyph_part_t
|
||||
hb_ot_math_has_data
|
||||
hb_ot_math_get_constant
|
||||
hb_ot_math_get_glyph_italics_correction
|
||||
hb_ot_math_get_glyph_top_accent_attachment
|
||||
hb_ot_math_get_glyph_kerning
|
||||
hb_ot_math_get_glyph_kernings
|
||||
hb_ot_math_is_glyph_extended_shape
|
||||
hb_ot_math_get_glyph_variants
|
||||
hb_ot_math_get_min_connector_overlap
|
||||
hb_ot_math_get_glyph_assembly
|
||||
HB_OT_TAG_MATH
|
||||
HB_OT_TAG_MATH_SCRIPT
|
||||
hb_ot_math_constant_t
|
||||
hb_ot_math_kern_t
|
||||
hb_ot_math_kern_entry_t
|
||||
hb_ot_math_glyph_variant_t
|
||||
hb_ot_math_glyph_part_flags_t
|
||||
hb_ot_math_glyph_part_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-meta</FILE>
|
||||
hb_ot_meta_tag_t
|
||||
hb_ot_meta_get_entry_tags
|
||||
hb_ot_meta_reference_entry
|
||||
hb_ot_meta_tag_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-metrics</FILE>
|
||||
hb_ot_metrics_tag_t
|
||||
hb_ot_metrics_get_position
|
||||
hb_ot_metrics_get_position_with_fallback
|
||||
hb_ot_metrics_get_variation
|
||||
hb_ot_metrics_get_x_variation
|
||||
hb_ot_metrics_get_y_variation
|
||||
hb_ot_metrics_tag_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -718,7 +574,14 @@ hb_ot_shape_glyphs_closure
|
|||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-var</FILE>
|
||||
HB_OT_TAG_VAR_AXIS_ITALIC
|
||||
HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE
|
||||
HB_OT_TAG_VAR_AXIS_SLANT
|
||||
HB_OT_TAG_VAR_AXIS_WEIGHT
|
||||
HB_OT_TAG_VAR_AXIS_WIDTH
|
||||
hb_ot_var_has_data
|
||||
hb_ot_var_axis_flags_t
|
||||
hb_ot_var_axis_info_t
|
||||
hb_ot_var_find_axis_info
|
||||
hb_ot_var_get_axis_count
|
||||
hb_ot_var_get_axis_infos
|
||||
|
@ -728,60 +591,46 @@ hb_ot_var_named_instance_get_postscript_name_id
|
|||
hb_ot_var_named_instance_get_design_coords
|
||||
hb_ot_var_normalize_variations
|
||||
hb_ot_var_normalize_coords
|
||||
HB_OT_TAG_VAR_AXIS_ITALIC
|
||||
HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE
|
||||
HB_OT_TAG_VAR_AXIS_SLANT
|
||||
HB_OT_TAG_VAR_AXIS_WEIGHT
|
||||
HB_OT_TAG_VAR_AXIS_WIDTH
|
||||
hb_ot_var_axis_flags_t
|
||||
hb_ot_var_axis_info_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-set</FILE>
|
||||
hb_set_create
|
||||
hb_set_allocation_successful
|
||||
hb_set_copy
|
||||
hb_set_get_empty
|
||||
hb_set_reference
|
||||
hb_set_destroy
|
||||
hb_set_set_user_data
|
||||
hb_set_get_user_data
|
||||
hb_set_clear
|
||||
hb_set_set
|
||||
hb_set_has
|
||||
HB_SET_VALUE_INVALID
|
||||
hb_set_add
|
||||
hb_set_add_range
|
||||
hb_set_add_sorted_array
|
||||
hb_set_allocation_successful
|
||||
hb_set_clear
|
||||
hb_set_create
|
||||
hb_set_del
|
||||
hb_set_del_range
|
||||
hb_set_destroy
|
||||
hb_set_get_empty
|
||||
hb_set_get_max
|
||||
hb_set_get_min
|
||||
hb_set_get_population
|
||||
hb_set_is_empty
|
||||
hb_set_hash
|
||||
hb_set_subtract
|
||||
hb_set_get_user_data
|
||||
hb_set_has
|
||||
hb_set_intersect
|
||||
hb_set_union
|
||||
hb_set_symmetric_difference
|
||||
hb_set_invert
|
||||
hb_set_is_inverted
|
||||
hb_set_is_empty
|
||||
hb_set_is_equal
|
||||
hb_set_is_subset
|
||||
hb_set_next
|
||||
hb_set_next_range
|
||||
hb_set_next_many
|
||||
hb_set_previous
|
||||
hb_set_previous_range
|
||||
HB_SET_VALUE_INVALID
|
||||
hb_set_reference
|
||||
hb_set_set
|
||||
hb_set_set_user_data
|
||||
hb_set_subtract
|
||||
hb_set_symmetric_difference
|
||||
hb_set_t
|
||||
hb_set_union
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-shape</FILE>
|
||||
hb_shape
|
||||
hb_shape_full
|
||||
hb_shape_justify
|
||||
hb_shape_list_shapers
|
||||
</SECTION>
|
||||
|
||||
|
@ -791,50 +640,50 @@ hb_shape_plan_create
|
|||
hb_shape_plan_create_cached
|
||||
hb_shape_plan_create2
|
||||
hb_shape_plan_create_cached2
|
||||
hb_shape_plan_get_empty
|
||||
hb_shape_plan_reference
|
||||
hb_shape_plan_destroy
|
||||
hb_shape_plan_set_user_data
|
||||
hb_shape_plan_get_user_data
|
||||
hb_shape_plan_execute
|
||||
hb_shape_plan_get_empty
|
||||
hb_shape_plan_get_shaper
|
||||
hb_shape_plan_get_user_data
|
||||
hb_shape_plan_reference
|
||||
hb_shape_plan_set_user_data
|
||||
hb_shape_plan_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-unicode</FILE>
|
||||
hb_unicode_general_category
|
||||
hb_unicode_combining_class
|
||||
hb_unicode_mirroring
|
||||
hb_unicode_script
|
||||
hb_unicode_compose
|
||||
hb_unicode_decompose
|
||||
hb_unicode_funcs_create
|
||||
hb_unicode_funcs_get_empty
|
||||
hb_unicode_funcs_reference
|
||||
hb_unicode_funcs_destroy
|
||||
hb_unicode_funcs_set_user_data
|
||||
hb_unicode_funcs_get_user_data
|
||||
hb_unicode_funcs_make_immutable
|
||||
hb_unicode_funcs_is_immutable
|
||||
hb_unicode_funcs_get_default
|
||||
hb_unicode_funcs_get_parent
|
||||
hb_unicode_general_category_func_t
|
||||
hb_unicode_funcs_set_general_category_func
|
||||
hb_unicode_combining_class_func_t
|
||||
hb_unicode_funcs_set_combining_class_func
|
||||
hb_unicode_mirroring_func_t
|
||||
hb_unicode_funcs_set_mirroring_func
|
||||
hb_unicode_script_func_t
|
||||
hb_unicode_funcs_set_script_func
|
||||
hb_unicode_compose_func_t
|
||||
hb_unicode_funcs_set_compose_func
|
||||
hb_unicode_decompose_func_t
|
||||
hb_unicode_funcs_set_decompose_func
|
||||
HB_UNICODE_MAX
|
||||
hb_unicode_combining_class
|
||||
hb_unicode_combining_class_func_t
|
||||
hb_unicode_combining_class_t
|
||||
hb_unicode_general_category_t
|
||||
hb_unicode_compose
|
||||
hb_unicode_compose_func_t
|
||||
hb_unicode_decompose
|
||||
hb_unicode_decompose_func_t
|
||||
hb_unicode_funcs_create
|
||||
hb_unicode_funcs_destroy
|
||||
hb_unicode_funcs_get_default
|
||||
hb_unicode_funcs_get_empty
|
||||
hb_unicode_funcs_get_parent
|
||||
hb_unicode_funcs_get_user_data
|
||||
hb_unicode_funcs_is_immutable
|
||||
hb_unicode_funcs_make_immutable
|
||||
hb_unicode_funcs_reference
|
||||
hb_unicode_funcs_set_combining_class_func
|
||||
hb_unicode_funcs_set_compose_func
|
||||
hb_unicode_funcs_set_decompose_func
|
||||
hb_unicode_funcs_set_general_category_func
|
||||
hb_unicode_funcs_set_mirroring_func
|
||||
hb_unicode_funcs_set_script_func
|
||||
hb_unicode_funcs_set_user_data
|
||||
hb_unicode_funcs_t
|
||||
hb_unicode_general_category
|
||||
hb_unicode_general_category_func_t
|
||||
hb_unicode_general_category_t
|
||||
hb_unicode_mirroring
|
||||
hb_unicode_mirroring_func_t
|
||||
hb_unicode_script
|
||||
hb_unicode_script_func_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -846,68 +695,11 @@ hb_uniscribe_font_get_logfontw
|
|||
<SECTION>
|
||||
<FILE>hb-version</FILE>
|
||||
HB_VERSION_ATLEAST
|
||||
hb_version
|
||||
hb_version_atleast
|
||||
hb_version_string
|
||||
HB_VERSION_MAJOR
|
||||
HB_VERSION_MICRO
|
||||
HB_VERSION_MINOR
|
||||
HB_VERSION_STRING
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-style</FILE>
|
||||
hb_style_tag_t
|
||||
hb_style_get_value
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-subset</FILE>
|
||||
hb_subset_input_create_or_fail
|
||||
hb_subset_input_reference
|
||||
hb_subset_input_destroy
|
||||
hb_subset_input_set_user_data
|
||||
hb_subset_input_get_user_data
|
||||
hb_subset_input_keep_everything
|
||||
hb_subset_input_set_flags
|
||||
hb_subset_input_get_flags
|
||||
hb_subset_input_unicode_set
|
||||
hb_subset_input_glyph_set
|
||||
hb_subset_input_set
|
||||
hb_subset_input_pin_axis_location
|
||||
hb_subset_input_pin_axis_to_default
|
||||
hb_subset_or_fail
|
||||
hb_subset_plan_create_or_fail
|
||||
hb_subset_plan_reference
|
||||
hb_subset_plan_destroy
|
||||
hb_subset_plan_set_user_data
|
||||
hb_subset_plan_get_user_data
|
||||
hb_subset_plan_execute_or_fail
|
||||
hb_subset_plan_unicode_to_old_glyph_mapping
|
||||
hb_subset_plan_new_to_old_glyph_mapping
|
||||
hb_subset_plan_old_to_new_glyph_mapping
|
||||
hb_subset_preprocess
|
||||
hb_subset_flags_t
|
||||
hb_subset_input_t
|
||||
hb_subset_sets_t
|
||||
hb_subset_plan_t
|
||||
<SUBSECTION Private>
|
||||
hb_link_t
|
||||
hb_object_t
|
||||
hb_subset_repack_or_fail
|
||||
hb_subset_input_override_name_table
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-cairo</FILE>
|
||||
hb_cairo_font_face_create_for_font
|
||||
hb_cairo_font_face_get_font
|
||||
hb_cairo_font_face_create_for_face
|
||||
hb_cairo_font_face_get_face
|
||||
hb_cairo_font_init_func_t
|
||||
hb_cairo_font_face_set_font_init_func
|
||||
hb_cairo_scaled_font_get_font
|
||||
hb_cairo_font_face_set_scale_factor
|
||||
hb_cairo_font_face_get_scale_factor
|
||||
hb_cairo_glyphs_from_buffer
|
||||
hb_version
|
||||
hb_version_atleast
|
||||
hb_version_string
|
||||
</SECTION>
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
if build_machine.system() == 'windows'
|
||||
message('Skipping gtk-doc while building on Windows')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
if not find_program('gtkdoc-scan', required: get_option('docs')).found()
|
||||
message('Not building documentation as gtk-doc was not found')
|
||||
subdir_done()
|
||||
|
@ -36,7 +41,6 @@ html_images = [
|
|||
]
|
||||
|
||||
ignore_headers = [
|
||||
'hb-features.h',
|
||||
'hb-gobject.h',
|
||||
'hb-gobject-enums.h',
|
||||
'hb-gobject-enums-tmp.h',
|
||||
|
@ -45,11 +49,11 @@ ignore_headers = [
|
|||
|
||||
gnome.gtkdoc('harfbuzz',
|
||||
main_sgml: 'harfbuzz-docs.xml',
|
||||
src_dir: [meson.current_source_dir() / '..' / 'src',
|
||||
meson.current_build_dir() / '..' / 'src',
|
||||
src_dir: [join_paths(meson.current_source_dir(), '../src'),
|
||||
join_paths(meson.current_build_dir(), '../src'),
|
||||
],
|
||||
scan_args: ['--deprecated-guards=HB_DISABLE_DEPRECATED',
|
||||
'--ignore-decorators=HB_EXTERN|HB_DEPRECATED|HB_DEPRECATED_FOR()',
|
||||
'--ignore-decorators=HB_EXTERN|HB_DEPRECATED',
|
||||
],
|
||||
mkdb_args: ['--source-suffixes=h,cc',
|
||||
'--xml-mode',
|
||||
|
@ -59,6 +63,4 @@ gnome.gtkdoc('harfbuzz',
|
|||
html_assets: html_images,
|
||||
ignore_headers: ignore_headers,
|
||||
dependencies: [libharfbuzz_dep],
|
||||
install: true,
|
||||
check: get_option('doc_tests'),
|
||||
)
|
||||
install: true)
|
||||
|
|
294
docs/repacker.md
294
docs/repacker.md
|
@ -1,294 +0,0 @@
|
|||
# Introduction
|
||||
|
||||
Several tables in the opentype format are formed internally by a graph of subtables. Parent node's
|
||||
reference their children through the use of positive offsets, which are typically 16 bits wide.
|
||||
Since offsets are always positive this forms a directed acyclic graph. For storage in the font file
|
||||
the graph must be given a topological ordering and then the subtables packed in serial according to
|
||||
that ordering. Since 16 bit offsets have a maximum value of 65,535 if the distance between a parent
|
||||
subtable and a child is more then 65,535 bytes then it's not possible for the offset to encode that
|
||||
edge.
|
||||
|
||||
For many fonts with complex layout rules (such as Arabic) it's not unusual for the tables containing
|
||||
layout rules ([GSUB/GPOS](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub)) to be
|
||||
larger than 65kb. As a result these types of fonts are susceptible to offset overflows when
|
||||
serializing to the binary font format.
|
||||
|
||||
Offset overflows can happen for a variety of reasons and require different strategies to resolve:
|
||||
* Simple overflows can often be resolved with a different topological ordering.
|
||||
* If a subtable has many parents this can result in the link from furthest parent(s)
|
||||
being at risk for overflows. In these cases it's possible to duplicate the shared subtable which
|
||||
allows it to be placed closer to it's parent.
|
||||
* If subtables exist which are themselves larger than 65kb it's not possible for any offsets to point
|
||||
past them. In these cases the subtable can usually be split into two smaller subtables to allow
|
||||
for more flexibility in the ordering.
|
||||
* In GSUB/GPOS overflows from Lookup subtables can be resolved by changing the Lookup to an extension
|
||||
lookup which uses a 32 bit offset instead of 16 bit offset.
|
||||
|
||||
In general there isn't a simple solution to produce an optimal topological ordering for a given graph.
|
||||
Finding an ordering which doesn't overflow is a NP hard problem. Existing solutions use heuristics
|
||||
which attempt a combination of the above strategies to attempt to find a non-overflowing configuration.
|
||||
|
||||
The harfbuzz subsetting library
|
||||
[includes a repacking algorithm](https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-repacker.hh)
|
||||
which is used to resolve offset overflows that are present in the subsetted tables it produces. This
|
||||
document provides a deep dive into how the harfbuzz repacking algorithm works.
|
||||
|
||||
Other implementations exist, such as in
|
||||
[fontTools](https://github.com/fonttools/fonttools/blob/7af43123d49c188fcef4e540fa94796b3b44e858/Lib/fontTools/ttLib/tables/otBase.py#L72), however these are not covered in this document.
|
||||
|
||||
# Foundations
|
||||
|
||||
There's four key pieces to the harfbuzz approach:
|
||||
|
||||
* Subtable Graph: a table's internal structure is abstracted out into a lightweight graph
|
||||
representation where each subtable is a node and each offset forms an edge. The nodes only need
|
||||
to know how many bytes the corresponding subtable occupies. This lightweight representation can
|
||||
be easily modified to test new ordering's and strategies as the repacking algorithm iterates.
|
||||
|
||||
* [Topological sorting algorithm](https://en.wikipedia.org/wiki/Topological_sorting): an algorithm
|
||||
which given a graph gives a linear sorting of the nodes such that all offsets will be positive.
|
||||
|
||||
* Overflow check: given a graph and a topological sorting it checks if there will be any overflows
|
||||
in any of the offsets. If there are overflows it returns a list of (parent, child) tuples that
|
||||
will overflow. Since the graph has information on the size of each subtable it's straightforward
|
||||
to calculate the final position of each subtable and then check if any offsets to it will
|
||||
overflow.
|
||||
|
||||
* Content Aware Preprocessing: if the overflow resolver is aware of the format of the underlying
|
||||
tables (eg. GSUB, GPOS) then in some cases preprocessing can be done to increase the chance of
|
||||
successfully packing the graph. For example for GSUB and GPOS we can preprocess the graph and
|
||||
promote lookups to extension lookups (upgrades a 16 bit offset to 32 bits) or split large lookup
|
||||
subtables into two or more pieces.
|
||||
|
||||
* Offset resolution strategies: given a particular occurrence of an overflow these strategies
|
||||
modify the graph to attempt to resolve the overflow.
|
||||
|
||||
# High Level Algorithm
|
||||
|
||||
```
|
||||
def repack(graph):
|
||||
graph.topological_sort()
|
||||
|
||||
if (graph.will_overflow())
|
||||
preprocess(graph)
|
||||
assign_spaces(graph)
|
||||
graph.topological_sort()
|
||||
|
||||
while (overflows = graph.will_overflow()):
|
||||
for overflow in overflows:
|
||||
apply_offset_resolution_strategy (overflow, graph)
|
||||
graph.topological_sort()
|
||||
```
|
||||
|
||||
The actual code for this processing loop can be found in the function hb_resolve_overflows () of
|
||||
[hb-repacker.hh](https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-repacker.hh).
|
||||
|
||||
# Topological Sorting Algorithms
|
||||
|
||||
The harfbuzz repacker uses two different algorithms for topological sorting:
|
||||
* [Kahn's Algorithm](https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm)
|
||||
* Sorting by shortest distance
|
||||
|
||||
Kahn's algorithm is approximately twice as fast as the shortest distance sort so that is attempted
|
||||
first (only on the first topological sort). If it fails to eliminate overflows then shortest distance
|
||||
sort will be used for all subsequent topological sorting operations.
|
||||
|
||||
## Shortest Distance Sort
|
||||
|
||||
This algorithm orders the nodes based on total distance to each node. Nodes with a shorter distance
|
||||
are ordered first.
|
||||
|
||||
The "weight" of an edge is the sum of the size of the sub-table being pointed to plus 2^16 for a 16 bit
|
||||
offset and 2^32 for a 32 bit offset.
|
||||
|
||||
The distance of a node is the sum of all weights along the shortest path from the root to that node
|
||||
plus a priority modifier (used to change where nodes are placed by moving increasing or
|
||||
decreasing the effective distance). Ties between nodes with the same distance are broken based
|
||||
on the order of the offset in the sub table bytes.
|
||||
|
||||
The shortest distance to each node is determined using
|
||||
[Djikstra's algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm). Then the topological
|
||||
ordering is produce by applying a modified version of Kahn's algorithm that uses a priority queue
|
||||
based on the shortest distance to each node.
|
||||
|
||||
## Optimizing the Sorting
|
||||
|
||||
The topological sorting operation is the core of the repacker and is run on each iteration so it needs
|
||||
to be as fast as possible. There's a few things that are done to speed up subsequent sorting
|
||||
operations:
|
||||
|
||||
* The number of incoming edges to each node is cached. This is required by the Kahn's algorithm
|
||||
portion of both sorts. Where possible when the graph is modified we manually update the cached
|
||||
edge counts of affected nodes.
|
||||
|
||||
* The distance to each node is cached. Where possible when the graph is modified we manually update
|
||||
the cached distances of any affected nodes.
|
||||
|
||||
Caching these values allows the repacker to avoid recalculating them for the full graph on each
|
||||
iteration.
|
||||
|
||||
The other important factor to speed is a fast priority queue which is a core datastructure to
|
||||
the topological sorting algorithm. Currently a basic heap based queue is used. Heap based queue's
|
||||
don't support fast priority decreases, but that can be worked around by just adding redundant entries
|
||||
to the priority queue and filtering the older ones out when poppping off entries. This is based
|
||||
on the recommendations in
|
||||
[a study of the practical performance of priority queues in Dijkstra's algorithm](https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf)
|
||||
|
||||
## Special Handling of 32 bit Offsets
|
||||
|
||||
If a graph contains multiple 32 bit offsets then the shortest distance sorting will be likely be
|
||||
suboptimal. For example consider the case where a graph contains two 32 bit offsets that each point
|
||||
to a subgraph which are not connected to each other. The shortest distance sort will interleave the
|
||||
subtables of the two subgraphs, potentially resulting in overflows. Since each of these subgraphs are
|
||||
independent of each other, and 32 bit offsets can point extremely long distances a better strategy is
|
||||
to pack the first subgraph in it's entirety and then have the second subgraph packed after with the 32
|
||||
bit offset pointing over the first subgraph. For example given the graph:
|
||||
|
||||
|
||||
```
|
||||
a--- b -- d -- f
|
||||
\
|
||||
\_ c -- e -- g
|
||||
```
|
||||
|
||||
Where the links from a to b and a to c are 32 bit offsets, the shortest distance sort would be:
|
||||
|
||||
```
|
||||
a, b, c, d, e, f, g
|
||||
|
||||
```
|
||||
|
||||
If nodes d and e have a combined size greater than 65kb then the offset from d to f will overflow.
|
||||
A better ordering is:
|
||||
|
||||
```
|
||||
a, b, d, f, c, e, g
|
||||
```
|
||||
|
||||
The ability for 32 bit offsets to point long distances is utilized to jump over the subgraph of
|
||||
b which gives the remaining 16 bit offsets a better chance of not overflowing.
|
||||
|
||||
The above is an ideal situation where the subgraphs are disconnected from each other, in practice
|
||||
this is often not this case. So this idea can be generalized as follows:
|
||||
|
||||
If there is a subgraph that is only reachable from one or more 32 bit offsets, then:
|
||||
* That subgraph can be treated as an independent unit and all nodes of the subgraph packed in isolation
|
||||
from the rest of the graph.
|
||||
* In a table that occupies less than 4gb of space (in practice all fonts), that packed independent
|
||||
subgraph can be placed anywhere after the parent nodes without overflowing the 32 bit offsets from
|
||||
the parent nodes.
|
||||
|
||||
The sorting algorithm incorporates this via a "space" modifier that can be applied to nodes in the
|
||||
graph. By default all nodes are treated as being in space zero. If a node is given a non-zero space, n,
|
||||
then the computed distance to the node will be modified by adding `n * 2^32`. This will cause that
|
||||
node and it's descendants to be packed between all nodes in space n-1 and space n+1. Resulting in a
|
||||
topological sort like:
|
||||
|
||||
```
|
||||
| space 0 subtables | space 1 subtables | .... | space n subtables |
|
||||
```
|
||||
|
||||
The assign_spaces() step in the high level algorithm is responsible for identifying independent
|
||||
subgraphs and assigning unique spaces to each one. More information on the space assignment can be
|
||||
found in the next section.
|
||||
|
||||
# Graph Preprocessing
|
||||
|
||||
For certain table types we can preprocess and modify the graph structure to reduce the occurences
|
||||
of overflows. Currently the repacker implements preprocessing only for GPOS and GSUB tables.
|
||||
|
||||
## GSUB/GPOS Table Splitting
|
||||
|
||||
The GSUB/GPOS preprocessor scans each lookup subtable and determines if the subtable's children are
|
||||
so large that no overflow resolution is possible (for example a single subtable that exceeds 65kb
|
||||
cannot be pointed over). When such cases are detected table splitting is invoked:
|
||||
|
||||
* The subtable is first analyzed to determine the smallest number of split points that will allow
|
||||
for successful offset overflow resolution.
|
||||
|
||||
* Then the subtable in the graph representation is modified to actually perform the split at the
|
||||
previously computed split points. At a high level splits are done by inserting new subtables
|
||||
which contain a subset of the data of the original subtable and then shrinking the original subtable.
|
||||
|
||||
Table splitting must be aware of the underlying format of each subtable type and thus needs custom
|
||||
code for each subtable type. Currently subtable splitting is only supported for GPOS subtable types.
|
||||
|
||||
## GSUB/GPOS Extension Lookup Promotion
|
||||
|
||||
In GSUB/GPOS tables lookups can be regular lookups which use 16 bit offsets to the children subtables
|
||||
or extension lookups which use 32 bit offsets to the children subtables. If the sub graph of all
|
||||
regular lookups is too large then it can be difficult to find an overflow free configuration. This
|
||||
can be remedied by promoting one or more regular lookups to extension lookups.
|
||||
|
||||
During preprocessing the graph is scanned to determine the size of the subgraph of regular lookups.
|
||||
If the graph is found to be too big then the analysis finds a set of lookups to promote to reduce
|
||||
the subgraph size. Lastly the graph is modified to convert those lookups to extension lookups.
|
||||
|
||||
# Offset Resolution Strategies
|
||||
|
||||
## Space Assignment
|
||||
|
||||
The goal of space assignment is to find connected subgraphs that are only reachable via 32 bit offsets
|
||||
and then assign each such subgraph to a unique non-zero space. The algorithm is roughly:
|
||||
|
||||
1. Collect the set, `S`, of nodes that are children of 32 bit offsets.
|
||||
|
||||
2. Do a directed traversal from each node in `S` and collect all encountered nodes into set `T`.
|
||||
Mark all nodes in the graph that are not in `T` as being in space 0.
|
||||
|
||||
3. Set `next_space = 1`.
|
||||
|
||||
4. While set `S` is not empty:
|
||||
|
||||
a. Pick a node `n` in set `S` then perform an undirected graph traversal and find the set `Q` of
|
||||
nodes that are reachable from `n`.
|
||||
|
||||
b. During traversal if a node, `m`, has a edge to a node in space 0 then `m` must be duplicated
|
||||
to disconnect it from space 0.
|
||||
|
||||
d. Remove all nodes in `Q` from `S` and assign all nodes in `Q` to `next_space`.
|
||||
|
||||
|
||||
c. Increment `next_space` by one.
|
||||
|
||||
|
||||
## Manual Iterative Resolutions
|
||||
|
||||
For each overflow in each iteration the algorithm will attempt to apply offset overflow resolution
|
||||
strategies to eliminate the overflow. The type of strategy applied is dependent on the characteristics
|
||||
of the overflowing link:
|
||||
|
||||
* If the overflowing offset is inside a space other than space 0 and the subgraph space has more
|
||||
than one 32 bit offset pointing into the subgraph then subdivide the space by moving subgraph
|
||||
from one of the 32 bit offsets into a new space via the duplication of shared nodes.
|
||||
|
||||
* If the overflowing offset is pointing to a subtable with more than one incoming edge: duplicate
|
||||
the node so that the overflowing offset is pointing at it's own copy of that node.
|
||||
|
||||
* Otherwise, attempt to move the child subtable closer to it's parent. This is accomplished by
|
||||
raising the priority of all children of the parent. Next time the topological sort is run the
|
||||
children will be ordered closer to the parent.
|
||||
|
||||
# Test Cases
|
||||
|
||||
The harfbuzz repacker has tests defined using generic graphs: https://github.com/harfbuzz/harfbuzz/blob/main/src/test-repacker.cc
|
||||
|
||||
# Future Improvements
|
||||
|
||||
Currently for GPOS tables the repacker implementation is sufficient to handle both subsetting and the
|
||||
general case of font compilation repacking. However for GSUB the repacker is only sufficient for
|
||||
subsetting related overflows. To enable general case repacking of GSUB, support for splitting of
|
||||
GSUB subtables will need to be added. Other table types such as COLRv1 shouldn't require table
|
||||
splitting due to the wide use of 24 bit offsets throughout the table.
|
||||
|
||||
Beyond subtable splitting there are a couple of "nice to have" improvements, but these are not required
|
||||
to support the general case:
|
||||
|
||||
* Extension demotion: currently extension promotion is supported but in some cases if the non-extension
|
||||
subgraph is underfilled then packed size can be reduced by demoting extension lookups back to regular
|
||||
lookups.
|
||||
|
||||
* Currently only children nodes are moved to resolve offsets. However, in many cases moving a parent
|
||||
node closer to it's children will have less impact on the size of other offsets. Thus the algorithm
|
||||
should use a heuristic (based on parent and child subtable sizes) to decide if the children's
|
||||
priority should be increased or the parent's priority decreased.
|
|
@ -1,178 +0,0 @@
|
|||
# Introduction
|
||||
|
||||
In hb-subset serialization is the process of writing the subsetted font
|
||||
tables out to actual bytes in the final format. All serialization works
|
||||
through an object called the serialize context
|
||||
([hb_serialize_context_t](https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-serialize.hh)).
|
||||
|
||||
Internally the serialize context holds a fixed size memory buffer. For simple
|
||||
tables the final bytes are written into the buffer sequentially to produce
|
||||
the final serialized bytes.
|
||||
|
||||
## Simple Tables
|
||||
|
||||
Simple tables are tables that do not use offset graphs.
|
||||
|
||||
To write a struct into the serialization context, first you call an
|
||||
allocation method on the context which requests a writable array of bytes of
|
||||
a fixed size. If the requested array will not exceed the bounds of the fixed
|
||||
buffer the serializer will return a pointer to the next unwritten portion
|
||||
of the buffer. Then the struct is cast onto the returned pointer and values
|
||||
are written to the structs fields.
|
||||
|
||||
Internally the serialization context ends up looking like:
|
||||
|
||||
```
|
||||
+-------+-------+-----+-------+--------------+
|
||||
| Obj 1 | Obj 2 | ... | Obj N | Unused Space |
|
||||
+-------+-------+-----+-------+--------------+
|
||||
```
|
||||
|
||||
Here Obj N, is the object currently being written.
|
||||
|
||||
## Complex Tables
|
||||
|
||||
Complex tables are made up of graphs of objects, where offset's are used
|
||||
to form the edges of the graphs. Each object is a continuous slice of bytes
|
||||
that contains zero or more offsets pointing to more objects.
|
||||
|
||||
In this case the serialization buffer has a different layout:
|
||||
|
||||
```
|
||||
|- in progress objects -| |--- packed objects --|
|
||||
+-----------+-----------+--------------+-------+-----+-------+
|
||||
| Obj n+2 | Obj n+1 | Unused Space | Obj n | ... | Obj 0 |
|
||||
+-----------+-----------+--------------+-------+-----+-------+
|
||||
|-----------------------> <---------------------|
|
||||
```
|
||||
|
||||
The buffer holds two stacks:
|
||||
|
||||
1. In progress objects are held in a stack starting from the start of buffer
|
||||
that grows towards the end of the buffer.
|
||||
|
||||
2. Packed objects are held in a stack that starts at the end of the buffer
|
||||
and grows towards the start of the buffer.
|
||||
|
||||
Once the object on the top of the in progress stack is finished being written
|
||||
its bytes are popped from the in progress stack and copied to the top of
|
||||
the packed objects stack. In the example above, finalizing Obj n+1
|
||||
would result in the following state:
|
||||
|
||||
```
|
||||
+---------+--------------+---------+-------+-----+-------+
|
||||
| Obj n+2 | Unused Space | Obj n+1 | Obj n | ... | Obj 0 |
|
||||
+---------+--------------+---------+-------+-----+-------+
|
||||
```
|
||||
|
||||
Each packed object is associated with an ID, it's zero based position in the packed
|
||||
objects stack. In this example Obj 0, would have an ID of 0.
|
||||
|
||||
During serialization offsets that link from one object to another are stored
|
||||
using object ids. The serialize context maintains a list of links between
|
||||
objects. Each link records the parent object id, the child object id, the position
|
||||
of the offset field within the parent object, and the width of the offset.
|
||||
|
||||
Links are always added to the current in progress object and you can only link too
|
||||
objects that have been packed and thus have an ID.
|
||||
|
||||
### Object De-duplication
|
||||
|
||||
An important optimization in packing offset graphs is de-duplicating equivalent objects. If you
|
||||
have two or more parent objects that point to child objects that are equivalent then you only need
|
||||
to encode the child once and can have the parents point to the same child. This can significantly
|
||||
reduce the final size of a serialized graph.
|
||||
|
||||
During packing of an inprogress object the serialization context checks if any existing packed
|
||||
objects are equivalent to the object being packed. Here equivalence means the object has the
|
||||
exact same bytes and all of it's links are equivalent. If an equivalent object is found the
|
||||
in progress object is discarded and not copied to the packed object stack. The object id of
|
||||
the equivalent object is instead returned. Thus parent objects will then link to the existing
|
||||
equivalent object.
|
||||
|
||||
To find equivalent objects the serialization context maintains a hashmap from object to the canonical
|
||||
object id.
|
||||
|
||||
### Link Resolution
|
||||
|
||||
Once all objects have been packed the next step is to assign actual values to all of the offset
|
||||
fields. Prior to this point all links in the graph have been recorded using object id's. For each
|
||||
link the resolver computes the offset between the parent and child and writes the offset into
|
||||
the serialization buffer at the appropriate location.
|
||||
|
||||
### Offset Overflow Resolution
|
||||
|
||||
If during link resolution the resolver finds that an offsets value would exceed what can be encoded
|
||||
in that offset field link resolution is aborted and the offset overflow resolver is invoked.
|
||||
That process is documented [here](reapcker.md).
|
||||
|
||||
|
||||
### Example of Complex Serialization
|
||||
|
||||
|
||||
If we wanted to serialize the following graph:
|
||||
|
||||
```
|
||||
a--b--d
|
||||
\ /
|
||||
c
|
||||
```
|
||||
|
||||
Serializer would be called like this:
|
||||
|
||||
```c++
|
||||
hb_serialize_context_t ctx;
|
||||
|
||||
struct root {
|
||||
char name;
|
||||
Offset16To<child> child_1;
|
||||
Offset16To<child> child_2;
|
||||
}
|
||||
|
||||
struct child {
|
||||
char name;
|
||||
Offset16To<char> leaf;
|
||||
}
|
||||
|
||||
// Object A.
|
||||
ctx->push();
|
||||
root* a = ctx->start_embed<root> ();
|
||||
ctx->extend_min (a);
|
||||
a->name = 'a';
|
||||
|
||||
// Object B.
|
||||
ctx->push();
|
||||
child* b = ctx->start_embed<child> ();
|
||||
ctx->extend_min (b);
|
||||
b->name = 'b';
|
||||
|
||||
// Object D.
|
||||
ctx->push();
|
||||
*ctx->allocate_size<char> (1) = 'd';
|
||||
unsigned d_id = ctx->pop_pack ();
|
||||
|
||||
ctx->add_link (b->leaf, d_id);
|
||||
unsigned b_id = ctx->pop_pack ();
|
||||
|
||||
// Object C
|
||||
ctx->push();
|
||||
child* c = ctx->start_embed<child> ();
|
||||
ctx->extend_min (c);
|
||||
c->name = 'c';
|
||||
|
||||
// Object D.
|
||||
ctx->push();
|
||||
*ctx->allocate_size<char> (1) = 'd';
|
||||
d_id = ctx->pop_pack (); // Serializer will automatically de-dup this with the previous 'd'
|
||||
|
||||
ctx->add_link (c->leaf, d_id);
|
||||
unsigned c_id = ctx->pop_pack ();
|
||||
|
||||
// Object A's links:
|
||||
ctx->add_link (a->child_1, b_id);
|
||||
ctx->add_link (a->child_2, c_id);
|
||||
ctx->pop_pack ();
|
||||
|
||||
ctx->end_serialize ();
|
||||
|
||||
```
|
|
@ -1,228 +0,0 @@
|
|||
# Introduction
|
||||
|
||||
Subset preprocessing is a mechanism which can significantly speed up font subsetting operations.
|
||||
It works by prepopulating datastructures from the source font which can be used in later subsetting
|
||||
operations to more quickly produce the subset. Preprocessing is useful in cases where multiple subsets
|
||||
will be cut from the same source font.
|
||||
|
||||
# Usage
|
||||
|
||||
```c++
|
||||
hb_face_t* preprocessed = hb_subset_preprocess (source_face);
|
||||
|
||||
...
|
||||
|
||||
hb_face_t* subset = hb_subset_or_fail (preprocessed, subset_input);
|
||||
```
|
||||
|
||||
# Additional Details
|
||||
|
||||
* A subset produced from a preprocessed face should be identical to a subset produced from only the
|
||||
original face. The preprocessor does not change the functionality of the subsetter, just speeds
|
||||
things up.
|
||||
|
||||
* The preprocessing operation may take longer than the time it takes to produce a subset from the
|
||||
source font. Thus the main performance gains are made when a preprocessed face is reused for
|
||||
multiple subsetting operations.
|
||||
|
||||
* Currently the largest performance gains are seen when using a preprocessed face for CFF subsetting.
|
||||
|
||||
* The preprocessed face may contain references to the memory backing the source face. If this memory
|
||||
is fully owned by a harfbuzz hb_blob_t* then it will automatically be kept alive for the lifetime
|
||||
of the preprocessed face. However, if this memory is not fully owned by a harfbuzz hb_blob_t* then
|
||||
it is necessary to ensure that the memory is kept alive for the lifetime of the preprocessed face.
|
||||
|
||||
|
||||
# Performance Improvements
|
||||
|
||||
Here is the performance difference of producing a subset with a preprocessed face vs producing
|
||||
a subset with the source face:
|
||||
|
||||
Benchmark | Delta Time (%)
|
||||
----------|-----------------
|
||||
BM_subset/subset_glyphs/Roboto-Regular.ttf/10_median|-56%
|
||||
BM_subset/subset_glyphs/Roboto-Regular.ttf/64_median|-33%
|
||||
BM_subset/subset_glyphs/Roboto-Regular.ttf/512_median|-28%
|
||||
BM_subset/subset_glyphs/Roboto-Regular.ttf/1000_median|-11%
|
||||
BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/10_median|-56%
|
||||
BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/64_median|-33%
|
||||
BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/512_median|-21%
|
||||
BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/1000_median|-9%
|
||||
BM_subset/subset_glyphs/Amiri-Regular.ttf/10_median|-67%
|
||||
BM_subset/subset_glyphs/Amiri-Regular.ttf/64_median|-48%
|
||||
BM_subset/subset_glyphs/Amiri-Regular.ttf/512_median|-21%
|
||||
BM_subset/subset_glyphs/Amiri-Regular.ttf/4096_median|-9%
|
||||
BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/10_median|-66%
|
||||
BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/64_median|-50%
|
||||
BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/512_median|-8%
|
||||
BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/4096_median|-9%
|
||||
BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/10_median|-85%
|
||||
BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/64_median|-71%
|
||||
BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/512_median|-3%
|
||||
BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/1400_median|4%
|
||||
BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/10_median|-84%
|
||||
BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/64_median|-72%
|
||||
BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/512_median|0%
|
||||
BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/1400_median|0%
|
||||
BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/10_median|-30%
|
||||
BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/64_median|-24%
|
||||
BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/512_median|-3%
|
||||
BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/1000_median|-3%
|
||||
BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/10_median|-30%
|
||||
BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/64_median|-24%
|
||||
BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/512_median|-3%
|
||||
BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/1000_median|-5%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/10_median|-96%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/64_median|-90%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/512_median|-74%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/4096_median|-25%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/10000_median|-23%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/10_median|-95%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/64_median|-90%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/512_median|-73%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/4096_median|-24%
|
||||
BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/10000_median|-11%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/10_median|-84%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/64_median|-77%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/512_median|-70%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/4096_median|-80%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/10000_median|-86%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/10_median|-84%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/64_median|-78%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/512_median|-71%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/4096_median|-86%
|
||||
BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/10000_median|-88%
|
||||
BM_subset/subset_glyphs/SourceSansPro-Regular.otf/10_median|-59%
|
||||
BM_subset/subset_glyphs/SourceSansPro-Regular.otf/64_median|-55%
|
||||
BM_subset/subset_glyphs/SourceSansPro-Regular.otf/512_median|-67%
|
||||
BM_subset/subset_glyphs/SourceSansPro-Regular.otf/2000_median|-68%
|
||||
BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/10_median|-60%
|
||||
BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/64_median|-58%
|
||||
BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/512_median|-72%
|
||||
BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/2000_median|-71%
|
||||
BM_subset/subset_glyphs/AdobeVFPrototype.otf/10_median|-70%
|
||||
BM_subset/subset_glyphs/AdobeVFPrototype.otf/64_median|-64%
|
||||
BM_subset/subset_glyphs/AdobeVFPrototype.otf/300_median|-73%
|
||||
BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/10_median|-71%
|
||||
BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/64_median|-68%
|
||||
BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/300_median|-72%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/10_median|-90%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/64_median|-82%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/512_median|-31%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/4096_median|-9%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/6000_median|-22%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/10_median|-88%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/64_median|-83%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/512_median|-31%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/4096_median|-16%
|
||||
BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/6000_median|-18%
|
||||
BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/10_median|-44%
|
||||
BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/64_median|-18%
|
||||
BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/512_median|-2%
|
||||
BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/900_median|-6%
|
||||
BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/10_median|-45%
|
||||
BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/64_median|-17%
|
||||
BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/512_median|-15%
|
||||
BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/900_median|-3%
|
||||
BM_subset/subset_codepoints/Roboto-Regular.ttf/10_median|-20%
|
||||
BM_subset/subset_codepoints/Roboto-Regular.ttf/64_median|-16%
|
||||
BM_subset/subset_codepoints/Roboto-Regular.ttf/512_median|-12%
|
||||
BM_subset/subset_codepoints/Roboto-Regular.ttf/1000_median|-10%
|
||||
BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/10_median|-24%
|
||||
BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/64_median|-14%
|
||||
BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/512_median|-15%
|
||||
BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/1000_median|-9%
|
||||
BM_subset/subset_codepoints/Amiri-Regular.ttf/10_median|-51%
|
||||
BM_subset/subset_codepoints/Amiri-Regular.ttf/64_median|-37%
|
||||
BM_subset/subset_codepoints/Amiri-Regular.ttf/512_median|-12%
|
||||
BM_subset/subset_codepoints/Amiri-Regular.ttf/4096_median|-1%
|
||||
BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/10_median|-49%
|
||||
BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/64_median|-35%
|
||||
BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/512_median|-6%
|
||||
BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/4096_median|-1%
|
||||
BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/10_median|-82%
|
||||
BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/64_median|-9%
|
||||
BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/512_median|0%
|
||||
BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/1400_median|0%
|
||||
BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/10_median|-82%
|
||||
BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/64_median|-13%
|
||||
BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/512_median|-3%
|
||||
BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/1400_median|2%
|
||||
BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/10_median|-40%
|
||||
BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/64_median|-26%
|
||||
BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/512_median|-5%
|
||||
BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/1000_median|3%
|
||||
BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/10_median|-43%
|
||||
BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/64_median|-24%
|
||||
BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/512_median|-2%
|
||||
BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/1000_median|2%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/10_median|-83%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/64_median|-67%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/512_median|-39%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/4096_median|-20%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/10000_median|-25%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/10_median|-83%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/64_median|-65%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/512_median|-42%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/4096_median|-34%
|
||||
BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/10000_median|-21%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/10_median|-69%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/64_median|-69%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/512_median|-70%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/4096_median|-84%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/10000_median|-83%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10_median|-71%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/64_median|-68%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/512_median|-70%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/4096_median|-86%
|
||||
BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10000_median|-88%
|
||||
BM_subset/subset_codepoints/SourceSansPro-Regular.otf/10_median|-45%
|
||||
BM_subset/subset_codepoints/SourceSansPro-Regular.otf/64_median|-48%
|
||||
BM_subset/subset_codepoints/SourceSansPro-Regular.otf/512_median|-57%
|
||||
BM_subset/subset_codepoints/SourceSansPro-Regular.otf/2000_median|-66%
|
||||
BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/10_median|-43%
|
||||
BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/64_median|-50%
|
||||
BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/512_median|-63%
|
||||
BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/2000_median|-72%
|
||||
BM_subset/subset_codepoints/AdobeVFPrototype.otf/10_median|-69%
|
||||
BM_subset/subset_codepoints/AdobeVFPrototype.otf/64_median|-66%
|
||||
BM_subset/subset_codepoints/AdobeVFPrototype.otf/300_median|-74%
|
||||
BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/10_median|-70%
|
||||
BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/64_median|-71%
|
||||
BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/300_median|-75%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/10_median|-66%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/64_median|-46%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/512_median|-15%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/4096_median|-5%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/6000_median|-16%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/10_median|-66%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/64_median|-45%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/512_median|-14%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/4096_median|-11%
|
||||
BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/6000_median|-27%
|
||||
BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/10_median|-38%
|
||||
BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/64_median|-9%
|
||||
BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/512_median|-3%
|
||||
BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/900_median|-16%
|
||||
BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/10_median|-39%
|
||||
BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/64_median|-12%
|
||||
BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/512_median|-4%
|
||||
BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/900_median|-2%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/10_median|-68%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/64_median|-45%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/512_median|-18%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/4096_median|-2%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/6000_median|4%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/nohinting/10_median|-69%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/nohinting/64_median|-46%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/nohinting/512_median|-11%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/nohinting/4096_median|4%
|
||||
BM_subset/instance/MPLUS1-Variable.ttf/nohinting/6000_median|-5%
|
||||
BM_subset/instance/RobotoFlex-Variable.ttf/10_median|-34%
|
||||
BM_subset/instance/RobotoFlex-Variable.ttf/64_median|-12%
|
||||
BM_subset/instance/RobotoFlex-Variable.ttf/512_median|6%
|
||||
BM_subset/instance/RobotoFlex-Variable.ttf/900_median|-6%
|
||||
BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/10_median|-33%
|
||||
BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/64_median|-11%
|
||||
BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/512_median|3%
|
||||
BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/900_median|0%
|
|
@ -182,7 +182,8 @@
|
|||
</para>
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para><emphasis>Level 0</emphasis> is the default.
|
||||
<para><emphasis>Level 0</emphasis> is the default and
|
||||
reproduces the behavior of the old HarfBuzz library.
|
||||
</para>
|
||||
<para>
|
||||
The distinguishing feature of level 0 behavior is that, at
|
||||
|
@ -193,7 +194,7 @@
|
|||
as well as the <emphasis>Zero Width Joiner</emphasis> and
|
||||
<emphasis>Zero Width Non-Joiner</emphasis> code points, are
|
||||
assigned the cluster value of the closest preceding code
|
||||
point from <emphasis>different</emphasis> category.
|
||||
point from <emphasis>different</emphasis> category.
|
||||
</para>
|
||||
<para>
|
||||
In essence, whenever a base character is followed by a mark
|
||||
|
@ -205,11 +206,6 @@
|
|||
url="https://www.unicode.org/reports/tr29/#Regex_Definitions">Unicode
|
||||
Technical Report 29</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
This cluster level is suitable for code that likes to use
|
||||
HarfBuzz cluster values as an approximation of the Unicode
|
||||
Grapheme Cluster Boundaries as well.
|
||||
</para>
|
||||
<para>
|
||||
Client programs can specify level 0 behavior for a buffer by
|
||||
setting its <literal>cluster_level</literal> to
|
||||
|
@ -224,13 +220,13 @@
|
|||
implement backward compatibility with the old HarfBuzz.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Level 1</emphasis> differs from level 0 by not merging the
|
||||
Level 1 differs from level 0 by not merging the
|
||||
clusters of marks and other modifier code points with the
|
||||
preceding "base" code point's cluster. By preserving the
|
||||
separate cluster values of these marks and modifier code
|
||||
points, script shapers can perform additional operations
|
||||
that might lead to improved results (for example, coloring
|
||||
mark glyphs differently than their base).
|
||||
that might lead to improved results (for example, reordering
|
||||
a sequence of marks).
|
||||
</para>
|
||||
<para>
|
||||
Client programs can specify level 1 behavior for a buffer by
|
||||
|
@ -246,7 +242,7 @@
|
|||
</para>
|
||||
<para>
|
||||
This difference can be seen most clearly when HarfBuzz processes
|
||||
ligature substitutions and glyph decompositions. In level 0
|
||||
ligature substitutions and glyph decompositions. In level 0
|
||||
and level 1, ligatures and glyph decomposition both involve
|
||||
merging clusters; in level 2, neither of these operations
|
||||
triggers a merge.
|
||||
|
@ -263,7 +259,7 @@
|
|||
assign initial cluster values in a buffer by reusing the indices
|
||||
of the code points in the input text. This gives a sequence of
|
||||
cluster values that is monotonically increasing (for example,
|
||||
0,1,2,3,4).
|
||||
0,1,2,3,4).
|
||||
</para>
|
||||
<para>
|
||||
It is not <emphasis>required</emphasis> that the cluster values
|
||||
|
@ -318,7 +314,7 @@
|
|||
</listitem>
|
||||
</itemizedlist>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="a-clustering-example-for-levels-0-and-1">
|
||||
<title>A clustering example for levels 0 and 1</title>
|
||||
<para>
|
||||
|
@ -423,7 +419,7 @@
|
|||
<section id="reordering-in-levels-0-and-1">
|
||||
<title>Reordering in levels 0 and 1</title>
|
||||
<para>
|
||||
Another common operation in some shapers is glyph
|
||||
Another common operation in the more complex shapers is glyph
|
||||
reordering. In order to maintain a monotonic cluster sequence
|
||||
when glyph reordering takes place, HarfBuzz merges the clusters
|
||||
of everything in the reordering sequence.
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
shaping. The typeface must be set to a specific point size in
|
||||
order for some details (such as hinting) to work. In addition,
|
||||
if the font file in question is an OpenType Variable Font, then
|
||||
you may need to specify one or more variation-axis settings (or a
|
||||
you may need to specify one or variation-axis settings (or a
|
||||
named instance) in order to get the output you need.
|
||||
</para>
|
||||
<para>
|
||||
|
@ -256,18 +256,6 @@
|
|||
<para>
|
||||
<function>hb_font_get_glyph_from_name_func_t</function>: returns
|
||||
the glyph index that corresponds to a given glyph name.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>hb_font_draw_glyph_func_t</function>: gets the outlines
|
||||
of a glyph (by calling #hb_draw_funcs_t callbacks).
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
<function>hb_font_paint_glyph_func_t</function>: paints a glyph
|
||||
(by calling #hb_paint_funcs_t callbacks).
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
@ -387,6 +375,20 @@
|
|||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
<!-- Commenting out FreeType integration section-holder for now. May move
|
||||
to the full-blown Integration Chapter. -->
|
||||
|
||||
<!-- <section id="fonts-and-faces-freetype">
|
||||
<title>Using FreeType</title>
|
||||
<para>
|
||||
|
||||
</para>
|
||||
<para>
|
||||
|
||||
</para>
|
||||
</section> -->
|
||||
|
||||
<section id="fonts-and-faces-variable">
|
||||
<title>Working with OpenType Variable Fonts</title>
|
||||
<para>
|
||||
|
@ -453,66 +455,13 @@
|
|||
range actually implemented in the font's variation axis. After
|
||||
all, a font might only provide lighter-than-regular weights, and
|
||||
setting a heavier value on the <literal>wght</literal> axis will
|
||||
not change that.
|
||||
not change that.
|
||||
</para>
|
||||
<para>
|
||||
Once your variation settings are specified on your font object,
|
||||
however, shaping with a variable font is just like shaping a
|
||||
static font.
|
||||
</para>
|
||||
<para>
|
||||
In addition to providing the variation axes themselves, fonts may also
|
||||
pre-define certain variation coordinates as named instances. HarfBuzz
|
||||
makes these coordinates (and their associated names) available via
|
||||
<function>hb_ot_var_named_instance_get_design_coords()</function> and
|
||||
<function>hb_ot_var_named_instance_get_subfamily_name_id()</function>.
|
||||
</para>
|
||||
<para>
|
||||
Applications should treat named instances like multiple independent,
|
||||
static fonts.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="glyphs-and-rendering">
|
||||
<title>Glyphs and rendering</title>
|
||||
|
||||
<para>
|
||||
The main purpose of HarfBuzz is shaping, which creates a list of positioned
|
||||
glyphs as output. The remaining task for text layout is to convert this list
|
||||
into rendered output. While HarfBuzz does not handle rasterization of glyphs
|
||||
per se, it does have APIs that provide access to the font data that is needed
|
||||
to perform this task.
|
||||
</para>
|
||||
<para>
|
||||
Traditionally, the shapes of glyphs in scalable fonts are provided as quadratic
|
||||
or cubic Beziér curves defining outlines to be filled. To obtain the outlines
|
||||
for a glyph, call <function>hb_font_draw_glyph()</function> and pass a
|
||||
<type>hb_draw_funcs_t</type> struct. The callbacks in that struct will be called
|
||||
for each segment of the outline. Note that this API provides access to outlines
|
||||
as they are defined in the font, without applying hinting to fit the curves
|
||||
to the pixel grid.
|
||||
</para>
|
||||
<para>
|
||||
Fonts may provide pre-rendered images for glyphs instead of or in addition to
|
||||
outlines. This is most common for fonts that contain colored glyphs, such as
|
||||
Emoji. To access these images, use <function>hb_ot_color_reference_png()</function>
|
||||
or <function>hb_ot_color_reference_svg()</function>.
|
||||
</para>
|
||||
<para>
|
||||
Another way in which fonts provide colored glyphs is via paint graphs that
|
||||
combine glyph outlines with gradients and allow for transformations and
|
||||
compositing. In its simplest form, this can be presented as a series of
|
||||
layers that are rendered on top of each other, each with its own color.
|
||||
HarfBuzz has the <function>hb_ot_color_glyph_get_layers()</function> to
|
||||
access glyph data in this form.
|
||||
</para>
|
||||
<para>
|
||||
In the general case, you have to use <function>hb_font_paint_glyph()</function>
|
||||
and pass a <type>hb_paint_funcs_t</type> struct with callbacks to obtain paint
|
||||
graphs for glyphs that have them. The <function>hb_font_paint_glyph()</function>
|
||||
API can handle outline and image glyphs as well, so it provides a unified API for
|
||||
access to glyph rendering information.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</chapter>
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
|
||||
<para>
|
||||
Although the default <function>hb_shape()</function> function is
|
||||
sufficient for most use cases, a variant is also provided that
|
||||
sufficient for most use cases, a variant is also provide that
|
||||
lets you specify which of HarfBuzz's shapers to use on a buffer.
|
||||
</para>
|
||||
|
||||
|
@ -117,7 +117,7 @@
|
|||
implements separate shapers for Indic, Arabic, Thai and
|
||||
Lao, Khmer, Myanmar, Tibetan, Hangul, Hebrew, the
|
||||
Universal Shaping Engine (USE), and a default shaper for
|
||||
scripts with no script-specific shaping model.
|
||||
non-complex scripts.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -241,7 +241,7 @@
|
|||
</listitem>
|
||||
</orderedlist>
|
||||
<programlisting language="C">
|
||||
hb_blob_t *blob = hb_blob_create_from_file(filename); /* or hb_blob_create_from_file_or_fail() */
|
||||
hb_blob_t *blob = hb_blob_create_from_file(filename);
|
||||
hb_face_t *face = hb_face_create(blob, 0);
|
||||
hb_font_t *font = hb_font_create(face);
|
||||
</programlisting>
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
Release notes are posted with each new release to provide an
|
||||
overview of the changes. The project <ulink url="https://github.com/harfbuzz/harfbuzz/issues">tracks bug
|
||||
reports and other issues</ulink> on GitHub. Discussion and
|
||||
questions are welcome on <ulink
|
||||
url="https://github.com/harfbuzz/harfbuzz/discussions">GitHub</ulink> as well.
|
||||
questions are welcome on the <ulink
|
||||
url="http://freedesktop.org/mailman/listinfo/harfbuzz/">HarfBuzz
|
||||
mailing list</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
The API included in the <filename
|
||||
|
@ -237,6 +238,26 @@
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>-Dfontconfig=enabled</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use <ulink url="https://www.freedesktop.org/wiki/Software/fontconfig/">Fontconfig</ulink>. <emphasis>(Default = auto)</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
This option enables or disables usage of the Fontconfig
|
||||
library, which provides font-matching functions and
|
||||
provides access to font properties. The default setting
|
||||
is to check for the presence of Fontconfig and, if it is
|
||||
found, build with Fontconfig support.
|
||||
</para>
|
||||
<para>
|
||||
Note: Fontconfig is used only by the HarfBuzz
|
||||
command-line utilities, and not by the HarfBuzz library.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><command>-Dicu=enabled</command></term>
|
||||
<listitem>
|
||||
|
@ -335,7 +356,7 @@
|
|||
<term><command>-Ddocs=enabled</command></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Use <ulink url="https://github.com/GNOME/gtk-doc">GTK-Doc</ulink>. <emphasis>(Default = no)</emphasis>
|
||||
Use <ulink url="https://www.gtk.org/gtk-doc/">GTK-Doc</ulink>. <emphasis>(Default = no)</emphasis>
|
||||
</para>
|
||||
<para>
|
||||
This option enables the building of the documentation.
|
||||
|
|
|
@ -174,9 +174,7 @@
|
|||
<para>
|
||||
HarfBuzz provides integration points with FreeType at the
|
||||
face-object and font-object level and for the font-functions
|
||||
virtual-method structure of a font object. These functions
|
||||
make it easy for clients that use FreeType for rasterization
|
||||
or font-loading, to use HarfBuzz for shaping. To use the
|
||||
virtual-method structure of a font object. To use the
|
||||
FreeType-integration API, include the
|
||||
<filename>hb-ft.h</filename> header.
|
||||
</para>
|
||||
|
@ -310,49 +308,7 @@
|
|||
it when it is unneeded.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="integration-cairo">
|
||||
<title>Cairo integration</title>
|
||||
|
||||
<para>
|
||||
Cairo is a 2D graphics library that is frequently used together
|
||||
with GTK and Pango. Cairo supports rendering text using FreeType, or
|
||||
by using callback-based 'user fonts'.
|
||||
</para>
|
||||
<para>
|
||||
HarfBuzz provides integration points with cairo for fonts as well as
|
||||
for buffers. To use the Cairo-integration API, link against libharfbuzz-cairo,
|
||||
and include the <filename>hb-cairo.h</filename> header. For easy buildsystem
|
||||
integration, HarfBuzz comes with a <filename>harfbuzz-cairo.pc</filename>
|
||||
pkg-config file.
|
||||
</para>
|
||||
<para>
|
||||
To create a <type>cairo_scaled_font_t</type> font from a HarfBuzz
|
||||
<type>hb_font_t</type>, you can use <function>hb_cairo_font_face_create_for_font()</function>
|
||||
or <function>hb_cairo_font_face_create_for_face()</function>. The former API
|
||||
applies variations and synthetic slant from the <type>hb_font_t</type> when
|
||||
rendering, the latter takes them from the <type>cairo_font_options_t</type>
|
||||
that were passed when creating the <type>cairo_scaled_font_t</type>.
|
||||
</para>
|
||||
<para>
|
||||
The Cairo fonts created in this way make use of Cairo's user-font facilities.
|
||||
They can be used to render on any Cairo context, and provide full support for
|
||||
font rendering features, including color. One current limitation of the
|
||||
implementation is that it does not support hinting for glyph outlines.
|
||||
</para>
|
||||
<para>
|
||||
When using color fonts with this API, the color palette index is taken from
|
||||
the <type>cairo_font_options_t</type> (with new enough Cairo), and the foreground
|
||||
color is extracted from the source of the Cairo context.
|
||||
</para>
|
||||
<para>
|
||||
To render the results of shaping a piece of text, use
|
||||
<function>hb_cairo_glyphs_from_buffer()</function> to obtain the glyphs in
|
||||
a form that can be passed to <function>cairo_show_text_glyphs()</function> or
|
||||
<function>cairo_show_glyphs()</function>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="integration-uniscribe">
|
||||
<title>Uniscribe integration</title>
|
||||
<para>
|
||||
|
@ -391,7 +347,7 @@
|
|||
<structname>hb_glyph_position_t</structname> structures.
|
||||
</para>
|
||||
<para>
|
||||
Your client program only needs to ensure that it converts
|
||||
Your client program only needs to ensure that it coverts
|
||||
correctly between HarfBuzz's low-level data types (such as
|
||||
<type>hb_position_t</type>) and Windows's corresponding types
|
||||
(such as <type>GOFFSET</type> and <type>ABC</type>). Be sure you
|
||||
|
@ -489,7 +445,7 @@
|
|||
is slightly lower-level than Core Text, provides
|
||||
<ulink url="https://developer.apple.com/documentation/coregraphics/cgfontref"><type>CGFontRef</type></ulink>, which enables access to typeface
|
||||
properties, but does not include size information. Core Text's
|
||||
<ulink url="https://developer.apple.com/documentation/coretext/ctfont-q6r"><type>CTFontRef</type></ulink> is analogous to a HarfBuzz font object,
|
||||
<ulink url="https://developer.apple.com/documentation/coretext/ctfont-q6r"><type>CTFontRef</type></ulink> is analagous to a HarfBuzz font object,
|
||||
with all of the properties required to render text at a specific
|
||||
size and configuration.
|
||||
Consequently, a HarfBuzz <type>hb_font_t</type> font object can
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
HarfBuzz features two kinds of data types: non-opaque,
|
||||
pass-by-value types and opaque, heap-allocated types. This kind
|
||||
of separation is common in C libraries that have to provide
|
||||
API/ABI compatibility (almost) indefinitely.
|
||||
API/ABI compatibility (almost) indefinitely.
|
||||
</para>
|
||||
<para>
|
||||
<emphasis>Value types:</emphasis> The non-opaque, pass-by-value
|
||||
|
@ -32,8 +32,8 @@
|
|||
possible future members. As such, it’s important to provide
|
||||
<function>equal()</function>, and <function>hash()</function>
|
||||
methods for such structs, allowing users of the API do
|
||||
effectively deal with the type without having to
|
||||
adapt their code to future changes.
|
||||
effectively deal with the type without having to
|
||||
adapt their code to future changes.
|
||||
</para>
|
||||
<para>
|
||||
Important value types provided by HarfBuzz include the structs
|
||||
|
@ -42,7 +42,7 @@
|
|||
OpenType properties.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
<section id="object-model-object-types">
|
||||
<title>Objects in HarfBuzz</title>
|
||||
<para>
|
||||
|
@ -63,17 +63,13 @@
|
|||
the <literal>hb_buffer_t</literal> object has
|
||||
<function>hb_buffer_create()</function> as its constructor,
|
||||
<function>hb_buffer_reference()</function> to reference, and
|
||||
<function>hb_buffer_destroy()</function> to dereference.
|
||||
<function>hb_buffer_destroy()</function> to dereference.
|
||||
</para>
|
||||
<para>
|
||||
After construction, each object's properties are accessible only
|
||||
through the setter and getter functions described in the API
|
||||
Reference manual.
|
||||
</para>
|
||||
<para>
|
||||
Note that many object types can be marked as read-only or immutable,
|
||||
facilitating their use in multi-threaded environments.
|
||||
</para>
|
||||
<para>
|
||||
Key object types provided by HarfBuzz include:
|
||||
</para>
|
||||
|
@ -114,11 +110,11 @@
|
|||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section id="object-model-lifecycle">
|
||||
<title>Object lifecycle management</title>
|
||||
<para>
|
||||
|
@ -135,7 +131,7 @@
|
|||
<literal>1</literal>. Client programs can increase the reference
|
||||
count on an object by calling its
|
||||
<function>reference()</function> method. Whenever a client
|
||||
program is finished with an object, it should call its
|
||||
program is finished with an object, it should call its
|
||||
corresponding <function>destroy()</function> method. The destroy
|
||||
method will decrease the reference count on the object and,
|
||||
whenever the reference count reaches zero, it will also destroy
|
||||
|
@ -145,8 +141,8 @@
|
|||
All of HarfBuzz's object-lifecycle-management APIs are
|
||||
thread-safe (unless you compiled HarfBuzz from source with the
|
||||
<literal>HB_NO_MT</literal> configuration flag), even when the
|
||||
object as a whole is not thread-safe.
|
||||
It is also permissible to <function>reference()</function> or to
|
||||
object as a whole is not thread-safe.
|
||||
It is also permissible to <function>reference()</function> or to
|
||||
<function>destroy()</function> the <literal>NULL</literal>
|
||||
value.
|
||||
</para>
|
||||
|
@ -164,7 +160,7 @@
|
|||
as immutable and <function>is_immutable()</function> methods to
|
||||
test whether or not an object is immutable. Attempts to use
|
||||
setter functions on immutable objects will fail silently; see the API
|
||||
Reference manual for specifics.
|
||||
Reference manual for specifics.
|
||||
</para>
|
||||
<para>
|
||||
Note also that there are no "make mutable" methods. If client
|
||||
|
@ -191,7 +187,7 @@
|
|||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section id="object-model-user-data">
|
||||
<title>User data</title>
|
||||
<para>
|
||||
|
@ -199,7 +195,7 @@
|
|||
offer a "user data" mechanism that can be used to attach
|
||||
arbitrary data to the object. User-data attachment can be
|
||||
useful for tying the lifecycles of various pieces of data
|
||||
together, or for creating language bindings.
|
||||
together, or for creating language bindings.
|
||||
</para>
|
||||
<para>
|
||||
Each object type has a <function>set_user_data()</function>
|
||||
|
@ -224,10 +220,10 @@
|
|||
existing <literal>user_data</literal>
|
||||
associated with the specified key.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
<section id="object-model-blobs">
|
||||
<title>Blobs</title>
|
||||
<para>
|
||||
|
@ -236,15 +232,15 @@
|
|||
different.
|
||||
</para>
|
||||
<para>
|
||||
Blobs are an abstraction designed to negotiate lifecycle and
|
||||
Blobs are an abstraction desgined to negotiate lifecycle and
|
||||
permissions for raw pieces of data. For example, when you load
|
||||
the raw font data into memory and want to pass it to HarfBuzz,
|
||||
you do so in a <literal>hb_blob_t</literal> wrapper.
|
||||
</para>
|
||||
<para>
|
||||
This allows you to take advantage of HarfBuzz's
|
||||
This allows you to take advantage of HarffBuzz's
|
||||
reference-counting and <function>destroy</function>
|
||||
callbacks. If you allocated the memory for the data using
|
||||
callbacks. If you allocated the memory for the data using
|
||||
<function>malloc()</function>, you would create the blob using
|
||||
</para>
|
||||
<programlisting language="C">
|
||||
|
@ -255,12 +251,8 @@
|
|||
allocated memory whenever the blob drops its last reference and
|
||||
is deconstructed. Consequently, the user code can stop worrying
|
||||
about freeing memory and let the reference-counting machinery
|
||||
take care of that.
|
||||
</para>
|
||||
<para>
|
||||
Most of the time, blobs are read-only, facilitating their use in
|
||||
immutable objects.
|
||||
take care of that.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
|
||||
</chapter>
|
||||
|
|
|
@ -65,10 +65,10 @@
|
|||
</para>
|
||||
<para>
|
||||
The algorithms
|
||||
used for shaping can be quite involved; HarfBuzz tries
|
||||
used for complex scripts can be quite involved; HarfBuzz tries
|
||||
to be compatible with the OpenType Layout specification
|
||||
and, wherever there is any ambiguity, HarfBuzz attempts to replicate the
|
||||
output of Microsoft's Uniscribe engine, to the extent that is feasible and desirable. See the <ulink
|
||||
output of Microsoft's Uniscribe engine. See the <ulink
|
||||
url="https://docs.microsoft.com/en-us/typography/script-development/standard">Microsoft
|
||||
Typography pages</ulink> for more detail.
|
||||
</para>
|
||||
|
@ -131,7 +131,7 @@
|
|||
</para>
|
||||
<para>
|
||||
Some OpenType features are defined for the purpose of supporting
|
||||
script-specific shaping, and are automatically activated, but
|
||||
complex-script shaping, and are automatically activated, but
|
||||
only when a buffer's script property is set to a script that the
|
||||
feature supports.
|
||||
</para>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
correct amount for each successive glyph.
|
||||
</para>
|
||||
<para>
|
||||
But, for other scripts (often unceremoniously called <emphasis>complex scripts</emphasis>), any combination of
|
||||
But, for <emphasis>complex scripts</emphasis>, any combination of
|
||||
several shaping operations may be required, and the rules for how
|
||||
and when they are applied vary from script to script. HarfBuzz and
|
||||
other shaping engines implement these rules.
|
||||
|
@ -36,35 +36,42 @@
|
|||
</para>
|
||||
</section>
|
||||
|
||||
<section id="script-specific-shaping">
|
||||
<title>Script-specific shaping</title>
|
||||
<section id="complex-scripts">
|
||||
<title>Complex scripts</title>
|
||||
<para>
|
||||
In many scripts, transforming the input
|
||||
sequence into the final layout often requires some combination of
|
||||
In text-shaping terminology, scripts are generally classified as
|
||||
either <emphasis>complex</emphasis> or <emphasis>non-complex</emphasis>.
|
||||
</para>
|
||||
<para>
|
||||
Complex scripts are those for which transforming the input
|
||||
sequence into the final layout requires some combination of
|
||||
operations—such as context-dependent substitutions,
|
||||
context-dependent mark positioning, glyph-to-glyph joining,
|
||||
glyph reordering, or glyph stacking.
|
||||
</para>
|
||||
<para>
|
||||
In some scripts, the shaping rules require that a text
|
||||
In some complex scripts, the shaping rules require that a text
|
||||
run be divided into syllables before the operations can be
|
||||
applied. Other scripts may apply shaping operations over
|
||||
applied. Other complex scripts may apply shaping operations over
|
||||
entire words or over the entire text run, with no subdivision
|
||||
required.
|
||||
</para>
|
||||
<para>
|
||||
Other scripts, do not require these
|
||||
operations. However, correctly shaping a text run in
|
||||
any script may still involve Unicode normalization,
|
||||
Non-complex scripts, by definition, do not require these
|
||||
operations. However, correctly shaping a text run in a
|
||||
non-complex script may still involve Unicode normalization,
|
||||
ligature substitutions, mark positioning, kerning, and applying
|
||||
other font features.
|
||||
other font features. The key difference is that a text run in a
|
||||
non-complex script can be processed sequentially and in the same
|
||||
order as the input sequence of Unicode codepoints, without
|
||||
requiring an analysis stage.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="shaping-operations">
|
||||
<title>Shaping operations</title>
|
||||
<para>
|
||||
Shaping a text run involves transforming the
|
||||
Shaping a complex-script text run involves transforming the
|
||||
input sequence of Unicode codepoints with some combination of
|
||||
operations that is specified in the shaping model for the
|
||||
script.
|
||||
|
@ -74,7 +81,7 @@
|
|||
text run varies from script to script, as do the order that the
|
||||
operations are performed in and which codepoints are
|
||||
affected. However, the same general set of shaping operations is
|
||||
common to all of the script shaping models.
|
||||
common to all of the complex-script shaping models.
|
||||
</para>
|
||||
|
||||
<itemizedlist>
|
||||
|
@ -85,7 +92,7 @@
|
|||
some other ("visual") position.
|
||||
</para>
|
||||
<para>
|
||||
The shaping model for a given script might involve
|
||||
The shaping model for a given complex script might involve
|
||||
more than one reordering step.
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -112,7 +119,7 @@
|
|||
particular string pattern.
|
||||
</para>
|
||||
<para>
|
||||
The shaping model for a given script might involve
|
||||
The shaping model for a given complex script might involve
|
||||
multiple contextual-substitution operations, each applying
|
||||
to different target glyphs and patterns, and which are
|
||||
performed in separate steps.
|
||||
|
@ -131,7 +138,7 @@
|
|||
Many contextual positioning operations are used to place
|
||||
<emphasis>mark</emphasis> glyphs (such as diacritics, vowel
|
||||
signs, and tone markers) with respect to
|
||||
<emphasis>base</emphasis> glyphs. However, some
|
||||
<emphasis>base</emphasis> glyphs. However, some complex
|
||||
scripts may use contextual positioning operations to
|
||||
correctly place base glyphs as well, such as
|
||||
when the script uses <emphasis>stacking</emphasis> characters.
|
||||
|
@ -187,7 +194,7 @@
|
|||
multiple positions).
|
||||
</para>
|
||||
<para>
|
||||
Some scripts require that the text run be split into
|
||||
Some complex scripts require that the text run be split into
|
||||
syllables. What constitutes a valid syllable in these
|
||||
scripts is specified in regular expressions, formed from the
|
||||
Letter and Mark codepoints, that take the UISC and UIPC
|
||||
|
@ -228,7 +235,7 @@
|
|||
<listitem>
|
||||
<para>
|
||||
The <emphasis>default</emphasis> shaping model handles all
|
||||
scripts with no script-specific shaping model, and may also be used as a fallback for
|
||||
non-complex scripts, and may also be used as a fallback for
|
||||
handling unrecognized scripts.
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -237,7 +244,7 @@
|
|||
<para>
|
||||
The <emphasis>Indic</emphasis> shaping model handles the Indic
|
||||
scripts Bengali, Devanagari, Gujarati, Gurmukhi, Kannada,
|
||||
Malayalam, Oriya, Tamil, and Telugu.
|
||||
Malayalam, Oriya, Tamil, Telugu, and Sinhala.
|
||||
</para>
|
||||
<para>
|
||||
The Indic shaping model was revised significantly in
|
||||
|
@ -303,7 +310,7 @@
|
|||
<listitem>
|
||||
<para>
|
||||
The <emphasis>Universal Shaping Engine</emphasis> (USE)
|
||||
shaping model supports scripts not covered by one of
|
||||
shaping model supports complex scripts not covered by one of
|
||||
the above, script-specific shaping models, including
|
||||
Javanese, Balinese, Buginese, Batak, Chakma, Lepcha, Modi,
|
||||
Phags-pa, Tagalog, Siddham, Sundanese, Tai Le, Tai Tham, Tai
|
||||
|
|
|
@ -237,7 +237,8 @@
|
|||
<listitem>
|
||||
<para>
|
||||
Indic (covering Devanagari, Bengali, Gujarati,
|
||||
Gurmukhi, Kannada, Malayalam, Oriya, Tamil, and Telugu)
|
||||
Gurmukhi, Kannada, Malayalam, Oriya, Tamil, Telugu, and
|
||||
Sinhala)
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
|
|
7
git.mk
7
git.mk
|
@ -204,7 +204,7 @@ git-mk-update:
|
|||
# Actual .gitignore generation:
|
||||
###############################################################################
|
||||
|
||||
$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk $(top_srcdir)/configure.ac
|
||||
$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk
|
||||
@echo "git.mk: Generating $@"
|
||||
@{ \
|
||||
if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \
|
||||
|
@ -375,9 +375,8 @@ $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk $(top_srcdir)/configure.a
|
|||
} | \
|
||||
sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \
|
||||
sed 's@/[.]/@/@g' | \
|
||||
LC_ALL=C sort | uniq > .gitignore.tmp && \
|
||||
(mv .gitignore.tmp $@ || (echo "WARNING: Cannot create $@ file; skipping"; \
|
||||
$(RM) .gitignore.tmp));
|
||||
LC_ALL=C sort | uniq > $@.tmp && \
|
||||
mv $@.tmp $@;
|
||||
|
||||
all: $(srcdir)/.gitignore gitignore-recurse-maybe
|
||||
gitignore: $(srcdir)/.gitignore gitignore-recurse
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
<shortdesc xml:lang="en">Text shaping library</shortdesc>
|
||||
|
||||
<homepage
|
||||
rdf:resource="https://github.com/harfbuzz/harfbuzz" />
|
||||
rdf:resource="http://harfbuzz.org/" />
|
||||
<mailing-list
|
||||
rdf:resource="https://github.com/harfbuzz/harfbuzz/discussions" />
|
||||
<download-page
|
||||
rdf:resource="https://github.com/harfbuzz/harfbuzz/releases" />
|
||||
rdf:resource="http://lists.freedesktop.org/mailman/listinfo/harfbuzz" />
|
||||
<!--download-page
|
||||
rdf:resource=""/-->
|
||||
<bug-database
|
||||
rdf:resource="https://github.com/harfbuzz/harfbuzz/issues" />
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
void memory_barrier (void) { __sync_synchronize (); }
|
||||
int atomic_add (int *i) { return __sync_fetch_and_add (i, 1); }
|
||||
int mutex_trylock (int *m) { return __sync_lock_test_and_set (m, 1); }
|
||||
void mutex_unlock (int *m) { __sync_lock_release (m); }
|
||||
|
||||
int main(void) { return 0;}
|
|
@ -0,0 +1,8 @@
|
|||
#include <atomic.h>
|
||||
/* This requires Solaris Studio 12.2 or newer: */
|
||||
#include <mbarrier.h>
|
||||
void memory_barrier (void) { __machine_rw_barrier (); }
|
||||
int atomic_add (volatile unsigned *i) { return atomic_add_int_nv (i, 1); }
|
||||
void *atomic_ptr_cmpxchg (volatile void **target, void *cmp, void *newval) { return atomic_cas_ptr (target, cmp, newval); }
|
||||
|
||||
int main(void) { return 0; }
|
226
meson.build
226
meson.build
|
@ -1,9 +1,9 @@
|
|||
project('harfbuzz', 'c', 'cpp',
|
||||
meson_version: '>= 0.55.0',
|
||||
version: '7.1.0',
|
||||
meson_version: '>= 0.47.0',
|
||||
version: '2.7.4',
|
||||
default_options: [
|
||||
'cpp_eh=none', # Just to support msvc, we are passing -fno-exceptions also anyway
|
||||
'cpp_rtti=false', # Just to support msvc, we are passing -fno-rtti also anyway
|
||||
'cpp_eh=none', # Just to support msvc, we are passing -fno-rtti also anyway
|
||||
'cpp_rtti=false', # Just to support msvc, we are passing -fno-exceptions also anyway
|
||||
'cpp_std=c++11',
|
||||
'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548
|
||||
],
|
||||
|
@ -15,20 +15,23 @@ hb_version_minor = hb_version_arr[1].to_int()
|
|||
hb_version_micro = hb_version_arr[2].to_int()
|
||||
|
||||
# libtool versioning
|
||||
hb_version_int = 60000 + hb_version_major*100 + hb_version_minor*10 + hb_version_micro
|
||||
hb_version_int = hb_version_major*10000 + hb_version_minor*100 + hb_version_micro
|
||||
hb_libtool_version_info = '@0@:0:@0@'.format(hb_version_int)
|
||||
|
||||
pkgmod = import('pkgconfig')
|
||||
cpp = meson.get_compiler('cpp')
|
||||
null_dep = dependency('', required: false)
|
||||
|
||||
if cpp.get_argument_syntax() == 'msvc'
|
||||
if cpp.get_id() == 'msvc'
|
||||
# Ignore several spurious warnings for things HarfBuzz does very commonly.
|
||||
# If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
|
||||
# If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
|
||||
# NOTE: Only add warnings here if you are sure they're spurious
|
||||
msvc_args = [
|
||||
'/wd4018', # implicit signed/unsigned conversion
|
||||
'/wd4146', # unary minus on unsigned (beware INT_MIN)
|
||||
'/wd4244', # lossy type conversion (e.g. double -> int)
|
||||
'/wd4305', # truncating type conversion (e.g. double -> float)
|
||||
cpp.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
|
||||
]
|
||||
add_project_arguments(msvc_args, language: ['c', 'cpp'])
|
||||
|
@ -53,17 +56,10 @@ if host_machine.cpu_family() == 'arm' and cpp.alignment('struct { char c; }') !=
|
|||
endif
|
||||
endif
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
add_project_arguments(cpp.get_supported_arguments([
|
||||
'-Wa,-mbig-obj'
|
||||
]), language : 'cpp')
|
||||
endif
|
||||
|
||||
check_headers = [
|
||||
['unistd.h'],
|
||||
['sys/mman.h'],
|
||||
['stdbool.h'],
|
||||
['xlocale.h'],
|
||||
]
|
||||
|
||||
check_funcs = [
|
||||
|
@ -73,84 +69,57 @@ check_funcs = [
|
|||
['getpagesize'],
|
||||
['mmap'],
|
||||
['isatty'],
|
||||
['uselocale'],
|
||||
['newlocale'],
|
||||
]
|
||||
|
||||
m_dep = cpp.find_library('m', required: false)
|
||||
|
||||
if meson.version().version_compare('>=0.60.0')
|
||||
# pkg-config: freetype2, cmake: Freetype
|
||||
freetype_dep = dependency('freetype2', 'Freetype',
|
||||
required: get_option('freetype'),
|
||||
default_options: ['harfbuzz=disabled'],
|
||||
allow_fallback: true)
|
||||
else
|
||||
# painful hack to handle multiple dependencies but also respect options
|
||||
freetype_opt = get_option('freetype')
|
||||
# we want to handle enabled manually after fallbacks, but also handle disabled normally
|
||||
if freetype_opt.enabled()
|
||||
freetype_opt = false
|
||||
freetype_dep = null_dep
|
||||
if not get_option('freetype').disabled()
|
||||
freetype_dep = dependency('freetype2', required: false)
|
||||
|
||||
if (not freetype_dep.found() and
|
||||
cpp.get_id() == 'msvc' and
|
||||
cpp.has_header('ft2build.h'))
|
||||
freetype_dep = cpp.find_library('freetype', required: false)
|
||||
endif
|
||||
# try pkg-config name
|
||||
freetype_dep = dependency('freetype2', method: 'pkg-config', required: freetype_opt)
|
||||
# when disabled, leave it not-found
|
||||
if not freetype_dep.found() and not get_option('freetype').disabled()
|
||||
# Try cmake name
|
||||
freetype_dep = dependency('Freetype', method: 'cmake', required: false)
|
||||
# Subproject fallback, `allow_fallback: true` means the fallback will be
|
||||
# tried even if the freetype option is set to `auto`.
|
||||
if not freetype_dep.found()
|
||||
freetype_dep = dependency('freetype2',
|
||||
method: 'pkg-config',
|
||||
required: get_option('freetype'),
|
||||
default_options: ['harfbuzz=disabled'],
|
||||
allow_fallback: true)
|
||||
endif
|
||||
|
||||
if not freetype_dep.found()
|
||||
# https://github.com/harfbuzz/harfbuzz/pull/2498
|
||||
freetype_dep = dependency('freetype2', required: get_option('freetype'),
|
||||
fallback: ['freetype2', 'freetype_dep'],
|
||||
default_options: ['harfbuzz=disabled'])
|
||||
endif
|
||||
endif
|
||||
|
||||
glib_dep = dependency('glib-2.0', required: get_option('glib'))
|
||||
gobject_dep = dependency('gobject-2.0', required: get_option('gobject'))
|
||||
graphite2_dep = dependency('graphite2', required: get_option('graphite2'))
|
||||
graphite_dep = dependency('graphite2', required: get_option('graphite'))
|
||||
glib_dep = dependency('glib-2.0', required: get_option('glib'),
|
||||
fallback: ['glib', 'libglib_dep'])
|
||||
gobject_dep = dependency('gobject-2.0', required: get_option('gobject'),
|
||||
fallback: ['glib', 'libgobject_dep'])
|
||||
fontconfig_dep = dependency('fontconfig', required: get_option('fontconfig'),
|
||||
fallback: ['fontconfig', 'fontconfig_dep'])
|
||||
graphite2_dep = dependency('graphite2', required: get_option('graphite'))
|
||||
|
||||
if meson.version().version_compare('>=0.60.0')
|
||||
# pkg-config: icu-uc, cmake: ICU but with components
|
||||
icu_dep = dependency('icu-uc', 'ICU',
|
||||
components: 'uc',
|
||||
required: get_option('icu'),
|
||||
default_options: ['harfbuzz=disabled'],
|
||||
allow_fallback: true)
|
||||
else
|
||||
# painful hack to handle multiple dependencies but also respect options
|
||||
icu_opt = get_option('icu')
|
||||
# we want to handle enabled manually after fallbacks, but also handle disabled normally
|
||||
if icu_opt.enabled()
|
||||
icu_opt = false
|
||||
endif
|
||||
# try pkg-config name
|
||||
icu_dep = dependency('icu-uc', method: 'pkg-config', required: icu_opt)
|
||||
# when disabled, leave it not-found
|
||||
if not icu_dep.found() and not get_option('icu').disabled()
|
||||
# Try cmake name
|
||||
icu_dep = dependency('ICU', method: 'cmake', components: 'uc', required: false)
|
||||
# Try again with subproject fallback. `allow_fallback: true` means the
|
||||
# fallback will be tried even if the icu option is set to `auto`, but
|
||||
# we cannot pass this option until Meson 0.59.0, because no wrap file
|
||||
# is checked into git.
|
||||
if not icu_dep.found()
|
||||
icu_dep = dependency('icu-uc',
|
||||
method: 'pkg-config',
|
||||
required: get_option('icu'))
|
||||
icu_dep = null_dep
|
||||
if not get_option('icu').disabled()
|
||||
icu_dep = dependency('icu-uc', required: false)
|
||||
|
||||
if (not icu_dep.found() and
|
||||
cpp.get_id() == 'msvc' and
|
||||
cpp.has_header('unicode/uchar.h') and
|
||||
cpp.has_header('unicode/unorm2.h') and
|
||||
cpp.has_header('unicode/ustring.h') and
|
||||
cpp.has_header('unicode/utf16.h') and
|
||||
cpp.has_header('unicode/uversion.h') and
|
||||
cpp.has_header('unicode/uscript.h'))
|
||||
if get_option('buildtype') == 'debug'
|
||||
icu_dep = cpp.find_library('icuucd', required: false)
|
||||
else
|
||||
icu_dep = cpp.find_library('icuuc', required: false)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if icu_dep.found() and icu_dep.type_name() == 'pkgconfig'
|
||||
icu_defs = icu_dep.get_variable(pkgconfig: 'DEFS', default_value: '').split()
|
||||
if icu_defs.length() > 0
|
||||
add_project_arguments(icu_defs, language: ['c', 'cpp'])
|
||||
if not icu_dep.found()
|
||||
icu_dep = dependency('icu-uc', required: get_option('icu'))
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -161,7 +130,7 @@ if not get_option('cairo').disabled()
|
|||
cairo_ft_dep = dependency('cairo-ft', required: false)
|
||||
|
||||
if (not cairo_dep.found() and
|
||||
cpp.get_argument_syntax() == 'msvc' and
|
||||
cpp.get_id() == 'msvc' and
|
||||
cpp.has_header('cairo.h'))
|
||||
cairo_dep = cpp.find_library('cairo', required: false)
|
||||
if cairo_dep.found() and cpp.has_function('cairo_ft_font_face_create_for_ft_face',
|
||||
|
@ -172,18 +141,21 @@ if not get_option('cairo').disabled()
|
|||
endif
|
||||
|
||||
if not cairo_dep.found()
|
||||
# Note that we don't have harfbuzz -> cairo -> freetype2 -> harfbuzz fallback
|
||||
# dependency cycle here because we have configured freetype2 above with
|
||||
# harfbuzz support disabled, so when cairo will lookup freetype2 dependency
|
||||
# it will be forced to use that one.
|
||||
cairo_dep = dependency('cairo', required: get_option('cairo'))
|
||||
cairo_ft_required = get_option('cairo').enabled() and get_option('freetype').enabled()
|
||||
cairo_ft_dep = dependency('cairo-ft', required: cairo_ft_required)
|
||||
# Requires Meson 0.54.0 to use cairo subproject
|
||||
if meson.version().version_compare('>=0.54.0')
|
||||
# Note that we don't have harfbuzz -> cairo -> freetype2 -> harfbuzz fallback
|
||||
# dependency cycle here because we have configured freetype2 above with
|
||||
# harfbuzz support disabled, so when cairo will lookup freetype2 dependency
|
||||
# it will be forced to use that one.
|
||||
cairo_dep = dependency('cairo', fallback: 'cairo', required: get_option('cairo'))
|
||||
cairo_ft_dep = dependency('cairo-ft', fallback: 'cairo', required: get_option('cairo'))
|
||||
elif get_option('cairo').enabled()
|
||||
error('cairo feature is enabled but it cannot be found on the system and ' +
|
||||
'meson>=0.54.0 is required to build it as subproject')
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
chafa_dep = dependency('chafa', version: '>= 1.6.0', required: get_option('chafa'))
|
||||
|
||||
conf = configuration_data()
|
||||
incconfig = include_directories('.')
|
||||
|
||||
|
@ -205,31 +177,13 @@ endif
|
|||
|
||||
if cairo_dep.found()
|
||||
conf.set('HAVE_CAIRO', 1)
|
||||
check_cairo_funcs = [
|
||||
['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}],
|
||||
['cairo_font_options_get_custom_palette_color', {'deps': cairo_dep}],
|
||||
['cairo_user_scaled_font_get_foreground_source', {'deps': cairo_dep}],
|
||||
]
|
||||
|
||||
if cairo_dep.type_name() == 'internal'
|
||||
foreach func: check_cairo_funcs
|
||||
name = func[0]
|
||||
conf.set('HAVE_@0@'.format(name.to_upper()), 1)
|
||||
endforeach
|
||||
else
|
||||
check_funcs += check_cairo_funcs
|
||||
endif
|
||||
endif
|
||||
|
||||
if cairo_ft_dep.found()
|
||||
conf.set('HAVE_CAIRO_FT', 1)
|
||||
endif
|
||||
|
||||
if chafa_dep.found()
|
||||
conf.set('HAVE_CHAFA', 1)
|
||||
endif
|
||||
|
||||
if graphite2_dep.found() or graphite_dep.found()
|
||||
if graphite2_dep.found()
|
||||
conf.set('HAVE_GRAPHITE2', 1)
|
||||
endif
|
||||
|
||||
|
@ -251,7 +205,6 @@ if freetype_dep.found()
|
|||
['FT_Get_Var_Blend_Coordinates', {'deps': freetype_dep}],
|
||||
['FT_Set_Var_Blend_Coordinates', {'deps': freetype_dep}],
|
||||
['FT_Done_MM_Var', {'deps': freetype_dep}],
|
||||
['FT_Get_Transform', {'deps': freetype_dep}],
|
||||
]
|
||||
|
||||
if freetype_dep.type_name() == 'internal'
|
||||
|
@ -264,6 +217,10 @@ if freetype_dep.found()
|
|||
endif
|
||||
endif
|
||||
|
||||
if fontconfig_dep.found()
|
||||
conf.set('HAVE_FONTCONFIG', 1)
|
||||
endif
|
||||
|
||||
gdi_uniscribe_deps = []
|
||||
# GDI (Uniscribe) (Windows)
|
||||
if host_machine.system() == 'windows' and not get_option('gdi').disabled()
|
||||
|
@ -286,12 +243,17 @@ if host_machine.system() == 'windows' and not get_option('gdi').disabled()
|
|||
endif
|
||||
|
||||
# DirectWrite (Windows)
|
||||
directwrite_dep = null_dep
|
||||
if host_machine.system() == 'windows' and not get_option('directwrite').disabled()
|
||||
if get_option('directwrite').enabled() and not cpp.has_header('dwrite_1.h')
|
||||
error('DirectWrite was enabled explicitly, but required header is missing.')
|
||||
endif
|
||||
|
||||
conf.set('HAVE_DIRECTWRITE', 1)
|
||||
directwrite_dep = cpp.find_library('dwrite', required: get_option('directwrite'))
|
||||
|
||||
if directwrite_dep.found()
|
||||
conf.set('HAVE_DIRECTWRITE', 1)
|
||||
endif
|
||||
endif
|
||||
|
||||
# CoreText (macOS)
|
||||
|
@ -323,6 +285,9 @@ if host_machine.system() != 'windows'
|
|||
|
||||
if thread_dep.found()
|
||||
conf.set('HAVE_PTHREAD', 1)
|
||||
else
|
||||
check_headers += ['sched.h']
|
||||
check_funcs += ['sched_yield', {'link_with': 'rt'}]
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -372,12 +337,17 @@ foreach check : check_funcs
|
|||
endif
|
||||
endforeach
|
||||
|
||||
subdir('src')
|
||||
|
||||
if not get_option('utilities').disabled()
|
||||
subdir('util')
|
||||
if cpp.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics')
|
||||
conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1)
|
||||
endif
|
||||
|
||||
if cpp.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops')
|
||||
conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1)
|
||||
endif
|
||||
|
||||
subdir('src')
|
||||
subdir('util')
|
||||
|
||||
if not get_option('tests').disabled()
|
||||
subdir('test')
|
||||
endif
|
||||
|
@ -392,9 +362,6 @@ endif
|
|||
|
||||
configure_file(output: 'config.h', configuration: conf)
|
||||
|
||||
alias_target('lib', libharfbuzz)
|
||||
alias_target('libs', libharfbuzz, libharfbuzz_subset)
|
||||
|
||||
build_summary = {
|
||||
'Directories':
|
||||
{'prefix': get_option('prefix'),
|
||||
|
@ -409,12 +376,11 @@ build_summary = {
|
|||
'ICU': conf.get('HAVE_ICU', 0) == 1,
|
||||
},
|
||||
'Font callbacks (the more the merrier)':
|
||||
{'Builtin' : true,
|
||||
'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
|
||||
{'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
|
||||
},
|
||||
'Dependencies used for command-line utilities':
|
||||
{'Cairo': conf.get('HAVE_CAIRO', 0) == 1,
|
||||
'Chafa': conf.get('HAVE_CHAFA', 0) == 1,
|
||||
'Fontconfig': conf.get('HAVE_FONTCONFIG', 0) == 1,
|
||||
},
|
||||
'Additional shapers':
|
||||
{'Graphite2': conf.get('HAVE_GRAPHITE2', 0) == 1,
|
||||
|
@ -427,7 +393,6 @@ build_summary = {
|
|||
'Other features':
|
||||
{'Documentation': conf.get('HAVE_GTK_DOC', 0) == 1,
|
||||
'GObject bindings': conf.get('HAVE_GOBJECT', 0) == 1,
|
||||
'Cairo integration': conf.get('HAVE_CAIRO', 0) == 1,
|
||||
'Introspection': conf.get('HAVE_INTROSPECTION', 0) == 1,
|
||||
'Experimental APIs': conf.get('HB_EXPERIMENTAL_API', 0) == 1,
|
||||
},
|
||||
|
@ -436,6 +401,19 @@ build_summary = {
|
|||
'Benchmark': get_option('benchmark').enabled(),
|
||||
},
|
||||
}
|
||||
foreach section_title, section : build_summary
|
||||
summary(section, bool_yn: true, section: section_title)
|
||||
endforeach
|
||||
if meson.version().version_compare('>=0.53')
|
||||
foreach section_title, section : build_summary
|
||||
summary(section, bool_yn: true, section: section_title)
|
||||
endforeach
|
||||
else
|
||||
summary = ['']
|
||||
foreach section_title, section : build_summary
|
||||
summary += ' @0@:'.format(section_title)
|
||||
foreach feature, value : section
|
||||
summary += ' @0@:'.format(feature)
|
||||
summary += ' @0@'.format(value)
|
||||
endforeach
|
||||
summary += ''
|
||||
endforeach
|
||||
message('\n'.join(summary))
|
||||
endif
|
||||
|
|
|
@ -5,13 +5,11 @@ option('gobject', type: 'feature', value: 'auto',
|
|||
description: 'Enable GObject bindings')
|
||||
option('cairo', type: 'feature', value: 'auto',
|
||||
description: 'Use Cairo graphics library')
|
||||
option('chafa', type: 'feature', value: 'auto',
|
||||
description: 'Use Chafa terminal graphics library')
|
||||
option('fontconfig', type: 'feature', value: 'auto',
|
||||
description: 'Use fontconfig')
|
||||
option('icu', type: 'feature', value: 'auto',
|
||||
description: 'Enable ICU library unicode functions')
|
||||
option('graphite', type: 'feature', value: 'disabled',
|
||||
description: 'Deprecated use graphite2 option instead')
|
||||
option('graphite2', type: 'feature', value: 'disabled',
|
||||
description: 'Enable Graphite2 complementary shaper')
|
||||
option('freetype', type: 'feature', value: 'auto',
|
||||
description: 'Enable freetype interop helpers')
|
||||
|
@ -29,10 +27,6 @@ option('introspection', type: 'feature', value: 'auto', yield: true,
|
|||
description: 'Generate gobject-introspection bindings (.gir/.typelib files)')
|
||||
option('docs', type: 'feature', value: 'auto', yield: true,
|
||||
description: 'Generate documentation with gtk-doc')
|
||||
option('doc_tests', type: 'boolean', value: false,
|
||||
description: 'Run gtkdoc-check tests')
|
||||
option('utilities', type: 'feature', value: 'enabled', yield: true,
|
||||
description: 'Build harfbuzz utils')
|
||||
|
||||
option('benchmark', type: 'feature', value: 'disabled',
|
||||
description: 'Enable benchmark tests')
|
||||
|
@ -40,7 +34,5 @@ option('icu_builtin', type: 'boolean', value: false,
|
|||
description: 'Don\'t separate ICU support as harfbuzz-icu module')
|
||||
option('experimental_api', type: 'boolean', value: false,
|
||||
description: 'Enable experimental APIs')
|
||||
option('ragel_subproject', type: 'boolean', value: false,
|
||||
description: 'Build Ragel subproject if no suitable version is found')
|
||||
option('fuzzer_ldflags', type: 'string',
|
||||
description: 'Extra LDFLAGS used during linking of fuzzing binaries')
|
||||
|
|
|
@ -17,14 +17,12 @@ exec "$(dirname "$0")"/configure \
|
|||
CPP= \
|
||||
LD= \
|
||||
CFLAGS="-static-libgcc" \
|
||||
CXXFLAGS="-O2 -static-libgcc -static-libstdc++" \
|
||||
CXXFLAGS="-static-libgcc -static-libstdc++" \
|
||||
CPPFLAGS="-I$HOME/.local/$target/include" \
|
||||
LDFLAGS=-L$HOME/.local/$target/lib \
|
||||
PKG_CONFIG_LIBDIR=$HOME/.local/$target/lib/pkgconfig:/usr/$target/sys-root/mingw/lib/pkgconfig/ \
|
||||
PKG_CONFIG_PATH=$HOME/.local/$target/share/pkgconfig:/usr/$target/sys-root/mingw/share/pkgconfig/ \
|
||||
PATH=$HOME/.local/$target/bin:/usr/$target/sys-root/mingw/bin:/usr/$target/bin:$PATH \
|
||||
--without-icu \
|
||||
--with-gdi \
|
||||
--with-uniscribe \
|
||||
--with-directwrite=auto \
|
||||
"$@"
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
# Process this file with automake to produce Makefile.in
|
||||
|
||||
NULL =
|
||||
EXTRA_DIST =
|
||||
SUBDIRS =
|
||||
|
||||
EXTRA_DIST += \
|
||||
meson.build \
|
||||
benchmark-font.cc \
|
||||
benchmark-map.cc \
|
||||
benchmark-ot.cc \
|
||||
benchmark-set.cc \
|
||||
benchmark-shape.cc \
|
||||
benchmark-subset.cc \
|
||||
fonts \
|
||||
texts \
|
||||
$(NULL)
|
||||
|
||||
# Convenience targets:
|
||||
lib:
|
||||
@$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src lib
|
||||
|
||||
-include $(top_srcdir)/git.mk
|
|
@ -1,54 +0,0 @@
|
|||
# Building and Running
|
||||
|
||||
Benchmarks are implemented using [Google Benchmark](https://github.com/google/benchmark).
|
||||
|
||||
To build the benchmarks in this directory you need to set the benchmark
|
||||
option while configuring the build with meson:
|
||||
|
||||
```
|
||||
meson build -Dbenchmark=enabled --buildtype=release
|
||||
```
|
||||
or:
|
||||
```
|
||||
meson build -Dbenchmark=enabled --buildtype=debugoptimized
|
||||
```
|
||||
|
||||
|
||||
Then build a specific benchmark binaries with ninja:
|
||||
```
|
||||
ninja -Cbuild perf/benchmark-set
|
||||
```
|
||||
or just build the whole project:
|
||||
```
|
||||
ninja -Cbuild
|
||||
```
|
||||
|
||||
Finally, to run one of the benchmarks:
|
||||
|
||||
```
|
||||
./build/perf/benchmark-set
|
||||
```
|
||||
|
||||
It's possible to filter the benchmarks being run and customize the output
|
||||
via flags to the benchmark binary. See the
|
||||
[Google Benchmark User Guide](https://github.com/google/benchmark/blob/main/docs/user_guide.md#user-guide) for more details.
|
||||
|
||||
# Profiling
|
||||
|
||||
Configure the build to include debug information for profiling:
|
||||
|
||||
```
|
||||
CXXFLAGS="-fno-omit-frame-pointer" meson --reconfigure build -Dbenchmark=enabled --buildtype=debug
|
||||
ninja -Cbuild
|
||||
```
|
||||
|
||||
Then run the benchmark with perf:
|
||||
|
||||
```
|
||||
perf record -g build/perf/benchmark-subset --benchmark_filter="BM_subset_codepoints/subset_notocjk/100000" --benchmark_repetitions=5
|
||||
```
|
||||
You probably want to filter to a specific benchmark of interest and set the number of repititions high enough to get a good sampling of profile data.
|
||||
|
||||
Finally view the profile with:
|
||||
|
||||
perf report
|
|
@ -1,245 +0,0 @@
|
|||
#include "benchmark/benchmark.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "hb.h"
|
||||
#include "hb-ot.h"
|
||||
#ifdef HAVE_FREETYPE
|
||||
#include "hb-ft.h"
|
||||
#endif
|
||||
|
||||
|
||||
#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
|
||||
|
||||
struct test_input_t
|
||||
{
|
||||
bool is_variable;
|
||||
const char *font_path;
|
||||
} default_tests[] =
|
||||
{
|
||||
{true , SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf"},
|
||||
{false, SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf"},
|
||||
{true , SUBSET_FONT_BASE_PATH "AdobeVFPrototype.otf"},
|
||||
{true , SUBSET_FONT_BASE_PATH "SourceSerifVariable-Roman.ttf"},
|
||||
{false, SUBSET_FONT_BASE_PATH "Comfortaa-Regular-new.ttf"},
|
||||
{false, SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf"},
|
||||
{false, SUBSET_FONT_BASE_PATH "NotoSerifMyanmar-Regular.otf"},
|
||||
};
|
||||
|
||||
static test_input_t *tests = default_tests;
|
||||
static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
|
||||
|
||||
enum backend_t { HARFBUZZ, FREETYPE };
|
||||
|
||||
enum operation_t
|
||||
{
|
||||
nominal_glyphs,
|
||||
glyph_h_advances,
|
||||
glyph_extents,
|
||||
glyph_shape,
|
||||
};
|
||||
|
||||
static void
|
||||
_hb_move_to (hb_draw_funcs_t *, void *, hb_draw_state_t *, float, float, void *) {}
|
||||
|
||||
static void
|
||||
_hb_line_to (hb_draw_funcs_t *, void *, hb_draw_state_t *, float, float, void *) {}
|
||||
|
||||
//static void
|
||||
//_hb_quadratic_to (hb_draw_funcs_t *, void *, hb_draw_state_t *, float, float, float, float, void *) {}
|
||||
|
||||
static void
|
||||
_hb_cubic_to (hb_draw_funcs_t *, void *, hb_draw_state_t *, float, float, float, float, float, float, void *) {}
|
||||
|
||||
static void
|
||||
_hb_close_path (hb_draw_funcs_t *, void *, hb_draw_state_t *, void *) {}
|
||||
|
||||
static hb_draw_funcs_t *
|
||||
_draw_funcs_create (void)
|
||||
{
|
||||
hb_draw_funcs_t *draw_funcs = hb_draw_funcs_create ();
|
||||
hb_draw_funcs_set_move_to_func (draw_funcs, _hb_move_to, nullptr, nullptr);
|
||||
hb_draw_funcs_set_line_to_func (draw_funcs, _hb_line_to, nullptr, nullptr);
|
||||
//hb_draw_funcs_set_quadratic_to_func (draw_funcs, _hb_quadratic_to, nullptr, nullptr);
|
||||
hb_draw_funcs_set_cubic_to_func (draw_funcs, _hb_cubic_to, nullptr, nullptr);
|
||||
hb_draw_funcs_set_close_path_func (draw_funcs, _hb_close_path, nullptr, nullptr);
|
||||
return draw_funcs;
|
||||
}
|
||||
|
||||
static void BM_Font (benchmark::State &state,
|
||||
bool is_var, backend_t backend, operation_t operation,
|
||||
const test_input_t &test_input)
|
||||
{
|
||||
hb_font_t *font;
|
||||
unsigned num_glyphs;
|
||||
{
|
||||
hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
|
||||
assert (blob);
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
hb_blob_destroy (blob);
|
||||
num_glyphs = hb_face_get_glyph_count (face);
|
||||
font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
if (is_var)
|
||||
{
|
||||
hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
|
||||
hb_font_set_variations (font, &wght, 1);
|
||||
}
|
||||
|
||||
switch (backend)
|
||||
{
|
||||
case HARFBUZZ:
|
||||
hb_ot_font_set_funcs (font);
|
||||
break;
|
||||
|
||||
case FREETYPE:
|
||||
#ifdef HAVE_FREETYPE
|
||||
hb_ft_font_set_funcs (font);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case nominal_glyphs:
|
||||
{
|
||||
hb_set_t *set = hb_set_create ();
|
||||
hb_face_collect_unicodes (hb_font_get_face (font), set);
|
||||
unsigned pop = hb_set_get_population (set);
|
||||
hb_codepoint_t *unicodes = (hb_codepoint_t *) calloc (pop, sizeof (hb_codepoint_t));
|
||||
hb_codepoint_t *glyphs = (hb_codepoint_t *) calloc (pop, sizeof (hb_codepoint_t));
|
||||
|
||||
hb_codepoint_t *p = unicodes;
|
||||
for (hb_codepoint_t u = HB_SET_VALUE_INVALID;
|
||||
hb_set_next (set, &u);)
|
||||
*p++ = u;
|
||||
assert (p == unicodes + pop);
|
||||
|
||||
for (auto _ : state)
|
||||
hb_font_get_nominal_glyphs (font,
|
||||
pop,
|
||||
unicodes, sizeof (*unicodes),
|
||||
glyphs, sizeof (*glyphs));
|
||||
|
||||
free (glyphs);
|
||||
free (unicodes);
|
||||
hb_set_destroy (set);
|
||||
break;
|
||||
}
|
||||
case glyph_h_advances:
|
||||
{
|
||||
hb_codepoint_t *glyphs = (hb_codepoint_t *) calloc (num_glyphs, sizeof (hb_codepoint_t));
|
||||
hb_position_t *advances = (hb_position_t *) calloc (num_glyphs, sizeof (hb_codepoint_t));
|
||||
|
||||
for (unsigned g = 0; g < num_glyphs; g++)
|
||||
glyphs[g] = g;
|
||||
|
||||
for (auto _ : state)
|
||||
hb_font_get_glyph_h_advances (font,
|
||||
num_glyphs,
|
||||
glyphs, sizeof (*glyphs),
|
||||
advances, sizeof (*advances));
|
||||
|
||||
free (advances);
|
||||
free (glyphs);
|
||||
break;
|
||||
}
|
||||
case glyph_extents:
|
||||
{
|
||||
hb_glyph_extents_t extents;
|
||||
for (auto _ : state)
|
||||
for (unsigned gid = 0; gid < num_glyphs; ++gid)
|
||||
hb_font_get_glyph_extents (font, gid, &extents);
|
||||
break;
|
||||
}
|
||||
case glyph_shape:
|
||||
{
|
||||
hb_draw_funcs_t *draw_funcs = _draw_funcs_create ();
|
||||
for (auto _ : state)
|
||||
for (unsigned gid = 0; gid < num_glyphs; ++gid)
|
||||
hb_font_draw_glyph (font, gid, draw_funcs, nullptr);
|
||||
break;
|
||||
hb_draw_funcs_destroy (draw_funcs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
|
||||
static void test_backend (backend_t backend,
|
||||
const char *backend_name,
|
||||
bool variable,
|
||||
operation_t op,
|
||||
const char *op_name,
|
||||
benchmark::TimeUnit time_unit,
|
||||
const test_input_t &test_input)
|
||||
{
|
||||
char name[1024] = "BM_Font/";
|
||||
strcat (name, op_name);
|
||||
strcat (name, "/");
|
||||
const char *p = strrchr (test_input.font_path, '/');
|
||||
strcat (name, p ? p + 1 : test_input.font_path);
|
||||
strcat (name, variable ? "/var" : "");
|
||||
strcat (name, "/");
|
||||
strcat (name, backend_name);
|
||||
|
||||
benchmark::RegisterBenchmark (name, BM_Font, variable, backend, op, test_input)
|
||||
->Unit(time_unit);
|
||||
}
|
||||
|
||||
static void test_operation (operation_t op,
|
||||
const char *op_name,
|
||||
benchmark::TimeUnit time_unit)
|
||||
{
|
||||
for (unsigned i = 0; i < num_tests; i++)
|
||||
{
|
||||
auto& test_input = tests[i];
|
||||
for (int variable = 0; variable < int (test_input.is_variable) + 1; variable++)
|
||||
{
|
||||
bool is_var = (bool) variable;
|
||||
|
||||
test_backend (HARFBUZZ, "hb", is_var, op, op_name, time_unit, test_input);
|
||||
#ifdef HAVE_FREETYPE
|
||||
test_backend (FREETYPE, "ft", is_var, op, op_name, time_unit, test_input);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
benchmark::Initialize(&argc, argv);
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
num_tests = argc - 1;
|
||||
tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
|
||||
for (unsigned i = 0; i < num_tests; i++)
|
||||
{
|
||||
tests[i].is_variable = true;
|
||||
tests[i].font_path = argv[i + 1];
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_OPERATION(op, time_unit) test_operation (op, #op, time_unit)
|
||||
|
||||
TEST_OPERATION (nominal_glyphs, benchmark::kMicrosecond);
|
||||
TEST_OPERATION (glyph_h_advances, benchmark::kMicrosecond);
|
||||
TEST_OPERATION (glyph_extents, benchmark::kMicrosecond);
|
||||
TEST_OPERATION (glyph_shape, benchmark::kMicrosecond);
|
||||
|
||||
#undef TEST_OPERATION
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Shutdown();
|
||||
|
||||
if (tests != default_tests)
|
||||
free (tests);
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
/*
|
||||
* Benchmarks for hb_map_t operations.
|
||||
*/
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include "hb.h"
|
||||
|
||||
void RandomMap(unsigned size, hb_map_t* out) {
|
||||
hb_map_clear(out);
|
||||
|
||||
srand(size);
|
||||
for (unsigned i = 0; i < size; i++) {
|
||||
while (true) {
|
||||
hb_codepoint_t next = rand();
|
||||
if (hb_map_has (out, next)) continue;
|
||||
|
||||
hb_map_set (out, next, rand ());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Insert a single value into map of varying sizes. */
|
||||
static void BM_MapInsert(benchmark::State& state) {
|
||||
unsigned map_size = state.range(0);
|
||||
|
||||
hb_map_t* original = hb_map_create ();
|
||||
RandomMap(map_size, original);
|
||||
assert(hb_map_get_population(original) == map_size);
|
||||
|
||||
auto needle = map_size / 2;
|
||||
auto v = 0;
|
||||
for (auto _ : state) {
|
||||
// TODO(garretrieger): create a copy of the original map.
|
||||
// Needs a hb_map_copy(..) in public api.
|
||||
|
||||
hb_map_set (original, needle++, v++);
|
||||
}
|
||||
|
||||
hb_map_destroy(original);
|
||||
}
|
||||
BENCHMARK(BM_MapInsert)
|
||||
->Range(1 << 4, 1 << 20);
|
||||
|
||||
/* Single value lookup on map of various sizes. */
|
||||
static void BM_MapLookup(benchmark::State& state) {
|
||||
unsigned map_size = state.range(0);
|
||||
|
||||
hb_map_t* original = hb_map_create ();
|
||||
RandomMap(map_size, original);
|
||||
assert(hb_map_get_population(original) == map_size);
|
||||
|
||||
auto needle = map_size / 2;
|
||||
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
hb_map_get (original, needle++));
|
||||
}
|
||||
|
||||
hb_map_destroy(original);
|
||||
}
|
||||
BENCHMARK(BM_MapLookup)
|
||||
->Range(1 << 4, 1 << 20); // Map size
|
||||
|
||||
|
||||
BENCHMARK_MAIN();
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Benchmarks for hb_set_t operations.
|
||||
*/
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "hb-ot.h"
|
||||
|
||||
static void BM_hb_ot_tags_from_script_and_language (benchmark::State& state,
|
||||
hb_script_t script,
|
||||
const char *language_str) {
|
||||
|
||||
hb_language_t language = hb_language_from_string (language_str, -1);
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT];
|
||||
unsigned script_count = HB_OT_MAX_TAGS_PER_SCRIPT;
|
||||
|
||||
hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
|
||||
unsigned language_count = HB_OT_MAX_TAGS_PER_LANGUAGE;
|
||||
|
||||
hb_ot_tags_from_script_and_language (script,
|
||||
language,
|
||||
&script_count /* IN/OUT */,
|
||||
script_tags /* OUT */,
|
||||
&language_count /* IN/OUT */,
|
||||
language_tags /* OUT */);
|
||||
}
|
||||
}
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON zh_abcd, HB_SCRIPT_COMMON, "zh_abcd");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON zh_hans, HB_SCRIPT_COMMON, "zh_hans");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON ab_abcd, HB_SCRIPT_COMMON, "ab_abcd");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON ab_abc, HB_SCRIPT_COMMON, "ab_abc");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON abcdef_XY, HB_SCRIPT_COMMON, "abcdef_XY");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON abcd_XY, HB_SCRIPT_COMMON, "abcd_XY");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON cxy_CN, HB_SCRIPT_COMMON, "cxy_CN");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON exy_CN, HB_SCRIPT_COMMON, "exy_CN");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON zh_CN, HB_SCRIPT_COMMON, "zh_CN");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON en_US, HB_SCRIPT_COMMON, "en_US");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, LATIN en_US, HB_SCRIPT_LATIN, "en_US");
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON none, HB_SCRIPT_LATIN, nullptr);
|
||||
BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, LATIN none, HB_SCRIPT_LATIN, nullptr);
|
||||
|
||||
BENCHMARK_MAIN();
|
|
@ -1,151 +0,0 @@
|
|||
/*
|
||||
* Benchmarks for hb_set_t operations.
|
||||
*/
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdlib>
|
||||
#include "hb.h"
|
||||
|
||||
void RandomSet(unsigned size, unsigned max_value, hb_set_t* out) {
|
||||
hb_set_clear(out);
|
||||
|
||||
srand(size * max_value);
|
||||
for (unsigned i = 0; i < size; i++) {
|
||||
while (true) {
|
||||
unsigned next = rand() % max_value;
|
||||
if (hb_set_has (out, next)) continue;
|
||||
|
||||
hb_set_add(out, next);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(garretrieger): benchmark union/subtract/intersection etc.
|
||||
|
||||
/* Insert a 1000 values into set of varying sizes. */
|
||||
static void BM_SetInsert_1000(benchmark::State& state) {
|
||||
unsigned set_size = state.range(0);
|
||||
unsigned max_value = state.range(0) * state.range(1);
|
||||
|
||||
hb_set_t* original = hb_set_create ();
|
||||
RandomSet(set_size, max_value, original);
|
||||
assert(hb_set_get_population(original) == set_size);
|
||||
|
||||
for (auto _ : state) {
|
||||
state.PauseTiming ();
|
||||
hb_set_t* data = hb_set_copy(original);
|
||||
state.ResumeTiming ();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
hb_set_add(data, i * 2654435761u % max_value);
|
||||
}
|
||||
hb_set_destroy(data);
|
||||
}
|
||||
|
||||
hb_set_destroy(original);
|
||||
}
|
||||
BENCHMARK(BM_SetInsert_1000)
|
||||
->Unit(benchmark::kMicrosecond)
|
||||
->Ranges(
|
||||
{{1 << 10, 1 << 16}, // Set Size
|
||||
{2, 512}}); // Density
|
||||
|
||||
/* Insert a 1000 values into set of varying sizes. */
|
||||
static void BM_SetOrderedInsert_1000(benchmark::State& state) {
|
||||
unsigned set_size = state.range(0);
|
||||
unsigned max_value = state.range(0) * state.range(1);
|
||||
|
||||
hb_set_t* original = hb_set_create ();
|
||||
RandomSet(set_size, max_value, original);
|
||||
assert(hb_set_get_population(original) == set_size);
|
||||
|
||||
for (auto _ : state) {
|
||||
state.PauseTiming ();
|
||||
hb_set_t* data = hb_set_copy(original);
|
||||
state.ResumeTiming ();
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
hb_set_add(data, i);
|
||||
}
|
||||
hb_set_destroy(data);
|
||||
}
|
||||
|
||||
hb_set_destroy(original);
|
||||
}
|
||||
BENCHMARK(BM_SetOrderedInsert_1000)
|
||||
->Unit(benchmark::kMicrosecond)
|
||||
->Ranges(
|
||||
{{1 << 10, 1 << 16}, // Set Size
|
||||
{2, 512}}); // Density
|
||||
|
||||
/* Single value lookup on sets of various sizes. */
|
||||
static void BM_SetLookup(benchmark::State& state, unsigned interval) {
|
||||
unsigned set_size = state.range(0);
|
||||
unsigned max_value = state.range(0) * state.range(1);
|
||||
|
||||
hb_set_t* original = hb_set_create ();
|
||||
RandomSet(set_size, max_value, original);
|
||||
assert(hb_set_get_population(original) == set_size);
|
||||
|
||||
auto needle = max_value / 2;
|
||||
for (auto _ : state) {
|
||||
benchmark::DoNotOptimize(
|
||||
hb_set_has (original, (needle += interval) % max_value));
|
||||
}
|
||||
|
||||
hb_set_destroy(original);
|
||||
}
|
||||
BENCHMARK_CAPTURE(BM_SetLookup, ordered, 3)
|
||||
->Ranges(
|
||||
{{1 << 10, 1 << 16}, // Set Size
|
||||
{2, 512}}); // Density
|
||||
BENCHMARK_CAPTURE(BM_SetLookup, random, 12345)
|
||||
->Ranges(
|
||||
{{1 << 10, 1 << 16}, // Set Size
|
||||
{2, 512}}); // Density
|
||||
|
||||
/* Full iteration of sets of varying sizes. */
|
||||
static void BM_SetIteration(benchmark::State& state) {
|
||||
unsigned set_size = state.range(0);
|
||||
unsigned max_value = state.range(0) * state.range(1);
|
||||
|
||||
hb_set_t* original = hb_set_create ();
|
||||
RandomSet(set_size, max_value, original);
|
||||
assert(hb_set_get_population(original) == set_size);
|
||||
|
||||
hb_codepoint_t cp = HB_SET_VALUE_INVALID;
|
||||
for (auto _ : state) {
|
||||
hb_set_next (original, &cp);
|
||||
}
|
||||
|
||||
hb_set_destroy(original);
|
||||
}
|
||||
BENCHMARK(BM_SetIteration)
|
||||
->Ranges(
|
||||
{{1 << 10, 1 << 16}, // Set Size
|
||||
{2, 512}}); // Density
|
||||
|
||||
/* Set copy. */
|
||||
static void BM_SetCopy(benchmark::State& state) {
|
||||
unsigned set_size = state.range(0);
|
||||
unsigned max_value = state.range(0) * state.range(1);
|
||||
|
||||
hb_set_t* original = hb_set_create ();
|
||||
RandomSet(set_size, max_value, original);
|
||||
assert(hb_set_get_population(original) == set_size);
|
||||
|
||||
for (auto _ : state) {
|
||||
hb_set_t *s = hb_set_create ();
|
||||
hb_set_set (s, original);
|
||||
hb_set_destroy (s);
|
||||
}
|
||||
|
||||
hb_set_destroy(original);
|
||||
}
|
||||
BENCHMARK(BM_SetCopy)
|
||||
->Unit(benchmark::kMicrosecond)
|
||||
->Ranges(
|
||||
{{1 << 10, 1 << 16}, // Set Size
|
||||
{2, 512}}); // Density
|
||||
|
||||
BENCHMARK_MAIN();
|
|
@ -1,180 +0,0 @@
|
|||
#include "benchmark/benchmark.h"
|
||||
#include <cstring>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include "hb.h"
|
||||
#include "hb-ot.h"
|
||||
#ifdef HAVE_FREETYPE
|
||||
#include "hb-ft.h"
|
||||
#endif
|
||||
|
||||
#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
|
||||
|
||||
struct test_input_t
|
||||
{
|
||||
const char *font_path;
|
||||
const char *text_path;
|
||||
bool is_variable;
|
||||
} default_tests[] =
|
||||
{
|
||||
|
||||
{"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
|
||||
"perf/texts/fa-thelittleprince.txt",
|
||||
false},
|
||||
|
||||
{"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
|
||||
"perf/texts/fa-words.txt",
|
||||
false},
|
||||
|
||||
{"perf/fonts/Amiri-Regular.ttf",
|
||||
"perf/texts/fa-thelittleprince.txt",
|
||||
false},
|
||||
|
||||
{SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf",
|
||||
"perf/texts/hi-words.txt",
|
||||
false},
|
||||
|
||||
{"perf/fonts/Roboto-Regular.ttf",
|
||||
"perf/texts/en-thelittleprince.txt",
|
||||
false},
|
||||
|
||||
{"perf/fonts/Roboto-Regular.ttf",
|
||||
"perf/texts/en-words.txt",
|
||||
false},
|
||||
|
||||
{SUBSET_FONT_BASE_PATH "SourceSerifVariable-Roman.ttf",
|
||||
"perf/texts/en-thelittleprince.txt",
|
||||
true},
|
||||
};
|
||||
|
||||
static test_input_t *tests = default_tests;
|
||||
static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
|
||||
|
||||
enum backend_t { HARFBUZZ, FREETYPE };
|
||||
|
||||
static void BM_Shape (benchmark::State &state,
|
||||
bool is_var,
|
||||
backend_t backend,
|
||||
const test_input_t &input)
|
||||
{
|
||||
hb_font_t *font;
|
||||
{
|
||||
hb_blob_t *blob = hb_blob_create_from_file_or_fail (input.font_path);
|
||||
assert (blob);
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
hb_blob_destroy (blob);
|
||||
font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
if (is_var)
|
||||
{
|
||||
hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
|
||||
hb_font_set_variations (font, &wght, 1);
|
||||
}
|
||||
|
||||
switch (backend)
|
||||
{
|
||||
case HARFBUZZ:
|
||||
hb_ot_font_set_funcs (font);
|
||||
break;
|
||||
|
||||
case FREETYPE:
|
||||
#ifdef HAVE_FREETYPE
|
||||
hb_ft_font_set_funcs (font);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
hb_blob_t *text_blob = hb_blob_create_from_file_or_fail (input.text_path);
|
||||
assert (text_blob);
|
||||
unsigned orig_text_length;
|
||||
const char *orig_text = hb_blob_get_data (text_blob, &orig_text_length);
|
||||
|
||||
hb_buffer_t *buf = hb_buffer_create ();
|
||||
for (auto _ : state)
|
||||
{
|
||||
unsigned text_length = orig_text_length;
|
||||
const char *text = orig_text;
|
||||
|
||||
const char *end;
|
||||
while ((end = (const char *) memchr (text, '\n', text_length)))
|
||||
{
|
||||
hb_buffer_clear_contents (buf);
|
||||
hb_buffer_add_utf8 (buf, text, text_length, 0, end - text);
|
||||
hb_buffer_guess_segment_properties (buf);
|
||||
hb_shape (font, buf, nullptr, 0);
|
||||
|
||||
unsigned skip = end - text + 1;
|
||||
text_length -= skip;
|
||||
text += skip;
|
||||
}
|
||||
}
|
||||
hb_buffer_destroy (buf);
|
||||
|
||||
hb_blob_destroy (text_blob);
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
|
||||
static void test_backend (backend_t backend,
|
||||
const char *backend_name,
|
||||
bool variable,
|
||||
const test_input_t &test_input)
|
||||
{
|
||||
char name[1024] = "BM_Shape";
|
||||
const char *p;
|
||||
strcat (name, "/");
|
||||
p = strrchr (test_input.font_path, '/');
|
||||
strcat (name, p ? p + 1 : test_input.font_path);
|
||||
strcat (name, "/");
|
||||
p = strrchr (test_input.text_path, '/');
|
||||
strcat (name, p ? p + 1 : test_input.text_path);
|
||||
strcat (name, variable ? "/var" : "");
|
||||
strcat (name, "/");
|
||||
strcat (name, backend_name);
|
||||
|
||||
benchmark::RegisterBenchmark (name, BM_Shape, variable, backend, test_input)
|
||||
->Unit(benchmark::kMillisecond);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
benchmark::Initialize(&argc, argv);
|
||||
|
||||
if (argc > 2)
|
||||
{
|
||||
num_tests = (argc - 1) / 2;
|
||||
tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
|
||||
for (unsigned i = 0; i < num_tests; i++)
|
||||
{
|
||||
tests[i].is_variable = true;
|
||||
tests[i].font_path = argv[1 + i * 2];
|
||||
tests[i].text_path = argv[2 + i * 2];
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < num_tests; i++)
|
||||
{
|
||||
auto& test_input = tests[i];
|
||||
for (int variable = 0; variable < int (test_input.is_variable) + 1; variable++)
|
||||
{
|
||||
bool is_var = (bool) variable;
|
||||
|
||||
test_backend (HARFBUZZ, "hb", is_var, test_input);
|
||||
#ifdef HAVE_FREETYPE
|
||||
test_backend (FREETYPE, "ft", is_var, test_input);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Shutdown();
|
||||
|
||||
if (tests != default_tests)
|
||||
free (tests);
|
||||
}
|
|
@ -1,259 +0,0 @@
|
|||
#include "benchmark/benchmark.h"
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "hb-subset.h"
|
||||
|
||||
|
||||
enum operation_t
|
||||
{
|
||||
subset_codepoints,
|
||||
subset_glyphs,
|
||||
instance,
|
||||
};
|
||||
|
||||
struct axis_location_t
|
||||
{
|
||||
hb_tag_t axis_tag;
|
||||
float axis_value;
|
||||
};
|
||||
|
||||
static const axis_location_t
|
||||
_roboto_flex_instance_opts[] =
|
||||
{
|
||||
{HB_TAG ('w', 'g', 'h', 't'), 600.f},
|
||||
{HB_TAG ('w', 'd', 't', 'h'), 75.f},
|
||||
{HB_TAG ('o', 'p', 's', 'z'), 90.f},
|
||||
{HB_TAG ('G', 'R', 'A', 'D'), -100.f},
|
||||
{HB_TAG ('s', 'l', 'n', 't'), -3.f},
|
||||
{HB_TAG ('X', 'T', 'R', 'A'), 500.f},
|
||||
{HB_TAG ('X', 'O', 'P', 'Q'), 150.f},
|
||||
{HB_TAG ('Y', 'O', 'P', 'Q'), 100.f},
|
||||
{HB_TAG ('Y', 'T', 'L', 'C'), 480.f},
|
||||
{HB_TAG ('Y', 'T', 'U', 'C'), 600.f},
|
||||
{HB_TAG ('Y', 'T', 'A', 'S'), 800.f},
|
||||
{HB_TAG ('Y', 'T', 'D', 'E'), -50.f},
|
||||
{HB_TAG ('Y', 'T', 'F', 'I'), 600.f},
|
||||
};
|
||||
|
||||
static const axis_location_t
|
||||
_mplus_instance_opts[] =
|
||||
{
|
||||
{HB_TAG ('w', 'g', 'h', 't'), 800.f},
|
||||
};
|
||||
|
||||
template <typename Type, unsigned int n>
|
||||
static inline unsigned int ARRAY_LEN (const Type (&)[n]) { return n; }
|
||||
|
||||
#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
|
||||
|
||||
struct test_input_t
|
||||
{
|
||||
const char *font_path;
|
||||
unsigned max_subset_size;
|
||||
const axis_location_t *instance_opts;
|
||||
unsigned num_instance_opts;
|
||||
} default_tests[] =
|
||||
{
|
||||
{SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf", 1000, nullptr, 0},
|
||||
{SUBSET_FONT_BASE_PATH "Amiri-Regular.ttf", 4096, nullptr, 0},
|
||||
{SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf", 1400, nullptr, 0},
|
||||
{SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf", 1000, nullptr, 0},
|
||||
{SUBSET_FONT_BASE_PATH "Mplus1p-Regular.ttf", 10000, nullptr, 0},
|
||||
{SUBSET_FONT_BASE_PATH "SourceHanSans-Regular_subset.otf", 10000, nullptr, 0},
|
||||
{SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf", 2000, nullptr, 0},
|
||||
{SUBSET_FONT_BASE_PATH "AdobeVFPrototype.otf", 300, nullptr, 0},
|
||||
{SUBSET_FONT_BASE_PATH "MPLUS1-Variable.ttf", 6000, _mplus_instance_opts, ARRAY_LEN (_mplus_instance_opts)},
|
||||
{SUBSET_FONT_BASE_PATH "RobotoFlex-Variable.ttf", 900, _roboto_flex_instance_opts, ARRAY_LEN (_roboto_flex_instance_opts)},
|
||||
#if 0
|
||||
{"perf/fonts/NotoSansCJKsc-VF.ttf", 100000},
|
||||
#endif
|
||||
};
|
||||
|
||||
static test_input_t *tests = default_tests;
|
||||
static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
|
||||
|
||||
|
||||
void AddCodepoints(const hb_set_t* codepoints_in_font,
|
||||
unsigned subset_size,
|
||||
hb_subset_input_t* input)
|
||||
{
|
||||
auto *unicodes = hb_subset_input_unicode_set (input);
|
||||
hb_codepoint_t cp = HB_SET_VALUE_INVALID;
|
||||
for (unsigned i = 0; i < subset_size; i++) {
|
||||
// TODO(garretrieger): pick randomly.
|
||||
if (!hb_set_next (codepoints_in_font, &cp)) return;
|
||||
hb_set_add (unicodes, cp);
|
||||
}
|
||||
}
|
||||
|
||||
void AddGlyphs(unsigned num_glyphs_in_font,
|
||||
unsigned subset_size,
|
||||
hb_subset_input_t* input)
|
||||
{
|
||||
auto *glyphs = hb_subset_input_glyph_set (input);
|
||||
for (unsigned i = 0; i < subset_size && i < num_glyphs_in_font; i++) {
|
||||
// TODO(garretrieger): pick randomly.
|
||||
hb_set_add (glyphs, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Preprocess face and populate the subset accelerator on it to speed up
|
||||
// the subsetting operations.
|
||||
static hb_face_t* preprocess_face(hb_face_t* face)
|
||||
{
|
||||
hb_face_t* new_face = hb_subset_preprocess(face);
|
||||
hb_face_destroy(face);
|
||||
return new_face;
|
||||
}
|
||||
|
||||
/* benchmark for subsetting a font */
|
||||
static void BM_subset (benchmark::State &state,
|
||||
operation_t operation,
|
||||
const test_input_t &test_input,
|
||||
bool hinting)
|
||||
{
|
||||
unsigned subset_size = state.range(0);
|
||||
|
||||
hb_face_t *face = nullptr;
|
||||
|
||||
static hb_face_t *cached_face;
|
||||
static const char *cached_font_path;
|
||||
|
||||
if (!cached_font_path || strcmp (cached_font_path, test_input.font_path))
|
||||
{
|
||||
hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
|
||||
assert (blob);
|
||||
face = hb_face_create (blob, 0);
|
||||
hb_blob_destroy (blob);
|
||||
|
||||
face = preprocess_face (face);
|
||||
|
||||
if (cached_face)
|
||||
hb_face_destroy (cached_face);
|
||||
|
||||
cached_face = hb_face_reference (face);
|
||||
cached_font_path = test_input.font_path;
|
||||
}
|
||||
else
|
||||
face = hb_face_reference (cached_face);
|
||||
|
||||
hb_subset_input_t* input = hb_subset_input_create_or_fail ();
|
||||
assert (input);
|
||||
|
||||
if (!hinting)
|
||||
hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_NO_HINTING);
|
||||
|
||||
switch (operation)
|
||||
{
|
||||
case subset_codepoints:
|
||||
{
|
||||
hb_set_t* all_codepoints = hb_set_create ();
|
||||
hb_face_collect_unicodes (face, all_codepoints);
|
||||
AddCodepoints(all_codepoints, subset_size, input);
|
||||
hb_set_destroy (all_codepoints);
|
||||
}
|
||||
break;
|
||||
|
||||
case subset_glyphs:
|
||||
{
|
||||
unsigned num_glyphs = hb_face_get_glyph_count (face);
|
||||
AddGlyphs(num_glyphs, subset_size, input);
|
||||
}
|
||||
break;
|
||||
|
||||
case instance:
|
||||
{
|
||||
hb_set_t* all_codepoints = hb_set_create ();
|
||||
hb_face_collect_unicodes (face, all_codepoints);
|
||||
AddCodepoints(all_codepoints, subset_size, input);
|
||||
hb_set_destroy (all_codepoints);
|
||||
|
||||
for (unsigned i = 0; i < test_input.num_instance_opts; i++)
|
||||
hb_subset_input_pin_axis_location (input, face,
|
||||
test_input.instance_opts[i].axis_tag,
|
||||
test_input.instance_opts[i].axis_value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
hb_face_t* subset = hb_subset_or_fail (face, input);
|
||||
assert (subset);
|
||||
hb_face_destroy (subset);
|
||||
}
|
||||
|
||||
hb_subset_input_destroy (input);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
static void test_subset (operation_t op,
|
||||
const char *op_name,
|
||||
bool hinting,
|
||||
benchmark::TimeUnit time_unit,
|
||||
const test_input_t &test_input)
|
||||
{
|
||||
if (op == instance && test_input.instance_opts == nullptr)
|
||||
return;
|
||||
|
||||
char name[1024] = "BM_subset/";
|
||||
strcat (name, op_name);
|
||||
strcat (name, "/");
|
||||
const char *p = strrchr (test_input.font_path, '/');
|
||||
strcat (name, p ? p + 1 : test_input.font_path);
|
||||
if (!hinting)
|
||||
strcat (name, "/nohinting");
|
||||
|
||||
benchmark::RegisterBenchmark (name, BM_subset, op, test_input, hinting)
|
||||
->Range(10, test_input.max_subset_size)
|
||||
->Unit(time_unit);
|
||||
}
|
||||
|
||||
static void test_operation (operation_t op,
|
||||
const char *op_name,
|
||||
const test_input_t *tests,
|
||||
unsigned num_tests,
|
||||
benchmark::TimeUnit time_unit)
|
||||
{
|
||||
for (unsigned i = 0; i < num_tests; i++)
|
||||
{
|
||||
auto& test_input = tests[i];
|
||||
test_subset (op, op_name, true, time_unit, test_input);
|
||||
test_subset (op, op_name, false, time_unit, test_input);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
benchmark::Initialize(&argc, argv);
|
||||
|
||||
if (argc > 1)
|
||||
{
|
||||
num_tests = (argc - 1) / 2;
|
||||
tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
|
||||
for (unsigned i = 0; i < num_tests; i++)
|
||||
{
|
||||
tests[i].font_path = argv[1 + i * 2];
|
||||
tests[i].max_subset_size = atoi (argv[2 + i * 2]);
|
||||
}
|
||||
}
|
||||
|
||||
#define TEST_OPERATION(op, time_unit) test_operation (op, #op, tests, num_tests, time_unit)
|
||||
|
||||
TEST_OPERATION (subset_glyphs, benchmark::kMillisecond);
|
||||
TEST_OPERATION (subset_codepoints, benchmark::kMillisecond);
|
||||
TEST_OPERATION (instance, benchmark::kMillisecond);
|
||||
|
||||
#undef TEST_OPERATION
|
||||
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Shutdown();
|
||||
|
||||
if (tests != default_tests)
|
||||
free (tests);
|
||||
}
|
|
@ -1,62 +1,27 @@
|
|||
google_benchmark = subproject('google-benchmark')
|
||||
google_benchmark_dep = google_benchmark.get_variable('google_benchmark_dep')
|
||||
|
||||
benchmark('benchmark-font', executable('benchmark-font', 'benchmark-font.cc',
|
||||
ttf_parser_dep = null_dep
|
||||
if get_option('experimental_api') and add_languages('rust', required: false, native: true)
|
||||
ttf_parser_dep = subproject('ttf-parser').get_variable('ttf_parser_dep')
|
||||
endif
|
||||
|
||||
if ttf_parser_dep.found()
|
||||
benchmark_cpp_args = ['-DHAVE_TTFPARSER']
|
||||
else
|
||||
benchmark_cpp_args = []
|
||||
endif
|
||||
|
||||
benchmark('perf', executable('perf', 'perf.cc',
|
||||
dependencies: [
|
||||
google_benchmark_dep, freetype_dep,
|
||||
|
||||
# the last two, thread and dl, aren't nice as ttf-parser isn't no_std yet
|
||||
# https://github.com/RazrFalcon/ttf-parser/issues/29
|
||||
ttf_parser_dep, thread_dep, cpp.find_library('dl'),
|
||||
],
|
||||
cpp_args: [],
|
||||
cpp_args: benchmark_cpp_args,
|
||||
include_directories: [incconfig, incsrc],
|
||||
link_with: [libharfbuzz],
|
||||
install: false,
|
||||
), workdir: meson.current_source_dir() / '..', timeout: 100)
|
||||
|
||||
benchmark('benchmark-map', executable('benchmark-map', 'benchmark-map.cc',
|
||||
dependencies: [
|
||||
google_benchmark_dep,
|
||||
],
|
||||
cpp_args: [],
|
||||
include_directories: [incconfig, incsrc],
|
||||
link_with: [libharfbuzz],
|
||||
install: false,
|
||||
), workdir: meson.current_source_dir() / '..', timeout: 100)
|
||||
|
||||
benchmark('benchmark-ot', executable('benchmark-ot', 'benchmark-ot.cc',
|
||||
dependencies: [
|
||||
google_benchmark_dep,
|
||||
],
|
||||
cpp_args: [],
|
||||
include_directories: [incconfig, incsrc],
|
||||
link_with: [libharfbuzz],
|
||||
install: false,
|
||||
), workdir: meson.current_source_dir() / '..', timeout: 100)
|
||||
|
||||
benchmark('benchmark-set', executable('benchmark-set', 'benchmark-set.cc',
|
||||
dependencies: [
|
||||
google_benchmark_dep,
|
||||
],
|
||||
cpp_args: [],
|
||||
include_directories: [incconfig, incsrc],
|
||||
link_with: [libharfbuzz],
|
||||
install: false,
|
||||
), workdir: meson.current_source_dir() / '..', timeout: 100)
|
||||
|
||||
benchmark('benchmark-shape', executable('benchmark-shape', 'benchmark-shape.cc',
|
||||
dependencies: [
|
||||
google_benchmark_dep, freetype_dep,
|
||||
],
|
||||
cpp_args: [],
|
||||
include_directories: [incconfig, incsrc],
|
||||
link_with: [libharfbuzz],
|
||||
install: false,
|
||||
), workdir: meson.current_source_dir() / '..', timeout: 100)
|
||||
|
||||
benchmark('benchmark-subset', executable('benchmark-subset', 'benchmark-subset.cc',
|
||||
dependencies: [
|
||||
google_benchmark_dep,
|
||||
],
|
||||
cpp_args: [],
|
||||
include_directories: [incconfig, incsrc],
|
||||
link_with: [libharfbuzz, libharfbuzz_subset],
|
||||
install: false,
|
||||
), workdir: meson.current_source_dir() / '..', timeout: 100)
|
||||
), workdir: join_paths(meson.current_source_dir(), '..'), timeout: 100)
|
||||
|
|
|
@ -0,0 +1,177 @@
|
|||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "hb.h"
|
||||
#include "hb-ot.h"
|
||||
#include "hb-ft.h"
|
||||
#include FT_OUTLINE_H
|
||||
|
||||
#ifdef HAVE_TTFPARSER
|
||||
#include "ttfparser.h"
|
||||
#endif
|
||||
|
||||
#define HB_UNUSED __attribute__((unused))
|
||||
|
||||
static void
|
||||
_hb_move_to (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_hb_line_to (hb_position_t to_x HB_UNUSED, hb_position_t to_y HB_UNUSED, void *user_data HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_hb_quadratic_to (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
|
||||
_hb_cubic_to (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
|
||||
_hb_close_path (void *user_data HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_ft_move_to (const FT_Vector* to HB_UNUSED, void* user HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_ft_line_to (const FT_Vector* to HB_UNUSED, void* user HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_ft_conic_to (const FT_Vector* control HB_UNUSED, const FT_Vector* to HB_UNUSED,
|
||||
void* user HB_UNUSED) {}
|
||||
|
||||
static void
|
||||
_ft_cubic_to (const FT_Vector* control1 HB_UNUSED, const FT_Vector* control2 HB_UNUSED,
|
||||
const FT_Vector* to HB_UNUSED, void* user HB_UNUSED) {}
|
||||
|
||||
#ifdef HAVE_TTFPARSER
|
||||
static void _tp_move_to (float x HB_UNUSED, float y HB_UNUSED, void *data HB_UNUSED) {}
|
||||
static void _tp_line_to (float x, float y, void *data) {}
|
||||
static void _tp_quad_to (float x1, float y1, float x, float y, void *data) {}
|
||||
static void _tp_curve_to (float x1, float y1, float x2, float y2, float x, float y, void *data) {}
|
||||
static void _tp_close_path (void *data) {}
|
||||
#endif
|
||||
|
||||
static void draw (benchmark::State &state, const char *font_path, bool is_var, backend_t backend)
|
||||
{
|
||||
hb_font_t *font;
|
||||
unsigned num_glyphs;
|
||||
{
|
||||
hb_blob_t *blob = hb_blob_create_from_file (font_path);
|
||||
assert (hb_blob_get_length (blob));
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
hb_blob_destroy (blob);
|
||||
num_glyphs = hb_face_get_glyph_count (face);
|
||||
font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
if (backend == HARFBUZZ)
|
||||
{
|
||||
if (is_var)
|
||||
{
|
||||
hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
|
||||
hb_font_set_variations (font, &wght, 1);
|
||||
}
|
||||
hb_draw_funcs_t *draw_funcs = hb_draw_funcs_create ();
|
||||
hb_draw_funcs_set_move_to_func (draw_funcs, _hb_move_to);
|
||||
hb_draw_funcs_set_line_to_func (draw_funcs, _hb_line_to);
|
||||
hb_draw_funcs_set_quadratic_to_func (draw_funcs, _hb_quadratic_to);
|
||||
hb_draw_funcs_set_cubic_to_func (draw_funcs, _hb_cubic_to);
|
||||
hb_draw_funcs_set_close_path_func (draw_funcs, _hb_close_path);
|
||||
|
||||
for (auto _ : state)
|
||||
for (unsigned gid = 0; gid < num_glyphs; ++gid)
|
||||
hb_font_draw_glyph (font, gid, draw_funcs, nullptr);
|
||||
|
||||
hb_draw_funcs_destroy (draw_funcs);
|
||||
}
|
||||
else if (backend == FREETYPE)
|
||||
{
|
||||
if (is_var)
|
||||
{
|
||||
hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
|
||||
hb_font_set_variations (font, &wght, 1);
|
||||
}
|
||||
hb_ft_font_set_funcs (font);
|
||||
FT_Face ft_face = hb_ft_font_get_face (font);
|
||||
hb_ft_font_set_load_flags (font, FT_LOAD_NO_HINTING | FT_LOAD_NO_SCALE);
|
||||
|
||||
FT_Outline_Funcs draw_funcs;
|
||||
draw_funcs.move_to = (FT_Outline_MoveToFunc) _ft_move_to;
|
||||
draw_funcs.line_to = (FT_Outline_LineToFunc) _ft_line_to;
|
||||
draw_funcs.conic_to = (FT_Outline_ConicToFunc) _ft_conic_to;
|
||||
draw_funcs.cubic_to = (FT_Outline_CubicToFunc) _ft_cubic_to;
|
||||
draw_funcs.shift = 0;
|
||||
draw_funcs.delta = 0;
|
||||
|
||||
for (auto _ : state)
|
||||
for (unsigned gid = 0; gid < num_glyphs; ++gid)
|
||||
{
|
||||
FT_Load_Glyph (ft_face, gid, FT_LOAD_NO_HINTING | FT_LOAD_NO_SCALE);
|
||||
FT_Outline_Decompose (&ft_face->glyph->outline, &draw_funcs, nullptr);
|
||||
}
|
||||
}
|
||||
else if (backend == TTF_PARSER)
|
||||
{
|
||||
#ifdef HAVE_TTFPARSER
|
||||
ttfp_face *tp_font = (ttfp_face *) malloc (ttfp_face_size_of ());
|
||||
hb_blob_t *blob = hb_face_reference_blob (hb_font_get_face (font));
|
||||
assert (ttfp_face_init (hb_blob_get_data (blob, nullptr), hb_blob_get_length (blob), 0, tp_font));
|
||||
if (is_var) ttfp_set_variation (tp_font, TTFP_TAG('w','g','h','t'), 500);
|
||||
|
||||
ttfp_outline_builder builder;
|
||||
builder.move_to = _tp_move_to;
|
||||
builder.line_to = _tp_line_to;
|
||||
builder.quad_to = _tp_quad_to;
|
||||
builder.curve_to = _tp_curve_to;
|
||||
builder.close_path = _tp_close_path;
|
||||
|
||||
ttfp_rect bbox;
|
||||
for (auto _ : state)
|
||||
for (unsigned gid = 0; gid < num_glyphs; ++gid)
|
||||
ttfp_outline_glyph (tp_font, builder, &builder, gid, &bbox);
|
||||
|
||||
hb_blob_destroy (blob);
|
||||
free (tp_font);
|
||||
#endif
|
||||
}
|
||||
else abort ();
|
||||
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
|
||||
#define FONT_BASE_PATH "test/subset/data/fonts/"
|
||||
|
||||
BENCHMARK_CAPTURE (draw, cff - ot - SourceSansPro, FONT_BASE_PATH "SourceSansPro-Regular.otf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (draw, cff - ft - SourceSansPro, FONT_BASE_PATH "SourceSansPro-Regular.otf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (draw, cff - tp - SourceSansPro, FONT_BASE_PATH "SourceSansPro-Regular.otf", false, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (draw, cff2 - ot - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (draw, cff2 - ft - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (draw, cff2 - tp - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", false, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (draw, cff2/vf - ot - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", true, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (draw, cff2/vf - ft - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", true, FREETYPE);
|
||||
BENCHMARK_CAPTURE (draw, cff2/vf - tp - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", true, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (draw, glyf - ot - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (draw, glyf - ft - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (draw, glyf - tp - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", false, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (draw, glyf/vf - ot - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", true, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (draw, glyf/vf - ft - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", true, FREETYPE);
|
||||
BENCHMARK_CAPTURE (draw, glyf/vf - tp - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", true, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (draw, glyf - ot - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (draw, glyf - ft - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (draw, glyf - tp - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", false, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (draw, glyf/vf - ot - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", true, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (draw, glyf/vf - ft - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", true, FREETYPE);
|
||||
BENCHMARK_CAPTURE (draw, glyf/vf - tp - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", true, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (draw, glyf - ot - Roboto, FONT_BASE_PATH "Roboto-Regular.ttf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (draw, glyf - ft - Roboto, FONT_BASE_PATH "Roboto-Regular.ttf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (draw, glyf - tp - Roboto, FONT_BASE_PATH "Roboto-Regular.ttf", false, TTF_PARSER);
|
|
@ -0,0 +1,98 @@
|
|||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "hb.h"
|
||||
#include "hb-ft.h"
|
||||
#include "hb-ot.h"
|
||||
|
||||
#ifdef HAVE_TTFPARSER
|
||||
#include "ttfparser.h"
|
||||
#endif
|
||||
|
||||
static void extents (benchmark::State &state, const char *font_path, bool is_var, backend_t backend)
|
||||
{
|
||||
hb_font_t *font;
|
||||
unsigned num_glyphs;
|
||||
{
|
||||
hb_blob_t *blob = hb_blob_create_from_file (font_path);
|
||||
assert (hb_blob_get_length (blob));
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
hb_blob_destroy (blob);
|
||||
num_glyphs = hb_face_get_glyph_count (face);
|
||||
font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
if (is_var)
|
||||
{
|
||||
hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
|
||||
hb_font_set_variations (font, &wght, 1);
|
||||
}
|
||||
|
||||
if (backend == HARFBUZZ || backend == FREETYPE)
|
||||
{
|
||||
if (backend == FREETYPE)
|
||||
{
|
||||
hb_ft_font_set_funcs (font);
|
||||
hb_ft_font_set_load_flags (font, FT_LOAD_NO_HINTING | FT_LOAD_NO_SCALE);
|
||||
}
|
||||
|
||||
hb_glyph_extents_t extents;
|
||||
for (auto _ : state)
|
||||
for (unsigned gid = 0; gid < num_glyphs; ++gid)
|
||||
hb_font_get_glyph_extents (font, gid, &extents);
|
||||
}
|
||||
else if (backend == TTF_PARSER)
|
||||
{
|
||||
#ifdef HAVE_TTFPARSER
|
||||
ttfp_face *tp_font = (ttfp_face *) malloc (ttfp_face_size_of ());
|
||||
hb_blob_t *blob = hb_face_reference_blob (hb_font_get_face (font));
|
||||
assert (ttfp_face_init (hb_blob_get_data (blob, nullptr), hb_blob_get_length (blob), 0, tp_font));
|
||||
if (is_var) ttfp_set_variation (tp_font, TTFP_TAG('w','g','h','t'), 500);
|
||||
|
||||
ttfp_rect bbox;
|
||||
for (auto _ : state)
|
||||
for (unsigned gid = 0; gid < num_glyphs; ++gid)
|
||||
ttfp_get_glyph_bbox(tp_font, gid, &bbox);
|
||||
|
||||
hb_blob_destroy (blob);
|
||||
free (tp_font);
|
||||
#endif
|
||||
}
|
||||
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
|
||||
#define FONT_BASE_PATH "test/subset/data/fonts/"
|
||||
|
||||
BENCHMARK_CAPTURE (extents, cff - ot - SourceSansPro, FONT_BASE_PATH "SourceSansPro-Regular.otf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (extents, cff - ft - SourceSansPro, FONT_BASE_PATH "SourceSansPro-Regular.otf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (extents, cff - tp - SourceSansPro, FONT_BASE_PATH "SourceSansPro-Regular.otf", false, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (extents, cff2 - ot - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (extents, cff2 - ft - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (extents, cff2 - tp - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", false, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (extents, cff2/vf - ot - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", true, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (extents, cff2/vf - ft - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", true, FREETYPE);
|
||||
BENCHMARK_CAPTURE (extents, cff2/vf - tp - AdobeVFPrototype, FONT_BASE_PATH "AdobeVFPrototype.otf", true, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (extents, glyf - ot - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (extents, glyf - ft - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (extents, glyf - tp - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", false, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (extents, glyf/vf - ot - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", true, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (extents, glyf/vf - ft - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", true, FREETYPE);
|
||||
BENCHMARK_CAPTURE (extents, glyf/vf - tp - SourceSerifVariable, FONT_BASE_PATH "SourceSerifVariable-Roman.ttf", true, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (extents, glyf - ot - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (extents, glyf - ft - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (extents, glyf - tp - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", false, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (extents, glyf/vf - ot - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", true, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (extents, glyf/vf - ft - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", true, FREETYPE);
|
||||
BENCHMARK_CAPTURE (extents, glyf/vf - tp - Comfortaa, FONT_BASE_PATH "Comfortaa-Regular-new.ttf", true, TTF_PARSER);
|
||||
|
||||
BENCHMARK_CAPTURE (extents, glyf - ot - Roboto, FONT_BASE_PATH "Roboto-Regular.ttf", false, HARFBUZZ);
|
||||
BENCHMARK_CAPTURE (extents, glyf - ft - Roboto, FONT_BASE_PATH "Roboto-Regular.ttf", false, FREETYPE);
|
||||
BENCHMARK_CAPTURE (extents, glyf - tp - Roboto, FONT_BASE_PATH "Roboto-Regular.ttf", false, TTF_PARSER);
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
#include "benchmark/benchmark.h"
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
static void shape (benchmark::State &state, const char *text_path,
|
||||
hb_direction_t direction, hb_script_t script,
|
||||
const char *font_path)
|
||||
{
|
||||
hb_font_t *font;
|
||||
{
|
||||
hb_blob_t *blob = hb_blob_create_from_file (font_path);
|
||||
assert (hb_blob_get_length (blob));
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
hb_blob_destroy (blob);
|
||||
font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
}
|
||||
|
||||
hb_blob_t *text_blob = hb_blob_create_from_file (text_path);
|
||||
unsigned text_length;
|
||||
const char *text = hb_blob_get_data (text_blob, &text_length);
|
||||
assert (text_length);
|
||||
|
||||
hb_buffer_t *buf = hb_buffer_create ();
|
||||
for (auto _ : state)
|
||||
{
|
||||
hb_buffer_add_utf8 (buf, text, text_length, 0, -1);
|
||||
hb_buffer_set_direction (buf, direction);
|
||||
hb_buffer_set_script (buf, script);
|
||||
hb_shape (font, buf, nullptr, 0);
|
||||
hb_buffer_clear_contents (buf);
|
||||
}
|
||||
hb_buffer_destroy (buf);
|
||||
|
||||
hb_blob_destroy (text_blob);
|
||||
hb_font_destroy (font);
|
||||
}
|
||||
|
||||
BENCHMARK_CAPTURE (shape, fa-thelittleprince.txt - Amiri,
|
||||
"perf/texts/fa-thelittleprince.txt",
|
||||
HB_DIRECTION_RTL, HB_SCRIPT_ARABIC,
|
||||
"perf/fonts/Amiri-Regular.ttf");
|
||||
BENCHMARK_CAPTURE (shape, fa-thelittleprince.txt - NotoNastaliqUrdu,
|
||||
"perf/texts/fa-thelittleprince.txt",
|
||||
HB_DIRECTION_RTL, HB_SCRIPT_ARABIC,
|
||||
"perf/fonts/NotoNastaliqUrdu-Regular.ttf");
|
||||
|
||||
BENCHMARK_CAPTURE (shape, fa-monologue.txt - Amiri,
|
||||
"perf/texts/fa-monologue.txt",
|
||||
HB_DIRECTION_RTL, HB_SCRIPT_ARABIC,
|
||||
"perf/fonts/Amiri-Regular.ttf");
|
||||
BENCHMARK_CAPTURE (shape, fa-monologue.txt - NotoNastaliqUrdu,
|
||||
"perf/texts/fa-monologue.txt",
|
||||
HB_DIRECTION_RTL, HB_SCRIPT_ARABIC,
|
||||
"perf/fonts/NotoNastaliqUrdu-Regular.ttf");
|
||||
|
||||
BENCHMARK_CAPTURE (shape, en-thelittleprince.txt - Roboto,
|
||||
"perf/texts/en-thelittleprince.txt",
|
||||
HB_DIRECTION_LTR, HB_SCRIPT_LATIN,
|
||||
"perf/fonts/Roboto-Regular.ttf");
|
||||
|
||||
BENCHMARK_CAPTURE (shape, en-words.txt - Roboto,
|
||||
"perf/texts/en-words.txt",
|
||||
HB_DIRECTION_LTR, HB_SCRIPT_LATIN,
|
||||
"perf/fonts/Roboto-Regular.ttf");
|
|
@ -0,0 +1,16 @@
|
|||
#include "benchmark/benchmark.h"
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "perf-shaping.hh"
|
||||
#ifdef HAVE_FREETYPE
|
||||
enum backend_t { HARFBUZZ, FREETYPE, TTF_PARSER };
|
||||
#include "perf-extents.hh"
|
||||
#ifdef HB_EXPERIMENTAL_API
|
||||
#include "perf-draw.hh"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
BENCHMARK_MAIN ();
|
|
@ -0,0 +1,25 @@
|
|||
#!/bin/bash
|
||||
CXX=clang++
|
||||
FONT=fonts/NotoNastaliqUrdu-Regular.ttf
|
||||
TEXT=texts/fa-monologue.txt
|
||||
|
||||
$CXX ../util/hb-shape.cc ../util/options.cc ../src/harfbuzz.cc \
|
||||
-lm -fno-rtti -fno-exceptions -fno-omit-frame-pointer -DHB_NO_MT \
|
||||
-I../src $FLAGS $SOURCES \
|
||||
-DPACKAGE_NAME='""' -DPACKAGE_VERSION='""' \
|
||||
-DHAVE_GLIB $(pkg-config --cflags --libs glib-2.0) \
|
||||
-o hb-shape -g -O2 # -O3 \
|
||||
#-march=native -mtune=native \
|
||||
#-Rpass=loop-vectorize -Rpass-missed=loop-vectorize \
|
||||
#-Rpass-analysis=loop-vectorize -fsave-optimization-record
|
||||
|
||||
# -march=native: enable all vector instructions current CPU can offer
|
||||
# -Rpass*: https://llvm.org/docs/Vectorizers.html#diagnostics
|
||||
|
||||
#sudo rm capture.syscap > /dev/null
|
||||
#sysprof-cli -c "./a.out $@"
|
||||
#sysprof capture.syscap
|
||||
|
||||
perf stat ./hb-shape -o /dev/null $FONT --text-file $TEXT --num-iterations=100 --font-funcs=ot
|
||||
#perf record -g ./hb-shape -O '' -o /dev/null $FONT --text-file $TEXT --num-iterations=100 --font-funcs=ot
|
||||
#perf report -g
|
|
@ -2841,6 +2841,7 @@ Deseret
|
|||
DESERET
|
||||
deserialize
|
||||
DESERIALIZE
|
||||
desgined
|
||||
design
|
||||
Design
|
||||
DESIGN
|
||||
|
@ -4782,7 +4783,7 @@ hb
|
|||
HB
|
||||
HBASELINE
|
||||
HBFixed
|
||||
HBGlyphID16
|
||||
HBGlyphID
|
||||
HBINT
|
||||
hbot
|
||||
hbotABCD
|
||||
|
|
File diff suppressed because one or more lines are too long
10000
perf/texts/fa-words.txt
10000
perf/texts/fa-words.txt
File diff suppressed because it is too large
Load Diff
10000
perf/texts/hi-words.txt
10000
perf/texts/hi-words.txt
File diff suppressed because it is too large
Load Diff
|
@ -1,250 +0,0 @@
|
|||
#
|
||||
# Name: Legacy Simplified Arabic encoding
|
||||
#
|
||||
# Format: Three tab-separated columns
|
||||
# Column #1 is the PUA code (in hex as 0xXXXX)
|
||||
# Column #2 is the Unicode (in hex as 0xXXXX)
|
||||
# Column #3 is the Unicode name (follows a comment sign, '#')
|
||||
#
|
||||
# The entries are in PUA order
|
||||
#
|
||||
0xF100 0x063B # ARABIC LETTER KEHEH WITH TWO DOTS ABOVE
|
||||
0xF100 0x063C # ARABIC LETTER KEHEH WITH THREE DOTS BELOW
|
||||
0xF100 0x063D # ARABIC LETTER FARSI YEH WITH INVERTED V
|
||||
0xF100 0x063E # ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE
|
||||
0xF100 0x063F # ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
|
||||
0xF100 0x0653 # ARABIC MADDAH ABOVE
|
||||
0xF100 0x0654 # ARABIC HAMZA ABOVE
|
||||
0xF100 0x0655 # ARABIC HAMZA BELOW
|
||||
0xF100 0x0656 # ARABIC SUBSCRIPT ALEF
|
||||
0xF100 0x0657 # ARABIC INVERTED DAMMA
|
||||
0xF100 0x0658 # ARABIC MARK NOON GHUNNA
|
||||
0xF100 0x0659 # ARABIC ZWARAKAY
|
||||
0xF100 0x065A # ARABIC VOWEL SIGN SMALL V ABOVE
|
||||
0xF100 0x065B # ARABIC VOWEL SIGN INVERTED SMALL V ABOVE
|
||||
0xF100 0x065C # ARABIC VOWEL SIGN DOT BELOW
|
||||
0xF100 0x065D # ARABIC REVERSED DAMMA
|
||||
0xF100 0x065E # ARABIC FATHA WITH TWO DOTS
|
||||
0xF10C 0x200C # ZERO WIDTH NON-JOINER
|
||||
0xF10D 0x200D # ZERO WIDTH JOINER
|
||||
0xF10E 0x200E # LEFT-TO-RIGHT MARK
|
||||
0xF10F 0x200F # RIGHT-TO-LEFT MARK
|
||||
0xF120 0x0020 # SPACE
|
||||
0xF121 0x0021 # EXCLAMATION MARK
|
||||
0xF122 0x0022 # QUOTATION MARK
|
||||
0xF123 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
0xF124 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
0xF125 0x0025 # PERCENT SIGN
|
||||
0xF126 0x00D7 # MULTIPLICATION SIGN
|
||||
0xF127 0x00F7 # DIVISION SIGN
|
||||
0xF128 0x0028 # LEFT PARENTHESIS
|
||||
0xF129 0x0029 # RIGHT PARENTHESIS
|
||||
0xF12A 0x002A # ASTERISK
|
||||
0xF12B 0x002B # PLUS SIGN
|
||||
0xF12C 0x060C # ARABIC COMMA
|
||||
0xF12D 0x002D # HYPHEN-MINUS
|
||||
0xF12E 0x002E # FULL STOP
|
||||
0xF12F 0x002F # SOLIDUS
|
||||
0xF130 0x0660 # ARABIC-INDIC DIGIT ZERO
|
||||
0xF131 0x0661 # ARABIC-INDIC DIGIT ONE
|
||||
0xF132 0x0662 # ARABIC-INDIC DIGIT TWO
|
||||
0xF133 0x0663 # ARABIC-INDIC DIGIT THREE
|
||||
0xF134 0x0664 # ARABIC-INDIC DIGIT FOUR
|
||||
0xF135 0x0665 # ARABIC-INDIC DIGIT FIVE
|
||||
0xF136 0x0666 # ARABIC-INDIC DIGIT SIX
|
||||
0xF137 0x0667 # ARABIC-INDIC DIGIT SEVEN
|
||||
0xF138 0x0668 # ARABIC-INDIC DIGIT EIGHT
|
||||
0xF139 0x0669 # ARABIC-INDIC DIGIT NINE
|
||||
0xF13A 0x003A # COLON
|
||||
0xF13B 0x003B # SEMICOLON
|
||||
0xF13B 0x061B # ARABIC SEMICOLON
|
||||
0xF13C 0x2018 # LEFT SINGLE QUOTATION MARK
|
||||
0xF13D 0x003D # EQUALS SIGN
|
||||
0xF13E 0x2019 # RIGHT SINGLE QUOTATION MARK
|
||||
0xF13F 0x003F # QUESTION MARK
|
||||
0xF13F 0x061F # ARABIC QUESTION MARK
|
||||
0xF141 0x0627 # ARABIC LETTER ALEF
|
||||
0xF141 0xFE8D # ARABIC LETTER ALEF ISOLATED FORM
|
||||
0xF142 0xFE8E # ARABIC LETTER ALEF FINAL FORM
|
||||
0xF143 0x0623 # ARABIC LETTER ALEF WITH HAMZA ABOVE
|
||||
0xF143 0xFE83 # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
|
||||
0xF144 0xFE84 # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
|
||||
0xF145 0x0622 # ARABIC LETTER ALEF WITH MADDA ABOVE
|
||||
0xF145 0xFE81 # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
|
||||
0xF146 0xFE82 # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
|
||||
0xF147 0x0625 # ARABIC LETTER ALEF WITH HAMZA BELOW
|
||||
0xF147 0xFE87 # ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM
|
||||
0xF148 0xFE88 # ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM
|
||||
0xF149 0xFE91 # ARABIC LETTER BEH INITIAL FORM
|
||||
0xF149 0xFE92 # ARABIC LETTER BEH MEDIAL FORM
|
||||
0xF14A 0x0628 # ARABIC LETTER BEH
|
||||
0xF14A 0xFE8F # ARABIC LETTER BEH ISOLATED FORM
|
||||
0xF14A 0xFE90 # ARABIC LETTER BEH FINAL FORM
|
||||
0xF14B 0xFE97 # ARABIC LETTER TEH INITIAL FORM
|
||||
0xF14B 0xFE98 # ARABIC LETTER TEH MEDIAL FORM
|
||||
0xF14C 0x062A # ARABIC LETTER TEH
|
||||
0xF14C 0xFE95 # ARABIC LETTER TEH ISOLATED FORM
|
||||
0xF14C 0xFE96 # ARABIC LETTER TEH FINAL FORM
|
||||
0xF14D 0xFE9B # ARABIC LETTER THEH INITIAL FORM
|
||||
0xF14D 0xFE9C # ARABIC LETTER THEH MEDIAL FORM
|
||||
0xF14E 0x062B # ARABIC LETTER THEH
|
||||
0xF14E 0xFE99 # ARABIC LETTER THEH ISOLATED FORM
|
||||
0xF14E 0xFE9A # ARABIC LETTER THEH FINAL FORM
|
||||
0xF14F 0xFE9F # ARABIC LETTER JEEM INITIAL FORM
|
||||
0xF14F 0xFEA0 # ARABIC LETTER JEEM MEDIAL FORM
|
||||
0xF150 0xFE9E # ARABIC LETTER JEEM FINAL FORM
|
||||
0xF151 0x062C # ARABIC LETTER JEEM
|
||||
0xF151 0xFE9D # ARABIC LETTER JEEM ISOLATED FORM
|
||||
0xF152 0xFEA3 # ARABIC LETTER HAH INITIAL FORM
|
||||
0xF152 0xFEA4 # ARABIC LETTER HAH MEDIAL FORM
|
||||
0xF153 0xFEA2 # ARABIC LETTER HAH FINAL FORM
|
||||
0xF154 0x062D # ARABIC LETTER HAH
|
||||
0xF154 0xFEA1 # ARABIC LETTER HAH ISOLATED FORM
|
||||
0xF155 0xFEA7 # ARABIC LETTER KHAH INITIAL FORM
|
||||
0xF155 0xFEA8 # ARABIC LETTER KHAH MEDIAL FORM
|
||||
0xF156 0xFEA6 # ARABIC LETTER KHAH FINAL FORM
|
||||
0xF157 0x062E # ARABIC LETTER KHAH
|
||||
0xF157 0xFEA5 # ARABIC LETTER KHAH ISOLATED FORM
|
||||
0xF158 0x062F # ARABIC LETTER DAL
|
||||
0xF158 0xFEA9 # ARABIC LETTER DAL ISOLATED FORM
|
||||
0xF158 0xFEAA # ARABIC LETTER DAL FINAL FORM
|
||||
0xF159 0x0630 # ARABIC LETTER THAL
|
||||
0xF159 0xFEAB # ARABIC LETTER THAL ISOLATED FORM
|
||||
0xF159 0xFEAC # ARABIC LETTER THAL FINAL FORM
|
||||
0xF15A 0x0631 # ARABIC LETTER REH
|
||||
0xF15A 0xFEAD # ARABIC LETTER REH ISOLATED FORM
|
||||
0xF15A 0xFEAE # ARABIC LETTER REH FINAL FORM
|
||||
0xF15B 0x005B # LEFT SQUARE BRACKET
|
||||
0xF15C 0x005C # REVERSE SOLIDUS
|
||||
0xF15D 0x005D # RIGHT SQUARE BRACKET
|
||||
0xF15E 0x002C # COMMA
|
||||
0xF15E 0x066B # ARABIC DECIMAL SEPARATOR
|
||||
0xF15E 0x066C # ARABIC THOUSANDS SEPARATOR
|
||||
0xF15F 0x0640 # ARABIC TATWEEL
|
||||
0xF160 0x0632 # ARABIC LETTER ZAIN
|
||||
0xF160 0xFEAF # ARABIC LETTER ZAIN ISOLATED FORM
|
||||
0xF160 0xFEB0 # ARABIC LETTER ZAIN FINAL FORM
|
||||
0xF161 0xFEB3 # ARABIC LETTER SEEN INITIAL FORM
|
||||
0xF161 0xFEB4 # ARABIC LETTER SEEN MEDIAL FORM
|
||||
0xF162 0x0633 # ARABIC LETTER SEEN
|
||||
0xF162 0xFEB1 # ARABIC LETTER SEEN ISOLATED FORM
|
||||
0xF162 0xFEB2 # ARABIC LETTER SEEN FINAL FORM
|
||||
0xF163 0xFEB7 # ARABIC LETTER SHEEN INITIAL FORM
|
||||
0xF163 0xFEB8 # ARABIC LETTER SHEEN MEDIAL FORM
|
||||
0xF164 0x0634 # ARABIC LETTER SHEEN
|
||||
0xF164 0xFEB5 # ARABIC LETTER SHEEN ISOLATED FORM
|
||||
0xF164 0xFEB6 # ARABIC LETTER SHEEN FINAL FORM
|
||||
0xF165 0xFEBB # ARABIC LETTER SAD INITIAL FORM
|
||||
0xF165 0xFEBC # ARABIC LETTER SAD MEDIAL FORM
|
||||
0xF166 0x0635 # ARABIC LETTER SAD
|
||||
0xF166 0xFEB9 # ARABIC LETTER SAD ISOLATED FORM
|
||||
0xF166 0xFEBA # ARABIC LETTER SAD FINAL FORM
|
||||
0xF167 0xFEBF # ARABIC LETTER DAD INITIAL FORM
|
||||
0xF167 0xFEC0 # ARABIC LETTER DAD MEDIAL FORM
|
||||
0xF168 0x0636 # ARABIC LETTER DAD
|
||||
0xF168 0xFEBD # ARABIC LETTER DAD ISOLATED FORM
|
||||
0xF168 0xFEBE # ARABIC LETTER DAD FINAL FORM
|
||||
0xF169 0x0637 # ARABIC LETTER TAH
|
||||
0xF169 0xFEC1 # ARABIC LETTER TAH ISOLATED FORM
|
||||
0xF169 0xFEC2 # ARABIC LETTER TAH FINAL FORM
|
||||
0xF169 0xFEC3 # ARABIC LETTER TAH INITIAL FORM
|
||||
0xF169 0xFEC4 # ARABIC LETTER TAH MEDIAL FORM
|
||||
0xF16A 0x0638 # ARABIC LETTER ZAH
|
||||
0xF16A 0xFEC5 # ARABIC LETTER ZAH ISOLATED FORM
|
||||
0xF16A 0xFEC6 # ARABIC LETTER ZAH FINAL FORM
|
||||
0xF16A 0xFEC7 # ARABIC LETTER ZAH INITIAL FORM
|
||||
0xF16A 0xFEC8 # ARABIC LETTER ZAH MEDIAL FORM
|
||||
0xF16B 0xFECB # ARABIC LETTER AIN INITIAL FORM
|
||||
0xF16C 0xFECC # ARABIC LETTER AIN MEDIAL FORM
|
||||
0xF16D 0xFECA # ARABIC LETTER AIN FINAL FORM
|
||||
0xF16E 0x0639 # ARABIC LETTER AIN
|
||||
0xF16E 0xFEC9 # ARABIC LETTER AIN ISOLATED FORM
|
||||
0xF16F 0xFECF # ARABIC LETTER GHAIN INITIAL FORM
|
||||
0xF170 0xFED0 # ARABIC LETTER GHAIN MEDIAL FORM
|
||||
0xF171 0xFECE # ARABIC LETTER GHAIN FINAL FORM
|
||||
0xF172 0x063A # ARABIC LETTER GHAIN
|
||||
0xF172 0xFECD # ARABIC LETTER GHAIN ISOLATED FORM
|
||||
0xF173 0xFED3 # ARABIC LETTER FEH INITIAL FORM
|
||||
0xF174 0xFED4 # ARABIC LETTER FEH MEDIAL FORM
|
||||
0xF175 0x0641 # ARABIC LETTER FEH
|
||||
0xF175 0xFED1 # ARABIC LETTER FEH ISOLATED FORM
|
||||
0xF175 0xFED2 # ARABIC LETTER FEH FINAL FORM
|
||||
0xF176 0xFED7 # ARABIC LETTER QAF INITIAL FORM
|
||||
0xF177 0xFED8 # ARABIC LETTER QAF MEDIAL FORM
|
||||
0xF178 0x0642 # ARABIC LETTER QAF
|
||||
0xF178 0xFED5 # ARABIC LETTER QAF ISOLATED FORM
|
||||
0xF178 0xFED6 # ARABIC LETTER QAF FINAL FORM
|
||||
0xF179 0xFEDB # ARABIC LETTER KAF INITIAL FORM
|
||||
0xF179 0xFEDC # ARABIC LETTER KAF MEDIAL FORM
|
||||
0xF17A 0x0643 # ARABIC LETTER KAF
|
||||
0xF17A 0xFED9 # ARABIC LETTER KAF ISOLATED FORM
|
||||
0xF17A 0xFEDA # ARABIC LETTER KAF FINAL FORM
|
||||
0xF17B 0xFEDF # ARABIC LETTER LAM INITIAL FORM
|
||||
0xF17B 0xFEE0 # ARABIC LETTER LAM MEDIAL FORM
|
||||
0xF17C 0x0644 # ARABIC LETTER LAM
|
||||
0xF17C 0xFEDD # ARABIC LETTER LAM ISOLATED FORM
|
||||
0xF17C 0xFEDE # ARABIC LETTER LAM FINAL FORM
|
||||
0xF17D 0xFEE3 # ARABIC LETTER MEEM INITIAL FORM
|
||||
0xF17D 0xFEE4 # ARABIC LETTER MEEM MEDIAL FORM
|
||||
0xF17E 0x0645 # ARABIC LETTER MEEM
|
||||
0xF17E 0xFEE1 # ARABIC LETTER MEEM ISOLATED FORM
|
||||
0xF17E 0xFEE2 # ARABIC LETTER MEEM FINAL FORM
|
||||
0xF17F 0xFEE7 # ARABIC LETTER NOON INITIAL FORM
|
||||
0xF17F 0xFEE8 # ARABIC LETTER NOON MEDIAL FORM
|
||||
0xF1A1 0xFEEB # ARABIC LETTER HEH INITIAL FORM
|
||||
0xF1A2 0xFEEC # ARABIC LETTER HEH MEDIAL FORM
|
||||
0xF1A3 0xFEEA # ARABIC LETTER HEH FINAL FORM
|
||||
0xF1A4 0x0647 # ARABIC LETTER HEH
|
||||
0xF1A4 0xFEE9 # ARABIC LETTER HEH ISOLATED FORM
|
||||
0xF1A5 0x0648 # ARABIC LETTER WAW
|
||||
0xF1A5 0xFEED # ARABIC LETTER WAW ISOLATED FORM
|
||||
0xF1A5 0xFEEE # ARABIC LETTER WAW FINAL FORM
|
||||
0xF1A6 0xFEF3 # ARABIC LETTER YEH INITIAL FORM
|
||||
0xF1A6 0xFEF4 # ARABIC LETTER YEH MEDIAL FORM
|
||||
0xF1A7 0xFEF2 # ARABIC LETTER YEH FINAL FORM
|
||||
0xF1A8 0x064A # ARABIC LETTER YEH
|
||||
0xF1A8 0xFEF1 # ARABIC LETTER YEH ISOLATED FORM
|
||||
0xF1A9 0x0629 # ARABIC LETTER TEH MARBUTA
|
||||
0xF1A9 0xFE93 # ARABIC LETTER TEH MARBUTA ISOLATED FORM
|
||||
0xF1AA 0xFE94 # ARABIC LETTER TEH MARBUTA FINAL FORM
|
||||
0xF1AB 0xFEF0 # ARABIC LETTER ALEF MAKSURA FINAL FORM
|
||||
0xF1AC 0x0649 # ARABIC LETTER ALEF MAKSURA
|
||||
0xF1AC 0xFEEF # ARABIC LETTER ALEF MAKSURA ISOLATED FORM
|
||||
0xF1AD 0x0621 # ARABIC LETTER HAMZA
|
||||
0xF1AE 0xFE8B # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
|
||||
0xF1AE 0xFE8C # ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM
|
||||
0xF1AF 0xFE8A # ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM
|
||||
0xF1B0 0x0030 # DIGIT ZERO
|
||||
0xF1B1 0x0031 # DIGIT ONE
|
||||
0xF1B2 0x0032 # DIGIT TWO
|
||||
0xF1B3 0x0033 # DIGIT THREE
|
||||
0xF1B4 0x0034 # DIGIT FOUR
|
||||
0xF1B5 0x0035 # DIGIT FIVE
|
||||
0xF1B6 0x0036 # DIGIT SIX
|
||||
0xF1B7 0x0037 # DIGIT SEVEN
|
||||
0xF1B8 0x0038 # DIGIT EIGHT
|
||||
0xF1B9 0x0039 # DIGIT NINE
|
||||
0xF1BA 0x0626 # ARABIC LETTER YEH WITH HAMZA ABOVE
|
||||
0xF1BA 0xFE89 # ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM
|
||||
0xF1BB 0x0624 # ARABIC LETTER WAW WITH HAMZA ABOVE
|
||||
0xF1BB 0xFE85 # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
|
||||
0xF1BB 0xFE86 # ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM
|
||||
0xF1BC 0xFEFC # ARABIC LIGATURE LAM WITH ALEF FINAL FORM
|
||||
0xF1BD 0xFEFB # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
|
||||
0xF1BE 0xFEF7 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
|
||||
0xF1BF 0xFEF8 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
|
||||
0xF1C0 0xFEF5 # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
|
||||
0xF1C1 0xFEF6 # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
|
||||
0xF1C2 0xFEF9 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
|
||||
0xF1C3 0xFEFA # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM
|
||||
0xF1C4 0x064E # ARABIC FATHA
|
||||
0xF1C5 0x064F # ARABIC DAMMA
|
||||
0xF1C6 0x0652 # ARABIC SUKUN
|
||||
0xF1C7 0x064B # ARABIC FATHATAN
|
||||
0xF1C8 0x064C # ARABIC DAMMATAN
|
||||
0xF1C9 0x0651 # ARABIC SHADDA
|
||||
0xF1CA 0x0650 # ARABIC KASRA
|
||||
0xF1CB 0x064D # ARABIC KASRATAN
|
||||
0xF1E1 0x0646 # ARABIC LETTER NOON
|
||||
0xF1E1 0xFEE5 # ARABIC LETTER NOON ISOLATED FORM
|
||||
0xF1E1 0xFEE6 # ARABIC LETTER NOON FINAL FORM
|
|
@ -1,295 +0,0 @@
|
|||
#
|
||||
# Name: Legacy Traditional Arabic encoding
|
||||
#
|
||||
# Format: Three tab-separated columns
|
||||
# Column #1 is the PUA code (in hex as 0xXXXX)
|
||||
# Column #2 is the Unicode (in hex as 0xXXXX)
|
||||
# Column #3 is the Unicode name (follows a comment sign, '#')
|
||||
#
|
||||
# The entries are in PUA order
|
||||
#
|
||||
0xF200 0x063B # ARABIC LETTER KEHEH WITH TWO DOTS ABOVE
|
||||
0xF200 0x063C # ARABIC LETTER KEHEH WITH THREE DOTS BELOW
|
||||
0xF200 0x063D # ARABIC LETTER FARSI YEH WITH INVERTED V
|
||||
0xF200 0x063E # ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE
|
||||
0xF200 0x063F # ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
|
||||
0xF200 0x0653 # ARABIC MADDAH ABOVE
|
||||
0xF200 0x0654 # ARABIC HAMZA ABOVE
|
||||
0xF200 0x0655 # ARABIC HAMZA BELOW
|
||||
0xF200 0x0656 # ARABIC SUBSCRIPT ALEF
|
||||
0xF200 0x0657 # ARABIC INVERTED DAMMA
|
||||
0xF200 0x0658 # ARABIC MARK NOON GHUNNA
|
||||
0xF200 0x0659 # ARABIC ZWARAKAY
|
||||
0xF200 0x065A # ARABIC VOWEL SIGN SMALL V ABOVE
|
||||
0xF200 0x065B # ARABIC VOWEL SIGN INVERTED SMALL V ABOVE
|
||||
0xF200 0x065C # ARABIC VOWEL SIGN DOT BELOW
|
||||
0xF200 0x065D # ARABIC REVERSED DAMMA
|
||||
0xF200 0x065E # ARABIC FATHA WITH TWO DOTS
|
||||
0xF202 0xFC08 # ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM
|
||||
0xF203 0xFC0E # ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM
|
||||
0xF204 0xFC12 # ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM
|
||||
0xF205 0xFC42 # ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM
|
||||
0xF206 0xFC4E # ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM
|
||||
0xF20C 0x200C # ZERO WIDTH NON-JOINER
|
||||
0xF20D 0x200D # ZERO WIDTH JOINER
|
||||
0xF20E 0x200E # LEFT-TO-RIGHT MARK
|
||||
0xF20F 0x200F # RIGHT-TO-LEFT MARK
|
||||
0xF210 0xFD88 # ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM
|
||||
0xF212 0xFC3F # ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM
|
||||
0xF213 0xFC40 # ARABIC LIGATURE LAM WITH HAH ISOLATED FORM
|
||||
0xF214 0xFC41 # ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM
|
||||
0xF215 0xFC6A # ARABIC LIGATURE BEH WITH REH FINAL FORM
|
||||
0xF216 0xFC70 # ARABIC LIGATURE TEH WITH REH FINAL FORM
|
||||
0xF217 0xFC91 # ARABIC LIGATURE YEH WITH REH FINAL FORM
|
||||
0xF218 0xFCB0 # ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM
|
||||
0xF219 0xFD30 # ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM
|
||||
0xF21A 0xFCCD # ARABIC LIGATURE LAM WITH HEH INITIAL FORM
|
||||
0xF21C 0xFC44 # ARABIC LIGATURE LAM WITH YEH ISOLATED FORM
|
||||
0xF21D 0xFC0A # ARABIC LIGATURE BEH WITH YEH ISOLATED FORM
|
||||
0xF21E 0xFC10 # ARABIC LIGATURE TEH WITH YEH ISOLATED FORM
|
||||
0xF21F 0xFC50 # ARABIC LIGATURE NOON WITH YEH ISOLATED FORM
|
||||
0xF220 0x0020 # SPACE
|
||||
0xF221 0x0021 # EXCLAMATION MARK
|
||||
0xF222 0x0022 # QUOTATION MARK
|
||||
0xF223 0x00AB # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
0xF224 0x00BB # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
|
||||
0xF225 0x0025 # PERCENT SIGN
|
||||
0xF226 0x00D7 # MULTIPLICATION SIGN
|
||||
0xF227 0x00F7 # DIVISION SIGN
|
||||
0xF228 0x0028 # LEFT PARENTHESIS
|
||||
0xF229 0x0029 # RIGHT PARENTHESIS
|
||||
0xF22A 0x002A # ASTERISK
|
||||
0xF22B 0x002B # PLUS SIGN
|
||||
0xF22C 0x060C # ARABIC COMMA
|
||||
0xF22D 0x002D # HYPHEN-MINUS
|
||||
0xF22E 0x002E # FULL STOP
|
||||
0xF22F 0x002F # SOLIDUS
|
||||
0xF230 0x0660 # ARABIC-INDIC DIGIT ZERO
|
||||
0xF231 0x0661 # ARABIC-INDIC DIGIT ONE
|
||||
0xF232 0x0662 # ARABIC-INDIC DIGIT TWO
|
||||
0xF233 0x0663 # ARABIC-INDIC DIGIT THREE
|
||||
0xF234 0x0664 # ARABIC-INDIC DIGIT FOUR
|
||||
0xF235 0x0665 # ARABIC-INDIC DIGIT FIVE
|
||||
0xF236 0x0666 # ARABIC-INDIC DIGIT SIX
|
||||
0xF237 0x0667 # ARABIC-INDIC DIGIT SEVEN
|
||||
0xF238 0x0668 # ARABIC-INDIC DIGIT EIGHT
|
||||
0xF239 0x0669 # ARABIC-INDIC DIGIT NINE
|
||||
0xF23A 0x003A # COLON
|
||||
0xF23B 0x003B # SEMICOLON
|
||||
0xF23B 0x061B # ARABIC SEMICOLON
|
||||
0xF23C 0x201C # LEFT DOUBLE QUOTATION MARK
|
||||
0xF23D 0x003D # EQUALS SIGN
|
||||
0xF23E 0x201D # RIGHT DOUBLE QUOTATION MARK
|
||||
0xF23F 0x003F # QUESTION MARK
|
||||
0xF23F 0x061F # ARABIC QUESTION MARK
|
||||
0xF241 0x0627 # ARABIC LETTER ALEF
|
||||
0xF241 0xFE8D # ARABIC LETTER ALEF ISOLATED FORM
|
||||
0xF242 0xFE8E # ARABIC LETTER ALEF FINAL FORM
|
||||
0xF243 0x0623 # ARABIC LETTER ALEF WITH HAMZA ABOVE
|
||||
0xF243 0xFE83 # ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
|
||||
0xF244 0xFE84 # ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
|
||||
0xF245 0x0622 # ARABIC LETTER ALEF WITH MADDA ABOVE
|
||||
0xF245 0xFE81 # ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
|
||||
0xF246 0xFE82 # ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
|
||||
0xF247 0x0625 # ARABIC LETTER ALEF WITH HAMZA BELOW
|
||||
0xF247 0xFE87 # ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM
|
||||
0xF248 0xFE88 # ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM
|
||||
0xF249 0xFE91 # ARABIC LETTER BEH INITIAL FORM
|
||||
0xF24A 0xFE92 # ARABIC LETTER BEH MEDIAL FORM
|
||||
0xF24B 0xFE90 # ARABIC LETTER BEH FINAL FORM
|
||||
0xF24C 0x0628 # ARABIC LETTER BEH
|
||||
0xF24C 0xFE8F # ARABIC LETTER BEH ISOLATED FORM
|
||||
0xF24D 0xFE97 # ARABIC LETTER TEH INITIAL FORM
|
||||
0xF24E 0xFE98 # ARABIC LETTER TEH MEDIAL FORM
|
||||
0xF24F 0xFE96 # ARABIC LETTER TEH FINAL FORM
|
||||
0xF250 0x062A # ARABIC LETTER TEH
|
||||
0xF250 0xFE95 # ARABIC LETTER TEH ISOLATED FORM
|
||||
0xF251 0xFE9B # ARABIC LETTER THEH INITIAL FORM
|
||||
0xF252 0xFE9C # ARABIC LETTER THEH MEDIAL FORM
|
||||
0xF253 0xFE9A # ARABIC LETTER THEH FINAL FORM
|
||||
0xF254 0x062B # ARABIC LETTER THEH
|
||||
0xF254 0xFE99 # ARABIC LETTER THEH ISOLATED FORM
|
||||
0xF255 0xFE9F # ARABIC LETTER JEEM INITIAL FORM
|
||||
0xF256 0xFEA0 # ARABIC LETTER JEEM MEDIAL FORM
|
||||
0xF257 0xFE9E # ARABIC LETTER JEEM FINAL FORM
|
||||
0xF258 0x062C # ARABIC LETTER JEEM
|
||||
0xF258 0xFE9D # ARABIC LETTER JEEM ISOLATED FORM
|
||||
0xF259 0xFEA3 # ARABIC LETTER HAH INITIAL FORM
|
||||
0xF25A 0xFEA4 # ARABIC LETTER HAH MEDIAL FORM
|
||||
0xF25B 0x005B # LEFT SQUARE BRACKET
|
||||
0xF25C 0xFEA2 # ARABIC LETTER HAH FINAL FORM
|
||||
0xF25D 0x005D # RIGHT SQUARE BRACKET
|
||||
0xF25E 0x002C # COMMA
|
||||
0xF25E 0x066B # ARABIC DECIMAL SEPARATOR
|
||||
0xF25E 0x066C # ARABIC THOUSANDS SEPARATOR
|
||||
0xF25F 0x0640 # ARABIC TATWEEL
|
||||
0xF260 0x062D # ARABIC LETTER HAH
|
||||
0xF260 0xFEA1 # ARABIC LETTER HAH ISOLATED FORM
|
||||
0xF261 0xFEA7 # ARABIC LETTER KHAH INITIAL FORM
|
||||
0xF262 0xFEA8 # ARABIC LETTER KHAH MEDIAL FORM
|
||||
0xF263 0xFEA6 # ARABIC LETTER KHAH FINAL FORM
|
||||
0xF264 0x062E # ARABIC LETTER KHAH
|
||||
0xF264 0xFEA5 # ARABIC LETTER KHAH ISOLATED FORM
|
||||
0xF265 0x062F # ARABIC LETTER DAL
|
||||
0xF265 0xFEA9 # ARABIC LETTER DAL ISOLATED FORM
|
||||
0xF266 0xFEAA # ARABIC LETTER DAL FINAL FORM
|
||||
0xF267 0x0630 # ARABIC LETTER THAL
|
||||
0xF267 0xFEAB # ARABIC LETTER THAL ISOLATED FORM
|
||||
0xF268 0xFEAC # ARABIC LETTER THAL FINAL FORM
|
||||
0xF269 0x0631 # ARABIC LETTER REH
|
||||
0xF269 0xFEAD # ARABIC LETTER REH ISOLATED FORM
|
||||
0xF26A 0xFEAE # ARABIC LETTER REH FINAL FORM
|
||||
0xF26B 0x0632 # ARABIC LETTER ZAIN
|
||||
0xF26B 0xFEAF # ARABIC LETTER ZAIN ISOLATED FORM
|
||||
0xF26C 0xFEB0 # ARABIC LETTER ZAIN FINAL FORM
|
||||
0xF26D 0xFEB3 # ARABIC LETTER SEEN INITIAL FORM
|
||||
0xF26E 0xFEB4 # ARABIC LETTER SEEN MEDIAL FORM
|
||||
0xF26F 0xFEB2 # ARABIC LETTER SEEN FINAL FORM
|
||||
0xF270 0x0633 # ARABIC LETTER SEEN
|
||||
0xF270 0xFEB1 # ARABIC LETTER SEEN ISOLATED FORM
|
||||
0xF271 0xFEB7 # ARABIC LETTER SHEEN INITIAL FORM
|
||||
0xF272 0xFEB8 # ARABIC LETTER SHEEN MEDIAL FORM
|
||||
0xF273 0xFEB6 # ARABIC LETTER SHEEN FINAL FORM
|
||||
0xF274 0x0634 # ARABIC LETTER SHEEN
|
||||
0xF274 0xFEB5 # ARABIC LETTER SHEEN ISOLATED FORM
|
||||
0xF275 0xFEBB # ARABIC LETTER SAD INITIAL FORM
|
||||
0xF276 0xFEBC # ARABIC LETTER SAD MEDIAL FORM
|
||||
0xF277 0xFEBA # ARABIC LETTER SAD FINAL FORM
|
||||
0xF278 0x0635 # ARABIC LETTER SAD
|
||||
0xF278 0xFEB9 # ARABIC LETTER SAD ISOLATED FORM
|
||||
0xF279 0xFEBF # ARABIC LETTER DAD INITIAL FORM
|
||||
0xF27A 0xFEC0 # ARABIC LETTER DAD MEDIAL FORM
|
||||
0xF27B 0xFD3E # ORNATE LEFT PARENTHESIS
|
||||
0xF27C 0xFEBE # ARABIC LETTER DAD FINAL FORM
|
||||
0xF27D 0xFD3F # ORNATE RIGHT PARENTHESIS
|
||||
0xF27E 0x0636 # ARABIC LETTER DAD
|
||||
0xF27E 0xFEBD # ARABIC LETTER DAD ISOLATED FORM
|
||||
0xF27F 0xFEC3 # ARABIC LETTER TAH INITIAL FORM
|
||||
0xF280 0xFC9C # ARABIC LIGATURE BEH WITH JEEM INITIAL FORM
|
||||
0xF281 0xFC9D # ARABIC LIGATURE BEH WITH HAH INITIAL FORM
|
||||
0xF282 0xFC9E # ARABIC LIGATURE BEH WITH KHAH INITIAL FORM
|
||||
0xF283 0xFCA1 # ARABIC LIGATURE TEH WITH JEEM INITIAL FORM
|
||||
0xF284 0xFCA2 # ARABIC LIGATURE TEH WITH HAH INITIAL FORM
|
||||
0xF285 0xFCA3 # ARABIC LIGATURE TEH WITH KHAH INITIAL FORM
|
||||
0xF286 0xFCC9 # ARABIC LIGATURE LAM WITH JEEM INITIAL FORM
|
||||
0xF287 0xFCCA # ARABIC LIGATURE LAM WITH HAH INITIAL FORM
|
||||
0xF288 0xFCCB # ARABIC LIGATURE LAM WITH KHAH INITIAL FORM
|
||||
0xF289 0xFCCE # ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM
|
||||
0xF28A 0xFCCF # ARABIC LIGATURE MEEM WITH HAH INITIAL FORM
|
||||
0xF28B 0xFCD0 # ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM
|
||||
0xF28D 0xFCD2 # ARABIC LIGATURE NOON WITH JEEM INITIAL FORM
|
||||
0xF28E 0xFCD3 # ARABIC LIGATURE NOON WITH HAH INITIAL FORM
|
||||
0xF28F 0xFCDA # ARABIC LIGATURE YEH WITH JEEM INITIAL FORM
|
||||
0xF290 0xFCDB # ARABIC LIGATURE YEH WITH HAH INITIAL FORM
|
||||
0xF291 0xFCDC # ARABIC LIGATURE YEH WITH KHAH INITIAL FORM
|
||||
0xF292 0xFC6D # ARABIC LIGATURE BEH WITH NOON FINAL FORM
|
||||
0xF293 0xFC73 # ARABIC LIGATURE TEH WITH NOON FINAL FORM
|
||||
0xF294 0xFC94 # ARABIC LIGATURE YEH WITH NOON FINAL FORM
|
||||
0xF295 0xFC86 # ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM
|
||||
0xF296 0xFC9F # ARABIC LIGATURE BEH WITH MEEM INITIAL FORM
|
||||
0xF297 0xFCA4 # ARABIC LIGATURE TEH WITH MEEM INITIAL FORM
|
||||
0xF298 0xFCD5 # ARABIC LIGATURE NOON WITH MEEM INITIAL FORM
|
||||
0xF299 0xFCDD # ARABIC LIGATURE YEH WITH MEEM INITIAL FORM
|
||||
0xF29A 0xFCA8 # ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM
|
||||
0xF29B 0xFCAA # ARABIC LIGATURE HAH WITH MEEM INITIAL FORM
|
||||
0xF29C 0xFCAC # ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM
|
||||
0xF29D 0xFCCC # ARABIC LIGATURE LAM WITH MEEM INITIAL FORM
|
||||
0xF29E 0xFCD1 # ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM
|
||||
0xF29F 0xFC32 # ARABIC LIGATURE FEH WITH YEH ISOLATED FORM
|
||||
0xF2A1 0xFEC2 # ARABIC LETTER TAH FINAL FORM
|
||||
0xF2A2 0x0637 # ARABIC LETTER TAH
|
||||
0xF2A2 0xFEC1 # ARABIC LETTER TAH ISOLATED FORM
|
||||
0xF2A3 0x0638 # ARABIC LETTER ZAH
|
||||
0xF2A3 0xFEC7 # ARABIC LETTER ZAH INITIAL FORM
|
||||
0xF2A4 0xFEC8 # ARABIC LETTER ZAH MEDIAL FORM
|
||||
0xF2A5 0xFEC6 # ARABIC LETTER ZAH FINAL FORM
|
||||
0xF2A6 0xFEC5 # ARABIC LETTER ZAH ISOLATED FORM
|
||||
0xF2A7 0xFECB # ARABIC LETTER AIN INITIAL FORM
|
||||
0xF2A8 0xFECC # ARABIC LETTER AIN MEDIAL FORM
|
||||
0xF2A9 0xFECA # ARABIC LETTER AIN FINAL FORM
|
||||
0xF2AA 0x0639 # ARABIC LETTER AIN
|
||||
0xF2AA 0xFEC9 # ARABIC LETTER AIN ISOLATED FORM
|
||||
0xF2AB 0xFECF # ARABIC LETTER GHAIN INITIAL FORM
|
||||
0xF2AC 0xFED0 # ARABIC LETTER GHAIN MEDIAL FORM
|
||||
0xF2AD 0xFECE # ARABIC LETTER GHAIN FINAL FORM
|
||||
0xF2AE 0x063A # ARABIC LETTER GHAIN
|
||||
0xF2AE 0xFECD # ARABIC LETTER GHAIN ISOLATED FORM
|
||||
0xF2AF 0xFED3 # ARABIC LETTER FEH INITIAL FORM
|
||||
0xF2B0 0xFED4 # ARABIC LETTER FEH MEDIAL FORM
|
||||
0xF2B1 0xFED2 # ARABIC LETTER FEH FINAL FORM
|
||||
0xF2B2 0x0641 # ARABIC LETTER FEH
|
||||
0xF2B2 0xFED1 # ARABIC LETTER FEH ISOLATED FORM
|
||||
0xF2B3 0xFED7 # ARABIC LETTER QAF INITIAL FORM
|
||||
0xF2B4 0xFED8 # ARABIC LETTER QAF MEDIAL FORM
|
||||
0xF2B5 0xFED6 # ARABIC LETTER QAF FINAL FORM
|
||||
0xF2B6 0x0642 # ARABIC LETTER QAF
|
||||
0xF2B6 0xFED5 # ARABIC LETTER QAF ISOLATED FORM
|
||||
0xF2B7 0xFEDB # ARABIC LETTER KAF INITIAL FORM
|
||||
0xF2B8 0xFEDC # ARABIC LETTER KAF MEDIAL FORM
|
||||
0xF2B9 0xFEDA # ARABIC LETTER KAF FINAL FORM
|
||||
0xF2BA 0x0643 # ARABIC LETTER KAF
|
||||
0xF2BA 0xFED9 # ARABIC LETTER KAF ISOLATED FORM
|
||||
0xF2BB 0xFEDF # ARABIC LETTER LAM INITIAL FORM
|
||||
0xF2BC 0xFEE0 # ARABIC LETTER LAM MEDIAL FORM
|
||||
0xF2BD 0xFEDE # ARABIC LETTER LAM FINAL FORM
|
||||
0xF2BE 0x0644 # ARABIC LETTER LAM
|
||||
0xF2BE 0xFEDD # ARABIC LETTER LAM ISOLATED FORM
|
||||
0xF2BF 0xFEE3 # ARABIC LETTER MEEM INITIAL FORM
|
||||
0xF2C0 0xFEE4 # ARABIC LETTER MEEM MEDIAL FORM
|
||||
0xF2C1 0xFEE2 # ARABIC LETTER MEEM FINAL FORM
|
||||
0xF2C2 0x0645 # ARABIC LETTER MEEM
|
||||
0xF2C2 0xFEE1 # ARABIC LETTER MEEM ISOLATED FORM
|
||||
0xF2C3 0xFEE7 # ARABIC LETTER NOON INITIAL FORM
|
||||
0xF2C4 0xFEE8 # ARABIC LETTER NOON MEDIAL FORM
|
||||
0xF2C5 0xFEE6 # ARABIC LETTER NOON FINAL FORM
|
||||
0xF2C6 0x0646 # ARABIC LETTER NOON
|
||||
0xF2C6 0xFEE5 # ARABIC LETTER NOON ISOLATED FORM
|
||||
0xF2C7 0xFEEB # ARABIC LETTER HEH INITIAL FORM
|
||||
0xF2C8 0xFEEC # ARABIC LETTER HEH MEDIAL FORM
|
||||
0xF2C9 0xFEEA # ARABIC LETTER HEH FINAL FORM
|
||||
0xF2CA 0x0647 # ARABIC LETTER HEH
|
||||
0xF2CA 0xFEE9 # ARABIC LETTER HEH ISOLATED FORM
|
||||
0xF2CB 0x0648 # ARABIC LETTER WAW
|
||||
0xF2CB 0xFEED # ARABIC LETTER WAW ISOLATED FORM
|
||||
0xF2CC 0xFEEE # ARABIC LETTER WAW FINAL FORM
|
||||
0xF2CD 0xFEF3 # ARABIC LETTER YEH INITIAL FORM
|
||||
0xF2CE 0xFEF4 # ARABIC LETTER YEH MEDIAL FORM
|
||||
0xF2CF 0xFEF2 # ARABIC LETTER YEH FINAL FORM
|
||||
0xF2D0 0x064A # ARABIC LETTER YEH
|
||||
0xF2D0 0xFEF1 # ARABIC LETTER YEH ISOLATED FORM
|
||||
0xF2D1 0x0629 # ARABIC LETTER TEH MARBUTA
|
||||
0xF2D1 0xFE93 # ARABIC LETTER TEH MARBUTA ISOLATED FORM
|
||||
0xF2D2 0xFE94 # ARABIC LETTER TEH MARBUTA FINAL FORM
|
||||
0xF2D3 0xFEF0 # ARABIC LETTER ALEF MAKSURA FINAL FORM
|
||||
0xF2D4 0x0649 # ARABIC LETTER ALEF MAKSURA
|
||||
0xF2D4 0xFEEF # ARABIC LETTER ALEF MAKSURA ISOLATED FORM
|
||||
0xF2D5 0x0621 # ARABIC LETTER HAMZA
|
||||
0xF2D6 0xFE8B # ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
|
||||
0xF2D7 0xFE8C # ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM
|
||||
0xF2D8 0xFE8A # ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM
|
||||
0xF2D9 0x0626 # ARABIC LETTER YEH WITH HAMZA ABOVE
|
||||
0xF2D9 0xFE89 # ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM
|
||||
0xF2DA 0x0624 # ARABIC LETTER WAW WITH HAMZA ABOVE
|
||||
0xF2DA 0xFE85 # ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
|
||||
0xF2DB 0xFE86 # ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM
|
||||
0xF2DC 0xFEFB # ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
|
||||
0xF2DD 0xFEFC # ARABIC LIGATURE LAM WITH ALEF FINAL FORM
|
||||
0xF2DE 0xFEF7 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
|
||||
0xF2DF 0xFEF8 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
|
||||
0xF2E0 0xFEF5 # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
|
||||
0xF2E1 0xFEF6 # ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
|
||||
0xF2E2 0xFEF9 # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
|
||||
0xF2E3 0xFEFA # ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM
|
||||
0xF2E4 0x064E # ARABIC FATHA
|
||||
0xF2E5 0x064F # ARABIC DAMMA
|
||||
0xF2E6 0x0652 # ARABIC SUKUN
|
||||
0xF2E7 0x064B # ARABIC FATHATAN
|
||||
0xF2E8 0x064C # ARABIC DAMMATAN
|
||||
0xF2E9 0x0651 # ARABIC SHADDA
|
||||
0xF2EA 0x0650 # ARABIC KASRA
|
||||
0xF2EB 0x064D # ARABIC KASRATAN
|
||||
0xF2EC 0xFC60 # ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM
|
||||
0xF2ED 0xFC61 # ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM
|
||||
0xF2EF 0xFC5E # ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM
|
||||
0xF2F0 0xFC62 # ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM
|
||||
0xF2F1 0xFEC4 # ARABIC LETTER TAH MEDIAL FORM
|
163
src/Makefile.am
163
src/Makefile.am
|
@ -12,7 +12,7 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
|
|||
TESTS =
|
||||
check_PROGRAMS =
|
||||
|
||||
EXTRA_DIST += harfbuzz.cc harfbuzz-subset.cc
|
||||
EXTRA_DIST += harfbuzz.cc
|
||||
EXTRA_DIST += meson.build
|
||||
EXTRA_DIST += fix_get_types.py
|
||||
|
||||
|
@ -47,9 +47,6 @@ HBLIBS += $(GLIB_LIBS)
|
|||
HBDEPS += $(GLIB_DEPS)
|
||||
HBSOURCES += $(HB_GLIB_sources)
|
||||
HBHEADERS += $(HB_GLIB_headers)
|
||||
HB_HAS_GLIB_DEF = define HB_HAS_GLIB 1
|
||||
else
|
||||
HB_HAS_GLIB_DEF = undef HB_HAS_GLIB
|
||||
endif
|
||||
|
||||
if HAVE_FREETYPE
|
||||
|
@ -58,9 +55,6 @@ HBLIBS += $(FREETYPE_LIBS)
|
|||
HBDEPS += $(FREETYPE_DEPS)
|
||||
HBSOURCES += $(HB_FT_sources)
|
||||
HBHEADERS += $(HB_FT_headers)
|
||||
HB_HAS_FREETYPE_DEF = define HB_HAS_FREETYPE 1
|
||||
else
|
||||
HB_HAS_FREETYPE_DEF = undef HB_HAS_FREETYPE
|
||||
endif
|
||||
|
||||
if HAVE_GRAPHITE2
|
||||
|
@ -69,9 +63,6 @@ HBLIBS += $(GRAPHITE2_LIBS)
|
|||
HBDEPS += $(GRAPHITE2_DEPS)
|
||||
HBSOURCES += $(HB_GRAPHITE2_sources)
|
||||
HBHEADERS += $(HB_GRAPHITE2_headers)
|
||||
HB_HAS_GRAPHITE_DEF = define HB_HAS_GRAPHITE 1
|
||||
else
|
||||
HB_HAS_GRAPHITE_DEF = undef HB_HAS_GRAPHITE
|
||||
endif
|
||||
|
||||
if HAVE_UNISCRIBE
|
||||
|
@ -79,9 +70,6 @@ HBCFLAGS += $(UNISCRIBE_CFLAGS)
|
|||
HBNONPCLIBS += $(UNISCRIBE_LIBS)
|
||||
HBSOURCES += $(HB_UNISCRIBE_sources)
|
||||
HBHEADERS += $(HB_UNISCRIBE_headers)
|
||||
HB_HAS_UNISCRIBE_DEF = define HB_HAS_UNISCRIBE 1
|
||||
else
|
||||
HB_HAS_UNISCRIBE_DEF = undef HB_HAS_UNISCRIBE
|
||||
endif
|
||||
|
||||
if HAVE_DIRECTWRITE
|
||||
|
@ -89,9 +77,6 @@ HBCFLAGS += $(DIRECTWRITE_CXXFLAGS)
|
|||
HBNONPCLIBS += $(DIRECTWRITE_LIBS)
|
||||
HBSOURCES += $(HB_DIRECTWRITE_sources)
|
||||
HBHEADERS += $(HB_DIRECTWRITE_headers)
|
||||
HB_HAS_DIRECTWRITE_DEF = define HB_HAS_DIRECTWRITE 1
|
||||
else
|
||||
HB_HAS_DIRECTWRITE_DEF = undef HB_HAS_DIRECTWRITE
|
||||
endif
|
||||
|
||||
if HAVE_GDI
|
||||
|
@ -99,9 +84,6 @@ HBCFLAGS += $(GDI_CXXFLAGS)
|
|||
HBNONPCLIBS += $(GDI_LIBS)
|
||||
HBSOURCES += $(HB_GDI_sources)
|
||||
HBHEADERS += $(HB_GDI_headers)
|
||||
HB_HAS_GDI_DEF = define HB_HAS_GDI 1
|
||||
else
|
||||
HB_HAS_GDI_DEF = undef HB_HAS_GDI
|
||||
endif
|
||||
|
||||
if HAVE_CORETEXT
|
||||
|
@ -109,9 +91,6 @@ HBCFLAGS += $(CORETEXT_CFLAGS)
|
|||
HBNONPCLIBS += $(CORETEXT_LIBS)
|
||||
HBSOURCES += $(HB_CORETEXT_sources)
|
||||
HBHEADERS += $(HB_CORETEXT_headers)
|
||||
HB_HAS_CORETEXT_DEF = define HB_HAS_CORETEXT 1
|
||||
else
|
||||
HB_HAS_CORETEXT_DEF = undef HB_HAS_CORETEXT
|
||||
endif
|
||||
|
||||
|
||||
|
@ -135,8 +114,6 @@ export_symbols = -export-symbols harfbuzz.def
|
|||
harfbuzz_def_dependency = harfbuzz.def
|
||||
export_symbols_subset = -export-symbols harfbuzz-subset.def
|
||||
harfbuzz_subset_def_dependency = harfbuzz-subset.def
|
||||
export_symbols_cairo = -export-symbols harfbuzz-cairo.def
|
||||
harfbuzz_cairo_def_dependency = harfbuzz-cairo.def
|
||||
export_symbols_icu = -export-symbols harfbuzz-icu.def
|
||||
harfbuzz_icu_def_dependency = harfbuzz-icu.def
|
||||
export_symbols_gobject = -export-symbols harfbuzz-gobject.def
|
||||
|
@ -170,7 +147,7 @@ pkgconfigdir = $(libdir)/pkgconfig
|
|||
pkgconfig_DATA = harfbuzz.pc
|
||||
cmakedir = $(libdir)/cmake/harfbuzz
|
||||
cmake_DATA = harfbuzz-config.cmake
|
||||
EXTRA_DIST += hb-version.h.in hb-features.h.in harfbuzz.pc.in harfbuzz-config.cmake.in
|
||||
EXTRA_DIST += hb-version.h.in harfbuzz.pc.in harfbuzz-config.cmake.in
|
||||
|
||||
lib_LTLIBRARIES += libharfbuzz-subset.la
|
||||
libharfbuzz_subset_la_LINK = $(chosen_linker) $(libharfbuzz_subset_la_LDFLAGS)
|
||||
|
@ -183,36 +160,12 @@ pkginclude_HEADERS += $(HB_SUBSET_headers)
|
|||
pkgconfig_DATA += harfbuzz-subset.pc
|
||||
EXTRA_DIST += harfbuzz-subset.pc.in
|
||||
|
||||
harfbuzz-subset.cc: Makefile.sources
|
||||
$(AM_V_GEN) \
|
||||
LANG=C; \
|
||||
for f in \
|
||||
$(HB_BASE_sources) \
|
||||
$(HB_SUBSET_sources) \
|
||||
; do echo '#include "'$$f'"'; done | \
|
||||
sort -u | \
|
||||
grep '[.]cc"' > $(srcdir)/harfbuzz-subset.cc \
|
||||
|| ($(RM) $(srcdir)/harfbuzz-subset.cc; false)
|
||||
BUILT_SOURCES += harfbuzz-subset.cc
|
||||
|
||||
lib_LTLIBRARIES += libharfbuzz-cairo.la
|
||||
libharfbuzz_cairo_la_LINK = $(chosen_linker) $(libharfbuzz_cairo_la_LDFLAGS)
|
||||
libharfbuzz_cairo_la_SOURCES = $(HB_CAIRO_sources)
|
||||
libharfbuzz_cairo_la_CPPFLAGS = $(HBCFLAGS) $(CAIRO_CFLAGS) $(CODE_COVERAGE_CFLAGS)
|
||||
libharfbuzz_cairo_la_LDFLAGS = $(base_link_flags) $(export_symbols_cairo) $(CODE_COVERAGE_LDFLAGS)
|
||||
libharfbuzz_cairo_la_LIBADD = $(CAIRO_LIBS) libharfbuzz.la
|
||||
EXTRA_libharfbuzz_cairo_la_DEPENDENCIES = $(harfbuzz_cairo_def_dependency)
|
||||
pkginclude_HEADERS += $(HB_CAIRO_headers)
|
||||
pkgconfig_DATA += harfbuzz-cairo.pc
|
||||
EXTRA_DIST += harfbuzz-cairo.pc.in
|
||||
|
||||
if HAVE_ICU
|
||||
if HAVE_ICU_BUILTIN
|
||||
HBCFLAGS += $(ICU_CFLAGS)
|
||||
HBLIBS += $(ICU_LIBS)
|
||||
HBSOURCES += $(HB_ICU_sources)
|
||||
HBHEADERS += $(HB_ICU_headers)
|
||||
HB_HAS_ICU_DEF = define HB_HAS_ICU 1
|
||||
else
|
||||
lib_LTLIBRARIES += libharfbuzz-icu.la
|
||||
libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources)
|
||||
|
@ -222,7 +175,6 @@ libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la
|
|||
EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency)
|
||||
pkginclude_HEADERS += $(HB_ICU_headers)
|
||||
pkgconfig_DATA += harfbuzz-icu.pc
|
||||
HB_HAS_ICU_DEF = undef HB_HAS_ICU
|
||||
endif
|
||||
endif
|
||||
EXTRA_DIST += harfbuzz-icu.pc.in
|
||||
|
@ -254,9 +206,6 @@ hb-gobject-enums.%: hb-gobject-enums.%.tmpl $(HBHEADERS)
|
|||
--template $^ | \
|
||||
sed 's/_t_get_type/_get_type/g; s/_T (/ (/g' > "$@" \
|
||||
|| ($(RM) "$@"; false)
|
||||
HB_HAS_GOBJECT_DEF = define HB_HAS_GOBJECT 1
|
||||
else
|
||||
HB_HAS_GOBJECT_DEF = undef HB_HAS_GOBJECT
|
||||
endif
|
||||
EXTRA_DIST += \
|
||||
harfbuzz-gobject.pc.in \
|
||||
|
@ -265,27 +214,6 @@ EXTRA_DIST += \
|
|||
$(NULL)
|
||||
|
||||
|
||||
BUILT_SOURCES += \
|
||||
hb-features.h
|
||||
DISTCLEANFILES += \
|
||||
hb-features.h
|
||||
|
||||
hb-features.h: hb-features.h.in $(top_builddir)/config.status
|
||||
$(AM_V_GEN) $(SED) \
|
||||
-e 's/mesondefine HB_HAS_CAIRO/$(HB_HAS_CAIRO_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_FREETYPE/$(HB_HAS_FREETYPE_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_GDI/$(HB_HAS_GDI_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_GRAPHITE/$(HB_HAS_GRAPHITE_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_GLIB/$(HB_HAS_GLIB_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_GOBJECT/$(HB_HAS_GOBJECT_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_UNISCRIBE/$(HB_HAS_UNISCRIBE_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_DIRECTWRITE/$(HB_HAS_DIRECTWRITE_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_CORETEXT/$(HB_HAS_CORETEXT_DEF)/' \
|
||||
-e 's/mesondefine HB_HAS_ICU/$(HB_HAS_ICU_DEF)/' \
|
||||
"$<" > "$@" || ($(RM) "$@"; false)
|
||||
|
||||
|
||||
%.pc: %.pc.in $(top_builddir)/config.status
|
||||
$(AM_V_GEN) \
|
||||
$(SED) -e 's@%prefix%@$(prefix)@g' \
|
||||
|
@ -307,13 +235,10 @@ DEF_FILES += harfbuzz-gobject.def
|
|||
endif
|
||||
check: $(DEF_FILES) # For check-symbols.sh
|
||||
CLEANFILES += $(DEF_FILES)
|
||||
harfbuzz.def: $(top_builddir)/config.status
|
||||
harfbuzz.def: $(HBHEADERS)
|
||||
harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS)
|
||||
$(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^
|
||||
harfbuzz-subset.def: $(HB_SUBSET_headers)
|
||||
$(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^
|
||||
harfbuzz-cairo.def: $(HB_CAIRO_headers)
|
||||
$(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^
|
||||
harfbuzz-icu.def: $(HB_ICU_headers)
|
||||
$(AM_V_GEN) $(srcdir)/gen-def.py "$@" $^
|
||||
harfbuzz-gobject.def: $(HB_GOBJECT_headers)
|
||||
|
@ -358,7 +283,6 @@ $(srcdir)/%.hh: $(srcdir)/%.rl
|
|||
|
||||
harfbuzz.cc: Makefile.sources
|
||||
$(AM_V_GEN) \
|
||||
LANG=C; \
|
||||
for f in \
|
||||
$(HB_BASE_sources) \
|
||||
$(HB_GLIB_sources) \
|
||||
|
@ -369,7 +293,6 @@ harfbuzz.cc: Makefile.sources
|
|||
$(HB_DIRECTWRITE_sources) \
|
||||
$(HB_CORETEXT_sources) \
|
||||
; do echo '#include "'$$f'"'; done | \
|
||||
sort -u | \
|
||||
grep '[.]cc"' > $(srcdir)/harfbuzz.cc \
|
||||
|| ($(RM) $(srcdir)/harfbuzz.cc; false)
|
||||
BUILT_SOURCES += harfbuzz.cc
|
||||
|
@ -382,9 +305,7 @@ noinst_PROGRAMS = \
|
|||
test-ot-name \
|
||||
test-ot-glyphname \
|
||||
test-gpos-size-params \
|
||||
test-gsub-get-alternates \
|
||||
test-gsub-would-substitute \
|
||||
test-use-table \
|
||||
$(NULL)
|
||||
bin_PROGRAMS =
|
||||
|
||||
|
@ -412,40 +333,15 @@ test_ot_glyphname_SOURCES = test-ot-glyphname.cc
|
|||
test_ot_glyphname_CPPFLAGS = $(HBCFLAGS)
|
||||
test_ot_glyphname_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_use_table_SOURCES = test-use-table.cc
|
||||
test_use_table_CPPFLAGS = $(HBCFLAGS)
|
||||
test_use_table_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_gpos_size_params_SOURCES = test-gpos-size-params.cc
|
||||
test_gpos_size_params_CPPFLAGS = $(HBCFLAGS)
|
||||
test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_gsub_get_alternates_SOURCES = test-gsub-get-alternates.cc
|
||||
test_gsub_get_alternates_CPPFLAGS = $(HBCFLAGS)
|
||||
test_gsub_get_alternates_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc
|
||||
test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS)
|
||||
test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS)
|
||||
|
||||
COMPILED_TESTS = \
|
||||
test-algs \
|
||||
test-array \
|
||||
test-bimap \
|
||||
test-iter \
|
||||
test-machinery \
|
||||
test-map \
|
||||
test-multimap \
|
||||
test-number \
|
||||
test-ot-tag \
|
||||
test-priority-queue \
|
||||
test-set \
|
||||
test-serialize \
|
||||
test-unicode-ranges \
|
||||
test-vector \
|
||||
test-repacker \
|
||||
test-classdef-graph \
|
||||
$(NULL)
|
||||
COMPILED_TESTS = test-algs test-array test-iter test-meta test-number test-ot-tag test-unicode-ranges test-bimap
|
||||
COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
|
||||
COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
check_PROGRAMS += $(COMPILED_TESTS)
|
||||
|
@ -459,25 +355,13 @@ test_array_SOURCES = test-array.cc
|
|||
test_array_CPPFLAGS = $(HBCFLAGS)
|
||||
test_array_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_bimap_SOURCES = test-bimap.cc hb-static.cc
|
||||
test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_bimap_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_iter_SOURCES = test-iter.cc hb-static.cc
|
||||
test_iter_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_iter_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_machinery_SOURCES = test-machinery.cc hb-static.cc
|
||||
test_machinery_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_machinery_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_map_SOURCES = test-map.cc hb-static.cc
|
||||
test_map_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_map_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_multimap_SOURCES = test-multimap.cc hb-static.cc
|
||||
test_multimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_multimap_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
test_meta_SOURCES = test-meta.cc hb-static.cc
|
||||
test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_meta_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_number_SOURCES = test-number.cc hb-number.cc
|
||||
test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
|
@ -487,33 +371,13 @@ test_ot_tag_SOURCES = hb-ot-tag.cc
|
|||
test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_priority_queue_SOURCES = test-priority-queue.cc hb-static.cc
|
||||
test_priority_queue_CPPFLAGS = $(HBCFLAGS)
|
||||
test_priority_queue_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
test_repacker_SOURCES = test-repacker.cc hb-static.cc graph/gsubgpos-context.cc
|
||||
test_repacker_CPPFLAGS = $(HBCFLAGS)
|
||||
test_repacker_LDADD = libharfbuzz.la libharfbuzz-subset.la $(HBLIBS)
|
||||
|
||||
test_classdef_graph_SOURCES = graph/test-classdef-graph.cc hb-static.cc graph/gsubgpos-context.cc
|
||||
test_classdef_graph_CPPFLAGS = $(HBCFLAGS)
|
||||
test_classdef_graph_LDADD = libharfbuzz.la libharfbuzz-subset.la $(HBLIBS)
|
||||
|
||||
test_set_SOURCES = test-set.cc hb-static.cc
|
||||
test_set_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_set_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_serialize_SOURCES = test-serialize.cc hb-static.cc
|
||||
test_serialize_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_serialize_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_unicode_ranges_SOURCES = test-unicode-ranges.cc
|
||||
test_unicode_ranges_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_unicode_ranges_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_vector_SOURCES = test-vector.cc hb-static.cc
|
||||
test_vector_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_vector_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
test_bimap_SOURCES = test-bimap.cc hb-static.cc
|
||||
test_bimap_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_bimap_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
dist_check_SCRIPTS = \
|
||||
check-c-linkage-decls.py \
|
||||
|
@ -533,15 +397,10 @@ endif
|
|||
|
||||
TESTS_ENVIRONMENT = \
|
||||
srcdir="$(srcdir)" \
|
||||
base_srcdir="$(srcdir)" \
|
||||
builddir="$(builddir)" \
|
||||
MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
|
||||
HBSOURCES="$(HBSOURCES)" \
|
||||
HBHEADERS="$(HBHEADERS)" \
|
||||
LDD="$(LDD)" \
|
||||
NM="$(NM)" \
|
||||
OBJDUMP="$(OBJDUMP)" \
|
||||
OTOOL="$(OTOOL)" \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_INTROSPECTION
|
||||
|
@ -562,7 +421,7 @@ INTROSPECTION_COMPILER_ARGS = --includedir=$(srcdir)
|
|||
INTROSPECTION_SCANNER_ENV = CC="$(CC)"
|
||||
|
||||
HarfBuzz-0.0.gir: libharfbuzz.la libharfbuzz-gobject.la
|
||||
HarfBuzz_0_0_gir_INCLUDES = GObject-2.0 freetype2-2.0
|
||||
HarfBuzz_0_0_gir_INCLUDES = GObject-2.0
|
||||
HarfBuzz_0_0_gir_CFLAGS = \
|
||||
$(INCLUDES) \
|
||||
$(HBCFLAGS) \
|
||||
|
|
|
@ -19,13 +19,9 @@ HB_BASE_sources = \
|
|||
hb-array.hh \
|
||||
hb-atomic.hh \
|
||||
hb-bimap.hh \
|
||||
hb-bit-page.hh \
|
||||
hb-bit-set.hh \
|
||||
hb-bit-set-invertible.hh \
|
||||
hb-blob.cc \
|
||||
hb-blob.hh \
|
||||
hb-buffer-serialize.cc \
|
||||
hb-buffer-verify.cc \
|
||||
hb-buffer.cc \
|
||||
hb-buffer.hh \
|
||||
hb-cache.hh \
|
||||
|
@ -42,19 +38,15 @@ HB_BASE_sources = \
|
|||
hb-draw.hh \
|
||||
hb-face.cc \
|
||||
hb-face.hh \
|
||||
hb-face-builder.cc \
|
||||
hb-fallback-shape.cc \
|
||||
hb-font.cc \
|
||||
hb-font.hh \
|
||||
hb-iter.hh \
|
||||
hb-kern.hh \
|
||||
hb-limits.hh \
|
||||
hb-machinery.hh \
|
||||
hb-map.cc \
|
||||
hb-map.hh \
|
||||
hb-meta.hh \
|
||||
hb-ms-feature-ranges.hh \
|
||||
hb-multimap.hh \
|
||||
hb-mutex.hh \
|
||||
hb-null.hh \
|
||||
hb-number.cc \
|
||||
|
@ -69,6 +61,11 @@ HB_BASE_sources = \
|
|||
hb-ot-cff2-table.cc \
|
||||
hb-ot-cff2-table.hh \
|
||||
hb-ot-cmap-table.hh \
|
||||
hb-ot-color-cbdt-table.hh \
|
||||
hb-ot-color-colr-table.hh \
|
||||
hb-ot-color-cpal-table.hh \
|
||||
hb-ot-color-sbix-table.hh \
|
||||
hb-ot-color-svg-table.hh \
|
||||
hb-ot-color.cc \
|
||||
hb-ot-face-table-list.hh \
|
||||
hb-ot-face.cc \
|
||||
|
@ -85,91 +82,7 @@ HB_BASE_sources = \
|
|||
hb-ot-layout-common.hh \
|
||||
hb-ot-layout-gdef-table.hh \
|
||||
hb-ot-layout-gpos-table.hh \
|
||||
hb-outline.hh \
|
||||
hb-outline.cc \
|
||||
hb-paint.cc \
|
||||
hb-paint.hh \
|
||||
hb-paint-extents.cc \
|
||||
hb-paint-extents.hh \
|
||||
hb-ot-layout-gsub-table.hh \
|
||||
OT/Color/CBDT/CBDT.hh \
|
||||
OT/Color/COLR/COLR.hh \
|
||||
OT/Color/CPAL/CPAL.hh \
|
||||
OT/Color/sbix/sbix.hh \
|
||||
OT/Color/svg/svg.hh \
|
||||
OT/glyf/glyf.hh \
|
||||
OT/glyf/glyf-helpers.hh \
|
||||
OT/glyf/loca.hh \
|
||||
OT/glyf/path-builder.hh \
|
||||
OT/glyf/Glyph.hh \
|
||||
OT/glyf/GlyphHeader.hh \
|
||||
OT/glyf/SimpleGlyph.hh \
|
||||
OT/glyf/coord-setter.hh \
|
||||
OT/glyf/composite-iter.hh \
|
||||
OT/glyf/CompositeGlyph.hh \
|
||||
OT/glyf/VarCompositeGlyph.hh \
|
||||
OT/glyf/SubsetGlyph.hh \
|
||||
OT/Layout/types.hh \
|
||||
OT/Layout/Common/Coverage.hh \
|
||||
OT/Layout/Common/CoverageFormat1.hh \
|
||||
OT/Layout/Common/CoverageFormat2.hh \
|
||||
OT/Layout/Common/RangeRecord.hh \
|
||||
OT/Layout/GDEF/GDEF.hh \
|
||||
OT/Layout/GPOS/AnchorFormat1.hh \
|
||||
OT/Layout/GPOS/AnchorFormat2.hh \
|
||||
OT/Layout/GPOS/AnchorFormat3.hh \
|
||||
OT/Layout/GPOS/Anchor.hh \
|
||||
OT/Layout/GPOS/AnchorMatrix.hh \
|
||||
OT/Layout/GPOS/ChainContextPos.hh \
|
||||
OT/Layout/GPOS/Common.hh \
|
||||
OT/Layout/GPOS/ContextPos.hh \
|
||||
OT/Layout/GPOS/CursivePosFormat1.hh \
|
||||
OT/Layout/GPOS/CursivePos.hh \
|
||||
OT/Layout/GPOS/ExtensionPos.hh \
|
||||
OT/Layout/GPOS/GPOS.hh \
|
||||
OT/Layout/GPOS/LigatureArray.hh \
|
||||
OT/Layout/GPOS/MarkArray.hh \
|
||||
OT/Layout/GPOS/MarkBasePosFormat1.hh \
|
||||
OT/Layout/GPOS/MarkBasePos.hh \
|
||||
OT/Layout/GPOS/MarkLigPosFormat1.hh \
|
||||
OT/Layout/GPOS/MarkLigPos.hh \
|
||||
OT/Layout/GPOS/MarkMarkPosFormat1.hh \
|
||||
OT/Layout/GPOS/MarkMarkPos.hh \
|
||||
OT/Layout/GPOS/MarkRecord.hh \
|
||||
OT/Layout/GPOS/PairPosFormat1.hh \
|
||||
OT/Layout/GPOS/PairPosFormat2.hh \
|
||||
OT/Layout/GPOS/PairPos.hh \
|
||||
OT/Layout/GPOS/PairSet.hh \
|
||||
OT/Layout/GPOS/PairValueRecord.hh \
|
||||
OT/Layout/GPOS/PosLookup.hh \
|
||||
OT/Layout/GPOS/PosLookupSubTable.hh \
|
||||
OT/Layout/GPOS/SinglePosFormat1.hh \
|
||||
OT/Layout/GPOS/SinglePosFormat2.hh \
|
||||
OT/Layout/GPOS/SinglePos.hh \
|
||||
OT/Layout/GPOS/ValueFormat.hh \
|
||||
OT/Layout/GSUB/AlternateSet.hh \
|
||||
OT/Layout/GSUB/AlternateSubstFormat1.hh \
|
||||
OT/Layout/GSUB/AlternateSubst.hh \
|
||||
OT/Layout/GSUB/ChainContextSubst.hh \
|
||||
OT/Layout/GSUB/Common.hh \
|
||||
OT/Layout/GSUB/ContextSubst.hh \
|
||||
OT/Layout/GSUB/ExtensionSubst.hh \
|
||||
OT/Layout/GSUB/GSUB.hh \
|
||||
OT/Layout/GSUB/Ligature.hh \
|
||||
OT/Layout/GSUB/LigatureSet.hh \
|
||||
OT/Layout/GSUB/LigatureSubstFormat1.hh \
|
||||
OT/Layout/GSUB/LigatureSubst.hh \
|
||||
OT/Layout/GSUB/MultipleSubstFormat1.hh \
|
||||
OT/Layout/GSUB/MultipleSubst.hh \
|
||||
OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh \
|
||||
OT/Layout/GSUB/ReverseChainSingleSubst.hh \
|
||||
OT/Layout/GSUB/Sequence.hh \
|
||||
OT/Layout/GSUB/SingleSubstFormat1.hh \
|
||||
OT/Layout/GSUB/SingleSubstFormat2.hh \
|
||||
OT/Layout/GSUB/SingleSubst.hh \
|
||||
OT/Layout/GSUB/SubstLookup.hh \
|
||||
OT/Layout/GSUB/SubstLookupSubTable.hh \
|
||||
OT/name/name.hh \
|
||||
hb-ot-layout-gsubgpos.hh \
|
||||
hb-ot-layout-jstf-table.hh \
|
||||
hb-ot-layout.cc \
|
||||
|
@ -191,29 +104,30 @@ HB_BASE_sources = \
|
|||
hb-ot-os2-unicode-ranges.hh \
|
||||
hb-ot-post-macroman.hh \
|
||||
hb-ot-post-table.hh \
|
||||
hb-ot-shaper-arabic-fallback.hh \
|
||||
hb-ot-shaper-arabic-joining-list.hh \
|
||||
hb-ot-shaper-arabic-pua.hh \
|
||||
hb-ot-shaper-arabic-table.hh \
|
||||
hb-ot-shaper-arabic-win1256.hh \
|
||||
hb-ot-shaper-arabic.cc \
|
||||
hb-ot-shaper-arabic.hh \
|
||||
hb-ot-shaper-default.cc \
|
||||
hb-ot-shaper-hangul.cc \
|
||||
hb-ot-shaper-hebrew.cc \
|
||||
hb-ot-shaper-indic-table.cc \
|
||||
hb-ot-shaper-indic.cc \
|
||||
hb-ot-shaper-indic.hh \
|
||||
hb-ot-shaper-khmer.cc \
|
||||
hb-ot-shaper-myanmar.cc \
|
||||
hb-ot-shaper-syllabic.cc \
|
||||
hb-ot-shaper-syllabic.hh \
|
||||
hb-ot-shaper-thai.cc \
|
||||
hb-ot-shaper-use-table.hh \
|
||||
hb-ot-shaper-use.cc \
|
||||
hb-ot-shaper-vowel-constraints.cc \
|
||||
hb-ot-shaper-vowel-constraints.hh \
|
||||
hb-ot-shaper.hh \
|
||||
hb-ot-shape-complex-arabic-fallback.hh \
|
||||
hb-ot-shape-complex-arabic-joining-list.hh \
|
||||
hb-ot-shape-complex-arabic-table.hh \
|
||||
hb-ot-shape-complex-arabic-win1256.hh \
|
||||
hb-ot-shape-complex-arabic.cc \
|
||||
hb-ot-shape-complex-arabic.hh \
|
||||
hb-ot-shape-complex-default.cc \
|
||||
hb-ot-shape-complex-hangul.cc \
|
||||
hb-ot-shape-complex-hebrew.cc \
|
||||
hb-ot-shape-complex-indic-table.cc \
|
||||
hb-ot-shape-complex-indic.cc \
|
||||
hb-ot-shape-complex-indic.hh \
|
||||
hb-ot-shape-complex-khmer.cc \
|
||||
hb-ot-shape-complex-khmer.hh \
|
||||
hb-ot-shape-complex-myanmar.cc \
|
||||
hb-ot-shape-complex-myanmar.hh \
|
||||
hb-ot-shape-complex-syllabic.cc \
|
||||
hb-ot-shape-complex-syllabic.hh \
|
||||
hb-ot-shape-complex-thai.cc \
|
||||
hb-ot-shape-complex-use-table.hh \
|
||||
hb-ot-shape-complex-use.cc \
|
||||
hb-ot-shape-complex-vowel-constraints.cc \
|
||||
hb-ot-shape-complex-vowel-constraints.hh \
|
||||
hb-ot-shape-complex.hh \
|
||||
hb-ot-shape-fallback.cc \
|
||||
hb-ot-shape-fallback.hh \
|
||||
hb-ot-shape-normalize.cc \
|
||||
|
@ -224,8 +138,6 @@ HB_BASE_sources = \
|
|||
hb-ot-tag-table.hh \
|
||||
hb-ot-tag.cc \
|
||||
hb-ot-var-avar-table.hh \
|
||||
hb-ot-var-common.hh \
|
||||
hb-ot-var-cvar-table.hh \
|
||||
hb-ot-var-fvar-table.hh \
|
||||
hb-ot-var-gvar-table.hh \
|
||||
hb-ot-var-hvar-table.hh \
|
||||
|
@ -255,29 +167,26 @@ HB_BASE_sources = \
|
|||
hb-unicode.hh \
|
||||
hb-utf.hh \
|
||||
hb-vector.hh \
|
||||
hb-priority-queue.hh \
|
||||
hb.hh \
|
||||
$(NULL)
|
||||
|
||||
HB_BASE_RAGEL_GENERATED_sources = \
|
||||
hb-buffer-deserialize-json.hh \
|
||||
hb-buffer-deserialize-text-glyphs.hh \
|
||||
hb-buffer-deserialize-text-unicode.hh \
|
||||
hb-buffer-deserialize-text.hh \
|
||||
hb-number-parser.hh \
|
||||
hb-ot-shaper-indic-machine.hh \
|
||||
hb-ot-shaper-khmer-machine.hh \
|
||||
hb-ot-shaper-myanmar-machine.hh \
|
||||
hb-ot-shaper-use-machine.hh \
|
||||
hb-ot-shape-complex-indic-machine.hh \
|
||||
hb-ot-shape-complex-khmer-machine.hh \
|
||||
hb-ot-shape-complex-myanmar-machine.hh \
|
||||
hb-ot-shape-complex-use-machine.hh \
|
||||
$(NULL)
|
||||
HB_BASE_RAGEL_sources = \
|
||||
hb-buffer-deserialize-json.rl \
|
||||
hb-buffer-deserialize-text-glyphs.rl \
|
||||
hb-buffer-deserialize-text-unicode.rl \
|
||||
hb-buffer-deserialize-text.rl \
|
||||
hb-number-parser.rl \
|
||||
hb-ot-shaper-indic-machine.rl \
|
||||
hb-ot-shaper-khmer-machine.rl \
|
||||
hb-ot-shaper-myanmar-machine.rl \
|
||||
hb-ot-shaper-use-machine.rl \
|
||||
hb-ot-shape-complex-indic-machine.rl \
|
||||
hb-ot-shape-complex-khmer-machine.rl \
|
||||
hb-ot-shape-complex-myanmar-machine.rl \
|
||||
hb-ot-shape-complex-use-machine.rl \
|
||||
$(NULL)
|
||||
|
||||
HB_BASE_headers = \
|
||||
|
@ -286,7 +195,6 @@ HB_BASE_headers = \
|
|||
hb-blob.h \
|
||||
hb-buffer.h \
|
||||
hb-common.h \
|
||||
hb-cplusplus.hh \
|
||||
hb-deprecated.h \
|
||||
hb-draw.h \
|
||||
hb-face.h \
|
||||
|
@ -303,7 +211,6 @@ HB_BASE_headers = \
|
|||
hb-ot-shape.h \
|
||||
hb-ot-var.h \
|
||||
hb-ot.h \
|
||||
hb-paint.h \
|
||||
hb-set.h \
|
||||
hb-shape-plan.h \
|
||||
hb-shape.h \
|
||||
|
@ -315,7 +222,7 @@ HB_BASE_headers = \
|
|||
|
||||
# Optional Sources and Headers with external deps
|
||||
|
||||
HB_FT_sources = hb-ft.cc hb-ft-colr.hh
|
||||
HB_FT_sources = hb-ft.cc
|
||||
HB_FT_headers = hb-ft.h
|
||||
|
||||
HB_GLIB_sources = hb-glib.cc
|
||||
|
@ -348,7 +255,6 @@ HB_SUBSET_sources = \
|
|||
hb-number.hh \
|
||||
hb-ot-cff1-table.cc \
|
||||
hb-ot-cff2-table.cc \
|
||||
hb-ot-post-table-v2subset.hh \
|
||||
hb-static.cc \
|
||||
hb-subset-cff-common.cc \
|
||||
hb-subset-cff-common.hh \
|
||||
|
@ -358,40 +264,14 @@ HB_SUBSET_sources = \
|
|||
hb-subset-cff2.hh \
|
||||
hb-subset-input.cc \
|
||||
hb-subset-input.hh \
|
||||
hb-subset-instancer-solver.cc \
|
||||
hb-subset-accelerator.hh \
|
||||
hb-subset-plan.cc \
|
||||
hb-subset-plan.hh \
|
||||
hb-subset-repacker.cc \
|
||||
hb-subset.cc \
|
||||
hb-subset.hh \
|
||||
hb-repacker.hh \
|
||||
graph/graph.hh \
|
||||
graph/gsubgpos-graph.hh \
|
||||
graph/gsubgpos-context.hh \
|
||||
graph/gsubgpos-context.cc \
|
||||
graph/coverage-graph.hh \
|
||||
graph/classdef-graph.hh \
|
||||
graph/pairpos-graph.hh \
|
||||
graph/markbasepos-graph.hh \
|
||||
graph/split-helpers.hh \
|
||||
graph/serialize.hh \
|
||||
OT/Color/COLR/colrv1-closure.hh \
|
||||
$(NULL)
|
||||
|
||||
HB_SUBSET_headers = \
|
||||
hb-subset.h \
|
||||
hb-subset-repacker.h \
|
||||
$(NULL)
|
||||
|
||||
HB_CAIRO_sources = \
|
||||
hb-cairo.cc \
|
||||
hb-cairo-utils.cc \
|
||||
hb-cairo-utils.hh \
|
||||
hb-static.cc \
|
||||
$(NULL)
|
||||
HB_CAIRO_headers = \
|
||||
hb-cairo.h \
|
||||
$(NULL)
|
||||
|
||||
HB_GOBJECT_DIST_sources = hb-gobject-structs.cc
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
* Copyright © 2020 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef OT_COLOR_COLR_COLRV1_CLOSURE_HH
|
||||
#define OT_COLOR_COLR_COLRV1_CLOSURE_HH
|
||||
|
||||
#include "../../../hb-open-type.hh"
|
||||
#include "COLR.hh"
|
||||
|
||||
/*
|
||||
* COLR -- Color
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/colr
|
||||
*/
|
||||
namespace OT {
|
||||
|
||||
HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
c->add_layer_indices (firstLayerIndex, numLayers);
|
||||
const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
|
||||
for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
|
||||
{
|
||||
const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i];
|
||||
paint.dispatch (c);
|
||||
}
|
||||
}
|
||||
|
||||
HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
c->add_glyph (gid);
|
||||
(this+paint).dispatch (c);
|
||||
}
|
||||
|
||||
HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
const COLR *colr_table = c->get_colr_table ();
|
||||
const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid);
|
||||
if (!baseglyph_paintrecord) return;
|
||||
c->add_glyph (gid);
|
||||
|
||||
const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList ();
|
||||
(&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c);
|
||||
}
|
||||
|
||||
template <template<typename> class Var>
|
||||
HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{ (this+src).dispatch (c); }
|
||||
|
||||
HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
|
||||
{
|
||||
(this+src).dispatch (c);
|
||||
(this+backdrop).dispatch (c);
|
||||
}
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* OT_COLOR_COLR_COLRV1_CLOSURE_HH */
|
|
@ -1,350 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2016 Google, Inc.
|
||||
* 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.
|
||||
*
|
||||
* Google Author(s): Sascha Brawer
|
||||
*/
|
||||
|
||||
#ifndef OT_COLOR_CPAL_CPAL_HH
|
||||
#define OT_COLOR_CPAL_CPAL_HH
|
||||
|
||||
#include "../../../hb-open-type.hh"
|
||||
#include "../../../hb-ot-color.h"
|
||||
#include "../../../hb-ot-name.h"
|
||||
|
||||
|
||||
/*
|
||||
* CPAL -- Color Palette
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
|
||||
*/
|
||||
#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
struct CPALV1Tail
|
||||
{
|
||||
friend struct CPAL;
|
||||
|
||||
private:
|
||||
hb_ot_color_palette_flags_t get_palette_flags (const void *base,
|
||||
unsigned int palette_index,
|
||||
unsigned int palette_count) const
|
||||
{
|
||||
if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
|
||||
return (hb_ot_color_palette_flags_t) (uint32_t)
|
||||
(base+paletteFlagsZ).as_array (palette_count)[palette_index];
|
||||
}
|
||||
|
||||
hb_ot_name_id_t get_palette_name_id (const void *base,
|
||||
unsigned int palette_index,
|
||||
unsigned int palette_count) const
|
||||
{
|
||||
if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID;
|
||||
return (base+paletteLabelsZ).as_array (palette_count)[palette_index];
|
||||
}
|
||||
|
||||
hb_ot_name_id_t get_color_name_id (const void *base,
|
||||
unsigned int color_index,
|
||||
unsigned int color_count) const
|
||||
{
|
||||
if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID;
|
||||
return (base+colorLabelsZ).as_array (color_count)[color_index];
|
||||
}
|
||||
|
||||
public:
|
||||
void collect_name_ids (const void *base,
|
||||
unsigned palette_count,
|
||||
unsigned color_count,
|
||||
const hb_map_t *color_index_map,
|
||||
hb_set_t *nameids_to_retain /* OUT */) const
|
||||
{
|
||||
if (paletteLabelsZ)
|
||||
{
|
||||
+ (base+paletteLabelsZ).as_array (palette_count)
|
||||
| hb_sink (nameids_to_retain)
|
||||
;
|
||||
}
|
||||
|
||||
if (colorLabelsZ)
|
||||
{
|
||||
const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
|
||||
for (unsigned i = 0; i < color_count; i++)
|
||||
{
|
||||
if (!color_index_map->has (i)) continue;
|
||||
nameids_to_retain->add (colorLabels[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
unsigned palette_count,
|
||||
unsigned color_count,
|
||||
const void *base,
|
||||
const hb_map_t *color_index_map) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto *out = c->allocate_size<CPALV1Tail> (static_size);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
out->paletteFlagsZ = 0;
|
||||
if (paletteFlagsZ)
|
||||
out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count);
|
||||
|
||||
out->paletteLabelsZ = 0;
|
||||
if (paletteLabelsZ)
|
||||
out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count);
|
||||
|
||||
const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
|
||||
if (colorLabelsZ)
|
||||
{
|
||||
c->push ();
|
||||
for (unsigned i = 0; i < color_count; i++)
|
||||
{
|
||||
if (!color_index_map->has (i)) continue;
|
||||
if (!c->copy<NameID> (colorLabels[i]))
|
||||
{
|
||||
c->pop_discard ();
|
||||
return_trace (false);
|
||||
}
|
||||
}
|
||||
c->add_link (out->colorLabelsZ, c->pop_pack ());
|
||||
}
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c,
|
||||
const void *base,
|
||||
unsigned int palette_count,
|
||||
unsigned int color_count) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
(!paletteFlagsZ || (base+paletteFlagsZ).sanitize (c, palette_count)) &&
|
||||
(!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) &&
|
||||
(!colorLabelsZ || (base+colorLabelsZ).sanitize (c, color_count)));
|
||||
}
|
||||
|
||||
protected:
|
||||
// TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets
|
||||
// here. Currently they are needed since UnsizedArrayOf doesn't define null_size
|
||||
NNOffset32To<UnsizedArrayOf<HBUINT32>>
|
||||
paletteFlagsZ; /* Offset from the beginning of CPAL table to
|
||||
* the Palette Type Array. Set to 0 if no array
|
||||
* is provided. */
|
||||
NNOffset32To<UnsizedArrayOf<NameID>>
|
||||
paletteLabelsZ; /* Offset from the beginning of CPAL table to
|
||||
* the palette labels array. Set to 0 if no
|
||||
* array is provided. */
|
||||
NNOffset32To<UnsizedArrayOf<NameID>>
|
||||
colorLabelsZ; /* Offset from the beginning of CPAL table to
|
||||
* the color labels array. Set to 0
|
||||
* if no array is provided. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
typedef HBUINT32 BGRAColor;
|
||||
|
||||
struct CPAL
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL;
|
||||
|
||||
bool has_data () const { return numPalettes; }
|
||||
|
||||
unsigned int get_size () const
|
||||
{ return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
|
||||
|
||||
unsigned int get_palette_count () const { return numPalettes; }
|
||||
unsigned int get_color_count () const { return numColors; }
|
||||
|
||||
hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
|
||||
{ return v1 ().get_palette_flags (this, palette_index, numPalettes); }
|
||||
|
||||
hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const
|
||||
{ return v1 ().get_palette_name_id (this, palette_index, numPalettes); }
|
||||
|
||||
hb_ot_name_id_t get_color_name_id (unsigned int color_index) const
|
||||
{ return v1 ().get_color_name_id (this, color_index, numColors); }
|
||||
|
||||
unsigned int get_palette_colors (unsigned int palette_index,
|
||||
unsigned int start_offset,
|
||||
unsigned int *color_count, /* IN/OUT. May be NULL. */
|
||||
hb_color_t *colors /* OUT. May be NULL. */) const
|
||||
{
|
||||
if (unlikely (palette_index >= numPalettes))
|
||||
{
|
||||
if (color_count) *color_count = 0;
|
||||
return 0;
|
||||
}
|
||||
unsigned int start_index = colorRecordIndicesZ[palette_index];
|
||||
hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords);
|
||||
hb_array_t<const BGRAColor> palette_colors = all_colors.sub_array (start_index,
|
||||
numColors);
|
||||
if (color_count)
|
||||
{
|
||||
+ palette_colors.sub_array (start_offset, color_count)
|
||||
| hb_sink (hb_array (colors, *color_count))
|
||||
;
|
||||
}
|
||||
return numColors;
|
||||
}
|
||||
|
||||
void collect_name_ids (const hb_map_t *color_index_map,
|
||||
hb_set_t *nameids_to_retain /* OUT */) const
|
||||
{
|
||||
if (version == 1)
|
||||
v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain);
|
||||
}
|
||||
|
||||
private:
|
||||
const CPALV1Tail& v1 () const
|
||||
{
|
||||
if (version == 0) return Null (CPALV1Tail);
|
||||
return StructAfter<CPALV1Tail> (*this);
|
||||
}
|
||||
|
||||
public:
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
const hb_array_t<const HBUINT16> &color_record_indices,
|
||||
const hb_array_t<const BGRAColor> &color_records,
|
||||
const hb_vector_t<unsigned>& first_color_index_for_layer,
|
||||
const hb_map_t& first_color_to_layer_index,
|
||||
const hb_set_t &retained_color_indices) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
|
||||
// TODO(grieger): limit total final size.
|
||||
|
||||
for (const auto idx : color_record_indices)
|
||||
{
|
||||
hb_codepoint_t layer_index = first_color_to_layer_index[idx];
|
||||
|
||||
HBUINT16 new_idx;
|
||||
new_idx = layer_index * retained_color_indices.get_population ();
|
||||
if (!c->copy<HBUINT16> (new_idx)) return_trace (false);
|
||||
}
|
||||
|
||||
c->push ();
|
||||
for (unsigned first_color_index : first_color_index_for_layer)
|
||||
{
|
||||
for (hb_codepoint_t color_index : retained_color_indices)
|
||||
{
|
||||
if (!c->copy<BGRAColor> (color_records[first_color_index + color_index]))
|
||||
{
|
||||
c->pop_discard ();
|
||||
return_trace (false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c->add_link (colorRecordsZ, c->pop_pack ());
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
if (!numPalettes) return_trace (false);
|
||||
|
||||
const hb_map_t *color_index_map = &c->plan->colr_palettes;
|
||||
if (color_index_map->is_empty ()) return_trace (false);
|
||||
|
||||
hb_set_t retained_color_indices;
|
||||
for (const auto _ : color_index_map->keys ())
|
||||
{
|
||||
if (_ == 0xFFFF) continue;
|
||||
retained_color_indices.add (_);
|
||||
}
|
||||
if (retained_color_indices.is_empty ()) return_trace (false);
|
||||
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
|
||||
out->version = version;
|
||||
out->numColors = retained_color_indices.get_population ();
|
||||
out->numPalettes = numPalettes;
|
||||
|
||||
hb_vector_t<unsigned> first_color_index_for_layer;
|
||||
hb_map_t first_color_to_layer_index;
|
||||
|
||||
const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes);
|
||||
for (const auto first_color_record_idx : colorRecordIndices)
|
||||
{
|
||||
if (first_color_to_layer_index.has (first_color_record_idx)) continue;
|
||||
|
||||
first_color_index_for_layer.push (first_color_record_idx);
|
||||
first_color_to_layer_index.set (first_color_record_idx,
|
||||
first_color_index_for_layer.length - 1);
|
||||
}
|
||||
|
||||
out->numColorRecords = first_color_index_for_layer.length
|
||||
* retained_color_indices.get_population ();
|
||||
|
||||
const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords);
|
||||
if (!out->serialize (c->serializer,
|
||||
colorRecordIndices,
|
||||
color_records,
|
||||
first_color_index_for_layer,
|
||||
first_color_to_layer_index,
|
||||
retained_color_indices))
|
||||
return_trace (false);
|
||||
|
||||
if (version == 1)
|
||||
return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map));
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
(this+colorRecordsZ).sanitize (c, numColorRecords) &&
|
||||
colorRecordIndicesZ.sanitize (c, numPalettes) &&
|
||||
(version == 0 || v1 ().sanitize (c, this, numPalettes, numColors)));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 version; /* Table version number */
|
||||
/* Version 0 */
|
||||
HBUINT16 numColors; /* Number of colors in each palette. */
|
||||
HBUINT16 numPalettes; /* Number of palettes in the table. */
|
||||
HBUINT16 numColorRecords; /* Total number of color records, combined for
|
||||
* all palettes. */
|
||||
NNOffset32To<UnsizedArrayOf<BGRAColor>>
|
||||
colorRecordsZ; /* Offset from the beginning of CPAL table to
|
||||
* the first ColorRecord. */
|
||||
UnsizedArrayOf<HBUINT16>
|
||||
colorRecordIndicesZ; /* Index of each palette’s first color record in
|
||||
* the combined color record array. */
|
||||
/*CPALV1Tail v1;*/
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* OT_COLOR_CPAL_CPAL_HH */
|
|
@ -1,452 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
* Copyright © 2020 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Calder Kitagawa
|
||||
*/
|
||||
|
||||
#ifndef OT_COLOR_SBIX_SBIX_HH
|
||||
#define OT_COLOR_SBIX_SBIX_HH
|
||||
|
||||
#include "../../../hb-open-type.hh"
|
||||
#include "../../../hb-paint.hh"
|
||||
|
||||
/*
|
||||
* sbix -- Standard Bitmap Graphics
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/sbix
|
||||
* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html
|
||||
*/
|
||||
#define HB_OT_TAG_sbix HB_TAG('s','b','i','x')
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
struct SBIXGlyph
|
||||
{
|
||||
SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> ();
|
||||
if (unlikely (!new_glyph)) return_trace (nullptr);
|
||||
if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
|
||||
|
||||
new_glyph->xOffset = xOffset;
|
||||
new_glyph->yOffset = yOffset;
|
||||
new_glyph->graphicType = graphicType;
|
||||
data.copy (c, data_length);
|
||||
return_trace (new_glyph);
|
||||
}
|
||||
|
||||
HBINT16 xOffset; /* The horizontal (x-axis) offset from the left
|
||||
* edge of the graphic to the glyph’s origin.
|
||||
* That is, the x-coordinate of the point on the
|
||||
* baseline at the left edge of the glyph. */
|
||||
HBINT16 yOffset; /* The vertical (y-axis) offset from the bottom
|
||||
* edge of the graphic to the glyph’s origin.
|
||||
* That is, the y-coordinate of the point on the
|
||||
* baseline at the left edge of the glyph. */
|
||||
Tag graphicType; /* Indicates the format of the embedded graphic
|
||||
* data: one of 'jpg ', 'png ' or 'tiff', or the
|
||||
* special format 'dupe'. */
|
||||
UnsizedArrayOf<HBUINT8>
|
||||
data; /* The actual embedded graphic data. The total
|
||||
* length is inferred from sequential entries in
|
||||
* the glyphDataOffsets array and the fixed size
|
||||
* (8 bytes) of the preceding fields. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, data);
|
||||
};
|
||||
|
||||
struct SBIXStrike
|
||||
{
|
||||
static unsigned int get_size (unsigned num_glyphs)
|
||||
{ return min_size + num_glyphs * HBUINT32::static_size; }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1));
|
||||
}
|
||||
|
||||
hb_blob_t *get_glyph_blob (unsigned int glyph_id,
|
||||
hb_blob_t *sbix_blob,
|
||||
hb_tag_t file_type,
|
||||
int *x_offset,
|
||||
int *y_offset,
|
||||
unsigned int num_glyphs,
|
||||
unsigned int *strike_ppem) const
|
||||
{
|
||||
if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */
|
||||
|
||||
unsigned int retry_count = 8;
|
||||
unsigned int sbix_len = sbix_blob->length;
|
||||
unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data;
|
||||
assert (strike_offset < sbix_len);
|
||||
|
||||
retry:
|
||||
if (unlikely (glyph_id >= num_glyphs ||
|
||||
imageOffsetsZ[glyph_id + 1] <= imageOffsetsZ[glyph_id] ||
|
||||
imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size ||
|
||||
(unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset))
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size;
|
||||
unsigned int glyph_length = imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size;
|
||||
|
||||
const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]);
|
||||
|
||||
if (glyph->graphicType == HB_TAG ('d','u','p','e'))
|
||||
{
|
||||
if (glyph_length >= 2)
|
||||
{
|
||||
glyph_id = *((HBUINT16 *) &glyph->data);
|
||||
if (retry_count--)
|
||||
goto retry;
|
||||
}
|
||||
return hb_blob_get_empty ();
|
||||
}
|
||||
|
||||
if (unlikely (file_type != glyph->graphicType))
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
if (strike_ppem) *strike_ppem = ppem;
|
||||
if (x_offset) *x_offset = glyph->xOffset;
|
||||
if (y_offset) *y_offset = glyph->yOffset;
|
||||
return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c, unsigned int available_len) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
|
||||
|
||||
auto* out = c->serializer->start_embed<SBIXStrike> ();
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
auto snap = c->serializer->snapshot ();
|
||||
if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false);
|
||||
out->ppem = ppem;
|
||||
out->resolution = resolution;
|
||||
HBUINT32 head;
|
||||
head = get_size (num_output_glyphs + 1);
|
||||
|
||||
bool has_glyphs = false;
|
||||
for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++)
|
||||
{
|
||||
hb_codepoint_t old_gid;
|
||||
if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) ||
|
||||
unlikely (imageOffsetsZ[old_gid].is_null () ||
|
||||
imageOffsetsZ[old_gid + 1].is_null () ||
|
||||
imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] ||
|
||||
imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) ||
|
||||
(unsigned int) imageOffsetsZ[old_gid + 1] > available_len)
|
||||
{
|
||||
out->imageOffsetsZ[new_gid] = head;
|
||||
continue;
|
||||
}
|
||||
has_glyphs = true;
|
||||
unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid];
|
||||
unsigned int glyph_data_length = delta - SBIXGlyph::min_size;
|
||||
if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length))
|
||||
return_trace (false);
|
||||
out->imageOffsetsZ[new_gid] = head;
|
||||
head += delta;
|
||||
}
|
||||
if (has_glyphs)
|
||||
out->imageOffsetsZ[num_output_glyphs] = head;
|
||||
else
|
||||
c->serializer->revert (snap);
|
||||
return_trace (has_glyphs);
|
||||
}
|
||||
|
||||
public:
|
||||
HBUINT16 ppem; /* The PPEM size for which this strike was designed. */
|
||||
HBUINT16 resolution; /* The device pixel density (in PPI) for which this
|
||||
* strike was designed. (E.g., 96 PPI, 192 PPI.) */
|
||||
protected:
|
||||
UnsizedArrayOf<Offset32To<SBIXGlyph>>
|
||||
imageOffsetsZ; /* Offset from the beginning of the strike data header
|
||||
* to bitmap data for an individual glyph ID. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, imageOffsetsZ);
|
||||
};
|
||||
|
||||
struct sbix
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_sbix;
|
||||
|
||||
bool has_data () const { return version; }
|
||||
|
||||
const SBIXStrike &get_strike (unsigned int i) const { return this+strikes[i]; }
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
table = hb_sanitize_context_t ().reference_table<sbix> (face);
|
||||
num_glyphs = face->get_num_glyphs ();
|
||||
}
|
||||
~accelerator_t () { table.destroy (); }
|
||||
|
||||
bool has_data () const { return table->has_data (); }
|
||||
|
||||
bool get_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents,
|
||||
bool scale = true) const
|
||||
{
|
||||
/* We only support PNG right now, and following function checks type. */
|
||||
return get_png_extents (font, glyph, extents, scale);
|
||||
}
|
||||
|
||||
hb_blob_t *reference_png (hb_font_t *font,
|
||||
hb_codepoint_t glyph_id,
|
||||
int *x_offset,
|
||||
int *y_offset,
|
||||
unsigned int *available_ppem) const
|
||||
{
|
||||
return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (),
|
||||
HB_TAG ('p','n','g',' '),
|
||||
x_offset, y_offset,
|
||||
num_glyphs, available_ppem);
|
||||
}
|
||||
|
||||
bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
|
||||
{
|
||||
if (!has_data ())
|
||||
return false;
|
||||
|
||||
int x_offset = 0, y_offset = 0;
|
||||
unsigned int strike_ppem = 0;
|
||||
hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
|
||||
hb_glyph_extents_t extents;
|
||||
hb_glyph_extents_t pixel_extents;
|
||||
|
||||
if (blob == hb_blob_get_empty ())
|
||||
return false;
|
||||
|
||||
if (!hb_font_get_glyph_extents (font, glyph, &extents))
|
||||
return false;
|
||||
|
||||
if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
|
||||
return false;
|
||||
|
||||
bool ret = funcs->image (data,
|
||||
blob,
|
||||
pixel_extents.width, -pixel_extents.height,
|
||||
HB_PAINT_IMAGE_FORMAT_PNG,
|
||||
font->slant_xy,
|
||||
&extents);
|
||||
|
||||
hb_blob_destroy (blob);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const SBIXStrike &choose_strike (hb_font_t *font) const
|
||||
{
|
||||
unsigned count = table->strikes.len;
|
||||
if (unlikely (!count))
|
||||
return Null (SBIXStrike);
|
||||
|
||||
unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
|
||||
if (!requested_ppem)
|
||||
requested_ppem = 1<<30; /* Choose largest strike. */
|
||||
/* TODO Add DPI sensitivity as well? */
|
||||
unsigned int best_i = 0;
|
||||
unsigned int best_ppem = table->get_strike (0).ppem;
|
||||
|
||||
for (unsigned int i = 1; i < count; i++)
|
||||
{
|
||||
unsigned int ppem = (table->get_strike (i)).ppem;
|
||||
if ((requested_ppem <= ppem && ppem < best_ppem) ||
|
||||
(requested_ppem > best_ppem && ppem > best_ppem))
|
||||
{
|
||||
best_i = i;
|
||||
best_ppem = ppem;
|
||||
}
|
||||
}
|
||||
|
||||
return table->get_strike (best_i);
|
||||
}
|
||||
|
||||
struct PNGHeader
|
||||
{
|
||||
HBUINT8 signature[8];
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
HBUINT32 length;
|
||||
Tag type;
|
||||
} header;
|
||||
HBUINT32 width;
|
||||
HBUINT32 height;
|
||||
HBUINT8 bitDepth;
|
||||
HBUINT8 colorType;
|
||||
HBUINT8 compressionMethod;
|
||||
HBUINT8 filterMethod;
|
||||
HBUINT8 interlaceMethod;
|
||||
} IHDR;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (29);
|
||||
};
|
||||
|
||||
bool get_png_extents (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
hb_glyph_extents_t *extents,
|
||||
bool scale = true) const
|
||||
{
|
||||
/* Following code is safe to call even without data.
|
||||
* But faster to short-circuit. */
|
||||
if (!has_data ())
|
||||
return false;
|
||||
|
||||
int x_offset = 0, y_offset = 0;
|
||||
unsigned int strike_ppem = 0;
|
||||
hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
|
||||
|
||||
const PNGHeader &png = *blob->as<PNGHeader>();
|
||||
|
||||
if (png.IHDR.height >= 65536 || png.IHDR.width >= 65536)
|
||||
{
|
||||
hb_blob_destroy (blob);
|
||||
return false;
|
||||
}
|
||||
|
||||
extents->x_bearing = x_offset;
|
||||
extents->y_bearing = png.IHDR.height + y_offset;
|
||||
extents->width = png.IHDR.width;
|
||||
extents->height = -1 * png.IHDR.height;
|
||||
|
||||
/* Convert to font units. */
|
||||
if (strike_ppem && scale)
|
||||
{
|
||||
float scale = font->face->get_upem () / (float) strike_ppem;
|
||||
extents->x_bearing = roundf (extents->x_bearing * scale);
|
||||
extents->y_bearing = roundf (extents->y_bearing * scale);
|
||||
extents->width = roundf (extents->width * scale);
|
||||
extents->height = roundf (extents->height * scale);
|
||||
}
|
||||
|
||||
if (scale)
|
||||
font->scale_glyph_extents (extents);
|
||||
|
||||
hb_blob_destroy (blob);
|
||||
|
||||
return strike_ppem;
|
||||
}
|
||||
|
||||
private:
|
||||
hb_blob_ptr_t<sbix> table;
|
||||
|
||||
unsigned int num_glyphs;
|
||||
};
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (likely (c->check_struct (this) &&
|
||||
version >= 1 &&
|
||||
strikes.sanitize (c, this)));
|
||||
}
|
||||
|
||||
bool
|
||||
add_strike (hb_subset_context_t *c, unsigned i) const
|
||||
{
|
||||
if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i])
|
||||
return false;
|
||||
|
||||
return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]);
|
||||
}
|
||||
|
||||
bool serialize_strike_offsets (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
|
||||
auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> ();
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
hb_vector_t<Offset32To<SBIXStrike>*> new_strikes;
|
||||
hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
|
||||
for (int i = strikes.len - 1; i >= 0; --i)
|
||||
{
|
||||
auto* o = out->serialize_append (c->serializer);
|
||||
if (unlikely (!o)) return_trace (false);
|
||||
*o = 0;
|
||||
auto snap = c->serializer->snapshot ();
|
||||
c->serializer->push ();
|
||||
bool ret = add_strike (c, i);
|
||||
if (!ret)
|
||||
{
|
||||
c->serializer->pop_discard ();
|
||||
out->pop ();
|
||||
c->serializer->revert (snap);
|
||||
}
|
||||
else
|
||||
{
|
||||
objidxs.push (c->serializer->pop_pack ());
|
||||
new_strikes.push (o);
|
||||
}
|
||||
}
|
||||
for (unsigned int i = 0; i < new_strikes.length; ++i)
|
||||
c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t* c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
|
||||
sbix *sbix_prime = c->serializer->start_embed<sbix> ();
|
||||
if (unlikely (!sbix_prime)) return_trace (false);
|
||||
if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
|
||||
if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
|
||||
|
||||
return_trace (serialize_strike_offsets (c));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 version; /* Table version number — set to 1 */
|
||||
HBUINT16 flags; /* Bit 0: Set to 1. Bit 1: Draw outlines.
|
||||
* Bits 2 to 15: reserved (set to 0). */
|
||||
Array32OfOffset32To<SBIXStrike>
|
||||
strikes; /* Offsets from the beginning of the 'sbix'
|
||||
* table to data for each individual bitmap strike. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, strikes);
|
||||
};
|
||||
|
||||
struct sbix_accelerator_t : sbix::accelerator_t {
|
||||
sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
#endif /* OT_COLOR_SBIX_SBIX_HH */
|
|
@ -1,151 +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 OT_COLOR_SVG_SVG_HH
|
||||
#define OT_COLOR_SVG_SVG_HH
|
||||
|
||||
#include "../../../hb-open-type.hh"
|
||||
#include "../../../hb-blob.hh"
|
||||
#include "../../../hb-paint.hh"
|
||||
|
||||
/*
|
||||
* SVG -- SVG (Scalable Vector Graphics)
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/svg
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ')
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
struct SVGDocumentIndexEntry
|
||||
{
|
||||
int cmp (hb_codepoint_t g) const
|
||||
{ return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; }
|
||||
|
||||
hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
|
||||
{
|
||||
return hb_blob_create_sub_blob (svg_blob,
|
||||
index_offset + (unsigned int) svgDoc,
|
||||
svgDocLength);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
svgDoc.sanitize (c, base, svgDocLength));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 startGlyphID; /* The first glyph ID in the range described by
|
||||
* this index entry. */
|
||||
HBUINT16 endGlyphID; /* The last glyph ID in the range described by
|
||||
* this index entry. Must be >= startGlyphID. */
|
||||
NNOffset32To<UnsizedArrayOf<HBUINT8>>
|
||||
svgDoc; /* Offset from the beginning of the SVG Document Index
|
||||
* to an SVG document. Must be non-zero. */
|
||||
HBUINT32 svgDocLength; /* Length of the SVG document.
|
||||
* Must be non-zero. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
||||
struct SVG
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_SVG;
|
||||
|
||||
bool has_data () const { return svgDocEntries; }
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
accelerator_t (hb_face_t *face)
|
||||
{ table = hb_sanitize_context_t ().reference_table<SVG> (face); }
|
||||
~accelerator_t () { table.destroy (); }
|
||||
|
||||
hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
|
||||
{
|
||||
return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (),
|
||||
table->svgDocEntries);
|
||||
}
|
||||
|
||||
bool has_data () const { return table->has_data (); }
|
||||
|
||||
bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
|
||||
{
|
||||
if (!has_data ())
|
||||
return false;
|
||||
|
||||
hb_blob_t *blob = reference_blob_for_glyph (glyph);
|
||||
|
||||
if (blob == hb_blob_get_empty ())
|
||||
return false;
|
||||
|
||||
funcs->image (data,
|
||||
blob,
|
||||
0, 0,
|
||||
HB_PAINT_IMAGE_FORMAT_SVG,
|
||||
font->slant_xy,
|
||||
nullptr);
|
||||
|
||||
hb_blob_destroy (blob);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
hb_blob_ptr_t<SVG> table;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (sizeof (hb_blob_ptr_t<SVG>));
|
||||
};
|
||||
|
||||
const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
|
||||
{ return (this+svgDocEntries).bsearch (glyph_id); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (likely (c->check_struct (this) &&
|
||||
(this+svgDocEntries).sanitize_shallow (c)));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 version; /* Table version (starting at 0). */
|
||||
Offset32To<SortedArray16Of<SVGDocumentIndexEntry>>
|
||||
svgDocEntries; /* Offset (relative to the start of the SVG table) to the
|
||||
* SVG Documents Index. Must be non-zero. */
|
||||
/* Array of SVG Document Index Entries. */
|
||||
HBUINT32 reserved; /* Set to 0. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
};
|
||||
|
||||
struct SVG_accelerator_t : SVG::accelerator_t {
|
||||
SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* OT_COLOR_SVG_SVG_HH */
|
|
@ -1,337 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2010,2012 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod, Garret Rieger
|
||||
*/
|
||||
|
||||
#ifndef OT_LAYOUT_COMMON_COVERAGE_HH
|
||||
#define OT_LAYOUT_COMMON_COVERAGE_HH
|
||||
|
||||
#include "../types.hh"
|
||||
#include "CoverageFormat1.hh"
|
||||
#include "CoverageFormat2.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace Common {
|
||||
|
||||
template<typename Iterator>
|
||||
static inline void Coverage_serialize (hb_serialize_context_t *c,
|
||||
Iterator it);
|
||||
|
||||
struct Coverage
|
||||
{
|
||||
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
CoverageFormat1_3<SmallTypes> format1;
|
||||
CoverageFormat2_4<SmallTypes> format2;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
CoverageFormat1_3<MediumTypes>format3;
|
||||
CoverageFormat2_4<MediumTypes>format4;
|
||||
#endif
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return_trace (false);
|
||||
switch (u.format)
|
||||
{
|
||||
case 1: return_trace (u.format1.sanitize (c));
|
||||
case 2: return_trace (u.format2.sanitize (c));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return_trace (u.format3.sanitize (c));
|
||||
case 4: return_trace (u.format4.sanitize (c));
|
||||
#endif
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
/* Has interface. */
|
||||
unsigned operator [] (hb_codepoint_t k) const { return get (k); }
|
||||
bool has (hb_codepoint_t k) const { return (*this)[k] != NOT_COVERED; }
|
||||
/* Predicate. */
|
||||
bool operator () (hb_codepoint_t k) const { return has (k); }
|
||||
|
||||
unsigned int get (hb_codepoint_t k) const { return get_coverage (k); }
|
||||
unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.get_coverage (glyph_id);
|
||||
case 2: return u.format2.get_coverage (glyph_id);
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3.get_coverage (glyph_id);
|
||||
case 4: return u.format4.get_coverage (glyph_id);
|
||||
#endif
|
||||
default:return NOT_COVERED;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned get_population () const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.get_population ();
|
||||
case 2: return u.format2.get_population ();
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3.get_population ();
|
||||
case 4: return u.format4.get_population ();
|
||||
#endif
|
||||
default:return NOT_COVERED;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Iterator,
|
||||
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
|
||||
bool serialize (hb_serialize_context_t *c, Iterator glyphs)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (this))) return_trace (false);
|
||||
|
||||
unsigned count = 0;
|
||||
unsigned num_ranges = 0;
|
||||
hb_codepoint_t last = (hb_codepoint_t) -2;
|
||||
for (auto g: glyphs)
|
||||
{
|
||||
if (last + 1 != g)
|
||||
num_ranges++;
|
||||
last = g;
|
||||
count++;
|
||||
}
|
||||
u.format = count <= num_ranges * 3 ? 1 : 2;
|
||||
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
if (count && last > 0xFFFFu)
|
||||
u.format += 2;
|
||||
#endif
|
||||
|
||||
switch (u.format)
|
||||
{
|
||||
case 1: return_trace (u.format1.serialize (c, glyphs));
|
||||
case 2: return_trace (u.format2.serialize (c, glyphs));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return_trace (u.format3.serialize (c, glyphs));
|
||||
case 4: return_trace (u.format4.serialize (c, glyphs));
|
||||
#endif
|
||||
default:return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto it =
|
||||
+ iter ()
|
||||
| hb_take (c->plan->source->get_num_glyphs ())
|
||||
| hb_filter (c->plan->glyph_map_gsub)
|
||||
| hb_map_retains_sorting (c->plan->glyph_map_gsub)
|
||||
;
|
||||
|
||||
// Cache the iterator result as it will be iterated multiple times
|
||||
// by the serialize code below.
|
||||
hb_sorted_vector_t<hb_codepoint_t> glyphs (it);
|
||||
Coverage_serialize (c->serializer, glyphs.iter ());
|
||||
return_trace (bool (glyphs));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
switch (u.format)
|
||||
{
|
||||
case 1: return u.format1.intersects (glyphs);
|
||||
case 2: return u.format2.intersects (glyphs);
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3.intersects (glyphs);
|
||||
case 4: return u.format4.intersects (glyphs);
|
||||
#endif
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
||||
{
|
||||
switch (u.format)
|
||||
{
|
||||
case 1: return u.format1.intersects_coverage (glyphs, index);
|
||||
case 2: return u.format2.intersects_coverage (glyphs, index);
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3.intersects_coverage (glyphs, index);
|
||||
case 4: return u.format4.intersects_coverage (glyphs, index);
|
||||
#endif
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Might return false if array looks unsorted.
|
||||
* Used for faster rejection of corrupt data. */
|
||||
template <typename set_t>
|
||||
bool collect_coverage (set_t *glyphs) const
|
||||
{
|
||||
switch (u.format)
|
||||
{
|
||||
case 1: return u.format1.collect_coverage (glyphs);
|
||||
case 2: return u.format2.collect_coverage (glyphs);
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3.collect_coverage (glyphs);
|
||||
case 4: return u.format4.collect_coverage (glyphs);
|
||||
#endif
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename IterableOut,
|
||||
hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
|
||||
void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
|
||||
{
|
||||
switch (u.format)
|
||||
{
|
||||
case 1: return u.format1.intersect_set (glyphs, intersect_glyphs);
|
||||
case 2: return u.format2.intersect_set (glyphs, intersect_glyphs);
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3.intersect_set (glyphs, intersect_glyphs);
|
||||
case 4: return u.format4.intersect_set (glyphs, intersect_glyphs);
|
||||
#endif
|
||||
default:return ;
|
||||
}
|
||||
}
|
||||
|
||||
struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
|
||||
{
|
||||
static constexpr bool is_sorted_iterator = true;
|
||||
iter_t (const Coverage &c_ = Null (Coverage))
|
||||
{
|
||||
hb_memset (this, 0, sizeof (*this));
|
||||
format = c_.u.format;
|
||||
switch (format)
|
||||
{
|
||||
case 1: u.format1.init (c_.u.format1); return;
|
||||
case 2: u.format2.init (c_.u.format2); return;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: u.format3.init (c_.u.format3); return;
|
||||
case 4: u.format4.init (c_.u.format4); return;
|
||||
#endif
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
bool __more__ () const
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case 1: return u.format1.__more__ ();
|
||||
case 2: return u.format2.__more__ ();
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3.__more__ ();
|
||||
case 4: return u.format4.__more__ ();
|
||||
#endif
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
void __next__ ()
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case 1: u.format1.__next__ (); break;
|
||||
case 2: u.format2.__next__ (); break;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: u.format3.__next__ (); break;
|
||||
case 4: u.format4.__next__ (); break;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
typedef hb_codepoint_t __item_t__;
|
||||
__item_t__ __item__ () const { return get_glyph (); }
|
||||
|
||||
hb_codepoint_t get_glyph () const
|
||||
{
|
||||
switch (format)
|
||||
{
|
||||
case 1: return u.format1.get_glyph ();
|
||||
case 2: return u.format2.get_glyph ();
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3.get_glyph ();
|
||||
case 4: return u.format4.get_glyph ();
|
||||
#endif
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
bool operator != (const iter_t& o) const
|
||||
{
|
||||
if (unlikely (format != o.format)) return true;
|
||||
switch (format)
|
||||
{
|
||||
case 1: return u.format1 != o.u.format1;
|
||||
case 2: return u.format2 != o.u.format2;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return u.format3 != o.u.format3;
|
||||
case 4: return u.format4 != o.u.format4;
|
||||
#endif
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
iter_t __end__ () const
|
||||
{
|
||||
iter_t it = {};
|
||||
it.format = format;
|
||||
switch (format)
|
||||
{
|
||||
case 1: it.u.format1 = u.format1.__end__ (); break;
|
||||
case 2: it.u.format2 = u.format2.__end__ (); break;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: it.u.format3 = u.format3.__end__ (); break;
|
||||
case 4: it.u.format4 = u.format4.__end__ (); break;
|
||||
#endif
|
||||
default: break;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int format;
|
||||
union {
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
CoverageFormat2_4<MediumTypes>::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */
|
||||
CoverageFormat1_3<MediumTypes>::iter_t format3;
|
||||
#endif
|
||||
CoverageFormat2_4<SmallTypes>::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */
|
||||
CoverageFormat1_3<SmallTypes>::iter_t format1;
|
||||
} u;
|
||||
};
|
||||
iter_t iter () const { return iter_t (*this); }
|
||||
};
|
||||
|
||||
template<typename Iterator>
|
||||
static inline void
|
||||
Coverage_serialize (hb_serialize_context_t *c,
|
||||
Iterator it)
|
||||
{ c->start_embed<Coverage> ()->serialize (c, it); }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef OT_LAYOUT_COMMON_COVERAGE_HH
|
|
@ -1,133 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2010,2012 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod, Garret Rieger
|
||||
*/
|
||||
|
||||
|
||||
#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
|
||||
#define OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace Common {
|
||||
|
||||
#define NOT_COVERED ((unsigned int) -1)
|
||||
|
||||
template <typename Types>
|
||||
struct CoverageFormat1_3
|
||||
{
|
||||
friend struct Coverage;
|
||||
|
||||
protected:
|
||||
HBUINT16 coverageFormat; /* Format identifier--format = 1 */
|
||||
SortedArray16Of<typename Types::HBGlyphID>
|
||||
glyphArray; /* Array of GlyphIDs--in numerical order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, glyphArray);
|
||||
|
||||
private:
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (glyphArray.sanitize (c));
|
||||
}
|
||||
|
||||
unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
||||
{
|
||||
unsigned int i;
|
||||
glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED);
|
||||
return i;
|
||||
}
|
||||
|
||||
unsigned get_population () const
|
||||
{
|
||||
return glyphArray.len;
|
||||
}
|
||||
|
||||
template <typename Iterator,
|
||||
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
|
||||
bool serialize (hb_serialize_context_t *c, Iterator glyphs)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
return_trace (glyphArray.serialize (c, glyphs));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2)
|
||||
{
|
||||
for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
|
||||
if (get_coverage (g) != NOT_COVERED)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& g : glyphArray.as_array ())
|
||||
if (glyphs->has (g))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
||||
{ return glyphs->has (glyphArray[index]); }
|
||||
|
||||
template <typename IterableOut,
|
||||
hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
|
||||
void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
|
||||
{
|
||||
unsigned count = glyphArray.len;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
if (glyphs.has (glyphArray[i]))
|
||||
intersect_glyphs << glyphArray[i];
|
||||
}
|
||||
|
||||
template <typename set_t>
|
||||
bool collect_coverage (set_t *glyphs) const
|
||||
{ return glyphs->add_sorted_array (glyphArray.as_array ()); }
|
||||
|
||||
public:
|
||||
/* Older compilers need this to be public. */
|
||||
struct iter_t
|
||||
{
|
||||
void init (const struct CoverageFormat1_3 &c_) { c = &c_; i = 0; }
|
||||
bool __more__ () const { return i < c->glyphArray.len; }
|
||||
void __next__ () { i++; }
|
||||
hb_codepoint_t get_glyph () const { return c->glyphArray[i]; }
|
||||
bool operator != (const iter_t& o) const
|
||||
{ return i != o.i; }
|
||||
iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; }
|
||||
|
||||
private:
|
||||
const struct CoverageFormat1_3 *c;
|
||||
unsigned int i;
|
||||
};
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
|
|
@ -1,232 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2010,2012 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod, Garret Rieger
|
||||
*/
|
||||
|
||||
#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
|
||||
#define OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
|
||||
|
||||
#include "RangeRecord.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace Common {
|
||||
|
||||
template <typename Types>
|
||||
struct CoverageFormat2_4
|
||||
{
|
||||
friend struct Coverage;
|
||||
|
||||
protected:
|
||||
HBUINT16 coverageFormat; /* Format identifier--format = 2 */
|
||||
SortedArray16Of<RangeRecord<Types>>
|
||||
rangeRecord; /* Array of glyph ranges--ordered by
|
||||
* Start GlyphID. rangeCount entries
|
||||
* long */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, rangeRecord);
|
||||
|
||||
private:
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (rangeRecord.sanitize (c));
|
||||
}
|
||||
|
||||
unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
||||
{
|
||||
const RangeRecord<Types> &range = rangeRecord.bsearch (glyph_id);
|
||||
return likely (range.first <= range.last)
|
||||
? (unsigned int) range.value + (glyph_id - range.first)
|
||||
: NOT_COVERED;
|
||||
}
|
||||
|
||||
unsigned get_population () const
|
||||
{
|
||||
typename Types::large_int ret = 0;
|
||||
for (const auto &r : rangeRecord)
|
||||
ret += r.get_population ();
|
||||
return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
|
||||
}
|
||||
|
||||
template <typename Iterator,
|
||||
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
|
||||
bool serialize (hb_serialize_context_t *c, Iterator glyphs)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (this))) return_trace (false);
|
||||
|
||||
unsigned num_ranges = 0;
|
||||
hb_codepoint_t last = (hb_codepoint_t) -2;
|
||||
for (auto g: glyphs)
|
||||
{
|
||||
if (last + 1 != g)
|
||||
num_ranges++;
|
||||
last = g;
|
||||
}
|
||||
|
||||
if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false);
|
||||
if (!num_ranges) return_trace (true);
|
||||
|
||||
unsigned count = 0;
|
||||
unsigned range = (unsigned) -1;
|
||||
last = (hb_codepoint_t) -2;
|
||||
for (auto g: glyphs)
|
||||
{
|
||||
if (last + 1 != g)
|
||||
{
|
||||
range++;
|
||||
rangeRecord[range].first = g;
|
||||
rangeRecord[range].value = count;
|
||||
}
|
||||
rangeRecord[range].last = g;
|
||||
last = g;
|
||||
count++;
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
|
||||
{
|
||||
for (hb_codepoint_t g = HB_SET_VALUE_INVALID; glyphs->next (&g);)
|
||||
if (get_coverage (g) != NOT_COVERED)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return hb_any (+ hb_iter (rangeRecord)
|
||||
| hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); }));
|
||||
}
|
||||
bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
||||
{
|
||||
auto *range = rangeRecord.as_array ().bsearch (index);
|
||||
if (range)
|
||||
return range->intersects (*glyphs);
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename IterableOut,
|
||||
hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
|
||||
void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
|
||||
{
|
||||
/* Break out of loop for overlapping, broken, tables,
|
||||
* to avoid fuzzer timouts. */
|
||||
hb_codepoint_t last = 0;
|
||||
for (const auto& range : rangeRecord)
|
||||
{
|
||||
if (unlikely (range.first < last))
|
||||
break;
|
||||
last = range.last;
|
||||
for (hb_codepoint_t g = range.first - 1;
|
||||
glyphs.next (&g) && g <= last;)
|
||||
intersect_glyphs << g;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename set_t>
|
||||
bool collect_coverage (set_t *glyphs) const
|
||||
{
|
||||
for (const auto& range: rangeRecord)
|
||||
if (unlikely (!range.collect_coverage (glyphs)))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
/* Older compilers need this to be public. */
|
||||
struct iter_t
|
||||
{
|
||||
void init (const CoverageFormat2_4 &c_)
|
||||
{
|
||||
c = &c_;
|
||||
coverage = 0;
|
||||
i = 0;
|
||||
j = c->rangeRecord.len ? c->rangeRecord[0].first : 0;
|
||||
if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last))
|
||||
{
|
||||
/* Broken table. Skip. */
|
||||
i = c->rangeRecord.len;
|
||||
j = 0;
|
||||
}
|
||||
}
|
||||
bool __more__ () const { return i < c->rangeRecord.len; }
|
||||
void __next__ ()
|
||||
{
|
||||
if (j >= c->rangeRecord[i].last)
|
||||
{
|
||||
i++;
|
||||
if (__more__ ())
|
||||
{
|
||||
unsigned int old = coverage;
|
||||
j = c->rangeRecord[i].first;
|
||||
coverage = c->rangeRecord[i].value;
|
||||
if (unlikely (coverage != old + 1))
|
||||
{
|
||||
/* Broken table. Skip. Important to avoid DoS.
|
||||
* Also, our callers depend on coverage being
|
||||
* consecutive and monotonically increasing,
|
||||
* ie. iota(). */
|
||||
i = c->rangeRecord.len;
|
||||
j = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
j = 0;
|
||||
return;
|
||||
}
|
||||
coverage++;
|
||||
j++;
|
||||
}
|
||||
hb_codepoint_t get_glyph () const { return j; }
|
||||
bool operator != (const iter_t& o) const
|
||||
{ return i != o.i || j != o.j; }
|
||||
iter_t __end__ () const
|
||||
{
|
||||
iter_t it;
|
||||
it.init (*c);
|
||||
it.i = c->rangeRecord.len;
|
||||
it.j = 0;
|
||||
return it;
|
||||
}
|
||||
|
||||
private:
|
||||
const struct CoverageFormat2_4 *c;
|
||||
unsigned int i, coverage;
|
||||
hb_codepoint_t j;
|
||||
};
|
||||
private:
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
|
|
@ -1,85 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2010,2012 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod, Garret Rieger
|
||||
*/
|
||||
|
||||
#ifndef OT_LAYOUT_COMMON_RANGERECORD_HH
|
||||
#define OT_LAYOUT_COMMON_RANGERECORD_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace Common {
|
||||
|
||||
template <typename Types>
|
||||
struct RangeRecord
|
||||
{
|
||||
typename Types::HBGlyphID first; /* First GlyphID in the range */
|
||||
typename Types::HBGlyphID last; /* Last GlyphID in the range */
|
||||
HBUINT16 value; /* Value */
|
||||
|
||||
DEFINE_SIZE_STATIC (2 + 2 * Types::size);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
int cmp (hb_codepoint_t g) const
|
||||
{ return g < first ? -1 : g <= last ? 0 : +1; }
|
||||
|
||||
unsigned get_population () const
|
||||
{
|
||||
if (unlikely (last < first)) return 0;
|
||||
return (last - first + 1);
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t &glyphs) const
|
||||
{ return glyphs.intersects (first, last); }
|
||||
|
||||
template <typename set_t>
|
||||
bool collect_coverage (set_t *glyphs) const
|
||||
{ return glyphs->add_range (first, last); }
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(garretrieger): This was previously implemented using
|
||||
// DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (OT, RangeRecord, 9);
|
||||
// but that only works when there is only a single namespace level.
|
||||
// The macro should probably be fixed so it can work in this situation.
|
||||
extern HB_INTERNAL const unsigned char _hb_Null_OT_RangeRecord[9];
|
||||
template <typename Spec>
|
||||
struct Null<OT::Layout::Common::RangeRecord<Spec>> {
|
||||
static OT::Layout::Common::RangeRecord<Spec> const & get_null () {
|
||||
return *reinterpret_cast<const OT::Layout::Common::RangeRecord<Spec> *> (_hb_Null_OT_RangeRecord);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef OT_LAYOUT_COMMON_RANGERECORD_HH
|
|
@ -1,918 +0,0 @@
|
|||
/*
|
||||
* Copyright © 2007,2008,2009 Red Hat, Inc.
|
||||
* Copyright © 2010,2011,2012 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef OT_LAYOUT_GDEF_GDEF_HH
|
||||
#define OT_LAYOUT_GDEF_GDEF_HH
|
||||
|
||||
#include "../../../hb-ot-layout-common.hh"
|
||||
|
||||
#include "../../../hb-font.hh"
|
||||
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* Attachment List Table
|
||||
*/
|
||||
|
||||
/* Array of contour point indices--in increasing numerical order */
|
||||
struct AttachPoint : Array16Of<HBUINT16>
|
||||
{
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
return_trace (out->serialize (c->serializer, + iter ()));
|
||||
}
|
||||
};
|
||||
|
||||
struct AttachList
|
||||
{
|
||||
unsigned int get_attach_points (hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (glyph_id);
|
||||
if (index == NOT_COVERED)
|
||||
{
|
||||
if (point_count)
|
||||
*point_count = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const AttachPoint &points = this+attachPoint[index];
|
||||
|
||||
if (point_count)
|
||||
{
|
||||
+ points.as_array ().sub_array (start_offset, point_count)
|
||||
| hb_sink (hb_array (point_array, *point_count))
|
||||
;
|
||||
}
|
||||
|
||||
return points.len;
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
|
||||
+ hb_zip (this+coverage, attachPoint)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_filter (subset_offset_array (c, out->attachPoint, this), hb_second)
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
|
||||
return_trace (bool (new_coverage));
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
Offset16To<Coverage>
|
||||
coverage; /* Offset to Coverage table -- from
|
||||
* beginning of AttachList table */
|
||||
Array16OfOffset16To<AttachPoint>
|
||||
attachPoint; /* Array of AttachPoint tables
|
||||
* in Coverage Index order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, attachPoint);
|
||||
};
|
||||
|
||||
/*
|
||||
* Ligature Caret Table
|
||||
*/
|
||||
|
||||
struct CaretValueFormat1
|
||||
{
|
||||
friend struct CaretValue;
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
private:
|
||||
hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
|
||||
{
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 caretValueFormat; /* Format identifier--format = 1 */
|
||||
FWORD coordinate; /* X or Y value, in design units */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct CaretValueFormat2
|
||||
{
|
||||
friend struct CaretValue;
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
private:
|
||||
hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
|
||||
{
|
||||
hb_position_t x, y;
|
||||
font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y);
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 caretValueFormat; /* Format identifier--format = 2 */
|
||||
HBUINT16 caretValuePoint; /* Contour point index on glyph */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
struct CaretValueFormat3
|
||||
{
|
||||
friend struct CaretValue;
|
||||
|
||||
hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction,
|
||||
const VariationStore &var_store) const
|
||||
{
|
||||
return HB_DIRECTION_IS_HORIZONTAL (direction) ?
|
||||
font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
|
||||
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
if (!c->serializer->embed (caretValueFormat)) return_trace (false);
|
||||
if (!c->serializer->embed (coordinate)) return_trace (false);
|
||||
|
||||
unsigned varidx = (this+deviceTable).get_variation_index ();
|
||||
if (c->plan->layout_variation_idx_delta_map.has (varidx))
|
||||
{
|
||||
int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (varidx));
|
||||
if (delta != 0)
|
||||
{
|
||||
if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||
return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
if (c->plan->all_axes_pinned)
|
||||
return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||
|
||||
if (!c->serializer->embed (deviceTable))
|
||||
return_trace (false);
|
||||
|
||||
return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this, c->serializer->to_bias (out),
|
||||
hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map));
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{ (this+deviceTable).collect_variation_indices (c); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 caretValueFormat; /* Format identifier--format = 3 */
|
||||
FWORD coordinate; /* X or Y value, in design units */
|
||||
Offset16To<Device>
|
||||
deviceTable; /* Offset to Device table for X or Y
|
||||
* value--from beginning of CaretValue
|
||||
* table */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
struct CaretValue
|
||||
{
|
||||
hb_position_t get_caret_value (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
const VariationStore &var_store) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.get_caret_value (font, direction);
|
||||
case 2: return u.format2.get_caret_value (font, direction, glyph_id);
|
||||
case 3: return u.format3.get_caret_value (font, direction, var_store);
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename context_t, typename ...Ts>
|
||||
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
|
||||
{
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||
case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1:
|
||||
case 2:
|
||||
return;
|
||||
case 3:
|
||||
u.format3.collect_variation_indices (c);
|
||||
return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return_trace (false);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (u.format1.sanitize (c));
|
||||
case 2: return_trace (u.format2.sanitize (c));
|
||||
case 3: return_trace (u.format3.sanitize (c));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
CaretValueFormat1 format1;
|
||||
CaretValueFormat2 format2;
|
||||
CaretValueFormat3 format3;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
struct LigGlyph
|
||||
{
|
||||
unsigned get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
const VariationStore &var_store,
|
||||
unsigned start_offset,
|
||||
unsigned *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{
|
||||
if (caret_count)
|
||||
{
|
||||
+ carets.as_array ().sub_array (start_offset, caret_count)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); })
|
||||
| hb_sink (hb_array (caret_array, *caret_count))
|
||||
;
|
||||
}
|
||||
|
||||
return carets.len;
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
+ hb_iter (carets)
|
||||
| hb_apply (subset_offset_array (c, out->carets, this))
|
||||
;
|
||||
|
||||
return_trace (bool (out->carets));
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
for (const Offset16To<CaretValue>& offset : carets.iter ())
|
||||
(this+offset).collect_variation_indices (c);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (carets.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
Array16OfOffset16To<CaretValue>
|
||||
carets; /* Offset array of CaretValue tables
|
||||
* --from beginning of LigGlyph table
|
||||
* --in increasing coordinate order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, carets);
|
||||
};
|
||||
|
||||
struct LigCaretList
|
||||
{
|
||||
unsigned int get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
const VariationStore &var_store,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (glyph_id);
|
||||
if (index == NOT_COVERED)
|
||||
{
|
||||
if (caret_count)
|
||||
*caret_count = 0;
|
||||
return 0;
|
||||
}
|
||||
const LigGlyph &lig_glyph = this+ligGlyph[index];
|
||||
return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
|
||||
+ hb_zip (this+coverage, ligGlyph)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second)
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
|
||||
return_trace (bool (new_coverage));
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
+ hb_zip (this+coverage, ligGlyph)
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_apply ([c] (const LigGlyph& _) { _.collect_variation_indices (c); })
|
||||
;
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
Offset16To<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of LigCaretList table */
|
||||
Array16OfOffset16To<LigGlyph>
|
||||
ligGlyph; /* Array of LigGlyph tables
|
||||
* in Coverage Index order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, ligGlyph);
|
||||
};
|
||||
|
||||
|
||||
struct MarkGlyphSetsFormat1
|
||||
{
|
||||
bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{ return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
out->format = format;
|
||||
|
||||
bool ret = true;
|
||||
for (const Offset32To<Coverage>& offset : coverage.iter ())
|
||||
{
|
||||
auto *o = out->coverage.serialize_append (c->serializer);
|
||||
if (unlikely (!o))
|
||||
{
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
|
||||
//not using o->serialize_subset (c, offset, this, out) here because
|
||||
//OTS doesn't allow null offset.
|
||||
//See issue: https://github.com/khaledhosny/ots/issues/172
|
||||
c->serializer->push ();
|
||||
c->dispatch (this+offset);
|
||||
c->serializer->add_link (*o, c->serializer->pop_pack ());
|
||||
}
|
||||
|
||||
return_trace (ret && out->coverage.len);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (coverage.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
Array16Of<Offset32To<Coverage>>
|
||||
coverage; /* Array of long offsets to mark set
|
||||
* coverage tables */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, coverage);
|
||||
};
|
||||
|
||||
struct MarkGlyphSets
|
||||
{
|
||||
bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: return u.format1.covers (set_index, glyph_id);
|
||||
default:return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (u.format1.subset (c));
|
||||
default:return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return_trace (false);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (u.format1.sanitize (c));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
MarkGlyphSetsFormat1 format1;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* GDEF -- Glyph Definition
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/gdef
|
||||
*/
|
||||
|
||||
|
||||
template <typename Types>
|
||||
struct GDEFVersion1_2
|
||||
{
|
||||
friend struct GDEF;
|
||||
|
||||
protected:
|
||||
FixedVersion<>version; /* Version of the GDEF table--currently
|
||||
* 0x00010003u */
|
||||
typename Types::template OffsetTo<ClassDef>
|
||||
glyphClassDef; /* Offset to class definition table
|
||||
* for glyph type--from beginning of
|
||||
* GDEF header (may be Null) */
|
||||
typename Types::template OffsetTo<AttachList>
|
||||
attachList; /* Offset to list of glyphs with
|
||||
* attachment points--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
typename Types::template OffsetTo<LigCaretList>
|
||||
ligCaretList; /* Offset to list of positioning points
|
||||
* for ligature carets--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
typename Types::template OffsetTo<ClassDef>
|
||||
markAttachClassDef; /* Offset to class definition table for
|
||||
* mark attachment type--from beginning
|
||||
* of GDEF header (may be Null) */
|
||||
typename Types::template OffsetTo<MarkGlyphSets>
|
||||
markGlyphSetsDef; /* Offset to the table of mark set
|
||||
* definitions--from beginning of GDEF
|
||||
* header (may be NULL). Introduced
|
||||
* in version 0x00010002. */
|
||||
Offset32To<VariationStore>
|
||||
varStore; /* Offset to the table of Item Variation
|
||||
* Store--from beginning of GDEF
|
||||
* header (may be NULL). Introduced
|
||||
* in version 0x00010003. */
|
||||
public:
|
||||
DEFINE_SIZE_MIN (4 + 4 * Types::size);
|
||||
|
||||
unsigned int get_size () const
|
||||
{
|
||||
return min_size +
|
||||
(version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) +
|
||||
(version.to_int () >= 0x00010003u ? varStore.static_size : 0);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (version.sanitize (c) &&
|
||||
glyphClassDef.sanitize (c, this) &&
|
||||
attachList.sanitize (c, this) &&
|
||||
ligCaretList.sanitize (c, this) &&
|
||||
markAttachClassDef.sanitize (c, this) &&
|
||||
(version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
|
||||
(version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true);
|
||||
bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this);
|
||||
bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this);
|
||||
bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true);
|
||||
|
||||
bool subset_markglyphsetsdef = false;
|
||||
if (version.to_int () >= 0x00010002u)
|
||||
{
|
||||
subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this);
|
||||
}
|
||||
|
||||
bool subset_varstore = false;
|
||||
if (version.to_int () >= 0x00010003u)
|
||||
{
|
||||
if (c->plan->all_axes_pinned)
|
||||
out->varStore = 0;
|
||||
else
|
||||
subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
|
||||
}
|
||||
|
||||
if (subset_varstore)
|
||||
{
|
||||
out->version.minor = 3;
|
||||
} else if (subset_markglyphsetsdef) {
|
||||
out->version.minor = 2;
|
||||
} else {
|
||||
out->version.minor = 0;
|
||||
}
|
||||
|
||||
return_trace (subset_glyphclassdef || subset_attachlist ||
|
||||
subset_ligcaretlist || subset_markattachclassdef ||
|
||||
(out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) ||
|
||||
(out->version.to_int () >= 0x00010003u && subset_varstore));
|
||||
}
|
||||
};
|
||||
|
||||
struct GDEF
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF;
|
||||
|
||||
enum GlyphClasses {
|
||||
UnclassifiedGlyph = 0,
|
||||
BaseGlyph = 1,
|
||||
LigatureGlyph = 2,
|
||||
MarkGlyph = 3,
|
||||
ComponentGlyph = 4
|
||||
};
|
||||
|
||||
unsigned int get_size () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version1.get_size ();
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return u.version2.get_size ();
|
||||
#endif
|
||||
default: return u.version.static_size;
|
||||
}
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!u.version.sanitize (c))) return_trace (false);
|
||||
switch (u.version.major) {
|
||||
case 1: return_trace (u.version1.sanitize (c));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return_trace (u.version2.sanitize (c));
|
||||
#endif
|
||||
default: return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version1.subset (c);
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return u.version2.subset (c);
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool has_glyph_classes () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version1.glyphClassDef != 0;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return u.version2.glyphClassDef != 0;
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
const ClassDef &get_glyph_class_def () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return this+u.version1.glyphClassDef;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return this+u.version2.glyphClassDef;
|
||||
#endif
|
||||
default: return Null(ClassDef);
|
||||
}
|
||||
}
|
||||
bool has_attach_list () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version1.attachList != 0;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return u.version2.attachList != 0;
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
const AttachList &get_attach_list () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return this+u.version1.attachList;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return this+u.version2.attachList;
|
||||
#endif
|
||||
default: return Null(AttachList);
|
||||
}
|
||||
}
|
||||
bool has_lig_carets () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version1.ligCaretList != 0;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return u.version2.ligCaretList != 0;
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
const LigCaretList &get_lig_caret_list () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return this+u.version1.ligCaretList;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return this+u.version2.ligCaretList;
|
||||
#endif
|
||||
default: return Null(LigCaretList);
|
||||
}
|
||||
}
|
||||
bool has_mark_attachment_types () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version1.markAttachClassDef != 0;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return u.version2.markAttachClassDef != 0;
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
const ClassDef &get_mark_attach_class_def () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return this+u.version1.markAttachClassDef;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return this+u.version2.markAttachClassDef;
|
||||
#endif
|
||||
default: return Null(ClassDef);
|
||||
}
|
||||
}
|
||||
bool has_mark_glyph_sets () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return u.version2.markGlyphSetsDef != 0;
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
const MarkGlyphSets &get_mark_glyph_sets () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets);
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return this+u.version2.markGlyphSetsDef;
|
||||
#endif
|
||||
default: return Null(MarkGlyphSets);
|
||||
}
|
||||
}
|
||||
bool has_var_store () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return u.version2.varStore != 0;
|
||||
#endif
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
const VariationStore &get_var_store () const
|
||||
{
|
||||
switch (u.version.major) {
|
||||
case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(VariationStore);
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return this+u.version2.varStore;
|
||||
#endif
|
||||
default: return Null(VariationStore);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool has_data () const { return u.version.to_int (); }
|
||||
unsigned int get_glyph_class (hb_codepoint_t glyph) const
|
||||
{ return get_glyph_class_def ().get_class (glyph); }
|
||||
void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
|
||||
{ get_glyph_class_def ().collect_class (glyphs, klass); }
|
||||
|
||||
unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
|
||||
{ return get_mark_attach_class_def ().get_class (glyph); }
|
||||
|
||||
unsigned int get_attach_points (hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *point_count /* IN/OUT */,
|
||||
unsigned int *point_array /* OUT */) const
|
||||
{ return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); }
|
||||
|
||||
unsigned int get_lig_carets (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t glyph_id,
|
||||
unsigned int start_offset,
|
||||
unsigned int *caret_count /* IN/OUT */,
|
||||
hb_position_t *caret_array /* OUT */) const
|
||||
{ return get_lig_caret_list ().get_lig_carets (font,
|
||||
direction, glyph_id, get_var_store(),
|
||||
start_offset, caret_count, caret_array); }
|
||||
|
||||
bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
|
||||
{ return get_mark_glyph_sets ().covers (set_index, glyph_id); }
|
||||
|
||||
/* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
|
||||
* glyph class and other bits, and high 8-bit the mark attachment type (if any).
|
||||
* Not to be confused with lookup_props which is very similar. */
|
||||
unsigned int get_glyph_props (hb_codepoint_t glyph) const
|
||||
{
|
||||
unsigned int klass = get_glyph_class (glyph);
|
||||
|
||||
static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs), "");
|
||||
static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures), "");
|
||||
static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), "");
|
||||
|
||||
switch (klass) {
|
||||
default: return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
|
||||
case BaseGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
|
||||
case LigatureGlyph: return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
|
||||
case MarkGlyph:
|
||||
klass = get_mark_attachment_type (glyph);
|
||||
return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
|
||||
}
|
||||
}
|
||||
|
||||
HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
|
||||
hb_face_t *face) const;
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
accelerator_t (hb_face_t *face)
|
||||
{
|
||||
table = hb_sanitize_context_t ().reference_table<GDEF> (face);
|
||||
if (unlikely (table->is_blocklisted (table.get_blob (), face)))
|
||||
{
|
||||
hb_blob_destroy (table.get_blob ());
|
||||
table = hb_blob_get_empty ();
|
||||
}
|
||||
}
|
||||
~accelerator_t () { table.destroy (); }
|
||||
|
||||
hb_blob_ptr_t<GDEF> table;
|
||||
};
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{ get_lig_caret_list ().collect_variation_indices (c); }
|
||||
|
||||
void remap_layout_variation_indices (const hb_set_t *layout_variation_indices,
|
||||
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map /* OUT */) const
|
||||
{
|
||||
if (!has_var_store ()) return;
|
||||
if (layout_variation_indices->is_empty ()) return;
|
||||
|
||||
unsigned new_major = 0, new_minor = 0;
|
||||
unsigned last_major = (layout_variation_indices->get_min ()) >> 16;
|
||||
for (unsigned idx : layout_variation_indices->iter ())
|
||||
{
|
||||
uint16_t major = idx >> 16;
|
||||
if (major >= get_var_store ().get_sub_table_count ()) break;
|
||||
if (major != last_major)
|
||||
{
|
||||
new_minor = 0;
|
||||
++new_major;
|
||||
}
|
||||
|
||||
unsigned new_idx = (new_major << 16) + new_minor;
|
||||
if (!layout_variation_idx_delta_map->has (idx))
|
||||
continue;
|
||||
int delta = hb_second (layout_variation_idx_delta_map->get (idx));
|
||||
|
||||
layout_variation_idx_delta_map->set (idx, hb_pair_t<unsigned, int> (new_idx, delta));
|
||||
++new_minor;
|
||||
last_major = major;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
FixedVersion<> version; /* Version identifier */
|
||||
GDEFVersion1_2<SmallTypes> version1;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
GDEFVersion1_2<MediumTypes> version2;
|
||||
#endif
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_MIN (4);
|
||||
};
|
||||
|
||||
struct GDEF_accelerator_t : GDEF::accelerator_t {
|
||||
GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* OT_LAYOUT_GDEF_GDEF_HH */
|
|
@ -1,83 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_ANCHOR_HH
|
||||
#define OT_LAYOUT_GPOS_ANCHOR_HH
|
||||
|
||||
#include "AnchorFormat1.hh"
|
||||
#include "AnchorFormat2.hh"
|
||||
#include "AnchorFormat3.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct Anchor
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
AnchorFormat1 format1;
|
||||
AnchorFormat2 format2;
|
||||
AnchorFormat3 format3;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, format);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.format.sanitize (c)) return_trace (false);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (u.format1.sanitize (c));
|
||||
case 2: return_trace (u.format2.sanitize (c));
|
||||
case 3: return_trace (u.format3.sanitize (c));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
|
||||
float *x, float *y) const
|
||||
{
|
||||
*x = *y = 0;
|
||||
switch (u.format) {
|
||||
case 1: u.format1.get_anchor (c, glyph_id, x, y); return;
|
||||
case 2: u.format2.get_anchor (c, glyph_id, x, y); return;
|
||||
case 3: u.format3.get_anchor (c, glyph_id, x, y); return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
|
||||
case 2:
|
||||
if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
||||
{
|
||||
// AnchorFormat 2 just containins extra hinting information, so
|
||||
// if hints are being dropped convert to format 1.
|
||||
return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
|
||||
}
|
||||
return_trace (bool (reinterpret_cast<Anchor *> (u.format2.copy (c->serializer))));
|
||||
case 3: return_trace (u.format3.subset (c));
|
||||
default:return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
switch (u.format) {
|
||||
case 1: case 2:
|
||||
return;
|
||||
case 3:
|
||||
u.format3.collect_variation_indices (c);
|
||||
return;
|
||||
default: return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_ANCHOR_HH
|
|
@ -1,46 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
|
||||
#define OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct AnchorFormat1
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||
FWORD yCoordinate; /* Vertical value--in design units */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
|
||||
float *x, float *y) const
|
||||
{
|
||||
hb_font_t *font = c->font;
|
||||
*x = font->em_fscale_x (xCoordinate);
|
||||
*y = font->em_fscale_y (yCoordinate);
|
||||
}
|
||||
|
||||
AnchorFormat1* copy (hb_serialize_context_t *c) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
AnchorFormat1* out = c->embed<AnchorFormat1> (this);
|
||||
if (!out) return_trace (out);
|
||||
out->format = 1;
|
||||
return_trace (out);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
|
|
@ -1,58 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
|
||||
#define OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct AnchorFormat2
|
||||
{
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 2 */
|
||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||
FWORD yCoordinate; /* Vertical value--in design units */
|
||||
HBUINT16 anchorPoint; /* Index to glyph contour point */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
|
||||
float *x, float *y) const
|
||||
{
|
||||
hb_font_t *font = c->font;
|
||||
|
||||
#ifdef HB_NO_HINTING
|
||||
*x = font->em_fscale_x (xCoordinate);
|
||||
*y = font->em_fscale_y (yCoordinate);
|
||||
return;
|
||||
#endif
|
||||
|
||||
unsigned int x_ppem = font->x_ppem;
|
||||
unsigned int y_ppem = font->y_ppem;
|
||||
hb_position_t cx = 0, cy = 0;
|
||||
bool ret;
|
||||
|
||||
ret = (x_ppem || y_ppem) &&
|
||||
font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
|
||||
*x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate);
|
||||
*y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate);
|
||||
}
|
||||
|
||||
AnchorFormat2* copy (hb_serialize_context_t *c) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
return_trace (c->embed<AnchorFormat2> (this));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
|
|
@ -1,100 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
|
||||
#define OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct AnchorFormat3
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 3 */
|
||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||
FWORD yCoordinate; /* Vertical value--in design units */
|
||||
Offset16To<Device>
|
||||
xDeviceTable; /* Offset to Device table for X
|
||||
* coordinate-- from beginning of
|
||||
* Anchor table (may be NULL) */
|
||||
Offset16To<Device>
|
||||
yDeviceTable; /* Offset to Device table for Y
|
||||
* coordinate-- from beginning of
|
||||
* Anchor table (may be NULL) */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
|
||||
}
|
||||
|
||||
void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
|
||||
float *x, float *y) const
|
||||
{
|
||||
hb_font_t *font = c->font;
|
||||
*x = font->em_fscale_x (xCoordinate);
|
||||
*y = font->em_fscale_y (yCoordinate);
|
||||
|
||||
if (font->x_ppem || font->num_coords)
|
||||
*x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache);
|
||||
if (font->y_ppem || font->num_coords)
|
||||
*y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
if (unlikely (!c->serializer->embed (format))) return_trace (false);
|
||||
if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false);
|
||||
if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false);
|
||||
|
||||
unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
|
||||
if (c->plan->layout_variation_idx_delta_map.has (x_varidx))
|
||||
{
|
||||
int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (x_varidx));
|
||||
if (delta != 0)
|
||||
{
|
||||
if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
|
||||
HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||
return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
|
||||
if (c->plan->layout_variation_idx_delta_map.has (y_varidx))
|
||||
{
|
||||
int delta = hb_second (c->plan->layout_variation_idx_delta_map.get (y_varidx));
|
||||
if (delta != 0)
|
||||
{
|
||||
if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
|
||||
HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||
return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
if (c->plan->all_axes_pinned)
|
||||
return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||
|
||||
if (!c->serializer->embed (xDeviceTable)) return_trace (false);
|
||||
if (!c->serializer->embed (yDeviceTable)) return_trace (false);
|
||||
|
||||
out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
|
||||
out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
|
||||
return_trace (out);
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
(this+xDeviceTable).collect_variation_indices (c);
|
||||
(this+yDeviceTable).collect_variation_indices (c);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
|
|
@ -1,77 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_ANCHORMATRIX_HH
|
||||
#define OT_LAYOUT_GPOS_ANCHORMATRIX_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct AnchorMatrix
|
||||
{
|
||||
HBUINT16 rows; /* Number of rows */
|
||||
UnsizedArrayOf<Offset16To<Anchor>>
|
||||
matrixZ; /* Matrix of offsets to Anchor tables--
|
||||
* from beginning of AnchorMatrix table */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, matrixZ);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!c->check_struct (this)) return_trace (false);
|
||||
if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
|
||||
unsigned int count = rows * cols;
|
||||
if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!matrixZ[i].sanitize (c, this)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
const Anchor& get_anchor (unsigned int row, unsigned int col,
|
||||
unsigned int cols, bool *found) const
|
||||
{
|
||||
*found = false;
|
||||
if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
|
||||
*found = !matrixZ[row * cols + col].is_null ();
|
||||
return this+matrixZ[row * cols + col];
|
||||
}
|
||||
|
||||
template <typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
||||
Iterator index_iter) const
|
||||
{
|
||||
for (unsigned i : index_iter)
|
||||
(this+matrixZ[i]).collect_variation_indices (c);
|
||||
}
|
||||
|
||||
template <typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
bool subset (hb_subset_context_t *c,
|
||||
unsigned num_rows,
|
||||
Iterator index_iter) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
|
||||
auto *out = c->serializer->start_embed (this);
|
||||
|
||||
if (!index_iter) return_trace (false);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
out->rows = num_rows;
|
||||
for (const unsigned i : index_iter)
|
||||
{
|
||||
auto *offset = c->serializer->embed (matrixZ[i]);
|
||||
if (!offset) return_trace (false);
|
||||
offset->serialize_subset (c, matrixZ[i], this);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH
|
||||
#define OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct ChainContextPos : ChainContext {};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH */
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_COMMON_HH
|
||||
#define OT_LAYOUT_GPOS_COMMON_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
enum attach_type_t {
|
||||
ATTACH_TYPE_NONE = 0X00,
|
||||
|
||||
/* Each attachment should be either a mark or a cursive; can't be both. */
|
||||
ATTACH_TYPE_MARK = 0X01,
|
||||
ATTACH_TYPE_CURSIVE = 0X02,
|
||||
};
|
||||
|
||||
/* buffer **position** var allocations */
|
||||
#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */
|
||||
#define attach_type() var.u8[2] /* attachment type */
|
||||
/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */
|
||||
|
||||
template<typename Iterator, typename SrcLookup>
|
||||
static void SinglePos_serialize (hb_serialize_context_t *c,
|
||||
const SrcLookup *src,
|
||||
Iterator it,
|
||||
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
|
||||
bool all_axes_pinned);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_COMMON_HH
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_CONTEXTPOS_HH
|
||||
#define OT_LAYOUT_GPOS_CONTEXTPOS_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct ContextPos : Context {};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_CONTEXTPOS_HH */
|
|
@ -1,35 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_CURSIVEPOS_HH
|
||||
#define OT_LAYOUT_GPOS_CURSIVEPOS_HH
|
||||
|
||||
#include "CursivePosFormat1.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct CursivePos
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
CursivePosFormat1 format1;
|
||||
} u;
|
||||
|
||||
public:
|
||||
template <typename context_t, typename ...Ts>
|
||||
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
|
||||
{
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_CURSIVEPOS_HH */
|
|
@ -1,301 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH
|
||||
#define OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH
|
||||
|
||||
#include "Anchor.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct EntryExitRecord
|
||||
{
|
||||
friend struct CursivePosFormat1;
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
||||
const void *src_base) const
|
||||
{
|
||||
(src_base+entryAnchor).collect_variation_indices (c);
|
||||
(src_base+exitAnchor).collect_variation_indices (c);
|
||||
}
|
||||
|
||||
EntryExitRecord* subset (hb_subset_context_t *c,
|
||||
const void *src_base) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto *out = c->serializer->embed (this);
|
||||
if (unlikely (!out)) return_trace (nullptr);
|
||||
|
||||
out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
|
||||
out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
|
||||
return_trace (out);
|
||||
}
|
||||
|
||||
protected:
|
||||
Offset16To<Anchor>
|
||||
entryAnchor; /* Offset to EntryAnchor table--from
|
||||
* beginning of CursivePos
|
||||
* subtable--may be NULL */
|
||||
Offset16To<Anchor>
|
||||
exitAnchor; /* Offset to ExitAnchor table--from
|
||||
* beginning of CursivePos
|
||||
* subtable--may be NULL */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
||||
static void
|
||||
reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) {
|
||||
int chain = pos[i].attach_chain(), type = pos[i].attach_type();
|
||||
if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE)))
|
||||
return;
|
||||
|
||||
pos[i].attach_chain() = 0;
|
||||
|
||||
unsigned int j = (int) i + chain;
|
||||
|
||||
/* Stop if we see new parent in the chain. */
|
||||
if (j == new_parent)
|
||||
return;
|
||||
|
||||
reverse_cursive_minor_offset (pos, j, direction, new_parent);
|
||||
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (direction))
|
||||
pos[j].y_offset = -pos[i].y_offset;
|
||||
else
|
||||
pos[j].x_offset = -pos[i].x_offset;
|
||||
|
||||
pos[j].attach_chain() = -chain;
|
||||
pos[j].attach_type() = type;
|
||||
}
|
||||
|
||||
|
||||
struct CursivePosFormat1
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
Offset16To<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of subtable */
|
||||
Array16Of<EntryExitRecord>
|
||||
entryExitRecord; /* Array of EntryExit records--in
|
||||
* Coverage Index order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, entryExitRecord);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (coverage.sanitize (c, this) && entryExitRecord.sanitize (c, this));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{ return (this+coverage).intersects (glyphs); }
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
+ hb_zip (this+coverage, entryExitRecord)
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_apply ([&] (const EntryExitRecord& record) { record.collect_variation_indices (c, this); })
|
||||
;
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{ if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
|
||||
|
||||
const Coverage &get_coverage () const { return this+coverage; }
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
|
||||
const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
|
||||
if (!this_record.entryAnchor) return_trace (false);
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
unsigned unsafe_from;
|
||||
if (!skippy_iter.prev (&unsafe_from))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
|
||||
if (!prev_record.exitAnchor)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned int i = skippy_iter.idx;
|
||||
unsigned int j = buffer->idx;
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"cursive attaching glyph at %u to glyph at %u",
|
||||
i, j);
|
||||
}
|
||||
|
||||
buffer->unsafe_to_break (i, j + 1);
|
||||
float entry_x, entry_y, exit_x, exit_y;
|
||||
(this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
|
||||
(this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
|
||||
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
|
||||
hb_position_t d;
|
||||
/* Main-direction adjustment */
|
||||
switch (c->direction) {
|
||||
case HB_DIRECTION_LTR:
|
||||
pos[i].x_advance = roundf (exit_x) + pos[i].x_offset;
|
||||
|
||||
d = roundf (entry_x) + pos[j].x_offset;
|
||||
pos[j].x_advance -= d;
|
||||
pos[j].x_offset -= d;
|
||||
break;
|
||||
case HB_DIRECTION_RTL:
|
||||
d = roundf (exit_x) + pos[i].x_offset;
|
||||
pos[i].x_advance -= d;
|
||||
pos[i].x_offset -= d;
|
||||
|
||||
pos[j].x_advance = roundf (entry_x) + pos[j].x_offset;
|
||||
break;
|
||||
case HB_DIRECTION_TTB:
|
||||
pos[i].y_advance = roundf (exit_y) + pos[i].y_offset;
|
||||
|
||||
d = roundf (entry_y) + pos[j].y_offset;
|
||||
pos[j].y_advance -= d;
|
||||
pos[j].y_offset -= d;
|
||||
break;
|
||||
case HB_DIRECTION_BTT:
|
||||
d = roundf (exit_y) + pos[i].y_offset;
|
||||
pos[i].y_advance -= d;
|
||||
pos[i].y_offset -= d;
|
||||
|
||||
pos[j].y_advance = roundf (entry_y);
|
||||
break;
|
||||
case HB_DIRECTION_INVALID:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Cross-direction adjustment */
|
||||
|
||||
/* We attach child to parent (think graph theory and rooted trees whereas
|
||||
* the root stays on baseline and each node aligns itself against its
|
||||
* parent.
|
||||
*
|
||||
* Optimize things for the case of RightToLeft, as that's most common in
|
||||
* Arabic. */
|
||||
unsigned int child = i;
|
||||
unsigned int parent = j;
|
||||
hb_position_t x_offset = entry_x - exit_x;
|
||||
hb_position_t y_offset = entry_y - exit_y;
|
||||
if (!(c->lookup_props & LookupFlag::RightToLeft))
|
||||
{
|
||||
unsigned int k = child;
|
||||
child = parent;
|
||||
parent = k;
|
||||
x_offset = -x_offset;
|
||||
y_offset = -y_offset;
|
||||
}
|
||||
|
||||
/* If child was already connected to someone else, walk through its old
|
||||
* chain and reverse the link direction, such that the whole tree of its
|
||||
* previous connection now attaches to new parent. Watch out for case
|
||||
* where new parent is on the path from old chain...
|
||||
*/
|
||||
reverse_cursive_minor_offset (pos, child, c->direction, parent);
|
||||
|
||||
pos[child].attach_type() = ATTACH_TYPE_CURSIVE;
|
||||
pos[child].attach_chain() = (int) parent - (int) child;
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
|
||||
pos[child].y_offset = y_offset;
|
||||
else
|
||||
pos[child].x_offset = x_offset;
|
||||
|
||||
/* If parent was attached to child, separate them.
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/2469
|
||||
*/
|
||||
if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain()))
|
||||
{
|
||||
pos[parent].attach_chain() = 0;
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
|
||||
pos[parent].y_offset = 0;
|
||||
else
|
||||
pos[parent].x_offset = 0;
|
||||
}
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"cursive attached glyph at %u to glyph at %u",
|
||||
i, j);
|
||||
}
|
||||
|
||||
buffer->idx++;
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
template <typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
void serialize (hb_subset_context_t *c,
|
||||
Iterator it,
|
||||
const void *src_base)
|
||||
{
|
||||
if (unlikely (!c->serializer->extend_min ((*this)))) return;
|
||||
this->format = 1;
|
||||
this->entryExitRecord.len = it.len ();
|
||||
|
||||
for (const EntryExitRecord& entry_record : + it
|
||||
| hb_map (hb_second))
|
||||
entry_record.subset (c, src_base);
|
||||
|
||||
auto glyphs =
|
||||
+ it
|
||||
| hb_map_retains_sorting (hb_first)
|
||||
;
|
||||
|
||||
coverage.serialize_serialize (c->serializer, glyphs);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
|
||||
auto it =
|
||||
+ hb_zip (this+coverage, entryExitRecord)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const EntryExitRecord&> p) -> hb_pair_t<hb_codepoint_t, const EntryExitRecord&>
|
||||
{ return hb_pair (glyph_map[p.first], p.second);})
|
||||
;
|
||||
|
||||
bool ret = bool (it);
|
||||
out->serialize (c, it, this);
|
||||
return_trace (ret);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH */
|
|
@ -1,17 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_EXTENSIONPOS_HH
|
||||
#define OT_LAYOUT_GPOS_EXTENSIONPOS_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct ExtensionPos : Extension<ExtensionPos>
|
||||
{
|
||||
typedef struct PosLookupSubTable SubTable;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_EXTENSIONPOS_HH */
|
|
@ -1,171 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_GPOS_HH
|
||||
#define OT_LAYOUT_GPOS_GPOS_HH
|
||||
|
||||
#include "../../../hb-ot-layout-common.hh"
|
||||
#include "../../../hb-ot-layout-gsubgpos.hh"
|
||||
#include "Common.hh"
|
||||
#include "PosLookup.hh"
|
||||
|
||||
namespace OT {
|
||||
|
||||
using Layout::GPOS_impl::PosLookup;
|
||||
|
||||
namespace Layout {
|
||||
|
||||
static void
|
||||
propagate_attachment_offsets (hb_glyph_position_t *pos,
|
||||
unsigned int len,
|
||||
unsigned int i,
|
||||
hb_direction_t direction,
|
||||
unsigned nesting_level = HB_MAX_NESTING_LEVEL);
|
||||
|
||||
/*
|
||||
* GPOS -- Glyph Positioning
|
||||
* https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
|
||||
*/
|
||||
|
||||
struct GPOS : GSUBGPOS
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS;
|
||||
|
||||
using Lookup = PosLookup;
|
||||
|
||||
const PosLookup& get_lookup (unsigned int i) const
|
||||
{ return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); }
|
||||
|
||||
static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
|
||||
static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
|
||||
static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer);
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
hb_subset_layout_context_t l (c, tableTag);
|
||||
return GSUBGPOS::subset<PosLookup> (&l);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (GSUBGPOS::sanitize<PosLookup> (c));
|
||||
}
|
||||
|
||||
HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
|
||||
hb_face_t *face) const;
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++)
|
||||
{
|
||||
if (!c->gpos_lookups->has (i)) continue;
|
||||
const PosLookup &l = get_lookup (i);
|
||||
l.dispatch (c);
|
||||
}
|
||||
}
|
||||
|
||||
void closure_lookups (hb_face_t *face,
|
||||
const hb_set_t *glyphs,
|
||||
hb_set_t *lookup_indexes /* IN/OUT */) const
|
||||
{ GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); }
|
||||
|
||||
typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t;
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
propagate_attachment_offsets (hb_glyph_position_t *pos,
|
||||
unsigned int len,
|
||||
unsigned int i,
|
||||
hb_direction_t direction,
|
||||
unsigned nesting_level)
|
||||
{
|
||||
/* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
|
||||
* offset of glyph they are attached to. */
|
||||
int chain = pos[i].attach_chain(), type = pos[i].attach_type();
|
||||
if (likely (!chain))
|
||||
return;
|
||||
|
||||
pos[i].attach_chain() = 0;
|
||||
|
||||
unsigned int j = (int) i + chain;
|
||||
|
||||
if (unlikely (j >= len))
|
||||
return;
|
||||
|
||||
if (unlikely (!nesting_level))
|
||||
return;
|
||||
|
||||
propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1);
|
||||
|
||||
assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE));
|
||||
|
||||
if (type & GPOS_impl::ATTACH_TYPE_CURSIVE)
|
||||
{
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (direction))
|
||||
pos[i].y_offset += pos[j].y_offset;
|
||||
else
|
||||
pos[i].x_offset += pos[j].x_offset;
|
||||
}
|
||||
else /*if (type & GPOS_impl::ATTACH_TYPE_MARK)*/
|
||||
{
|
||||
pos[i].x_offset += pos[j].x_offset;
|
||||
pos[i].y_offset += pos[j].y_offset;
|
||||
|
||||
assert (j < i);
|
||||
if (HB_DIRECTION_IS_FORWARD (direction))
|
||||
for (unsigned int k = j; k < i; k++) {
|
||||
pos[i].x_offset -= pos[k].x_advance;
|
||||
pos[i].y_offset -= pos[k].y_advance;
|
||||
}
|
||||
else
|
||||
for (unsigned int k = j + 1; k < i + 1; k++) {
|
||||
pos[i].x_offset += pos[k].x_advance;
|
||||
pos[i].y_offset += pos[k].y_advance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
|
||||
{
|
||||
unsigned int count = buffer->len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0;
|
||||
}
|
||||
|
||||
void
|
||||
GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
|
||||
{
|
||||
//_hb_buffer_assert_gsubgpos_vars (buffer);
|
||||
}
|
||||
|
||||
void
|
||||
GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
|
||||
{
|
||||
_hb_buffer_assert_gsubgpos_vars (buffer);
|
||||
|
||||
unsigned int len;
|
||||
hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
|
||||
hb_direction_t direction = buffer->props.direction;
|
||||
|
||||
/* Handle attachments */
|
||||
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
propagate_attachment_offsets (pos, len, i, direction);
|
||||
|
||||
if (unlikely (font->slant))
|
||||
{
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
if (unlikely (pos[i].y_offset))
|
||||
pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
struct GPOS_accelerator_t : Layout::GPOS::accelerator_t {
|
||||
GPOS_accelerator_t (hb_face_t *face) : Layout::GPOS::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_GPOS_HH */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue