Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
Behdad Esfahbod | 3ce0a9841f | |
Behdad Esfahbod | 204d71514c |
|
@ -2,17 +2,15 @@
|
|||
set -e
|
||||
|
||||
meson --cross-file=.ci/win32-cross-file.txt \
|
||||
--wrap-mode=default \
|
||||
--wrap-mode=forcefallback \
|
||||
-Dtests=disabled \
|
||||
-Dcairo=enabled \
|
||||
-Dcairo:fontconfig=disabled \
|
||||
-Dcairo:freetype=disabled \
|
||||
-Dcairo:dwrite=disabled \
|
||||
-Dcairo:tests=disabled \
|
||||
-Dglib=enabled \
|
||||
-Dfreetype=disabled \
|
||||
-Dfreetype=enabled \
|
||||
-Dgdi=enabled \
|
||||
-Ddirectwrite=enabled \
|
||||
-Dcairo=enabled \
|
||||
win32build \
|
||||
$@
|
||||
|
||||
|
|
|
@ -2,17 +2,15 @@
|
|||
set -e
|
||||
|
||||
meson --cross-file=.ci/win64-cross-file.txt \
|
||||
--wrap-mode=default \
|
||||
--wrap-mode=forcefallback \
|
||||
-Dtests=disabled \
|
||||
-Dcairo=enabled \
|
||||
-Dcairo:fontconfig=disabled \
|
||||
-Dcairo:freetype=disabled \
|
||||
-Dcairo:dwrite=disabled \
|
||||
-Dcairo:tests=disabled \
|
||||
-Dglib=enabled \
|
||||
-Dfreetype=disabled \
|
||||
-Dfreetype=enabled \
|
||||
-Dgdi=enabled \
|
||||
-Ddirectwrite=enabled \
|
||||
-Dcairo=enabled \
|
||||
win64build \
|
||||
$@
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
@ -15,8 +17,8 @@ cp ../build/docs/html/* .
|
|||
|
||||
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"
|
||||
|
|
|
@ -18,9 +18,9 @@ jobs:
|
|||
xcode: "12.5.1"
|
||||
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 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 setup build -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled -Dchafa=disabled -Ddocs=disabled
|
||||
- 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 -Dchafa=disabled
|
||||
- run: meson compile -Cbuild
|
||||
- run: meson test -Cbuild --print-errorlogs
|
||||
- store_artifacts:
|
||||
|
@ -57,8 +57,8 @@ jobs:
|
|||
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))
|
||||
|
||||
|
@ -69,9 +69,24 @@ jobs:
|
|||
- 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 build --buildtype=minsize
|
||||
- run: ninja -Cbuild -j9
|
||||
- run: meson test -Cbuild --print-errorlogs
|
||||
|
||||
archlinux:
|
||||
docker:
|
||||
- image: archlinux/base
|
||||
steps:
|
||||
- checkout
|
||||
- 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
|
||||
- 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
|
||||
|
||||
asan-ubsan:
|
||||
docker:
|
||||
|
@ -81,9 +96,8 @@ jobs:
|
|||
- 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: meson compile -Cbuild -j9
|
||||
- run: meson test -Cbuild --print-errorlogs | asan_symbolize | c++filt
|
||||
- run: CC=clang CXX=clang++ 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:
|
||||
docker:
|
||||
|
@ -93,9 +107,8 @@ jobs:
|
|||
- 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
|
||||
- run: CC=clang CXX=clang++ 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:
|
||||
docker:
|
||||
|
@ -106,9 +119,8 @@ jobs:
|
|||
- 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
|
||||
# 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
|
||||
- run: CC=clang CXX=clang++ 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
|
||||
|
||||
clang-cxx2a:
|
||||
docker:
|
||||
|
@ -117,14 +129,14 @@ jobs:
|
|||
- 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: clang -c src/harfbuzz.cc src/hb-subset*.cc -DHB_NO_MT -Werror -std=c++2a
|
||||
|
||||
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 gtk-doc-tools 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
|
||||
|
@ -146,8 +158,8 @@ jobs:
|
|||
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: sudo apt update && DEBIAN_FRONTEND=noninteractive sudo apt install -y ninja-build gtk-doc-tools python3 python3-pip git g++-mingw-w64-x86-64 zip
|
||||
- run: pip3 install meson==0.56.0 --upgrade
|
||||
- run: bash .ci/build-win64.sh
|
||||
- store_artifacts:
|
||||
path: harfbuzz-win64.zip
|
||||
|
@ -186,6 +198,7 @@ workflows:
|
|||
ignore: /.*/
|
||||
- fedora-valgrind
|
||||
- alpine
|
||||
#- archlinux
|
||||
- asan-ubsan
|
||||
- tsan
|
||||
- msan
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
comment: false
|
||||
comment: off
|
||||
|
||||
coverage:
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
patch:
|
||||
default:
|
||||
informational: true
|
||||
threshold: 1%
|
||||
patch: off
|
||||
|
|
|
@ -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,9 +1,5 @@
|
|||
name: CIFuzz
|
||||
on: [pull_request]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
Fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
|
@ -21,7 +17,7 @@ jobs:
|
|||
fuzz-seconds: 600
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v1
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
|
|
|
@ -11,10 +11,10 @@ permissions:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: sudo apt-get install gcc
|
||||
- name: HB_DISABLE_DEPRECATED
|
||||
|
|
|
@ -11,7 +11,7 @@ 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
|
||||
|
||||
|
|
|
@ -3,7 +3,6 @@ name: linux-ci
|
|||
on:
|
||||
push:
|
||||
branches: [ main ]
|
||||
tags: ["*.*.*"]
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
|
||||
|
@ -12,60 +11,46 @@ permissions:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-20.04
|
||||
runs-on: ubuntu-18.04
|
||||
|
||||
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 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 meson==0.56.0 gcovr==5.0
|
||||
- name: run
|
||||
run: meson build -Db_coverage=true --auto-features=enabled -Dgraphite=enabled -Dchafa=disabled -Dragel_subproject=true -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/main'
|
||||
run: .ci/deploy-docs.sh
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
REVISION: ${{ github.sha }}
|
||||
- name: Generate Coverage
|
||||
|
||||
# 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-xml
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
- uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: build/meson-logs/coverage.xml
|
||||
|
|
|
@ -11,50 +11,20 @@ permissions:
|
|||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: macos-latest
|
||||
runs-on: macos-10.15
|
||||
|
||||
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
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install pkg-config freetype glib cairo icu4c graphite2 gobject-introspection gtk-doc ninja
|
||||
- run: pip3 install fonttools meson==0.56.0 gcovr==5.0
|
||||
- name: run
|
||||
run: PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" meson build -Db_coverage=true -Dcoretext=enabled -Dgraphite=enabled -Dauto_features=enabled -Dchafa=disabled -Doptimization=2
|
||||
- name: ci
|
||||
run: meson test --print-errorlogs -Cbuild
|
||||
- name: Generate Coverage
|
||||
|
||||
- name: cov
|
||||
run: ninja -Cbuild coverage-xml
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
- uses: codecov/codecov-action@v1
|
||||
with:
|
||||
file: build/meson-logs/coverage.xml
|
||||
|
|
|
@ -14,7 +14,6 @@ jobs:
|
|||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-2019, windows-latest]
|
||||
include:
|
||||
|
@ -27,35 +26,33 @@ 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: Upgrade pip
|
||||
run: |
|
||||
python -m pip install -U pip
|
||||
- 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
|
||||
|
|
|
@ -14,7 +14,6 @@ jobs:
|
|||
runs-on: windows-latest
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- MSYSTEM: MINGW32
|
||||
|
@ -23,51 +22,47 @@ 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 \
|
||||
-Dchafa=disabled
|
||||
ninja -C build
|
||||
- name: Test
|
||||
run: |
|
||||
meson test \
|
||||
--print-errorlogs \
|
||||
--suite=harfbuzz \
|
||||
-C build
|
||||
|
|
29
BUILD.md
29
BUILD.md
|
@ -1,29 +1,28 @@
|
|||
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-devel
|
||||
|
||||
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. It is recommended to install CMake either
|
||||
manually or via the Visual Studio installer when building with MSVC when building with meson.
|
||||
|
||||
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.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
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.")
|
||||
|
@ -80,7 +80,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,17 +106,12 @@ 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 ()
|
||||
|
||||
|
@ -213,10 +207,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 +219,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 +239,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 +271,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 +299,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)
|
||||
|
@ -453,7 +426,7 @@ 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)
|
||||
target_link_libraries(harfbuzz PUBLIC freetype)
|
||||
endif ()
|
||||
|
||||
|
||||
|
@ -566,7 +539,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 +693,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 +701,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 +712,11 @@ 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 +745,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 ()
|
||||
|
|
|
@ -100,14 +100,13 @@ 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
|
||||
HarfBuzz from the same thread), you can disable thread-safety by defining
|
||||
|
@ -141,7 +140,7 @@ 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
|
||||
name. HarfBuzz will then include that file at appropriate right place during
|
||||
configuration.
|
||||
|
||||
Up until HarfBuzz 3.1.2 the the configuration override header file's name was
|
||||
|
@ -155,4 +154,4 @@ 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.
|
||||
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.
|
||||
for CFF fonts.
|
||||
|
|
20
COPYING
20
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 © 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,2015 Mozilla Foundation
|
||||
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 © 2005,2006,2020,2021 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,6 +25,7 @@ EXTRA_DIST = \
|
|||
subprojects/google-benchmark.wrap \
|
||||
subprojects/ragel.wrap \
|
||||
subprojects/packagefiles/ragel/meson.build \
|
||||
subprojects/ttf-parser.wrap \
|
||||
mingw-configure.sh \
|
||||
$(NULL)
|
||||
|
||||
|
|
359
NEWS
359
NEWS
|
@ -1,362 +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
|
||||
====================================
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
- [ ] Based on severity of changes, decide whether it's a minor or micro release number bump.
|
||||
|
||||
- [ ] Search for 'XSince: REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'.
|
||||
- [ ] Search for REPLACEME on the repository and replace it with the chosen version for the release.
|
||||
|
||||
- [ ] Make sure you have correct date and new version at the top of NEWS file.
|
||||
|
||||
|
|
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.
|
|
@ -39,7 +39,11 @@ 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
|
||||
|
||||
|
|
12
configure.ac
12
configure.ac
|
@ -1,6 +1,6 @@
|
|||
AC_PREREQ([2.64])
|
||||
AC_INIT([HarfBuzz],
|
||||
[7.1.0],
|
||||
[4.3.0],
|
||||
[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)
|
||||
|
||||
|
@ -308,7 +308,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 +366,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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -219,7 +219,7 @@ notes [fontname="Verdana",shape=box,label=<<table border="0" cellborder="0" cell
|
|||
<b>Indic</b> scripts are: Bengali, Devanagari,
|
||||
Gujarati, Gurmukhi, Kannada,
|
||||
Malayalam, Oriya, Tamil,
|
||||
Telugu
|
||||
Telugu, Sinhala
|
||||
</td></tr>
|
||||
|
||||
<tr><td align="left">
|
||||
|
@ -240,7 +240,7 @@ 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,
|
||||
Saurashtra, Sharada, Siddham, Sogdian, Soyombo, Sundanese,
|
||||
Syloti Nagri, Tagalog, Tagbanwa, Tai Le, Tai Tham, Tai Viet,
|
||||
</td></tr>
|
||||
<tr><td align="left">
|
||||
|
|
|
@ -56,9 +56,7 @@
|
|||
<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,7 +96,6 @@
|
|||
<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">
|
||||
|
@ -118,79 +115,73 @@
|
|||
</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-4-3-0" role="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" role="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" role="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" role="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" role="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" role="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" role="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" role="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" role="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" role="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" role="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" 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-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
|
||||
|
@ -27,33 +26,33 @@ 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 +79,15 @@ 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_set_invisible_glyph
|
||||
hb_buffer_get_not_found_glyph
|
||||
hb_buffer_set_not_found_glyph
|
||||
hb_buffer_set_replacement_codepoint
|
||||
hb_buffer_get_replacement_codepoint
|
||||
hb_buffer_normalize_glyphs
|
||||
|
@ -106,11 +106,9 @@ 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 +119,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 +151,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
|
||||
|
@ -180,35 +178,20 @@ 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_t
|
||||
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_reference
|
||||
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
|
||||
|
@ -219,79 +202,13 @@ 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_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>
|
||||
|
@ -338,6 +255,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 +265,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 +293,118 @@ 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_shape_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_name_func_t
|
||||
hb_font_get_glyph_origin_for_direction
|
||||
hb_font_get_glyph_origin_func_t
|
||||
hb_font_get_glyph_shape
|
||||
hb_font_draw_glyph
|
||||
hb_font_paint_glyph
|
||||
hb_font_get_glyph_shape_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_user_data
|
||||
hb_font_get_variation_glyph
|
||||
hb_font_get_variation_glyph_func_t
|
||||
hb_font_get_var_coords_design
|
||||
hb_font_set_var_coords_normalized
|
||||
hb_font_get_var_coords_normalized
|
||||
hb_font_glyph_from_string
|
||||
hb_font_glyph_to_string
|
||||
hb_font_is_immutable
|
||||
hb_font_make_immutable
|
||||
hb_font_get_serial
|
||||
hb_font_changed
|
||||
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_synthetic_slant
|
||||
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 +421,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 +452,30 @@ 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_copy
|
||||
hb_map_create
|
||||
hb_map_del
|
||||
hb_map_destroy
|
||||
hb_map_get
|
||||
hb_map_get_empty
|
||||
hb_map_get_population
|
||||
hb_map_is_equal
|
||||
hb_map_get_user_data
|
||||
hb_map_has
|
||||
hb_map_hash
|
||||
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 +485,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,21 +504,35 @@ 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_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
|
||||
HB_OT_LAYOUT_NO_VARIATIONS_INDEX
|
||||
HB_OT_TAG_BASE
|
||||
HB_OT_TAG_GDEF
|
||||
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
|
||||
|
@ -631,6 +547,7 @@ 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
|
||||
|
@ -640,14 +557,12 @@ 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
|
||||
|
@ -655,25 +570,18 @@ 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_LAYOUT_DEFAULT_LANGUAGE_INDEX
|
||||
HB_OT_LAYOUT_NO_FEATURE_INDEX
|
||||
HB_OT_LAYOUT_NO_SCRIPT_INDEX
|
||||
HB_OT_LAYOUT_NO_VARIATIONS_INDEX
|
||||
HB_OT_TAG_BASE
|
||||
HB_OT_TAG_GDEF
|
||||
HB_OT_TAG_GPOS
|
||||
HB_OT_TAG_GSUB
|
||||
HB_OT_TAG_JSTF
|
||||
hb_ot_layout_baseline_tag_t
|
||||
hb_ot_layout_glyph_class_t
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-math</FILE>
|
||||
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
|
||||
hb_ot_math_has_data
|
||||
hb_ot_math_get_constant
|
||||
hb_ot_math_get_glyph_italics_correction
|
||||
|
@ -684,31 +592,23 @@ 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 +618,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,44 +635,31 @@ 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_copy
|
||||
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_get_user_data
|
||||
hb_set_has
|
||||
hb_set_hash
|
||||
hb_set_subtract
|
||||
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
|
||||
|
@ -773,15 +667,19 @@ 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 +689,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,13 +744,13 @@ 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
|
||||
hb_version
|
||||
hb_version_atleast
|
||||
hb_version_string
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -863,19 +761,20 @@ hb_style_get_value
|
|||
|
||||
<SECTION>
|
||||
<FILE>hb-subset</FILE>
|
||||
hb_subset_flags_t
|
||||
hb_subset_input_t
|
||||
hb_subset_sets_t
|
||||
hb_subset_plan_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_keep_everything
|
||||
hb_subset_input_set_flags
|
||||
hb_subset_input_get_flags
|
||||
hb_subset_input_set_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
|
||||
|
@ -886,28 +785,8 @@ 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
|
||||
</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',
|
||||
|
@ -49,7 +53,7 @@ gnome.gtkdoc('harfbuzz',
|
|||
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)
|
||||
|
|
|
@ -23,11 +23,11 @@ Offset overflows can happen for a variety of reasons and require different strat
|
|||
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
|
||||
|
@ -47,22 +47,16 @@ There's four key pieces to the harfbuzz approach:
|
|||
|
||||
* [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
|
||||
|
||||
```
|
||||
|
@ -70,7 +64,6 @@ def repack(graph):
|
|||
graph.topological_sort()
|
||||
|
||||
if (graph.will_overflow())
|
||||
preprocess(graph)
|
||||
assign_spaces(graph)
|
||||
graph.topological_sort()
|
||||
|
||||
|
@ -92,7 +85,7 @@ The harfbuzz repacker uses two different algorithms for topological sorting:
|
|||
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
|
||||
|
@ -120,7 +113,7 @@ 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.
|
||||
|
||||
|
@ -192,37 +185,6 @@ The assign_spaces() step in the high level algorithm is responsible for identify
|
|||
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
|
||||
|
||||
|
@ -242,13 +204,13 @@ and then assign each such subgraph to a unique non-zero space. The algorithm is
|
|||
|
||||
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.
|
||||
|
||||
|
||||
|
@ -264,31 +226,40 @@ of the overflowing link:
|
|||
|
||||
* 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.
|
||||
The above resolution strategies are not sufficient to resolve all overflows. For example consider
|
||||
the case where a single subtable is 65k and the graph structure requires an offset to point over it.
|
||||
|
||||
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.
|
||||
The current harfbuzz implementation is suitable for the vast majority of subsetting related overflows.
|
||||
Subsetting related overflows are typically easy to solve since all subsets are derived from a font
|
||||
that was originally overflow free. A more general purpose version of the algorithm suitable for font
|
||||
creation purposes will likely need some additional offset resolution strategies:
|
||||
|
||||
* 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.
|
||||
|
||||
* Many subtables can be split into two smaller subtables without impacting the overall functionality.
|
||||
This should be done when an overflow is the result of a very large table which can't be moved
|
||||
to avoid offsets pointing over it.
|
||||
|
||||
* Lookup subtables in GSUB/GPOS can be upgraded to extension lookups which uses a 32 bit offset.
|
||||
Overflows from a Lookup subtable to it's child should be resolved by converting to an extension
|
||||
lookup.
|
||||
|
||||
Once additional resolution strategies are added to the algorithm it's likely that we'll need to
|
||||
switch to using a [backtracking algorithm](https://en.wikipedia.org/wiki/Backtracking) to explore
|
||||
the various combinations of resolution strategies until a non-overflowing combination is found. This
|
||||
will require the ability to restore the graph to an earlier state. It's likely that using a stack
|
||||
of undoable resolution commands could be used to accomplish this.
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -237,7 +237,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
|
||||
|
|
|
@ -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,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" />
|
||||
|
||||
|
|
123
meson.build
123
meson.build
|
@ -1,9 +1,8 @@
|
|||
project('harfbuzz', 'c', 'cpp',
|
||||
meson_version: '>= 0.55.0',
|
||||
version: '7.1.0',
|
||||
version: '4.3.0',
|
||||
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_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,25 +14,30 @@ 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'])
|
||||
# Disable SAFESEH with MSVC for libs that use external deps that are built with MinGW
|
||||
# noseh_link_args = ['/SAFESEH:NO']
|
||||
# disable exception handling
|
||||
add_project_arguments(['/EHs-', '/EHc-'], language: 'cpp')
|
||||
endif
|
||||
|
||||
add_project_link_arguments(cpp.get_supported_link_arguments([
|
||||
|
@ -79,72 +83,25 @@ check_funcs = [
|
|||
|
||||
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
|
||||
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
|
||||
endif
|
||||
endif
|
||||
# https://github.com/harfbuzz/harfbuzz/pull/2498
|
||||
freetype_dep = dependency(cpp.get_argument_syntax() == 'msvc' ? 'freetype' : 'freetype2',
|
||||
required: get_option('freetype'),
|
||||
default_options: ['harfbuzz=disabled'])
|
||||
|
||||
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'))
|
||||
|
||||
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)
|
||||
if cpp.get_argument_syntax() == 'msvc'
|
||||
icu_dep = dependency('ICU',
|
||||
required: get_option('icu'),
|
||||
components: 'uc',
|
||||
method: 'cmake')
|
||||
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'))
|
||||
endif
|
||||
endif
|
||||
icu_dep = dependency('icu-uc',
|
||||
required: get_option('icu'),
|
||||
method: 'pkg-config')
|
||||
endif
|
||||
|
||||
if icu_dep.found() and icu_dep.type_name() == 'pkgconfig'
|
||||
|
@ -161,7 +118,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',
|
||||
|
@ -177,8 +134,7 @@ if not get_option('cairo').disabled()
|
|||
# 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)
|
||||
cairo_ft_dep = dependency('cairo-ft', required: get_option('cairo'))
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -205,19 +161,10 @@ 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
|
||||
conf.set('HAVE_CAIRO_USER_FONT_FACE_SET_RENDER_COLOR_GLYPH_FUNC', 1)
|
||||
else
|
||||
check_funcs += check_cairo_funcs
|
||||
check_funcs += [['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}]]
|
||||
endif
|
||||
endif
|
||||
|
||||
|
@ -251,7 +198,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'
|
||||
|
@ -286,12 +232,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)
|
||||
|
@ -373,10 +324,7 @@ foreach check : check_funcs
|
|||
endforeach
|
||||
|
||||
subdir('src')
|
||||
|
||||
if not get_option('utilities').disabled()
|
||||
subdir('util')
|
||||
endif
|
||||
subdir('util')
|
||||
|
||||
if not get_option('tests').disabled()
|
||||
subdir('test')
|
||||
|
@ -392,9 +340,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,8 +354,7 @@ 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,
|
||||
|
@ -427,7 +371,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,
|
||||
},
|
||||
|
|
|
@ -29,10 +29,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')
|
||||
|
|
|
@ -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 \
|
||||
"$@"
|
||||
|
|
|
@ -6,22 +6,14 @@ 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
|
||||
meson configure build -Dbenchmark=enabled --buildtype=release
|
||||
```
|
||||
|
||||
Then build the benchmark binaries with ninja:
|
||||
|
||||
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:
|
||||
|
||||
|
@ -45,10 +37,10 @@ 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
|
||||
perf record -g -o ~/tmp/profiles/subset.prof ./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
|
||||
perf report -i ~/tmp/profiles/subset.prof
|
||||
|
|
|
@ -49,8 +49,8 @@ _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_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 *) {}
|
||||
|
@ -64,7 +64,7 @@ _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_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;
|
||||
|
@ -163,7 +163,7 @@ static void BM_Font (benchmark::State &state,
|
|||
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);
|
||||
hb_font_get_glyph_shape (font, gid, draw_funcs, nullptr);
|
||||
break;
|
||||
hb_draw_funcs_destroy (draw_funcs);
|
||||
}
|
||||
|
|
|
@ -27,18 +27,10 @@ struct test_input_t
|
|||
"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},
|
||||
|
|
|
@ -2,82 +2,35 @@
|
|||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "hb-subset.h"
|
||||
|
||||
|
||||
enum operation_t
|
||||
{
|
||||
subset_codepoints,
|
||||
subset_glyphs,
|
||||
instance,
|
||||
subset_glyphs
|
||||
};
|
||||
|
||||
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[] =
|
||||
const unsigned max_subset_size;
|
||||
} 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)},
|
||||
{SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf", 4000},
|
||||
{SUBSET_FONT_BASE_PATH "Amiri-Regular.ttf", 4000},
|
||||
{SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf", 1000},
|
||||
{SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf", 1000},
|
||||
{SUBSET_FONT_BASE_PATH "Mplus1p-Regular.ttf", 10000},
|
||||
{SUBSET_FONT_BASE_PATH "SourceHanSans-Regular_subset.otf", 10000},
|
||||
{SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf", 2000},
|
||||
#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)
|
||||
|
@ -102,52 +55,24 @@ void AddGlyphs(unsigned num_glyphs_in_font,
|
|||
}
|
||||
}
|
||||
|
||||
// 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)
|
||||
const char *font_path)
|
||||
{
|
||||
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_face_t *face;
|
||||
{
|
||||
hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
|
||||
hb_blob_t *blob = hb_blob_create_from_file_or_fail (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:
|
||||
|
@ -165,20 +90,6 @@ static void BM_subset (benchmark::State &state,
|
|||
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)
|
||||
|
@ -194,66 +105,38 @@ static void BM_subset (benchmark::State &state,
|
|||
|
||||
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");
|
||||
strcat (name, strrchr (test_input.font_path, '/'));
|
||||
|
||||
benchmark::RegisterBenchmark (name, BM_subset, op, test_input, hinting)
|
||||
benchmark::RegisterBenchmark (name, BM_subset, op, test_input.font_path)
|
||||
->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++)
|
||||
for (auto& test_input : tests)
|
||||
{
|
||||
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);
|
||||
test_subset (op, op_name, 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)
|
||||
#define TEST_OPERATION(op, time_unit) test_operation (op, #op, time_unit)
|
||||
|
||||
TEST_OPERATION (subset_glyphs, benchmark::kMillisecond);
|
||||
TEST_OPERATION (subset_codepoints, benchmark::kMillisecond);
|
||||
TEST_OPERATION (instance, benchmark::kMillisecond);
|
||||
|
||||
#undef TEST_OPERATION
|
||||
|
||||
benchmark::Initialize(&argc, argv);
|
||||
benchmark::RunSpecifiedBenchmarks();
|
||||
benchmark::Shutdown();
|
||||
|
||||
if (tests != default_tests)
|
||||
free (tests);
|
||||
}
|
||||
|
|
|
@ -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
|
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
|
102
src/Makefile.am
102
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' \
|
||||
|
@ -312,8 +240,6 @@ harfbuzz.def: $(HBHEADERS)
|
|||
$(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 +284,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 +294,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 +306,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,18 +334,10 @@ 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)
|
||||
|
@ -435,7 +349,6 @@ COMPILED_TESTS = \
|
|||
test-iter \
|
||||
test-machinery \
|
||||
test-map \
|
||||
test-multimap \
|
||||
test-number \
|
||||
test-ot-tag \
|
||||
test-priority-queue \
|
||||
|
@ -444,7 +357,6 @@ COMPILED_TESTS = \
|
|||
test-unicode-ranges \
|
||||
test-vector \
|
||||
test-repacker \
|
||||
test-classdef-graph \
|
||||
$(NULL)
|
||||
COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
|
||||
COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
@ -475,10 +387,6 @@ 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_number_SOURCES = test-number.cc hb-number.cc
|
||||
test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_number_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
@ -491,14 +399,10 @@ 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_SOURCES = test-repacker.cc hb-static.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)
|
||||
|
|
|
@ -42,19 +42,16 @@ 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 +66,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 +87,29 @@ 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/MultipleSubstFormat1.hh \
|
||||
OT/Layout/GSUB/MultipleSubst.hh \
|
||||
OT/Layout/GSUB/AlternateSubstFormat1.hh \
|
||||
OT/Layout/GSUB/AlternateSubst.hh \
|
||||
OT/Layout/GSUB/AlternateSet.hh \
|
||||
OT/Layout/GSUB/LigatureSubstFormat1.hh \
|
||||
OT/Layout/GSUB/LigatureSubst.hh \
|
||||
OT/Layout/GSUB/LigatureSet.hh \
|
||||
OT/Layout/GSUB/Ligature.hh \
|
||||
OT/Layout/GSUB/ReverseChainSingleSubst.hh \
|
||||
OT/Layout/GSUB/ReverseChainSingleSubstFormat1.hh \
|
||||
OT/Layout/GSUB/ContextSubst.hh \
|
||||
OT/Layout/GSUB/ChainContextSubst.hh \
|
||||
OT/Layout/GSUB/ExtensionSubst.hh \
|
||||
OT/Layout/GSUB/SubstLookupSubTable.hh \
|
||||
OT/name/name.hh \
|
||||
OT/Layout/GSUB/SubstLookup.hh \
|
||||
OT/Layout/GSUB/GSUB.hh \
|
||||
hb-ot-layout-gsubgpos.hh \
|
||||
hb-ot-layout-jstf-table.hh \
|
||||
hb-ot-layout.cc \
|
||||
|
@ -193,7 +133,6 @@ HB_BASE_sources = \
|
|||
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 \
|
||||
|
@ -205,7 +144,9 @@ HB_BASE_sources = \
|
|||
hb-ot-shaper-indic.cc \
|
||||
hb-ot-shaper-indic.hh \
|
||||
hb-ot-shaper-khmer.cc \
|
||||
hb-ot-shaper-khmer.hh \
|
||||
hb-ot-shaper-myanmar.cc \
|
||||
hb-ot-shaper-myanmar.hh \
|
||||
hb-ot-shaper-syllabic.cc \
|
||||
hb-ot-shaper-syllabic.hh \
|
||||
hb-ot-shaper-thai.cc \
|
||||
|
@ -225,7 +166,6 @@ HB_BASE_sources = \
|
|||
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 \
|
||||
|
@ -261,8 +201,7 @@ HB_BASE_sources = \
|
|||
|
||||
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 \
|
||||
|
@ -271,8 +210,7 @@ HB_BASE_RAGEL_GENERATED_sources = \
|
|||
$(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 \
|
||||
|
@ -303,7 +241,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 +252,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,6 +285,7 @@ HB_SUBSET_sources = \
|
|||
hb-number.hh \
|
||||
hb-ot-cff1-table.cc \
|
||||
hb-ot-cff2-table.cc \
|
||||
hb-ot-color-colrv1-closure.hh \
|
||||
hb-ot-post-table-v2subset.hh \
|
||||
hb-static.cc \
|
||||
hb-subset-cff-common.cc \
|
||||
|
@ -358,25 +296,12 @@ 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 = \
|
||||
|
@ -384,16 +309,6 @@ HB_SUBSET_headers = \
|
|||
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
|
||||
HB_GOBJECT_DIST_headers = hb-gobject.h hb-gobject-structs.h
|
||||
HB_GOBJECT_ENUM_sources = hb-gobject-enums.cc
|
||||
|
|
|
@ -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 */
|
|
@ -1,56 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH
|
||||
#define OT_LAYOUT_GPOS_LIGATUREARRAY_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
|
||||
typedef AnchorMatrix LigatureAttach; /* component-major--
|
||||
* in order of writing direction--,
|
||||
* mark-minor--
|
||||
* ordered by class--zero-based. */
|
||||
|
||||
/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
|
||||
struct LigatureArray : List16OfOffset16To<LigatureAttach>
|
||||
{
|
||||
template <typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
bool subset (hb_subset_context_t *c,
|
||||
Iterator coverage,
|
||||
unsigned class_count,
|
||||
const hb_map_t *klass_mapping) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||
|
||||
auto *out = c->serializer->start_embed (this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
for (const auto _ : + hb_zip (coverage, *this)
|
||||
| hb_filter (glyphset, hb_first))
|
||||
{
|
||||
auto *matrix = out->serialize_append (c->serializer);
|
||||
if (unlikely (!matrix)) return_trace (false);
|
||||
|
||||
const LigatureAttach& src = (this + _.second);
|
||||
auto indexes =
|
||||
+ hb_range (src.rows * class_count)
|
||||
| hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
|
||||
;
|
||||
matrix->serialize_subset (c,
|
||||
_.second,
|
||||
this,
|
||||
src.rows,
|
||||
indexes);
|
||||
}
|
||||
return_trace (this->len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */
|
|
@ -1,128 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_MARKARRAY_HH
|
||||
#define OT_LAYOUT_GPOS_MARKARRAY_HH
|
||||
|
||||
#include "AnchorMatrix.hh"
|
||||
#include "MarkRecord.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct MarkArray : Array16Of<MarkRecord> /* Array of MarkRecords--in Coverage order */
|
||||
{
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (Array16Of<MarkRecord>::sanitize (c, this));
|
||||
}
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c,
|
||||
unsigned int mark_index, unsigned int glyph_index,
|
||||
const AnchorMatrix &anchors, unsigned int class_count,
|
||||
unsigned int glyph_pos) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
const MarkRecord &record = Array16Of<MarkRecord>::operator[](mark_index);
|
||||
unsigned int mark_class = record.klass;
|
||||
|
||||
const Anchor& mark_anchor = this + record.markAnchor;
|
||||
bool found;
|
||||
const Anchor& glyph_anchor = anchors.get_anchor (glyph_index, mark_class, class_count, &found);
|
||||
/* If this subtable doesn't have an anchor for this base and this class,
|
||||
* return false such that the subsequent subtables have a chance at it. */
|
||||
if (unlikely (!found)) return_trace (false);
|
||||
|
||||
float mark_x, mark_y, base_x, base_y;
|
||||
|
||||
buffer->unsafe_to_break (glyph_pos, buffer->idx + 1);
|
||||
mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
|
||||
glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"attaching mark glyph at %u to glyph at %u",
|
||||
c->buffer->idx, glyph_pos);
|
||||
}
|
||||
|
||||
hb_glyph_position_t &o = buffer->cur_pos();
|
||||
o.x_offset = roundf (base_x - mark_x);
|
||||
o.y_offset = roundf (base_y - mark_y);
|
||||
o.attach_type() = ATTACH_TYPE_MARK;
|
||||
o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"attached mark glyph at %u to glyph at %u",
|
||||
c->buffer->idx, glyph_pos);
|
||||
}
|
||||
|
||||
buffer->idx++;
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
template <typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
bool subset (hb_subset_context_t *c,
|
||||
Iterator coverage,
|
||||
const hb_map_t *klass_mapping) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||
|
||||
auto* out = c->serializer->start_embed (this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
|
||||
auto mark_iter =
|
||||
+ hb_zip (coverage, this->iter ())
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_map (hb_second)
|
||||
;
|
||||
|
||||
unsigned new_length = 0;
|
||||
for (const auto& mark_record : mark_iter) {
|
||||
if (unlikely (!mark_record.subset (c, this, klass_mapping)))
|
||||
return_trace (false);
|
||||
new_length++;
|
||||
}
|
||||
|
||||
if (unlikely (!c->serializer->check_assign (out->len, new_length,
|
||||
HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)))
|
||||
return_trace (false);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
};
|
||||
|
||||
HB_INTERNAL inline
|
||||
void Markclass_closure_and_remap_indexes (const Coverage &mark_coverage,
|
||||
const MarkArray &mark_array,
|
||||
const hb_set_t &glyphset,
|
||||
hb_map_t* klass_mapping /* INOUT */)
|
||||
{
|
||||
hb_set_t orig_classes;
|
||||
|
||||
+ hb_zip (mark_coverage, mark_array)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_map (&MarkRecord::get_class)
|
||||
| hb_sink (orig_classes)
|
||||
;
|
||||
|
||||
unsigned idx = 0;
|
||||
for (auto klass : orig_classes.iter ())
|
||||
{
|
||||
if (klass_mapping->has (klass)) continue;
|
||||
klass_mapping->set (klass, idx);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_MARKARRAY_HH */
|
|
@ -1,41 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_MARKBASEPOS_HH
|
||||
#define OT_LAYOUT_GPOS_MARKBASEPOS_HH
|
||||
|
||||
#include "MarkBasePosFormat1.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct MarkBasePos
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
MarkBasePosFormat1_2<SmallTypes> format1;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
MarkBasePosFormat1_2<MediumTypes> format2;
|
||||
#endif
|
||||
} 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)...));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||
#endif
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_MARKBASEPOS_HH */
|
|
@ -1,244 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH
|
||||
#define OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH
|
||||
|
||||
#include "MarkArray.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
typedef AnchorMatrix BaseArray; /* base-major--
|
||||
* in order of BaseCoverage Index--,
|
||||
* mark-minor--
|
||||
* ordered by class--zero-based. */
|
||||
|
||||
template <typename Types>
|
||||
struct MarkBasePosFormat1_2
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
markCoverage; /* Offset to MarkCoverage table--from
|
||||
* beginning of MarkBasePos subtable */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
baseCoverage; /* Offset to BaseCoverage table--from
|
||||
* beginning of MarkBasePos subtable */
|
||||
HBUINT16 classCount; /* Number of classes defined for marks */
|
||||
typename Types::template OffsetTo<MarkArray>
|
||||
markArray; /* Offset to MarkArray table--from
|
||||
* beginning of MarkBasePos subtable */
|
||||
typename Types::template OffsetTo<BaseArray>
|
||||
baseArray; /* Offset to BaseArray table--from
|
||||
* beginning of MarkBasePos subtable */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4 + 4 * Types::size);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
markCoverage.sanitize (c, this) &&
|
||||
baseCoverage.sanitize (c, this) &&
|
||||
markArray.sanitize (c, this) &&
|
||||
baseArray.sanitize (c, this, (unsigned int) classCount));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
return (this+markCoverage).intersects (glyphs) &&
|
||||
(this+baseCoverage).intersects (glyphs);
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
+ hb_zip (this+markCoverage, this+markArray)
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
|
||||
;
|
||||
|
||||
hb_map_t klass_mapping;
|
||||
Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
|
||||
|
||||
unsigned basecount = (this+baseArray).rows;
|
||||
auto base_iter =
|
||||
+ hb_zip (this+baseCoverage, hb_range (basecount))
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
;
|
||||
|
||||
hb_sorted_vector_t<unsigned> base_indexes;
|
||||
for (const unsigned row : base_iter)
|
||||
{
|
||||
+ hb_range ((unsigned) classCount)
|
||||
| hb_filter (klass_mapping)
|
||||
| hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
|
||||
| hb_sink (base_indexes)
|
||||
;
|
||||
}
|
||||
(this+baseArray).collect_variation_indices (c, base_indexes.iter ());
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{
|
||||
if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
|
||||
if (unlikely (!(this+baseCoverage).collect_coverage (c->input))) return;
|
||||
}
|
||||
|
||||
const Coverage &get_coverage () const { return this+markCoverage; }
|
||||
|
||||
static inline bool accept (hb_buffer_t *buffer, unsigned idx)
|
||||
{
|
||||
/* We only want to attach to the first of a MultipleSubst sequence.
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/740
|
||||
* Reject others...
|
||||
* ...but stop if we find a mark in the MultipleSubst sequence:
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/1020 */
|
||||
return !_hb_glyph_info_multiplied (&buffer->info[idx]) ||
|
||||
0 == _hb_glyph_info_get_lig_comp (&buffer->info[idx]) ||
|
||||
(idx == 0 ||
|
||||
_hb_glyph_info_is_mark (&buffer->info[idx - 1]) ||
|
||||
!_hb_glyph_info_multiplied (&buffer->info[idx - 1]) ||
|
||||
_hb_glyph_info_get_lig_id (&buffer->info[idx]) !=
|
||||
_hb_glyph_info_get_lig_id (&buffer->info[idx - 1]) ||
|
||||
_hb_glyph_info_get_lig_comp (&buffer->info[idx]) !=
|
||||
_hb_glyph_info_get_lig_comp (&buffer->info[idx - 1]) + 1
|
||||
);
|
||||
}
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
|
||||
if (likely (mark_index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
/* Now we search backwards for a non-mark glyph.
|
||||
* We don't use skippy_iter.prev() to avoid O(n^2) behavior. */
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
|
||||
|
||||
if (c->last_base_until > buffer->idx)
|
||||
{
|
||||
c->last_base_until = 0;
|
||||
c->last_base = -1;
|
||||
}
|
||||
unsigned j;
|
||||
for (j = buffer->idx; j > c->last_base_until; j--)
|
||||
{
|
||||
auto match = skippy_iter.match (buffer->info[j - 1]);
|
||||
if (match == skippy_iter.MATCH)
|
||||
{
|
||||
// https://github.com/harfbuzz/harfbuzz/issues/4124
|
||||
if (!accept (buffer, j - 1) &&
|
||||
NOT_COVERED == (this+baseCoverage).get_coverage (buffer->info[j - 1].codepoint))
|
||||
match = skippy_iter.SKIP;
|
||||
}
|
||||
if (match == skippy_iter.MATCH)
|
||||
{
|
||||
c->last_base = (signed) j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
c->last_base_until = buffer->idx;
|
||||
if (c->last_base == -1)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned idx = (unsigned) c->last_base;
|
||||
|
||||
/* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
|
||||
//if (!_hb_glyph_info_is_base_glyph (&buffer->info[idx])) { return_trace (false); }
|
||||
|
||||
unsigned int base_index = (this+baseCoverage).get_coverage (buffer->info[idx].codepoint);
|
||||
if (base_index == NOT_COVERED)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, idx));
|
||||
}
|
||||
|
||||
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);
|
||||
out->format = format;
|
||||
|
||||
hb_map_t klass_mapping;
|
||||
Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
|
||||
|
||||
if (!klass_mapping.get_population ()) return_trace (false);
|
||||
out->classCount = klass_mapping.get_population ();
|
||||
|
||||
auto mark_iter =
|
||||
+ hb_zip (this+markCoverage, this+markArray)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
;
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
|
||||
+ mark_iter
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
|
||||
if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
|
||||
return_trace (false);
|
||||
|
||||
out->markArray.serialize_subset (c, markArray, this,
|
||||
(this+markCoverage).iter (),
|
||||
&klass_mapping);
|
||||
|
||||
unsigned basecount = (this+baseArray).rows;
|
||||
auto base_iter =
|
||||
+ hb_zip (this+baseCoverage, hb_range (basecount))
|
||||
| hb_filter (glyphset, hb_first)
|
||||
;
|
||||
|
||||
new_coverage.reset ();
|
||||
+ base_iter
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
|
||||
if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
|
||||
return_trace (false);
|
||||
|
||||
hb_sorted_vector_t<unsigned> base_indexes;
|
||||
for (const unsigned row : + base_iter
|
||||
| hb_map (hb_second))
|
||||
{
|
||||
+ hb_range ((unsigned) classCount)
|
||||
| hb_filter (klass_mapping)
|
||||
| hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
|
||||
| hb_sink (base_indexes)
|
||||
;
|
||||
}
|
||||
|
||||
out->baseArray.serialize_subset (c, baseArray, this,
|
||||
base_iter.len (),
|
||||
base_indexes.iter ());
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH */
|
|
@ -1,41 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_MARKLIGPOS_HH
|
||||
#define OT_LAYOUT_GPOS_MARKLIGPOS_HH
|
||||
|
||||
#include "MarkLigPosFormat1.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct MarkLigPos
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
MarkLigPosFormat1_2<SmallTypes> format1;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
MarkLigPosFormat1_2<MediumTypes> format2;
|
||||
#endif
|
||||
} 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)...));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||
#endif
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_MARKLIGPOS_HH */
|
|
@ -1,223 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
|
||||
#define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
|
||||
|
||||
#include "LigatureArray.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
|
||||
template <typename Types>
|
||||
struct MarkLigPosFormat1_2
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
markCoverage; /* Offset to Mark Coverage table--from
|
||||
* beginning of MarkLigPos subtable */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
ligatureCoverage; /* Offset to Ligature Coverage
|
||||
* table--from beginning of MarkLigPos
|
||||
* subtable */
|
||||
HBUINT16 classCount; /* Number of defined mark classes */
|
||||
typename Types::template OffsetTo<MarkArray>
|
||||
markArray; /* Offset to MarkArray table--from
|
||||
* beginning of MarkLigPos subtable */
|
||||
typename Types::template OffsetTo<LigatureArray>
|
||||
ligatureArray; /* Offset to LigatureArray table--from
|
||||
* beginning of MarkLigPos subtable */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4 + 4 * Types::size);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
markCoverage.sanitize (c, this) &&
|
||||
ligatureCoverage.sanitize (c, this) &&
|
||||
markArray.sanitize (c, this) &&
|
||||
ligatureArray.sanitize (c, this, (unsigned int) classCount));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
return (this+markCoverage).intersects (glyphs) &&
|
||||
(this+ligatureCoverage).intersects (glyphs);
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
+ hb_zip (this+markCoverage, this+markArray)
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
|
||||
;
|
||||
|
||||
hb_map_t klass_mapping;
|
||||
Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
|
||||
|
||||
unsigned ligcount = (this+ligatureArray).len;
|
||||
auto lig_iter =
|
||||
+ hb_zip (this+ligatureCoverage, hb_range (ligcount))
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
;
|
||||
|
||||
const LigatureArray& lig_array = this+ligatureArray;
|
||||
for (const unsigned i : lig_iter)
|
||||
{
|
||||
hb_sorted_vector_t<unsigned> lig_indexes;
|
||||
unsigned row_count = lig_array[i].rows;
|
||||
for (unsigned row : + hb_range (row_count))
|
||||
{
|
||||
+ hb_range ((unsigned) classCount)
|
||||
| hb_filter (klass_mapping)
|
||||
| hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
|
||||
| hb_sink (lig_indexes)
|
||||
;
|
||||
}
|
||||
|
||||
lig_array[i].collect_variation_indices (c, lig_indexes.iter ());
|
||||
}
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{
|
||||
if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
|
||||
if (unlikely (!(this+ligatureCoverage).collect_coverage (c->input))) return;
|
||||
}
|
||||
|
||||
const Coverage &get_coverage () const { return this+markCoverage; }
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
unsigned int mark_index = (this+markCoverage).get_coverage (buffer->cur().codepoint);
|
||||
if (likely (mark_index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
/* Now we search backwards for a non-mark glyph */
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
|
||||
|
||||
if (c->last_base_until > buffer->idx)
|
||||
{
|
||||
c->last_base_until = 0;
|
||||
c->last_base = -1;
|
||||
}
|
||||
unsigned j;
|
||||
for (j = buffer->idx; j > c->last_base_until; j--)
|
||||
{
|
||||
auto match = skippy_iter.match (buffer->info[j - 1]);
|
||||
if (match == skippy_iter.MATCH)
|
||||
{
|
||||
c->last_base = (signed) j - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
c->last_base_until = buffer->idx;
|
||||
if (c->last_base == -1)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned idx = (unsigned) c->last_base;
|
||||
|
||||
/* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
|
||||
//if (!_hb_glyph_info_is_ligature (&buffer->info[idx])) { return_trace (false); }
|
||||
|
||||
unsigned int lig_index = (this+ligatureCoverage).get_coverage (buffer->info[idx].codepoint);
|
||||
if (lig_index == NOT_COVERED)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
const LigatureArray& lig_array = this+ligatureArray;
|
||||
const LigatureAttach& lig_attach = lig_array[lig_index];
|
||||
|
||||
/* Find component to attach to */
|
||||
unsigned int comp_count = lig_attach.rows;
|
||||
if (unlikely (!comp_count))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
/* We must now check whether the ligature ID of the current mark glyph
|
||||
* is identical to the ligature ID of the found ligature. If yes, we
|
||||
* can directly use the component index. If not, we attach the mark
|
||||
* glyph to the last component of the ligature. */
|
||||
unsigned int comp_index;
|
||||
unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[idx]);
|
||||
unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
|
||||
unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
|
||||
if (lig_id && lig_id == mark_id && mark_comp > 0)
|
||||
comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
|
||||
else
|
||||
comp_index = comp_count - 1;
|
||||
|
||||
return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, idx));
|
||||
}
|
||||
|
||||
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);
|
||||
out->format = format;
|
||||
|
||||
hb_map_t klass_mapping;
|
||||
Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
|
||||
|
||||
if (!klass_mapping.get_population ()) return_trace (false);
|
||||
out->classCount = klass_mapping.get_population ();
|
||||
|
||||
auto mark_iter =
|
||||
+ hb_zip (this+markCoverage, this+markArray)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
;
|
||||
|
||||
auto new_mark_coverage =
|
||||
+ mark_iter
|
||||
| hb_map_retains_sorting (hb_first)
|
||||
| hb_map_retains_sorting (glyph_map)
|
||||
;
|
||||
|
||||
if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage))
|
||||
return_trace (false);
|
||||
|
||||
out->markArray.serialize_subset (c, markArray, this,
|
||||
(this+markCoverage).iter (),
|
||||
&klass_mapping);
|
||||
|
||||
auto new_ligature_coverage =
|
||||
+ hb_iter (this + ligatureCoverage)
|
||||
| hb_filter (glyphset)
|
||||
| hb_map_retains_sorting (glyph_map)
|
||||
;
|
||||
|
||||
if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))
|
||||
return_trace (false);
|
||||
|
||||
out->ligatureArray.serialize_subset (c, ligatureArray, this,
|
||||
hb_iter (this+ligatureCoverage), classCount, &klass_mapping);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH */
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_MARKMARKPOS_HH
|
||||
#define OT_LAYOUT_GPOS_MARKMARKPOS_HH
|
||||
|
||||
#include "MarkMarkPosFormat1.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct MarkMarkPos
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
MarkMarkPosFormat1_2<SmallTypes> format1;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
MarkMarkPosFormat1_2<MediumTypes> format2;
|
||||
#endif
|
||||
} 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)...));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||
#endif
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_MARKMARKPOS_HH */
|
|
@ -1,228 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH
|
||||
#define OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH
|
||||
|
||||
#include "MarkMarkPosFormat1.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
typedef AnchorMatrix Mark2Array; /* mark2-major--
|
||||
* in order of Mark2Coverage Index--,
|
||||
* mark1-minor--
|
||||
* ordered by class--zero-based. */
|
||||
|
||||
template <typename Types>
|
||||
struct MarkMarkPosFormat1_2
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
mark1Coverage; /* Offset to Combining Mark1 Coverage
|
||||
* table--from beginning of MarkMarkPos
|
||||
* subtable */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
mark2Coverage; /* Offset to Combining Mark2 Coverage
|
||||
* table--from beginning of MarkMarkPos
|
||||
* subtable */
|
||||
HBUINT16 classCount; /* Number of defined mark classes */
|
||||
typename Types::template OffsetTo<MarkArray>
|
||||
mark1Array; /* Offset to Mark1Array table--from
|
||||
* beginning of MarkMarkPos subtable */
|
||||
typename Types::template OffsetTo<Mark2Array>
|
||||
mark2Array; /* Offset to Mark2Array table--from
|
||||
* beginning of MarkMarkPos subtable */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4 + 4 * Types::size);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
mark1Coverage.sanitize (c, this) &&
|
||||
mark2Coverage.sanitize (c, this) &&
|
||||
mark1Array.sanitize (c, this) &&
|
||||
mark2Array.sanitize (c, this, (unsigned int) classCount));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
return (this+mark1Coverage).intersects (glyphs) &&
|
||||
(this+mark2Coverage).intersects (glyphs);
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
+ hb_zip (this+mark1Coverage, this+mark1Array)
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); })
|
||||
;
|
||||
|
||||
hb_map_t klass_mapping;
|
||||
Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping);
|
||||
|
||||
unsigned mark2_count = (this+mark2Array).rows;
|
||||
auto mark2_iter =
|
||||
+ hb_zip (this+mark2Coverage, hb_range (mark2_count))
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
;
|
||||
|
||||
hb_sorted_vector_t<unsigned> mark2_indexes;
|
||||
for (const unsigned row : mark2_iter)
|
||||
{
|
||||
+ hb_range ((unsigned) classCount)
|
||||
| hb_filter (klass_mapping)
|
||||
| hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
|
||||
| hb_sink (mark2_indexes)
|
||||
;
|
||||
}
|
||||
(this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ());
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{
|
||||
if (unlikely (!(this+mark1Coverage).collect_coverage (c->input))) return;
|
||||
if (unlikely (!(this+mark2Coverage).collect_coverage (c->input))) return;
|
||||
}
|
||||
|
||||
const Coverage &get_coverage () const { return this+mark1Coverage; }
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
unsigned int mark1_index = (this+mark1Coverage).get_coverage (buffer->cur().codepoint);
|
||||
if (likely (mark1_index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
|
||||
unsigned unsafe_from;
|
||||
if (!skippy_iter.prev (&unsafe_from))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned int j = skippy_iter.idx;
|
||||
|
||||
unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
|
||||
unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
|
||||
unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
|
||||
unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
|
||||
|
||||
if (likely (id1 == id2))
|
||||
{
|
||||
if (id1 == 0) /* Marks belonging to the same base. */
|
||||
goto good;
|
||||
else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
|
||||
goto good;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If ligature ids don't match, it may be the case that one of the marks
|
||||
* itself is a ligature. In which case match. */
|
||||
if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
|
||||
goto good;
|
||||
}
|
||||
|
||||
/* Didn't match. */
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
|
||||
good:
|
||||
unsigned int mark2_index = (this+mark2Coverage).get_coverage (buffer->info[j].codepoint);
|
||||
if (mark2_index == NOT_COVERED)
|
||||
{
|
||||
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
|
||||
}
|
||||
|
||||
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);
|
||||
out->format = format;
|
||||
|
||||
hb_map_t klass_mapping;
|
||||
Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping);
|
||||
|
||||
if (!klass_mapping.get_population ()) return_trace (false);
|
||||
out->classCount = klass_mapping.get_population ();
|
||||
|
||||
auto mark1_iter =
|
||||
+ hb_zip (this+mark1Coverage, this+mark1Array)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
;
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
|
||||
+ mark1_iter
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
|
||||
if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
|
||||
return_trace (false);
|
||||
|
||||
out->mark1Array.serialize_subset (c, mark1Array, this,
|
||||
(this+mark1Coverage).iter (),
|
||||
&klass_mapping);
|
||||
|
||||
unsigned mark2count = (this+mark2Array).rows;
|
||||
auto mark2_iter =
|
||||
+ hb_zip (this+mark2Coverage, hb_range (mark2count))
|
||||
| hb_filter (glyphset, hb_first)
|
||||
;
|
||||
|
||||
new_coverage.reset ();
|
||||
+ mark2_iter
|
||||
| hb_map (hb_first)
|
||||
| hb_map (glyph_map)
|
||||
| hb_sink (new_coverage)
|
||||
;
|
||||
|
||||
if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
|
||||
return_trace (false);
|
||||
|
||||
hb_sorted_vector_t<unsigned> mark2_indexes;
|
||||
for (const unsigned row : + mark2_iter
|
||||
| hb_map (hb_second))
|
||||
{
|
||||
+ hb_range ((unsigned) classCount)
|
||||
| hb_filter (klass_mapping)
|
||||
| hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
|
||||
| hb_sink (mark2_indexes)
|
||||
;
|
||||
}
|
||||
|
||||
out->mark2Array.serialize_subset (c, mark2Array, this, mark2_iter.len (), mark2_indexes.iter ());
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH */
|
|
@ -1,52 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_MARKRECORD_HH
|
||||
#define OT_LAYOUT_GPOS_MARKRECORD_HH
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct MarkRecord
|
||||
{
|
||||
friend struct MarkArray;
|
||||
|
||||
public:
|
||||
HBUINT16 klass; /* Class defined for this mark */
|
||||
Offset16To<Anchor>
|
||||
markAnchor; /* Offset to Anchor table--from
|
||||
* beginning of MarkArray table */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
|
||||
unsigned get_class () const { return (unsigned) klass; }
|
||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
|
||||
}
|
||||
|
||||
MarkRecord *subset (hb_subset_context_t *c,
|
||||
const void *src_base,
|
||||
const hb_map_t *klass_mapping) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (this);
|
||||
if (unlikely (!out)) return_trace (nullptr);
|
||||
|
||||
out->klass = klass_mapping->get (klass);
|
||||
out->markAnchor.serialize_subset (c, markAnchor, src_base);
|
||||
return_trace (out);
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
||||
const void *src_base) const
|
||||
{
|
||||
(src_base+markAnchor).collect_variation_indices (c);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_MARKRECORD_HH */
|
|
@ -1,46 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_PAIRPOS_HH
|
||||
#define OT_LAYOUT_GPOS_PAIRPOS_HH
|
||||
|
||||
#include "PairPosFormat1.hh"
|
||||
#include "PairPosFormat2.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct PairPos
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
PairPosFormat1_3<SmallTypes> format1;
|
||||
PairPosFormat2_4<SmallTypes> format2;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
PairPosFormat1_3<MediumTypes> format3;
|
||||
PairPosFormat2_4<MediumTypes> format4;
|
||||
#endif
|
||||
} 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)...));
|
||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
|
||||
case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
|
||||
#endif
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_PAIRPOS_HH
|
|
@ -1,217 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
|
||||
#define OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
|
||||
|
||||
#include "PairSet.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
|
||||
template <typename Types>
|
||||
struct PairPosFormat1_3
|
||||
{
|
||||
using PairSet = GPOS_impl::PairSet<Types>;
|
||||
using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of subtable */
|
||||
ValueFormat valueFormat[2]; /* [0] Defines the types of data in
|
||||
* ValueRecord1--for the first glyph
|
||||
* in the pair--may be zero (0) */
|
||||
/* [1] Defines the types of data in
|
||||
* ValueRecord2--for the second glyph
|
||||
* in the pair--may be zero (0) */
|
||||
Array16Of<typename Types::template OffsetTo<PairSet>>
|
||||
pairSet; /* Array of PairSet tables
|
||||
* ordered by Coverage Index */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8 + Types::size, pairSet);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
||||
if (!c->check_struct (this)) return_trace (false);
|
||||
|
||||
unsigned int len1 = valueFormat[0].get_len ();
|
||||
unsigned int len2 = valueFormat[1].get_len ();
|
||||
typename PairSet::sanitize_closure_t closure =
|
||||
{
|
||||
valueFormat,
|
||||
len1,
|
||||
PairSet::get_size (len1, len2)
|
||||
};
|
||||
|
||||
return_trace (coverage.sanitize (c, this) && pairSet.sanitize (c, this, &closure));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
auto &cov = this+coverage;
|
||||
|
||||
if (pairSet.len > glyphs->get_population () * hb_bit_storage ((unsigned) pairSet.len) / 4)
|
||||
{
|
||||
for (hb_codepoint_t g : glyphs->iter())
|
||||
{
|
||||
unsigned i = cov.get_coverage (g);
|
||||
if ((this+pairSet[i]).intersects (glyphs, valueFormat))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return
|
||||
+ hb_zip (cov, pairSet)
|
||||
| hb_filter (*glyphs, hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_)
|
||||
{ return (this+_).intersects (glyphs, valueFormat); })
|
||||
| hb_any
|
||||
;
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
if ((!valueFormat[0].has_device ()) && (!valueFormat[1].has_device ())) return;
|
||||
|
||||
auto it =
|
||||
+ hb_zip (this+coverage, pairSet)
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
| hb_map (hb_second)
|
||||
;
|
||||
|
||||
if (!it) return;
|
||||
+ it
|
||||
| hb_map (hb_add (this))
|
||||
| hb_apply ([&] (const PairSet& _) { _.collect_variation_indices (c, valueFormat); })
|
||||
;
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{
|
||||
if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
|
||||
unsigned int count = pairSet.len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
(this+pairSet[i]).collect_glyphs (c, valueFormat);
|
||||
}
|
||||
|
||||
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;
|
||||
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
|
||||
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
unsigned unsafe_to;
|
||||
if (!skippy_iter.next (&unsafe_to))
|
||||
{
|
||||
buffer->unsafe_to_concat (buffer->idx, unsafe_to);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
return_trace ((this+pairSet[index]).apply (c, valueFormat, skippy_iter.idx));
|
||||
}
|
||||
|
||||
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);
|
||||
out->format = format;
|
||||
out->valueFormat[0] = valueFormat[0];
|
||||
out->valueFormat[1] = valueFormat[1];
|
||||
if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
||||
{
|
||||
hb_pair_t<unsigned, unsigned> newFormats = compute_effective_value_formats (glyphset);
|
||||
out->valueFormat[0] = newFormats.first;
|
||||
out->valueFormat[1] = newFormats.second;
|
||||
}
|
||||
|
||||
if (c->plan->all_axes_pinned)
|
||||
{
|
||||
out->valueFormat[0] = out->valueFormat[0].drop_device_table_flags ();
|
||||
out->valueFormat[1] = out->valueFormat[1].drop_device_table_flags ();
|
||||
}
|
||||
|
||||
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
|
||||
|
||||
+ hb_zip (this+coverage, pairSet)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_filter ([this, c, out] (const typename Types::template OffsetTo<PairSet>& _)
|
||||
{
|
||||
auto snap = c->serializer->snapshot ();
|
||||
auto *o = out->pairSet.serialize_append (c->serializer);
|
||||
if (unlikely (!o)) return false;
|
||||
bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat);
|
||||
if (!ret)
|
||||
{
|
||||
out->pairSet.pop ();
|
||||
c->serializer->revert (snap);
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_set_t& glyphset) const
|
||||
{
|
||||
unsigned record_size = PairSet::get_size (valueFormat);
|
||||
|
||||
unsigned format1 = 0;
|
||||
unsigned format2 = 0;
|
||||
for (const auto & _ :
|
||||
+ hb_zip (this+coverage, pairSet)
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_map (hb_second)
|
||||
)
|
||||
{
|
||||
const PairSet& set = (this + _);
|
||||
const PairValueRecord *record = &set.firstPairValueRecord;
|
||||
|
||||
unsigned count = set.len;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
if (record->intersects (glyphset))
|
||||
{
|
||||
format1 = format1 | valueFormat[0].get_effective_format (record->get_values_1 ());
|
||||
format2 = format2 | valueFormat[1].get_effective_format (record->get_values_2 (valueFormat[0]));
|
||||
}
|
||||
record = &StructAtOffset<const PairValueRecord> (record, record_size);
|
||||
}
|
||||
|
||||
if (format1 == valueFormat[0] && format2 == valueFormat[1])
|
||||
break;
|
||||
}
|
||||
|
||||
return hb_pair (format1, format2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_PAIRPOSFORMAT1_HH
|
|
@ -1,351 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
|
||||
#define OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
|
||||
|
||||
#include "ValueFormat.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
template <typename Types>
|
||||
struct PairPosFormat2_4
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 2 */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of subtable */
|
||||
ValueFormat valueFormat1; /* ValueRecord definition--for the
|
||||
* first glyph of the pair--may be zero
|
||||
* (0) */
|
||||
ValueFormat valueFormat2; /* ValueRecord definition--for the
|
||||
* second glyph of the pair--may be
|
||||
* zero (0) */
|
||||
typename Types::template OffsetTo<ClassDef>
|
||||
classDef1; /* Offset to ClassDef table--from
|
||||
* beginning of PairPos subtable--for
|
||||
* the first glyph of the pair */
|
||||
typename Types::template OffsetTo<ClassDef>
|
||||
classDef2; /* Offset to ClassDef table--from
|
||||
* beginning of PairPos subtable--for
|
||||
* the second glyph of the pair */
|
||||
HBUINT16 class1Count; /* Number of classes in ClassDef1
|
||||
* table--includes Class0 */
|
||||
HBUINT16 class2Count; /* Number of classes in ClassDef2
|
||||
* table--includes Class0 */
|
||||
ValueRecord values; /* Matrix of value pairs:
|
||||
* class1-major, class2-minor,
|
||||
* Each entry has value1 and value2 */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (10 + 3 * Types::size, values);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!(c->check_struct (this)
|
||||
&& coverage.sanitize (c, this)
|
||||
&& classDef1.sanitize (c, this)
|
||||
&& classDef2.sanitize (c, this))) return_trace (false);
|
||||
|
||||
unsigned int len1 = valueFormat1.get_len ();
|
||||
unsigned int len2 = valueFormat2.get_len ();
|
||||
unsigned int stride = HBUINT16::static_size * (len1 + len2);
|
||||
unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
|
||||
unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
|
||||
return_trace (c->check_range ((const void *) values,
|
||||
count,
|
||||
record_size) &&
|
||||
valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
|
||||
valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
return (this+coverage).intersects (glyphs) &&
|
||||
(this+classDef2).intersects (glyphs);
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
if (!intersects (c->glyph_set)) return;
|
||||
if ((!valueFormat1.has_device ()) && (!valueFormat2.has_device ())) return;
|
||||
|
||||
hb_set_t klass1_glyphs, klass2_glyphs;
|
||||
if (!(this+classDef1).collect_coverage (&klass1_glyphs)) return;
|
||||
if (!(this+classDef2).collect_coverage (&klass2_glyphs)) return;
|
||||
|
||||
hb_set_t class1_set, class2_set;
|
||||
for (const unsigned cp : + c->glyph_set->iter () | hb_filter (this + coverage))
|
||||
{
|
||||
if (!klass1_glyphs.has (cp)) class1_set.add (0);
|
||||
else
|
||||
{
|
||||
unsigned klass1 = (this+classDef1).get (cp);
|
||||
class1_set.add (klass1);
|
||||
}
|
||||
}
|
||||
|
||||
class2_set.add (0);
|
||||
for (const unsigned cp : + c->glyph_set->iter () | hb_filter (klass2_glyphs))
|
||||
{
|
||||
unsigned klass2 = (this+classDef2).get (cp);
|
||||
class2_set.add (klass2);
|
||||
}
|
||||
|
||||
if (class1_set.is_empty ()
|
||||
|| class2_set.is_empty ()
|
||||
|| (class2_set.get_population() == 1 && class2_set.has(0)))
|
||||
return;
|
||||
|
||||
unsigned len1 = valueFormat1.get_len ();
|
||||
unsigned len2 = valueFormat2.get_len ();
|
||||
const hb_array_t<const Value> values_array = values.as_array ((unsigned)class1Count * (unsigned) class2Count * (len1 + len2));
|
||||
for (const unsigned class1_idx : class1_set.iter ())
|
||||
{
|
||||
for (const unsigned class2_idx : class2_set.iter ())
|
||||
{
|
||||
unsigned start_offset = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
|
||||
if (valueFormat1.has_device ())
|
||||
valueFormat1.collect_variation_indices (c, this, values_array.sub_array (start_offset, len1));
|
||||
|
||||
if (valueFormat2.has_device ())
|
||||
valueFormat2.collect_variation_indices (c, this, values_array.sub_array (start_offset+len1, len2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{
|
||||
if (unlikely (!(this+coverage).collect_coverage (c->input))) return;
|
||||
if (unlikely (!(this+classDef2).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;
|
||||
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
|
||||
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
unsigned unsafe_to;
|
||||
if (!skippy_iter.next (&unsafe_to))
|
||||
{
|
||||
buffer->unsafe_to_concat (buffer->idx, unsafe_to);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned int len1 = valueFormat1.get_len ();
|
||||
unsigned int len2 = valueFormat2.get_len ();
|
||||
unsigned int record_len = len1 + len2;
|
||||
|
||||
unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
|
||||
unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
|
||||
if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
|
||||
{
|
||||
buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
|
||||
|
||||
bool applied_first = false, applied_second = false;
|
||||
|
||||
|
||||
/* Isolate simple kerning and apply it half to each side.
|
||||
* Results in better cursor positinoing / underline drawing.
|
||||
*
|
||||
* Disabled, because causes issues... :-(
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/3408
|
||||
* https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
|
||||
*/
|
||||
#ifndef HB_SPLIT_KERN
|
||||
if (0)
|
||||
#endif
|
||||
{
|
||||
if (!len2)
|
||||
{
|
||||
const hb_direction_t dir = buffer->props.direction;
|
||||
const bool horizontal = HB_DIRECTION_IS_HORIZONTAL (dir);
|
||||
const bool backward = HB_DIRECTION_IS_BACKWARD (dir);
|
||||
unsigned mask = horizontal ? ValueFormat::xAdvance : ValueFormat::yAdvance;
|
||||
if (backward)
|
||||
mask |= mask >> 2; /* Add eg. xPlacement in RTL. */
|
||||
/* Add Devices. */
|
||||
mask |= mask << 4;
|
||||
|
||||
if (valueFormat1 & ~mask)
|
||||
goto bail;
|
||||
|
||||
/* Is simple kern. Apply value on an empty position slot,
|
||||
* then split it between sides. */
|
||||
|
||||
hb_glyph_position_t pos{};
|
||||
if (valueFormat1.apply_value (c, this, v, pos))
|
||||
{
|
||||
hb_position_t *src = &pos.x_advance;
|
||||
hb_position_t *dst1 = &buffer->cur_pos().x_advance;
|
||||
hb_position_t *dst2 = &buffer->pos[skippy_iter.idx].x_advance;
|
||||
unsigned i = horizontal ? 0 : 1;
|
||||
|
||||
hb_position_t kern = src[i];
|
||||
hb_position_t kern1 = kern >> 1;
|
||||
hb_position_t kern2 = kern - kern1;
|
||||
|
||||
if (!backward)
|
||||
{
|
||||
dst1[i] += kern1;
|
||||
dst2[i] += kern2;
|
||||
dst2[i + 2] += kern2;
|
||||
}
|
||||
else
|
||||
{
|
||||
dst1[i] += kern1;
|
||||
dst1[i + 2] += src[i + 2] - kern2;
|
||||
dst2[i] += kern2;
|
||||
}
|
||||
|
||||
applied_first = applied_second = kern != 0;
|
||||
goto success;
|
||||
}
|
||||
goto boring;
|
||||
}
|
||||
}
|
||||
bail:
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"try kerning glyphs at %u,%u",
|
||||
c->buffer->idx, skippy_iter.idx);
|
||||
}
|
||||
|
||||
applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
|
||||
applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
|
||||
|
||||
if (applied_first || applied_second)
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"kerned glyphs at %u,%u",
|
||||
c->buffer->idx, skippy_iter.idx);
|
||||
}
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"tried kerning glyphs at %u,%u",
|
||||
c->buffer->idx, skippy_iter.idx);
|
||||
}
|
||||
|
||||
success:
|
||||
if (applied_first || applied_second)
|
||||
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
|
||||
else
|
||||
boring:
|
||||
buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
|
||||
|
||||
if (len2)
|
||||
{
|
||||
skippy_iter.idx++;
|
||||
// https://github.com/harfbuzz/harfbuzz/issues/3824
|
||||
// https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
|
||||
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
|
||||
}
|
||||
|
||||
buffer->idx = skippy_iter.idx;
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
hb_map_t klass1_map;
|
||||
out->classDef1.serialize_subset (c, classDef1, this, &klass1_map, true, true, &(this + coverage));
|
||||
out->class1Count = klass1_map.get_population ();
|
||||
|
||||
hb_map_t klass2_map;
|
||||
out->classDef2.serialize_subset (c, classDef2, this, &klass2_map, true, false);
|
||||
out->class2Count = klass2_map.get_population ();
|
||||
|
||||
unsigned len1 = valueFormat1.get_len ();
|
||||
unsigned len2 = valueFormat2.get_len ();
|
||||
|
||||
hb_pair_t<unsigned, unsigned> newFormats = hb_pair (valueFormat1, valueFormat2);
|
||||
if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
||||
newFormats = compute_effective_value_formats (klass1_map, klass2_map);
|
||||
|
||||
out->valueFormat1 = newFormats.first;
|
||||
out->valueFormat2 = newFormats.second;
|
||||
|
||||
if (c->plan->all_axes_pinned)
|
||||
{
|
||||
out->valueFormat1 = out->valueFormat1.drop_device_table_flags ();
|
||||
out->valueFormat2 = out->valueFormat2.drop_device_table_flags ();
|
||||
}
|
||||
|
||||
for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
|
||||
{
|
||||
for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
|
||||
{
|
||||
unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * (len1 + len2);
|
||||
valueFormat1.copy_values (c->serializer, out->valueFormat1, this, &values[idx], &c->plan->layout_variation_idx_delta_map);
|
||||
valueFormat2.copy_values (c->serializer, out->valueFormat2, this, &values[idx + len1], &c->plan->layout_variation_idx_delta_map);
|
||||
}
|
||||
}
|
||||
|
||||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||
|
||||
auto it =
|
||||
+ hb_iter (this+coverage)
|
||||
| hb_filter (glyphset)
|
||||
| hb_map_retains_sorting (glyph_map)
|
||||
;
|
||||
|
||||
out->coverage.serialize_serialize (c->serializer, it);
|
||||
return_trace (out->class1Count && out->class2Count && bool (it));
|
||||
}
|
||||
|
||||
|
||||
hb_pair_t<unsigned, unsigned> compute_effective_value_formats (const hb_map_t& klass1_map,
|
||||
const hb_map_t& klass2_map) const
|
||||
{
|
||||
unsigned len1 = valueFormat1.get_len ();
|
||||
unsigned len2 = valueFormat2.get_len ();
|
||||
unsigned record_size = len1 + len2;
|
||||
|
||||
unsigned format1 = 0;
|
||||
unsigned format2 = 0;
|
||||
|
||||
for (unsigned class1_idx : + hb_range ((unsigned) class1Count) | hb_filter (klass1_map))
|
||||
{
|
||||
for (unsigned class2_idx : + hb_range ((unsigned) class2Count) | hb_filter (klass2_map))
|
||||
{
|
||||
unsigned idx = (class1_idx * (unsigned) class2Count + class2_idx) * record_size;
|
||||
format1 = format1 | valueFormat1.get_effective_format (&values[idx]);
|
||||
format2 = format2 | valueFormat2.get_effective_format (&values[idx + len1]);
|
||||
}
|
||||
|
||||
if (format1 == valueFormat1 && format2 == valueFormat2)
|
||||
break;
|
||||
}
|
||||
|
||||
return hb_pair (format1, format2);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_PAIRPOSFORMAT2_HH
|
|
@ -1,207 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_PAIRSET_HH
|
||||
#define OT_LAYOUT_GPOS_PAIRSET_HH
|
||||
|
||||
#include "PairValueRecord.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
|
||||
template <typename Types>
|
||||
struct PairSet
|
||||
{
|
||||
template <typename Types2>
|
||||
friend struct PairPosFormat1_3;
|
||||
|
||||
using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
|
||||
|
||||
protected:
|
||||
HBUINT16 len; /* Number of PairValueRecords */
|
||||
PairValueRecord firstPairValueRecord;
|
||||
/* Array of PairValueRecords--ordered
|
||||
* by GlyphID of the second glyph */
|
||||
public:
|
||||
DEFINE_SIZE_MIN (2);
|
||||
|
||||
static unsigned get_size (unsigned len1, unsigned len2)
|
||||
{
|
||||
return Types::HBGlyphID::static_size + Value::static_size * (len1 + len2);
|
||||
}
|
||||
static unsigned get_size (const ValueFormat valueFormats[2])
|
||||
{
|
||||
unsigned len1 = valueFormats[0].get_len ();
|
||||
unsigned len2 = valueFormats[1].get_len ();
|
||||
return get_size (len1, len2);
|
||||
}
|
||||
|
||||
struct sanitize_closure_t
|
||||
{
|
||||
const ValueFormat *valueFormats;
|
||||
unsigned int len1; /* valueFormats[0].get_len() */
|
||||
unsigned int stride; /* bytes */
|
||||
};
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c, const sanitize_closure_t *closure) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!(c->check_struct (this)
|
||||
&& c->check_range (&firstPairValueRecord,
|
||||
len,
|
||||
closure->stride))) return_trace (false);
|
||||
|
||||
unsigned int count = len;
|
||||
const PairValueRecord *record = &firstPairValueRecord;
|
||||
return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, this, &record->values[0], count, closure->stride) &&
|
||||
closure->valueFormats[1].sanitize_values_stride_unsafe (c, this, &record->values[closure->len1], count, closure->stride));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs,
|
||||
const ValueFormat *valueFormats) const
|
||||
{
|
||||
unsigned record_size = get_size (valueFormats);
|
||||
|
||||
const PairValueRecord *record = &firstPairValueRecord;
|
||||
unsigned int count = len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (glyphs->has (record->secondGlyph))
|
||||
return true;
|
||||
record = &StructAtOffset<const PairValueRecord> (record, record_size);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c,
|
||||
const ValueFormat *valueFormats) const
|
||||
{
|
||||
unsigned record_size = get_size (valueFormats);
|
||||
|
||||
const PairValueRecord *record = &firstPairValueRecord;
|
||||
c->input->add_array (&record->secondGlyph, len, record_size);
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
||||
const ValueFormat *valueFormats) const
|
||||
{
|
||||
unsigned record_size = get_size (valueFormats);
|
||||
|
||||
const PairValueRecord *record = &firstPairValueRecord;
|
||||
unsigned count = len;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
if (c->glyph_set->has (record->secondGlyph))
|
||||
{ record->collect_variation_indices (c, valueFormats, this); }
|
||||
|
||||
record = &StructAtOffset<const PairValueRecord> (record, record_size);
|
||||
}
|
||||
}
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c,
|
||||
const ValueFormat *valueFormats,
|
||||
unsigned int pos) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
unsigned int len1 = valueFormats[0].get_len ();
|
||||
unsigned int len2 = valueFormats[1].get_len ();
|
||||
unsigned record_size = get_size (len1, len2);
|
||||
|
||||
const PairValueRecord *record = hb_bsearch (buffer->info[pos].codepoint,
|
||||
&firstPairValueRecord,
|
||||
len,
|
||||
record_size);
|
||||
if (record)
|
||||
{
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"try kerning glyphs at %u,%u",
|
||||
c->buffer->idx, pos);
|
||||
}
|
||||
|
||||
bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
|
||||
bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
|
||||
|
||||
if (applied_first || applied_second)
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"kerned glyphs at %u,%u",
|
||||
c->buffer->idx, pos);
|
||||
}
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"tried kerning glyphs at %u,%u",
|
||||
c->buffer->idx, pos);
|
||||
}
|
||||
|
||||
if (applied_first || applied_second)
|
||||
buffer->unsafe_to_break (buffer->idx, pos + 1);
|
||||
|
||||
if (len2)
|
||||
{
|
||||
pos++;
|
||||
// https://github.com/harfbuzz/harfbuzz/issues/3824
|
||||
// https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
|
||||
buffer->unsafe_to_break (buffer->idx, pos + 1);
|
||||
}
|
||||
|
||||
buffer->idx = pos;
|
||||
return_trace (true);
|
||||
}
|
||||
buffer->unsafe_to_concat (buffer->idx, pos + 1);
|
||||
return_trace (false);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c,
|
||||
const ValueFormat valueFormats[2],
|
||||
const ValueFormat newFormats[2]) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto snap = c->serializer->snapshot ();
|
||||
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||
out->len = 0;
|
||||
|
||||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||
|
||||
unsigned len1 = valueFormats[0].get_len ();
|
||||
unsigned len2 = valueFormats[1].get_len ();
|
||||
unsigned record_size = get_size (len1, len2);
|
||||
|
||||
typename PairValueRecord::context_t context =
|
||||
{
|
||||
this,
|
||||
valueFormats,
|
||||
newFormats,
|
||||
len1,
|
||||
&glyph_map,
|
||||
&c->plan->layout_variation_idx_delta_map
|
||||
};
|
||||
|
||||
const PairValueRecord *record = &firstPairValueRecord;
|
||||
unsigned count = len, num = 0;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
if (glyphset.has (record->secondGlyph)
|
||||
&& record->subset (c, &context)) num++;
|
||||
record = &StructAtOffset<const PairValueRecord> (record, record_size);
|
||||
}
|
||||
|
||||
out->len = num;
|
||||
if (!num) c->serializer->revert (snap);
|
||||
return_trace (num);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_PAIRSET_HH
|
|
@ -1,99 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
|
||||
#define OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
|
||||
|
||||
#include "ValueFormat.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
|
||||
template <typename Types>
|
||||
struct PairValueRecord
|
||||
{
|
||||
template <typename Types2>
|
||||
friend struct PairSet;
|
||||
|
||||
protected:
|
||||
typename Types::HBGlyphID
|
||||
secondGlyph; /* GlyphID of second glyph in the
|
||||
* pair--first glyph is listed in the
|
||||
* Coverage table */
|
||||
ValueRecord values; /* Positioning data for the first glyph
|
||||
* followed by for second glyph */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (Types::size, values);
|
||||
|
||||
int cmp (hb_codepoint_t k) const
|
||||
{ return secondGlyph.cmp (k); }
|
||||
|
||||
struct context_t
|
||||
{
|
||||
const void *base;
|
||||
const ValueFormat *valueFormats;
|
||||
const ValueFormat *newFormats;
|
||||
unsigned len1; /* valueFormats[0].get_len() */
|
||||
const hb_map_t *glyph_map;
|
||||
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map;
|
||||
};
|
||||
|
||||
bool subset (hb_subset_context_t *c,
|
||||
context_t *closure) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto *s = c->serializer;
|
||||
auto *out = s->start_embed (*this);
|
||||
if (unlikely (!s->extend_min (out))) return_trace (false);
|
||||
|
||||
out->secondGlyph = (*closure->glyph_map)[secondGlyph];
|
||||
|
||||
closure->valueFormats[0].copy_values (s,
|
||||
closure->newFormats[0],
|
||||
closure->base, &values[0],
|
||||
closure->layout_variation_idx_delta_map);
|
||||
closure->valueFormats[1].copy_values (s,
|
||||
closure->newFormats[1],
|
||||
closure->base,
|
||||
&values[closure->len1],
|
||||
closure->layout_variation_idx_delta_map);
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
||||
const ValueFormat *valueFormats,
|
||||
const void *base) const
|
||||
{
|
||||
unsigned record1_len = valueFormats[0].get_len ();
|
||||
unsigned record2_len = valueFormats[1].get_len ();
|
||||
const hb_array_t<const Value> values_array = values.as_array (record1_len + record2_len);
|
||||
|
||||
if (valueFormats[0].has_device ())
|
||||
valueFormats[0].collect_variation_indices (c, base, values_array.sub_array (0, record1_len));
|
||||
|
||||
if (valueFormats[1].has_device ())
|
||||
valueFormats[1].collect_variation_indices (c, base, values_array.sub_array (record1_len, record2_len));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t& glyphset) const
|
||||
{
|
||||
return glyphset.has(secondGlyph);
|
||||
}
|
||||
|
||||
const Value* get_values_1 () const
|
||||
{
|
||||
return &values[0];
|
||||
}
|
||||
|
||||
const Value* get_values_2 (ValueFormat format1) const
|
||||
{
|
||||
return &values[format1.get_len ()];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // OT_LAYOUT_GPOS_PAIRVALUERECORD_HH
|
|
@ -1,79 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_POSLOOKUP_HH
|
||||
#define OT_LAYOUT_GPOS_POSLOOKUP_HH
|
||||
|
||||
#include "PosLookupSubTable.hh"
|
||||
#include "../../../hb-ot-layout-common.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct PosLookup : Lookup
|
||||
{
|
||||
using SubTable = PosLookupSubTable;
|
||||
|
||||
const SubTable& get_subtable (unsigned int i) const
|
||||
{ return Lookup::get_subtable<SubTable> (i); }
|
||||
|
||||
bool is_reverse () const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
return_trace (dispatch (c));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{
|
||||
hb_intersects_context_t c (glyphs);
|
||||
return dispatch (&c);
|
||||
}
|
||||
|
||||
hb_collect_glyphs_context_t::return_t collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{ return dispatch (c); }
|
||||
|
||||
hb_closure_lookups_context_t::return_t closure_lookups (hb_closure_lookups_context_t *c, unsigned this_index) const
|
||||
{
|
||||
if (c->is_lookup_visited (this_index))
|
||||
return hb_closure_lookups_context_t::default_return_value ();
|
||||
|
||||
c->set_lookup_visited (this_index);
|
||||
if (!intersects (c->glyphs))
|
||||
{
|
||||
c->set_lookup_inactive (this_index);
|
||||
return hb_closure_lookups_context_t::default_return_value ();
|
||||
}
|
||||
|
||||
hb_closure_lookups_context_t::return_t ret = dispatch (c);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename set_t>
|
||||
void collect_coverage (set_t *glyphs) const
|
||||
{
|
||||
hb_collect_coverage_context_t<set_t> c (glyphs);
|
||||
dispatch (&c);
|
||||
}
|
||||
|
||||
template <typename context_t>
|
||||
static typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
|
||||
|
||||
template <typename context_t, typename ...Ts>
|
||||
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
|
||||
{ return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{ return Lookup::subset<SubTable> (c); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{ return Lookup::sanitize<SubTable> (c); }
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_POSLOOKUP_HH */
|
|
@ -1,79 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH
|
||||
#define OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH
|
||||
|
||||
#include "SinglePos.hh"
|
||||
#include "PairPos.hh"
|
||||
#include "CursivePos.hh"
|
||||
#include "MarkBasePos.hh"
|
||||
#include "MarkLigPos.hh"
|
||||
#include "MarkMarkPos.hh"
|
||||
#include "ContextPos.hh"
|
||||
#include "ChainContextPos.hh"
|
||||
#include "ExtensionPos.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct PosLookupSubTable
|
||||
{
|
||||
friend struct ::OT::Lookup;
|
||||
friend struct PosLookup;
|
||||
|
||||
enum Type {
|
||||
Single = 1,
|
||||
Pair = 2,
|
||||
Cursive = 3,
|
||||
MarkBase = 4,
|
||||
MarkLig = 5,
|
||||
MarkMark = 6,
|
||||
Context = 7,
|
||||
ChainContext = 8,
|
||||
Extension = 9
|
||||
};
|
||||
|
||||
template <typename context_t, typename ...Ts>
|
||||
typename context_t::return_t dispatch (context_t *c, unsigned int lookup_type, Ts&&... ds) const
|
||||
{
|
||||
TRACE_DISPATCH (this, lookup_type);
|
||||
switch (lookup_type) {
|
||||
case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
|
||||
case Pair: return_trace (u.pair.dispatch (c, std::forward<Ts> (ds)...));
|
||||
case Cursive: return_trace (u.cursive.dispatch (c, std::forward<Ts> (ds)...));
|
||||
case MarkBase: return_trace (u.markBase.dispatch (c, std::forward<Ts> (ds)...));
|
||||
case MarkLig: return_trace (u.markLig.dispatch (c, std::forward<Ts> (ds)...));
|
||||
case MarkMark: return_trace (u.markMark.dispatch (c, std::forward<Ts> (ds)...));
|
||||
case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
|
||||
case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
|
||||
case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
|
||||
default: return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
|
||||
{
|
||||
hb_intersects_context_t c (glyphs);
|
||||
return dispatch (&c, lookup_type);
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
SinglePos single;
|
||||
PairPos pair;
|
||||
CursivePos cursive;
|
||||
MarkBasePos markBase;
|
||||
MarkLigPos markLig;
|
||||
MarkMarkPos markMark;
|
||||
ContextPos context;
|
||||
ChainContextPos chainContext;
|
||||
ExtensionPos extension;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_MIN (0);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* HB_OT_LAYOUT_GPOS_POSLOOKUPSUBTABLE_HH */
|
|
@ -1,100 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_SINGLEPOS_HH
|
||||
#define OT_LAYOUT_GPOS_SINGLEPOS_HH
|
||||
|
||||
#include "SinglePosFormat1.hh"
|
||||
#include "SinglePosFormat2.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct SinglePos
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
SinglePosFormat1 format1;
|
||||
SinglePosFormat2 format2;
|
||||
} u;
|
||||
|
||||
public:
|
||||
template<typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
unsigned get_format (Iterator glyph_val_iter_pairs)
|
||||
{
|
||||
hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs);
|
||||
|
||||
for (const auto iter : glyph_val_iter_pairs)
|
||||
for (const auto _ : hb_zip (iter.second, first_val_iter))
|
||||
if (_.first != _.second)
|
||||
return 2;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
template<typename Iterator,
|
||||
typename SrcLookup,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
void serialize (hb_serialize_context_t *c,
|
||||
const SrcLookup* src,
|
||||
Iterator glyph_val_iter_pairs,
|
||||
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
|
||||
bool all_axes_pinned)
|
||||
{
|
||||
if (unlikely (!c->extend_min (u.format))) return;
|
||||
unsigned format = 2;
|
||||
ValueFormat new_format = src->get_value_format ();
|
||||
|
||||
if (all_axes_pinned)
|
||||
new_format = new_format.drop_device_table_flags ();
|
||||
|
||||
if (glyph_val_iter_pairs)
|
||||
format = get_format (glyph_val_iter_pairs);
|
||||
|
||||
u.format = format;
|
||||
switch (u.format) {
|
||||
case 1: u.format1.serialize (c,
|
||||
src,
|
||||
glyph_val_iter_pairs,
|
||||
new_format,
|
||||
layout_variation_idx_delta_map);
|
||||
return;
|
||||
case 2: u.format2.serialize (c,
|
||||
src,
|
||||
glyph_val_iter_pairs,
|
||||
new_format,
|
||||
layout_variation_idx_delta_map);
|
||||
return;
|
||||
default:return;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename context_t, typename ...Ts>
|
||||
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
|
||||
{
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
|
||||
TRACE_DISPATCH (this, u.format);
|
||||
switch (u.format) {
|
||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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)
|
||||
{ c->start_embed<SinglePos> ()->serialize (c, src, it, layout_variation_idx_delta_map, all_axes_pinned); }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_SINGLEPOS_HH */
|
|
@ -1,164 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH
|
||||
#define OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH
|
||||
|
||||
#include "Common.hh"
|
||||
#include "ValueFormat.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct SinglePosFormat1
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
Offset16To<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of subtable */
|
||||
ValueFormat valueFormat; /* Defines the types of data in the
|
||||
* ValueRecord */
|
||||
ValueRecord values; /* Defines positioning
|
||||
* value(s)--applied to all glyphs in
|
||||
* the Coverage table */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, values);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
coverage.sanitize (c, this) &&
|
||||
/* The coverage table may use a range to represent a set
|
||||
* of glyphs, which means a small number of bytes can
|
||||
* generate a large glyph set. Manually modify the
|
||||
* sanitizer max ops to take this into account.
|
||||
*
|
||||
* Note: This check *must* be right after coverage sanitize. */
|
||||
c->check_ops ((this + coverage).get_population () >> 1) &&
|
||||
valueFormat.sanitize_value (c, this, values));
|
||||
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{ return (this+coverage).intersects (glyphs); }
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
if (!valueFormat.has_device ()) return;
|
||||
|
||||
hb_set_t intersection;
|
||||
(this+coverage).intersect_set (*c->glyph_set, intersection);
|
||||
if (!intersection) return;
|
||||
|
||||
valueFormat.collect_variation_indices (c, this, values.as_array (valueFormat.get_len ()));
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{ if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
|
||||
|
||||
const Coverage &get_coverage () const { return this+coverage; }
|
||||
|
||||
ValueFormat get_value_format () const { return valueFormat; }
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
|
||||
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"positioning glyph at %u",
|
||||
c->buffer->idx);
|
||||
}
|
||||
|
||||
valueFormat.apply_value (c, this, values, buffer->cur_pos());
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"positioned glyph at %u",
|
||||
c->buffer->idx);
|
||||
}
|
||||
|
||||
buffer->idx++;
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool
|
||||
position_single (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t gid,
|
||||
hb_glyph_position_t &pos) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (gid);
|
||||
if (likely (index == NOT_COVERED)) return false;
|
||||
|
||||
/* This is ugly... */
|
||||
hb_buffer_t buffer;
|
||||
buffer.props.direction = direction;
|
||||
OT::hb_ot_apply_context_t c (1, font, &buffer);
|
||||
|
||||
valueFormat.apply_value (&c, this, values, pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename Iterator,
|
||||
typename SrcLookup,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
void serialize (hb_serialize_context_t *c,
|
||||
const SrcLookup *src,
|
||||
Iterator it,
|
||||
ValueFormat newFormat,
|
||||
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map)
|
||||
{
|
||||
if (unlikely (!c->extend_min (this))) return;
|
||||
if (unlikely (!c->check_assign (valueFormat,
|
||||
newFormat,
|
||||
HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
|
||||
|
||||
for (const hb_array_t<const Value>& _ : + it | hb_map (hb_second))
|
||||
{
|
||||
src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_map);
|
||||
// Only serialize the first entry in the iterator, the rest are assumed to
|
||||
// be the same.
|
||||
break;
|
||||
}
|
||||
|
||||
auto glyphs =
|
||||
+ it
|
||||
| hb_map_retains_sorting (hb_first)
|
||||
;
|
||||
|
||||
coverage.serialize_serialize (c, 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;
|
||||
|
||||
hb_set_t intersection;
|
||||
(this+coverage).intersect_set (glyphset, intersection);
|
||||
|
||||
auto it =
|
||||
+ hb_iter (intersection)
|
||||
| hb_map_retains_sorting (glyph_map)
|
||||
| hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
|
||||
;
|
||||
|
||||
bool ret = bool (it);
|
||||
SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
|
||||
return_trace (ret);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_SINGLEPOSFORMAT1_HH */
|
|
@ -1,176 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH
|
||||
#define OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH
|
||||
|
||||
#include "Common.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
struct SinglePosFormat2
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 2 */
|
||||
Offset16To<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of subtable */
|
||||
ValueFormat valueFormat; /* Defines the types of data in the
|
||||
* ValueRecord */
|
||||
HBUINT16 valueCount; /* Number of ValueRecords */
|
||||
ValueRecord values; /* Array of ValueRecords--positioning
|
||||
* values applied to glyphs */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, values);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
coverage.sanitize (c, this) &&
|
||||
valueFormat.sanitize_values (c, this, values, valueCount));
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{ return (this+coverage).intersects (glyphs); }
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
|
||||
{
|
||||
if (!valueFormat.has_device ()) return;
|
||||
|
||||
auto it =
|
||||
+ hb_zip (this+coverage, hb_range ((unsigned) valueCount))
|
||||
| hb_filter (c->glyph_set, hb_first)
|
||||
;
|
||||
|
||||
if (!it) return;
|
||||
|
||||
unsigned sub_length = valueFormat.get_len ();
|
||||
const hb_array_t<const Value> values_array = values.as_array (valueCount * sub_length);
|
||||
|
||||
for (unsigned i : + it
|
||||
| hb_map (hb_second))
|
||||
valueFormat.collect_variation_indices (c, this, values_array.sub_array (i * sub_length, sub_length));
|
||||
|
||||
}
|
||||
|
||||
void collect_glyphs (hb_collect_glyphs_context_t *c) const
|
||||
{ if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
|
||||
|
||||
const Coverage &get_coverage () const { return this+coverage; }
|
||||
|
||||
ValueFormat get_value_format () const { return valueFormat; }
|
||||
|
||||
bool apply (hb_ot_apply_context_t *c) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
|
||||
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
if (unlikely (index >= valueCount)) return_trace (false);
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"positioning glyph at %u",
|
||||
c->buffer->idx);
|
||||
}
|
||||
|
||||
valueFormat.apply_value (c, this,
|
||||
&values[index * valueFormat.get_len ()],
|
||||
buffer->cur_pos());
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"positioned glyph at %u",
|
||||
c->buffer->idx);
|
||||
}
|
||||
|
||||
buffer->idx++;
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
bool
|
||||
position_single (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_codepoint_t gid,
|
||||
hb_glyph_position_t &pos) const
|
||||
{
|
||||
unsigned int index = (this+coverage).get_coverage (gid);
|
||||
if (likely (index == NOT_COVERED)) return false;
|
||||
if (unlikely (index >= valueCount)) return false;
|
||||
|
||||
/* This is ugly... */
|
||||
hb_buffer_t buffer;
|
||||
buffer.props.direction = direction;
|
||||
OT::hb_ot_apply_context_t c (1, font, &buffer);
|
||||
|
||||
valueFormat.apply_value (&c, this,
|
||||
&values[index * valueFormat.get_len ()],
|
||||
pos);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
template<typename Iterator,
|
||||
typename SrcLookup,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
void serialize (hb_serialize_context_t *c,
|
||||
const SrcLookup *src,
|
||||
Iterator it,
|
||||
ValueFormat newFormat,
|
||||
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map)
|
||||
{
|
||||
auto out = c->extend_min (this);
|
||||
if (unlikely (!out)) return;
|
||||
if (unlikely (!c->check_assign (valueFormat, newFormat, HB_SERIALIZE_ERROR_INT_OVERFLOW))) return;
|
||||
if (unlikely (!c->check_assign (valueCount, it.len (), HB_SERIALIZE_ERROR_ARRAY_OVERFLOW))) return;
|
||||
|
||||
+ it
|
||||
| hb_map (hb_second)
|
||||
| hb_apply ([&] (hb_array_t<const Value> _)
|
||||
{ src->get_value_format ().copy_values (c, newFormat, src, &_, layout_variation_idx_delta_map); })
|
||||
;
|
||||
|
||||
auto glyphs =
|
||||
+ it
|
||||
| hb_map_retains_sorting (hb_first)
|
||||
;
|
||||
|
||||
coverage.serialize_serialize (c, 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;
|
||||
|
||||
unsigned sub_length = valueFormat.get_len ();
|
||||
auto values_array = values.as_array (valueCount * sub_length);
|
||||
|
||||
auto it =
|
||||
+ hb_zip (this+coverage, hb_range ((unsigned) valueCount))
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _)
|
||||
{
|
||||
return hb_pair (glyph_map[_.first],
|
||||
values_array.sub_array (_.second * sub_length,
|
||||
sub_length));
|
||||
})
|
||||
;
|
||||
|
||||
bool ret = bool (it);
|
||||
SinglePos_serialize (c->serializer, this, it, &c->plan->layout_variation_idx_delta_map, c->plan->all_axes_pinned);
|
||||
return_trace (ret);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OT_LAYOUT_GPOS_SINGLEPOSFORMAT2_HH */
|
|
@ -1,394 +0,0 @@
|
|||
#ifndef OT_LAYOUT_GPOS_VALUEFORMAT_HH
|
||||
#define OT_LAYOUT_GPOS_VALUEFORMAT_HH
|
||||
|
||||
#include "../../../hb-ot-layout-gsubgpos.hh"
|
||||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GPOS_impl {
|
||||
|
||||
typedef HBUINT16 Value;
|
||||
|
||||
typedef UnsizedArrayOf<Value> ValueRecord;
|
||||
|
||||
struct ValueFormat : HBUINT16
|
||||
{
|
||||
enum Flags {
|
||||
xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */
|
||||
yPlacement = 0x0002u, /* Includes vertical adjustment for placement */
|
||||
xAdvance = 0x0004u, /* Includes horizontal adjustment for advance */
|
||||
yAdvance = 0x0008u, /* Includes vertical adjustment for advance */
|
||||
xPlaDevice = 0x0010u, /* Includes horizontal Device table for placement */
|
||||
yPlaDevice = 0x0020u, /* Includes vertical Device table for placement */
|
||||
xAdvDevice = 0x0040u, /* Includes horizontal Device table for advance */
|
||||
yAdvDevice = 0x0080u, /* Includes vertical Device table for advance */
|
||||
ignored = 0x0F00u, /* Was used in TrueType Open for MM fonts */
|
||||
reserved = 0xF000u, /* For future use */
|
||||
|
||||
devices = 0x00F0u /* Mask for having any Device table */
|
||||
};
|
||||
|
||||
/* All fields are options. Only those available advance the value pointer. */
|
||||
#if 0
|
||||
HBINT16 xPlacement; /* Horizontal adjustment for
|
||||
* placement--in design units */
|
||||
HBINT16 yPlacement; /* Vertical adjustment for
|
||||
* placement--in design units */
|
||||
HBINT16 xAdvance; /* Horizontal adjustment for
|
||||
* advance--in design units (only used
|
||||
* for horizontal writing) */
|
||||
HBINT16 yAdvance; /* Vertical adjustment for advance--in
|
||||
* design units (only used for vertical
|
||||
* writing) */
|
||||
Offset16To<Device> xPlaDevice; /* Offset to Device table for
|
||||
* horizontal placement--measured from
|
||||
* beginning of PosTable (may be NULL) */
|
||||
Offset16To<Device> yPlaDevice; /* Offset to Device table for vertical
|
||||
* placement--measured from beginning
|
||||
* of PosTable (may be NULL) */
|
||||
Offset16To<Device> xAdvDevice; /* Offset to Device table for
|
||||
* horizontal advance--measured from
|
||||
* beginning of PosTable (may be NULL) */
|
||||
Offset16To<Device> yAdvDevice; /* Offset to Device table for vertical
|
||||
* advance--measured from beginning of
|
||||
* PosTable (may be NULL) */
|
||||
#endif
|
||||
|
||||
IntType& operator = (uint16_t i) { v = i; return *this; }
|
||||
|
||||
unsigned int get_len () const { return hb_popcount ((unsigned int) *this); }
|
||||
unsigned int get_size () const { return get_len () * Value::static_size; }
|
||||
|
||||
hb_vector_t<unsigned> get_device_table_indices () const {
|
||||
unsigned i = 0;
|
||||
hb_vector_t<unsigned> result;
|
||||
unsigned format = *this;
|
||||
|
||||
if (format & xPlacement) i++;
|
||||
if (format & yPlacement) i++;
|
||||
if (format & xAdvance) i++;
|
||||
if (format & yAdvance) i++;
|
||||
|
||||
if (format & xPlaDevice) result.push (i++);
|
||||
if (format & yPlaDevice) result.push (i++);
|
||||
if (format & xAdvDevice) result.push (i++);
|
||||
if (format & yAdvDevice) result.push (i++);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool apply_value (hb_ot_apply_context_t *c,
|
||||
const void *base,
|
||||
const Value *values,
|
||||
hb_glyph_position_t &glyph_pos) const
|
||||
{
|
||||
bool ret = false;
|
||||
unsigned int format = *this;
|
||||
if (!format) return ret;
|
||||
|
||||
hb_font_t *font = c->font;
|
||||
bool horizontal =
|
||||
#ifndef HB_NO_VERTICAL
|
||||
HB_DIRECTION_IS_HORIZONTAL (c->direction)
|
||||
#else
|
||||
true
|
||||
#endif
|
||||
;
|
||||
|
||||
if (format & xPlacement) glyph_pos.x_offset += font->em_scale_x (get_short (values++, &ret));
|
||||
if (format & yPlacement) glyph_pos.y_offset += font->em_scale_y (get_short (values++, &ret));
|
||||
if (format & xAdvance) {
|
||||
if (likely (horizontal)) glyph_pos.x_advance += font->em_scale_x (get_short (values, &ret));
|
||||
values++;
|
||||
}
|
||||
/* y_advance values grow downward but font-space grows upward, hence negation */
|
||||
if (format & yAdvance) {
|
||||
if (unlikely (!horizontal)) glyph_pos.y_advance -= font->em_scale_y (get_short (values, &ret));
|
||||
values++;
|
||||
}
|
||||
|
||||
if (!has_device ()) return ret;
|
||||
|
||||
bool use_x_device = font->x_ppem || font->num_coords;
|
||||
bool use_y_device = font->y_ppem || font->num_coords;
|
||||
|
||||
if (!use_x_device && !use_y_device) return ret;
|
||||
|
||||
const VariationStore &store = c->var_store;
|
||||
auto *cache = c->var_store_cache;
|
||||
|
||||
/* pixel -> fractional pixel */
|
||||
if (format & xPlaDevice) {
|
||||
if (use_x_device) glyph_pos.x_offset += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
|
||||
values++;
|
||||
}
|
||||
if (format & yPlaDevice) {
|
||||
if (use_y_device) glyph_pos.y_offset += (base + get_device (values, &ret)).get_y_delta (font, store, cache);
|
||||
values++;
|
||||
}
|
||||
if (format & xAdvDevice) {
|
||||
if (horizontal && use_x_device) glyph_pos.x_advance += (base + get_device (values, &ret)).get_x_delta (font, store, cache);
|
||||
values++;
|
||||
}
|
||||
if (format & yAdvDevice) {
|
||||
/* y_advance values grow downward but font-space grows upward, hence negation */
|
||||
if (!horizontal && use_y_device) glyph_pos.y_advance -= (base + get_device (values, &ret)).get_y_delta (font, store, cache);
|
||||
values++;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int get_effective_format (const Value *values) const
|
||||
{
|
||||
unsigned int format = *this;
|
||||
for (unsigned flag = xPlacement; flag <= yAdvDevice; flag = flag << 1) {
|
||||
if (format & flag) should_drop (*values++, (Flags) flag, &format);
|
||||
}
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
template<typename Iterator,
|
||||
hb_requires (hb_is_iterator (Iterator))>
|
||||
unsigned int get_effective_format (Iterator it) const {
|
||||
unsigned int new_format = 0;
|
||||
|
||||
for (const hb_array_t<const Value>& values : it)
|
||||
new_format = new_format | get_effective_format (&values);
|
||||
|
||||
return new_format;
|
||||
}
|
||||
|
||||
void copy_values (hb_serialize_context_t *c,
|
||||
unsigned int new_format,
|
||||
const void *base,
|
||||
const Value *values,
|
||||
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const
|
||||
{
|
||||
unsigned int format = *this;
|
||||
if (!format) return;
|
||||
|
||||
HBINT16 *x_placement = nullptr, *y_placement = nullptr, *x_adv = nullptr, *y_adv = nullptr;
|
||||
if (format & xPlacement) x_placement = copy_value (c, new_format, xPlacement, *values++);
|
||||
if (format & yPlacement) y_placement = copy_value (c, new_format, yPlacement, *values++);
|
||||
if (format & xAdvance) x_adv = copy_value (c, new_format, xAdvance, *values++);
|
||||
if (format & yAdvance) y_adv = copy_value (c, new_format, yAdvance, *values++);
|
||||
|
||||
if (format & xPlaDevice)
|
||||
{
|
||||
add_delta_to_value (x_placement, base, values, layout_variation_idx_delta_map);
|
||||
copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, xPlaDevice);
|
||||
}
|
||||
|
||||
if (format & yPlaDevice)
|
||||
{
|
||||
add_delta_to_value (y_placement, base, values, layout_variation_idx_delta_map);
|
||||
copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, yPlaDevice);
|
||||
}
|
||||
|
||||
if (format & xAdvDevice)
|
||||
{
|
||||
add_delta_to_value (x_adv, base, values, layout_variation_idx_delta_map);
|
||||
copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, xAdvDevice);
|
||||
}
|
||||
|
||||
if (format & yAdvDevice)
|
||||
{
|
||||
add_delta_to_value (y_adv, base, values, layout_variation_idx_delta_map);
|
||||
copy_device (c, base, values++, layout_variation_idx_delta_map, new_format, yAdvDevice);
|
||||
}
|
||||
}
|
||||
|
||||
HBINT16* copy_value (hb_serialize_context_t *c,
|
||||
unsigned int new_format,
|
||||
Flags flag,
|
||||
Value value) const
|
||||
{
|
||||
// Filter by new format.
|
||||
if (!(new_format & flag)) return nullptr;
|
||||
return reinterpret_cast<HBINT16 *> (c->copy (value));
|
||||
}
|
||||
|
||||
void collect_variation_indices (hb_collect_variation_indices_context_t *c,
|
||||
const void *base,
|
||||
const hb_array_t<const Value>& values) const
|
||||
{
|
||||
unsigned format = *this;
|
||||
unsigned i = 0;
|
||||
if (format & xPlacement) i++;
|
||||
if (format & yPlacement) i++;
|
||||
if (format & xAdvance) i++;
|
||||
if (format & yAdvance) i++;
|
||||
if (format & xPlaDevice)
|
||||
{
|
||||
(base + get_device (&(values[i]))).collect_variation_indices (c);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (format & ValueFormat::yPlaDevice)
|
||||
{
|
||||
(base + get_device (&(values[i]))).collect_variation_indices (c);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (format & ValueFormat::xAdvDevice)
|
||||
{
|
||||
|
||||
(base + get_device (&(values[i]))).collect_variation_indices (c);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (format & ValueFormat::yAdvDevice)
|
||||
{
|
||||
|
||||
(base + get_device (&(values[i]))).collect_variation_indices (c);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned drop_device_table_flags () const
|
||||
{
|
||||
unsigned format = *this;
|
||||
for (unsigned flag = xPlaDevice; flag <= yAdvDevice; flag = flag << 1)
|
||||
format = format & ~flag;
|
||||
|
||||
return format;
|
||||
}
|
||||
|
||||
private:
|
||||
bool sanitize_value_devices (hb_sanitize_context_t *c, const void *base, const Value *values) const
|
||||
{
|
||||
unsigned int format = *this;
|
||||
|
||||
if (format & xPlacement) values++;
|
||||
if (format & yPlacement) values++;
|
||||
if (format & xAdvance) values++;
|
||||
if (format & yAdvance) values++;
|
||||
|
||||
if ((format & xPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
|
||||
if ((format & yPlaDevice) && !get_device (values++).sanitize (c, base)) return false;
|
||||
if ((format & xAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
|
||||
if ((format & yAdvDevice) && !get_device (values++).sanitize (c, base)) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline Offset16To<Device>& get_device (Value* value)
|
||||
{
|
||||
return *static_cast<Offset16To<Device> *> (value);
|
||||
}
|
||||
static inline const Offset16To<Device>& get_device (const Value* value, bool *worked=nullptr)
|
||||
{
|
||||
if (worked) *worked |= bool (*value);
|
||||
return *static_cast<const Offset16To<Device> *> (value);
|
||||
}
|
||||
|
||||
void add_delta_to_value (HBINT16 *value,
|
||||
const void *base,
|
||||
const Value *src_value,
|
||||
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map) const
|
||||
{
|
||||
if (!value) return;
|
||||
unsigned varidx = (base + get_device (src_value)).get_variation_index ();
|
||||
hb_pair_t<unsigned, int> *varidx_delta;
|
||||
if (!layout_variation_idx_delta_map->has (varidx, &varidx_delta)) return;
|
||||
|
||||
*value += hb_second (*varidx_delta);
|
||||
}
|
||||
|
||||
bool copy_device (hb_serialize_context_t *c, const void *base,
|
||||
const Value *src_value,
|
||||
const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
|
||||
unsigned int new_format, Flags flag) const
|
||||
{
|
||||
// Filter by new format.
|
||||
if (!(new_format & flag)) return true;
|
||||
|
||||
Value *dst_value = c->copy (*src_value);
|
||||
|
||||
if (!dst_value) return false;
|
||||
if (*dst_value == 0) return true;
|
||||
|
||||
*dst_value = 0;
|
||||
c->push ();
|
||||
if ((base + get_device (src_value)).copy (c, layout_variation_idx_delta_map))
|
||||
{
|
||||
c->add_link (*dst_value, c->pop_pack ());
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
c->pop_discard ();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static inline const HBINT16& get_short (const Value* value, bool *worked=nullptr)
|
||||
{
|
||||
if (worked) *worked |= bool (*value);
|
||||
return *reinterpret_cast<const HBINT16 *> (value);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
bool has_device () const
|
||||
{
|
||||
unsigned int format = *this;
|
||||
return (format & devices) != 0;
|
||||
}
|
||||
|
||||
bool sanitize_value (hb_sanitize_context_t *c, const void *base, const Value *values) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_range (values, get_size ()) && (!has_device () || sanitize_value_devices (c, base, values)));
|
||||
}
|
||||
|
||||
bool sanitize_values (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
unsigned int len = get_len ();
|
||||
|
||||
if (!c->check_range (values, count, get_size ())) return_trace (false);
|
||||
|
||||
if (!has_device ()) return_trace (true);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
if (!sanitize_value_devices (c, base, values))
|
||||
return_trace (false);
|
||||
values += len;
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
/* Just sanitize referenced Device tables. Doesn't check the values themselves. */
|
||||
bool sanitize_values_stride_unsafe (hb_sanitize_context_t *c, const void *base, const Value *values, unsigned int count, unsigned int stride) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
||||
if (!has_device ()) return_trace (true);
|
||||
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
if (!sanitize_value_devices (c, base, values))
|
||||
return_trace (false);
|
||||
values = &StructAtOffset<const Value> (values, stride);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void should_drop (Value value, Flags flag, unsigned int* format) const
|
||||
{
|
||||
if (value) return;
|
||||
*format = *format & ~flag;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #ifndef OT_LAYOUT_GPOS_VALUEFORMAT_HH
|
|
@ -5,13 +5,12 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
template <typename Types>
|
||||
struct AlternateSet
|
||||
{
|
||||
protected:
|
||||
Array16Of<typename Types::HBGlyphID>
|
||||
Array16Of<HBGlyphID16>
|
||||
alternates; /* Array of alternate GlyphIDs--in
|
||||
* arbitrary order */
|
||||
public:
|
||||
|
@ -57,23 +56,8 @@ struct AlternateSet
|
|||
|
||||
if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->sync_so_far ();
|
||||
c->buffer->message (c->font,
|
||||
"replacing glyph at %u (alternate substitution)",
|
||||
c->buffer->idx);
|
||||
}
|
||||
|
||||
c->replace_glyph (alternates[alt_index - 1]);
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"replaced glyph at %u (alternate substitution)",
|
||||
c->buffer->idx - 1u);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
@ -84,7 +68,7 @@ struct AlternateSet
|
|||
{
|
||||
if (alternates.len && alternate_count)
|
||||
{
|
||||
+ alternates.as_array ().sub_array (start_offset, alternate_count)
|
||||
+ alternates.sub_array (start_offset, alternate_count)
|
||||
| hb_sink (hb_array (alternate_glyphs, *alternate_count))
|
||||
;
|
||||
}
|
||||
|
|
|
@ -6,36 +6,28 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
struct AlternateSubst
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
AlternateSubstFormat1_2<SmallTypes> format1;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
AlternateSubstFormat1_2<MediumTypes> format2;
|
||||
#endif
|
||||
HBUINT16 format; /* Format identifier */
|
||||
AlternateSubstFormat1 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);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||
#endif
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO This function is unused and not updated to 24bit GIDs. Should be done by using
|
||||
* iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
hb_sorted_array_t<const HBGlyphID16> glyphs,
|
||||
hb_array_t<const unsigned int> alternate_len_list,
|
||||
|
@ -50,9 +42,6 @@ struct AlternateSubst
|
|||
default:return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO subset() should choose format. */
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -6,21 +6,20 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
template <typename Types>
|
||||
struct AlternateSubstFormat1_2
|
||||
struct AlternateSubstFormat1
|
||||
{
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
typename Types::template OffsetTo<Coverage>
|
||||
Offset16To<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of Substitution table */
|
||||
Array16Of<typename Types::template OffsetTo<AlternateSet<Types>>>
|
||||
Array16OfOffset16To<AlternateSet>
|
||||
alternateSet; /* Array of AlternateSet tables
|
||||
* ordered by Coverage Index */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2 + 2 * Types::size, alternateSet);
|
||||
DEFINE_SIZE_ARRAY (6, alternateSet);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
|
@ -28,6 +27,8 @@ struct AlternateSubstFormat1_2
|
|||
return_trace (coverage.sanitize (c, this) && alternateSet.sanitize (c, this));
|
||||
}
|
||||
|
||||
inline bool is_inplace () const { return true; }
|
||||
|
||||
bool intersects (const hb_set_t *glyphs) const
|
||||
{ return (this+coverage).intersects (glyphs); }
|
||||
|
||||
|
@ -40,8 +41,9 @@ struct AlternateSubstFormat1_2
|
|||
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||
| hb_map (hb_second)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_apply ([c] (const AlternateSet<Types> &_) { _.closure (c); })
|
||||
| hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
void closure_lookups (hb_closure_lookups_context_t *c) const {}
|
||||
|
@ -52,7 +54,7 @@ struct AlternateSubstFormat1_2
|
|||
+ hb_zip (this+coverage, alternateSet)
|
||||
| hb_map (hb_second)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_apply ([c] (const AlternateSet<Types> &_) { _.collect_glyphs (c); })
|
||||
| hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
|
||||
;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
struct ChainContextSubst : ChainContext {};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
struct ContextSubst : Context {};
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
struct ExtensionSubst : Extension<ExtensionSubst>
|
||||
{
|
||||
|
|
|
@ -1,15 +1,16 @@
|
|||
#ifndef OT_LAYOUT_GSUB_GSUB_HH
|
||||
#define OT_LAYOUT_GSUB_GSUB_HH
|
||||
|
||||
// TODO(garretrieger): move to new layout.
|
||||
#include "../../../hb-ot-layout-gsubgpos.hh"
|
||||
#include "Common.hh"
|
||||
#include "SubstLookup.hh"
|
||||
|
||||
using OT::Layout::GSUB::SubstLookup;
|
||||
|
||||
namespace OT {
|
||||
|
||||
using Layout::GSUB_impl::SubstLookup;
|
||||
|
||||
namespace Layout {
|
||||
namespace GSUB {
|
||||
|
||||
/*
|
||||
* GSUB -- Glyph Substitution
|
||||
|
@ -18,8 +19,6 @@ namespace Layout {
|
|||
|
||||
struct GSUB : GSUBGPOS
|
||||
{
|
||||
using Lookup = SubstLookup;
|
||||
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_GSUB;
|
||||
|
||||
const SubstLookup& get_lookup (unsigned int i) const
|
||||
|
@ -27,15 +26,12 @@ struct GSUB : GSUBGPOS
|
|||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
hb_subset_layout_context_t l (c, tableTag);
|
||||
hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_langsys, c->plan->gsub_features);
|
||||
return GSUBGPOS::subset<SubstLookup> (&l);
|
||||
}
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (GSUBGPOS::sanitize<SubstLookup> (c));
|
||||
}
|
||||
{ return GSUBGPOS::sanitize<SubstLookup> (c); }
|
||||
|
||||
HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
|
||||
hb_face_t *face) const;
|
||||
|
@ -49,10 +45,11 @@ struct GSUB : GSUBGPOS
|
|||
};
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
struct GSUB_accelerator_t : Layout::GSUB::accelerator_t {
|
||||
GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::accelerator_t (face) {}
|
||||
struct GSUB_accelerator_t : Layout::GSUB::GSUB::accelerator_t {
|
||||
GSUB_accelerator_t (hb_face_t *face) : Layout::GSUB::GSUB::accelerator_t (face) {}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -5,20 +5,18 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
template <typename Types>
|
||||
struct Ligature
|
||||
{
|
||||
protected:
|
||||
typename Types::HBGlyphID
|
||||
ligGlyph; /* GlyphID of ligature to substitute */
|
||||
HeadlessArrayOf<typename Types::HBGlyphID>
|
||||
component; /* Array of component GlyphIDs--start
|
||||
HBGlyphID16 ligGlyph; /* GlyphID of ligature to substitute */
|
||||
HeadlessArrayOf<HBGlyphID16>
|
||||
component; /* Array of component GlyphIDs--start
|
||||
* with the second component--ordered
|
||||
* in writing direction */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (Types::size + 2, component);
|
||||
DEFINE_SIZE_ARRAY (4, component);
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
|
@ -29,9 +27,6 @@ struct Ligature
|
|||
bool intersects (const hb_set_t *glyphs) const
|
||||
{ return hb_all (component, glyphs); }
|
||||
|
||||
bool intersects_lig_glyph (const hb_set_t *glyphs) const
|
||||
{ return glyphs->has(ligGlyph); }
|
||||
|
||||
void closure (hb_closure_context_t *c) const
|
||||
{
|
||||
if (!intersects (c->glyphs)) return;
|
||||
|
@ -67,24 +62,7 @@ struct Ligature
|
|||
* as a "ligated" substitution. */
|
||||
if (unlikely (count == 1))
|
||||
{
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->sync_so_far ();
|
||||
c->buffer->message (c->font,
|
||||
"replacing glyph at %u (ligature substitution)",
|
||||
c->buffer->idx);
|
||||
}
|
||||
|
||||
c->replace_glyph (ligGlyph);
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->message (c->font,
|
||||
"replaced glyph at %u (ligature substitution)",
|
||||
c->buffer->idx - 1u);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
@ -105,31 +83,6 @@ struct Ligature
|
|||
return_trace (false);
|
||||
}
|
||||
|
||||
unsigned pos = 0;
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
unsigned delta = c->buffer->sync_so_far ();
|
||||
|
||||
pos = c->buffer->idx;
|
||||
|
||||
char buf[HB_MAX_CONTEXT_LENGTH * 16] = {0};
|
||||
char *p = buf;
|
||||
|
||||
match_end += delta;
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
match_positions[i] += delta;
|
||||
if (i)
|
||||
*p++ = ',';
|
||||
snprintf (p, sizeof(buf) - (p - buf), "%u", match_positions[i]);
|
||||
p += strlen(p);
|
||||
}
|
||||
|
||||
c->buffer->message (c->font,
|
||||
"ligating glyphs at %s",
|
||||
buf);
|
||||
}
|
||||
|
||||
ligate_input (c,
|
||||
count,
|
||||
match_positions,
|
||||
|
@ -137,14 +90,6 @@ struct Ligature
|
|||
ligGlyph,
|
||||
total_component_count);
|
||||
|
||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||
{
|
||||
c->buffer->sync_so_far ();
|
||||
c->buffer->message (c->font,
|
||||
"ligated glyph at %u",
|
||||
pos);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
template <typename Types>
|
||||
struct LigatureSet
|
||||
{
|
||||
protected:
|
||||
Array16OfOffset16To<Ligature<Types>>
|
||||
Array16OfOffset16To<Ligature>
|
||||
ligature; /* Array LigatureSet tables
|
||||
* ordered by preference */
|
||||
public:
|
||||
|
@ -29,19 +28,7 @@ struct LigatureSet
|
|||
return
|
||||
+ hb_iter (ligature)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_map ([glyphs] (const Ligature<Types> &_) { return _.intersects (glyphs); })
|
||||
| hb_any
|
||||
;
|
||||
}
|
||||
|
||||
bool intersects_lig_glyph (const hb_set_t *glyphs) const
|
||||
{
|
||||
return
|
||||
+ hb_iter (ligature)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_map ([glyphs] (const Ligature<Types> &_) {
|
||||
return _.intersects_lig_glyph (glyphs) && _.intersects (glyphs);
|
||||
})
|
||||
| hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
|
||||
| hb_any
|
||||
;
|
||||
}
|
||||
|
@ -50,7 +37,7 @@ struct LigatureSet
|
|||
{
|
||||
+ hb_iter (ligature)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_apply ([c] (const Ligature<Types> &_) { _.closure (c); })
|
||||
| hb_apply ([c] (const Ligature &_) { _.closure (c); })
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -58,7 +45,7 @@ struct LigatureSet
|
|||
{
|
||||
+ hb_iter (ligature)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_apply ([c] (const Ligature<Types> &_) { _.collect_glyphs (c); })
|
||||
| hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -67,7 +54,7 @@ struct LigatureSet
|
|||
return
|
||||
+ hb_iter (ligature)
|
||||
| hb_map (hb_add (this))
|
||||
| hb_map ([c] (const Ligature<Types> &_) { return _.would_apply (c); })
|
||||
| hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
|
||||
| hb_any
|
||||
;
|
||||
}
|
||||
|
@ -78,7 +65,7 @@ struct LigatureSet
|
|||
unsigned int num_ligs = ligature.len;
|
||||
for (unsigned int i = 0; i < num_ligs; i++)
|
||||
{
|
||||
const auto &lig = this+ligature[i];
|
||||
const Ligature &lig = this+ligature[i];
|
||||
if (lig.apply (c)) return_trace (true);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,37 +6,28 @@
|
|||
|
||||
namespace OT {
|
||||
namespace Layout {
|
||||
namespace GSUB_impl {
|
||||
namespace GSUB {
|
||||
|
||||
struct LigatureSubst
|
||||
{
|
||||
protected:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
LigatureSubstFormat1_2<SmallTypes> format1;
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
LigatureSubstFormat1_2<MediumTypes> format2;
|
||||
#endif
|
||||
HBUINT16 format; /* Format identifier */
|
||||
LigatureSubstFormat1 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);
|
||||
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
||||
switch (u.format) {
|
||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||
#ifndef HB_NO_BEYOND_64K
|
||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||
#endif
|
||||
default:return_trace (c->default_return_value ());
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO This function is only used by small GIDs, and not updated to 24bit GIDs. Should
|
||||
* be done by using iterators. While at it perhaps using iterator of arrays of hb_codepoint_t
|
||||
* instead. */
|
||||
bool serialize (hb_serialize_context_t *c,
|
||||
hb_sorted_array_t<const HBGlyphID16> first_glyphs,
|
||||
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
||||
|
@ -58,9 +49,6 @@ struct LigatureSubst
|
|||
default:return_trace (false);
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO subset() should choose format. */
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue