Merge branch 'master' into cff-subset
This commit is contained in:
commit
3dd43f0234
@ -32,10 +32,10 @@ jobs:
|
||||
- image: ubuntu:17.10
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update && apt install -y ninja-build binutils libtool autoconf automake make cmake gcc g++ pkg-config ragel gtk-doc-tools libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: apt update && apt install -y ninja-build binutils libtool autoconf automake make cmake gcc g++ pkg-config ragel gtk-doc-tools libfontconfig1-dev libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: pip install fonttools
|
||||
- run: ./autogen.sh
|
||||
- run: make
|
||||
- run: make -j32
|
||||
- run: make distcheck || .ci/fail.sh
|
||||
- run: rm -rf harfbuzz-*
|
||||
- run: make distdir && cd harfbuzz-* && cmake -DHB_CHECK=ON -Bbuild -H. -GNinja && ninja -Cbuild && CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test && ninja -Cbuild install
|
||||
@ -48,7 +48,7 @@ jobs:
|
||||
- run: apk update && apk add ragel make pkgconfig libtool autoconf automake gettext gcc g++ glib-dev freetype-dev cairo-dev
|
||||
# C??FLAGS are not needed for a regular build
|
||||
- run: CFLAGS="-O3" CXXFLAGS="-O3 -DHB_NO_MMAP" ./autogen.sh
|
||||
- run: make
|
||||
- run: make -j32
|
||||
- run: make check || .ci/fail.sh
|
||||
|
||||
archlinux-debug-O0-py3:
|
||||
@ -60,7 +60,7 @@ jobs:
|
||||
- run: pip install fonttools
|
||||
# C??FLAGS are not needed for a regular build
|
||||
- run: CFLAGS="-O0" CXXFLAGS="-O0" CPPFLAGS="-DHB_DEBUG" ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: make -j32
|
||||
- run: make check || .ci/fail.sh
|
||||
|
||||
clang-O3-O0:
|
||||
@ -69,63 +69,98 @@ jobs:
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true
|
||||
- run: apt install -y ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: apt install -y ragel libfreetype6-dev libfontconfig1-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: pip install fonttools
|
||||
- run: wget http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2 && tar xf freetype-2.9.tar.bz2 && cd freetype-2.9 && ./autogen.sh && ./configure && make -j4 && cd ..
|
||||
- run: CFLAGS="-O3" CXXFLAGS="-O3" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: wget http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2 && tar xf freetype-2.9.tar.bz2 && cd freetype-2.9 && ./autogen.sh && ./configure && make -j32 && cd ..
|
||||
- run: CFLAGS="-O3" CXXFLAGS="-O3" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-fontconfig --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make -j32
|
||||
- run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || .ci/fail.sh
|
||||
- run: CFLAGS="-O0" CXXFLAGS="-O0" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: CFLAGS="-O0" CXXFLAGS="-O0" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-fontconfig --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make -j32
|
||||
- run: LD_LIBRARY_PATH="$PWD/freetype-2.9/objs/.libs" make check || .ci/fail.sh
|
||||
|
||||
clang-everything:
|
||||
docker:
|
||||
- image: ubuntu:18.10
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true; apt install -y wget gnupg
|
||||
- run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
- run: echo "deb http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdev.list
|
||||
- run: echo "deb-src http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdevsrc.list
|
||||
- run: apt update || true
|
||||
- run: apt install -y clang lld binutils libtool autoconf automake make pkg-config gtk-doc-tools ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: pip install fonttools
|
||||
- run: CFLAGS="-Weverything -Werror -fPIC -Wno-unused-parameter -Wno-missing-variable-declarations -Wno-padded -Wno-cast-qual -Wno-sign-conversion -Wno-conversion -Wno-documentation -Wno-documentation-unknown-command -Wno-reserved-id-macro -Wno-shadow -Wno-reserved-id-macro -Wno-disabled-macro-expansion -Wno-missing-variable-declarations -Wno-unused-macros -Wno-unreachable-code-return" CXXFLAGS="-Weverything -Werror -fPIC -Wno-undef -Wno-deprecated-declarations -Wno-weak-vtables -Wno-old-style-cast -Wno-documentation -Wno-documentation-unknown-command -Wno-conversion -Wno-sign-conversion -Wno-c++98-compat -Wno-extra-semi -Wno-c++98-compat-pedantic -Wno-padded -Wno-shift-sign-overflow -Wno-missing-field-initializers -Wno-double-promotion -Wno-reserved-id-macro -Wno-cast-qual -Wno-unused-parameter -Wno-comma -Wno-shadow -Wno-used-but-marked-unused -Wno-format-pedantic -Wno-zero-as-null-pointer-constant -Wno-disabled-macro-expansion -Wno-covered-switch-default -Wno-conditional-uninitialized -Wno-unreachable-code -Wno-unused-macros -Wno-float-equal -Wno-missing-prototypes" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make -j32
|
||||
- run: make check || .ci/fail.sh
|
||||
|
||||
clang-asan:
|
||||
docker:
|
||||
- image: ubuntu:18.04
|
||||
- image: ubuntu:18.10
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true; apt install -y wget gnupg
|
||||
- run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
- run: echo "deb http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdev.list
|
||||
- run: echo "deb-src http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdevsrc.list
|
||||
- run: apt update || true
|
||||
- run: apt install -y clang-6.0 binutils libtool autoconf automake make pkg-config gtk-doc-tools ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: apt install -y clang lld binutils libtool autoconf automake make pkg-config gtk-doc-tools ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: pip install fonttools
|
||||
- run: CPPFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address" CC=clang-6.0 CXX=clang++-6.0 ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: make check || .ci/fail.sh
|
||||
- run: CPPFLAGS="-fsanitize=address" LDFLAGS="-fsanitize=address -O1 -g -fno-omit-frame-pointer" CFLAGS="-fsanitize=address -O1 -g -fno-omit-frame-pointer" CXXFLAGS="-fsanitize=address -O1 -g -fno-omit-frame-pointer" LD=ld.lld CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make -j32
|
||||
- run: make check || .ci/fail.sh | asan_symbolize | c++filt
|
||||
|
||||
clang-msan:
|
||||
docker:
|
||||
- image: ubuntu:18.04
|
||||
- image: ubuntu:18.10
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true; apt install -y wget gnupg
|
||||
- run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
- run: echo "deb http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdev.list
|
||||
- run: echo "deb-src http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdevsrc.list
|
||||
- run: apt update || true
|
||||
- run: apt install -y clang-6.0 binutils libtool autoconf automake make pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: apt install -y clang lld binutils libtool autoconf automake automake1.11 gtk-doc-tools gettext make pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: pip install fonttools
|
||||
- run: CPPFLAGS="-fsanitize=memory" LDFLAGS="-fsanitize=memory" CC=clang-6.0 CXX=clang++-6.0 ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: make check || .ci/fail.sh
|
||||
- run: update-alternatives --install "/usr/bin/ld" "ld" "/usr/bin/ld.lld" 10
|
||||
- run: wget https://ftp.gnome.org/pub/gnome/sources/glib/2.28/glib-2.28.0.tar.bz2 && tar xf glib-2.28.0.tar.bz2 && cd glib-2.28.0 && ./autogen.sh || true && ./configure CPPFLAGS="-fsanitize=memory" LDFLAGS="-fsanitize=memory" CFLAGS="-fsanitize=memory" CXXFLAGS="-fsanitize=memory" LD=ld.lld CC=clang CXX=clang++ && make -j32 && make install && cd ..
|
||||
- run: wget http://download.savannah.gnu.org/releases/freetype/freetype-2.9.tar.bz2 && tar xf freetype-2.9.tar.bz2 && cd freetype-2.9 && ./autogen.sh && ./configure CPPFLAGS="-fsanitize=memory" LDFLAGS="-fsanitize=memory -O1 -g -fno-omit-frame-pointer" CFLAGS="-fsanitize=memory -O1 -g -fno-omit-frame-pointer" CXXFLAGS="-fsanitize=memory -O1 -g -fno-omit-frame-pointer" LD=ld.lld CC=clang CXX=clang++ && make -j32 && make install && cd ..
|
||||
- run: CPPFLAGS="-fsanitize=memory" LDFLAGS="-fsanitize=memory -O1 -g -fno-omit-frame-pointer" CFLAGS="-fsanitize=memory -O1 -g -fno-omit-frame-pointer" CXXFLAGS="-fsanitize=memory -O1 -g -fno-omit-frame-pointer" LD=ld.lld CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --without-icu
|
||||
- run: make -j32
|
||||
- run: MSAN_OPTIONS=exitcode=42 SKIPCHECKSYMBOLS=1 SKIPFUZZERTESTS=1 make check || .ci/fail.sh | asan_symbolize | c++filt
|
||||
|
||||
clang-tsan:
|
||||
docker:
|
||||
- image: ubuntu:18.04
|
||||
- image: ubuntu:18.10
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true; apt install -y wget gnupg
|
||||
- run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
- run: echo "deb http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdev.list
|
||||
- run: echo "deb-src http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdevsrc.list
|
||||
- run: apt update || true
|
||||
- run: apt install -y clang-6.0 binutils libtool autoconf automake make pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: apt install -y clang lld binutils libtool autoconf automake make pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: pip install fonttools
|
||||
- run: CPPFLAGS="-fsanitize=thread" LDFLAGS="-fsanitize=thread" CC=clang-6.0 CXX=clang++-6.0 ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: make check || .ci/fail.sh
|
||||
- run: CPPFLAGS="-fsanitize=thread" LDFLAGS="-fsanitize=thread -O1 -g -fno-omit-frame-pointer" CFLAGS="-fsanitize=thread -O1 -g -fno-omit-frame-pointer" CXXFLAGS="-fsanitize=thread -O1 -g -fno-omit-frame-pointer" LD=ld.lld CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make -j32
|
||||
- run: make check || .ci/fail.sh | asan_symbolize | c++filt
|
||||
|
||||
clang-ubsan:
|
||||
docker:
|
||||
- image: ubuntu:18.04
|
||||
- image: ubuntu:18.10
|
||||
steps:
|
||||
- checkout
|
||||
- run: apt update || true; apt install -y wget gnupg
|
||||
- run: wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | apt-key add -
|
||||
- run: echo "deb http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdev.list
|
||||
- run: echo "deb-src http://apt.llvm.org/cosmic/ llvm-toolchain-cosmic main" > /etc/apt/sources.list.d/llvmdevsrc.list
|
||||
- run: apt update || true
|
||||
- run: apt install -y clang-6.0 binutils libtool autoconf automake make pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: apt install -y clang lld binutils libtool autoconf automake make pkg-config ragel libfreetype6-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||
- run: pip install fonttools
|
||||
- run: CPPFLAGS="-fsanitize=undefined" LDFLAGS="-fsanitize=undefined" CC=clang-6.0 CXX=clang++-6.0 ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make
|
||||
- run: make check || .ci/fail.sh
|
||||
- run: CPPFLAGS="-fsanitize=undefined" LDFLAGS="-fsanitize=undefined -O1 -g -fno-omit-frame-pointer" CFLAGS="-fsanitize=undefined -O1 -g -fno-omit-frame-pointer" CXXFLAGS="-fsanitize=undefined -O1 -g -fno-omit-frame-pointer" LD=ld.lld CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2
|
||||
- run: make -j32
|
||||
- run: make check || .ci/fail.sh | asan_symbolize | c++filt
|
||||
|
||||
fedora-outoftreebuild:
|
||||
docker:
|
||||
@ -156,7 +191,7 @@ jobs:
|
||||
- run: dnf install -y gcc ragel cmake make which glib2-devel freetype-devel cairo-devel libicu-devel graphite2-devel wget tar bzip2 python libnsl || true
|
||||
- run: wget http://$ODSUSER:$ODSPASS@behdad.org/harfbuzz-private/OracleDeveloperStudio12.6-linux-x86-bin.tar.bz2 && tar xf OracleDeveloperStudio12.6-linux-x86-bin.tar.bz2 --owner root --group root --no-same-owner
|
||||
- run: CC=/root/project/OracleDeveloperStudio12.6-linux-x86-bin/developerstudio12.6/bin/suncc CXX=/root/project/OracleDeveloperStudio12.6-linux-x86-bin/developerstudio12.6/bin/sunCC cmake -DHB_HAVE_GRAPHITE2=ON -DHB_BUILTIN_UCDN=ON -DHB_HAVE_GLIB=ON -DHB_HAVE_FREETYPE=ON -Bbuild -H.
|
||||
- run: make -Cbuild
|
||||
- run: make -Cbuild -j32
|
||||
- run: CTEST_OUTPUT_ON_FAILURE=1 make -Cbuild test
|
||||
- run: make -Cbuild install
|
||||
|
||||
@ -167,7 +202,7 @@ jobs:
|
||||
- checkout
|
||||
- run: apt update && apt install -y ragel pkg-config libtool autoconf
|
||||
- run: CFLAGS="-Wno-attributes" CXXFLAGS="-Wno-attributes" ./autogen.sh --prefix=/usr/local/djgpp --host=i586-pc-msdosdjgpp
|
||||
- run: make
|
||||
- run: make -j32
|
||||
|
||||
crosscompile-notest-freebsd9:
|
||||
docker:
|
||||
@ -176,7 +211,7 @@ jobs:
|
||||
- checkout
|
||||
- run: apt update && apt install -y pkg-config ragel
|
||||
- run: ./autogen.sh --prefix=/freebsd --host=x86_64-pc-freebsd9
|
||||
- run: make
|
||||
- run: make -j32
|
||||
|
||||
crosscompile-notest-psvita:
|
||||
docker:
|
||||
@ -186,7 +221,7 @@ jobs:
|
||||
- run: apt update && apt install ragel
|
||||
- run: git clone https://github.com/vitasdk/vdpm && cd vdpm && ./bootstrap-vitasdk.sh
|
||||
- run: ./autogen.sh --prefix=/usr/local/vitasdk/arm-vita-eabi --host=arm-vita-eabi
|
||||
- run: make
|
||||
- run: make -j32
|
||||
|
||||
crosscompile-cmake-notest-android-arm:
|
||||
docker:
|
||||
@ -248,10 +283,11 @@ workflows:
|
||||
- alpine-O3-NOMMAP
|
||||
- archlinux-debug-O0-py3
|
||||
- clang-O3-O0
|
||||
- clang-everything
|
||||
- clang-asan
|
||||
#- clang-msan
|
||||
- clang-msan
|
||||
- clang-tsan
|
||||
#- clang-ubsan
|
||||
- clang-ubsan
|
||||
- fedora-outoftreebuild
|
||||
|
||||
# cmake based builds
|
||||
|
@ -29,7 +29,7 @@ environment:
|
||||
MSYS2_ARCH: i686
|
||||
|
||||
install:
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman -Syu --noconfirm"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --force --noconfirm -Sy && pacman --noconfirm --force -S pacman-mirrors && pacman --force -Syu --noconfirm"'
|
||||
- C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S mingw-w64-x86_64-ragel"
|
||||
|
||||
build_script:
|
||||
@ -44,8 +44,8 @@ build_script:
|
||||
- 'if "%compiler%"=="msvc" msbuild harfbuzz.sln /p:Configuration=%configuration% /p:Platform=%platform%'
|
||||
- 'if "%compiler%"=="msvc" if not "%platform%"=="ARM" ctest --output-on-failure -C %configuration%'
|
||||
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -Syyu mingw-w64-$MSYS2_ARCH-gcc"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm -S --needed mingw-w64-$MSYS2_ARCH-{freetype,cairo,icu,gettext,gobject-introspection,gcc,gcc-libs,glib2,graphite2,pkg-config,python2}"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm --force -Syyu mingw-w64-$MSYS2_ARCH-gcc"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "pacman --noconfirm --force -S --needed mingw-w64-$MSYS2_ARCH-{freetype,cairo,icu,gettext,gobject-introspection,gcc,gcc-libs,glib2,graphite2,pkg-config,python2}"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "curl https://raw.githubusercontent.com/mirror/mingw-w64/023eb04c396d4e8d8fcf604cfababc53dae13398/mingw-w64-headers/include/dwrite_1.h > %MINGW_PREFIX%/%MINGW_CHOST%/include/dwrite_1.h"'
|
||||
- 'if "%compiler%"=="msys2" C:\msys64\usr\bin\bash -lc "cd $APPVEYOR_BUILD_FOLDER; PATH=$PATH:/mingw64/bin:/mingw32/bin; ./autogen.sh --with-uniscribe --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 --with-directwrite --build=%MINGW_CHOST% --host=%MINGW_CHOST% --prefix=%MINGW_PREFIX%; make; make check || .ci/fail.sh"'
|
||||
|
||||
|
@ -7,7 +7,6 @@ test -z "$srcdir" && srcdir=.
|
||||
test -z "$libs" && libs=.libs
|
||||
stat=0
|
||||
|
||||
|
||||
if which objdump 2>/dev/null >/dev/null; then
|
||||
:
|
||||
else
|
||||
@ -31,7 +30,8 @@ done
|
||||
|
||||
echo "Checking that no object file has lazy static C++ constructors/destructors or other such stuff"
|
||||
for obj in $OBJS; do
|
||||
if objdump -t "$obj" | grep '__cxa_'; then
|
||||
if objdump -t "$obj" | grep -q '__cxa_' && ! objdump -t "$obj" | grep -q __ubsan_handle; then
|
||||
objdump -t "$obj" | grep '__cxa_'
|
||||
echo "Ouch, $obj has lazy static C++ constructors/destructors or other such stuff"
|
||||
stat=1
|
||||
fi
|
||||
|
@ -3,6 +3,8 @@
|
||||
LC_ALL=C
|
||||
export LC_ALL
|
||||
|
||||
test -z "$SKIPCHECKSYMBOLS" || exit 77
|
||||
|
||||
test -z "$srcdir" && srcdir=.
|
||||
test -z "$libs" && libs=.libs
|
||||
stat=0
|
||||
@ -26,7 +28,7 @@ for soname in harfbuzz harfbuzz-subset harfbuzz-icu harfbuzz-gobject; do
|
||||
symprefix=
|
||||
if test $suffix = dylib; then symprefix=_; fi
|
||||
|
||||
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTV] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`"
|
||||
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRST] .' | grep -v " $symprefix\\($IGNORED_SYMBOLS\\>\\)" | cut -d' ' -f3 | c++filt`"
|
||||
|
||||
prefix=$symprefix`basename "$so" | sed 's/libharfbuzz/hb/; s/-/_/g; s/[.].*//'`
|
||||
|
||||
|
@ -281,8 +281,8 @@ use_positions = {
|
||||
'V': {
|
||||
'Abv': [Top, Top_And_Bottom, Top_And_Bottom_And_Right, Top_And_Right],
|
||||
'Blw': [Bottom, Overstruck, Bottom_And_Right],
|
||||
'Pst': [Right],
|
||||
'Pre': [Left, Top_And_Left, Top_And_Left_And_Right, Left_And_Right],
|
||||
'Pst': [Right, Top_And_Left, Top_And_Left_And_Right, Left_And_Right],
|
||||
'Pre': [Left],
|
||||
},
|
||||
'VM': {
|
||||
'Abv': [Top],
|
||||
|
@ -12,7 +12,11 @@ set(_harfbuzz_libdir "@libdir@")
|
||||
string(REPLACE "${_harfbuzz_remove_string}/" "" _harfbuzz_libdir "${_harfbuzz_libdir}")
|
||||
set(_harfbuzz_libdir_iter "${_harfbuzz_libdir}")
|
||||
while (_harfbuzz_libdir_iter)
|
||||
set(_harfbuzz_libdir_prev_iter "${_harfbuzz_libdir_iter}")
|
||||
get_filename_component(_harfbuzz_libdir_iter "${_harfbuzz_libdir_iter}" DIRECTORY)
|
||||
if (_harfbuzz_libdir_prev_iter STREQUAL _harfbuzz_libdir_iter)
|
||||
break()
|
||||
endif ()
|
||||
get_filename_component(_harfbuzz_prefix "${_harfbuzz_prefix}" DIRECTORY)
|
||||
endwhile ()
|
||||
unset(_harfbuzz_libdir_iter)
|
||||
|
@ -585,6 +585,8 @@ struct StateTableDriver
|
||||
if (unlikely (!c->transition (this, entry)))
|
||||
break;
|
||||
|
||||
if (unlikely (!buffer->successful)) return;
|
||||
|
||||
last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0;
|
||||
|
||||
state = entry->newState;
|
||||
|
@ -592,7 +592,6 @@ struct InsertionSubtable
|
||||
hb_aat_apply_context_t *c_) :
|
||||
ret (false),
|
||||
c (c_),
|
||||
mark_set (false),
|
||||
mark (0),
|
||||
insertionAction (table+table->insertionAction) {}
|
||||
|
||||
@ -608,7 +607,7 @@ struct InsertionSubtable
|
||||
hb_buffer_t *buffer = driver->buffer;
|
||||
unsigned int flags = entry->flags;
|
||||
|
||||
if (entry->data.markedInsertIndex != 0xFFFF && mark_set)
|
||||
if (entry->data.markedInsertIndex != 0xFFFF)
|
||||
{
|
||||
unsigned int count = (flags & MarkedInsertCount);
|
||||
unsigned int start = entry->data.markedInsertIndex;
|
||||
@ -629,6 +628,8 @@ struct InsertionSubtable
|
||||
buffer->skip_glyph ();
|
||||
|
||||
buffer->move_to (end + count);
|
||||
|
||||
buffer->unsafe_to_break_from_outbuffer (mark, MIN (buffer->idx + 1, buffer->len));
|
||||
}
|
||||
|
||||
if (entry->data.currentInsertIndex != 0xFFFF)
|
||||
@ -667,10 +668,7 @@ struct InsertionSubtable
|
||||
}
|
||||
|
||||
if (flags & SetMark)
|
||||
{
|
||||
mark_set = true;
|
||||
mark = buffer->out_len;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -679,7 +677,6 @@ struct InsertionSubtable
|
||||
bool ret;
|
||||
private:
|
||||
hb_aat_apply_context_t *c;
|
||||
bool mark_set;
|
||||
unsigned int mark;
|
||||
const UnsizedArrayOf<GlyphID> &insertionAction;
|
||||
};
|
||||
@ -889,6 +886,8 @@ struct Chain
|
||||
|
||||
(void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index);
|
||||
|
||||
if (unlikely (!c->buffer->successful)) return;
|
||||
|
||||
skip:
|
||||
subtable = &StructAfter<ChainSubtable> (*subtable);
|
||||
c->set_lookup_index (c->lookup_index + 1);
|
||||
@ -945,12 +944,14 @@ struct morx
|
||||
|
||||
inline void apply (hb_aat_apply_context_t *c) const
|
||||
{
|
||||
if (unlikely (!c->buffer->successful)) return;
|
||||
c->set_lookup_index (0);
|
||||
const Chain *chain = &firstChain;
|
||||
unsigned int count = chainCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
chain->apply (c);
|
||||
if (unlikely (!c->buffer->successful)) return;
|
||||
chain = &StructAfter<Chain> (*chain);
|
||||
}
|
||||
}
|
||||
|
@ -49,17 +49,21 @@
|
||||
/* Defined externally, i.e. in config.h. */
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(__ATOMIC_CONSUME)
|
||||
#elif !defined(HB_NO_MT) && defined(__ATOMIC_ACQUIRE)
|
||||
|
||||
/* C++11-style GCC primitives. */
|
||||
|
||||
#define _hb_memory_barrier() __sync_synchronize ()
|
||||
|
||||
#define hb_atomic_int_impl_add(AI, V) __atomic_fetch_add ((AI), (V), __ATOMIC_ACQ_REL)
|
||||
#define hb_atomic_int_impl_set_relaxed(AI, V) __atomic_store_n ((AI), (V), __ATOMIC_RELAXED)
|
||||
#define hb_atomic_int_impl_set(AI, V) __atomic_store_n ((AI), (V), __ATOMIC_RELEASE)
|
||||
#define hb_atomic_int_impl_get_relaxed(AI) __atomic_load_n ((AI), __ATOMIC_RELAXED)
|
||||
#define hb_atomic_int_impl_get(AI) __atomic_load_n ((AI), __ATOMIC_ACQUIRE)
|
||||
|
||||
#define hb_atomic_ptr_impl_set_relaxed(P, V) __atomic_store_n ((P), (V), __ATOMIC_RELAXED)
|
||||
#define hb_atomic_ptr_impl_get_relaxed(P) __atomic_load_n ((P), __ATOMIC_RELAXED)
|
||||
#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_CONSUME)
|
||||
#define hb_atomic_ptr_impl_get(P) __atomic_load_n ((P), __ATOMIC_ACQUIRE)
|
||||
static inline bool
|
||||
_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
|
||||
{
|
||||
@ -74,13 +78,19 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#define _hb_memory_barrier() std::atomic_thread_fence(std::memory_order_ack_rel)
|
||||
#define _hb_memory_r_barrier() std::atomic_thread_fence(std::memory_order_acquire)
|
||||
#define _hb_memory_w_barrier() std::atomic_thread_fence(std::memory_order_release)
|
||||
|
||||
#define hb_atomic_int_impl_add(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->fetch_add ((V), std::memory_order_acq_rel))
|
||||
#define hb_atomic_int_impl_set_relaxed(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_relaxed))
|
||||
#define hb_atomic_int_impl_set(AI, V) (reinterpret_cast<std::atomic<int> *> (AI)->store ((V), std::memory_order_release))
|
||||
#define hb_atomic_int_impl_get_relaxed(AI) (reinterpret_cast<std::atomic<int> *> (AI)->load (std::memory_order_relaxed))
|
||||
#define hb_atomic_int_impl_get(AI) (reinterpret_cast<std::atomic<int> *> (AI)->load (std::memory_order_acquire))
|
||||
|
||||
#define hb_atomic_ptr_impl_set_relaxed(P, V) (reinterpret_cast<std::atomic<void*> *> (P)->store ((V), std::memory_order_relaxed))
|
||||
#define hb_atomic_ptr_impl_get_relaxed(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_relaxed))
|
||||
#define hb_atomic_ptr_impl_get(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_consume))
|
||||
#define hb_atomic_ptr_impl_get(P) (reinterpret_cast<std::atomic<void*> *> (P)->load (std::memory_order_acquire))
|
||||
static inline bool
|
||||
_hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
|
||||
{
|
||||
@ -109,7 +119,7 @@ static inline void _hb_memory_barrier (void)
|
||||
#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((LONG *) (AI), (V))
|
||||
static_assert ((sizeof (LONG) == sizeof (int)), "");
|
||||
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((P), (N), (O)) == (O))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
|
||||
@ -137,17 +147,17 @@ static inline int _hb_fetch_and_add (int *AI, int V)
|
||||
_hb_memory_r_barrier ();
|
||||
return result;
|
||||
}
|
||||
static inline bool _hb_compare_and_swap_ptr (const void **P, const void *O, const void *N)
|
||||
static inline bool _hb_compare_and_swap_ptr (void **P, void *O, void *N)
|
||||
{
|
||||
_hb_memory_w_barrier ();
|
||||
int result = atomic_cas_ptr ((void **) P, (void *) O, (void *) N) == (void *) O;
|
||||
bool result = atomic_cas_ptr (P, O, N) == O;
|
||||
_hb_memory_r_barrier ();
|
||||
return result;
|
||||
}
|
||||
|
||||
#define hb_atomic_int_impl_add(AI, V) _hb_fetch_and_add ((AI), (V))
|
||||
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((const void **) (P), (O), (N))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_compare_and_swap_ptr ((P), (O), (N))
|
||||
|
||||
|
||||
#elif !defined(HB_NO_MT) && defined(__APPLE__)
|
||||
@ -164,12 +174,12 @@ static inline bool _hb_compare_and_swap_ptr (const void **P, const void *O, cons
|
||||
#define hb_atomic_int_impl_add(AI, V) (OSAtomicAdd32Barrier ((V), (AI)) - (V))
|
||||
|
||||
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((O), (N), (P))
|
||||
#else
|
||||
#if __ppc64__ || __x86_64__ || __aarch64__
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (void *) (O), (int64_t) (void *) (N), (int64_t*) (P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
|
||||
#else
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (void *) (O), (int32_t) (void *) (N), (int32_t*) (P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@ -243,6 +253,12 @@ static_assert ((sizeof (long) == sizeof (void *)), "");
|
||||
#ifndef hb_atomic_ptr_impl_get_relaxed
|
||||
#define hb_atomic_ptr_impl_get_relaxed(P) (*(P))
|
||||
#endif
|
||||
#ifndef hb_atomic_int_impl_set
|
||||
inline void hb_atomic_int_impl_set (int *AI, int v) { _hb_memory_w_barrier (); *AI = v; }
|
||||
#endif
|
||||
#ifndef hb_atomic_int_impl_get
|
||||
inline int hb_atomic_int_impl_get (int *AI) { int v = *AI; _hb_memory_r_barrier (); return v; }
|
||||
#endif
|
||||
#ifndef hb_atomic_ptr_impl_get
|
||||
inline void *hb_atomic_ptr_impl_get (void **P) { void *v = *P; _hb_memory_r_barrier (); return v; }
|
||||
#endif
|
||||
@ -252,7 +268,9 @@ inline void *hb_atomic_ptr_impl_get (void **P) { void *v = *P; _hb_memory_r_barr
|
||||
struct hb_atomic_int_t
|
||||
{
|
||||
inline void set_relaxed (int v_) const { hb_atomic_int_impl_set_relaxed (&v, v_); }
|
||||
inline void set (int v_) const { hb_atomic_int_impl_set (&v, v_); }
|
||||
inline int get_relaxed (void) const { return hb_atomic_int_impl_get_relaxed (&v); }
|
||||
inline int get (void) const { return hb_atomic_int_impl_get (&v); }
|
||||
inline int inc (void) { return hb_atomic_int_impl_add (&v, 1); }
|
||||
inline int dec (void) { return hb_atomic_int_impl_add (&v, -1); }
|
||||
|
||||
@ -271,9 +289,9 @@ struct hb_atomic_ptr_t
|
||||
|
||||
inline void init (T* v_ = nullptr) { set_relaxed (v_); }
|
||||
inline void set_relaxed (T* v_) const { hb_atomic_ptr_impl_set_relaxed (&v, v_); }
|
||||
inline T *get_relaxed (void) const { return hb_atomic_ptr_impl_get_relaxed (&v); }
|
||||
inline T *get_relaxed (void) const { return (T *) hb_atomic_ptr_impl_get_relaxed (&v); }
|
||||
inline T *get (void) const { return (T *) hb_atomic_ptr_impl_get ((void **) &v); }
|
||||
inline bool cmpexch (const T *old, T *new_) const{ return hb_atomic_ptr_impl_cmpexch (&v, old, new_); }
|
||||
inline bool cmpexch (const T *old, T *new_) const { return hb_atomic_ptr_impl_cmpexch ((void **) &v, (void *) old, (void *) new_); }
|
||||
|
||||
mutable T *v;
|
||||
};
|
||||
|
@ -25,11 +25,6 @@
|
||||
* Red Hat Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#endif
|
||||
|
||||
#include "hb.hh"
|
||||
#include "hb-blob.hh"
|
||||
|
||||
@ -293,6 +288,8 @@ hb_blob_make_immutable (hb_blob_t *blob)
|
||||
{
|
||||
if (hb_object_is_inert (blob))
|
||||
return;
|
||||
if (blob->immutable)
|
||||
return;
|
||||
|
||||
blob->immutable = true;
|
||||
}
|
||||
|
@ -1499,6 +1499,8 @@ hb_buffer_reverse_clusters (hb_buffer_t *buffer)
|
||||
* it will be set to the process's default language as returned by
|
||||
* hb_language_get_default(). This may change in the future by
|
||||
* taking buffer script into consideration when choosing a language.
|
||||
* Note that hb_language_get_default() is NOT threadsafe the first time
|
||||
* it is called. See documentation for that function for details.
|
||||
*
|
||||
* Since: 0.9.7
|
||||
**/
|
||||
|
@ -93,8 +93,7 @@ typedef struct hb_glyph_info_t
|
||||
typedef enum { /*< flags >*/
|
||||
HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001,
|
||||
|
||||
/*< private >*/
|
||||
HB_GLYPH_FLAG_DEFINED = 0x00000001 /* OR of all defined flags */
|
||||
HB_GLYPH_FLAG_DEFINED = 0x00000001 /*< skip >*/ /* OR of all defined flags */
|
||||
} hb_glyph_flags_t;
|
||||
|
||||
HB_EXTERN hb_glyph_flags_t
|
||||
|
@ -68,7 +68,8 @@ enum hb_buffer_scratch_flags_t {
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000020u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_JOINERS = 0x00000020u,
|
||||
HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000040u,
|
||||
|
||||
/* Reserved for complex shapers' internal use. */
|
||||
HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,
|
||||
|
@ -36,19 +36,24 @@ template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bit
|
||||
struct hb_cache_t
|
||||
{
|
||||
static_assert ((key_bits >= cache_bits), "");
|
||||
static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (unsigned int)), "");
|
||||
static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (hb_atomic_int_t)), "");
|
||||
static_assert (sizeof (hb_atomic_int_t) == sizeof (unsigned int), "");
|
||||
|
||||
inline void init (void) { clear (); }
|
||||
inline void fini (void) {}
|
||||
|
||||
inline void clear (void)
|
||||
{ memset (values, 255, sizeof (values)); }
|
||||
{
|
||||
for (unsigned i = 0; i < ARRAY_LENGTH (values); i++)
|
||||
values[i].set_relaxed (-1);
|
||||
}
|
||||
|
||||
inline bool get (unsigned int key, unsigned int *value) const
|
||||
{
|
||||
unsigned int k = key & ((1u<<cache_bits)-1);
|
||||
unsigned int v = values[k].get_relaxed ();
|
||||
if ((v >> value_bits) != (key >> cache_bits))
|
||||
if ((key_bits + value_bits - cache_bits == 8 * sizeof (hb_atomic_int_t) && v == (unsigned int) -1) ||
|
||||
(v >> value_bits) != (key >> cache_bits))
|
||||
return false;
|
||||
*value = v & ((1u<<value_bits)-1);
|
||||
return true;
|
||||
|
@ -361,7 +361,14 @@ hb_language_to_string (hb_language_t language)
|
||||
/**
|
||||
* hb_language_get_default:
|
||||
*
|
||||
* Get default language from current locale.
|
||||
*
|
||||
* Note that the first time this function is called, it calls
|
||||
* "setlocale (LC_CTYPE, nullptr)" to fetch current locale. The underlying
|
||||
* setlocale function is, in many implementations, NOT threadsafe. To avoid
|
||||
* problems, call this function once before multiple threads can call it.
|
||||
* This function is only used from hb_buffer_guess_segment_properties() by
|
||||
* HarfBuzz itself.
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
*
|
||||
|
@ -86,8 +86,8 @@ typedef union _hb_var_int_t {
|
||||
|
||||
typedef uint32_t hb_tag_t;
|
||||
|
||||
#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint8_t)(c1))<<24)|(((uint8_t)(c2))<<16)|(((uint8_t)(c3))<<8)|((uint8_t)(c4))))
|
||||
#define HB_UNTAG(tag) ((uint8_t)((tag)>>24)), ((uint8_t)((tag)>>16)), ((uint8_t)((tag)>>8)), ((uint8_t)(tag))
|
||||
#define HB_TAG(c1,c2,c3,c4) ((hb_tag_t)((((uint32_t)(c1)&0xFF)<<24)|(((uint32_t)(c2)&0xFF)<<16)|(((uint32_t)(c3)&0xFF)<<8)|((uint32_t)(c4)&0xFF)))
|
||||
#define HB_UNTAG(tag) (((tag)>>24)&0xFF), (((tag)>>16)&0xFF), (((tag)>>8)&0xFF), ((tag)&0xFF)
|
||||
|
||||
#define HB_TAG_NONE HB_TAG(0,0,0,0)
|
||||
#define HB_TAG_MAX HB_TAG(0xff,0xff,0xff,0xff)
|
||||
@ -340,13 +340,15 @@ typedef enum
|
||||
HB_SCRIPT_INVALID = HB_TAG_NONE,
|
||||
|
||||
/* Dummy values to ensure any hb_tag_t value can be passed/stored as hb_script_t
|
||||
* without risking undefined behavior. Include both a signed and unsigned max,
|
||||
* since technically enums are int, and indeed, hb_script_t ends up being signed.
|
||||
* without risking undefined behavior. We have two, for historical reasons.
|
||||
* HB_TAG_MAX used to be unsigned, but that was invalid Ansi C, so was changed
|
||||
* to _HB_SCRIPT_MAX_VALUE to be equal to HB_TAG_MAX_SIGNED as well.
|
||||
*
|
||||
* See this thread for technicalities:
|
||||
*
|
||||
* https://lists.freedesktop.org/archives/harfbuzz/2014-March/004150.html
|
||||
*/
|
||||
_HB_SCRIPT_MAX_VALUE = HB_TAG_MAX, /*< skip >*/
|
||||
_HB_SCRIPT_MAX_VALUE = HB_TAG_MAX_SIGNED, /*< skip >*/
|
||||
_HB_SCRIPT_MAX_VALUE_SIGNED = HB_TAG_MAX_SIGNED /*< skip >*/
|
||||
|
||||
} hb_script_t;
|
||||
|
@ -210,7 +210,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
|
||||
}
|
||||
|
||||
CFURLRef original_url = nullptr;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
#if TARGET_OS_MAC && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
ATSFontRef atsFont;
|
||||
FSRef fsref;
|
||||
OSStatus status;
|
||||
@ -240,7 +240,7 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
|
||||
* process in Blink. This can be detected by the new file URL location
|
||||
* that the newly found font points to. */
|
||||
CFURLRef new_url = nullptr;
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
#if TARGET_OS_MAC && MAC_OS_X_VERSION_MIN_REQUIRED < 1060
|
||||
atsFont = CTFontGetPlatformFont (new_ct_font, NULL);
|
||||
status = ATSFontGetFileReference (atsFont, &fsref);
|
||||
if (status == noErr)
|
||||
|
@ -325,6 +325,8 @@ hb_face_make_immutable (hb_face_t *face)
|
||||
{
|
||||
if (unlikely (hb_object_is_inert (face)))
|
||||
return;
|
||||
if (face->immutable)
|
||||
return;
|
||||
|
||||
face->immutable = true;
|
||||
}
|
||||
|
@ -141,6 +141,12 @@ hb_font_get_glyph_h_advance_default (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
if (font->has_glyph_h_advances_func ())
|
||||
{
|
||||
hb_position_t ret;
|
||||
font->get_glyph_h_advances (1, &glyph, 0, &ret, 0);
|
||||
return ret;
|
||||
}
|
||||
return font->parent_scale_x_distance (font->parent->get_glyph_h_advance (glyph));
|
||||
}
|
||||
|
||||
@ -159,6 +165,12 @@ hb_font_get_glyph_v_advance_default (hb_font_t *font,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
if (font->has_glyph_v_advances_func ())
|
||||
{
|
||||
hb_position_t ret;
|
||||
font->get_glyph_v_advances (1, &glyph, 0, &ret, 0);
|
||||
return ret;
|
||||
}
|
||||
return font->parent_scale_y_distance (font->parent->get_glyph_v_advance (glyph));
|
||||
}
|
||||
|
||||
@ -586,6 +598,8 @@ hb_font_funcs_make_immutable (hb_font_funcs_t *ffuncs)
|
||||
{
|
||||
if (unlikely (hb_object_is_inert (ffuncs)))
|
||||
return;
|
||||
if (ffuncs->immutable)
|
||||
return;
|
||||
|
||||
ffuncs->immutable = true;
|
||||
}
|
||||
@ -1444,6 +1458,8 @@ hb_font_make_immutable (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (hb_object_is_inert (font)))
|
||||
return;
|
||||
if (font->immutable)
|
||||
return;
|
||||
|
||||
if (font->parent)
|
||||
hb_font_make_immutable (font->parent);
|
||||
|
27
src/hb-ft.cc
27
src/hb-ft.cc
@ -70,7 +70,7 @@ struct hb_ft_font_t
|
||||
bool symbol; /* Whether selected cmap is symbol cmap. */
|
||||
bool unref; /* Whether to destroy ft_face when done. */
|
||||
|
||||
mutable int cached_x_scale;
|
||||
mutable hb_atomic_int_t cached_x_scale;
|
||||
mutable hb_advance_cache_t advance_cache;
|
||||
};
|
||||
|
||||
@ -88,7 +88,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
|
||||
|
||||
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
|
||||
|
||||
ft_font->cached_x_scale = 0;
|
||||
ft_font->cached_x_scale.set (0);
|
||||
ft_font->advance_cache.init ();
|
||||
|
||||
return ft_font;
|
||||
@ -218,24 +218,6 @@ hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ft_get_glyph_h_advance (hb_font_t *font,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Fixed v;
|
||||
|
||||
if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags, &v)))
|
||||
return 0;
|
||||
|
||||
if (font->x_scale < 0)
|
||||
v = -v;
|
||||
|
||||
return (v + (1<<9)) >> 10;
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
|
||||
unsigned count,
|
||||
@ -250,10 +232,10 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
|
||||
int load_flags = ft_font->load_flags;
|
||||
int mult = font->x_scale < 0 ? -1 : +1;
|
||||
|
||||
if (font->x_scale != ft_font->cached_x_scale)
|
||||
if (font->x_scale != ft_font->cached_x_scale.get ())
|
||||
{
|
||||
ft_font->advance_cache.clear ();
|
||||
ft_font->cached_x_scale = font->x_scale;
|
||||
ft_font->cached_x_scale.set (font->x_scale);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
@ -480,7 +462,6 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
|
||||
//hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr);
|
||||
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr);
|
||||
hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr);
|
||||
|
@ -65,16 +65,6 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
||||
return ot_face->cmap.get_relaxed ()->get_variation_glyph (unicode, variation_selector, glyph);
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ot_get_glyph_h_advance (hb_font_t *font,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return font->em_scale_x (ot_face->hmtx.get_relaxed ()->get_advance (glyph, font));
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
|
||||
unsigned count,
|
||||
@ -95,16 +85,6 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
|
||||
}
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ot_get_glyph_v_advance (hb_font_t *font,
|
||||
void *font_data,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return font->em_scale_y (-(int) ot_face->vmtx.get_relaxed ()->get_advance (glyph, font));
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
|
||||
unsigned count,
|
||||
@ -221,9 +201,7 @@ static struct hb_ot_face_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
|
||||
hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
|
||||
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
|
||||
hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
|
||||
|
@ -506,21 +506,21 @@ struct hb_ot_apply_context_t :
|
||||
auto_zwnj (true),
|
||||
auto_zwj (true),
|
||||
random (false),
|
||||
random_state (1) {}
|
||||
random_state (1) { init_iters (); }
|
||||
|
||||
inline void reinit_iters (void)
|
||||
inline void init_iters (void)
|
||||
{
|
||||
iter_input.init (this, false);
|
||||
iter_context.init (this, true);
|
||||
}
|
||||
|
||||
inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
|
||||
inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; reinit_iters (); }
|
||||
inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; reinit_iters (); }
|
||||
inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; init_iters (); }
|
||||
inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); }
|
||||
inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); }
|
||||
inline void set_random (bool random_) { random = random_; }
|
||||
inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
|
||||
inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
|
||||
inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; reinit_iters (); }
|
||||
inline void set_lookup_props (unsigned int lookup_props_) { lookup_props = lookup_props_; init_iters (); }
|
||||
|
||||
inline uint32_t random_number (void)
|
||||
{
|
||||
|
@ -224,8 +224,16 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
|
||||
{
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES;
|
||||
props |= UPROPS_MASK_IGNORABLE;
|
||||
if (u == 0x200Cu) props |= UPROPS_MASK_Cf_ZWNJ;
|
||||
else if (u == 0x200Du) props |= UPROPS_MASK_Cf_ZWJ;
|
||||
if (u == 0x200Cu)
|
||||
{
|
||||
props |= UPROPS_MASK_Cf_ZWNJ;
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_JOINERS;
|
||||
}
|
||||
else if (u == 0x200Du)
|
||||
{
|
||||
props |= UPROPS_MASK_Cf_ZWJ;
|
||||
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_JOINERS;
|
||||
}
|
||||
/* Mongolian Free Variation Selectors need to be remembered
|
||||
* because although we need to hide them like default-ignorables,
|
||||
* they need to non-ignorable during shaping. This is similar to
|
||||
|
@ -74,8 +74,9 @@ hb_ot_map_builder_t::~hb_ot_map_builder_t (void)
|
||||
stages[table_index].fini ();
|
||||
}
|
||||
|
||||
void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
|
||||
hb_ot_map_feature_flags_t flags)
|
||||
void hb_ot_map_builder_t::add_feature (hb_tag_t tag,
|
||||
hb_ot_map_feature_flags_t flags,
|
||||
unsigned int value)
|
||||
{
|
||||
feature_info_t *info = feature_infos.push();
|
||||
if (unlikely (!tag)) return;
|
||||
|
@ -166,18 +166,26 @@ struct hb_ot_map_t
|
||||
hb_vector_t<stage_map_t, 4> stages[2]; /* GSUB/GPOS */
|
||||
};
|
||||
|
||||
enum hb_ot_map_feature_flags_t {
|
||||
enum hb_ot_map_feature_flags_t
|
||||
{
|
||||
F_NONE = 0x0000u,
|
||||
F_GLOBAL = 0x0001u, /* Feature applies to all characters; results in no mask allocated for it. */
|
||||
F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */
|
||||
F_MANUAL_ZWNJ = 0x0004u, /* Don't skip over ZWNJ when matching **context**. */
|
||||
F_MANUAL_ZWJ = 0x0008u, /* Don't skip over ZWJ when matching **input**. */
|
||||
F_MANUAL_JOINERS = F_MANUAL_ZWNJ | F_MANUAL_ZWJ,
|
||||
F_GLOBAL_MANUAL_JOINERS= F_GLOBAL | F_MANUAL_JOINERS,
|
||||
F_GLOBAL_SEARCH = 0x0010u, /* If feature not found in LangSys, look for it in global feature list and pick one. */
|
||||
F_RANDOM = 0x0020u /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
|
||||
};
|
||||
HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t);
|
||||
/* Macro version for where const is desired. */
|
||||
#define F_COMBINE(l,r) (hb_ot_map_feature_flags_t ((unsigned int) (l) | (unsigned int) (r)))
|
||||
|
||||
|
||||
struct hb_ot_map_feature_t
|
||||
{
|
||||
hb_tag_t tag;
|
||||
hb_ot_map_feature_flags_t flags;
|
||||
};
|
||||
|
||||
|
||||
struct hb_ot_map_builder_t
|
||||
@ -189,11 +197,18 @@ struct hb_ot_map_builder_t
|
||||
|
||||
HB_INTERNAL ~hb_ot_map_builder_t (void);
|
||||
|
||||
HB_INTERNAL void add_feature (hb_tag_t tag, unsigned int value,
|
||||
hb_ot_map_feature_flags_t flags);
|
||||
HB_INTERNAL void add_feature (hb_tag_t tag,
|
||||
hb_ot_map_feature_flags_t flags=F_NONE,
|
||||
unsigned int value=1);
|
||||
|
||||
inline void add_global_bool_feature (hb_tag_t tag)
|
||||
{ add_feature (tag, 1, F_GLOBAL); }
|
||||
inline void add_feature (const hb_ot_map_feature_t &feat)
|
||||
{ add_feature (feat.tag, feat.flags); }
|
||||
|
||||
inline void enable_feature (hb_tag_t tag)
|
||||
{ add_feature (tag, F_GLOBAL); }
|
||||
|
||||
inline void disable_feature (hb_tag_t tag)
|
||||
{ add_feature (tag, F_GLOBAL, 0); }
|
||||
|
||||
inline void add_gsub_pause (hb_ot_map_t::pause_func_t pause_func)
|
||||
{ add_pause (0, pause_func); }
|
||||
|
@ -159,7 +159,7 @@ static const struct arabic_state_table_entry {
|
||||
|
||||
|
||||
static void
|
||||
nuke_joiners (const hb_ot_shape_plan_t *plan,
|
||||
flip_joiners (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer);
|
||||
|
||||
@ -200,31 +200,45 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
|
||||
* work correctly. See https://github.com/harfbuzz/harfbuzz/issues/505
|
||||
*/
|
||||
|
||||
map->add_gsub_pause (nuke_joiners);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('s','t','c','h'));
|
||||
map->enable_feature (HB_TAG('s','t','c','h'));
|
||||
map->add_gsub_pause (record_stch);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
map->enable_feature (HB_TAG('c','c','m','p'));
|
||||
map->enable_feature (HB_TAG('l','o','c','l'));
|
||||
|
||||
map->add_gsub_pause (nullptr);
|
||||
|
||||
for (unsigned int i = 0; i < ARABIC_NUM_FEATURES; i++)
|
||||
{
|
||||
bool has_fallback = plan->props.script == HB_SCRIPT_ARABIC && !FEATURE_IS_SYRIAC (arabic_features[i]);
|
||||
map->add_feature (arabic_features[i], 1, has_fallback ? F_HAS_FALLBACK : F_NONE);
|
||||
map->add_feature (arabic_features[i], has_fallback ? F_HAS_FALLBACK : F_NONE);
|
||||
map->add_gsub_pause (nullptr);
|
||||
}
|
||||
|
||||
map->add_feature (HB_TAG('r','l','i','g'), 1, F_GLOBAL|F_HAS_FALLBACK);
|
||||
/* Normally, Unicode says a ZWNJ means "don't ligate". In Arabic script
|
||||
* however, it says a ZWJ should also mean "don't ligate". So we convert
|
||||
* a ZWJ to a ZWNJ for GSUB. We want to revert it back to ZWJ before
|
||||
* GPOS processing though. So we just flip their roles, and flip back
|
||||
* later. Note that this makes a ZWNJ into ZWJ for GSUB stage, which
|
||||
* means it would *not* break ligatures. But since ligatures around
|
||||
* ZWNJ are rare, we don't care.
|
||||
*
|
||||
* Since we don't currently have a way to apply a pause before GPOS
|
||||
* starts, let's just do this dance around a few required GUSB features. */
|
||||
map->add_gsub_pause (flip_joiners);
|
||||
|
||||
map->add_feature (HB_TAG('r','l','i','g'), F_GLOBAL | F_HAS_FALLBACK);
|
||||
|
||||
if (plan->props.script == HB_SCRIPT_ARABIC)
|
||||
map->add_gsub_pause (arabic_fallback_shape);
|
||||
|
||||
/* No pause after rclt. See 98460779bae19e4d64d29461ff154b3527bf8420. */
|
||||
map->add_global_bool_feature (HB_TAG('r','c','l','t'));
|
||||
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
|
||||
map->add_gsub_pause (nullptr);
|
||||
map->enable_feature (HB_TAG('r','c','l','t'));
|
||||
map->enable_feature (HB_TAG('c','a','l','t'));
|
||||
|
||||
/* And undo here. */
|
||||
map->add_gsub_pause (flip_joiners);
|
||||
|
||||
/* The spec includes 'cswh'. Earlier versions of Windows
|
||||
* used to enable this by default, but testing suggests
|
||||
@ -234,8 +248,8 @@ collect_features_arabic (hb_ot_shape_planner_t *plan)
|
||||
* Note that IranNastaliq uses this feature extensively
|
||||
* to fixup broken glyph sequences. Oh well...
|
||||
* Test case: U+0643,U+0640,U+0631. */
|
||||
//map->add_global_bool_feature (HB_TAG('c','s','w','h'));
|
||||
map->add_global_bool_feature (HB_TAG('m','s','e','t'));
|
||||
//map->enable_feature (HB_TAG('c','s','w','h'));
|
||||
map->enable_feature (HB_TAG('m','s','e','t'));
|
||||
}
|
||||
|
||||
#include "hb-ot-shape-complex-arabic-fallback.hh"
|
||||
@ -381,14 +395,17 @@ setup_masks_arabic (const hb_ot_shape_plan_t *plan,
|
||||
|
||||
|
||||
static void
|
||||
nuke_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
flip_joiners (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font HB_UNUSED,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_JOINERS))
|
||||
return;
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (_hb_glyph_info_is_zwj (&info[i]))
|
||||
if (_hb_glyph_info_is_joiner (&info[i]))
|
||||
_hb_glyph_info_flip_joiners (&info[i]);
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ collect_features_hangul (hb_ot_shape_planner_t *plan)
|
||||
hb_ot_map_builder_t *map = &plan->map;
|
||||
|
||||
for (unsigned int i = FIRST_HANGUL_FEATURE; i < HANGUL_FEATURE_COUNT; i++)
|
||||
map->add_feature (hangul_features[i], 1, F_NONE);
|
||||
map->add_feature (hangul_features[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -65,7 +65,7 @@ override_features_hangul (hb_ot_shape_planner_t *plan)
|
||||
/* Uniscribe does not apply 'calt' for Hangul, and certain fonts
|
||||
* (Noto Sans CJK, Source Sans Han, etc) apply all of jamo lookups
|
||||
* in calt, which is not desirable. */
|
||||
plan->map.add_feature (HB_TAG('c','a','l','t'), 0, F_GLOBAL);
|
||||
plan->map.disable_feature (HB_TAG('c','a','l','t'));
|
||||
}
|
||||
|
||||
struct hangul_shape_plan_t
|
||||
|
@ -95,42 +95,36 @@ static const indic_config_t indic_configs[] =
|
||||
* Indic shaper.
|
||||
*/
|
||||
|
||||
struct feature_list_t
|
||||
{
|
||||
hb_tag_t tag;
|
||||
hb_ot_map_feature_flags_t flags;
|
||||
};
|
||||
|
||||
static const feature_list_t
|
||||
static const hb_ot_map_feature_t
|
||||
indic_features[] =
|
||||
{
|
||||
/*
|
||||
* Basic features.
|
||||
* These features are applied in order, one at a time, after initial_reordering.
|
||||
*/
|
||||
{HB_TAG('n','u','k','t'), F_GLOBAL},
|
||||
{HB_TAG('a','k','h','n'), F_GLOBAL},
|
||||
{HB_TAG('r','p','h','f'), F_NONE},
|
||||
{HB_TAG('r','k','r','f'), F_GLOBAL},
|
||||
{HB_TAG('p','r','e','f'), F_NONE},
|
||||
{HB_TAG('b','l','w','f'), F_NONE},
|
||||
{HB_TAG('a','b','v','f'), F_NONE},
|
||||
{HB_TAG('h','a','l','f'), F_NONE},
|
||||
{HB_TAG('p','s','t','f'), F_NONE},
|
||||
{HB_TAG('v','a','t','u'), F_GLOBAL},
|
||||
{HB_TAG('c','j','c','t'), F_GLOBAL},
|
||||
{HB_TAG('n','u','k','t'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('a','k','h','n'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('r','p','h','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('r','k','r','f'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('p','r','e','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('b','l','w','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('a','b','v','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('h','a','l','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('p','s','t','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('v','a','t','u'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('c','j','c','t'), F_GLOBAL_MANUAL_JOINERS},
|
||||
/*
|
||||
* Other features.
|
||||
* These features are applied all at once, after final_reordering.
|
||||
* Default Bengali font in Windows for example has intermixed
|
||||
* lookups for init,pres,abvs,blws features.
|
||||
*/
|
||||
{HB_TAG('i','n','i','t'), F_NONE},
|
||||
{HB_TAG('p','r','e','s'), F_GLOBAL},
|
||||
{HB_TAG('a','b','v','s'), F_GLOBAL},
|
||||
{HB_TAG('b','l','w','s'), F_GLOBAL},
|
||||
{HB_TAG('p','s','t','s'), F_GLOBAL},
|
||||
{HB_TAG('h','a','l','n'), F_GLOBAL},
|
||||
{HB_TAG('i','n','i','t'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('h','a','l','n'), F_GLOBAL_MANUAL_JOINERS},
|
||||
/*
|
||||
* Positioning features.
|
||||
* We don't care about the types.
|
||||
@ -169,7 +163,6 @@ enum {
|
||||
|
||||
INDIC_NUM_FEATURES,
|
||||
INDIC_BASIC_FEATURES = INIT, /* Don't forget to update this! */
|
||||
INDIC_SUBST_FEATURES = _DIST /* Don't forget to update this! */
|
||||
};
|
||||
|
||||
static void
|
||||
@ -197,30 +190,27 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
map->enable_feature (HB_TAG('l','o','c','l'));
|
||||
/* The Indic specs do not require ccmp, but we apply it here since if
|
||||
* there is a use of it, it's typically at the beginning. */
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
map->enable_feature (HB_TAG('c','c','m','p'));
|
||||
|
||||
|
||||
unsigned int i = 0;
|
||||
map->add_gsub_pause (initial_reordering);
|
||||
|
||||
for (; i < INDIC_BASIC_FEATURES; i++) {
|
||||
map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
|
||||
map->add_feature (indic_features[i]);
|
||||
map->add_gsub_pause (nullptr);
|
||||
}
|
||||
|
||||
map->add_gsub_pause (final_reordering);
|
||||
|
||||
for (; i < INDIC_SUBST_FEATURES; i++)
|
||||
map->add_feature (indic_features[i].tag, 1, indic_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
|
||||
|
||||
for (; i < INDIC_NUM_FEATURES; i++)
|
||||
map->add_feature (indic_features[i].tag, 1, indic_features[i].flags);
|
||||
map->add_feature (indic_features[i]);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
|
||||
map->add_global_bool_feature (HB_TAG('c','l','i','g'));
|
||||
map->enable_feature (HB_TAG('c','a','l','t'));
|
||||
map->enable_feature (HB_TAG('c','l','i','g'));
|
||||
|
||||
map->add_gsub_pause (clear_syllables);
|
||||
}
|
||||
@ -228,7 +218,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
|
||||
static void
|
||||
override_features_indic (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
|
||||
plan->map.disable_feature (HB_TAG('l','i','g','a'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,32 +32,26 @@
|
||||
* Khmer shaper.
|
||||
*/
|
||||
|
||||
struct feature_list_t
|
||||
{
|
||||
hb_tag_t tag;
|
||||
hb_ot_map_feature_flags_t flags;
|
||||
};
|
||||
|
||||
static const feature_list_t
|
||||
static const hb_ot_map_feature_t
|
||||
khmer_features[] =
|
||||
{
|
||||
/*
|
||||
* Basic features.
|
||||
* These features are applied in order, one at a time, after reordering.
|
||||
*/
|
||||
{HB_TAG('p','r','e','f'), F_NONE},
|
||||
{HB_TAG('b','l','w','f'), F_NONE},
|
||||
{HB_TAG('a','b','v','f'), F_NONE},
|
||||
{HB_TAG('p','s','t','f'), F_NONE},
|
||||
{HB_TAG('c','f','a','r'), F_NONE},
|
||||
{HB_TAG('p','r','e','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('b','l','w','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('a','b','v','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('p','s','t','f'), F_MANUAL_JOINERS},
|
||||
{HB_TAG('c','f','a','r'), F_MANUAL_JOINERS},
|
||||
/*
|
||||
* Other features.
|
||||
* These features are applied all at once.
|
||||
*/
|
||||
{HB_TAG('p','r','e','s'), F_GLOBAL},
|
||||
{HB_TAG('a','b','v','s'), F_GLOBAL},
|
||||
{HB_TAG('b','l','w','s'), F_GLOBAL},
|
||||
{HB_TAG('p','s','t','s'), F_GLOBAL},
|
||||
{HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
|
||||
{HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
|
||||
/*
|
||||
* Positioning features.
|
||||
* We don't care about the types.
|
||||
@ -88,7 +82,6 @@ enum {
|
||||
|
||||
KHMER_NUM_FEATURES,
|
||||
KHMER_BASIC_FEATURES = _PRES, /* Don't forget to update this! */
|
||||
KHMER_SUBST_FEATURES = _DIST, /* Don't forget to update this! */
|
||||
};
|
||||
|
||||
static void
|
||||
@ -123,23 +116,20 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
|
||||
*
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/974
|
||||
*/
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
map->enable_feature (HB_TAG('l','o','c','l'));
|
||||
map->enable_feature (HB_TAG('c','c','m','p'));
|
||||
|
||||
unsigned int i = 0;
|
||||
for (; i < KHMER_BASIC_FEATURES; i++)
|
||||
map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
|
||||
map->add_feature (khmer_features[i]);
|
||||
|
||||
map->add_gsub_pause (clear_syllables);
|
||||
|
||||
for (; i < KHMER_SUBST_FEATURES; i++)
|
||||
map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
|
||||
|
||||
for (; i < KHMER_NUM_FEATURES; i++)
|
||||
map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags);
|
||||
map->add_feature (khmer_features[i]);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
|
||||
map->add_global_bool_feature (HB_TAG('c','l','i','g'));
|
||||
map->enable_feature (HB_TAG('c','a','l','t'));
|
||||
map->enable_feature (HB_TAG('c','l','i','g'));
|
||||
|
||||
}
|
||||
|
||||
@ -149,10 +139,10 @@ override_features_khmer (hb_ot_shape_planner_t *plan)
|
||||
/* Uniscribe does not apply 'kern' in Khmer. */
|
||||
if (hb_options ().uniscribe_bug_compatible)
|
||||
{
|
||||
plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
|
||||
plan->map.disable_feature (HB_TAG('k','e','r','n'));
|
||||
}
|
||||
|
||||
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
|
||||
plan->map.disable_feature (HB_TAG('l','i','g','a'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -96,33 +96,33 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
|
||||
/* Do this before any lookups have been applied. */
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
map->enable_feature (HB_TAG('l','o','c','l'));
|
||||
/* The Indic specs do not require ccmp, but we apply it here since if
|
||||
* there is a use of it, it's typically at the beginning. */
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
map->enable_feature (HB_TAG('c','c','m','p'));
|
||||
|
||||
|
||||
map->add_gsub_pause (initial_reordering);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
|
||||
{
|
||||
map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_feature (basic_features[i], F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_gsub_pause (nullptr);
|
||||
}
|
||||
|
||||
map->add_gsub_pause (final_reordering);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
|
||||
map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_feature (other_features[i], F_GLOBAL | F_MANUAL_ZWJ);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
|
||||
map->add_feature (positioning_features[i], 1, F_GLOBAL);
|
||||
map->enable_feature (positioning_features[i]);
|
||||
}
|
||||
|
||||
static void
|
||||
override_features_myanmar (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
|
||||
plan->map.disable_feature (HB_TAG('l','i','g','a'));
|
||||
}
|
||||
|
||||
|
||||
|
@ -40,7 +40,7 @@ static void
|
||||
collect_features_tibetan (hb_ot_shape_planner_t *plan)
|
||||
{
|
||||
for (const hb_tag_t *script_features = tibetan_features; script_features && *script_features; script_features++)
|
||||
plan->map.add_global_bool_feature (*script_features);
|
||||
plan->map.enable_feature (*script_features);
|
||||
}
|
||||
|
||||
|
||||
|
@ -101,7 +101,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 0990 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 09A0 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
|
||||
/* 09B0 */ B, O, B, O, O, O, B, B, B, B, O, O, CMBlw, B, VPst, VPre,
|
||||
/* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, IND, O,
|
||||
/* 09C0 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPst, VPst, H, IND, O,
|
||||
/* 09D0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, B, B, O, B,
|
||||
/* 09E0 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 09F0 */ B, B, O, O, O, O, O, O, O, O, O, O, B, O, FM, O,
|
||||
@ -134,7 +134,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 0B10 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 0B20 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
|
||||
/* 0B30 */ B, O, B, B, O, B, B, B, B, B, O, O, CMBlw, B, VPst, VAbv,
|
||||
/* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
|
||||
/* 0B40 */ VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, O, O, VPst, VPst, H, O, O,
|
||||
/* 0B50 */ O, O, O, O, O, O, VAbv, VAbv, O, O, O, O, B, B, O, B,
|
||||
/* 0B60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 0B70 */ O, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
|
||||
@ -145,7 +145,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 0B90 */ B, O, B, B, B, B, O, O, O, B, B, O, B, O, B, B,
|
||||
/* 0BA0 */ O, O, O, B, B, O, O, O, B, B, B, O, O, O, B, B,
|
||||
/* 0BB0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, VPst, VPst,
|
||||
/* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, O, O,
|
||||
/* 0BC0 */ VAbv, VPst, VPst, O, O, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, O, O,
|
||||
/* 0BD0 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, O, O,
|
||||
/* 0BE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 0BF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
|
||||
@ -178,7 +178,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 0D10 */ B, O, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 0D20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 0D30 */ B, B, B, B, B, B, B, B, B, B, B, VAbv, VAbv, B, VPst, VPst,
|
||||
/* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPre, VPre, VPre, H, R, O,
|
||||
/* 0D40 */ VPst, VPst, VPst, VBlw, VBlw, O, VPre, VPre, VPre, O, VPst, VPst, VPst, H, R, O,
|
||||
/* 0D50 */ O, O, O, O, IND, IND, IND, VPst, O, O, O, O, O, O, O, B,
|
||||
/* 0D60 */ B, B, VBlw, VBlw, O, O, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 0D70 */ O, O, O, O, O, O, O, O, O, O, IND, IND, IND, IND, IND, IND,
|
||||
@ -190,7 +190,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 0DA0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 0DB0 */ B, B, O, B, B, B, B, B, B, B, B, B, O, B, O, O,
|
||||
/* 0DC0 */ B, B, B, B, B, B, B, O, O, O, H, O, O, O, O, VPst,
|
||||
/* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPre, VPre, VPre, VPre, VPre, VPst,
|
||||
/* 0DD0 */ VPst, VPst, VAbv, VAbv, VBlw, O, VBlw, O, VPst, VPre, VPst, VPre, VPst, VPst, VPst, VPst,
|
||||
/* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 0DF0 */ O, O, VPst, VPst, O, O, O, O,
|
||||
|
||||
@ -238,8 +238,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre,
|
||||
/* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FM, FAbv, CMAbv, FM, FM,
|
||||
/* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPst, VPst,
|
||||
/* 17C0 */ VPst, VPre, VPre, VPre, VPst, VPst, VMAbv, VMPst, VPst, VMAbv, VMAbv, FM, FAbv, CMAbv, FM, FM,
|
||||
/* 17D0 */ FM, VAbv, H, FM, O, O, O, O, O, O, O, O, B, VAbv, O, O,
|
||||
/* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
|
||||
|
||||
@ -296,7 +296,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 1B10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre,
|
||||
/* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O,
|
||||
/* 1B40 */ VPst, VPst, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O,
|
||||
/* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
|
||||
/* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
|
||||
/* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O,
|
||||
@ -319,7 +319,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
|
||||
/* 1C00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 1C10 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPre, VPst, VPst, VBlw, FAbv, FAbv, FAbv,
|
||||
/* 1C20 */ B, B, B, B, SUB, SUB, VPst, VPre, VPre, VPst, VPst, VPst, VBlw, FAbv, FAbv, FAbv,
|
||||
/* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FM, CMBlw, O, O, O, O, O, O, O, O,
|
||||
/* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B,
|
||||
|
||||
@ -564,7 +564,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 11310 */ B, O, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 11320 */ B, B, B, B, B, B, B, B, B, O, B, B, B, B, B, B,
|
||||
/* 11330 */ B, O, B, B, O, B, B, B, B, B, O, CMBlw, CMBlw, B, VPst, VPst,
|
||||
/* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPre, VPre, H, O, O,
|
||||
/* 11340 */ VAbv, VPst, VPst, VPst, VPst, O, O, VPre, VPre, O, O, VPst, VPst, H, O, O,
|
||||
/* 11350 */ O, O, O, O, O, O, O, VPst, O, O, O, O, O, O, B, B,
|
||||
/* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
|
||||
/* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
|
||||
@ -588,7 +588,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 11480 */ O, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 11490 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 114A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPre, VPre, VPst, VPre, VMAbv,
|
||||
/* 114B0 */ VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VPre, VAbv, VPst, VPst, VPst, VPst, VMAbv,
|
||||
/* 114C0 */ VMAbv, VMPst, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O,
|
||||
/* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
|
||||
|
||||
@ -600,7 +600,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
|
||||
/* 11580 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 11590 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
|
||||
/* 115A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, VPst,
|
||||
/* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPre, VPre, VPre, VMAbv, VMAbv, VMPst, H,
|
||||
/* 115B0 */ VPre, VPst, VBlw, VBlw, VBlw, VBlw, O, O, VPre, VPst, VPst, VPst, VMAbv, VMAbv, VMPst, H,
|
||||
/* 115C0 */ CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
|
||||
/* 115D0 */ O, O, O, O, O, O, O, O, B, B, B, B, VBlw, VBlw, O, O,
|
||||
/* 115E0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
|
||||
|
@ -129,37 +129,37 @@ collect_features_use (hb_ot_shape_planner_t *plan)
|
||||
map->add_gsub_pause (setup_syllables);
|
||||
|
||||
/* "Default glyph pre-processing group" */
|
||||
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
|
||||
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
|
||||
map->add_global_bool_feature (HB_TAG('n','u','k','t'));
|
||||
map->add_global_bool_feature (HB_TAG('a','k','h','n'));
|
||||
map->enable_feature (HB_TAG('l','o','c','l'));
|
||||
map->enable_feature (HB_TAG('c','c','m','p'));
|
||||
map->enable_feature (HB_TAG('n','u','k','t'));
|
||||
map->add_feature (HB_TAG('a','k','h','n'), F_GLOBAL | F_MANUAL_ZWJ);
|
||||
|
||||
/* "Reordering group" */
|
||||
map->add_gsub_pause (clear_substitution_flags);
|
||||
map->add_feature (HB_TAG('r','p','h','f'), 1, F_MANUAL_ZWJ);
|
||||
map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ);
|
||||
map->add_gsub_pause (record_rphf);
|
||||
map->add_gsub_pause (clear_substitution_flags);
|
||||
map->add_feature (HB_TAG('p','r','e','f'), 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_feature (HB_TAG('p','r','e','f'), F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_gsub_pause (record_pref);
|
||||
|
||||
/* "Orthographic unit shaping group" */
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
|
||||
map->add_feature (basic_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_feature (basic_features[i], F_GLOBAL | F_MANUAL_ZWJ);
|
||||
|
||||
map->add_gsub_pause (reorder);
|
||||
|
||||
/* "Topographical features" */
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++)
|
||||
map->add_feature (arabic_features[i], 1, F_NONE);
|
||||
map->add_feature (arabic_features[i]);
|
||||
map->add_gsub_pause (nullptr);
|
||||
|
||||
/* "Standard typographic presentation" */
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
|
||||
map->add_feature (other_features[i], 1, F_GLOBAL | F_MANUAL_ZWJ);
|
||||
map->add_feature (other_features[i], F_GLOBAL | F_MANUAL_ZWJ);
|
||||
|
||||
/* "Positional feature application" */
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (positioning_features); i++)
|
||||
map->add_feature (positioning_features[i], 1, F_GLOBAL);
|
||||
map->enable_feature (positioning_features[i]);
|
||||
}
|
||||
|
||||
struct use_shape_plan_t
|
||||
|
@ -444,7 +444,8 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
||||
if (!plan->has_kern) return;
|
||||
|
||||
OT::hb_ot_apply_context_t c (1, font, buffer);
|
||||
c.set_lookup_mask (plan->kern_mask);
|
||||
hb_mask_t kern_mask = plan->kern_mask;
|
||||
c.set_lookup_mask (kern_mask);
|
||||
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
||||
OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
|
||||
skippy_iter.init (&c);
|
||||
@ -454,6 +455,12 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
for (unsigned int idx = 0; idx < count;)
|
||||
{
|
||||
if (!(info[idx].mask & kern_mask))
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
skippy_iter.reset (idx, 1);
|
||||
if (!skippy_iter.next ())
|
||||
{
|
||||
|
@ -71,17 +71,17 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
||||
{
|
||||
hb_ot_map_builder_t *map = &planner->map;
|
||||
|
||||
map->add_global_bool_feature (HB_TAG('r','v','r','n'));
|
||||
map->enable_feature (HB_TAG('r','v','r','n'));
|
||||
map->add_gsub_pause (nullptr);
|
||||
|
||||
switch (props->direction) {
|
||||
case HB_DIRECTION_LTR:
|
||||
map->add_global_bool_feature (HB_TAG ('l','t','r','a'));
|
||||
map->add_global_bool_feature (HB_TAG ('l','t','r','m'));
|
||||
map->enable_feature (HB_TAG ('l','t','r','a'));
|
||||
map->enable_feature (HB_TAG ('l','t','r','m'));
|
||||
break;
|
||||
case HB_DIRECTION_RTL:
|
||||
map->add_global_bool_feature (HB_TAG ('r','t','l','a'));
|
||||
map->add_feature (HB_TAG ('r','t','l','m'), 1, F_NONE);
|
||||
map->enable_feature (HB_TAG ('r','t','l','a'));
|
||||
map->add_feature (HB_TAG ('r','t','l','m'));
|
||||
break;
|
||||
case HB_DIRECTION_TTB:
|
||||
case HB_DIRECTION_BTT:
|
||||
@ -91,22 +91,22 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
||||
}
|
||||
|
||||
/* Automatic fractions. */
|
||||
map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE);
|
||||
map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE);
|
||||
map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE);
|
||||
map->add_feature (HB_TAG ('f','r','a','c'));
|
||||
map->add_feature (HB_TAG ('n','u','m','r'));
|
||||
map->add_feature (HB_TAG ('d','n','o','m'));
|
||||
|
||||
/* Random! */
|
||||
map->add_feature (HB_TAG ('r','a','n','d'), HB_OT_MAP_MAX_VALUE, F_GLOBAL | F_RANDOM);
|
||||
map->add_feature (HB_TAG ('r','a','n','d'), F_GLOBAL | F_RANDOM, HB_OT_MAP_MAX_VALUE);
|
||||
|
||||
if (planner->shaper->collect_features)
|
||||
planner->shaper->collect_features (planner);
|
||||
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
|
||||
map->add_global_bool_feature (common_features[i]);
|
||||
map->enable_feature (common_features[i]);
|
||||
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
|
||||
map->add_feature (horizontal_features[i], 1, F_GLOBAL |
|
||||
map->add_feature (horizontal_features[i], F_GLOBAL |
|
||||
(horizontal_features[i] == HB_TAG('k','e','r','n') ?
|
||||
F_HAS_FALLBACK : F_NONE));
|
||||
else
|
||||
@ -115,7 +115,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
||||
* matter which script/langsys it is listed (or not) under.
|
||||
* See various bugs referenced from:
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/63 */
|
||||
map->add_feature (HB_TAG ('v','e','r','t'), 1, F_GLOBAL | F_GLOBAL_SEARCH);
|
||||
map->add_feature (HB_TAG ('v','e','r','t'), F_GLOBAL | F_GLOBAL_SEARCH);
|
||||
}
|
||||
|
||||
if (planner->shaper->override_features)
|
||||
@ -124,9 +124,10 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
||||
for (unsigned int i = 0; i < num_user_features; i++)
|
||||
{
|
||||
const hb_feature_t *feature = &user_features[i];
|
||||
map->add_feature (feature->tag, feature->value,
|
||||
(feature->start == 0 && feature->end == (unsigned int) -1) ?
|
||||
F_GLOBAL : F_NONE);
|
||||
map->add_feature (feature->tag,
|
||||
(feature->start == HB_FEATURE_GLOBAL_START &&
|
||||
feature->end == HB_FEATURE_GLOBAL_END) ? F_GLOBAL : F_NONE,
|
||||
feature->value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -240,7 +240,9 @@ hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||
}
|
||||
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static void free_static_ucdn_funcs (void);
|
||||
#endif
|
||||
|
||||
static struct hb_ucdn_unicode_funcs_lazy_loader_t : hb_unicode_funcs_lazy_loader_t<hb_ucdn_unicode_funcs_lazy_loader_t>
|
||||
{
|
||||
|
@ -308,6 +308,8 @@ hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
|
||||
{
|
||||
if (unlikely (hb_object_is_inert (ufuncs)))
|
||||
return;
|
||||
if (ufuncs->immutable)
|
||||
return;
|
||||
|
||||
ufuncs->immutable = true;
|
||||
}
|
||||
|
@ -35,6 +35,10 @@
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#ifndef _POSIX_C_SOURCE
|
||||
#define _POSIX_C_SOURCE 200809L
|
||||
#endif
|
||||
|
||||
#include "hb.h"
|
||||
#define HB_H_IN
|
||||
#ifdef HAVE_OT
|
||||
|
@ -16,6 +16,8 @@ EXTRA_DIST += CMakeLists.txt
|
||||
|
||||
EXTRA_DIST += fonts
|
||||
|
||||
LINK = $(CXXLINK)
|
||||
|
||||
if HAVE_GLIB
|
||||
AM_CPPFLAGS = -DSRCDIR="\"$(srcdir)\"" -I$(top_srcdir)/src/ -I$(top_builddir)/src/ $(GLIB_CFLAGS)
|
||||
LDADD = $(top_builddir)/src/libharfbuzz.la $(GLIB_LIBS)
|
||||
@ -28,13 +30,13 @@ noinst_PROGRAMS = $(TEST_PROGS)
|
||||
TEST_PROGS = \
|
||||
test-blob \
|
||||
test-buffer \
|
||||
test-collect-unicodes \
|
||||
test-common \
|
||||
test-font \
|
||||
test-object \
|
||||
test-set \
|
||||
test-shape \
|
||||
test-subset \
|
||||
test-subset-codepoints \
|
||||
test-subset-cmap \
|
||||
test-subset-glyf \
|
||||
test-subset-hdmx \
|
||||
@ -78,6 +80,17 @@ TEST_PROGS += \
|
||||
test-ot-tag \
|
||||
$(NULL)
|
||||
|
||||
if HAVE_PTHREAD
|
||||
if HAVE_FREETYPE
|
||||
TEST_PROGS += test-multithread
|
||||
test_multithread_CFLAGS = $(CFLAGS) $(PTHREAD_CFLAGS) $(FREETYPE_CFLAGS)
|
||||
test_multithread_LDADD = $(LDADD) $(PTHREAD_LIBS) $(FREETYPE_LIBS)
|
||||
# The auto-generated link rule somehow includes CFLAGS as well. Without
|
||||
# it, pthread link fails, because, who knows why, $PTHREAD_LIBS is empty.
|
||||
test_multithread_LINK = $(LINK) $(PTHREAD_CFLAGS)
|
||||
endif
|
||||
endif
|
||||
|
||||
if HAVE_FREETYPE
|
||||
TEST_PROGS += \
|
||||
test-ot-math \
|
||||
|
@ -42,6 +42,7 @@ HB_BEGIN_DECLS
|
||||
/* Just in case */
|
||||
#undef G_DISABLE_ASSERT
|
||||
|
||||
#define HB_UNUSED G_GNUC_UNUSED
|
||||
|
||||
/* Misc */
|
||||
|
||||
|
@ -195,7 +195,7 @@ fixture_init (fixture_t *fixture, gconstpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
fixture_finish (fixture_t *fixture, gconstpointer user_data)
|
||||
fixture_finish (fixture_t *fixture, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
hb_blob_destroy (fixture->blob);
|
||||
g_assert_cmpint (fixture->freed, ==, 1);
|
||||
|
@ -58,7 +58,7 @@
|
||||
#endif
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
main (void)
|
||||
{
|
||||
return !*hb_shape_list_shapers ();
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ free_up (void *user_data)
|
||||
}
|
||||
|
||||
static hb_blob_t *
|
||||
get_table (hb_face_t *face, hb_tag_t tag, void *user_data)
|
||||
get_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data HB_UNUSED)
|
||||
{
|
||||
if (tag == HB_TAG ('a','b','c','d'))
|
||||
return hb_blob_create (test_data, sizeof (test_data), HB_MEMORY_MODE_READONLY, NULL, NULL);
|
||||
@ -210,10 +210,10 @@ test_fontfuncs_nil (void)
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
contour_point_func1 (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t glyph, unsigned int point_index,
|
||||
contour_point_func1 (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
|
||||
hb_codepoint_t glyph, unsigned int point_index HB_UNUSED,
|
||||
hb_position_t *x, hb_position_t *y,
|
||||
void *user_data)
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
if (glyph == 1) {
|
||||
*x = 2;
|
||||
@ -230,10 +230,10 @@ contour_point_func1 (hb_font_t *font, void *font_data,
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
contour_point_func2 (hb_font_t *font, void *font_data,
|
||||
contour_point_func2 (hb_font_t *font, void *font_data HB_UNUSED,
|
||||
hb_codepoint_t glyph, unsigned int point_index,
|
||||
hb_position_t *x, hb_position_t *y,
|
||||
void *user_data)
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
if (glyph == 1) {
|
||||
*x = 6;
|
||||
@ -246,9 +246,9 @@ contour_point_func2 (hb_font_t *font, void *font_data,
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
glyph_h_advance_func1 (hb_font_t *font, void *font_data,
|
||||
glyph_h_advance_func1 (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data)
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
if (glyph == 1)
|
||||
return 8;
|
||||
|
170
test/api/test-multithread.c
Normal file
170
test/api/test-multithread.c
Normal file
@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright © 2018 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include <hb.h>
|
||||
#include <hb-ft.h>
|
||||
#include <hb-ot.h>
|
||||
|
||||
static const char *text = "طرحنَما";
|
||||
static const char *path =
|
||||
#if defined(__linux__)
|
||||
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf";
|
||||
#elif defined(_WIN32) || defined(_WIN64)
|
||||
"C:\\Windows\\Fonts\\tahoma.ttf";
|
||||
#elif __APPLE__
|
||||
"/Library/Fonts/Tahoma.ttf";
|
||||
#endif
|
||||
|
||||
static int num_threads = 30;
|
||||
static int num_iters = 200;
|
||||
|
||||
static hb_font_t *font;
|
||||
static hb_buffer_t *ref_buffer;
|
||||
|
||||
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static void
|
||||
fill_the_buffer (hb_buffer_t *buffer)
|
||||
{
|
||||
hb_buffer_add_utf8 (buffer, text, sizeof (text), 0, sizeof (text));
|
||||
hb_buffer_guess_segment_properties (buffer);
|
||||
hb_shape (font, buffer, NULL, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
validity_check (hb_buffer_t *buffer) {
|
||||
if (hb_buffer_diff (ref_buffer, buffer, (hb_codepoint_t) -1, 0))
|
||||
{
|
||||
fprintf (stderr, "One of the buffers was different from the reference.\n");
|
||||
char out[255];
|
||||
|
||||
hb_buffer_serialize_glyphs (buffer, 0, hb_buffer_get_length (ref_buffer),
|
||||
out, sizeof (out), NULL,
|
||||
font, HB_BUFFER_SERIALIZE_FORMAT_TEXT,
|
||||
HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES);
|
||||
fprintf (stderr, "Actual: %s\n", out);
|
||||
|
||||
hb_buffer_serialize_glyphs (ref_buffer, 0, hb_buffer_get_length (ref_buffer),
|
||||
out, sizeof (out), NULL,
|
||||
font, HB_BUFFER_SERIALIZE_FORMAT_TEXT,
|
||||
HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES);
|
||||
fprintf (stderr, "Expected: %s\n", out);
|
||||
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
thread_func (void *data)
|
||||
{
|
||||
hb_buffer_t *buffer = (hb_buffer_t *) data;
|
||||
|
||||
pthread_mutex_lock (&mutex);
|
||||
pthread_mutex_unlock (&mutex);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < num_iters; i++)
|
||||
{
|
||||
hb_buffer_clear_contents (buffer);
|
||||
fill_the_buffer (buffer);
|
||||
validity_check (buffer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
test_body (void)
|
||||
{
|
||||
int i;
|
||||
int num_threads = 30;
|
||||
pthread_t *threads = calloc (num_threads, sizeof (pthread_t));
|
||||
hb_buffer_t **buffers = calloc (num_threads, sizeof (hb_buffer_t *));
|
||||
|
||||
pthread_mutex_lock (&mutex);
|
||||
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
hb_buffer_t *buffer = hb_buffer_create ();
|
||||
buffers[i] = buffer;
|
||||
pthread_create (&threads[i], NULL, thread_func, buffer);
|
||||
}
|
||||
|
||||
/* Let them loose! */
|
||||
pthread_mutex_unlock (&mutex);
|
||||
|
||||
for (i = 0; i < num_threads; i++)
|
||||
{
|
||||
pthread_join (threads[i], NULL);
|
||||
hb_buffer_destroy (buffers[i]);
|
||||
}
|
||||
|
||||
free (buffers);
|
||||
free (threads);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (argc > 1)
|
||||
num_threads = atoi (argv[1]);
|
||||
if (argc > 2)
|
||||
num_iters = atoi (argv[2]);
|
||||
|
||||
// Dummy call to alleviate _guess_segment_properties thread safety-ness
|
||||
// https://github.com/harfbuzz/harfbuzz/issues/1191
|
||||
hb_language_get_default ();
|
||||
|
||||
hb_blob_t *blob = hb_blob_create_from_file (path);
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
font = hb_font_create (face);
|
||||
|
||||
hb_ot_font_set_funcs (font);
|
||||
|
||||
ref_buffer = hb_buffer_create ();
|
||||
fill_the_buffer (ref_buffer);
|
||||
|
||||
test_body ();
|
||||
|
||||
/* hb-font backed by FreeType functions can only be used from
|
||||
* one thread at a time, because that's FT_Face's MT guarantee.
|
||||
* So, disable this, even though it works "most of the time". */
|
||||
//hb_ft_font_set_funcs (font);
|
||||
//test_body ();
|
||||
|
||||
hb_buffer_destroy (ref_buffer);
|
||||
|
||||
hb_font_destroy (font);
|
||||
hb_face_destroy (face);
|
||||
hb_blob_destroy (blob);
|
||||
|
||||
return 0;
|
||||
}
|
@ -99,6 +99,7 @@ static hb_face_t *cpal_v0 = NULL;
|
||||
static hb_face_t *cpal_v1 = NULL;
|
||||
|
||||
|
||||
#if 0
|
||||
#define assert_color_rgba(colors, i, r, g, b, a) G_STMT_START { \
|
||||
const hb_ot_color_t *_colors = (colors); \
|
||||
const size_t _i = (i); \
|
||||
@ -122,7 +123,6 @@ static hb_face_t *cpal_v1 = NULL;
|
||||
} G_STMT_END
|
||||
|
||||
|
||||
#if 0
|
||||
static void
|
||||
test_hb_ot_color_get_palette_count (void)
|
||||
{
|
||||
|
@ -41,9 +41,9 @@
|
||||
static const char test_data[] = "test\0data";
|
||||
|
||||
static hb_position_t
|
||||
glyph_h_advance_func (hb_font_t *font, void *font_data,
|
||||
glyph_h_advance_func (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
|
||||
hb_codepoint_t glyph,
|
||||
void *user_data)
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
switch (glyph) {
|
||||
case 1: return 10;
|
||||
@ -54,10 +54,10 @@ glyph_h_advance_func (hb_font_t *font, void *font_data,
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
glyph_func (hb_font_t *font, void *font_data,
|
||||
hb_codepoint_t unicode, hb_codepoint_t variant_selector,
|
||||
glyph_func (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
|
||||
hb_codepoint_t unicode, hb_codepoint_t variation_selector HB_UNUSED,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data)
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
switch (unicode) {
|
||||
case 'T': *glyph = 1; return TRUE;
|
||||
@ -68,9 +68,9 @@ glyph_func (hb_font_t *font, void *font_data,
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
glyph_h_kerning_func (hb_font_t *font, void *font_data,
|
||||
glyph_h_kerning_func (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
|
||||
hb_codepoint_t left, hb_codepoint_t right,
|
||||
void *user_data)
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
if (left == 1 && right == 2)
|
||||
return -2;
|
||||
|
@ -645,18 +645,18 @@ typedef struct {
|
||||
} data_fixture_t;
|
||||
|
||||
static void
|
||||
data_fixture_init (data_fixture_t *f, gconstpointer user_data)
|
||||
data_fixture_init (data_fixture_t *f, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
f->data[0].value = MAGIC0;
|
||||
f->data[1].value = MAGIC1;
|
||||
}
|
||||
static void
|
||||
data_fixture_finish (data_fixture_t *f, gconstpointer user_data)
|
||||
data_fixture_finish (data_fixture_t *f HB_UNUSED, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
test_unicode_subclassing_nil (data_fixture_t *f, gconstpointer user_data)
|
||||
test_unicode_subclassing_nil (data_fixture_t *f, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
hb_unicode_funcs_t *uf, *aa;
|
||||
|
||||
@ -678,7 +678,7 @@ test_unicode_subclassing_nil (data_fixture_t *f, gconstpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
test_unicode_subclassing_default (data_fixture_t *f, gconstpointer user_data)
|
||||
test_unicode_subclassing_default (data_fixture_t *f, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
hb_unicode_funcs_t *uf, *aa;
|
||||
|
||||
@ -697,7 +697,7 @@ test_unicode_subclassing_default (data_fixture_t *f, gconstpointer user_data)
|
||||
}
|
||||
|
||||
static void
|
||||
test_unicode_subclassing_deep (data_fixture_t *f, gconstpointer user_data)
|
||||
test_unicode_subclassing_deep (data_fixture_t *f, gconstpointer user_data HB_UNUSED)
|
||||
{
|
||||
hb_unicode_funcs_t *uf, *aa;
|
||||
|
||||
|
@ -4,6 +4,8 @@ from __future__ import print_function, division, absolute_import
|
||||
|
||||
import sys, os, subprocess
|
||||
|
||||
if os.environ.get ("SKIPFUZZERTESTS", "") != "": sys.exit (0)
|
||||
|
||||
srcdir = os.environ.get ("srcdir", ".")
|
||||
EXEEXT = os.environ.get ("EXEEXT", "")
|
||||
top_builddir = os.environ.get ("top_builddir", ".")
|
||||
|
@ -4,6 +4,8 @@ from __future__ import print_function, division, absolute_import
|
||||
|
||||
import sys, os, subprocess
|
||||
|
||||
if os.environ.get ("SKIPFUZZERTESTS", "") != "": sys.exit (0)
|
||||
|
||||
srcdir = os.environ.get ("srcdir", ".")
|
||||
EXEEXT = os.environ.get ("EXEEXT", "")
|
||||
top_builddir = os.environ.get ("top_builddir", ".")
|
||||
|
@ -28,6 +28,10 @@ tests/MORX-25.tests
|
||||
tests/MORX-26.tests
|
||||
tests/MORX-27.tests
|
||||
tests/MORX-28.tests
|
||||
tests/MORX-29.tests
|
||||
tests/MORX-30.tests
|
||||
tests/MORX-31.tests
|
||||
tests/MORX-32.tests
|
||||
|
||||
# Rounding differences
|
||||
tests/SHARAN-1.tests
|
||||
|
@ -52,7 +52,11 @@ DISBALED_TESTS = \
|
||||
tests/MORX-26.tests \
|
||||
tests/MORX-27.tests \
|
||||
tests/MORX-28.tests \
|
||||
tests/MORX-29.tests \
|
||||
tests/MORX-2.tests \
|
||||
tests/MORX-30.tests \
|
||||
tests/MORX-31.tests \
|
||||
tests/MORX-32.tests \
|
||||
tests/MORX-3.tests \
|
||||
tests/MORX-4.tests \
|
||||
tests/MORX-5.tests \
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,4 @@
|
||||
../fonts/TestMORXTwentynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0050,U+0051,U+0052,U+004D,U+004D,U+0058,U+0058,U+004D,U+004D,U+0059,U+0059,U+0041,U+005A,U+005A:[P|Q@333,0|R@699,0|M@1050,0|M@1880,0|X@2710,0|X@3074,0|M@3438,0|I@4268,0|N@5098,0|S@5928,0|M@6758,0|Y@7588,0|Y@7920,0|A@8252,0|Z@9082,0|Z@9404,0]
|
||||
../fonts/TestMORXTwentynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0050,U+0051,U+0052,U+004D,U+004D,U+0058,U+0058,U+004D,U+004D,U+0059,U+0059,U+0042,U+005A,U+005A:[P|Q@333,0|R@699,0|M@1050,0|M@1880,0|X@2710,0|X@3074,0|M@3438,0|M@4268,0|I@5098,0|N@5928,0|S@6758,0|Y@7588,0|Y@7920,0|B@8252,0|Z@9082,0|Z@9404,0]
|
||||
../fonts/TestMORXTwentynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0050,U+0051,U+0052,U+004D,U+004D,U+0058,U+0058,U+004D,U+004D,U+0059,U+0059,U+0043,U+005A,U+005A:[P|Q@333,0|R@699,0|M@1050,0|M@1880,0|X@2710,0|X@3074,0|M@3438,0|M@4268,0|Y@5098,0|Y@5430,0|I@5762,0|N@6592,0|S@7422,0|C@8252,0|Z@9082,0|Z@9404,0]
|
||||
../fonts/TestMORXTwentynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0050,U+0051,U+0052,U+004D,U+004D,U+0058,U+0058,U+004D,U+004D,U+0059,U+0059,U+0044,U+005A,U+005A:[P|Q@333,0|R@699,0|M@1050,0|M@1880,0|X@2710,0|X@3074,0|M@3438,0|M@4268,0|Y@5098,0|Y@5430,0|D@5762,0|I@6592,0|N@7422,0|S@8252,0|Z@9082,0|Z@9404,0]
|
@ -0,0 +1,4 @@
|
||||
../fonts/TestMORXTwentynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0050,U+0051,U+0052,U+004D,U+004D,U+0058,U+0058,U+0058,U+0041,U+0059,U+0059,U+0041,U+005A,U+005A:[P|Q@333,0|R@699,0|M@1050,0|I@1880,0|N@2710,0|S@3540,0|I@4370,0|N@5200,0|S@6030,0|M@6860,0|X@7690,0|X@8054,0|X@8418,0|A@8782,0|Y@9612,0|Y@9944,0|A@10276,0|Z@11106,0|Z@11428,0]
|
||||
../fonts/TestMORXTwentynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0050,U+0051,U+0052,U+004D,U+004D,U+0058,U+0058,U+0058,U+0041,U+0059,U+0059,U+0042,U+005A,U+005A:[P|Q@333,0|R@699,0|M@1050,0|I@1880,0|I@2710,0|N@3540,0|S@4370,0|N@5200,0|S@6030,0|M@6860,0|X@7690,0|X@8054,0|X@8418,0|A@8782,0|Y@9612,0|Y@9944,0|B@10276,0|Z@11106,0|Z@11428,0]
|
||||
../fonts/TestMORXTwentynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0050,U+0051,U+0052,U+004D,U+004D,U+0058,U+0058,U+0058,U+0042,U+0059,U+0059,U+0041,U+005A,U+005A:[P|Q@333,0|R@699,0|M@1050,0|I@1880,0|N@2710,0|S@3540,0|M@4370,0|I@5200,0|N@6030,0|S@6860,0|X@7690,0|X@8054,0|X@8418,0|B@8782,0|Y@9612,0|Y@9944,0|A@10276,0|Z@11106,0|Z@11428,0]
|
||||
../fonts/TestMORXTwentynine.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0050,U+0051,U+0052,U+004D,U+004D,U+0058,U+0058,U+0058,U+0042,U+0059,U+0059,U+0042,U+005A,U+005A:[P|Q@333,0|R@699,0|M@1050,0|M@1880,0|I@2710,0|N@3540,0|S@4370,0|I@5200,0|N@6030,0|S@6860,0|X@7690,0|X@8054,0|X@8418,0|B@8782,0|Y@9612,0|Y@9944,0|B@10276,0|Z@11106,0|Z@11428,0]
|
@ -0,0 +1,8 @@
|
||||
../fonts/TestMORXThirtyone.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0058,U+0041,U+0059,U+0059,U+0041,U+005A,U+005A:[X|X@364,0|I@728,0|N@1558,0|S@2388,0|A@3218,0|Y@4048,0|Y@4380,0|A@4712,0|Z@5542,0|Z@5864,0]
|
||||
../fonts/TestMORXThirtyone.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0058,U+0041,U+0059,U+0059,U+0042,U+0059,U+0059:[X|X@364,0|A@728,0|I@1558,0|N@2388,0|S@3218,0|Y@4048,0|Y@4380,0|B@4712,0|Y@5542,0|Y@5874,0]
|
||||
../fonts/TestMORXThirtyone.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0058,U+0042,U+0059,U+0059,U+0041,U+005A,U+005A:[X|X@364,0|I@728,0|N@1558,0|S@2388,0|B@3218,0|Y@4048,0|Y@4380,0|A@4712,0|Z@5542,0|Z@5864,0]
|
||||
../fonts/TestMORXThirtyone.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0058,U+0042,U+0059,U+0059,U+0042,U+005A,U+005A:[X|X@364,0|B@728,0|I@1558,0|N@2388,0|S@3218,0|Y@4048,0|Y@4380,0|B@4712,0|Z@5542,0|Z@5864,0]
|
||||
../fonts/TestMORXThirtyone.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+004D,U+0050,U+0051,U+0052,U+0041,U+0058,U+0059,U+005A,U+0041:[I|N@830,0|S@1660,0|M@2490,0|P@3320,0|Q@3653,0|R@4019,0|I@4370,0|N@5200,0|S@6030,0|A@6860,0|X@7690,0|Y@8054,0|Z@8386,0|A@8708,0]
|
||||
../fonts/TestMORXThirtyone.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+004D,U+0050,U+0051,U+0052,U+0041,U+0058,U+0059,U+005A,U+0042:[I|N@830,0|S@1660,0|M@2490,0|P@3320,0|Q@3653,0|R@4019,0|A@4370,0|I@5200,0|N@6030,0|S@6860,0|X@7690,0|Y@8054,0|Z@8386,0|B@8708,0]
|
||||
../fonts/TestMORXThirtyone.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+004D,U+0050,U+0051,U+0052,U+0042,U+0058,U+0059,U+005A,U+0041:[M|I@830,0|N@1660,0|S@2490,0|P@3320,0|Q@3653,0|R@4019,0|I@4370,0|N@5200,0|S@6030,0|B@6860,0|X@7690,0|Y@8054,0|Z@8386,0|A@8708,0]
|
||||
../fonts/TestMORXThirtyone.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+004D,U+0050,U+0051,U+0052,U+0042,U+0058,U+0059,U+005A,U+0042:[M|I@830,0|N@1660,0|S@2490,0|P@3320,0|Q@3653,0|R@4019,0|B@4370,0|I@5200,0|N@6030,0|S@6860,0|X@7690,0|Y@8054,0|Z@8386,0|B@8708,0]
|
@ -0,0 +1,4 @@
|
||||
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[I|N@830,0|S@1660,0|A@2490,0]
|
||||
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[I|N@830,0|S@1660,0|X@2490,0|A@2854,0|Y@3684,0]
|
||||
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0042:[B|I@830,0|N@1660,0|S@2490,0]
|
||||
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0042,U+0059:[X|I@364,0|N@1194,0|S@2024,0|B@2854,0|Y@3684,0]
|
@ -4,6 +4,10 @@ from __future__ import print_function, division, absolute_import
|
||||
|
||||
import sys, os, re, difflib, unicodedata, errno, cgi
|
||||
from itertools import *
|
||||
try:
|
||||
import unicodedata2 as unicodedata
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
diff_symbols = "-+=*&^%$#@!~/"
|
||||
diff_colors = ['red', 'green', 'blue']
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "view-cairo.hh"
|
||||
|
||||
#define DEFAULT_FONT_SIZE 256
|
||||
#define SUBPIXEL_BITS 8
|
||||
#define SUBPIXEL_BITS 6
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
|
@ -64,11 +64,13 @@ _cairo_eps_surface_create_for_stream (cairo_write_func_t write_func,
|
||||
|
||||
static FT_Library ft_library;
|
||||
|
||||
#ifdef HAVE_ATEXIT
|
||||
static inline
|
||||
void free_ft_library (void)
|
||||
{
|
||||
FT_Done_FreeType (ft_library);
|
||||
}
|
||||
#endif
|
||||
|
||||
cairo_scaled_font_t *
|
||||
helper_cairo_create_scaled_font (const font_options_t *font_opts)
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include <hb-ot.h>
|
||||
#endif
|
||||
|
||||
struct supported_font_funcs_t {
|
||||
static struct supported_font_funcs_t {
|
||||
char name[4];
|
||||
void (*func) (hb_font_t *);
|
||||
} supported_font_funcs[] =
|
||||
@ -172,9 +172,9 @@ parse_margin (const char *name G_GNUC_UNUSED,
|
||||
view_options_t *view_opts = (view_options_t *) data;
|
||||
view_options_t::margin_t &m = view_opts->margin;
|
||||
switch (sscanf (arg, "%lf%*[ ,]%lf%*[ ,]%lf%*[ ,]%lf", &m.t, &m.r, &m.b, &m.l)) {
|
||||
case 1: m.r = m.t;
|
||||
case 2: m.b = m.t;
|
||||
case 3: m.l = m.r;
|
||||
case 1: m.r = m.t; HB_FALLTHROUGH;
|
||||
case 2: m.b = m.t; HB_FALLTHROUGH;
|
||||
case 3: m.l = m.r; HB_FALLTHROUGH;
|
||||
case 4: return true;
|
||||
default:
|
||||
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||
@ -489,7 +489,7 @@ parse_font_size (const char *name G_GNUC_UNUSED,
|
||||
return true;
|
||||
}
|
||||
switch (sscanf (arg, "%lf%*[ ,]%lf", &font_opts->font_size_x, &font_opts->font_size_y)) {
|
||||
case 1: font_opts->font_size_y = font_opts->font_size_x;
|
||||
case 1: font_opts->font_size_y = font_opts->font_size_x; HB_FALLTHROUGH;
|
||||
case 2: return true;
|
||||
default:
|
||||
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||
@ -507,7 +507,7 @@ parse_font_ppem (const char *name G_GNUC_UNUSED,
|
||||
{
|
||||
font_options_t *font_opts = (font_options_t *) data;
|
||||
switch (sscanf (arg, "%d%*[ ,]%d", &font_opts->x_ppem, &font_opts->y_ppem)) {
|
||||
case 1: font_opts->y_ppem = font_opts->x_ppem;
|
||||
case 1: font_opts->y_ppem = font_opts->x_ppem; HB_FALLTHROUGH;
|
||||
case 2: return true;
|
||||
default:
|
||||
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
|
||||
|
@ -56,16 +56,19 @@ void fail (hb_bool_t suggest_help, const char *format, ...) G_GNUC_NORETURN G_GN
|
||||
|
||||
struct option_group_t
|
||||
{
|
||||
virtual ~option_group_t (void) {}
|
||||
|
||||
virtual void add_options (struct option_parser_t *parser) = 0;
|
||||
|
||||
virtual void pre_parse (GError **error G_GNUC_UNUSED) {};
|
||||
virtual void post_parse (GError **error G_GNUC_UNUSED) {};
|
||||
virtual void pre_parse (GError **error G_GNUC_UNUSED) {}
|
||||
virtual void post_parse (GError **error G_GNUC_UNUSED) {}
|
||||
};
|
||||
|
||||
|
||||
struct option_parser_t
|
||||
{
|
||||
option_parser_t (const char *usage) {
|
||||
option_parser_t (const char *usage)
|
||||
{
|
||||
memset (this, 0, sizeof (*this));
|
||||
usage_str = usage;
|
||||
context = g_option_context_new (usage);
|
||||
@ -73,7 +76,8 @@ struct option_parser_t
|
||||
|
||||
add_main_options ();
|
||||
}
|
||||
~option_parser_t (void) {
|
||||
~option_parser_t (void)
|
||||
{
|
||||
g_option_context_free (context);
|
||||
g_ptr_array_foreach (to_free, (GFunc) g_free, nullptr);
|
||||
g_ptr_array_free (to_free, TRUE);
|
||||
@ -113,7 +117,8 @@ struct option_parser_t
|
||||
|
||||
struct view_options_t : option_group_t
|
||||
{
|
||||
view_options_t (option_parser_t *parser) {
|
||||
view_options_t (option_parser_t *parser)
|
||||
{
|
||||
annotate = false;
|
||||
fore = nullptr;
|
||||
back = nullptr;
|
||||
@ -122,7 +127,7 @@ struct view_options_t : option_group_t
|
||||
|
||||
add_options (parser);
|
||||
}
|
||||
~view_options_t (void)
|
||||
virtual ~view_options_t (void)
|
||||
{
|
||||
g_free (fore);
|
||||
g_free (back);
|
||||
@ -157,7 +162,7 @@ struct shape_options_t : option_group_t
|
||||
|
||||
add_options (parser);
|
||||
}
|
||||
~shape_options_t (void)
|
||||
virtual ~shape_options_t (void)
|
||||
{
|
||||
g_free (direction);
|
||||
g_free (language);
|
||||
@ -461,7 +466,8 @@ struct font_options_t : option_group_t
|
||||
|
||||
add_options (parser);
|
||||
}
|
||||
~font_options_t (void) {
|
||||
virtual ~font_options_t (void)
|
||||
{
|
||||
g_free (font_file);
|
||||
free (variations);
|
||||
g_free (font_funcs);
|
||||
@ -494,7 +500,8 @@ struct font_options_t : option_group_t
|
||||
|
||||
struct text_options_t : option_group_t
|
||||
{
|
||||
text_options_t (option_parser_t *parser) {
|
||||
text_options_t (option_parser_t *parser)
|
||||
{
|
||||
text_before = nullptr;
|
||||
text_after = nullptr;
|
||||
|
||||
@ -508,7 +515,8 @@ struct text_options_t : option_group_t
|
||||
|
||||
add_options (parser);
|
||||
}
|
||||
~text_options_t (void) {
|
||||
virtual ~text_options_t (void)
|
||||
{
|
||||
g_free (text_before);
|
||||
g_free (text_after);
|
||||
g_free (text);
|
||||
@ -546,7 +554,8 @@ struct text_options_t : option_group_t
|
||||
struct output_options_t : option_group_t
|
||||
{
|
||||
output_options_t (option_parser_t *parser,
|
||||
const char **supported_formats_ = nullptr) {
|
||||
const char **supported_formats_ = nullptr)
|
||||
{
|
||||
output_file = nullptr;
|
||||
output_format = nullptr;
|
||||
supported_formats = supported_formats_;
|
||||
@ -556,7 +565,8 @@ struct output_options_t : option_group_t
|
||||
|
||||
add_options (parser);
|
||||
}
|
||||
~output_options_t (void) {
|
||||
virtual ~output_options_t (void)
|
||||
{
|
||||
g_free (output_file);
|
||||
g_free (output_format);
|
||||
if (fp)
|
||||
|
Loading…
Reference in New Issue
Block a user