Merge remote-tracking branch 'upstream/master' into var-subset
This commit is contained in:
commit
19d45dcab7
|
@ -22,15 +22,16 @@ jobs:
|
||||||
- run: make -j4
|
- run: make -j4
|
||||||
- run: make check || .ci/fail.sh
|
- run: make check || .ci/fail.sh
|
||||||
|
|
||||||
macos-10.14.3-aat-fonts:
|
macos-10.14.4-aat-fonts:
|
||||||
macos:
|
macos:
|
||||||
xcode: "10.2.0"
|
xcode: "11.0.0"
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget autoconf automake libtool pkg-config ragel freetype glib cairo icu4c graphite2
|
- run: HOMEBREW_NO_AUTO_UPDATE=1 brew install wget autoconf automake libtool pkg-config ragel freetype glib cairo icu4c graphite2 cmake
|
||||||
- run: export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" && ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-coretext --with-graphite2
|
- run: export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libffi/lib/pkgconfig" && ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-coretext --with-graphite2
|
||||||
- run: make -j4
|
- run: make -j4
|
||||||
- run: make check || .ci/fail.sh
|
- run: make check || .ci/fail.sh
|
||||||
|
- run: cmake -Bbuild -H. -DHB_HAVE_CORETEXT=1 -DHB_BUILD_TESTS=0 && cmake --build build
|
||||||
|
|
||||||
distcheck:
|
distcheck:
|
||||||
docker:
|
docker:
|
||||||
|
@ -127,7 +128,7 @@ jobs:
|
||||||
- run: apt update || true
|
- run: apt update || true
|
||||||
- run: apt install -y clang lld binutils libtool autoconf automake make pkg-config gtk-doc-tools ragel libfreetype6-dev libfontconfig1-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 libfontconfig1-dev libglib2.0-dev libcairo2-dev libicu-dev libgraphite2-dev python python-pip
|
||||||
- run: pip install fonttools
|
- run: pip install fonttools
|
||||||
- run: CFLAGS="-Weverything -Wno-reserved-id-macro -Wno-conversion -Wno-padded -Wno-sign-conversion -Wno-cast-qual -Wno-documentation -Wno-documentation-unknown-command" CXXFLAGS="-Weverything -Wno-old-style-cast -Wno-documentation -Wno-documentation-unknown-command -Wno-c++98-compat -Wno-cast-qual -Wno-c++98-compat-pedantic -Wno-sign-conversion -Wno-padded -Wno-shorten-64-to-32 -Wno-reserved-id-macro -Wno-float-conversion -Wno-format-pedantic -Wno-shadow -Wno-conversion -Wno-zero-as-null-pointer-constant -Wno-missing-field-initializers -Wno-used-but-marked-unused -Wno-unused-macros -Wno-comma -Wno-float-equal -Wno-disabled-macro-expansion -Wno-weak-vtables -Wno-unused-parameter -Wno-covered-switch-default -Wno-unreachable-code -Wno-unused-template" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2 --with-fontconfig
|
- run: CFLAGS="-Weverything -Wno-reserved-id-macro -Wno-conversion -Wno-padded -Wno-sign-conversion -Wno-cast-qual -Wno-documentation -Wno-documentation-unknown-command -DHB_WITH_WIN1256" CXXFLAGS="-Weverything -Wno-old-style-cast -Wno-documentation -Wno-documentation-unknown-command -Wno-c++98-compat -Wno-cast-qual -Wno-c++98-compat-pedantic -Wno-sign-conversion -Wno-padded -Wno-shorten-64-to-32 -Wno-reserved-id-macro -Wno-float-conversion -Wno-format-pedantic -Wno-shadow -Wno-conversion -Wno-zero-as-null-pointer-constant -Wno-missing-field-initializers -Wno-used-but-marked-unused -Wno-unused-macros -Wno-comma -Wno-float-equal -Wno-disabled-macro-expansion -Wno-weak-vtables -Wno-unused-parameter -Wno-covered-switch-default -Wno-unreachable-code -Wno-unused-template -DHB_WITH_WIN1256" CC=clang CXX=clang++ ./autogen.sh --with-freetype --with-glib --with-cairo --with-icu --with-graphite2 --with-fontconfig
|
||||||
- run: make -j32 CPPFLAGS="-Werror"
|
- run: make -j32 CPPFLAGS="-Werror"
|
||||||
- run: make check CPPFLAGS="-Werror" || .ci/fail.sh
|
- run: make check CPPFLAGS="-Werror" || .ci/fail.sh
|
||||||
|
|
||||||
|
@ -193,9 +194,9 @@ jobs:
|
||||||
- run: apt update || true
|
- run: apt update || true
|
||||||
- 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: 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: pip install fonttools
|
||||||
- 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: CPPFLAGS="-fsanitize=undefined -fno-sanitize-recover=undefined" LDFLAGS="-fsanitize=undefined -fno-sanitize-recover=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 -j32
|
||||||
- run: make check || .ci/fail.sh | asan_symbolize | c++filt
|
- run: UBSAN_OPTIONS=print_stacktrace=1 make check || .ci/fail.sh | asan_symbolize | c++filt
|
||||||
|
|
||||||
fedora-O0-debug-outoftreebuild-mingw:
|
fedora-O0-debug-outoftreebuild-mingw:
|
||||||
docker:
|
docker:
|
||||||
|
@ -203,8 +204,8 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- run: dnf install -y pkg-config ragel gcc gcc-c++ automake autoconf libtool make which glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python mingw32-gcc-c++ mingw64-gcc-c++ mingw32-glib2 mingw32-cairo mingw32-freetype mingw64-glib2 mingw64-cairo mingw64-freetype glibc-devel.i686 || true
|
- run: dnf install -y pkg-config ragel gcc gcc-c++ automake autoconf libtool make which glib2-devel freetype-devel cairo-devel libicu-devel gobject-introspection-devel graphite2-devel redhat-rpm-config python mingw32-gcc-c++ mingw64-gcc-c++ mingw32-glib2 mingw32-cairo mingw32-freetype mingw64-glib2 mingw64-cairo mingw64-freetype glibc-devel.i686 || true
|
||||||
- run: CFLAGS="-O0" CXXFLAGS="-O0" CPPFLAGS="-DHB_DEBUG" NOCONFIGURE=1 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2
|
- run: NOCONFIGURE=1 ./autogen.sh
|
||||||
- run: mkdir build && cd build && ../configure && make -j32 && (make check || ../.ci/fail.sh)
|
- run: mkdir build && cd build && CFLAGS="-O0" CXXFLAGS="-O0" CPPFLAGS="-DHB_DEBUG" ../configure --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2 && make -j32 && (make check || ../.ci/fail.sh)
|
||||||
- run: pip install pefile
|
- run: pip install pefile
|
||||||
- run: mkdir winbuild32 && cd winbuild32 && ../mingw32.sh && make -j32 && make dist-win && cp harfbuzz-*-win32.zip harfbuzz-win32.zip
|
- run: mkdir winbuild32 && cd winbuild32 && ../mingw32.sh && make -j32 && make dist-win && cp harfbuzz-*-win32.zip harfbuzz-win32.zip
|
||||||
- run: mkdir winbuild64 && cd winbuild64 && ../mingw64.sh && make -j32 && make dist-win && cp harfbuzz-*-win64.zip harfbuzz-win64.zip
|
- run: mkdir winbuild64 && cd winbuild64 && ../mingw64.sh && make -j32 && make dist-win && cp harfbuzz-*-win64.zip harfbuzz-win64.zip
|
||||||
|
@ -306,7 +307,7 @@ workflows:
|
||||||
# macOS
|
# macOS
|
||||||
- macos-10.12.6-aat-fonts
|
- macos-10.12.6-aat-fonts
|
||||||
- macos-10.13.6-aat-fonts
|
- macos-10.13.6-aat-fonts
|
||||||
- macos-10.14.3-aat-fonts
|
- macos-10.14.4-aat-fonts
|
||||||
|
|
||||||
# both autotools and cmake
|
# both autotools and cmake
|
||||||
- distcheck
|
- distcheck
|
||||||
|
|
|
@ -6,7 +6,7 @@ trim_trailing_whitespace = true
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
||||||
[*.{c,cc,h,hh}]
|
[*.{c,cc,h,hh,rl}]
|
||||||
tab_width = 8
|
tab_width = 8
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
indent_style = tab # should be space
|
indent_style = tab # should be space
|
||||||
|
|
|
@ -108,7 +108,7 @@ endmacro ()
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
list(APPEND CMAKE_REQUIRED_LIBRARIES m)
|
list(APPEND CMAKE_REQUIRED_LIBRARIES m)
|
||||||
endif ()
|
endif ()
|
||||||
check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
|
check_funcs(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l roundf)
|
||||||
check_include_file(unistd.h HAVE_UNISTD_H)
|
check_include_file(unistd.h HAVE_UNISTD_H)
|
||||||
if (${HAVE_UNISTD_H})
|
if (${HAVE_UNISTD_H})
|
||||||
add_definitions(-DHAVE_UNISTD_H)
|
add_definitions(-DHAVE_UNISTD_H)
|
||||||
|
|
6
NEWS
6
NEWS
|
@ -1,3 +1,9 @@
|
||||||
|
Overview of changes leading to 2.6.2
|
||||||
|
Monday, September 30, 2019
|
||||||
|
====================================
|
||||||
|
- Misc small fixes, mostly to build-related issues.
|
||||||
|
|
||||||
|
|
||||||
Overview of changes leading to 2.6.1
|
Overview of changes leading to 2.6.1
|
||||||
Thursday, August 22, 2019
|
Thursday, August 22, 2019
|
||||||
====================================
|
====================================
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
[](https://app.codacy.com/app/behdad/harfbuzz)
|
[](https://app.codacy.com/app/behdad/harfbuzz)
|
||||||
[](https://codecov.io/gh/harfbuzz/harfbuzz)
|
[](https://codecov.io/gh/harfbuzz/harfbuzz)
|
||||||
[](https://coveralls.io/r/harfbuzz/harfbuzz)
|
[](https://coveralls.io/r/harfbuzz/harfbuzz)
|
||||||
|
[](https://repology.org/project/harfbuzz/versions)
|
||||||
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
|
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
|
||||||
|
|
||||||
This is HarfBuzz, a text shaping library.
|
This is HarfBuzz, a text shaping library.
|
||||||
|
@ -23,3 +24,11 @@ For custom configurations, see [CONFIG.md](CONFIG.md).
|
||||||
For test execution, see [TESTING.md](TESTING.md).
|
For test execution, see [TESTING.md](TESTING.md).
|
||||||
|
|
||||||
Documentation: https://harfbuzz.github.io
|
Documentation: https://harfbuzz.github.io
|
||||||
|
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Packaging status of HarfBuzz</summary
|
||||||
|
|
||||||
|
[](https://repology.org/project/harfbuzz/versions)
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
AC_PREREQ([2.64])
|
AC_PREREQ([2.64])
|
||||||
AC_INIT([HarfBuzz],
|
AC_INIT([HarfBuzz],
|
||||||
[2.6.1],
|
[2.6.2],
|
||||||
[https://github.com/harfbuzz/harfbuzz/issues/new],
|
[https://github.com/harfbuzz/harfbuzz/issues/new],
|
||||||
[harfbuzz],
|
[harfbuzz],
|
||||||
[http://harfbuzz.org/])
|
[http://harfbuzz.org/])
|
||||||
|
@ -77,7 +77,7 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
|
||||||
])
|
])
|
||||||
|
|
||||||
# Functions and headers
|
# Functions and headers
|
||||||
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
|
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l roundf)
|
||||||
AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h)
|
AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h)
|
||||||
|
|
||||||
# Compiler flags
|
# Compiler flags
|
||||||
|
|
|
@ -612,14 +612,14 @@ hb_ot_math_get_glyph_assembly
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>hb-ot-meta</FILE>
|
<FILE>hb-ot-meta</FILE>
|
||||||
hb_ot_meta_t
|
hb_ot_meta_tag_t
|
||||||
hb_ot_meta_get_entry_tags
|
hb_ot_meta_get_entry_tags
|
||||||
hb_ot_meta_reference_entry
|
hb_ot_meta_reference_entry
|
||||||
</SECTION>
|
</SECTION>
|
||||||
|
|
||||||
<SECTION>
|
<SECTION>
|
||||||
<FILE>hb-ot-metrics</FILE>
|
<FILE>hb-ot-metrics</FILE>
|
||||||
hb_ot_metrics_t
|
hb_ot_metrics_tag_t
|
||||||
hb_ot_metrics_get_position
|
hb_ot_metrics_get_position
|
||||||
hb_ot_metrics_get_variation
|
hb_ot_metrics_get_variation
|
||||||
hb_ot_metrics_get_x_variation
|
hb_ot_metrics_get_x_variation
|
||||||
|
|
|
@ -411,7 +411,7 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
|
||||||
dump_use_data_CPPFLAGS = $(HBCFLAGS)
|
dump_use_data_CPPFLAGS = $(HBCFLAGS)
|
||||||
dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
|
dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
|
||||||
|
|
||||||
COMPILED_TESTS = test-algs test-iter test-meta test-ot-tag test-unicode-ranges test-bimap
|
COMPILED_TESTS = test-algs test-iter test-meta test-number test-ot-tag test-unicode-ranges test-bimap
|
||||||
COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
|
COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
|
||||||
COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
|
COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
|
||||||
check_PROGRAMS += $(COMPILED_TESTS)
|
check_PROGRAMS += $(COMPILED_TESTS)
|
||||||
|
@ -429,6 +429,10 @@ test_meta_SOURCES = test-meta.cc hb-static.cc
|
||||||
test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||||
test_meta_LDADD = $(COMPILED_TESTS_LDADD)
|
test_meta_LDADD = $(COMPILED_TESTS_LDADD)
|
||||||
|
|
||||||
|
test_number_SOURCES = test-number.cc hb-number.cc
|
||||||
|
test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||||
|
test_number_LDADD = $(COMPILED_TESTS_LDADD)
|
||||||
|
|
||||||
test_ot_tag_SOURCES = hb-ot-tag.cc
|
test_ot_tag_SOURCES = hb-ot-tag.cc
|
||||||
test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||||
test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
|
test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
|
||||||
|
|
|
@ -49,6 +49,8 @@ HB_BASE_sources = \
|
||||||
hb-meta.hh \
|
hb-meta.hh \
|
||||||
hb-mutex.hh \
|
hb-mutex.hh \
|
||||||
hb-null.hh \
|
hb-null.hh \
|
||||||
|
hb-number.cc \
|
||||||
|
hb-number.hh \
|
||||||
hb-object.hh \
|
hb-object.hh \
|
||||||
hb-open-file.hh \
|
hb-open-file.hh \
|
||||||
hb-open-type.hh \
|
hb-open-type.hh \
|
||||||
|
@ -169,6 +171,7 @@ HB_BASE_sources = \
|
||||||
HB_BASE_RAGEL_GENERATED_sources = \
|
HB_BASE_RAGEL_GENERATED_sources = \
|
||||||
hb-buffer-deserialize-json.hh \
|
hb-buffer-deserialize-json.hh \
|
||||||
hb-buffer-deserialize-text.hh \
|
hb-buffer-deserialize-text.hh \
|
||||||
|
hb-number-parser.hh \
|
||||||
hb-ot-shape-complex-indic-machine.hh \
|
hb-ot-shape-complex-indic-machine.hh \
|
||||||
hb-ot-shape-complex-khmer-machine.hh \
|
hb-ot-shape-complex-khmer-machine.hh \
|
||||||
hb-ot-shape-complex-myanmar-machine.hh \
|
hb-ot-shape-complex-myanmar-machine.hh \
|
||||||
|
@ -177,6 +180,7 @@ HB_BASE_RAGEL_GENERATED_sources = \
|
||||||
HB_BASE_RAGEL_sources = \
|
HB_BASE_RAGEL_sources = \
|
||||||
hb-buffer-deserialize-json.rl \
|
hb-buffer-deserialize-json.rl \
|
||||||
hb-buffer-deserialize-text.rl \
|
hb-buffer-deserialize-text.rl \
|
||||||
|
hb-number-parser.rl \
|
||||||
hb-ot-shape-complex-indic-machine.rl \
|
hb-ot-shape-complex-indic-machine.rl \
|
||||||
hb-ot-shape-complex-khmer-machine.rl \
|
hb-ot-shape-complex-khmer-machine.rl \
|
||||||
hb-ot-shape-complex-myanmar-machine.rl \
|
hb-ot-shape-complex-myanmar-machine.rl \
|
||||||
|
@ -243,6 +247,8 @@ HB_ICU_headers = hb-icu.h
|
||||||
|
|
||||||
# Sources for libharfbuzz-subset
|
# Sources for libharfbuzz-subset
|
||||||
HB_SUBSET_sources = \
|
HB_SUBSET_sources = \
|
||||||
|
hb-number.cc \
|
||||||
|
hb-number.hh \
|
||||||
hb-ot-cff1-table.cc \
|
hb-ot-cff1-table.cc \
|
||||||
hb-ot-cff2-table.cc \
|
hb-ot-cff2-table.cc \
|
||||||
hb-static.cc \
|
hb-static.cc \
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "hb-fallback-shape.cc"
|
#include "hb-fallback-shape.cc"
|
||||||
#include "hb-font.cc"
|
#include "hb-font.cc"
|
||||||
#include "hb-map.cc"
|
#include "hb-map.cc"
|
||||||
|
#include "hb-number.cc"
|
||||||
#include "hb-ot-cff1-table.cc"
|
#include "hb-ot-cff1-table.cc"
|
||||||
#include "hb-ot-cff2-table.cc"
|
#include "hb-ot-cff2-table.cc"
|
||||||
#include "hb-ot-color.cc"
|
#include "hb-ot-color.cc"
|
||||||
|
|
|
@ -65,7 +65,7 @@ struct FontDescriptor
|
||||||
protected:
|
protected:
|
||||||
Tag tag; /* The 4-byte table tag name. */
|
Tag tag; /* The 4-byte table tag name. */
|
||||||
union {
|
union {
|
||||||
Fixed value; /* The value for the descriptor tag. */
|
HBFixed value; /* The value for the descriptor tag. */
|
||||||
HBUINT32 nalfType; /* If the tag is `nalf`, see non_alphabetic_value_t */
|
HBUINT32 nalfType; /* If the tag is `nalf`, see non_alphabetic_value_t */
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
|
@ -108,7 +108,7 @@ struct fdsc
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Fixed version; /* Version number of the font descriptors
|
HBFixed version; /* Version number of the font descriptors
|
||||||
* table (0x00010000 for the current version). */
|
* table (0x00010000 for the current version). */
|
||||||
LArrayOf<FontDescriptor>
|
LArrayOf<FontDescriptor>
|
||||||
descriptors; /* List of tagged-coordinate pairs style descriptors
|
descriptors; /* List of tagged-coordinate pairs style descriptors
|
||||||
|
|
|
@ -82,7 +82,7 @@ struct BaselineTableFormat2Part
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlyphID stdGlyph; /* The specific glyph index number in this
|
HBGlyphID stdGlyph; /* The specific glyph index number in this
|
||||||
* font that is used to set the baseline values.
|
* font that is used to set the baseline values.
|
||||||
* This is the standard glyph.
|
* This is the standard glyph.
|
||||||
* This glyph must contain a set of control points
|
* This glyph must contain a set of control points
|
||||||
|
@ -105,7 +105,7 @@ struct BaselineTableFormat3Part
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlyphID stdGlyph; /* ditto */
|
HBGlyphID stdGlyph; /* ditto */
|
||||||
HBUINT16 ctlPoints[32]; /* ditto */
|
HBUINT16 ctlPoints[32]; /* ditto */
|
||||||
Lookup<HBUINT16>
|
Lookup<HBUINT16>
|
||||||
lookupTable; /* Lookup table that maps glyphs to their
|
lookupTable; /* Lookup table that maps glyphs to their
|
||||||
|
|
|
@ -93,8 +93,8 @@ struct LookupSegmentSingle
|
||||||
return_trace (c->check_struct (this) && value.sanitize (c, base));
|
return_trace (c->check_struct (this) && value.sanitize (c, base));
|
||||||
}
|
}
|
||||||
|
|
||||||
GlyphID last; /* Last GlyphID in this segment */
|
HBGlyphID last; /* Last GlyphID in this segment */
|
||||||
GlyphID first; /* First GlyphID in this segment */
|
HBGlyphID first; /* First GlyphID in this segment */
|
||||||
T value; /* The lookup value (only one) */
|
T value; /* The lookup value (only one) */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (4 + T::static_size);
|
DEFINE_SIZE_STATIC (4 + T::static_size);
|
||||||
|
@ -162,8 +162,8 @@ struct LookupSegmentArray
|
||||||
valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...));
|
valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...));
|
||||||
}
|
}
|
||||||
|
|
||||||
GlyphID last; /* Last GlyphID in this segment */
|
HBGlyphID last; /* Last GlyphID in this segment */
|
||||||
GlyphID first; /* First GlyphID in this segment */
|
HBGlyphID first; /* First GlyphID in this segment */
|
||||||
NNOffsetTo<UnsizedArrayOf<T>>
|
NNOffsetTo<UnsizedArrayOf<T>>
|
||||||
valuesZ; /* A 16-bit offset from the start of
|
valuesZ; /* A 16-bit offset from the start of
|
||||||
* the table to the data. */
|
* the table to the data. */
|
||||||
|
@ -222,7 +222,7 @@ struct LookupSingle
|
||||||
return_trace (c->check_struct (this) && value.sanitize (c, base));
|
return_trace (c->check_struct (this) && value.sanitize (c, base));
|
||||||
}
|
}
|
||||||
|
|
||||||
GlyphID glyph; /* Last GlyphID */
|
HBGlyphID glyph; /* Last GlyphID */
|
||||||
T value; /* The lookup value (only one) */
|
T value; /* The lookup value (only one) */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (2 + T::static_size);
|
DEFINE_SIZE_STATIC (2 + T::static_size);
|
||||||
|
@ -284,7 +284,7 @@ struct LookupFormat8
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 8 */
|
HBUINT16 format; /* Format identifier--format = 8 */
|
||||||
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||||
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
|
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
|
||||||
* glyph minus the value of firstGlyph plus 1). */
|
* glyph minus the value of firstGlyph plus 1). */
|
||||||
UnsizedArrayOf<T>
|
UnsizedArrayOf<T>
|
||||||
|
@ -326,7 +326,7 @@ struct LookupFormat10
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 8 */
|
HBUINT16 format; /* Format identifier--format = 8 */
|
||||||
HBUINT16 valueSize; /* Byte size of each value. */
|
HBUINT16 valueSize; /* Byte size of each value. */
|
||||||
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||||
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
|
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
|
||||||
* glyph minus the value of firstGlyph plus 1). */
|
* glyph minus the value of firstGlyph plus 1). */
|
||||||
UnsizedArrayOf<HBUINT8>
|
UnsizedArrayOf<HBUINT8>
|
||||||
|
@ -658,7 +658,7 @@ struct ClassTable
|
||||||
return_trace (c->check_struct (this) && classArray.sanitize (c));
|
return_trace (c->check_struct (this) && classArray.sanitize (c));
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||||
ArrayOf<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus
|
ArrayOf<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus
|
||||||
* firstGlyph). */
|
* firstGlyph). */
|
||||||
public:
|
public:
|
||||||
|
@ -678,7 +678,7 @@ struct ObsoleteTypes
|
||||||
const void *base,
|
const void *base,
|
||||||
const T *array)
|
const T *array)
|
||||||
{
|
{
|
||||||
return (offset - ((const char *) array - (const char *) base)) / sizeof (T);
|
return (offset - ((const char *) array - (const char *) base)) / T::static_size;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static unsigned int byteOffsetToIndex (unsigned int offset,
|
static unsigned int byteOffsetToIndex (unsigned int offset,
|
||||||
|
|
|
@ -206,7 +206,7 @@ struct feat
|
||||||
SortedUnsizedArrayOf<FeatureName>
|
SortedUnsizedArrayOf<FeatureName>
|
||||||
namesZ; /* The feature name array. */
|
namesZ; /* The feature name array. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (24);
|
DEFINE_SIZE_ARRAY (12, namesZ);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace AAT */
|
} /* namespace AAT */
|
||||||
|
|
|
@ -70,9 +70,9 @@ struct DecompositionAction
|
||||||
|
|
||||||
ActionSubrecordHeader
|
ActionSubrecordHeader
|
||||||
header;
|
header;
|
||||||
Fixed lowerLimit; /* If the distance factor is less than this value,
|
HBFixed lowerLimit; /* If the distance factor is less than this value,
|
||||||
* then the ligature is decomposed. */
|
* then the ligature is decomposed. */
|
||||||
Fixed upperLimit; /* If the distance factor is greater than this value,
|
HBFixed upperLimit; /* If the distance factor is greater than this value,
|
||||||
* then the ligature is decomposed. */
|
* then the ligature is decomposed. */
|
||||||
HBUINT16 order; /* Numerical order in which this ligature will
|
HBUINT16 order; /* Numerical order in which this ligature will
|
||||||
* be decomposed; you may want infrequent ligatures
|
* be decomposed; you may want infrequent ligatures
|
||||||
|
@ -100,7 +100,7 @@ struct UnconditionalAddGlyphAction
|
||||||
protected:
|
protected:
|
||||||
ActionSubrecordHeader
|
ActionSubrecordHeader
|
||||||
header;
|
header;
|
||||||
GlyphID addGlyph; /* Glyph that should be added if the distance factor
|
HBGlyphID addGlyph; /* Glyph that should be added if the distance factor
|
||||||
* is growing. */
|
* is growing. */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -118,14 +118,14 @@ struct ConditionalAddGlyphAction
|
||||||
protected:
|
protected:
|
||||||
ActionSubrecordHeader
|
ActionSubrecordHeader
|
||||||
header;
|
header;
|
||||||
Fixed substThreshold; /* Distance growth factor (in ems) at which
|
HBFixed substThreshold; /* Distance growth factor (in ems) at which
|
||||||
* this glyph is replaced and the growth factor
|
* this glyph is replaced and the growth factor
|
||||||
* recalculated. */
|
* recalculated. */
|
||||||
GlyphID addGlyph; /* Glyph to be added as kashida. If this value is
|
HBGlyphID addGlyph; /* Glyph to be added as kashida. If this value is
|
||||||
* 0xFFFF, no extra glyph will be added. Note that
|
* 0xFFFF, no extra glyph will be added. Note that
|
||||||
* generally when a glyph is added, justification
|
* generally when a glyph is added, justification
|
||||||
* will need to be redone. */
|
* will need to be redone. */
|
||||||
GlyphID substGlyph; /* Glyph to be substituted for this glyph if the
|
HBGlyphID substGlyph; /* Glyph to be substituted for this glyph if the
|
||||||
* growth factor equals or exceeds the value of
|
* growth factor equals or exceeds the value of
|
||||||
* substThreshold. */
|
* substThreshold. */
|
||||||
public:
|
public:
|
||||||
|
@ -146,13 +146,13 @@ struct DuctileGlyphAction
|
||||||
HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
|
HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
|
||||||
* This would normally be 0x64756374 ('duct'),
|
* This would normally be 0x64756374 ('duct'),
|
||||||
* but you may use any axis the font contains. */
|
* but you may use any axis the font contains. */
|
||||||
Fixed minimumLimit; /* The lowest value for the ductility axis tha
|
HBFixed minimumLimit; /* The lowest value for the ductility axis tha
|
||||||
* still yields an acceptable appearance. Normally
|
* still yields an acceptable appearance. Normally
|
||||||
* this will be 1.0. */
|
* this will be 1.0. */
|
||||||
Fixed noStretchValue; /* This is the default value that corresponds to
|
HBFixed noStretchValue; /* This is the default value that corresponds to
|
||||||
* no change in appearance. Normally, this will
|
* no change in appearance. Normally, this will
|
||||||
* be 1.0. */
|
* be 1.0. */
|
||||||
Fixed maximumLimit; /* The highest value for the ductility axis that
|
HBFixed maximumLimit; /* The highest value for the ductility axis that
|
||||||
* still yields an acceptable appearance. */
|
* still yields an acceptable appearance. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (22);
|
DEFINE_SIZE_STATIC (22);
|
||||||
|
@ -170,7 +170,7 @@ struct RepeatedAddGlyphAction
|
||||||
ActionSubrecordHeader
|
ActionSubrecordHeader
|
||||||
header;
|
header;
|
||||||
HBUINT16 flags; /* Currently unused; set to 0. */
|
HBUINT16 flags; /* Currently unused; set to 0. */
|
||||||
GlyphID glyph; /* Glyph that should be added if the distance factor
|
HBGlyphID glyph; /* Glyph that should be added if the distance factor
|
||||||
* is growing. */
|
* is growing. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (10);
|
DEFINE_SIZE_STATIC (10);
|
||||||
|
@ -271,14 +271,14 @@ struct JustWidthDeltaEntry
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Fixed beforeGrowLimit;/* The ratio by which the advance width of the
|
HBFixed beforeGrowLimit;/* The ratio by which the advance width of the
|
||||||
* glyph is permitted to grow on the left or top side. */
|
* glyph is permitted to grow on the left or top side. */
|
||||||
Fixed beforeShrinkLimit;
|
HBFixed beforeShrinkLimit;
|
||||||
/* The ratio by which the advance width of the
|
/* The ratio by which the advance width of the
|
||||||
* glyph is permitted to shrink on the left or top side. */
|
* glyph is permitted to shrink on the left or top side. */
|
||||||
Fixed afterGrowLimit; /* The ratio by which the advance width of the glyph
|
HBFixed afterGrowLimit; /* The ratio by which the advance width of the glyph
|
||||||
* is permitted to shrink on the left or top side. */
|
* is permitted to shrink on the left or top side. */
|
||||||
Fixed afterShrinkLimit;
|
HBFixed afterShrinkLimit;
|
||||||
/* The ratio by which the advance width of the glyph
|
/* The ratio by which the advance width of the glyph
|
||||||
* is at most permitted to shrink on the right or
|
* is at most permitted to shrink on the right or
|
||||||
* bottom side. */
|
* bottom side. */
|
||||||
|
|
|
@ -82,8 +82,8 @@ struct KernPair
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlyphID left;
|
HBGlyphID left;
|
||||||
GlyphID right;
|
HBGlyphID right;
|
||||||
FWORD value;
|
FWORD value;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
|
@ -392,7 +392,7 @@ struct KerxSubTableFormat2
|
||||||
|
|
||||||
const UnsizedArrayOf<FWORD> &arrayZ = this+array;
|
const UnsizedArrayOf<FWORD> &arrayZ = this+array;
|
||||||
unsigned int kern_idx = l + r;
|
unsigned int kern_idx = l + r;
|
||||||
kern_idx = Types::offsetToIndex (kern_idx, this, &arrayZ);
|
kern_idx = Types::offsetToIndex (kern_idx, this, arrayZ.arrayZ);
|
||||||
const FWORD *v = &arrayZ[kern_idx];
|
const FWORD *v = &arrayZ[kern_idx];
|
||||||
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
||||||
|
|
||||||
|
@ -733,8 +733,8 @@ struct KerxSubTableHeader
|
||||||
{
|
{
|
||||||
typedef ExtendedTypes Types;
|
typedef ExtendedTypes Types;
|
||||||
|
|
||||||
unsigned int tuple_count () const { return tupleCount; }
|
unsigned tuple_count () const { return tupleCount; }
|
||||||
bool is_horizontal () const { return !(coverage & Vertical); }
|
bool is_horizontal () const { return !(coverage & Vertical); }
|
||||||
|
|
||||||
enum Coverage
|
enum Coverage
|
||||||
{
|
{
|
||||||
|
|
|
@ -240,21 +240,21 @@ struct ContextualSubtable
|
||||||
if (buffer->idx == buffer->len && !mark_set)
|
if (buffer->idx == buffer->len && !mark_set)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const GlyphID *replacement;
|
const HBGlyphID *replacement;
|
||||||
|
|
||||||
replacement = nullptr;
|
replacement = nullptr;
|
||||||
if (Types::extended)
|
if (Types::extended)
|
||||||
{
|
{
|
||||||
if (entry.data.markIndex != 0xFFFF)
|
if (entry.data.markIndex != 0xFFFF)
|
||||||
{
|
{
|
||||||
const Lookup<GlyphID> &lookup = subs[entry.data.markIndex];
|
const Lookup<HBGlyphID> &lookup = subs[entry.data.markIndex];
|
||||||
replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs);
|
replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint;
|
unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint;
|
||||||
const UnsizedArrayOf<GlyphID> &subs_old = (const UnsizedArrayOf<GlyphID> &) subs;
|
const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs;
|
||||||
replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
|
replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
|
||||||
if (!replacement->sanitize (&c->sanitizer) || !*replacement)
|
if (!replacement->sanitize (&c->sanitizer) || !*replacement)
|
||||||
replacement = nullptr;
|
replacement = nullptr;
|
||||||
|
@ -272,14 +272,14 @@ struct ContextualSubtable
|
||||||
{
|
{
|
||||||
if (entry.data.currentIndex != 0xFFFF)
|
if (entry.data.currentIndex != 0xFFFF)
|
||||||
{
|
{
|
||||||
const Lookup<GlyphID> &lookup = subs[entry.data.currentIndex];
|
const Lookup<HBGlyphID> &lookup = subs[entry.data.currentIndex];
|
||||||
replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs);
|
replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint;
|
unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint;
|
||||||
const UnsizedArrayOf<GlyphID> &subs_old = (const UnsizedArrayOf<GlyphID> &) subs;
|
const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs;
|
||||||
replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
|
replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
|
||||||
if (!replacement->sanitize (&c->sanitizer) || !*replacement)
|
if (!replacement->sanitize (&c->sanitizer) || !*replacement)
|
||||||
replacement = nullptr;
|
replacement = nullptr;
|
||||||
|
@ -304,7 +304,7 @@ struct ContextualSubtable
|
||||||
bool mark_set;
|
bool mark_set;
|
||||||
unsigned int mark;
|
unsigned int mark;
|
||||||
const ContextualSubtable *table;
|
const ContextualSubtable *table;
|
||||||
const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false> &subs;
|
const UnsizedOffsetListOf<Lookup<HBGlyphID>, HBUINT, false> &subs;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool apply (hb_aat_apply_context_t *c) const
|
bool apply (hb_aat_apply_context_t *c) const
|
||||||
|
@ -348,7 +348,7 @@ struct ContextualSubtable
|
||||||
protected:
|
protected:
|
||||||
StateTable<Types, EntryData>
|
StateTable<Types, EntryData>
|
||||||
machine;
|
machine;
|
||||||
NNOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false>, HBUINT>
|
NNOffsetTo<UnsizedOffsetListOf<Lookup<HBGlyphID>, HBUINT, false>, HBUINT>
|
||||||
substitutionTables;
|
substitutionTables;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (20);
|
DEFINE_SIZE_STATIC (20);
|
||||||
|
@ -520,7 +520,7 @@ struct LigatureSubtable
|
||||||
if (action & (LigActionStore | LigActionLast))
|
if (action & (LigActionStore | LigActionLast))
|
||||||
{
|
{
|
||||||
ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ);
|
ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ);
|
||||||
const GlyphID &ligatureData = ligature[ligature_idx];
|
const HBGlyphID &ligatureData = ligature[ligature_idx];
|
||||||
if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break;
|
if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break;
|
||||||
hb_codepoint_t lig = ligatureData;
|
hb_codepoint_t lig = ligatureData;
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ struct LigatureSubtable
|
||||||
const LigatureSubtable *table;
|
const LigatureSubtable *table;
|
||||||
const UnsizedArrayOf<HBUINT32> &ligAction;
|
const UnsizedArrayOf<HBUINT32> &ligAction;
|
||||||
const UnsizedArrayOf<HBUINT16> &component;
|
const UnsizedArrayOf<HBUINT16> &component;
|
||||||
const UnsizedArrayOf<GlyphID> &ligature;
|
const UnsizedArrayOf<HBGlyphID> &ligature;
|
||||||
unsigned int match_length;
|
unsigned int match_length;
|
||||||
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
|
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
|
||||||
};
|
};
|
||||||
|
@ -586,7 +586,7 @@ struct LigatureSubtable
|
||||||
ligAction; /* Offset to the ligature action table. */
|
ligAction; /* Offset to the ligature action table. */
|
||||||
NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT>
|
NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT>
|
||||||
component; /* Offset to the component table. */
|
component; /* Offset to the component table. */
|
||||||
NNOffsetTo<UnsizedArrayOf<GlyphID>, HBUINT>
|
NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT>
|
||||||
ligature; /* Offset to the actual ligature lists. */
|
ligature; /* Offset to the actual ligature lists. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (28);
|
DEFINE_SIZE_STATIC (28);
|
||||||
|
@ -606,7 +606,7 @@ struct NoncontextualSubtable
|
||||||
unsigned int count = c->buffer->len;
|
unsigned int count = c->buffer->len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
const GlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
|
const HBGlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
|
||||||
if (replacement)
|
if (replacement)
|
||||||
{
|
{
|
||||||
info[i].codepoint = *replacement;
|
info[i].codepoint = *replacement;
|
||||||
|
@ -624,7 +624,7 @@ struct NoncontextualSubtable
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Lookup<GlyphID> substitute;
|
Lookup<HBGlyphID> substitute;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_MIN (2);
|
DEFINE_SIZE_MIN (2);
|
||||||
};
|
};
|
||||||
|
@ -726,7 +726,7 @@ struct InsertionSubtable
|
||||||
{
|
{
|
||||||
unsigned int count = (flags & MarkedInsertCount);
|
unsigned int count = (flags & MarkedInsertCount);
|
||||||
unsigned int start = entry.data.markedInsertIndex;
|
unsigned int start = entry.data.markedInsertIndex;
|
||||||
const GlyphID *glyphs = &insertionAction[start];
|
const HBGlyphID *glyphs = &insertionAction[start];
|
||||||
if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
|
if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
|
||||||
|
|
||||||
bool before = flags & MarkedInsertBefore;
|
bool before = flags & MarkedInsertBefore;
|
||||||
|
@ -754,7 +754,7 @@ struct InsertionSubtable
|
||||||
{
|
{
|
||||||
unsigned int count = (flags & CurrentInsertCount) >> 5;
|
unsigned int count = (flags & CurrentInsertCount) >> 5;
|
||||||
unsigned int start = entry.data.currentInsertIndex;
|
unsigned int start = entry.data.currentInsertIndex;
|
||||||
const GlyphID *glyphs = &insertionAction[start];
|
const HBGlyphID *glyphs = &insertionAction[start];
|
||||||
if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
|
if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
|
||||||
|
|
||||||
bool before = flags & CurrentInsertBefore;
|
bool before = flags & CurrentInsertBefore;
|
||||||
|
@ -793,7 +793,7 @@ struct InsertionSubtable
|
||||||
private:
|
private:
|
||||||
hb_aat_apply_context_t *c;
|
hb_aat_apply_context_t *c;
|
||||||
unsigned int mark;
|
unsigned int mark;
|
||||||
const UnsizedArrayOf<GlyphID> &insertionAction;
|
const UnsizedArrayOf<HBGlyphID> &insertionAction;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool apply (hb_aat_apply_context_t *c) const
|
bool apply (hb_aat_apply_context_t *c) const
|
||||||
|
@ -819,7 +819,7 @@ struct InsertionSubtable
|
||||||
protected:
|
protected:
|
||||||
StateTable<Types, EntryData>
|
StateTable<Types, EntryData>
|
||||||
machine;
|
machine;
|
||||||
NNOffsetTo<UnsizedArrayOf<GlyphID>, HBUINT>
|
NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT>
|
||||||
insertionAction; /* Byte offset from stateHeader to the start of
|
insertionAction; /* Byte offset from stateHeader to the start of
|
||||||
* the insertion glyph table. */
|
* the insertion glyph table. */
|
||||||
public:
|
public:
|
||||||
|
@ -1080,10 +1080,10 @@ struct Chain
|
||||||
* The 'mort'/'morx' Table
|
* The 'mort'/'morx' Table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <typename Types>
|
template <typename Types, hb_tag_t TAG>
|
||||||
struct mortmorx
|
struct mortmorx
|
||||||
{
|
{
|
||||||
static constexpr hb_tag_t tableTag = HB_AAT_TAG_morx;
|
static constexpr hb_tag_t tableTag = TAG;
|
||||||
|
|
||||||
bool has_data () const { return version != 0; }
|
bool has_data () const { return version != 0; }
|
||||||
|
|
||||||
|
@ -1143,14 +1143,8 @@ struct mortmorx
|
||||||
DEFINE_SIZE_MIN (8);
|
DEFINE_SIZE_MIN (8);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct morx : mortmorx<ExtendedTypes>
|
struct morx : mortmorx<ExtendedTypes, HB_AAT_TAG_morx> {};
|
||||||
{
|
struct mort : mortmorx<ObsoleteTypes, HB_AAT_TAG_mort> {};
|
||||||
static constexpr hb_tag_t tableTag = HB_AAT_TAG_morx;
|
|
||||||
};
|
|
||||||
struct mort : mortmorx<ObsoleteTypes>
|
|
||||||
{
|
|
||||||
static constexpr hb_tag_t tableTag = HB_AAT_TAG_mort;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} /* namespace AAT */
|
} /* namespace AAT */
|
||||||
|
|
|
@ -62,7 +62,7 @@ struct TrackTableEntry
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Fixed track; /* Track value for this record. */
|
HBFixed track; /* Track value for this record. */
|
||||||
NameID trackNameID; /* The 'name' table index for this track.
|
NameID trackNameID; /* The 'name' table index for this track.
|
||||||
* (a short word or phrase like "loose"
|
* (a short word or phrase like "loose"
|
||||||
* or "very tight") */
|
* or "very tight") */
|
||||||
|
@ -82,7 +82,7 @@ struct TrackData
|
||||||
const void *base) const
|
const void *base) const
|
||||||
{
|
{
|
||||||
unsigned int sizes = nSizes;
|
unsigned int sizes = nSizes;
|
||||||
hb_array_t<const Fixed> size_table ((base+sizeTable).arrayZ, sizes);
|
hb_array_t<const HBFixed> size_table ((base+sizeTable).arrayZ, sizes);
|
||||||
|
|
||||||
float s0 = size_table[idx].to_float ();
|
float s0 = size_table[idx].to_float ();
|
||||||
float s1 = size_table[idx + 1].to_float ();
|
float s1 = size_table[idx + 1].to_float ();
|
||||||
|
@ -120,7 +120,7 @@ struct TrackData
|
||||||
if (!sizes) return 0.;
|
if (!sizes) return 0.;
|
||||||
if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
|
if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
|
||||||
|
|
||||||
hb_array_t<const Fixed> size_table ((base+sizeTable).arrayZ, sizes);
|
hb_array_t<const HBFixed> size_table ((base+sizeTable).arrayZ, sizes);
|
||||||
unsigned int size_index;
|
unsigned int size_index;
|
||||||
for (size_index = 0; size_index < sizes - 1; size_index++)
|
for (size_index = 0; size_index < sizes - 1; size_index++)
|
||||||
if (size_table[size_index].to_float () >= ptem)
|
if (size_table[size_index].to_float () >= ptem)
|
||||||
|
@ -141,7 +141,7 @@ struct TrackData
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 nTracks; /* Number of separate tracks included in this table. */
|
HBUINT16 nTracks; /* Number of separate tracks included in this table. */
|
||||||
HBUINT16 nSizes; /* Number of point sizes included in this table. */
|
HBUINT16 nSizes; /* Number of point sizes included in this table. */
|
||||||
LOffsetTo<UnsizedArrayOf<Fixed>, false>
|
LOffsetTo<UnsizedArrayOf<HBFixed>, false>
|
||||||
sizeTable; /* Offset from start of the tracking table to
|
sizeTable; /* Offset from start of the tracking table to
|
||||||
* Array[nSizes] of size values.. */
|
* Array[nSizes] of size values.. */
|
||||||
UnsizedArrayOf<TrackTableEntry>
|
UnsizedArrayOf<TrackTableEntry>
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
#include "hb-meta.hh"
|
#include "hb-meta.hh"
|
||||||
#include "hb-null.hh"
|
#include "hb-null.hh"
|
||||||
|
#include "hb-number.hh"
|
||||||
|
|
||||||
|
|
||||||
/* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits,
|
/* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits,
|
||||||
|
@ -82,6 +83,7 @@ HB_FUNCOBJ (hb_bool);
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
|
||||||
template <typename T> constexpr auto
|
template <typename T> constexpr auto
|
||||||
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
|
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
|
||||||
|
|
||||||
|
@ -895,17 +897,12 @@ hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
|
||||||
static inline hb_bool_t
|
static inline hb_bool_t
|
||||||
hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
|
hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
|
||||||
{
|
{
|
||||||
/* Pain because we don't know whether s is nul-terminated. */
|
unsigned int v;
|
||||||
char buf[64];
|
const char *p = s;
|
||||||
len = hb_min (ARRAY_LENGTH (buf) - 1, len);
|
const char *end = p + len;
|
||||||
strncpy (buf, s, len);
|
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, base)))
|
||||||
buf[len] = '\0';
|
return false;
|
||||||
|
|
||||||
char *end;
|
|
||||||
errno = 0;
|
|
||||||
unsigned long v = strtoul (buf, &end, base);
|
|
||||||
if (errno) return false;
|
|
||||||
if (*end) return false;
|
|
||||||
*out = v;
|
*out = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -994,6 +991,18 @@ struct
|
||||||
operator () (const T &a) const HB_AUTO_RETURN (-a)
|
operator () (const T &a) const HB_AUTO_RETURN (-a)
|
||||||
}
|
}
|
||||||
HB_FUNCOBJ (hb_neg);
|
HB_FUNCOBJ (hb_neg);
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
template <typename T> constexpr auto
|
||||||
|
operator () (T &a) const HB_AUTO_RETURN (++a)
|
||||||
|
}
|
||||||
|
HB_FUNCOBJ (hb_inc);
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
template <typename T> constexpr auto
|
||||||
|
operator () (T &a) const HB_AUTO_RETURN (--a)
|
||||||
|
}
|
||||||
|
HB_FUNCOBJ (hb_dec);
|
||||||
|
|
||||||
|
|
||||||
/* Compiler-assisted vectorization. */
|
/* Compiler-assisted vectorization. */
|
||||||
|
|
|
@ -50,7 +50,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||||
template <typename U,
|
template <typename U,
|
||||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||||
hb_array_t (const hb_array_t<U> &o) :
|
hb_array_t (const hb_array_t<U> &o) :
|
||||||
hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (),
|
hb_iter_with_fallback_t<hb_array_t, Type&> (),
|
||||||
arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
|
arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
|
||||||
template <typename U,
|
template <typename U,
|
||||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||||
|
@ -106,7 +106,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Note: our compare is NOT lexicographic; it also does NOT call Type::cmp. */
|
/* Note: our compare is NOT lexicographic; it also does NOT call Type::cmp. */
|
||||||
int cmp (const hb_array_t<Type> &a) const
|
int cmp (const hb_array_t &a) const
|
||||||
{
|
{
|
||||||
if (length != a.length)
|
if (length != a.length)
|
||||||
return (int) a.length - (int) length;
|
return (int) a.length - (int) length;
|
||||||
|
@ -114,8 +114,8 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||||
}
|
}
|
||||||
HB_INTERNAL static int cmp (const void *pa, const void *pb)
|
HB_INTERNAL static int cmp (const void *pa, const void *pb)
|
||||||
{
|
{
|
||||||
hb_array_t<Type> *a = (hb_array_t<Type> *) pa;
|
hb_array_t *a = (hb_array_t *) pa;
|
||||||
hb_array_t<Type> *b = (hb_array_t<Type> *) pb;
|
hb_array_t *b = (hb_array_t *) pb;
|
||||||
return b->cmp (*a);
|
return b->cmp (*a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,13 +141,13 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||||
hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*))
|
hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*))
|
||||||
{
|
{
|
||||||
if (likely (length))
|
if (likely (length))
|
||||||
hb_qsort (arrayZ, length, this->item_size, cmp_);
|
hb_qsort (arrayZ, length, this->get_item_size (), cmp_);
|
||||||
return hb_sorted_array_t<Type> (*this);
|
return hb_sorted_array_t<Type> (*this);
|
||||||
}
|
}
|
||||||
hb_sorted_array_t<Type> qsort ()
|
hb_sorted_array_t<Type> qsort ()
|
||||||
{
|
{
|
||||||
if (likely (length))
|
if (likely (length))
|
||||||
hb_qsort (arrayZ, length, this->item_size, Type::cmp);
|
hb_qsort (arrayZ, length, this->get_item_size (), Type::cmp);
|
||||||
return hb_sorted_array_t<Type> (*this);
|
return hb_sorted_array_t<Type> (*this);
|
||||||
}
|
}
|
||||||
void qsort (unsigned int start, unsigned int end)
|
void qsort (unsigned int start, unsigned int end)
|
||||||
|
@ -155,16 +155,16 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||||
end = hb_min (end, length);
|
end = hb_min (end, length);
|
||||||
assert (start <= end);
|
assert (start <= end);
|
||||||
if (likely (start < end))
|
if (likely (start < end))
|
||||||
hb_qsort (arrayZ + start, end - start, this->item_size, Type::cmp);
|
hb_qsort (arrayZ + start, end - start, this->get_item_size (), Type::cmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Other methods.
|
* Other methods.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
unsigned int get_size () const { return length * this->item_size; }
|
unsigned int get_size () const { return length * this->get_item_size (); }
|
||||||
|
|
||||||
hb_array_t<Type> sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const
|
hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const
|
||||||
{
|
{
|
||||||
if (!start_offset && !seg_count)
|
if (!start_offset && !seg_count)
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -176,11 +176,13 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||||
count -= start_offset;
|
count -= start_offset;
|
||||||
if (seg_count)
|
if (seg_count)
|
||||||
count = *seg_count = hb_min (count, *seg_count);
|
count = *seg_count = hb_min (count, *seg_count);
|
||||||
return hb_array_t<Type> (arrayZ + start_offset, count);
|
return hb_array_t (arrayZ + start_offset, count);
|
||||||
}
|
}
|
||||||
hb_array_t<Type> sub_array (unsigned int start_offset, unsigned int seg_count) const
|
hb_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
|
||||||
{ return sub_array (start_offset, &seg_count); }
|
{ return sub_array (start_offset, &seg_count); }
|
||||||
|
|
||||||
|
hb_array_t truncate (unsigned length) const { return sub_array (0, length); }
|
||||||
|
|
||||||
template <typename T,
|
template <typename T,
|
||||||
unsigned P = sizeof (Type),
|
unsigned P = sizeof (Type),
|
||||||
hb_enable_if (P == 1)>
|
hb_enable_if (P == 1)>
|
||||||
|
@ -234,7 +236,7 @@ struct hb_sorted_array_t :
|
||||||
hb_iter_t<hb_sorted_array_t<Type>, Type&>,
|
hb_iter_t<hb_sorted_array_t<Type>, Type&>,
|
||||||
hb_array_t<Type>
|
hb_array_t<Type>
|
||||||
{
|
{
|
||||||
typedef hb_iter_t<hb_sorted_array_t<Type>, Type&> iter_base_t;
|
typedef hb_iter_t<hb_sorted_array_t, Type&> iter_base_t;
|
||||||
HB_ITER_USING (iter_base_t);
|
HB_ITER_USING (iter_base_t);
|
||||||
static constexpr bool is_random_access_iterator = true;
|
static constexpr bool is_random_access_iterator = true;
|
||||||
static constexpr bool is_sorted_iterator = true;
|
static constexpr bool is_sorted_iterator = true;
|
||||||
|
@ -247,7 +249,7 @@ struct hb_sorted_array_t :
|
||||||
template <typename U,
|
template <typename U,
|
||||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||||
hb_sorted_array_t (const hb_array_t<U> &o) :
|
hb_sorted_array_t (const hb_array_t<U> &o) :
|
||||||
hb_iter_t<hb_sorted_array_t<Type>, Type&> (),
|
hb_iter_t<hb_sorted_array_t, Type&> (),
|
||||||
hb_array_t<Type> (o) {}
|
hb_array_t<Type> (o) {}
|
||||||
template <typename U,
|
template <typename U,
|
||||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||||
|
@ -258,11 +260,13 @@ struct hb_sorted_array_t :
|
||||||
bool operator != (const hb_sorted_array_t& o) const
|
bool operator != (const hb_sorted_array_t& o) const
|
||||||
{ return this->arrayZ != o.arrayZ || this->length != o.length; }
|
{ return this->arrayZ != o.arrayZ || this->length != o.length; }
|
||||||
|
|
||||||
hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
|
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const
|
||||||
{ return hb_sorted_array_t<Type> (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
|
{ return hb_sorted_array_t (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
|
||||||
hb_sorted_array_t<Type> sub_array (unsigned int start_offset, unsigned int seg_count) const
|
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
|
||||||
{ return sub_array (start_offset, &seg_count); }
|
{ return sub_array (start_offset, &seg_count); }
|
||||||
|
|
||||||
|
hb_sorted_array_t truncate (unsigned length) const { return sub_array (0, length); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Type *bsearch (const T &x, Type *not_found = nullptr)
|
Type *bsearch (const T &x, Type *not_found = nullptr)
|
||||||
{
|
{
|
||||||
|
@ -277,8 +281,8 @@ struct hb_sorted_array_t :
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool bfind (const T &x, unsigned int *i = nullptr,
|
bool bfind (const T &x, unsigned int *i = nullptr,
|
||||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||||
unsigned int to_store = (unsigned int) -1) const
|
unsigned int to_store = (unsigned int) -1) const
|
||||||
{
|
{
|
||||||
int min = 0, max = (int) this->length - 1;
|
int min = 0, max = (int) this->length - 1;
|
||||||
const Type *array = this->arrayZ;
|
const Type *array = this->arrayZ;
|
||||||
|
|
|
@ -48,7 +48,6 @@
|
||||||
#endif /* HAVE_SYS_MMAN_H */
|
#endif /* HAVE_SYS_MMAN_H */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -379,43 +379,24 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
static hb_bool_t
|
parse_int (const char *pp, const char *end, int32_t *pv)
|
||||||
parse_uint (const char *pp, const char *end, uint32_t *pv)
|
|
||||||
{
|
{
|
||||||
char buf[32];
|
int v;
|
||||||
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
|
const char *p = pp;
|
||||||
strncpy (buf, pp, len);
|
if (unlikely (!hb_parse_int (&p, end, &v, true/* whole buffer */)))
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
char *p = buf;
|
|
||||||
char *pend = p;
|
|
||||||
uint32_t v;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
v = strtol (p, &pend, 10);
|
|
||||||
if (errno || p == pend || pend - p != end - pp)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*pv = v;
|
*pv = v;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static bool
|
||||||
parse_int (const char *pp, const char *end, int32_t *pv)
|
parse_uint (const char *pp, const char *end, uint32_t *pv)
|
||||||
{
|
{
|
||||||
char buf[32];
|
unsigned int v;
|
||||||
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - pp));
|
const char *p = pp;
|
||||||
strncpy (buf, pp, len);
|
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */)))
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
char *p = buf;
|
|
||||||
char *pend = p;
|
|
||||||
int32_t v;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
v = strtol (p, &pend, 10);
|
|
||||||
if (errno || p == pend || pend - p != end - pp)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
*pv = v;
|
*pv = v;
|
||||||
|
|
|
@ -324,7 +324,8 @@ hb_buffer_t::clear_positions ()
|
||||||
out_len = 0;
|
out_len = 0;
|
||||||
out_info = info;
|
out_info = info;
|
||||||
|
|
||||||
memset (pos, 0, sizeof (pos[0]) * len);
|
if (likely (len))
|
||||||
|
memset (pos, 0, sizeof (pos[0]) * len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -408,8 +408,7 @@ struct hb_buffer_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unsafe_to_break_all ()
|
void unsafe_to_break_all () { unsafe_to_break_impl (0, len); }
|
||||||
{ unsafe_to_break_impl (0, len); }
|
|
||||||
void safe_to_break_all ()
|
void safe_to_break_all ()
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < len; i++)
|
for (unsigned int i = 0; i < len; i++)
|
||||||
|
|
|
@ -94,130 +94,52 @@ struct dict_opset_t : opset_t<number_t>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Turns CFF's BCD format into strtod understandable string */
|
||||||
static double parse_bcd (byte_str_ref_t& str_ref)
|
static double parse_bcd (byte_str_ref_t& str_ref)
|
||||||
{
|
{
|
||||||
bool neg = false;
|
if (unlikely (str_ref.in_error ())) return .0;
|
||||||
double int_part = 0;
|
|
||||||
uint64_t frac_part = 0;
|
|
||||||
uint32_t frac_count = 0;
|
|
||||||
bool exp_neg = false;
|
|
||||||
uint32_t exp_part = 0;
|
|
||||||
bool exp_overflow = false;
|
|
||||||
enum Part { INT_PART=0, FRAC_PART, EXP_PART } part = INT_PART;
|
|
||||||
enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };
|
|
||||||
const uint64_t MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
|
||||||
const uint32_t MAX_EXP = 0x7FFu; /* 1^11-1 */
|
|
||||||
|
|
||||||
double value = 0.0;
|
enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };
|
||||||
|
|
||||||
|
char buf[32];
|
||||||
unsigned char byte = 0;
|
unsigned char byte = 0;
|
||||||
for (uint32_t i = 0;; i++)
|
for (unsigned i = 0, count = 0; count < ARRAY_LENGTH (buf); ++i, ++count)
|
||||||
{
|
{
|
||||||
char d;
|
unsigned nibble;
|
||||||
if ((i & 1) == 0)
|
if (!(i & 1))
|
||||||
{
|
{
|
||||||
if (!str_ref.avail ())
|
if (unlikely (!str_ref.avail ())) break;
|
||||||
{
|
|
||||||
str_ref.set_error ();
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
byte = str_ref[0];
|
byte = str_ref[0];
|
||||||
str_ref.inc ();
|
str_ref.inc ();
|
||||||
d = byte >> 4;
|
nibble = byte >> 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
d = byte & 0x0F;
|
nibble = byte & 0x0F;
|
||||||
|
|
||||||
switch (d)
|
if (unlikely (nibble == RESERVED)) break;
|
||||||
|
else if (nibble == END)
|
||||||
{
|
{
|
||||||
case RESERVED:
|
const char *p = buf;
|
||||||
str_ref.set_error ();
|
double pv;
|
||||||
return value;
|
if (unlikely (!hb_parse_double (&p, p + count, &pv, true/* whole buffer */)))
|
||||||
|
|
||||||
case END:
|
|
||||||
value = (double) (neg ? -int_part : int_part);
|
|
||||||
if (frac_count > 0)
|
|
||||||
{
|
|
||||||
double frac = (frac_part / pow (10.0, (double) frac_count));
|
|
||||||
if (neg) frac = -frac;
|
|
||||||
value += frac;
|
|
||||||
}
|
|
||||||
if (unlikely (exp_overflow))
|
|
||||||
{
|
|
||||||
if (value == 0.0)
|
|
||||||
return value;
|
|
||||||
if (exp_neg)
|
|
||||||
return neg ? -DBL_MIN : DBL_MIN;
|
|
||||||
else
|
|
||||||
return neg ? -DBL_MAX : DBL_MAX;
|
|
||||||
}
|
|
||||||
if (exp_part != 0)
|
|
||||||
{
|
|
||||||
if (exp_neg)
|
|
||||||
value /= pow (10.0, (double) exp_part);
|
|
||||||
else
|
|
||||||
value *= pow (10.0, (double) exp_part);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
|
|
||||||
case NEG:
|
|
||||||
if (i != 0)
|
|
||||||
{
|
|
||||||
str_ref.set_error ();
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
neg = true;
|
|
||||||
break;
|
break;
|
||||||
|
return pv;
|
||||||
case DECIMAL:
|
}
|
||||||
if (part != INT_PART)
|
else
|
||||||
{
|
{
|
||||||
str_ref.set_error ();
|
buf[count] = "0123456789.EE?-?"[nibble];
|
||||||
return value;
|
if (nibble == EXP_NEG)
|
||||||
}
|
{
|
||||||
part = FRAC_PART;
|
++count;
|
||||||
break;
|
if (unlikely (count == ARRAY_LENGTH (buf))) break;
|
||||||
|
buf[count] = '-';
|
||||||
case EXP_NEG:
|
}
|
||||||
exp_neg = true;
|
|
||||||
HB_FALLTHROUGH;
|
|
||||||
|
|
||||||
case EXP_POS:
|
|
||||||
if (part == EXP_PART)
|
|
||||||
{
|
|
||||||
str_ref.set_error ();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
part = EXP_PART;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
switch (part) {
|
|
||||||
default:
|
|
||||||
case INT_PART:
|
|
||||||
int_part = (int_part * 10) + d;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FRAC_PART:
|
|
||||||
if (likely (frac_part <= MAX_FRACT / 10))
|
|
||||||
{
|
|
||||||
frac_part = (frac_part * 10) + (unsigned)d;
|
|
||||||
frac_count++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EXP_PART:
|
|
||||||
if (likely (exp_part * 10 + d <= MAX_EXP))
|
|
||||||
{
|
|
||||||
exp_part = (exp_part * 10) + d;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
exp_overflow = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
str_ref.set_error ();
|
||||||
|
return .0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_hint_op (op_code_t op)
|
static bool is_hint_op (op_code_t op)
|
||||||
|
|
136
src/hb-common.cc
136
src/hb-common.cc
|
@ -27,13 +27,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
|
|
||||||
#include "hb-machinery.hh"
|
#include "hb-machinery.hh"
|
||||||
|
|
||||||
#include <locale.h>
|
#include <locale.h>
|
||||||
#ifdef HAVE_XLOCALE_H
|
|
||||||
#include <xlocale.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HB_NO_SETLOCALE
|
#ifdef HB_NO_SETLOCALE
|
||||||
#define setlocale(Category, Locale) "C"
|
#define setlocale(Category, Locale) "C"
|
||||||
|
@ -385,7 +381,8 @@ hb_language_from_string (const char *str, int len)
|
||||||
const char *
|
const char *
|
||||||
hb_language_to_string (hb_language_t language)
|
hb_language_to_string (hb_language_t language)
|
||||||
{
|
{
|
||||||
/* This is actually nullptr-safe! */
|
if (unlikely (!language)) return nullptr;
|
||||||
|
|
||||||
return language->s;
|
return language->s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -722,131 +719,24 @@ parse_char (const char **pp, const char *end, char c)
|
||||||
static bool
|
static bool
|
||||||
parse_uint (const char **pp, const char *end, unsigned int *pv)
|
parse_uint (const char **pp, const char *end, unsigned int *pv)
|
||||||
{
|
{
|
||||||
char buf[32];
|
/* Intentionally use hb_parse_int inside instead of hb_parse_uint,
|
||||||
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
|
* such that -1 turns into "big number"... */
|
||||||
strncpy (buf, *pp, len);
|
int v;
|
||||||
buf[len] = '\0';
|
if (unlikely (!hb_parse_int (pp, end, &v))) return false;
|
||||||
|
|
||||||
char *p = buf;
|
|
||||||
char *pend = p;
|
|
||||||
unsigned int v;
|
|
||||||
|
|
||||||
/* Intentionally use strtol instead of strtoul, such that
|
|
||||||
* -1 turns into "big number"... */
|
|
||||||
errno = 0;
|
|
||||||
v = strtol (p, &pend, 10);
|
|
||||||
if (errno || p == pend)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*pv = v;
|
*pv = v;
|
||||||
*pp += pend - p;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
parse_uint32 (const char **pp, const char *end, uint32_t *pv)
|
parse_uint32 (const char **pp, const char *end, uint32_t *pv)
|
||||||
{
|
{
|
||||||
char buf[32];
|
/* Intentionally use hb_parse_int inside instead of hb_parse_uint,
|
||||||
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
|
* such that -1 turns into "big number"... */
|
||||||
strncpy (buf, *pp, len);
|
int v;
|
||||||
buf[len] = '\0';
|
if (unlikely (!hb_parse_int (pp, end, &v))) return false;
|
||||||
|
|
||||||
char *p = buf;
|
|
||||||
char *pend = p;
|
|
||||||
unsigned int v;
|
|
||||||
|
|
||||||
/* Intentionally use strtol instead of strtoul, such that
|
|
||||||
* -1 turns into "big number"... */
|
|
||||||
errno = 0;
|
|
||||||
v = strtol (p, &pend, 10);
|
|
||||||
if (errno || p == pend)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*pv = v;
|
*pv = v;
|
||||||
*pp += pend - p;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
|
|
||||||
#define USE_XLOCALE 1
|
|
||||||
#define HB_LOCALE_T locale_t
|
|
||||||
#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
|
|
||||||
#define HB_FREE_LOCALE(loc) freelocale (loc)
|
|
||||||
#elif defined(_MSC_VER)
|
|
||||||
#define USE_XLOCALE 1
|
|
||||||
#define HB_LOCALE_T _locale_t
|
|
||||||
#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
|
|
||||||
#define HB_FREE_LOCALE(loc) _free_locale (loc)
|
|
||||||
#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_XLOCALE
|
|
||||||
|
|
||||||
#if HB_USE_ATEXIT
|
|
||||||
static void free_static_C_locale ();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
|
|
||||||
hb_C_locale_lazy_loader_t>
|
|
||||||
{
|
|
||||||
static HB_LOCALE_T create ()
|
|
||||||
{
|
|
||||||
HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
|
|
||||||
|
|
||||||
#if HB_USE_ATEXIT
|
|
||||||
atexit (free_static_C_locale);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return C_locale;
|
|
||||||
}
|
|
||||||
static void destroy (HB_LOCALE_T p)
|
|
||||||
{
|
|
||||||
HB_FREE_LOCALE (p);
|
|
||||||
}
|
|
||||||
static HB_LOCALE_T get_null ()
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
} static_C_locale;
|
|
||||||
|
|
||||||
#if HB_USE_ATEXIT
|
|
||||||
static
|
|
||||||
void free_static_C_locale ()
|
|
||||||
{
|
|
||||||
static_C_locale.free_instance ();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static HB_LOCALE_T
|
|
||||||
get_C_locale ()
|
|
||||||
{
|
|
||||||
return static_C_locale.get_unconst ();
|
|
||||||
}
|
|
||||||
#endif /* USE_XLOCALE */
|
|
||||||
|
|
||||||
static bool
|
|
||||||
parse_float (const char **pp, const char *end, float *pv)
|
|
||||||
{
|
|
||||||
char buf[32];
|
|
||||||
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1, (unsigned int) (end - *pp));
|
|
||||||
strncpy (buf, *pp, len);
|
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
char *p = buf;
|
|
||||||
char *pend = p;
|
|
||||||
float v;
|
|
||||||
|
|
||||||
errno = 0;
|
|
||||||
#ifdef USE_XLOCALE
|
|
||||||
v = strtod_l (p, &pend, get_C_locale ());
|
|
||||||
#else
|
|
||||||
v = strtod (p, &pend);
|
|
||||||
#endif
|
|
||||||
if (errno || p == pend)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
*pv = v;
|
|
||||||
*pp += pend - p;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1099,7 +989,11 @@ static bool
|
||||||
parse_variation_value (const char **pp, const char *end, hb_variation_t *variation)
|
parse_variation_value (const char **pp, const char *end, hb_variation_t *variation)
|
||||||
{
|
{
|
||||||
parse_char (pp, end, '='); /* Optional. */
|
parse_char (pp, end, '='); /* Optional. */
|
||||||
return parse_float (pp, end, &variation->value);
|
double v;
|
||||||
|
if (unlikely (!hb_parse_double (pp, end, &v))) return false;
|
||||||
|
|
||||||
|
variation->value = v;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
|
|
@ -63,6 +63,8 @@ typedef __int32 int32_t;
|
||||||
typedef unsigned __int32 uint32_t;
|
typedef unsigned __int32 uint32_t;
|
||||||
typedef __int64 int64_t;
|
typedef __int64 int64_t;
|
||||||
typedef unsigned __int64 uint64_t;
|
typedef unsigned __int64 uint64_t;
|
||||||
|
#elif defined (__KERNEL__)
|
||||||
|
# include <linux/types.h>
|
||||||
#else
|
#else
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
#define HB_NO_BITMAP
|
#define HB_NO_BITMAP
|
||||||
#define HB_NO_CFF
|
#define HB_NO_CFF
|
||||||
#define HB_NO_COLOR
|
#define HB_NO_COLOR
|
||||||
|
#define HB_NO_ERRNO
|
||||||
#define HB_NO_FACE_COLLECT_UNICODES
|
#define HB_NO_FACE_COLLECT_UNICODES
|
||||||
#define HB_NO_GETENV
|
#define HB_NO_GETENV
|
||||||
#define HB_NO_HINTING
|
#define HB_NO_HINTING
|
||||||
|
|
|
@ -302,7 +302,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
|
||||||
if (unlikely (!face_data)) return nullptr;
|
if (unlikely (!face_data)) return nullptr;
|
||||||
CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
|
CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
|
||||||
|
|
||||||
CGFloat font_size = font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem;
|
CGFloat font_size = (CGFloat) (font->ptem <= 0.f ? HB_CORETEXT_DEFAULT_FONT_SIZE : font->ptem);
|
||||||
CTFontRef ct_font = create_ct_font (cg_font, font_size);
|
CTFontRef ct_font = create_ct_font (cg_font, font_size);
|
||||||
|
|
||||||
if (unlikely (!ct_font))
|
if (unlikely (!ct_font))
|
||||||
|
@ -327,7 +327,7 @@ retry:
|
||||||
const hb_coretext_font_data_t *data = font->data.coretext;
|
const hb_coretext_font_data_t *data = font->data.coretext;
|
||||||
if (unlikely (!data)) return nullptr;
|
if (unlikely (!data)) return nullptr;
|
||||||
|
|
||||||
if (fabs (CTFontGetSize ((CTFontRef) data) - font->ptem) > .5)
|
if (fabs (CTFontGetSize ((CTFontRef) data) - (CGFloat) font->ptem) > .5)
|
||||||
{
|
{
|
||||||
/* XXX-MT-bug
|
/* XXX-MT-bug
|
||||||
* Note that evaluating condition above can be dangerous if another thread
|
* Note that evaluating condition above can be dangerous if another thread
|
||||||
|
|
|
@ -625,7 +625,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
||||||
HB_STMT_START { \
|
HB_STMT_START { \
|
||||||
DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
|
DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
|
||||||
return false; \
|
return false; \
|
||||||
} HB_STMT_END;
|
} HB_STMT_END
|
||||||
|
|
||||||
if (FAILED (hr))
|
if (FAILED (hr))
|
||||||
FAIL ("Analyzer failed to generate results.");
|
FAIL ("Analyzer failed to generate results.");
|
||||||
|
|
|
@ -367,6 +367,9 @@ hb_blob_t *
|
||||||
hb_face_reference_table (const hb_face_t *face,
|
hb_face_reference_table (const hb_face_t *face,
|
||||||
hb_tag_t tag)
|
hb_tag_t tag)
|
||||||
{
|
{
|
||||||
|
if (unlikely (tag == HB_TAG_NONE))
|
||||||
|
return hb_blob_get_empty ();
|
||||||
|
|
||||||
return face->reference_table (tag);
|
return face->reference_table (tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -649,8 +649,8 @@ hb_font_set_funcs (hb_font_t *font,
|
||||||
/* Be *very* careful with this function! */
|
/* Be *very* careful with this function! */
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
hb_font_set_funcs_data (hb_font_t *font,
|
hb_font_set_funcs_data (hb_font_t *font,
|
||||||
void *font_data,
|
void *font_data,
|
||||||
hb_destroy_func_t destroy);
|
hb_destroy_func_t destroy);
|
||||||
|
|
||||||
|
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
|
|
|
@ -216,7 +216,7 @@ struct hb_font_t
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
|
hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
|
||||||
hb_codepoint_t *glyph)
|
hb_codepoint_t *glyph)
|
||||||
{
|
{
|
||||||
*glyph = 0;
|
*glyph = 0;
|
||||||
return klass->get.f.nominal_glyph (this, user_data,
|
return klass->get.f.nominal_glyph (this, user_data,
|
||||||
|
@ -286,7 +286,7 @@ struct hb_font_t
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
|
hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph,
|
||||||
hb_position_t *x, hb_position_t *y)
|
hb_position_t *x, hb_position_t *y)
|
||||||
{
|
{
|
||||||
*x = *y = 0;
|
*x = *y = 0;
|
||||||
return klass->get.f.glyph_h_origin (this, user_data,
|
return klass->get.f.glyph_h_origin (this, user_data,
|
||||||
|
@ -328,7 +328,7 @@ struct hb_font_t
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
|
hb_bool_t get_glyph_extents (hb_codepoint_t glyph,
|
||||||
hb_glyph_extents_t *extents)
|
hb_glyph_extents_t *extents)
|
||||||
{
|
{
|
||||||
memset (extents, 0, sizeof (*extents));
|
memset (extents, 0, sizeof (*extents));
|
||||||
return klass->get.f.glyph_extents (this, user_data,
|
return klass->get.f.glyph_extents (this, user_data,
|
||||||
|
@ -499,7 +499,7 @@ struct hb_font_t
|
||||||
}
|
}
|
||||||
|
|
||||||
void subtract_glyph_h_origin (hb_codepoint_t glyph,
|
void subtract_glyph_h_origin (hb_codepoint_t glyph,
|
||||||
hb_position_t *x, hb_position_t *y)
|
hb_position_t *x, hb_position_t *y)
|
||||||
{
|
{
|
||||||
hb_position_t origin_x, origin_y;
|
hb_position_t origin_x, origin_y;
|
||||||
|
|
||||||
|
|
|
@ -840,8 +840,8 @@ hb_ft_font_set_funcs (hb_font_t *font)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE))
|
if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL))
|
||||||
FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL);
|
FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
|
||||||
|
|
||||||
FT_Set_Char_Size (ft_face,
|
FT_Set_Char_Size (ft_face,
|
||||||
abs (font->x_scale), abs (font->y_scale),
|
abs (font->x_scale), abs (font->y_scale),
|
||||||
|
@ -866,7 +866,7 @@ hb_ft_font_set_funcs (hb_font_t *font)
|
||||||
if (ft_coords)
|
if (ft_coords)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < num_coords; i++)
|
for (unsigned int i = 0; i < num_coords; i++)
|
||||||
ft_coords[i] = coords[i] << 2;
|
ft_coords[i] = coords[i] * 4;
|
||||||
FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
|
FT_Set_Var_Blend_Coordinates (ft_face, num_coords, ft_coords);
|
||||||
free (ft_coords);
|
free (ft_coords);
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ fail:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_gdi_face_create:
|
* hb_gdi_face_create:
|
||||||
* @hdc: a HFONT object.
|
* @hfont: a HFONT object.
|
||||||
*
|
*
|
||||||
* Return value: #hb_face_t object corresponding to the given input
|
* Return value: #hb_face_t object corresponding to the given input
|
||||||
*
|
*
|
||||||
|
|
|
@ -41,6 +41,12 @@
|
||||||
#include <unicode/utf16.h>
|
#include <unicode/utf16.h>
|
||||||
#include <unicode/uversion.h>
|
#include <unicode/uversion.h>
|
||||||
|
|
||||||
|
/* ICU extra semicolon, fixed since 65, https://github.com/unicode-org/icu/commit/480bec3 */
|
||||||
|
#if U_ICU_VERSION_MAJOR_NUM < 65 && (defined(__GNUC__) || defined(__clang__))
|
||||||
|
#define HB_ICU_EXTRA_SEMI_IGNORED
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wextra-semi-stmt"
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SECTION:hb-icu
|
* SECTION:hb-icu
|
||||||
|
@ -51,10 +57,6 @@
|
||||||
* Functions for using HarfBuzz with the ICU library to provide Unicode data.
|
* Functions for using HarfBuzz with the ICU library to provide Unicode data.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
/* ICU doesn't do-while(0) around their statements. Ugh!
|
|
||||||
* https://unicode-org.atlassian.net/browse/CLDR-13027 */
|
|
||||||
#define HB_ICU_STMT(S) do { S } while (0)
|
|
||||||
|
|
||||||
hb_script_t
|
hb_script_t
|
||||||
hb_icu_script_to_script (UScriptCode script)
|
hb_icu_script_to_script (UScriptCode script)
|
||||||
{
|
{
|
||||||
|
@ -188,9 +190,9 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
err = false;
|
err = false;
|
||||||
HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err));
|
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err);
|
||||||
if (err) return false;
|
if (err) return false;
|
||||||
HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err));
|
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err);
|
||||||
if (err) return false;
|
if (err) return false;
|
||||||
|
|
||||||
icu_err = U_ZERO_ERROR;
|
icu_err = U_ZERO_ERROR;
|
||||||
|
@ -198,7 +200,7 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
if (U_FAILURE (icu_err))
|
if (U_FAILURE (icu_err))
|
||||||
return false;
|
return false;
|
||||||
if (u_countChar32 (normalized, len) == 1) {
|
if (u_countChar32 (normalized, len) == 1) {
|
||||||
HB_ICU_STMT (U16_GET_UNSAFE (normalized, 0, *ab));
|
U16_GET_UNSAFE (normalized, 0, *ab);
|
||||||
ret = true;
|
ret = true;
|
||||||
} else {
|
} else {
|
||||||
ret = false;
|
ret = false;
|
||||||
|
@ -226,13 +228,13 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
|
|
||||||
len = u_countChar32 (decomposed, len);
|
len = u_countChar32 (decomposed, len);
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
HB_ICU_STMT (U16_GET_UNSAFE (decomposed, 0, *a));
|
U16_GET_UNSAFE (decomposed, 0, *a);
|
||||||
*b = 0;
|
*b = 0;
|
||||||
return *a != ab;
|
return *a != ab;
|
||||||
} else if (len == 2) {
|
} else if (len == 2) {
|
||||||
len =0;
|
len = 0;
|
||||||
HB_ICU_STMT (U16_NEXT_UNSAFE (decomposed, len, *a));
|
U16_NEXT_UNSAFE (decomposed, len, *a);
|
||||||
HB_ICU_STMT (U16_NEXT_UNSAFE (decomposed, len, *b));
|
U16_NEXT_UNSAFE (decomposed, len, *b);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -252,7 +254,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
|
|
||||||
len = 0;
|
len = 0;
|
||||||
err = false;
|
err = false;
|
||||||
HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err));
|
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err);
|
||||||
if (err) return false;
|
if (err) return false;
|
||||||
|
|
||||||
icu_err = U_ZERO_ERROR;
|
icu_err = U_ZERO_ERROR;
|
||||||
|
@ -263,13 +265,13 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
len = u_countChar32 (normalized, len);
|
len = u_countChar32 (normalized, len);
|
||||||
|
|
||||||
if (len == 1) {
|
if (len == 1) {
|
||||||
HB_ICU_STMT (U16_GET_UNSAFE (normalized, 0, *a));
|
U16_GET_UNSAFE (normalized, 0, *a);
|
||||||
*b = 0;
|
*b = 0;
|
||||||
ret = *a != ab;
|
ret = *a != ab;
|
||||||
} else if (len == 2) {
|
} else if (len == 2) {
|
||||||
len =0;
|
len = 0;
|
||||||
HB_ICU_STMT (U16_NEXT_UNSAFE (normalized, len, *a));
|
U16_NEXT_UNSAFE (normalized, len, *a);
|
||||||
HB_ICU_STMT (U16_NEXT_UNSAFE (normalized, len, *b));
|
U16_NEXT_UNSAFE (normalized, len, *b);
|
||||||
|
|
||||||
/* Here's the ugly part: if ab decomposes to a single character and
|
/* Here's the ugly part: if ab decomposes to a single character and
|
||||||
* that character decomposes again, we have to detect that and undo
|
* that character decomposes again, we have to detect that and undo
|
||||||
|
@ -280,7 +282,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
if (U_FAILURE (icu_err))
|
if (U_FAILURE (icu_err))
|
||||||
return false;
|
return false;
|
||||||
hb_codepoint_t c;
|
hb_codepoint_t c;
|
||||||
HB_ICU_STMT (U16_GET_UNSAFE (recomposed, 0, c));
|
U16_GET_UNSAFE (recomposed, 0, c);
|
||||||
if (c != *a && c != ab) {
|
if (c != *a && c != ab) {
|
||||||
*a = c;
|
*a = c;
|
||||||
*b = 0;
|
*b = 0;
|
||||||
|
@ -289,7 +291,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
} else {
|
} else {
|
||||||
/* If decomposed to more than two characters, take the last one,
|
/* If decomposed to more than two characters, take the last one,
|
||||||
* and recompose the rest to get the first component. */
|
* and recompose the rest to get the first component. */
|
||||||
HB_ICU_STMT (U16_PREV_UNSAFE (normalized, len, *b)); /* Changes len in-place. */
|
U16_PREV_UNSAFE (normalized, len, *b); /* Changes len in-place. */
|
||||||
UChar recomposed[18 * 2];
|
UChar recomposed[18 * 2];
|
||||||
icu_err = U_ZERO_ERROR;
|
icu_err = U_ZERO_ERROR;
|
||||||
len = unorm2_normalize (unorm2_getNFCInstance (&icu_err), normalized, len, recomposed, ARRAY_LENGTH (recomposed), &icu_err);
|
len = unorm2_normalize (unorm2_getNFCInstance (&icu_err), normalized, len, recomposed, ARRAY_LENGTH (recomposed), &icu_err);
|
||||||
|
@ -298,7 +300,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
||||||
/* We expect that recomposed has exactly one character now. */
|
/* We expect that recomposed has exactly one character now. */
|
||||||
if (unlikely (u_countChar32 (recomposed, len) != 1))
|
if (unlikely (u_countChar32 (recomposed, len) != 1))
|
||||||
return false;
|
return false;
|
||||||
HB_ICU_STMT (U16_GET_UNSAFE (recomposed, 0, *a));
|
U16_GET_UNSAFE (recomposed, 0, *a);
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,5 +356,8 @@ hb_icu_get_unicode_funcs ()
|
||||||
return static_icu_funcs.get_unconst ();
|
return static_icu_funcs.get_unconst ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HB_ICU_EXTRA_SEMI_IGNORED
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
153
src/hb-iter.hh
153
src/hb-iter.hh
|
@ -64,7 +64,7 @@ template <typename iter_t, typename Item = typename iter_t::__item_t__>
|
||||||
struct hb_iter_t
|
struct hb_iter_t
|
||||||
{
|
{
|
||||||
typedef Item item_t;
|
typedef Item item_t;
|
||||||
static constexpr unsigned item_size = hb_static_size (Item);
|
constexpr unsigned get_item_size () const { return hb_static_size (Item); }
|
||||||
static constexpr bool is_iterator = true;
|
static constexpr bool is_iterator = true;
|
||||||
static constexpr bool is_random_access_iterator = false;
|
static constexpr bool is_random_access_iterator = false;
|
||||||
static constexpr bool is_sorted_iterator = false;
|
static constexpr bool is_sorted_iterator = false;
|
||||||
|
@ -130,7 +130,7 @@ struct hb_iter_t
|
||||||
using item_t = typename Name::item_t; \
|
using item_t = typename Name::item_t; \
|
||||||
using Name::begin; \
|
using Name::begin; \
|
||||||
using Name::end; \
|
using Name::end; \
|
||||||
using Name::item_size; \
|
using Name::get_item_size; \
|
||||||
using Name::is_iterator; \
|
using Name::is_iterator; \
|
||||||
using Name::iter; \
|
using Name::iter; \
|
||||||
using Name::operator bool; \
|
using Name::operator bool; \
|
||||||
|
@ -156,6 +156,7 @@ using hb_item_type = decltype (*hb_deref (hb_declval (Iterable)).iter ());
|
||||||
|
|
||||||
|
|
||||||
template <typename> struct hb_array_t;
|
template <typename> struct hb_array_t;
|
||||||
|
template <typename> struct hb_sorted_array_t;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -175,6 +176,14 @@ struct
|
||||||
|
|
||||||
}
|
}
|
||||||
HB_FUNCOBJ (hb_iter);
|
HB_FUNCOBJ (hb_iter);
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
template <typename T> unsigned
|
||||||
|
operator () (T&& c) const
|
||||||
|
{ return c.len (); }
|
||||||
|
|
||||||
|
}
|
||||||
|
HB_FUNCOBJ (hb_len);
|
||||||
|
|
||||||
/* Mixin to fill in what the subclass doesn't provide. */
|
/* Mixin to fill in what the subclass doesn't provide. */
|
||||||
template <typename iter_t, typename item_t = typename iter_t::__item_t__>
|
template <typename iter_t, typename item_t = typename iter_t::__item_t__>
|
||||||
|
@ -563,7 +572,7 @@ struct hb_zip_iter_t :
|
||||||
B b;
|
B b;
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{ HB_PARTIALIZE(2);
|
||||||
template <typename A, typename B,
|
template <typename A, typename B,
|
||||||
hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
|
hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
|
||||||
hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>>
|
hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>>
|
||||||
|
@ -602,18 +611,18 @@ struct
|
||||||
}
|
}
|
||||||
HB_FUNCOBJ (hb_apply);
|
HB_FUNCOBJ (hb_apply);
|
||||||
|
|
||||||
/* hb_iota()/hb_range() */
|
/* hb_range()/hb_iota()/hb_repeat() */
|
||||||
|
|
||||||
template <typename T, typename S>
|
template <typename T, typename S>
|
||||||
struct hb_counter_iter_t :
|
struct hb_range_iter_t :
|
||||||
hb_iter_t<hb_counter_iter_t<T, S>, T>
|
hb_iter_t<hb_range_iter_t<T, S>, T>
|
||||||
{
|
{
|
||||||
hb_counter_iter_t (T start, T end_, S step) : v (start), end_ (end_for (start, end_, step)), step (step) {}
|
hb_range_iter_t (T start, T end_, S step) : v (start), end_ (end_for (start, end_, step)), step (step) {}
|
||||||
|
|
||||||
typedef T __item_t__;
|
typedef T __item_t__;
|
||||||
static constexpr bool is_random_access_iterator = true;
|
static constexpr bool is_random_access_iterator = true;
|
||||||
static constexpr bool is_sorted_iterator = true;
|
static constexpr bool is_sorted_iterator = true;
|
||||||
__item_t__ __item__ () const { return +v; }
|
__item_t__ __item__ () const { return hb_ridentity (v); }
|
||||||
__item_t__ __item_at__ (unsigned j) const { return v + j * step; }
|
__item_t__ __item_at__ (unsigned j) const { return v + j * step; }
|
||||||
bool __more__ () const { return v != end_; }
|
bool __more__ () const { return v != end_; }
|
||||||
unsigned __len__ () const { return !step ? UINT_MAX : (end_ - v) / step; }
|
unsigned __len__ () const { return !step ? UINT_MAX : (end_ - v) / step; }
|
||||||
|
@ -621,8 +630,8 @@ struct hb_counter_iter_t :
|
||||||
void __forward__ (unsigned n) { v += n * step; }
|
void __forward__ (unsigned n) { v += n * step; }
|
||||||
void __prev__ () { v -= step; }
|
void __prev__ () { v -= step; }
|
||||||
void __rewind__ (unsigned n) { v -= n * step; }
|
void __rewind__ (unsigned n) { v -= n * step; }
|
||||||
hb_counter_iter_t __end__ () const { return hb_counter_iter_t (end_, end_, step); }
|
hb_range_iter_t __end__ () const { return hb_range_iter_t (end_, end_, step); }
|
||||||
bool operator != (const hb_counter_iter_t& o) const
|
bool operator != (const hb_range_iter_t& o) const
|
||||||
{ return v != o.v; }
|
{ return v != o.v; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -644,24 +653,91 @@ struct hb_counter_iter_t :
|
||||||
};
|
};
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
template <typename T = unsigned, typename S = unsigned> hb_counter_iter_t<T, S>
|
template <typename T = unsigned> hb_range_iter_t<T, unsigned>
|
||||||
operator () (T start = 0u, S&& step = 1u) const
|
|
||||||
{ return hb_counter_iter_t<T, S> (start, step >= 0 ? hb_int_max (T) : hb_int_min (T), step); }
|
|
||||||
}
|
|
||||||
HB_FUNCOBJ (hb_iota);
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
template <typename T = unsigned> hb_counter_iter_t<T, unsigned>
|
|
||||||
operator () (T end = (unsigned) -1) const
|
operator () (T end = (unsigned) -1) const
|
||||||
{ return hb_counter_iter_t<T, unsigned> (0, end, 1u); }
|
{ return hb_range_iter_t<T, unsigned> (0, end, 1u); }
|
||||||
|
|
||||||
template <typename T, typename S = unsigned> hb_counter_iter_t<T, S>
|
template <typename T, typename S = unsigned> hb_range_iter_t<T, S>
|
||||||
operator () (T start, T end, S&& step = 1u) const
|
operator () (T start, T end, S step = 1u) const
|
||||||
{ return hb_counter_iter_t<T, S> (start, end, step); }
|
{ return hb_range_iter_t<T, S> (start, end, step); }
|
||||||
}
|
}
|
||||||
HB_FUNCOBJ (hb_range);
|
HB_FUNCOBJ (hb_range);
|
||||||
|
|
||||||
/* hb_enumerate */
|
template <typename T, typename S>
|
||||||
|
struct hb_iota_iter_t :
|
||||||
|
hb_iter_with_fallback_t<hb_iota_iter_t<T, S>, T>
|
||||||
|
{
|
||||||
|
hb_iota_iter_t (T start, S step) : v (start), step (step) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
template <typename S2 = S>
|
||||||
|
auto
|
||||||
|
inc (hb_type_identity<S2> s, hb_priority<1>)
|
||||||
|
-> hb_void_t<decltype (hb_invoke (hb_forward<S2> (s), hb_declval<T&> ()))>
|
||||||
|
{ v = hb_invoke (hb_forward<S2> (s), v); }
|
||||||
|
|
||||||
|
void
|
||||||
|
inc (S s, hb_priority<0>)
|
||||||
|
{ v += s; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
typedef T __item_t__;
|
||||||
|
static constexpr bool is_random_access_iterator = true;
|
||||||
|
static constexpr bool is_sorted_iterator = true;
|
||||||
|
__item_t__ __item__ () const { return hb_ridentity (v); }
|
||||||
|
bool __more__ () const { return true; }
|
||||||
|
unsigned __len__ () const { return UINT_MAX; }
|
||||||
|
void __next__ () { inc (step, hb_prioritize); }
|
||||||
|
void __prev__ () { v -= step; }
|
||||||
|
hb_iota_iter_t __end__ () const { return *this; }
|
||||||
|
bool operator != (const hb_iota_iter_t& o) const { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T v;
|
||||||
|
S step;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
template <typename T = unsigned, typename S = unsigned> hb_iota_iter_t<T, S>
|
||||||
|
operator () (T start = 0u, S step = 1u) const
|
||||||
|
{ return hb_iota_iter_t<T, S> (start, step); }
|
||||||
|
}
|
||||||
|
HB_FUNCOBJ (hb_iota);
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct hb_repeat_iter_t :
|
||||||
|
hb_iter_t<hb_repeat_iter_t<T>, T>
|
||||||
|
{
|
||||||
|
hb_repeat_iter_t (T value) : v (value) {}
|
||||||
|
|
||||||
|
typedef T __item_t__;
|
||||||
|
static constexpr bool is_random_access_iterator = true;
|
||||||
|
static constexpr bool is_sorted_iterator = true;
|
||||||
|
__item_t__ __item__ () const { return v; }
|
||||||
|
__item_t__ __item_at__ (unsigned j) const { return v; }
|
||||||
|
bool __more__ () const { return true; }
|
||||||
|
unsigned __len__ () const { return UINT_MAX; }
|
||||||
|
void __next__ () {}
|
||||||
|
void __forward__ (unsigned) {}
|
||||||
|
void __prev__ () {}
|
||||||
|
void __rewind__ (unsigned) {}
|
||||||
|
hb_repeat_iter_t __end__ () const { return *this; }
|
||||||
|
bool operator != (const hb_repeat_iter_t& o) const { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T v;
|
||||||
|
};
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
template <typename T> hb_repeat_iter_t<T>
|
||||||
|
operator () (T value) const
|
||||||
|
{ return hb_repeat_iter_t<T> (value); }
|
||||||
|
}
|
||||||
|
HB_FUNCOBJ (hb_repeat);
|
||||||
|
|
||||||
|
/* hb_enumerate()/hb_take() */
|
||||||
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
|
@ -673,6 +749,37 @@ struct
|
||||||
}
|
}
|
||||||
HB_FUNCOBJ (hb_enumerate);
|
HB_FUNCOBJ (hb_enumerate);
|
||||||
|
|
||||||
|
struct
|
||||||
|
{ HB_PARTIALIZE(2);
|
||||||
|
template <typename Iterable,
|
||||||
|
hb_requires (hb_is_iterable (Iterable))>
|
||||||
|
auto operator () (Iterable&& it, unsigned count) const HB_AUTO_RETURN
|
||||||
|
( hb_zip (hb_range (count), it) | hb_map (hb_second) )
|
||||||
|
|
||||||
|
/* Specialization arrays. */
|
||||||
|
|
||||||
|
template <typename Type> inline hb_array_t<Type>
|
||||||
|
operator () (hb_array_t<Type> array, unsigned count) const
|
||||||
|
{ return array.sub_array (0, count); }
|
||||||
|
|
||||||
|
template <typename Type> inline hb_sorted_array_t<Type>
|
||||||
|
operator () (hb_sorted_array_t<Type> array, unsigned count) const
|
||||||
|
{ return array.sub_array (0, count); }
|
||||||
|
}
|
||||||
|
HB_FUNCOBJ (hb_take);
|
||||||
|
|
||||||
|
struct
|
||||||
|
{ HB_PARTIALIZE(2);
|
||||||
|
template <typename Iter,
|
||||||
|
hb_requires (hb_is_iterator (Iter))>
|
||||||
|
auto operator () (Iter it, unsigned count) const HB_AUTO_RETURN
|
||||||
|
(
|
||||||
|
+ hb_iota (it, hb_add (count))
|
||||||
|
| hb_map (hb_take (count))
|
||||||
|
| hb_take ((hb_len (it) + count - 1) / count)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
HB_FUNCOBJ (hb_chop);
|
||||||
|
|
||||||
/* hb_sink() */
|
/* hb_sink() */
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ static inline Type& StructAfter(TObject &X)
|
||||||
|
|
||||||
#define DEFINE_SIZE_ARRAY(size, array) \
|
#define DEFINE_SIZE_ARRAY(size, array) \
|
||||||
DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
|
DEFINE_COMPILES_ASSERTION ((void) (array)[0].static_size) \
|
||||||
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof ((array)[0])) \
|
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + HB_VAR_ARRAY * sizeof ((array)[0])) \
|
||||||
static constexpr unsigned null_size = (size); \
|
static constexpr unsigned null_size = (size); \
|
||||||
static constexpr unsigned min_size = (size)
|
static constexpr unsigned min_size = (size)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,240 @@
|
||||||
|
|
||||||
|
#line 1 "hb-number-parser.rl"
|
||||||
|
/*
|
||||||
|
* Copyright © 2019 Ebrahim Byagowi
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_NUMBER_PARSER_HH
|
||||||
|
#define HB_NUMBER_PARSER_HH
|
||||||
|
|
||||||
|
#include "hb.hh"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
|
||||||
|
#line 37 "hb-number-parser.hh"
|
||||||
|
static const unsigned char _double_parser_trans_keys[] = {
|
||||||
|
0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
|
||||||
|
46u, 101u, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char _double_parser_key_spans[] = {
|
||||||
|
0, 15, 12, 10, 15, 10, 54, 10,
|
||||||
|
56
|
||||||
|
};
|
||||||
|
|
||||||
|
static const unsigned char _double_parser_index_offsets[] = {
|
||||||
|
0, 0, 16, 29, 40, 56, 67, 122,
|
||||||
|
133
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char _double_parser_indicies[] = {
|
||||||
|
0, 1, 2, 3, 1, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
1, 3, 1, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 4, 4, 4, 1, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 5, 5,
|
||||||
|
1, 6, 1, 7, 1, 1, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
1, 8, 8, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 1, 5, 5, 5, 5,
|
||||||
|
5, 5, 5, 5, 5, 5, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 9, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 9, 1, 8, 8, 8, 8, 8,
|
||||||
|
8, 8, 8, 8, 8, 1, 3, 1,
|
||||||
|
4, 4, 4, 4, 4, 4, 4, 4,
|
||||||
|
4, 4, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 9, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 9, 1, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char _double_parser_trans_targs[] = {
|
||||||
|
2, 0, 2, 3, 8, 6, 5, 5,
|
||||||
|
7, 4
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char _double_parser_trans_actions[] = {
|
||||||
|
0, 0, 1, 0, 2, 3, 0, 4,
|
||||||
|
5, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int double_parser_start = 1;
|
||||||
|
static const int double_parser_first_final = 6;
|
||||||
|
static const int double_parser_error = 0;
|
||||||
|
|
||||||
|
static const int double_parser_en_main = 1;
|
||||||
|
|
||||||
|
|
||||||
|
#line 70 "hb-number-parser.rl"
|
||||||
|
|
||||||
|
|
||||||
|
/* Works only for n < 512 */
|
||||||
|
static inline double
|
||||||
|
_pow10 (unsigned int exponent)
|
||||||
|
{
|
||||||
|
static const double _powers_of_10[] =
|
||||||
|
{
|
||||||
|
1.0e+256,
|
||||||
|
1.0e+128,
|
||||||
|
1.0e+64,
|
||||||
|
1.0e+32,
|
||||||
|
1.0e+16,
|
||||||
|
1.0e+8,
|
||||||
|
10000.,
|
||||||
|
100.,
|
||||||
|
10.
|
||||||
|
};
|
||||||
|
unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
|
||||||
|
double result = 1;
|
||||||
|
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
|
||||||
|
if (exponent & mask) result *= *power;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
strtod_rl (const char *buf, char **end_ptr)
|
||||||
|
{
|
||||||
|
const char *p, *pe;
|
||||||
|
double value = 0;
|
||||||
|
double frac = 0;
|
||||||
|
double frac_count = 0;
|
||||||
|
unsigned int exp = 0;
|
||||||
|
bool neg = false, exp_neg = false, exp_overflow = false;
|
||||||
|
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
||||||
|
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||||
|
p = buf;
|
||||||
|
pe = p + strlen (p);
|
||||||
|
|
||||||
|
while (p < pe && ISSPACE (*p))
|
||||||
|
p++;
|
||||||
|
|
||||||
|
int cs;
|
||||||
|
|
||||||
|
#line 142 "hb-number-parser.hh"
|
||||||
|
{
|
||||||
|
cs = double_parser_start;
|
||||||
|
}
|
||||||
|
|
||||||
|
#line 147 "hb-number-parser.hh"
|
||||||
|
{
|
||||||
|
int _slen;
|
||||||
|
int _trans;
|
||||||
|
const unsigned char *_keys;
|
||||||
|
const char *_inds;
|
||||||
|
if ( p == pe )
|
||||||
|
goto _test_eof;
|
||||||
|
if ( cs == 0 )
|
||||||
|
goto _out;
|
||||||
|
_resume:
|
||||||
|
_keys = _double_parser_trans_keys + (cs<<1);
|
||||||
|
_inds = _double_parser_indicies + _double_parser_index_offsets[cs];
|
||||||
|
|
||||||
|
_slen = _double_parser_key_spans[cs];
|
||||||
|
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
|
||||||
|
(*p) <= _keys[1] ?
|
||||||
|
(*p) - _keys[0] : _slen ];
|
||||||
|
|
||||||
|
cs = _double_parser_trans_targs[_trans];
|
||||||
|
|
||||||
|
if ( _double_parser_trans_actions[_trans] == 0 )
|
||||||
|
goto _again;
|
||||||
|
|
||||||
|
switch ( _double_parser_trans_actions[_trans] ) {
|
||||||
|
case 1:
|
||||||
|
#line 39 "hb-number-parser.rl"
|
||||||
|
{ neg = true; }
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
#line 40 "hb-number-parser.rl"
|
||||||
|
{ exp_neg = true; }
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
#line 42 "hb-number-parser.rl"
|
||||||
|
{
|
||||||
|
value = value * 10. + ((*p) - '0');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
#line 45 "hb-number-parser.rl"
|
||||||
|
{
|
||||||
|
if (likely (frac <= MAX_FRACT / 10))
|
||||||
|
{
|
||||||
|
frac = frac * 10. + ((*p) - '0');
|
||||||
|
++frac_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
#line 52 "hb-number-parser.rl"
|
||||||
|
{
|
||||||
|
if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
|
||||||
|
exp = exp * 10 + ((*p) - '0');
|
||||||
|
else
|
||||||
|
exp_overflow = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#line 205 "hb-number-parser.hh"
|
||||||
|
}
|
||||||
|
|
||||||
|
_again:
|
||||||
|
if ( cs == 0 )
|
||||||
|
goto _out;
|
||||||
|
if ( ++p != pe )
|
||||||
|
goto _resume;
|
||||||
|
_test_eof: {}
|
||||||
|
_out: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#line 116 "hb-number-parser.rl"
|
||||||
|
|
||||||
|
|
||||||
|
*end_ptr = (char *) p;
|
||||||
|
|
||||||
|
if (frac_count) value += frac / _pow10 (frac_count);
|
||||||
|
if (neg) value *= -1.;
|
||||||
|
|
||||||
|
if (unlikely (exp_overflow))
|
||||||
|
{
|
||||||
|
if (value == 0) return value;
|
||||||
|
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
|
||||||
|
else return neg ? -DBL_MAX : DBL_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exp)
|
||||||
|
{
|
||||||
|
if (exp_neg) value /= _pow10 (exp);
|
||||||
|
else value *= _pow10 (exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HB_NUMBER_PARSER_HH */
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2019 Ebrahim Byagowi
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_NUMBER_PARSER_HH
|
||||||
|
#define HB_NUMBER_PARSER_HH
|
||||||
|
|
||||||
|
#include "hb.hh"
|
||||||
|
|
||||||
|
#include <float.h>
|
||||||
|
|
||||||
|
%%{
|
||||||
|
|
||||||
|
machine double_parser;
|
||||||
|
alphtype unsigned char;
|
||||||
|
write data;
|
||||||
|
|
||||||
|
action see_neg { neg = true; }
|
||||||
|
action see_exp_neg { exp_neg = true; }
|
||||||
|
|
||||||
|
action add_int {
|
||||||
|
value = value * 10. + (fc - '0');
|
||||||
|
}
|
||||||
|
action add_frac {
|
||||||
|
if (likely (frac <= MAX_FRACT / 10))
|
||||||
|
{
|
||||||
|
frac = frac * 10. + (fc - '0');
|
||||||
|
++frac_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action add_exp {
|
||||||
|
if (likely (exp * 10 + (fc - '0') <= MAX_EXP))
|
||||||
|
exp = exp * 10 + (fc - '0');
|
||||||
|
else
|
||||||
|
exp_overflow = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
num = [0-9]+;
|
||||||
|
|
||||||
|
main := (
|
||||||
|
(
|
||||||
|
(('+'|'-'@see_neg)? num @add_int) ('.' num @add_frac)?
|
||||||
|
|
|
||||||
|
(('+'|'-'@see_neg)? '.' num @add_frac)
|
||||||
|
)
|
||||||
|
(('e'|'E') (('+'|'-'@see_exp_neg)? num @add_exp))?
|
||||||
|
);
|
||||||
|
|
||||||
|
}%%
|
||||||
|
|
||||||
|
/* Works only for n < 512 */
|
||||||
|
static inline double
|
||||||
|
_pow10 (unsigned int exponent)
|
||||||
|
{
|
||||||
|
static const double _powers_of_10[] =
|
||||||
|
{
|
||||||
|
1.0e+256,
|
||||||
|
1.0e+128,
|
||||||
|
1.0e+64,
|
||||||
|
1.0e+32,
|
||||||
|
1.0e+16,
|
||||||
|
1.0e+8,
|
||||||
|
10000.,
|
||||||
|
100.,
|
||||||
|
10.
|
||||||
|
};
|
||||||
|
unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
|
||||||
|
double result = 1;
|
||||||
|
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
|
||||||
|
if (exponent & mask) result *= *power;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
strtod_rl (const char *buf, char **end_ptr)
|
||||||
|
{
|
||||||
|
const char *p, *pe;
|
||||||
|
double value = 0;
|
||||||
|
double frac = 0;
|
||||||
|
double frac_count = 0;
|
||||||
|
unsigned int exp = 0;
|
||||||
|
bool neg = false, exp_neg = false, exp_overflow = false;
|
||||||
|
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
||||||
|
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||||
|
p = buf;
|
||||||
|
pe = p + strlen (p);
|
||||||
|
|
||||||
|
while (p < pe && ISSPACE (*p))
|
||||||
|
p++;
|
||||||
|
|
||||||
|
int cs;
|
||||||
|
%%{
|
||||||
|
write init;
|
||||||
|
write exec;
|
||||||
|
}%%
|
||||||
|
|
||||||
|
*end_ptr = (char *) p;
|
||||||
|
|
||||||
|
if (frac_count) value += frac / _pow10 (frac_count);
|
||||||
|
if (neg) value *= -1.;
|
||||||
|
|
||||||
|
if (unlikely (exp_overflow))
|
||||||
|
{
|
||||||
|
if (value == 0) return value;
|
||||||
|
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
|
||||||
|
else return neg ? -DBL_MAX : DBL_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exp)
|
||||||
|
{
|
||||||
|
if (exp_neg) value /= _pow10 (exp);
|
||||||
|
else value *= _pow10 (exp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HB_NUMBER_PARSER_HH */
|
|
@ -0,0 +1,147 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2019 Ebrahim Byagowi
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hb.hh"
|
||||||
|
#include "hb-machinery.hh"
|
||||||
|
#include "hb-number-parser.hh"
|
||||||
|
|
||||||
|
#include <locale.h>
|
||||||
|
#ifdef HAVE_XLOCALE_H
|
||||||
|
#include <xlocale.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T, typename Func>
|
||||||
|
static bool
|
||||||
|
_parse_number (const char **pp, const char *end, T *pv,
|
||||||
|
bool whole_buffer, Func f)
|
||||||
|
{
|
||||||
|
char buf[32];
|
||||||
|
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1,
|
||||||
|
(unsigned int) (end - *pp));
|
||||||
|
strncpy (buf, *pp, len);
|
||||||
|
buf[len] = '\0';
|
||||||
|
|
||||||
|
char *p = buf;
|
||||||
|
char *pend = p;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
*pv = f (p, &pend);
|
||||||
|
if (unlikely (errno || p == pend ||
|
||||||
|
/* Check if consumed whole buffer if is requested */
|
||||||
|
(whole_buffer && pend - p != end - *pp))) return false;
|
||||||
|
|
||||||
|
*pp += pend - p;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
hb_parse_int (const char **pp, const char *end, int *pv, bool whole_buffer)
|
||||||
|
{
|
||||||
|
return _parse_number<int> (pp, end, pv, whole_buffer,
|
||||||
|
[] (const char *p, char **end)
|
||||||
|
{ return strtol (p, end, 10); });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
|
||||||
|
bool whole_buffer, int base)
|
||||||
|
{
|
||||||
|
return _parse_number<unsigned int> (pp, end, pv, whole_buffer,
|
||||||
|
[base] (const char *p, char **end)
|
||||||
|
{ return strtoul (p, end, base); });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
|
||||||
|
#define USE_XLOCALE 1
|
||||||
|
#define HB_LOCALE_T locale_t
|
||||||
|
#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
|
||||||
|
#define HB_FREE_LOCALE(loc) freelocale (loc)
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
#define USE_XLOCALE 1
|
||||||
|
#define HB_LOCALE_T _locale_t
|
||||||
|
#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
|
||||||
|
#define HB_FREE_LOCALE(loc) _free_locale (loc)
|
||||||
|
#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_XLOCALE
|
||||||
|
|
||||||
|
#if HB_USE_ATEXIT
|
||||||
|
static void free_static_C_locale ();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
|
||||||
|
hb_C_locale_lazy_loader_t>
|
||||||
|
{
|
||||||
|
static HB_LOCALE_T create ()
|
||||||
|
{
|
||||||
|
HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
|
||||||
|
|
||||||
|
#if HB_USE_ATEXIT
|
||||||
|
atexit (free_static_C_locale);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return C_locale;
|
||||||
|
}
|
||||||
|
static void destroy (HB_LOCALE_T p)
|
||||||
|
{
|
||||||
|
HB_FREE_LOCALE (p);
|
||||||
|
}
|
||||||
|
static HB_LOCALE_T get_null ()
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
} static_C_locale;
|
||||||
|
|
||||||
|
#if HB_USE_ATEXIT
|
||||||
|
static
|
||||||
|
void free_static_C_locale ()
|
||||||
|
{
|
||||||
|
static_C_locale.free_instance ();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static HB_LOCALE_T
|
||||||
|
get_C_locale ()
|
||||||
|
{
|
||||||
|
return static_C_locale.get_unconst ();
|
||||||
|
}
|
||||||
|
#endif /* USE_XLOCALE */
|
||||||
|
|
||||||
|
bool
|
||||||
|
hb_parse_double (const char **pp, const char *end, double *pv,
|
||||||
|
bool whole_buffer)
|
||||||
|
{
|
||||||
|
return _parse_number<double> (pp, end, pv, whole_buffer,
|
||||||
|
[] (const char *p, char **end)
|
||||||
|
{
|
||||||
|
#ifdef USE_XLOCALE
|
||||||
|
return strtod_l (p, end, get_C_locale ());
|
||||||
|
#else
|
||||||
|
return strtod_rl (p, end);
|
||||||
|
#endif
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2019 Ebrahim Byagowi
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_NUMBER_HH
|
||||||
|
#define HB_NUMBER_HH
|
||||||
|
|
||||||
|
HB_INTERNAL bool
|
||||||
|
hb_parse_int (const char **pp, const char *end, int *pv,
|
||||||
|
bool whole_buffer = false);
|
||||||
|
|
||||||
|
HB_INTERNAL bool
|
||||||
|
hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
|
||||||
|
bool whole_buffer = false, int base = 10);
|
||||||
|
|
||||||
|
HB_INTERNAL bool
|
||||||
|
hb_parse_double (const char **pp, const char *end, double *pv,
|
||||||
|
bool whole_buffer = false);
|
||||||
|
|
||||||
|
#endif /* HB_NUMBER_HH */
|
|
@ -287,7 +287,7 @@ struct ResourceRecord
|
||||||
{ return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
|
{ return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c,
|
bool sanitize (hb_sanitize_context_t *c,
|
||||||
const void *data_base) const
|
const void *data_base) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (c->check_struct (this) &&
|
return_trace (c->check_struct (this) &&
|
||||||
|
|
|
@ -124,9 +124,9 @@ struct F2DOT14 : HBINT16
|
||||||
};
|
};
|
||||||
|
|
||||||
/* 32-bit signed fixed-point number (16.16). */
|
/* 32-bit signed fixed-point number (16.16). */
|
||||||
struct Fixed : HBINT32
|
struct HBFixed : HBINT32
|
||||||
{
|
{
|
||||||
Fixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; }
|
HBFixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; }
|
||||||
// 65536 means 1<<16
|
// 65536 means 1<<16
|
||||||
float to_float () const { return ((int32_t) v) / 65536.f; }
|
float to_float () const { return ((int32_t) v) / 65536.f; }
|
||||||
void set_float (float f) { v = roundf (f * 65536.f); }
|
void set_float (float f) { v = roundf (f * 65536.f); }
|
||||||
|
@ -163,9 +163,9 @@ struct Tag : HBUINT32
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Glyph index number, same as uint16 (length = 16 bits) */
|
/* Glyph index number, same as uint16 (length = 16 bits) */
|
||||||
struct GlyphID : HBUINT16
|
struct HBGlyphID : HBUINT16
|
||||||
{
|
{
|
||||||
GlyphID& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
|
HBGlyphID& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Script/language-system/feature index */
|
/* Script/language-system/feature index */
|
||||||
|
@ -264,8 +264,8 @@ struct _hb_has_null
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
struct _hb_has_null<Type, true>
|
struct _hb_has_null<Type, true>
|
||||||
{
|
{
|
||||||
static const Type *get_null () { return &Null(Type); }
|
static const Type *get_null () { return &Null (Type); }
|
||||||
static Type *get_crap () { return &Crap(Type); }
|
static Type *get_crap () { return &Crap (Type); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
|
template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
|
||||||
|
@ -423,7 +423,7 @@ struct UnsizedArrayOf
|
||||||
{ return hb_array (arrayZ, len); }
|
{ return hb_array (arrayZ, len); }
|
||||||
hb_array_t<const Type> as_array (unsigned int len) const
|
hb_array_t<const Type> as_array (unsigned int len) const
|
||||||
{ return hb_array (arrayZ, len); }
|
{ return hb_array (arrayZ, len); }
|
||||||
operator hb_array_t<Type> () { return as_array (); }
|
operator hb_array_t< Type> () { return as_array (); }
|
||||||
operator hb_array_t<const Type> () const { return as_array (); }
|
operator hb_array_t<const Type> () const { return as_array (); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -483,7 +483,7 @@ struct UnsizedArrayOf
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Type arrayZ[VAR];
|
Type arrayZ[HB_VAR_ARRAY];
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_UNBOUNDED (0);
|
DEFINE_SIZE_UNBOUNDED (0);
|
||||||
};
|
};
|
||||||
|
@ -669,7 +669,7 @@ struct ArrayOf
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LenType len;
|
LenType len;
|
||||||
Type arrayZ[VAR];
|
Type arrayZ[HB_VAR_ARRAY];
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
||||||
};
|
};
|
||||||
|
@ -802,7 +802,7 @@ struct HeadlessArrayOf
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LenType lenP1;
|
LenType lenP1;
|
||||||
Type arrayZ[VAR];
|
Type arrayZ[HB_VAR_ARRAY];
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
||||||
};
|
};
|
||||||
|
@ -850,7 +850,7 @@ struct ArrayOfM1
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LenType lenM1;
|
LenType lenM1;
|
||||||
Type arrayZ[VAR];
|
Type arrayZ[HB_VAR_ARRAY];
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
||||||
};
|
};
|
||||||
|
@ -902,8 +902,8 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
|
||||||
{ return *as_array ().bsearch (x, ¬_found); }
|
{ return *as_array ().bsearch (x, ¬_found); }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool bfind (const T &x, unsigned int *i = nullptr,
|
bool bfind (const T &x, unsigned int *i = nullptr,
|
||||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||||
unsigned int to_store = (unsigned int) -1) const
|
unsigned int to_store = (unsigned int) -1) const
|
||||||
{ return as_array ().bfind (x, i, not_found, to_store); }
|
{ return as_array ().bfind (x, i, not_found, to_store); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -237,8 +237,8 @@ struct CFFIndex
|
||||||
public:
|
public:
|
||||||
COUNT count; /* Number of object data. Note there are (count+1) offsets */
|
COUNT count; /* Number of object data. Note there are (count+1) offsets */
|
||||||
HBUINT8 offSize; /* The byte size of each offset in the offsets array. */
|
HBUINT8 offSize; /* The byte size of each offset in the offsets array. */
|
||||||
HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
|
HBUINT8 offsets[HB_VAR_ARRAY]; /* The array of (count + 1) offsets into objects array (1-base). */
|
||||||
/* HBUINT8 data[VAR]; Object data */
|
/* HBUINT8 data[HB_VAR_ARRAY]; Object data */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets);
|
DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets);
|
||||||
};
|
};
|
||||||
|
@ -514,9 +514,9 @@ struct FDSelect0 {
|
||||||
unsigned int get_size (unsigned int num_glyphs) const
|
unsigned int get_size (unsigned int num_glyphs) const
|
||||||
{ return HBUINT8::static_size * num_glyphs; }
|
{ return HBUINT8::static_size * num_glyphs; }
|
||||||
|
|
||||||
HBUINT8 fds[VAR];
|
HBUINT8 fds[HB_VAR_ARRAY];
|
||||||
|
|
||||||
DEFINE_SIZE_MIN (1);
|
DEFINE_SIZE_MIN (0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename GID_TYPE, typename FD_TYPE>
|
template <typename GID_TYPE, typename FD_TYPE>
|
||||||
|
@ -564,13 +564,13 @@ struct FDSelect3_4
|
||||||
if (glyph < ranges[i].first)
|
if (glyph < ranges[i].first)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
return (hb_codepoint_t)ranges[i - 1].fd;
|
return (hb_codepoint_t) ranges[i - 1].fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
GID_TYPE &nRanges () { return ranges.len; }
|
GID_TYPE &nRanges () { return ranges.len; }
|
||||||
GID_TYPE nRanges () const { return ranges.len; }
|
GID_TYPE nRanges () const { return ranges.len; }
|
||||||
GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
|
GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
|
||||||
const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
|
const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
|
||||||
|
|
||||||
ArrayOf<FDSelect3_4_Range<GID_TYPE, FD_TYPE>, GID_TYPE> ranges;
|
ArrayOf<FDSelect3_4_Range<GID_TYPE, FD_TYPE>, GID_TYPE> ranges;
|
||||||
/* GID_TYPE sentinel */
|
/* GID_TYPE sentinel */
|
||||||
|
@ -608,8 +608,8 @@ struct FDSelect
|
||||||
|
|
||||||
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
if (this == &Null (FDSelect))
|
if (this == &Null (FDSelect)) return 0;
|
||||||
return 0;
|
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case 0: return u.format0.get_fd (glyph);
|
case 0: return u.format0.get_fd (glyph);
|
||||||
|
|
|
@ -203,8 +203,7 @@ struct bounds_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty () const
|
bool empty () const { return (min.x >= max.x) || (min.y >= max.y); }
|
||||||
{ return (min.x >= max.x) || (min.y >= max.y); }
|
|
||||||
|
|
||||||
point_t min;
|
point_t min;
|
||||||
point_t max;
|
point_t max;
|
||||||
|
@ -219,12 +218,12 @@ struct cff1_extents_param_t
|
||||||
bounds.init ();
|
bounds.init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_path () { path_open = true; }
|
void start_path () { path_open = true; }
|
||||||
void end_path () { path_open = false; }
|
void end_path () { path_open = false; }
|
||||||
bool is_path_open () const { return path_open; }
|
bool is_path_open () const { return path_open; }
|
||||||
|
|
||||||
bool path_open;
|
bool path_open;
|
||||||
bounds_t bounds;
|
bounds_t bounds;
|
||||||
|
|
||||||
const OT::cff1::accelerator_t *cff;
|
const OT::cff1::accelerator_t *cff;
|
||||||
};
|
};
|
||||||
|
|
|
@ -357,7 +357,7 @@ struct Charset0 {
|
||||||
return HBUINT16::static_size * (num_glyphs - 1);
|
return HBUINT16::static_size * (num_glyphs - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
HBUINT16 sids[VAR];
|
HBUINT16 sids[HB_VAR_ARRAY];
|
||||||
|
|
||||||
DEFINE_SIZE_ARRAY(0, sids);
|
DEFINE_SIZE_ARRAY(0, sids);
|
||||||
};
|
};
|
||||||
|
@ -439,7 +439,7 @@ struct Charset1_2 {
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
Charset_Range<TYPE> ranges[VAR];
|
Charset_Range<TYPE> ranges[HB_VAR_ARRAY];
|
||||||
|
|
||||||
DEFINE_SIZE_ARRAY (0, ranges);
|
DEFINE_SIZE_ARRAY (0, ranges);
|
||||||
};
|
};
|
||||||
|
@ -1155,7 +1155,7 @@ struct cff1
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_valid () const { return blob != nullptr; }
|
bool is_valid () const { return blob != nullptr; }
|
||||||
bool is_CID () const { return topDict.is_CID (); }
|
bool is_CID () const { return topDict.is_CID (); }
|
||||||
|
|
||||||
bool is_predef_charset () const { return topDict.CharsetOffset <= ExpertSubsetCharset; }
|
bool is_predef_charset () const { return topDict.CharsetOffset <= ExpertSubsetCharset; }
|
||||||
|
|
||||||
|
@ -1225,25 +1225,25 @@ struct cff1
|
||||||
|
|
||||||
bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
|
bool is_predef_encoding () const { return topDict.EncodingOffset <= ExpertEncoding; }
|
||||||
|
|
||||||
hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
|
hb_codepoint_t glyph_to_code (hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
if (encoding != &Null(Encoding))
|
if (encoding != &Null(Encoding))
|
||||||
return encoding->get_code (glyph);
|
return encoding->get_code (glyph);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hb_codepoint_t sid = glyph_to_sid (glyph);
|
hb_codepoint_t sid = glyph_to_sid (glyph);
|
||||||
if (sid == 0) return 0;
|
if (sid == 0) return 0;
|
||||||
hb_codepoint_t code = 0;
|
hb_codepoint_t code = 0;
|
||||||
switch (topDict.EncodingOffset)
|
switch (topDict.EncodingOffset)
|
||||||
{
|
{
|
||||||
case StandardEncoding:
|
case StandardEncoding:
|
||||||
code = lookup_standard_encoding_for_code (sid);
|
code = lookup_standard_encoding_for_code (sid);
|
||||||
break;
|
break;
|
||||||
case ExpertEncoding:
|
case ExpertEncoding:
|
||||||
code = lookup_expert_encoding_for_code (sid);
|
code = lookup_expert_encoding_for_code (sid);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,8 +44,8 @@ struct cff2_extents_param_t
|
||||||
max_y.set_int (INT_MIN);
|
max_y.set_int (INT_MIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_path () { path_open = true; }
|
void start_path () { path_open = true; }
|
||||||
void end_path () { path_open = false; }
|
void end_path () { path_open = false; }
|
||||||
bool is_path_open () const { return path_open; }
|
bool is_path_open () const { return path_open; }
|
||||||
|
|
||||||
void update_bounds (const point_t &pt)
|
void update_bounds (const point_t &pt)
|
||||||
|
|
|
@ -334,9 +334,7 @@ struct CmapSubtableFormat4
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
|
HB_INTERNAL static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
|
||||||
{
|
{ return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph); }
|
||||||
return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph);
|
|
||||||
}
|
|
||||||
void collect_unicodes (hb_set_t *out) const
|
void collect_unicodes (hb_set_t *out) const
|
||||||
{
|
{
|
||||||
unsigned int count = this->segCount;
|
unsigned int count = this->segCount;
|
||||||
|
@ -498,7 +496,7 @@ struct CmapSubtableTrimmed
|
||||||
UINT length; /* Byte length of this subtable. */
|
UINT length; /* Byte length of this subtable. */
|
||||||
UINT language; /* Ignore. */
|
UINT language; /* Ignore. */
|
||||||
UINT startCharCode; /* First character code covered. */
|
UINT startCharCode; /* First character code covered. */
|
||||||
ArrayOf<GlyphID, UINT>
|
ArrayOf<HBGlyphID, UINT>
|
||||||
glyphIdArray; /* Array of glyph index values for character
|
glyphIdArray; /* Array of glyph index values for character
|
||||||
* codes in the range. */
|
* codes in the range. */
|
||||||
public:
|
public:
|
||||||
|
@ -609,11 +607,9 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t get_sub_table_size (const hb_sorted_vector_t<CmapSubtableLongGroup> &groups_data)
|
static size_t get_sub_table_size (const hb_sorted_vector_t<CmapSubtableLongGroup> &groups_data)
|
||||||
{
|
{ return 16 + 12 * groups_data.length; }
|
||||||
return 16 + 12 * groups_data.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static bool _is_gid_consecutive (hb_codepoint_t endCharCode,
|
static bool _is_gid_consecutive (hb_codepoint_t endCharCode,
|
||||||
hb_codepoint_t startCharCode,
|
hb_codepoint_t startCharCode,
|
||||||
hb_codepoint_t glyphID,
|
hb_codepoint_t glyphID,
|
||||||
|
@ -676,6 +672,63 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefaultUVS* copy (hb_serialize_context_t *c,
|
||||||
|
const hb_set_t *unicodes) const
|
||||||
|
{
|
||||||
|
DefaultUVS *out = c->start_embed<DefaultUVS> ();
|
||||||
|
if (unlikely (!out)) return nullptr;
|
||||||
|
auto snap = c->snapshot ();
|
||||||
|
|
||||||
|
HBUINT32 len;
|
||||||
|
len = 0;
|
||||||
|
if (unlikely (!c->copy<HBUINT32> (len))) return nullptr;
|
||||||
|
unsigned init_len = c->length ();
|
||||||
|
|
||||||
|
hb_codepoint_t lastCode = HB_MAP_VALUE_INVALID;
|
||||||
|
int count = -1;
|
||||||
|
|
||||||
|
for (const UnicodeValueRange& _ : as_array ())
|
||||||
|
{
|
||||||
|
for (const unsigned addcnt : hb_range ((unsigned) _.additionalCount + 1))
|
||||||
|
{
|
||||||
|
unsigned curEntry = (unsigned) _.startUnicodeValue + addcnt;
|
||||||
|
if (!unicodes->has (curEntry)) continue;
|
||||||
|
count += 1;
|
||||||
|
if (lastCode == HB_MAP_VALUE_INVALID)
|
||||||
|
lastCode = curEntry;
|
||||||
|
else if (lastCode + count != curEntry)
|
||||||
|
{
|
||||||
|
UnicodeValueRange rec;
|
||||||
|
rec.startUnicodeValue = lastCode;
|
||||||
|
rec.additionalCount = count - 1;
|
||||||
|
c->copy<UnicodeValueRange> (rec);
|
||||||
|
|
||||||
|
lastCode = curEntry;
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastCode != HB_MAP_VALUE_INVALID)
|
||||||
|
{
|
||||||
|
UnicodeValueRange rec;
|
||||||
|
rec.startUnicodeValue = lastCode;
|
||||||
|
rec.additionalCount = count;
|
||||||
|
c->copy<UnicodeValueRange> (rec);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c->length () - init_len == 0)
|
||||||
|
{
|
||||||
|
c->revert (snap);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (unlikely (!c->check_assign (out->len, (c->length () - init_len) / UnicodeValueRange::static_size))) return nullptr;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (4, *this);
|
DEFINE_SIZE_ARRAY (4, *this);
|
||||||
};
|
};
|
||||||
|
@ -683,9 +736,7 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32>
|
||||||
struct UVSMapping
|
struct UVSMapping
|
||||||
{
|
{
|
||||||
int cmp (const hb_codepoint_t &codepoint) const
|
int cmp (const hb_codepoint_t &codepoint) const
|
||||||
{
|
{ return unicodeValue.cmp (codepoint); }
|
||||||
return unicodeValue.cmp (codepoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
@ -694,7 +745,7 @@ struct UVSMapping
|
||||||
}
|
}
|
||||||
|
|
||||||
HBUINT24 unicodeValue; /* Base Unicode value of the UVS */
|
HBUINT24 unicodeValue; /* Base Unicode value of the UVS */
|
||||||
GlyphID glyphID; /* Glyph ID of the UVS */
|
HBGlyphID glyphID; /* Glyph ID of the UVS */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (5);
|
DEFINE_SIZE_STATIC (5);
|
||||||
};
|
};
|
||||||
|
@ -708,6 +759,49 @@ struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32>
|
||||||
out->add (arrayZ[i].glyphID);
|
out->add (arrayZ[i].glyphID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void closure_glyphs (const hb_set_t *unicodes,
|
||||||
|
hb_set_t *glyphset) const
|
||||||
|
{
|
||||||
|
+ as_array ()
|
||||||
|
| hb_filter (unicodes, &UVSMapping::unicodeValue)
|
||||||
|
| hb_map (&UVSMapping::glyphID)
|
||||||
|
| hb_sink (glyphset)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
NonDefaultUVS* copy (hb_serialize_context_t *c,
|
||||||
|
const hb_set_t *unicodes,
|
||||||
|
const hb_set_t *glyphs,
|
||||||
|
const hb_map_t *glyph_map) const
|
||||||
|
{
|
||||||
|
NonDefaultUVS *out = c->start_embed<NonDefaultUVS> ();
|
||||||
|
if (unlikely (!out)) return nullptr;
|
||||||
|
|
||||||
|
auto it =
|
||||||
|
+ as_array ()
|
||||||
|
| hb_filter ([&] (const UVSMapping& _)
|
||||||
|
{
|
||||||
|
return unicodes->has (_.unicodeValue) || glyphs->has (_.glyphID);
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
if (!it) return nullptr;
|
||||||
|
|
||||||
|
HBUINT32 len;
|
||||||
|
len = it.len ();
|
||||||
|
if (unlikely (!c->copy<HBUINT32> (len))) return nullptr;
|
||||||
|
|
||||||
|
for (const UVSMapping& _ : it)
|
||||||
|
{
|
||||||
|
UVSMapping mapping;
|
||||||
|
mapping.unicodeValue = _.unicodeValue;
|
||||||
|
mapping.glyphID = glyph_map->get (_.glyphID);
|
||||||
|
c->copy<UVSMapping> (mapping);
|
||||||
|
}
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (4, *this);
|
DEFINE_SIZE_ARRAY (4, *this);
|
||||||
};
|
};
|
||||||
|
@ -736,9 +830,7 @@ struct VariationSelectorRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
int cmp (const hb_codepoint_t &variation_selector) const
|
int cmp (const hb_codepoint_t &variation_selector) const
|
||||||
{
|
{ return varSelector.cmp (variation_selector); }
|
||||||
return varSelector.cmp (variation_selector);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
{
|
{
|
||||||
|
@ -748,6 +840,52 @@ struct VariationSelectorRecord
|
||||||
nonDefaultUVS.sanitize (c, base));
|
nonDefaultUVS.sanitize (c, base));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VariationSelectorRecord* copy (hb_serialize_context_t *c,
|
||||||
|
const hb_set_t *unicodes,
|
||||||
|
const hb_set_t *glyphs,
|
||||||
|
const hb_map_t *glyph_map,
|
||||||
|
const void *src_base,
|
||||||
|
const void *dst_base) const
|
||||||
|
{
|
||||||
|
auto snap = c->snapshot ();
|
||||||
|
auto *out = c->embed<VariationSelectorRecord> (*this);
|
||||||
|
if (unlikely (!out)) return nullptr;
|
||||||
|
|
||||||
|
out->defaultUVS = 0;
|
||||||
|
out->nonDefaultUVS = 0;
|
||||||
|
|
||||||
|
bool drop = true;
|
||||||
|
|
||||||
|
if (defaultUVS != 0)
|
||||||
|
{
|
||||||
|
c->push ();
|
||||||
|
if (c->copy (src_base+defaultUVS, unicodes))
|
||||||
|
{
|
||||||
|
c->add_link (out->defaultUVS, c->pop_pack (), dst_base);
|
||||||
|
drop = false;
|
||||||
|
}
|
||||||
|
else c->pop_discard ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nonDefaultUVS != 0)
|
||||||
|
{
|
||||||
|
c->push ();
|
||||||
|
if (c->copy (src_base+nonDefaultUVS, unicodes, glyphs, glyph_map))
|
||||||
|
{
|
||||||
|
c->add_link (out->nonDefaultUVS, c->pop_pack (), dst_base);
|
||||||
|
drop = false;
|
||||||
|
}
|
||||||
|
else c->pop_discard ();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (drop)
|
||||||
|
{
|
||||||
|
c->revert (snap);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
else return out;
|
||||||
|
}
|
||||||
|
|
||||||
HBUINT24 varSelector; /* Variation selector. */
|
HBUINT24 varSelector; /* Variation selector. */
|
||||||
LOffsetTo<DefaultUVS>
|
LOffsetTo<DefaultUVS>
|
||||||
defaultUVS; /* Offset to Default UVS Table. May be 0. */
|
defaultUVS; /* Offset to Default UVS Table. May be 0. */
|
||||||
|
@ -762,9 +900,7 @@ struct CmapSubtableFormat14
|
||||||
glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
|
glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
|
||||||
hb_codepoint_t variation_selector,
|
hb_codepoint_t variation_selector,
|
||||||
hb_codepoint_t *glyph) const
|
hb_codepoint_t *glyph) const
|
||||||
{
|
{ return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this); }
|
||||||
return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void collect_variation_selectors (hb_set_t *out) const
|
void collect_variation_selectors (hb_set_t *out) const
|
||||||
{
|
{
|
||||||
|
@ -774,8 +910,44 @@ struct CmapSubtableFormat14
|
||||||
}
|
}
|
||||||
void collect_variation_unicodes (hb_codepoint_t variation_selector,
|
void collect_variation_unicodes (hb_codepoint_t variation_selector,
|
||||||
hb_set_t *out) const
|
hb_set_t *out) const
|
||||||
|
{ record.bsearch (variation_selector).collect_unicodes (out, this); }
|
||||||
|
|
||||||
|
void serialize (hb_serialize_context_t *c,
|
||||||
|
const hb_set_t *unicodes,
|
||||||
|
const hb_set_t *glyphs,
|
||||||
|
const hb_map_t *glyph_map,
|
||||||
|
const void *src_base)
|
||||||
{
|
{
|
||||||
record.bsearch (variation_selector).collect_unicodes (out, this);
|
auto snap = c->snapshot ();
|
||||||
|
unsigned table_initpos = c->length ();
|
||||||
|
const char* init_tail = c->tail;
|
||||||
|
|
||||||
|
if (unlikely (!c->extend_min (*this))) return;
|
||||||
|
this->format = 14;
|
||||||
|
|
||||||
|
const CmapSubtableFormat14 *src_tbl = reinterpret_cast<const CmapSubtableFormat14*> (src_base);
|
||||||
|
for (const VariationSelectorRecord& _ : src_tbl->record)
|
||||||
|
c->copy (_, unicodes, glyphs, glyph_map, src_base, this);
|
||||||
|
|
||||||
|
if (c->length () - table_initpos == CmapSubtableFormat14::min_size)
|
||||||
|
c->revert (snap);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int tail_len = init_tail - c->tail;
|
||||||
|
c->check_assign (this->length, c->length () - table_initpos + tail_len);
|
||||||
|
c->check_assign (this->record.len, (c->length () - table_initpos - CmapSubtableFormat14::min_size) / VariationSelectorRecord::static_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void closure_glyphs (const hb_set_t *unicodes,
|
||||||
|
hb_set_t *glyphset) const
|
||||||
|
{
|
||||||
|
+ hb_iter (record)
|
||||||
|
| hb_filter (hb_bool, &VariationSelectorRecord::nonDefaultUVS)
|
||||||
|
| hb_map (&VariationSelectorRecord::nonDefaultUVS)
|
||||||
|
| hb_map (hb_add (this))
|
||||||
|
| hb_apply ([=] (const NonDefaultUVS& _) { _.closure_glyphs (unicodes, glyphset); })
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
@ -831,11 +1003,14 @@ struct CmapSubtable
|
||||||
hb_requires (hb_is_iterator (Iterator))>
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
void serialize (hb_serialize_context_t *c,
|
void serialize (hb_serialize_context_t *c,
|
||||||
Iterator it,
|
Iterator it,
|
||||||
unsigned format)
|
unsigned format,
|
||||||
|
const hb_subset_plan_t *plan,
|
||||||
|
const void *src_base)
|
||||||
{
|
{
|
||||||
switch (format) {
|
switch (format) {
|
||||||
case 4: u.format4.serialize (c, it); return;
|
case 4: u.format4.serialize (c, it); return;
|
||||||
case 12: u.format12.serialize (c, it); return;
|
case 12: u.format12.serialize (c, it); return;
|
||||||
|
case 14: u.format14.serialize (c, plan->unicodes, plan->_glyphset, plan->glyph_map, src_base); return;
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -896,10 +1071,13 @@ struct EncodingRecord
|
||||||
EncodingRecord* copy (hb_serialize_context_t *c,
|
EncodingRecord* copy (hb_serialize_context_t *c,
|
||||||
Iterator it,
|
Iterator it,
|
||||||
unsigned format,
|
unsigned format,
|
||||||
void *base,
|
const void *src_base,
|
||||||
|
const void *dst_base,
|
||||||
|
const hb_subset_plan_t *plan,
|
||||||
/* INOUT */ unsigned *objidx) const
|
/* INOUT */ unsigned *objidx) const
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
auto snap = c->snapshot ();
|
||||||
auto *out = c->embed (this);
|
auto *out = c->embed (this);
|
||||||
if (unlikely (!out)) return_trace (nullptr);
|
if (unlikely (!out)) return_trace (nullptr);
|
||||||
out->subtable = 0;
|
out->subtable = 0;
|
||||||
|
@ -908,12 +1086,18 @@ struct EncodingRecord
|
||||||
{
|
{
|
||||||
CmapSubtable *cmapsubtable = c->push<CmapSubtable> ();
|
CmapSubtable *cmapsubtable = c->push<CmapSubtable> ();
|
||||||
unsigned origin_length = c->length ();
|
unsigned origin_length = c->length ();
|
||||||
cmapsubtable->serialize (c, it, format);
|
cmapsubtable->serialize (c, it, format, plan, &(src_base+subtable));
|
||||||
if (c->length () - origin_length > 0) *objidx = c->pop_pack ();
|
if (c->length () - origin_length > 0) *objidx = c->pop_pack ();
|
||||||
else c->pop_discard ();
|
else c->pop_discard ();
|
||||||
}
|
}
|
||||||
|
|
||||||
c->add_link (out->subtable, *objidx, base);
|
if (*objidx == 0)
|
||||||
|
{
|
||||||
|
c->revert (snap);
|
||||||
|
return_trace (nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
c->add_link (out->subtable, *objidx, dst_base);
|
||||||
return_trace (out);
|
return_trace (out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -929,27 +1113,40 @@ struct cmap
|
||||||
{
|
{
|
||||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
|
static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
|
||||||
|
|
||||||
template<typename Iterator,
|
template<typename Iterator, typename EncodingRecIter,
|
||||||
hb_requires (hb_is_iterator (Iterator))>
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
void serialize (hb_serialize_context_t *c,
|
void serialize (hb_serialize_context_t *c,
|
||||||
Iterator it,
|
Iterator it,
|
||||||
const EncodingRecord *unicode_bmp,
|
EncodingRecIter encodingrec_iter,
|
||||||
const EncodingRecord *unicode_ucs4,
|
const void *src_base,
|
||||||
const EncodingRecord *ms_bmp,
|
const hb_subset_plan_t *plan)
|
||||||
const EncodingRecord *ms_ucs4)
|
|
||||||
{
|
{
|
||||||
if (unlikely (!c->extend_min ((*this)))) return;
|
if (unlikely (!c->extend_min ((*this)))) return;
|
||||||
this->version = 0;
|
this->version = 0;
|
||||||
|
|
||||||
unsigned numTables = (unicode_bmp ? 1 : 0) + (unicode_ucs4 ? 1 : 0) + (ms_bmp ? 1 : 0) + (ms_ucs4 ? 1 : 0);
|
unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0;
|
||||||
if (unlikely (!c->check_assign(this->encodingRecord.len, numTables))) return;
|
|
||||||
|
|
||||||
unsigned format4objidx = 0, format12objidx = 0;
|
for (const EncodingRecord& _ : encodingrec_iter)
|
||||||
if (unicode_bmp) c->copy (unicode_bmp, it, 4u, this, &format4objidx);
|
{
|
||||||
if (unicode_ucs4) c->copy (unicode_ucs4, it, 12u, this, &format12objidx);
|
unsigned format = (src_base+_.subtable).u.format;
|
||||||
if (ms_bmp) c->copy (ms_bmp, it, 4u, this, &format4objidx);
|
|
||||||
if (ms_ucs4) c->copy (ms_ucs4, it, 12u, this, &format12objidx);
|
|
||||||
|
|
||||||
|
if (format == 4) c->copy (_, it, 4u, src_base, this, plan, &format4objidx);
|
||||||
|
else if (format == 12) c->copy (_, it, 12u, src_base, this, plan, &format12objidx);
|
||||||
|
else if (format == 14) c->copy (_, it, 14u, src_base, this, plan, &format14objidx);
|
||||||
|
}
|
||||||
|
|
||||||
|
c->check_assign(this->encodingRecord.len, (c->length () - cmap::min_size)/EncodingRecord::static_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void closure_glyphs (const hb_set_t *unicodes,
|
||||||
|
hb_set_t *glyphset) const
|
||||||
|
{
|
||||||
|
+ hb_iter (encodingRecord)
|
||||||
|
| hb_map (&EncodingRecord::subtable)
|
||||||
|
| hb_map (hb_add (this))
|
||||||
|
| hb_filter ([&] (const CmapSubtable& _) { return _.u.format == 14; })
|
||||||
|
| hb_apply ([=] (const CmapSubtable& _) { _.u.format14.closure_glyphs (unicodes, glyphset); })
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
@ -959,31 +1156,55 @@ struct cmap
|
||||||
cmap *cmap_prime = c->serializer->start_embed<cmap> ();
|
cmap *cmap_prime = c->serializer->start_embed<cmap> ();
|
||||||
if (unlikely (!c->serializer->check_success (cmap_prime))) return_trace (false);
|
if (unlikely (!c->serializer->check_success (cmap_prime))) return_trace (false);
|
||||||
|
|
||||||
const EncodingRecord *unicode_bmp = find_encodingrec (0, 3);
|
auto encodingrec_iter =
|
||||||
const EncodingRecord *unicode_ucs4 = find_encodingrec (0, 4);
|
+ hb_iter (encodingRecord)
|
||||||
const EncodingRecord *ms_bmp = find_encodingrec (3, 1);
|
| hb_filter ([&] (const EncodingRecord& _)
|
||||||
const EncodingRecord *ms_ucs4 = find_encodingrec (3, 10);
|
{
|
||||||
bool has_format12 = find_subtable (12);
|
if ((_.platformID == 0 && _.encodingID == 3) ||
|
||||||
|
(_.platformID == 0 && _.encodingID == 4) ||
|
||||||
|
(_.platformID == 3 && _.encodingID == 1) ||
|
||||||
|
(_.platformID == 3 && _.encodingID == 10) ||
|
||||||
|
(this + _.subtable).u.format == 14)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
if (unlikely (!encodingrec_iter.len ())) return_trace (false);
|
||||||
|
|
||||||
|
const EncodingRecord *unicode_bmp= nullptr, *unicode_ucs4 = nullptr, *ms_bmp = nullptr, *ms_ucs4 = nullptr;
|
||||||
|
bool has_format12 = false;
|
||||||
|
|
||||||
|
for (const EncodingRecord& _ : encodingrec_iter)
|
||||||
|
{
|
||||||
|
unsigned format = (this + _.subtable).u.format;
|
||||||
|
if (format == 12) has_format12 = true;
|
||||||
|
|
||||||
|
const EncodingRecord *table = hb_addressof (_);
|
||||||
|
if (_.platformID == 0 && _.encodingID == 3) unicode_bmp = table;
|
||||||
|
else if (_.platformID == 0 && _.encodingID == 4) unicode_ucs4 = table;
|
||||||
|
else if (_.platformID == 3 && _.encodingID == 1) ms_bmp = table;
|
||||||
|
else if (_.platformID == 3 && _.encodingID == 10) ms_ucs4 = table;
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely (!unicode_bmp && !ms_bmp)) return_trace (false);
|
if (unlikely (!unicode_bmp && !ms_bmp)) return_trace (false);
|
||||||
if (unlikely (has_format12 && (!unicode_ucs4 && !ms_ucs4))) return_trace (false);
|
if (unlikely (has_format12 && (!unicode_ucs4 && !ms_ucs4))) return_trace (false);
|
||||||
|
|
||||||
|
|
||||||
auto it =
|
auto it =
|
||||||
+ hb_iter (c->plan->unicodes)
|
+ hb_iter (c->plan->unicodes)
|
||||||
| hb_map ([&] (hb_codepoint_t _)
|
| hb_map ([&] (hb_codepoint_t _)
|
||||||
{
|
|
||||||
hb_codepoint_t new_gid = HB_MAP_VALUE_INVALID;
|
|
||||||
c->plan->new_gid_for_codepoint (_, &new_gid);
|
|
||||||
return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, new_gid);
|
|
||||||
})
|
|
||||||
| hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _)
|
|
||||||
{
|
{
|
||||||
return (_.second != HB_MAP_VALUE_INVALID);
|
hb_codepoint_t new_gid = HB_MAP_VALUE_INVALID;
|
||||||
|
c->plan->new_gid_for_codepoint (_, &new_gid);
|
||||||
|
return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, new_gid);
|
||||||
})
|
})
|
||||||
|
| hb_filter ([&] (const hb_pair_t<hb_codepoint_t, hb_codepoint_t> _)
|
||||||
|
{ return (_.second != HB_MAP_VALUE_INVALID); })
|
||||||
;
|
;
|
||||||
|
|
||||||
cmap_prime->serialize (c->serializer, it, unicode_bmp, unicode_ucs4, ms_bmp, ms_ucs4);
|
cmap_prime->serialize (c->serializer, it, encodingrec_iter, this, c->plan);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1034,9 +1255,9 @@ struct cmap
|
||||||
|
|
||||||
this->get_glyph_data = subtable;
|
this->get_glyph_data = subtable;
|
||||||
if (unlikely (symbol))
|
if (unlikely (symbol))
|
||||||
{
|
|
||||||
this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>;
|
this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>;
|
||||||
} else {
|
else
|
||||||
|
{
|
||||||
switch (subtable->u.format) {
|
switch (subtable->u.format) {
|
||||||
/* Accelerate format 4 and format 12. */
|
/* Accelerate format 4 and format 12. */
|
||||||
default:
|
default:
|
||||||
|
@ -1046,20 +1267,20 @@ struct cmap
|
||||||
this->get_glyph_funcZ = get_glyph_from<CmapSubtableFormat12>;
|
this->get_glyph_funcZ = get_glyph_from<CmapSubtableFormat12>;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
{
|
{
|
||||||
this->format4_accel.init (&subtable->u.format4);
|
this->format4_accel.init (&subtable->u.format4);
|
||||||
this->get_glyph_data = &this->format4_accel;
|
this->get_glyph_data = &this->format4_accel;
|
||||||
this->get_glyph_funcZ = this->format4_accel.get_glyph_func;
|
this->get_glyph_funcZ = this->format4_accel.get_glyph_func;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void fini () { this->table.destroy (); }
|
void fini () { this->table.destroy (); }
|
||||||
|
|
||||||
bool get_nominal_glyph (hb_codepoint_t unicode,
|
bool get_nominal_glyph (hb_codepoint_t unicode,
|
||||||
hb_codepoint_t *glyph) const
|
hb_codepoint_t *glyph) const
|
||||||
{
|
{
|
||||||
if (unlikely (!this->get_glyph_funcZ)) return false;
|
if (unlikely (!this->get_glyph_funcZ)) return false;
|
||||||
return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
|
return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
|
||||||
|
@ -1103,18 +1324,12 @@ struct cmap
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect_unicodes (hb_set_t *out) const
|
void collect_unicodes (hb_set_t *out) const
|
||||||
{
|
{ subtable->collect_unicodes (out); }
|
||||||
subtable->collect_unicodes (out);
|
|
||||||
}
|
|
||||||
void collect_variation_selectors (hb_set_t *out) const
|
void collect_variation_selectors (hb_set_t *out) const
|
||||||
{
|
{ subtable_uvs->collect_variation_selectors (out); }
|
||||||
subtable_uvs->collect_variation_selectors (out);
|
|
||||||
}
|
|
||||||
void collect_variation_unicodes (hb_codepoint_t variation_selector,
|
void collect_variation_unicodes (hb_codepoint_t variation_selector,
|
||||||
hb_set_t *out) const
|
hb_set_t *out) const
|
||||||
{
|
{ subtable_uvs->collect_variation_unicodes (variation_selector, out); }
|
||||||
subtable_uvs->collect_variation_unicodes (variation_selector, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
|
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
|
||||||
|
@ -1161,6 +1376,7 @@ struct cmap
|
||||||
|
|
||||||
CmapSubtableFormat4::accelerator_t format4_accel;
|
CmapSubtableFormat4::accelerator_t format4_accel;
|
||||||
|
|
||||||
|
public:
|
||||||
hb_blob_ptr_t<cmap> table;
|
hb_blob_ptr_t<cmap> table;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -226,8 +226,8 @@ struct IndexSubtableRecord
|
||||||
offset, length, format);
|
offset, length, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlyphID firstGlyphIndex;
|
HBGlyphID firstGlyphIndex;
|
||||||
GlyphID lastGlyphIndex;
|
HBGlyphID lastGlyphIndex;
|
||||||
LOffsetTo<IndexSubtable> offsetToSubtable;
|
LOffsetTo<IndexSubtable> offsetToSubtable;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC(8);
|
DEFINE_SIZE_STATIC(8);
|
||||||
|
@ -290,8 +290,8 @@ struct BitmapSizeTable
|
||||||
HBUINT32 colorRef;
|
HBUINT32 colorRef;
|
||||||
SBitLineMetrics horizontal;
|
SBitLineMetrics horizontal;
|
||||||
SBitLineMetrics vertical;
|
SBitLineMetrics vertical;
|
||||||
GlyphID startGlyphIndex;
|
HBGlyphID startGlyphIndex;
|
||||||
GlyphID endGlyphIndex;
|
HBGlyphID endGlyphIndex;
|
||||||
HBUINT8 ppemX;
|
HBUINT8 ppemX;
|
||||||
HBUINT8 ppemY;
|
HBUINT8 ppemY;
|
||||||
HBUINT8 bitDepth;
|
HBUINT8 bitDepth;
|
||||||
|
@ -453,7 +453,7 @@ struct CBDT
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_blob_t* reference_png (hb_font_t *font,
|
hb_blob_t* reference_png (hb_font_t *font,
|
||||||
hb_codepoint_t glyph) const
|
hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
const void *base;
|
const void *base;
|
||||||
const BitmapSizeTable &strike = this->cblc->choose_strike (font);
|
const BitmapSizeTable &strike = this->cblc->choose_strike (font);
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct LayerRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlyphID glyphId; /* Glyph ID of layer glyph */
|
HBGlyphID glyphId; /* Glyph ID of layer glyph */
|
||||||
Index colorIdx; /* Index value to use with a
|
Index colorIdx; /* Index value to use with a
|
||||||
* selected color palette.
|
* selected color palette.
|
||||||
* An index value of 0xFFFF
|
* An index value of 0xFFFF
|
||||||
|
@ -75,7 +75,7 @@ struct BaseGlyphRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GlyphID glyphId; /* Glyph ID of reference glyph */
|
HBGlyphID glyphId; /* Glyph ID of reference glyph */
|
||||||
HBUINT16 firstLayerIdx; /* Index (from beginning of
|
HBUINT16 firstLayerIdx; /* Index (from beginning of
|
||||||
* the Layer Records) to the
|
* the Layer Records) to the
|
||||||
* layer record. There will be
|
* layer record. There will be
|
||||||
|
|
|
@ -115,7 +115,7 @@ struct CPAL
|
||||||
{ return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
|
{ return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
|
||||||
|
|
||||||
unsigned int get_palette_count () const { return numPalettes; }
|
unsigned int get_palette_count () const { return numPalettes; }
|
||||||
unsigned int get_color_count () const { return numColors; }
|
unsigned int get_color_count () const { return numColors; }
|
||||||
|
|
||||||
hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
|
hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
|
||||||
{ return v1 ().get_palette_flags (this, palette_index, numPalettes); }
|
{ return v1 ().get_palette_flags (this, palette_index, numPalettes); }
|
||||||
|
|
|
@ -125,7 +125,7 @@ struct SBIXStrike
|
||||||
imageOffsetsZ; /* Offset from the beginning of the strike data header
|
imageOffsetsZ; /* Offset from the beginning of the strike data header
|
||||||
* to bitmap data for an individual glyph ID. */
|
* to bitmap data for an individual glyph ID. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (8);
|
DEFINE_SIZE_ARRAY (4, imageOffsetsZ);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sbix
|
struct sbix
|
||||||
|
|
|
@ -147,11 +147,7 @@ struct glyf
|
||||||
const hb_subset_plan_t *plan)
|
const hb_subset_plan_t *plan)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
for (const auto &_ : it) _.serialize (c, plan);
|
||||||
+ it
|
|
||||||
| hb_apply ([=] (const SubsetGlyph& _) { _.serialize (c, plan); })
|
|
||||||
;
|
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,7 +322,7 @@ struct glyf
|
||||||
};
|
};
|
||||||
|
|
||||||
HBUINT16 flags;
|
HBUINT16 flags;
|
||||||
GlyphID glyphIndex;
|
HBGlyphID glyphIndex;
|
||||||
|
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{
|
{
|
||||||
|
|
|
@ -197,8 +197,6 @@ struct hmtxvmtx
|
||||||
var_table.destroy ();
|
var_table.destroy ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool has_data () const { return table.get () != nullptr; }
|
|
||||||
|
|
||||||
int get_side_bearing (hb_codepoint_t glyph) const
|
int get_side_bearing (hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
if (glyph < num_advances)
|
if (glyph < num_advances)
|
||||||
|
@ -214,17 +212,14 @@ struct hmtxvmtx
|
||||||
int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
|
int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
|
||||||
{
|
{
|
||||||
int side_bearing = get_side_bearing (glyph);
|
int side_bearing = get_side_bearing (glyph);
|
||||||
if (likely (glyph < num_metrics))
|
|
||||||
{
|
if (unlikely (glyph >= num_metrics) || !font->num_coords)
|
||||||
if (font->num_coords)
|
return side_bearing;
|
||||||
{
|
|
||||||
if (var_table.get_blob () != hb_blob_get_empty ())
|
if (var_table.get_blob () == &Null (hb_blob_t))
|
||||||
side_bearing += var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
|
return get_side_bearing_var_tt (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
|
||||||
else
|
|
||||||
side_bearing = get_side_bearing_var_tt (font, glyph, T::tableTag==HB_OT_TAG_vmtx);
|
return side_bearing + var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
|
||||||
}
|
|
||||||
}
|
|
||||||
return side_bearing;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int get_advance (hb_codepoint_t glyph) const
|
unsigned int get_advance (hb_codepoint_t glyph) const
|
||||||
|
@ -247,17 +242,14 @@ struct hmtxvmtx
|
||||||
hb_font_t *font) const
|
hb_font_t *font) const
|
||||||
{
|
{
|
||||||
unsigned int advance = get_advance (glyph);
|
unsigned int advance = get_advance (glyph);
|
||||||
if (likely (glyph < num_metrics))
|
|
||||||
{
|
if (unlikely (glyph >= num_metrics) || !font->num_coords)
|
||||||
if (font->num_coords)
|
return advance;
|
||||||
{
|
|
||||||
if (var_table.get_blob () != hb_blob_get_empty ())
|
if (var_table.get_blob () == &Null (hb_blob_t))
|
||||||
advance += roundf (var_table->get_advance_var (glyph, font->coords, font->num_coords)); // TODO Optimize?!
|
return get_advance_var_tt (font, glyph, T::tableTag == HB_OT_TAG_vmtx);
|
||||||
else
|
|
||||||
advance = get_advance_var_tt (font, glyph, T::tableTag==HB_OT_TAG_vmtx);
|
return advance + roundf (var_table->get_advance_var (glyph, font->coords, font->num_coords)); // TODO Optimize?!
|
||||||
}
|
|
||||||
}
|
|
||||||
return advance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int num_advances_for_subset (const hb_subset_plan_t *plan) const
|
unsigned int num_advances_for_subset (const hb_subset_plan_t *plan) const
|
||||||
|
|
|
@ -167,8 +167,8 @@ struct KernOTSubTableHeader
|
||||||
static constexpr bool apple = false;
|
static constexpr bool apple = false;
|
||||||
typedef AAT::ObsoleteTypes Types;
|
typedef AAT::ObsoleteTypes Types;
|
||||||
|
|
||||||
unsigned int tuple_count () const { return 0; }
|
unsigned tuple_count () const { return 0; }
|
||||||
bool is_horizontal () const { return (coverage & Horizontal); }
|
bool is_horizontal () const { return (coverage & Horizontal); }
|
||||||
|
|
||||||
enum Coverage
|
enum Coverage
|
||||||
{
|
{
|
||||||
|
@ -222,8 +222,8 @@ struct KernAATSubTableHeader
|
||||||
static constexpr bool apple = true;
|
static constexpr bool apple = true;
|
||||||
typedef AAT::ObsoleteTypes Types;
|
typedef AAT::ObsoleteTypes Types;
|
||||||
|
|
||||||
unsigned int tuple_count () const { return 0; }
|
unsigned tuple_count () const { return 0; }
|
||||||
bool is_horizontal () const { return !(coverage & Vertical); }
|
bool is_horizontal () const { return !(coverage & Vertical); }
|
||||||
|
|
||||||
enum Coverage
|
enum Coverage
|
||||||
{
|
{
|
||||||
|
@ -275,8 +275,8 @@ struct kern
|
||||||
{
|
{
|
||||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
|
static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
|
||||||
|
|
||||||
bool has_data () const { return u.version32; }
|
bool has_data () const { return u.version32; }
|
||||||
unsigned int get_type () const { return u.major; }
|
unsigned get_type () const { return u.major; }
|
||||||
|
|
||||||
bool has_state_machine () const
|
bool has_state_machine () const
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,7 +73,7 @@ struct BaseCoordFormat2
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 2 */
|
HBUINT16 format; /* Format identifier--format = 2 */
|
||||||
FWORD coordinate; /* X or Y value, in design units */
|
FWORD coordinate; /* X or Y value, in design units */
|
||||||
GlyphID referenceGlyph; /* Glyph ID of control glyph */
|
HBGlyphID referenceGlyph; /* Glyph ID of control glyph */
|
||||||
HBUINT16 coordPoint; /* Index of contour point on the
|
HBUINT16 coordPoint; /* Index of contour point on the
|
||||||
* reference glyph */
|
* reference glyph */
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -173,8 +173,8 @@ struct RangeRecord
|
||||||
bool add_coverage (set_t *glyphs) const
|
bool add_coverage (set_t *glyphs) const
|
||||||
{ return glyphs->add_range (start, end); }
|
{ return glyphs->add_range (start, end); }
|
||||||
|
|
||||||
GlyphID start; /* First GlyphID in the range */
|
HBGlyphID start; /* First GlyphID in the range */
|
||||||
GlyphID end; /* Last GlyphID in the range */
|
HBGlyphID end; /* Last GlyphID in the range */
|
||||||
HBUINT16 value; /* Value */
|
HBUINT16 value; /* Value */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
|
@ -541,7 +541,7 @@ struct FeatureParams
|
||||||
FeatureParamsCharacterVariants characterVariants;
|
FeatureParamsCharacterVariants characterVariants;
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (17);
|
DEFINE_SIZE_MIN (0);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Feature
|
struct Feature
|
||||||
|
@ -781,7 +781,7 @@ struct Lookup
|
||||||
HBUINT16 lookupFlag; /* Lookup qualifiers */
|
HBUINT16 lookupFlag; /* Lookup qualifiers */
|
||||||
ArrayOf<Offset16>
|
ArrayOf<Offset16>
|
||||||
subTable; /* Array of SubTables */
|
subTable; /* Array of SubTables */
|
||||||
/*HBUINT16 markFilteringSetX[VAR];*//* Index (base 0) into GDEF mark glyph sets
|
/*HBUINT16 markFilteringSetX[HB_VAR_ARRAY];*//* Index (base 0) into GDEF mark glyph sets
|
||||||
* structure. This field is only present if bit
|
* structure. This field is only present if bit
|
||||||
* UseMarkFilteringSet of lookup flags is set. */
|
* UseMarkFilteringSet of lookup flags is set. */
|
||||||
public:
|
public:
|
||||||
|
@ -857,7 +857,7 @@ struct CoverageFormat1
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 coverageFormat; /* Format identifier--format = 1 */
|
HBUINT16 coverageFormat; /* Format identifier--format = 1 */
|
||||||
SortedArrayOf<GlyphID>
|
SortedArrayOf<HBGlyphID>
|
||||||
glyphArray; /* Array of GlyphIDs--in numerical order */
|
glyphArray; /* Array of GlyphIDs--in numerical order */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (4, glyphArray);
|
DEFINE_SIZE_ARRAY (4, glyphArray);
|
||||||
|
@ -1063,7 +1063,7 @@ struct Coverage
|
||||||
last = g;
|
last = g;
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
u.format = count * 2 < num_ranges * 3 ? 1 : 2;
|
u.format = count <= num_ranges * 3 ? 1 : 2;
|
||||||
|
|
||||||
switch (u.format)
|
switch (u.format)
|
||||||
{
|
{
|
||||||
|
@ -1197,7 +1197,7 @@ struct Coverage
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static inline void ClassDef_serialize (hb_serialize_context_t *c,
|
static inline void ClassDef_serialize (hb_serialize_context_t *c,
|
||||||
hb_array_t<const GlyphID> glyphs,
|
hb_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const HBUINT16> klasses);
|
hb_array_t<const HBUINT16> klasses);
|
||||||
|
|
||||||
struct ClassDefFormat1
|
struct ClassDefFormat1
|
||||||
|
@ -1211,7 +1211,7 @@ struct ClassDefFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_array_t<const GlyphID> glyphs,
|
hb_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const HBUINT16> klasses)
|
hb_array_t<const HBUINT16> klasses)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
@ -1242,7 +1242,7 @@ struct ClassDefFormat1
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
const hb_set_t &glyphset = *c->plan->glyphset ();
|
const hb_set_t &glyphset = *c->plan->glyphset ();
|
||||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||||
hb_sorted_vector_t<GlyphID> glyphs;
|
hb_sorted_vector_t<HBGlyphID> glyphs;
|
||||||
hb_vector_t<HBUINT16> klasses;
|
hb_vector_t<HBUINT16> klasses;
|
||||||
|
|
||||||
hb_codepoint_t start = startGlyph;
|
hb_codepoint_t start = startGlyph;
|
||||||
|
@ -1329,7 +1329,7 @@ struct ClassDefFormat1
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 classFormat; /* Format identifier--format = 1 */
|
HBUINT16 classFormat; /* Format identifier--format = 1 */
|
||||||
GlyphID startGlyph; /* First GlyphID of the classValueArray */
|
HBGlyphID startGlyph; /* First GlyphID of the classValueArray */
|
||||||
ArrayOf<HBUINT16>
|
ArrayOf<HBUINT16>
|
||||||
classValue; /* Array of Class Values--one per GlyphID */
|
classValue; /* Array of Class Values--one per GlyphID */
|
||||||
public:
|
public:
|
||||||
|
@ -1347,7 +1347,7 @@ struct ClassDefFormat2
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_array_t<const GlyphID> glyphs,
|
hb_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const HBUINT16> klasses)
|
hb_array_t<const HBUINT16> klasses)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
@ -1391,7 +1391,7 @@ struct ClassDefFormat2
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
const hb_set_t &glyphset = *c->plan->glyphset ();
|
const hb_set_t &glyphset = *c->plan->glyphset ();
|
||||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||||
hb_vector_t<GlyphID> glyphs;
|
hb_vector_t<HBGlyphID> glyphs;
|
||||||
hb_vector_t<HBUINT16> klasses;
|
hb_vector_t<HBUINT16> klasses;
|
||||||
|
|
||||||
unsigned int count = rangeRecord.len;
|
unsigned int count = rangeRecord.len;
|
||||||
|
@ -1507,7 +1507,7 @@ struct ClassDef
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_array_t<const GlyphID> glyphs,
|
hb_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const HBUINT16> klasses)
|
hb_array_t<const HBUINT16> klasses)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
@ -1612,7 +1612,7 @@ struct ClassDef
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void ClassDef_serialize (hb_serialize_context_t *c,
|
static inline void ClassDef_serialize (hb_serialize_context_t *c,
|
||||||
hb_array_t<const GlyphID> glyphs,
|
hb_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const HBUINT16> klasses)
|
hb_array_t<const HBUINT16> klasses)
|
||||||
{ c->start_embed<ClassDef> ()->serialize (c, glyphs, klasses); }
|
{ c->start_embed<ClassDef> ()->serialize (c, glyphs, klasses); }
|
||||||
|
|
||||||
|
@ -2218,6 +2218,8 @@ struct HintingDevice
|
||||||
hb_position_t get_y_delta (hb_font_t *font) const
|
hb_position_t get_y_delta (hb_font_t *font) const
|
||||||
{ return get_delta (font->y_ppem, font->y_scale); }
|
{ return get_delta (font->y_ppem, font->y_scale); }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{
|
{
|
||||||
unsigned int f = deltaFormat;
|
unsigned int f = deltaFormat;
|
||||||
|
@ -2231,6 +2233,12 @@ struct HintingDevice
|
||||||
return_trace (c->check_struct (this) && c->check_range (this, this->get_size ()));
|
return_trace (c->check_struct (this) && c->check_range (this, this->get_size ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HintingDevice* copy (hb_serialize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
return_trace (c->embed<HintingDevice> (this));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
int get_delta (unsigned int ppem, int scale) const
|
int get_delta (unsigned int ppem, int scale) const
|
||||||
|
@ -2292,6 +2300,12 @@ struct VariationDevice
|
||||||
hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const
|
hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store) const
|
||||||
{ return font->em_scalef_y (get_delta (font, store)); }
|
{ return font->em_scalef_y (get_delta (font, store)); }
|
||||||
|
|
||||||
|
VariationDevice* copy (hb_serialize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
return_trace (c->embed<VariationDevice> (this));
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
|
@ -2377,6 +2391,25 @@ struct Device
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Device* copy (hb_serialize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
switch (u.b.format) {
|
||||||
|
#ifndef HB_NO_HINTING
|
||||||
|
case 1:
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
return_trace (reinterpret_cast<Device *> (u.hinting.copy (c)));
|
||||||
|
#endif
|
||||||
|
#ifndef HB_NO_VAR
|
||||||
|
case 0x8000:
|
||||||
|
return_trace (reinterpret_cast<Device *> (u.variation.copy (c)));
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
return_trace (nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
DeviceHeader b;
|
DeviceHeader b;
|
||||||
|
|
|
@ -101,10 +101,10 @@ struct ValueFormat : HBUINT16
|
||||||
unsigned int get_len () const { return hb_popcount ((unsigned int) *this); }
|
unsigned int get_len () const { return hb_popcount ((unsigned int) *this); }
|
||||||
unsigned int get_size () const { return get_len () * Value::static_size; }
|
unsigned int get_size () const { return get_len () * Value::static_size; }
|
||||||
|
|
||||||
bool apply_value (hb_ot_apply_context_t *c,
|
bool apply_value (hb_ot_apply_context_t *c,
|
||||||
const void *base,
|
const void *base,
|
||||||
const Value *values,
|
const Value *values,
|
||||||
hb_glyph_position_t &glyph_pos) const
|
hb_glyph_position_t &glyph_pos) const
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false;
|
||||||
unsigned int format = *this;
|
unsigned int format = *this;
|
||||||
|
@ -258,6 +258,12 @@ struct AnchorFormat1
|
||||||
return_trace (c->check_struct (this));
|
return_trace (c->check_struct (this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnchorFormat1* copy (hb_serialize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
return_trace (c->embed<AnchorFormat1> (this));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||||
|
@ -296,6 +302,12 @@ struct AnchorFormat2
|
||||||
return_trace (c->check_struct (this));
|
return_trace (c->check_struct (this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnchorFormat2* copy (hb_serialize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
return_trace (c->embed<AnchorFormat2> (this));
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 2 */
|
HBUINT16 format; /* Format identifier--format = 2 */
|
||||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||||
|
@ -326,6 +338,17 @@ struct AnchorFormat3
|
||||||
return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
|
return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AnchorFormat3* copy (hb_serialize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
auto *out = c->embed<AnchorFormat3> (this);
|
||||||
|
if (unlikely (!out)) return_trace (nullptr);
|
||||||
|
|
||||||
|
out->xDeviceTable.serialize_copy (c, xDeviceTable, this, out);
|
||||||
|
out->yDeviceTable.serialize_copy (c, yDeviceTable, this, out);
|
||||||
|
return_trace (out);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 3 */
|
HBUINT16 format; /* Format identifier--format = 3 */
|
||||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||||
|
@ -368,6 +391,17 @@ struct Anchor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Anchor* copy (hb_serialize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return_trace (reinterpret_cast<Anchor *> (u.format1.copy (c)));
|
||||||
|
case 2: return_trace (reinterpret_cast<Anchor *> (u.format2.copy (c)));
|
||||||
|
case 3: return_trace (reinterpret_cast<Anchor *> (u.format3.copy (c)));
|
||||||
|
default:return_trace (nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
|
@ -510,11 +544,8 @@ struct SinglePosFormat1
|
||||||
if (unlikely (!c->extend_min (*this))) return;
|
if (unlikely (!c->extend_min (*this))) return;
|
||||||
if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
|
if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
|
||||||
|
|
||||||
auto vals = hb_second (*it);
|
for (const auto &_ : hb_second (*it))
|
||||||
|
c->copy (_);
|
||||||
+ vals
|
|
||||||
| hb_apply ([=] (const Value& _) { c->copy (_); })
|
|
||||||
;
|
|
||||||
|
|
||||||
auto glyphs =
|
auto glyphs =
|
||||||
+ it
|
+ it
|
||||||
|
@ -530,15 +561,11 @@ struct SinglePosFormat1
|
||||||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||||
|
|
||||||
unsigned length = valueFormat.get_len ();
|
|
||||||
|
|
||||||
auto it =
|
auto it =
|
||||||
+ hb_iter (this+coverage)
|
+ hb_iter (this+coverage)
|
||||||
| hb_filter (glyphset)
|
| hb_filter (glyphset)
|
||||||
| hb_map_retains_sorting ([&] (hb_codepoint_t p)
|
| hb_map_retains_sorting (glyph_map)
|
||||||
{
|
| hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
|
||||||
return hb_pair (glyph_map[p], values.as_array (length));
|
|
||||||
})
|
|
||||||
;
|
;
|
||||||
|
|
||||||
bool ret = bool (it);
|
bool ret = bool (it);
|
||||||
|
@ -605,15 +632,9 @@ struct SinglePosFormat2
|
||||||
if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
|
if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
|
||||||
if (unlikely (!c->check_assign (valueCount, it.len ()))) return;
|
if (unlikely (!c->check_assign (valueCount, it.len ()))) return;
|
||||||
|
|
||||||
+ it
|
for (const auto iter : it)
|
||||||
| hb_map (hb_second)
|
for (const auto &_ : iter.second)
|
||||||
| hb_apply ([=] (hb_array_t<const Value> val_iter)
|
c->copy (_);
|
||||||
{
|
|
||||||
+ val_iter
|
|
||||||
| hb_apply ([=] (const Value& _) { c->copy (_); })
|
|
||||||
;
|
|
||||||
})
|
|
||||||
;
|
|
||||||
|
|
||||||
auto glyphs =
|
auto glyphs =
|
||||||
+ it
|
+ it
|
||||||
|
@ -630,14 +651,16 @@ struct SinglePosFormat2
|
||||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||||
|
|
||||||
unsigned sub_length = valueFormat.get_len ();
|
unsigned sub_length = valueFormat.get_len ();
|
||||||
unsigned total_length = (unsigned)valueCount * sub_length;
|
auto values_array = values.as_array (valueCount * sub_length);
|
||||||
|
|
||||||
auto it =
|
auto it =
|
||||||
+ hb_zip (this+coverage, hb_range ((unsigned) valueCount))
|
+ hb_zip (this+coverage, hb_range ((unsigned) valueCount))
|
||||||
| hb_filter (glyphset, hb_first)
|
| hb_filter (glyphset, hb_first)
|
||||||
| hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _)
|
| hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _)
|
||||||
{
|
{
|
||||||
return hb_pair (glyph_map[_.first], values.as_array (total_length).sub_array (_.second * sub_length, sub_length));
|
return hb_pair (glyph_map[_.first],
|
||||||
|
values_array.sub_array (_.second * sub_length,
|
||||||
|
sub_length));
|
||||||
})
|
})
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -674,27 +697,14 @@ struct SinglePos
|
||||||
hb_requires (hb_is_iterator (Iterator))>
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
unsigned get_format (Iterator glyph_val_iter_pairs)
|
unsigned get_format (Iterator glyph_val_iter_pairs)
|
||||||
{
|
{
|
||||||
unsigned subset_format = 1;
|
|
||||||
hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs);
|
hb_array_t<const Value> first_val_iter = hb_second (*glyph_val_iter_pairs);
|
||||||
|
|
||||||
+ glyph_val_iter_pairs
|
for (const auto iter : glyph_val_iter_pairs)
|
||||||
| hb_map (hb_second)
|
for (const auto _ : hb_zip (iter.second, first_val_iter))
|
||||||
| hb_apply ([&] (hb_array_t<const Value> val_iter)
|
if (_.first != _.second)
|
||||||
{
|
return 2;
|
||||||
+ hb_zip (val_iter, first_val_iter)
|
|
||||||
| hb_apply ([&] (const hb_pair_t<Value, Value>& _)
|
|
||||||
{
|
|
||||||
if (_.first != _.second)
|
|
||||||
{
|
|
||||||
subset_format = 2;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
})
|
|
||||||
;
|
|
||||||
})
|
|
||||||
;
|
|
||||||
|
|
||||||
return subset_format;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -752,7 +762,7 @@ struct PairValueRecord
|
||||||
friend struct PairSet;
|
friend struct PairSet;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlyphID secondGlyph; /* GlyphID of second glyph in the
|
HBGlyphID secondGlyph; /* GlyphID of second glyph in the
|
||||||
* pair--first glyph is listed in the
|
* pair--first glyph is listed in the
|
||||||
* Coverage table */
|
* Coverage table */
|
||||||
ValueRecord values; /* Positioning data for the first glyph
|
ValueRecord values; /* Positioning data for the first glyph
|
||||||
|
@ -1088,6 +1098,19 @@ struct EntryExitRecord
|
||||||
return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
|
return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EntryExitRecord* copy (hb_serialize_context_t *c,
|
||||||
|
const void *src_base,
|
||||||
|
const void *dst_base) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
auto *out = c->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (nullptr);
|
||||||
|
|
||||||
|
out->entryAnchor.serialize_copy (c, entryAnchor, src_base, dst_base);
|
||||||
|
out->exitAnchor.serialize_copy (c, exitAnchor, src_base, dst_base);
|
||||||
|
return_trace (out);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
OffsetTo<Anchor>
|
OffsetTo<Anchor>
|
||||||
entryAnchor; /* Offset to EntryAnchor table--from
|
entryAnchor; /* Offset to EntryAnchor table--from
|
||||||
|
@ -1215,11 +1238,47 @@ struct CursivePosFormat1
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Iterator,
|
||||||
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
|
void serialize (hb_serialize_context_t *c,
|
||||||
|
Iterator it,
|
||||||
|
const void *src_base)
|
||||||
|
{
|
||||||
|
if (unlikely (!c->extend_min ((*this)))) return;
|
||||||
|
this->format = 1;
|
||||||
|
this->entryExitRecord.len = it.len ();
|
||||||
|
|
||||||
|
for (const EntryExitRecord& entry_record : + it
|
||||||
|
| hb_map (hb_second))
|
||||||
|
c->copy (entry_record, src_base, this);
|
||||||
|
|
||||||
|
auto glyphs =
|
||||||
|
+ it
|
||||||
|
| hb_map_retains_sorting (hb_first)
|
||||||
|
;
|
||||||
|
|
||||||
|
coverage.serialize (c, this).serialize (c, glyphs);
|
||||||
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
// TODO(subset)
|
const hb_set_t &glyphset = *c->plan->glyphset ();
|
||||||
return_trace (false);
|
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||||
|
|
||||||
|
auto *out = c->serializer->start_embed (*this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
auto it =
|
||||||
|
+ hb_zip (this+coverage, entryExitRecord)
|
||||||
|
| hb_filter (glyphset, hb_first)
|
||||||
|
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const EntryExitRecord&> p) -> hb_pair_t<hb_codepoint_t, const EntryExitRecord&>
|
||||||
|
{ return hb_pair (glyph_map[p.first], p.second);})
|
||||||
|
;
|
||||||
|
|
||||||
|
bool ret = bool (it);
|
||||||
|
out->serialize (c->serializer, it, this);
|
||||||
|
return_trace (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
|
|
@ -111,8 +111,11 @@ struct SingleSubstFormat1
|
||||||
+ hb_iter (this+coverage)
|
+ hb_iter (this+coverage)
|
||||||
| hb_filter (glyphset)
|
| hb_filter (glyphset)
|
||||||
| hb_map_retains_sorting ([&] (hb_codepoint_t g) {
|
| hb_map_retains_sorting ([&] (hb_codepoint_t g) {
|
||||||
return hb_codepoint_pair_t (glyph_map[g],
|
return hb_codepoint_pair_t (g,
|
||||||
glyph_map[(g + delta) & 0xFFFF]); })
|
(g + delta) & 0xFFFF); })
|
||||||
|
| hb_filter (glyphset, hb_second)
|
||||||
|
| hb_map_retains_sorting ([&] (hb_codepoint_pair_t p) -> hb_codepoint_pair_t
|
||||||
|
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
|
||||||
;
|
;
|
||||||
|
|
||||||
bool ret = bool (it);
|
bool ret = bool (it);
|
||||||
|
@ -208,7 +211,8 @@ struct SingleSubstFormat2
|
||||||
auto it =
|
auto it =
|
||||||
+ hb_zip (this+coverage, substitute)
|
+ hb_zip (this+coverage, substitute)
|
||||||
| hb_filter (glyphset, hb_first)
|
| hb_filter (glyphset, hb_first)
|
||||||
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const GlyphID &> p) -> hb_codepoint_pair_t
|
| hb_filter (glyphset, hb_second)
|
||||||
|
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID &> p) -> hb_codepoint_pair_t
|
||||||
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
|
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -228,7 +232,7 @@ struct SingleSubstFormat2
|
||||||
OffsetTo<Coverage>
|
OffsetTo<Coverage>
|
||||||
coverage; /* Offset to Coverage table--from
|
coverage; /* Offset to Coverage table--from
|
||||||
* beginning of Substitution table */
|
* beginning of Substitution table */
|
||||||
ArrayOf<GlyphID>
|
ArrayOf<HBGlyphID>
|
||||||
substitute; /* Array of substitute
|
substitute; /* Array of substitute
|
||||||
* GlyphIDs--ordered by Coverage Index */
|
* GlyphIDs--ordered by Coverage Index */
|
||||||
public:
|
public:
|
||||||
|
@ -370,7 +374,7 @@ struct Sequence
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ArrayOf<GlyphID>
|
ArrayOf<HBGlyphID>
|
||||||
substitute; /* String of GlyphIDs to substitute */
|
substitute; /* String of GlyphIDs to substitute */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (2, substitute);
|
DEFINE_SIZE_ARRAY (2, substitute);
|
||||||
|
@ -417,9 +421,9 @@ struct MultipleSubstFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const GlyphID> glyphs,
|
hb_sorted_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const unsigned int> substitute_len_list,
|
hb_array_t<const unsigned int> substitute_len_list,
|
||||||
hb_array_t<const GlyphID> substitute_glyphs_list)
|
hb_array_t<const HBGlyphID> substitute_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||||
|
@ -492,9 +496,9 @@ struct MultipleSubstFormat1
|
||||||
struct MultipleSubst
|
struct MultipleSubst
|
||||||
{
|
{
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const GlyphID> glyphs,
|
hb_sorted_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const unsigned int> substitute_len_list,
|
hb_array_t<const unsigned int> substitute_len_list,
|
||||||
hb_array_t<const GlyphID> substitute_glyphs_list)
|
hb_array_t<const HBGlyphID> substitute_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
||||||
|
@ -593,7 +597,7 @@ struct AlternateSet
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ArrayOf<GlyphID>
|
ArrayOf<HBGlyphID>
|
||||||
alternates; /* Array of alternate GlyphIDs--in
|
alternates; /* Array of alternate GlyphIDs--in
|
||||||
* arbitrary order */
|
* arbitrary order */
|
||||||
public:
|
public:
|
||||||
|
@ -640,9 +644,9 @@ struct AlternateSubstFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const GlyphID> glyphs,
|
hb_sorted_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const unsigned int> alternate_len_list,
|
hb_array_t<const unsigned int> alternate_len_list,
|
||||||
hb_array_t<const GlyphID> alternate_glyphs_list)
|
hb_array_t<const HBGlyphID> alternate_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||||
|
@ -715,9 +719,9 @@ struct AlternateSubstFormat1
|
||||||
struct AlternateSubst
|
struct AlternateSubst
|
||||||
{
|
{
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const GlyphID> glyphs,
|
hb_sorted_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const unsigned int> alternate_len_list,
|
hb_array_t<const unsigned int> alternate_len_list,
|
||||||
hb_array_t<const GlyphID> alternate_glyphs_list)
|
hb_array_t<const HBGlyphID> alternate_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
||||||
|
@ -856,8 +860,8 @@ struct Ligature
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlyphID ligGlyph; /* GlyphID of ligature to substitute */
|
HBGlyphID ligGlyph; /* GlyphID of ligature to substitute */
|
||||||
HeadlessArrayOf<GlyphID>
|
HeadlessArrayOf<HBGlyphID>
|
||||||
component; /* Array of component GlyphIDs--start
|
component; /* Array of component GlyphIDs--start
|
||||||
* with the second component--ordered
|
* with the second component--ordered
|
||||||
* in writing direction */
|
* in writing direction */
|
||||||
|
@ -917,9 +921,9 @@ struct LigatureSet
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_array_t<const GlyphID> ligatures,
|
hb_array_t<const HBGlyphID> ligatures,
|
||||||
hb_array_t<const unsigned int> component_count_list,
|
hb_array_t<const unsigned int> component_count_list,
|
||||||
hb_array_t<const GlyphID> &component_list /* Starting from second for each ligature */)
|
hb_array_t<const HBGlyphID> &component_list /* Starting from second for each ligature */)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||||
|
@ -1034,11 +1038,11 @@ struct LigatureSubstFormat1
|
||||||
}
|
}
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const GlyphID> first_glyphs,
|
hb_sorted_array_t<const HBGlyphID> first_glyphs,
|
||||||
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
||||||
hb_array_t<const GlyphID> ligatures_list,
|
hb_array_t<const HBGlyphID> ligatures_list,
|
||||||
hb_array_t<const unsigned int> component_count_list,
|
hb_array_t<const unsigned int> component_count_list,
|
||||||
hb_array_t<const GlyphID> component_list /* Starting from second for each ligature */)
|
hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||||
|
@ -1114,11 +1118,11 @@ struct LigatureSubstFormat1
|
||||||
struct LigatureSubst
|
struct LigatureSubst
|
||||||
{
|
{
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const GlyphID> first_glyphs,
|
hb_sorted_array_t<const HBGlyphID> first_glyphs,
|
||||||
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
||||||
hb_array_t<const GlyphID> ligatures_list,
|
hb_array_t<const HBGlyphID> ligatures_list,
|
||||||
hb_array_t<const unsigned int> component_count_list,
|
hb_array_t<const unsigned int> component_count_list,
|
||||||
hb_array_t<const GlyphID> component_list /* Starting from second for each ligature */)
|
hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
||||||
|
@ -1195,7 +1199,7 @@ struct ReverseChainSingleSubstFormat1
|
||||||
if (!intersects (c->glyphs)) return;
|
if (!intersects (c->glyphs)) return;
|
||||||
|
|
||||||
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
||||||
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
|
const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
|
||||||
|
|
||||||
+ hb_zip (this+coverage, substitute)
|
+ hb_zip (this+coverage, substitute)
|
||||||
| hb_filter (*c->glyphs, hb_first)
|
| hb_filter (*c->glyphs, hb_first)
|
||||||
|
@ -1219,7 +1223,7 @@ struct ReverseChainSingleSubstFormat1
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
|
if (unlikely (!(this+lookahead[i]).add_coverage (c->after))) return;
|
||||||
|
|
||||||
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
|
const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
|
||||||
count = substitute.len;
|
count = substitute.len;
|
||||||
c->output->add_array (substitute.arrayZ, substitute.len);
|
c->output->add_array (substitute.arrayZ, substitute.len);
|
||||||
}
|
}
|
||||||
|
@ -1239,7 +1243,7 @@ struct ReverseChainSingleSubstFormat1
|
||||||
if (likely (index == NOT_COVERED)) return_trace (false);
|
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||||
|
|
||||||
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
||||||
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
|
const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
|
||||||
|
|
||||||
unsigned int start_index = 0, end_index = 0;
|
unsigned int start_index = 0, end_index = 0;
|
||||||
if (match_backtrack (c,
|
if (match_backtrack (c,
|
||||||
|
@ -1277,7 +1281,7 @@ struct ReverseChainSingleSubstFormat1
|
||||||
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
||||||
if (!lookahead.sanitize (c, this))
|
if (!lookahead.sanitize (c, this))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
|
const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
|
||||||
return_trace (substitute.sanitize (c));
|
return_trace (substitute.sanitize (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1294,7 +1298,7 @@ struct ReverseChainSingleSubstFormat1
|
||||||
lookaheadX; /* Array of coverage tables
|
lookaheadX; /* Array of coverage tables
|
||||||
* in lookahead sequence, in glyph
|
* in lookahead sequence, in glyph
|
||||||
* sequence order */
|
* sequence order */
|
||||||
ArrayOf<GlyphID>
|
ArrayOf<HBGlyphID>
|
||||||
substituteX; /* Array of substitute
|
substituteX; /* Array of substitute
|
||||||
* GlyphIDs--ordered by Coverage Index */
|
* GlyphIDs--ordered by Coverage Index */
|
||||||
public:
|
public:
|
||||||
|
@ -1449,8 +1453,8 @@ struct SubstLookup : Lookup
|
||||||
|
|
||||||
bool serialize_single (hb_serialize_context_t *c,
|
bool serialize_single (hb_serialize_context_t *c,
|
||||||
uint32_t lookup_props,
|
uint32_t lookup_props,
|
||||||
hb_sorted_array_t<const GlyphID> glyphs,
|
hb_sorted_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const GlyphID> substitutes)
|
hb_array_t<const HBGlyphID> substitutes)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
|
if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
|
||||||
|
@ -1460,9 +1464,9 @@ struct SubstLookup : Lookup
|
||||||
|
|
||||||
bool serialize_multiple (hb_serialize_context_t *c,
|
bool serialize_multiple (hb_serialize_context_t *c,
|
||||||
uint32_t lookup_props,
|
uint32_t lookup_props,
|
||||||
hb_sorted_array_t<const GlyphID> glyphs,
|
hb_sorted_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const unsigned int> substitute_len_list,
|
hb_array_t<const unsigned int> substitute_len_list,
|
||||||
hb_array_t<const GlyphID> substitute_glyphs_list)
|
hb_array_t<const HBGlyphID> substitute_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false);
|
if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false);
|
||||||
|
@ -1475,9 +1479,9 @@ struct SubstLookup : Lookup
|
||||||
|
|
||||||
bool serialize_alternate (hb_serialize_context_t *c,
|
bool serialize_alternate (hb_serialize_context_t *c,
|
||||||
uint32_t lookup_props,
|
uint32_t lookup_props,
|
||||||
hb_sorted_array_t<const GlyphID> glyphs,
|
hb_sorted_array_t<const HBGlyphID> glyphs,
|
||||||
hb_array_t<const unsigned int> alternate_len_list,
|
hb_array_t<const unsigned int> alternate_len_list,
|
||||||
hb_array_t<const GlyphID> alternate_glyphs_list)
|
hb_array_t<const HBGlyphID> alternate_glyphs_list)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false);
|
if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false);
|
||||||
|
@ -1490,11 +1494,11 @@ struct SubstLookup : Lookup
|
||||||
|
|
||||||
bool serialize_ligature (hb_serialize_context_t *c,
|
bool serialize_ligature (hb_serialize_context_t *c,
|
||||||
uint32_t lookup_props,
|
uint32_t lookup_props,
|
||||||
hb_sorted_array_t<const GlyphID> first_glyphs,
|
hb_sorted_array_t<const HBGlyphID> first_glyphs,
|
||||||
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
||||||
hb_array_t<const GlyphID> ligatures_list,
|
hb_array_t<const HBGlyphID> ligatures_list,
|
||||||
hb_array_t<const unsigned int> component_count_list,
|
hb_array_t<const unsigned int> component_count_list,
|
||||||
hb_array_t<const GlyphID> component_list /* Starting from second for each ligature */)
|
hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
|
if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
|
||||||
|
|
|
@ -136,7 +136,7 @@ struct JstfLangSys : OffsetListOf<JstfPriority>
|
||||||
* ExtenderGlyphs -- Extender Glyph Table
|
* ExtenderGlyphs -- Extender Glyph Table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
|
typedef SortedArrayOf<HBGlyphID> ExtenderGlyphs;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1227,7 +1227,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
|
||||||
* @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
|
* @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
|
||||||
*
|
*
|
||||||
* Fetches a list of all glyphs affected by the specified lookup in the
|
* Fetches a list of all glyphs affected by the specified lookup in the
|
||||||
* specified face's GSUB table of GPOS table.
|
* specified face's GSUB table or GPOS table.
|
||||||
*
|
*
|
||||||
* Since: 0.9.7
|
* Since: 0.9.7
|
||||||
**/
|
**/
|
||||||
|
@ -1949,7 +1949,7 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
||||||
/**
|
/**
|
||||||
* hb_ot_layout_get_baseline:
|
* hb_ot_layout_get_baseline:
|
||||||
* @font: a font
|
* @font: a font
|
||||||
* @baseline: a baseline tag
|
* @baseline_tag: a baseline tag
|
||||||
* @direction: text direction.
|
* @direction: text direction.
|
||||||
* @script_tag: script tag.
|
* @script_tag: script tag.
|
||||||
* @language_tag: language tag.
|
* @language_tag: language tag.
|
||||||
|
|
|
@ -191,7 +191,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
||||||
feature_infos[j].max_value = feature_infos[i].max_value;
|
feature_infos[j].max_value = feature_infos[i].max_value;
|
||||||
feature_infos[j].default_value = feature_infos[i].default_value;
|
feature_infos[j].default_value = feature_infos[i].default_value;
|
||||||
} else {
|
} else {
|
||||||
feature_infos[j].flags &= ~F_GLOBAL;
|
if (feature_infos[j].flags & F_GLOBAL)
|
||||||
|
feature_infos[j].flags ^= F_GLOBAL;
|
||||||
feature_infos[j].max_value = hb_max (feature_infos[j].max_value, feature_infos[i].max_value);
|
feature_infos[j].max_value = hb_max (feature_infos[j].max_value, feature_infos[i].max_value);
|
||||||
/* Inherit default_value from j */
|
/* Inherit default_value from j */
|
||||||
}
|
}
|
||||||
|
|
|
@ -423,7 +423,7 @@ struct MathGlyphVariantRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlyphID variantGlyph; /* Glyph ID for the variant. */
|
HBGlyphID variantGlyph; /* Glyph ID for the variant. */
|
||||||
HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the
|
HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the
|
||||||
* variant, in the direction of requested
|
* variant, in the direction of requested
|
||||||
* glyph extension. */
|
* glyph extension. */
|
||||||
|
@ -471,7 +471,7 @@ struct MathGlyphPartRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
GlyphID glyph; /* Glyph ID for the part. */
|
HBGlyphID glyph; /* Glyph ID for the part. */
|
||||||
HBUINT16 startConnectorLength; /* Advance width/ height of the straight bar
|
HBUINT16 startConnectorLength; /* Advance width/ height of the straight bar
|
||||||
* connector material, in design units, is at
|
* connector material, in design units, is at
|
||||||
* the beginning of the glyph, in the
|
* the beginning of the glyph, in the
|
||||||
|
|
|
@ -129,7 +129,7 @@ struct maxp
|
||||||
FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0),
|
FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0),
|
||||||
* 0x00005000u or 0x00010000u. */
|
* 0x00005000u or 0x00010000u. */
|
||||||
HBUINT16 numGlyphs; /* The number of glyphs in the font. */
|
HBUINT16 numGlyphs; /* The number of glyphs in the font. */
|
||||||
/*maxpV1Tail v1Tail[VAR]; */
|
/*maxpV1Tail v1Tail[HB_VAR_ARRAY]; */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
};
|
};
|
||||||
|
|
|
@ -191,9 +191,7 @@ struct name
|
||||||
|
|
||||||
const void *dst_string_pool = &(this + this->stringOffset);
|
const void *dst_string_pool = &(this + this->stringOffset);
|
||||||
|
|
||||||
+ it
|
for (const auto &_ : it) c->copy (_, src_string_pool, dst_string_pool);
|
||||||
| hb_apply ([=] (const NameRecord& _) { c->copy (_, src_string_pool, dst_string_pool); })
|
|
||||||
;
|
|
||||||
|
|
||||||
if (unlikely (c->ran_out_of_room)) return_trace (false);
|
if (unlikely (c->ran_out_of_room)) return_trace (false);
|
||||||
|
|
||||||
|
@ -330,6 +328,9 @@ struct name
|
||||||
DEFINE_SIZE_ARRAY (6, nameRecordZ);
|
DEFINE_SIZE_ARRAY (6, nameRecordZ);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef entry_index
|
||||||
|
#undef entry_score
|
||||||
|
|
||||||
struct name_accelerator_t : name::accelerator_t {};
|
struct name_accelerator_t : name::accelerator_t {};
|
||||||
|
|
||||||
} /* namespace OT */
|
} /* namespace OT */
|
||||||
|
|
|
@ -134,8 +134,8 @@ struct OS2
|
||||||
OBLIQUE = 1u<<9
|
OBLIQUE = 1u<<9
|
||||||
};
|
};
|
||||||
|
|
||||||
bool is_italic () const { return fsSelection & ITALIC; }
|
bool is_italic () const { return fsSelection & ITALIC; }
|
||||||
bool is_oblique () const { return fsSelection & OBLIQUE; }
|
bool is_oblique () const { return fsSelection & OBLIQUE; }
|
||||||
bool use_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
|
bool use_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
|
||||||
|
|
||||||
enum width_class_t {
|
enum width_class_t {
|
||||||
|
|
|
@ -262,7 +262,7 @@ struct post
|
||||||
* 0x00020000 for version 2.0
|
* 0x00020000 for version 2.0
|
||||||
* 0x00025000 for version 2.5 (deprecated)
|
* 0x00025000 for version 2.5 (deprecated)
|
||||||
* 0x00030000 for version 3.0 */
|
* 0x00030000 for version 3.0 */
|
||||||
Fixed italicAngle; /* Italic angle in counter-clockwise degrees
|
HBFixed italicAngle; /* Italic angle in counter-clockwise degrees
|
||||||
* from the vertical. Zero for upright text,
|
* from the vertical. Zero for upright text,
|
||||||
* negative for text that leans to the right
|
* negative for text that leans to the right
|
||||||
* (forward). */
|
* (forward). */
|
||||||
|
|
|
@ -49,8 +49,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
|
||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
unsigned int feature_index)
|
unsigned int feature_index)
|
||||||
{
|
{
|
||||||
OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
OT::HBGlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||||
OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
OT::HBGlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||||
unsigned int num_glyphs = 0;
|
unsigned int num_glyphs = 0;
|
||||||
|
|
||||||
/* Populate arrays */
|
/* Populate arrays */
|
||||||
|
@ -78,7 +78,7 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
|
||||||
/* Bubble-sort or something equally good!
|
/* Bubble-sort or something equally good!
|
||||||
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
||||||
hb_stable_sort (&glyphs[0], num_glyphs,
|
hb_stable_sort (&glyphs[0], num_glyphs,
|
||||||
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::GlyphID::cmp,
|
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp,
|
||||||
&substitutes[0]);
|
&substitutes[0]);
|
||||||
|
|
||||||
|
|
||||||
|
@ -99,15 +99,15 @@ static OT::SubstLookup *
|
||||||
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||||
hb_font_t *font)
|
hb_font_t *font)
|
||||||
{
|
{
|
||||||
OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
|
OT::HBGlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
|
||||||
unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
|
unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
|
||||||
unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
|
unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
|
||||||
unsigned int num_first_glyphs = 0;
|
unsigned int num_first_glyphs = 0;
|
||||||
|
|
||||||
/* We know that all our ligatures are 2-component */
|
/* We know that all our ligatures are 2-component */
|
||||||
OT::GlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
|
OT::HBGlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
|
||||||
unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
|
unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
|
||||||
OT::GlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
|
OT::HBGlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
|
||||||
unsigned int num_ligatures = 0;
|
unsigned int num_ligatures = 0;
|
||||||
|
|
||||||
/* Populate arrays */
|
/* Populate arrays */
|
||||||
|
@ -125,7 +125,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
|
||||||
num_first_glyphs++;
|
num_first_glyphs++;
|
||||||
}
|
}
|
||||||
hb_stable_sort (&first_glyphs[0], num_first_glyphs,
|
hb_stable_sort (&first_glyphs[0], num_first_glyphs,
|
||||||
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::GlyphID::cmp,
|
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp,
|
||||||
&first_glyphs_indirection[0]);
|
&first_glyphs_indirection[0]);
|
||||||
|
|
||||||
/* Now that the first-glyphs are sorted, walk again, populate ligatures. */
|
/* Now that the first-glyphs are sorted, walk again, populate ligatures. */
|
||||||
|
@ -230,8 +230,8 @@ arabic_fallback_plan_init_win1256 (arabic_fallback_plan_t *fallback_plan HB_UNUS
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
|
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
|
||||||
static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
|
static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) ==
|
||||||
<= ARABIC_FALLBACK_MAX_LOOKUPS, "");
|
ARABIC_FALLBACK_MAX_LOOKUPS * sizeof (ManifestLookup), "");
|
||||||
/* TODO sanitize the table? */
|
/* TODO sanitize the table? */
|
||||||
|
|
||||||
unsigned j = 0;
|
unsigned j = 0;
|
||||||
|
|
|
@ -116,8 +116,8 @@ enum myanmar_syllable_type_t {
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
hb_font_t *font HB_UNUSED)
|
hb_font_t *font HB_UNUSED)
|
||||||
{
|
{
|
||||||
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
|
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
|
||||||
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
|
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
|
||||||
|
|
|
@ -77,7 +77,7 @@ struct AxisValueFormat1
|
||||||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||||
* that provide a display string for this
|
* that provide a display string for this
|
||||||
* attribute value. */
|
* attribute value. */
|
||||||
Fixed value; /* A numeric value for this attribute value. */
|
HBFixed value; /* A numeric value for this attribute value. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (12);
|
DEFINE_SIZE_STATIC (12);
|
||||||
};
|
};
|
||||||
|
@ -102,10 +102,10 @@ struct AxisValueFormat2
|
||||||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||||
* that provide a display string for this
|
* that provide a display string for this
|
||||||
* attribute value. */
|
* attribute value. */
|
||||||
Fixed nominalValue; /* A numeric value for this attribute value. */
|
HBFixed nominalValue; /* A numeric value for this attribute value. */
|
||||||
Fixed rangeMinValue; /* The minimum value for a range associated
|
HBFixed rangeMinValue; /* The minimum value for a range associated
|
||||||
* with the specified name ID. */
|
* with the specified name ID. */
|
||||||
Fixed rangeMaxValue; /* The maximum value for a range associated
|
HBFixed rangeMaxValue; /* The maximum value for a range associated
|
||||||
* with the specified name ID. */
|
* with the specified name ID. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (20);
|
DEFINE_SIZE_STATIC (20);
|
||||||
|
@ -131,8 +131,8 @@ struct AxisValueFormat3
|
||||||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||||
* that provide a display string for this
|
* that provide a display string for this
|
||||||
* attribute value. */
|
* attribute value. */
|
||||||
Fixed value; /* A numeric value for this attribute value. */
|
HBFixed value; /* A numeric value for this attribute value. */
|
||||||
Fixed linkedValue; /* The numeric value for a style-linked mapping
|
HBFixed linkedValue; /* The numeric value for a style-linked mapping
|
||||||
* from this value. */
|
* from this value. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (16);
|
DEFINE_SIZE_STATIC (16);
|
||||||
|
@ -150,7 +150,7 @@ struct AxisValueRecord
|
||||||
HBUINT16 axisIndex; /* Zero-base index into the axis record array
|
HBUINT16 axisIndex; /* Zero-base index into the axis record array
|
||||||
* identifying the axis to which this value
|
* identifying the axis to which this value
|
||||||
* applies. Must be less than designAxisCount. */
|
* applies. Must be less than designAxisCount. */
|
||||||
Fixed value; /* A numeric value for this attribute value. */
|
HBFixed value; /* A numeric value for this attribute value. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
};
|
};
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct InstanceRecord
|
||||||
{
|
{
|
||||||
friend struct fvar;
|
friend struct fvar;
|
||||||
|
|
||||||
hb_array_t<const Fixed> get_coordinates (unsigned int axis_count) const
|
hb_array_t<const HBFixed> get_coordinates (unsigned int axis_count) const
|
||||||
{ return coordinatesZ.as_array (axis_count); }
|
{ return coordinatesZ.as_array (axis_count); }
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
|
bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
|
||||||
|
@ -58,7 +58,7 @@ struct InstanceRecord
|
||||||
NameID subfamilyNameID;/* The name ID for entries in the 'name' table
|
NameID subfamilyNameID;/* The name ID for entries in the 'name' table
|
||||||
* that provide subfamily names for this instance. */
|
* that provide subfamily names for this instance. */
|
||||||
HBUINT16 flags; /* Reserved for future use — set to 0. */
|
HBUINT16 flags; /* Reserved for future use — set to 0. */
|
||||||
UnsizedArrayOf<Fixed>
|
UnsizedArrayOf<HBFixed>
|
||||||
coordinatesZ; /* The coordinates array for this instance. */
|
coordinatesZ; /* The coordinates array for this instance. */
|
||||||
//NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
|
//NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
|
||||||
// * table that provide PostScript names for this
|
// * table that provide PostScript names for this
|
||||||
|
@ -83,9 +83,9 @@ struct AxisRecord
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Tag axisTag; /* Tag identifying the design variation for the axis. */
|
Tag axisTag; /* Tag identifying the design variation for the axis. */
|
||||||
Fixed minValue; /* The minimum coordinate value for the axis. */
|
HBFixed minValue; /* The minimum coordinate value for the axis. */
|
||||||
Fixed defaultValue; /* The default coordinate value for the axis. */
|
HBFixed defaultValue; /* The default coordinate value for the axis. */
|
||||||
Fixed maxValue; /* The maximum coordinate value for the axis. */
|
HBFixed maxValue; /* The maximum coordinate value for the axis. */
|
||||||
HBUINT16 flags; /* Axis flags. */
|
HBUINT16 flags; /* Axis flags. */
|
||||||
NameID axisNameID; /* The name ID for entries in the 'name' table that
|
NameID axisNameID; /* The name ID for entries in the 'name' table that
|
||||||
* provide a display name for this axis. */
|
* provide a display name for this axis. */
|
||||||
|
@ -286,7 +286,7 @@ struct fvar
|
||||||
|
|
||||||
if (coords_length && *coords_length)
|
if (coords_length && *coords_length)
|
||||||
{
|
{
|
||||||
hb_array_t<const Fixed> instanceCoords = instance->get_coordinates (axisCount)
|
hb_array_t<const HBFixed> instanceCoords = instance->get_coordinates (axisCount)
|
||||||
.sub_array (0, *coords_length);
|
.sub_array (0, *coords_length);
|
||||||
for (unsigned int i = 0; i < instanceCoords.length; i++)
|
for (unsigned int i = 0; i < instanceCoords.length; i++)
|
||||||
coords[i] = instanceCoords.arrayZ[i].to_float ();
|
coords[i] = instanceCoords.arrayZ[i].to_float ();
|
||||||
|
@ -340,8 +340,8 @@ struct fvar
|
||||||
HBUINT16 instanceCount; /* The number of named instances defined in the font
|
HBUINT16 instanceCount; /* The number of named instances defined in the font
|
||||||
* (the number of records in the instances array). */
|
* (the number of records in the instances array). */
|
||||||
HBUINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
|
HBUINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
|
||||||
* to either axisCount * sizeof(Fixed) + 4, or to
|
* to either axisCount * sizeof(HBFixed) + 4, or to
|
||||||
* axisCount * sizeof(Fixed) + 6. */
|
* axisCount * sizeof(HBFixed) + 6. */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (16);
|
DEFINE_SIZE_STATIC (16);
|
||||||
|
|
|
@ -48,7 +48,7 @@ struct VertOriginMetric
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GlyphID glyph;
|
HBGlyphID glyph;
|
||||||
FWORD vertOriginY;
|
FWORD vertOriginY;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -84,9 +84,7 @@ struct VORG
|
||||||
this->defaultVertOriginY = defaultVertOriginY;
|
this->defaultVertOriginY = defaultVertOriginY;
|
||||||
this->vertYOrigins.len = it.len ();
|
this->vertYOrigins.len = it.len ();
|
||||||
|
|
||||||
+ it
|
for (const auto _ : it) c->copy (_);
|
||||||
| hb_apply ([c] (const VertOriginMetric& _) { c->copy (_); })
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
|
|
@ -91,9 +91,7 @@ struct hb_serialize_context_t
|
||||||
|
|
||||||
void fini ()
|
void fini ()
|
||||||
{
|
{
|
||||||
++ hb_iter (packed)
|
for (object_t *_ : ++hb_iter (packed)) _->fini ();
|
||||||
| hb_apply ([] (object_t *_) { _->fini (); })
|
|
||||||
;
|
|
||||||
packed.fini ();
|
packed.fini ();
|
||||||
this->packed_map.fini ();
|
this->packed_map.fini ();
|
||||||
|
|
||||||
|
@ -194,6 +192,7 @@ struct hb_serialize_context_t
|
||||||
if (unlikely (!obj)) return;
|
if (unlikely (!obj)) return;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
revert (*obj);
|
revert (*obj);
|
||||||
|
obj->fini ();
|
||||||
object_pool.free (obj);
|
object_pool.free (obj);
|
||||||
}
|
}
|
||||||
objidx_t pop_pack ()
|
objidx_t pop_pack ()
|
||||||
|
@ -291,7 +290,6 @@ struct hb_serialize_context_t
|
||||||
assert (packed.length > 1);
|
assert (packed.length > 1);
|
||||||
|
|
||||||
for (const object_t* parent : ++hb_iter (packed))
|
for (const object_t* parent : ++hb_iter (packed))
|
||||||
{
|
|
||||||
for (const object_t::link_t &link : parent->links)
|
for (const object_t::link_t &link : parent->links)
|
||||||
{
|
{
|
||||||
const object_t* child = packed[link.objidx];
|
const object_t* child = packed[link.objidx];
|
||||||
|
@ -311,7 +309,6 @@ struct hb_serialize_context_t
|
||||||
check_assign (off, offset);
|
check_assign (off, offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int length () const { return this->head - current->head; }
|
unsigned int length () const { return this->head - current->head; }
|
||||||
|
@ -353,9 +350,7 @@ struct hb_serialize_context_t
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
Type *allocate_min ()
|
Type *allocate_min ()
|
||||||
{
|
{ return this->allocate_size<Type> (Type::min_size); }
|
||||||
return this->allocate_size<Type> (Type::min_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
Type *embed (const Type *obj)
|
Type *embed (const Type *obj)
|
||||||
|
@ -427,14 +422,12 @@ struct hb_serialize_context_t
|
||||||
/* Copy both items from head side and tail side... */
|
/* Copy both items from head side and tail side... */
|
||||||
unsigned int len = (this->head - this->start)
|
unsigned int len = (this->head - this->start)
|
||||||
+ (this->end - this->tail);
|
+ (this->end - this->tail);
|
||||||
|
|
||||||
char *p = (char *) malloc (len);
|
char *p = (char *) malloc (len);
|
||||||
if (p)
|
if (unlikely (!p)) return hb_bytes_t ();
|
||||||
{
|
|
||||||
memcpy (p, this->start, this->head - this->start);
|
memcpy (p, this->start, this->head - this->start);
|
||||||
memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
|
memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
|
||||||
}
|
|
||||||
else
|
|
||||||
return hb_bytes_t ();
|
|
||||||
return hb_bytes_t (p, len);
|
return hb_bytes_t (p, len);
|
||||||
}
|
}
|
||||||
template <typename Type>
|
template <typename Type>
|
||||||
|
|
|
@ -136,12 +136,17 @@ struct hb_set_t
|
||||||
unsigned int j = m & ELT_MASK;
|
unsigned int j = m & ELT_MASK;
|
||||||
|
|
||||||
const elt_t vv = v[i] & ((elt_t (1) << (j + 1)) - 1);
|
const elt_t vv = v[i] & ((elt_t (1) << (j + 1)) - 1);
|
||||||
for (const elt_t *p = &vv; (int) i >= 0; p = &v[--i])
|
const elt_t *p = &vv;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
if (*p)
|
if (*p)
|
||||||
{
|
{
|
||||||
*codepoint = i * ELT_BITS + elt_get_max (*p);
|
*codepoint = i * ELT_BITS + elt_get_max (*p);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if ((int) i <= 0) break;
|
||||||
|
p = &v[--i];
|
||||||
|
}
|
||||||
|
|
||||||
*codepoint = INVALID;
|
*codepoint = INVALID;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -48,7 +48,7 @@ static const union HB_STRING_ARRAY_TYPE_NAME {
|
||||||
#include HB_STRING_ARRAY_LIST
|
#include HB_STRING_ARRAY_LIST
|
||||||
#undef _S
|
#undef _S
|
||||||
} st;
|
} st;
|
||||||
char str[VAR];
|
char str[HB_VAR_ARRAY];
|
||||||
}
|
}
|
||||||
HB_STRING_ARRAY_POOL_NAME =
|
HB_STRING_ARRAY_POOL_NAME =
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,7 +39,7 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
|
||||||
hb_codepoint_t gid,
|
hb_codepoint_t gid,
|
||||||
hb_set_t *gids_to_retain)
|
hb_set_t *gids_to_retain)
|
||||||
{
|
{
|
||||||
if (hb_set_has (gids_to_retain, gid))
|
if (gids_to_retain->has (gid))
|
||||||
// Already visited this gid, ignore.
|
// Already visited this gid, ignore.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -87,6 +87,14 @@ _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_cmap_closure (hb_face_t *face,
|
||||||
|
const hb_set_t *unicodes,
|
||||||
|
hb_set_t *glyphset)
|
||||||
|
{
|
||||||
|
face->table.cmap->table->closure_glyphs (unicodes, glyphset);
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
_remove_invalid_gids (hb_set_t *glyphs,
|
_remove_invalid_gids (hb_set_t *glyphs,
|
||||||
unsigned int num_glyphs)
|
unsigned int num_glyphs)
|
||||||
|
@ -129,6 +137,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
||||||
plan->_glyphset_gsub->add (gid);
|
plan->_glyphset_gsub->add (gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_cmap_closure (plan->source, plan->unicodes, plan->_glyphset_gsub);
|
||||||
|
|
||||||
#ifndef HB_NO_SUBSET_LAYOUT
|
#ifndef HB_NO_SUBSET_LAYOUT
|
||||||
if (close_over_gsub)
|
if (close_over_gsub)
|
||||||
// Add all glyphs needed for GSUB substitutions.
|
// Add all glyphs needed for GSUB substitutions.
|
||||||
|
|
|
@ -249,11 +249,6 @@ _subset_table (hb_subset_plan_t *plan,
|
||||||
static bool
|
static bool
|
||||||
_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
|
_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
|
||||||
{
|
{
|
||||||
if (!tag)
|
|
||||||
/* Drop tables with no tag as that means table header in
|
|
||||||
_hb_face_builder_reference_table */
|
|
||||||
return true;
|
|
||||||
|
|
||||||
if (plan->drop_tables->has (tag))
|
if (plan->drop_tables->has (tag))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -301,17 +296,19 @@ hb_subset (hb_face_t *source,
|
||||||
hb_tag_t table_tags[32];
|
hb_tag_t table_tags[32];
|
||||||
unsigned int offset = 0, count;
|
unsigned int offset = 0, count;
|
||||||
bool success = true;
|
bool success = true;
|
||||||
|
hb_set_t tags_set;
|
||||||
do {
|
do {
|
||||||
count = ARRAY_LENGTH (table_tags);
|
count = ARRAY_LENGTH (table_tags);
|
||||||
hb_face_get_table_tags (source, offset, &count, table_tags);
|
hb_face_get_table_tags (source, offset, &count, table_tags);
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
hb_tag_t tag = table_tags[i];
|
hb_tag_t tag = table_tags[i];
|
||||||
if (_should_drop_table (plan, tag))
|
if (_should_drop_table (plan, tag) && !tags_set.has (tag))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag));
|
DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
tags_set.add (tag);
|
||||||
success = success && _subset_table (plan, tag);
|
success = success && _subset_table (plan, tag);
|
||||||
}
|
}
|
||||||
offset += count;
|
offset += count;
|
||||||
|
|
|
@ -270,9 +270,9 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
|
||||||
**/
|
**/
|
||||||
hb_bool_t
|
hb_bool_t
|
||||||
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy,
|
hb_destroy_func_t destroy,
|
||||||
hb_bool_t replace)
|
hb_bool_t replace)
|
||||||
{
|
{
|
||||||
return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
|
return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
|
||||||
|
@ -291,7 +291,7 @@ hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||||
**/
|
**/
|
||||||
void *
|
void *
|
||||||
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_user_data_key_t *key)
|
hb_user_data_key_t *key)
|
||||||
{
|
{
|
||||||
return hb_object_get_user_data (ufuncs, key);
|
return hb_object_get_user_data (ufuncs, key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,15 +200,15 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
|
||||||
|
|
||||||
HB_EXTERN hb_bool_t
|
HB_EXTERN hb_bool_t
|
||||||
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_user_data_key_t *key,
|
hb_user_data_key_t *key,
|
||||||
void * data,
|
void * data,
|
||||||
hb_destroy_func_t destroy,
|
hb_destroy_func_t destroy,
|
||||||
hb_bool_t replace);
|
hb_bool_t replace);
|
||||||
|
|
||||||
|
|
||||||
HB_EXTERN void *
|
HB_EXTERN void *
|
||||||
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
|
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
|
||||||
hb_user_data_key_t *key);
|
hb_user_data_key_t *key);
|
||||||
|
|
||||||
|
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
|
@ -260,7 +260,7 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
|
||||||
* @user_data:
|
* @user_data:
|
||||||
* @destroy:
|
* @destroy:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -276,7 +276,7 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
|
||||||
* @user_data:
|
* @user_data:
|
||||||
* @destroy:
|
* @destroy:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -292,7 +292,7 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
|
||||||
* @user_data:
|
* @user_data:
|
||||||
* @destroy:
|
* @destroy:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -308,7 +308,7 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
|
||||||
* @user_data:
|
* @user_data:
|
||||||
* @destroy:
|
* @destroy:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -324,7 +324,7 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
|
||||||
* @user_data:
|
* @user_data:
|
||||||
* @destroy:
|
* @destroy:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
@ -340,7 +340,7 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
|
||||||
* @user_data:
|
* @user_data:
|
||||||
* @destroy:
|
* @destroy:
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* Since: 0.9.2
|
* Since: 0.9.2
|
||||||
**/
|
**/
|
||||||
|
|
|
@ -302,8 +302,8 @@ struct hb_sorted_vector_t : hb_vector_t<Type>
|
||||||
{ return as_array ().bsearch (x, not_found); }
|
{ return as_array ().bsearch (x, not_found); }
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool bfind (const T &x, unsigned int *i = nullptr,
|
bool bfind (const T &x, unsigned int *i = nullptr,
|
||||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||||
unsigned int to_store = (unsigned int) -1) const
|
unsigned int to_store = (unsigned int) -1) const
|
||||||
{ return as_array ().bfind (x, i, not_found, to_store); }
|
{ return as_array ().bfind (x, i, not_found, to_store); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,9 @@ HB_BEGIN_DECLS
|
||||||
|
|
||||||
#define HB_VERSION_MAJOR 2
|
#define HB_VERSION_MAJOR 2
|
||||||
#define HB_VERSION_MINOR 6
|
#define HB_VERSION_MINOR 6
|
||||||
#define HB_VERSION_MICRO 1
|
#define HB_VERSION_MICRO 2
|
||||||
|
|
||||||
#define HB_VERSION_STRING "2.6.1"
|
#define HB_VERSION_STRING "2.6.2"
|
||||||
|
|
||||||
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
||||||
((major)*10000+(minor)*100+(micro) <= \
|
((major)*10000+(minor)*100+(micro) <= \
|
||||||
|
|
27
src/hb.hh
27
src/hb.hh
|
@ -180,7 +180,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
@ -242,7 +241,7 @@ extern "C" void hb_free_impl(void *ptr);
|
||||||
#define HB_CONST_FUNC
|
#define HB_CONST_FUNC
|
||||||
#define HB_PRINTF_FUNC(format_idx, arg_idx)
|
#define HB_PRINTF_FUNC(format_idx, arg_idx)
|
||||||
#endif
|
#endif
|
||||||
#if defined(__GNUC__) && (__GNUC__ >= 4)
|
#if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__)
|
||||||
#define HB_UNUSED __attribute__((unused))
|
#define HB_UNUSED __attribute__((unused))
|
||||||
#elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
|
#elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
|
||||||
#define HB_UNUSED __pragma(warning(suppress: 4100 4101))
|
#define HB_UNUSED __pragma(warning(suppress: 4100 4101))
|
||||||
|
@ -355,7 +354,7 @@ extern "C" void hb_free_impl(void *ptr);
|
||||||
# endif
|
# endif
|
||||||
# if _WIN32_WCE < 0x800
|
# if _WIN32_WCE < 0x800
|
||||||
# define HB_NO_SETLOCALE
|
# define HB_NO_SETLOCALE
|
||||||
static int errno = 0; /* Use something better? */
|
# define HB_NO_ERRNO
|
||||||
# endif
|
# endif
|
||||||
# elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
|
# elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
|
||||||
# ifndef HB_NO_GETENV
|
# ifndef HB_NO_GETENV
|
||||||
|
@ -371,6 +370,12 @@ static int errno = 0; /* Use something better? */
|
||||||
#define getenv(Name) nullptr
|
#define getenv(Name) nullptr
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HB_NO_ERRNO
|
||||||
|
static int errno = 0; /* Use something better? */
|
||||||
|
#else
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT)
|
#if defined(HAVE_ATEXIT) && !defined(HB_USE_ATEXIT)
|
||||||
/* atexit() is only safe to be called from shared libraries on certain
|
/* atexit() is only safe to be called from shared libraries on certain
|
||||||
* platforms. Whitelist.
|
* platforms. Whitelist.
|
||||||
|
@ -475,7 +480,18 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
|
||||||
|
|
||||||
|
|
||||||
/* Size signifying variable-sized array */
|
/* Size signifying variable-sized array */
|
||||||
#define VAR 1
|
#ifndef HB_VAR_ARRAY
|
||||||
|
#define HB_VAR_ARRAY 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static inline double
|
||||||
|
_hb_roundf (float x)
|
||||||
|
{
|
||||||
|
return x >= 0 ? floor ((double) x + .5) : ceil ((double) x - .5);
|
||||||
|
}
|
||||||
|
#ifndef HAVE_ROUNDF
|
||||||
|
#define roundf(x) _hb_roundf(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Endian swap, used in Windows related backends */
|
/* Endian swap, used in Windows related backends */
|
||||||
static inline uint16_t hb_uint16_swap (const uint16_t v)
|
static inline uint16_t hb_uint16_swap (const uint16_t v)
|
||||||
|
@ -585,9 +601,10 @@ struct BEInt<Type, 4>
|
||||||
* them directly.*/
|
* them directly.*/
|
||||||
#include "hb-meta.hh"
|
#include "hb-meta.hh"
|
||||||
#include "hb-mutex.hh"
|
#include "hb-mutex.hh"
|
||||||
|
#include "hb-number.hh"
|
||||||
#include "hb-atomic.hh" // Requires: hb-meta
|
#include "hb-atomic.hh" // Requires: hb-meta
|
||||||
#include "hb-null.hh" // Requires: hb-meta
|
#include "hb-null.hh" // Requires: hb-meta
|
||||||
#include "hb-algs.hh" // Requires: hb-meta hb-null
|
#include "hb-algs.hh" // Requires: hb-meta hb-null hb-number
|
||||||
#include "hb-iter.hh" // Requires: hb-algs hb-meta
|
#include "hb-iter.hh" // Requires: hb-algs hb-meta
|
||||||
#include "hb-debug.hh" // Requires: hb-algs hb-atomic
|
#include "hb-debug.hh" // Requires: hb-algs hb-atomic
|
||||||
#include "hb-array.hh" // Requires: hb-algs hb-iter hb-null
|
#include "hb-array.hh" // Requires: hb-algs hb-iter hb-null
|
||||||
|
|
37
src/main.cc
37
src/main.cc
|
@ -45,7 +45,8 @@ using namespace OT;
|
||||||
int
|
int
|
||||||
main (int argc, char **argv)
|
main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc != 2) {
|
if (argc != 2)
|
||||||
|
{
|
||||||
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
|
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
|
||||||
exit (1);
|
exit (1);
|
||||||
}
|
}
|
||||||
|
@ -65,7 +66,8 @@ main (int argc, char **argv)
|
||||||
const OpenTypeFontFile& ot = *sanitized;
|
const OpenTypeFontFile& ot = *sanitized;
|
||||||
|
|
||||||
|
|
||||||
switch (ot.get_tag ()) {
|
switch (ot.get_tag ())
|
||||||
|
{
|
||||||
case OpenTypeFontFile::TrueTypeTag:
|
case OpenTypeFontFile::TrueTypeTag:
|
||||||
printf ("OpenType font with TrueType outlines\n");
|
printf ("OpenType font with TrueType outlines\n");
|
||||||
break;
|
break;
|
||||||
|
@ -91,20 +93,23 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
int num_fonts = ot.get_face_count ();
|
int num_fonts = ot.get_face_count ();
|
||||||
printf ("%d font(s) found in file\n", num_fonts);
|
printf ("%d font(s) found in file\n", num_fonts);
|
||||||
for (int n_font = 0; n_font < num_fonts; n_font++) {
|
for (int n_font = 0; n_font < num_fonts; n_font++)
|
||||||
|
{
|
||||||
const OpenTypeFontFace &font = ot.get_face (n_font);
|
const OpenTypeFontFace &font = ot.get_face (n_font);
|
||||||
printf ("Font %d of %d:\n", n_font, num_fonts);
|
printf ("Font %d of %d:\n", n_font, num_fonts);
|
||||||
|
|
||||||
int num_tables = font.get_table_count ();
|
int num_tables = font.get_table_count ();
|
||||||
printf (" %d table(s) found in font\n", num_tables);
|
printf (" %d table(s) found in font\n", num_tables);
|
||||||
for (int n_table = 0; n_table < num_tables; n_table++) {
|
for (int n_table = 0; n_table < num_tables; n_table++)
|
||||||
|
{
|
||||||
const OpenTypeTable &table = font.get_table (n_table);
|
const OpenTypeTable &table = font.get_table (n_table);
|
||||||
printf (" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables,
|
printf (" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables,
|
||||||
(const char *) table.tag,
|
(const char *) table.tag,
|
||||||
(unsigned int) table.offset,
|
(unsigned int) table.offset,
|
||||||
(unsigned int) table.length);
|
(unsigned int) table.length);
|
||||||
|
|
||||||
switch (table.tag) {
|
switch (table.tag)
|
||||||
|
{
|
||||||
|
|
||||||
case HB_OT_TAG_GSUB:
|
case HB_OT_TAG_GSUB:
|
||||||
case HB_OT_TAG_GPOS:
|
case HB_OT_TAG_GPOS:
|
||||||
|
@ -114,10 +119,11 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
int num_scripts = g.get_script_count ();
|
int num_scripts = g.get_script_count ();
|
||||||
printf (" %d script(s) found in table\n", num_scripts);
|
printf (" %d script(s) found in table\n", num_scripts);
|
||||||
for (int n_script = 0; n_script < num_scripts; n_script++) {
|
for (int n_script = 0; n_script < num_scripts; n_script++)
|
||||||
|
{
|
||||||
const Script &script = g.get_script (n_script);
|
const Script &script = g.get_script (n_script);
|
||||||
printf (" Script %2d of %2d: %.4s\n", n_script, num_scripts,
|
printf (" Script %2d of %2d: %.4s\n", n_script, num_scripts,
|
||||||
(const char *)g.get_script_tag(n_script));
|
(const char *)g.get_script_tag(n_script));
|
||||||
|
|
||||||
if (!script.has_default_lang_sys())
|
if (!script.has_default_lang_sys())
|
||||||
printf (" No default language system\n");
|
printf (" No default language system\n");
|
||||||
|
@ -140,34 +146,37 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
int num_features = langsys.get_feature_count ();
|
int num_features = langsys.get_feature_count ();
|
||||||
printf (" %d feature(s) found in language system\n", num_features);
|
printf (" %d feature(s) found in language system\n", num_features);
|
||||||
for (int n_feature = 0; n_feature < num_features; n_feature++) {
|
for (int n_feature = 0; n_feature < num_features; n_feature++)
|
||||||
|
{
|
||||||
printf (" Feature index %2d of %2d: %d\n", n_feature, num_features,
|
printf (" Feature index %2d of %2d: %d\n", n_feature, num_features,
|
||||||
langsys.get_feature_index (n_feature));
|
langsys.get_feature_index (n_feature));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_features = g.get_feature_count ();
|
int num_features = g.get_feature_count ();
|
||||||
printf (" %d feature(s) found in table\n", num_features);
|
printf (" %d feature(s) found in table\n", num_features);
|
||||||
for (int n_feature = 0; n_feature < num_features; n_feature++) {
|
for (int n_feature = 0; n_feature < num_features; n_feature++)
|
||||||
|
{
|
||||||
const Feature &feature = g.get_feature (n_feature);
|
const Feature &feature = g.get_feature (n_feature);
|
||||||
int num_lookups = feature.get_lookup_count ();
|
int num_lookups = feature.get_lookup_count ();
|
||||||
printf (" Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features,
|
printf (" Feature %2d of %2d: %c%c%c%c\n", n_feature, num_features,
|
||||||
HB_UNTAG(g.get_feature_tag(n_feature)));
|
HB_UNTAG(g.get_feature_tag(n_feature)));
|
||||||
|
|
||||||
printf (" %d lookup(s) found in feature\n", num_lookups);
|
printf (" %d lookup(s) found in feature\n", num_lookups);
|
||||||
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
|
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
|
||||||
printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups,
|
printf (" Lookup index %2d of %2d: %d\n", n_lookup, num_lookups,
|
||||||
feature.get_lookup_index (n_lookup));
|
feature.get_lookup_index (n_lookup));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int num_lookups = g.get_lookup_count ();
|
int num_lookups = g.get_lookup_count ();
|
||||||
printf (" %d lookup(s) found in table\n", num_lookups);
|
printf (" %d lookup(s) found in table\n", num_lookups);
|
||||||
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
|
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++)
|
||||||
|
{
|
||||||
const Lookup &lookup = g.get_lookup (n_lookup);
|
const Lookup &lookup = g.get_lookup (n_lookup);
|
||||||
printf (" Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups,
|
printf (" Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups,
|
||||||
lookup.get_type(), lookup.get_props());
|
lookup.get_type(), lookup.get_props());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,5 +87,9 @@ main (int argc, char **argv)
|
||||||
assert (hb_add (2) (5) == 7);
|
assert (hb_add (2) (5) == 7);
|
||||||
assert (hb_add (5) (2) == 7);
|
assert (hb_add (5) (2) == 7);
|
||||||
|
|
||||||
|
x = 1;
|
||||||
|
assert (++hb_inc (x) == 3);
|
||||||
|
assert (x == 3);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,7 +234,7 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
hb_set_t *set = hb_set_create ();
|
hb_set_t *set = hb_set_create ();
|
||||||
for (unsigned int i = 0; i < temp1; ++i)
|
for (unsigned int i = 0; i < temp1; ++i)
|
||||||
hb_set_add (set, i);
|
hb_set_add (set, i);
|
||||||
temp1++;
|
temp1++;
|
||||||
return set;
|
return set;
|
||||||
})
|
})
|
||||||
|
@ -267,7 +267,12 @@ main (int argc, char **argv)
|
||||||
hb_iota ();
|
hb_iota ();
|
||||||
hb_iota (3);
|
hb_iota (3);
|
||||||
hb_iota (3, 2);
|
hb_iota (3, 2);
|
||||||
|
assert ((&vl) + 1 == *++hb_iota (&vl, hb_inc));
|
||||||
hb_range ();
|
hb_range ();
|
||||||
|
hb_repeat (7u);
|
||||||
|
hb_repeat (nullptr);
|
||||||
|
hb_repeat (vl) | hb_chop (3);
|
||||||
|
assert (hb_len (hb_range (10) | hb_take (3)) == 3);
|
||||||
assert (hb_range (9).len () == 9);
|
assert (hb_range (9).len () == 9);
|
||||||
assert (hb_range (2, 9).len () == 7);
|
assert (hb_range (2, 9).len () == 7);
|
||||||
assert (hb_range (2, 9, 3).len () == 3);
|
assert (hb_range (2, 9, 3).len () == 3);
|
||||||
|
|
|
@ -0,0 +1,253 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2019 Ebrahim Byagowi
|
||||||
|
*
|
||||||
|
* This is part of HarfBuzz, a text shaping library.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, without written agreement and without
|
||||||
|
* license or royalty fees, to use, copy, modify, and distribute this
|
||||||
|
* software and its documentation for any purpose, provided that the
|
||||||
|
* above copyright notice and the following two paragraphs appear in
|
||||||
|
* all copies of this software.
|
||||||
|
*
|
||||||
|
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||||
|
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||||
|
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||||
|
* DAMAGE.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||||
|
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||||
|
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hb.hh"
|
||||||
|
#include "hb-number.hh"
|
||||||
|
#include "hb-number-parser.hh"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
const char str[] = "123";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + 3;
|
||||||
|
|
||||||
|
int pv;
|
||||||
|
assert (hb_parse_int (&pp, end, &pv));
|
||||||
|
assert (pv == 123);
|
||||||
|
assert (pp - str == 3);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
assert (!*end);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "123";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + strlen (str);
|
||||||
|
|
||||||
|
unsigned int pv;
|
||||||
|
assert (hb_parse_uint (&pp, end, &pv));
|
||||||
|
assert (pv == 123);
|
||||||
|
assert (pp - str == 3);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
assert (!*end);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "12F";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + 3;
|
||||||
|
|
||||||
|
unsigned int pv;
|
||||||
|
assert (hb_parse_uint (&pp, end, &pv, true, 16));
|
||||||
|
assert (pv == 0x12F);
|
||||||
|
assert (pp - str == 3);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
assert (!*end);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "12Fq";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + 4;
|
||||||
|
|
||||||
|
unsigned int pv;
|
||||||
|
assert (!hb_parse_uint (&pp, end, &pv, true, 16));
|
||||||
|
assert (hb_parse_uint (&pp, end, &pv, false, 16));
|
||||||
|
assert (pv == 0x12F);
|
||||||
|
assert (pp - str == 3);
|
||||||
|
assert (end - pp == 1);
|
||||||
|
assert (!*end);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "-123";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + 4;
|
||||||
|
|
||||||
|
int pv;
|
||||||
|
assert (hb_parse_int (&pp, end, &pv));
|
||||||
|
assert (pv == -123);
|
||||||
|
assert (pp - str == 4);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
assert (!*end);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "123";
|
||||||
|
const char *pp = str;
|
||||||
|
assert (ARRAY_LENGTH (str) == 4);
|
||||||
|
const char *end = str + ARRAY_LENGTH (str);
|
||||||
|
|
||||||
|
unsigned int pv;
|
||||||
|
assert (hb_parse_uint (&pp, end, &pv));
|
||||||
|
assert (pv == 123);
|
||||||
|
assert (pp - str == 3);
|
||||||
|
assert (end - pp == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "123\0";
|
||||||
|
const char *pp = str;
|
||||||
|
assert (ARRAY_LENGTH (str) == 5);
|
||||||
|
const char *end = str + ARRAY_LENGTH (str);
|
||||||
|
|
||||||
|
unsigned int pv;
|
||||||
|
assert (hb_parse_uint (&pp, end, &pv));
|
||||||
|
assert (pv == 123);
|
||||||
|
assert (pp - str == 3);
|
||||||
|
assert (end - pp == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "123V";
|
||||||
|
const char *pp = str;
|
||||||
|
assert (ARRAY_LENGTH (str) == 5);
|
||||||
|
const char *end = str + ARRAY_LENGTH (str);
|
||||||
|
|
||||||
|
unsigned int pv;
|
||||||
|
assert (hb_parse_uint (&pp, end, &pv));
|
||||||
|
assert (pv == 123);
|
||||||
|
assert (pp - str == 3);
|
||||||
|
assert (end - pp == 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = ".123";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + ARRAY_LENGTH (str);
|
||||||
|
|
||||||
|
double pv;
|
||||||
|
assert (hb_parse_double (&pp, end, &pv));
|
||||||
|
assert ((int) roundf (pv * 1000.) == 123);
|
||||||
|
assert (pp - str == 4);
|
||||||
|
assert (end - pp == 1);
|
||||||
|
|
||||||
|
/* Test strtod_rl even if libc's strtod_l is used */
|
||||||
|
char *pend;
|
||||||
|
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||||
|
assert (pend - str == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "0.123";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||||
|
|
||||||
|
double pv;
|
||||||
|
assert (hb_parse_double (&pp, end, &pv));
|
||||||
|
assert ((int) roundf (pv * 1000.) == 123);
|
||||||
|
assert (pp - str == 5);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
|
||||||
|
char *pend;
|
||||||
|
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||||
|
assert (pend - str == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "0.123e0";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||||
|
|
||||||
|
double pv;
|
||||||
|
assert (hb_parse_double (&pp, end, &pv));
|
||||||
|
assert ((int) roundf (pv * 1000.) == 123);
|
||||||
|
assert (pp - str == 7);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
|
||||||
|
char *pend;
|
||||||
|
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||||
|
assert (pend - str == 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "123e-3";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||||
|
|
||||||
|
double pv;
|
||||||
|
assert (hb_parse_double (&pp, end, &pv));
|
||||||
|
assert ((int) roundf (pv * 1000.) == 123);
|
||||||
|
assert (pp - str == 6);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
|
||||||
|
char *pend;
|
||||||
|
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||||
|
assert (pend - str == 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = ".000123e+3";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||||
|
|
||||||
|
double pv;
|
||||||
|
assert (hb_parse_double (&pp, end, &pv));
|
||||||
|
assert ((int) roundf (pv * 1000.) == 123);
|
||||||
|
assert (pp - str == 10);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
|
||||||
|
char *pend;
|
||||||
|
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||||
|
assert (pend - str == 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "-.000000123e6";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||||
|
|
||||||
|
double pv;
|
||||||
|
assert (hb_parse_double (&pp, end, &pv));
|
||||||
|
assert ((int) roundf (pv * 1000.) == -123);
|
||||||
|
assert (pp - str == 13);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
|
||||||
|
char *pend;
|
||||||
|
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
|
||||||
|
assert (pend - str == 13);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const char str[] = "-1.23E-1";
|
||||||
|
const char *pp = str;
|
||||||
|
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||||
|
|
||||||
|
double pv;
|
||||||
|
assert (hb_parse_double (&pp, end, &pv));
|
||||||
|
assert ((int) roundf (pv * 1000.) == -123);
|
||||||
|
assert (pp - str == 8);
|
||||||
|
assert (end - pp == 0);
|
||||||
|
|
||||||
|
char *pend;
|
||||||
|
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
|
||||||
|
assert (pend - str == 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -351,9 +351,6 @@ test_ot_tag_language (void)
|
||||||
test_tag_from_language ("ZHH", "yue-Hant");
|
test_tag_from_language ("ZHH", "yue-Hant");
|
||||||
test_tag_from_language ("ZHS", "yue-Hans");
|
test_tag_from_language ("ZHS", "yue-Hans");
|
||||||
|
|
||||||
test_tag_from_language ("ZHS", "zh"); /* Chinese */
|
|
||||||
test_tag_from_language ("ZHS", "zh-xx");
|
|
||||||
|
|
||||||
test_language_two_way ("ABC", "abc");
|
test_language_two_way ("ABC", "abc");
|
||||||
test_language_two_way ("ABCD", "x-hbotabcd");
|
test_language_two_way ("ABCD", "x-hbotabcd");
|
||||||
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc");
|
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc");
|
||||||
|
|
Binary file not shown.
|
@ -39,7 +39,12 @@ def cmd (command):
|
||||||
timer.start()
|
timer.start()
|
||||||
p.wait ()
|
p.wait ()
|
||||||
tempf.seek (0)
|
tempf.seek (0)
|
||||||
text = tempf.read ().decode ("utf-8").strip ()
|
text = tempf.read ()
|
||||||
|
|
||||||
|
#TODO: Detect debug mode with a better way
|
||||||
|
is_debug_mode = b"SANITIZE" in text
|
||||||
|
|
||||||
|
text = "" if is_debug_mode else text.decode ("utf-8").strip ()
|
||||||
returncode = p.returncode
|
returncode = p.returncode
|
||||||
finally:
|
finally:
|
||||||
timer.cancel()
|
timer.cancel()
|
||||||
|
|
|
@ -39,7 +39,12 @@ def cmd(command):
|
||||||
timer.start()
|
timer.start()
|
||||||
p.wait ()
|
p.wait ()
|
||||||
tempf.seek (0)
|
tempf.seek (0)
|
||||||
text = tempf.read().decode ("utf-8").strip ()
|
text = tempf.read ()
|
||||||
|
|
||||||
|
#TODO: Detect debug mode with a better way
|
||||||
|
is_debug_mode = b"SANITIZE" in text
|
||||||
|
|
||||||
|
text = "" if is_debug_mode else text.decode ("utf-8").strip ()
|
||||||
returncode = p.returncode
|
returncode = p.returncode
|
||||||
finally:
|
finally:
|
||||||
timer.cancel()
|
timer.cancel()
|
||||||
|
|
|
@ -6,7 +6,8 @@ CLEANFILES =
|
||||||
SUBDIRS = data
|
SUBDIRS = data
|
||||||
|
|
||||||
# Convenience targets:
|
# Convenience targets:
|
||||||
lib:
|
lib: libs # Always build subsetter lib in this subdir
|
||||||
|
libs:
|
||||||
@$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src libs
|
@$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src libs
|
||||||
|
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
|
|
|
@ -14,6 +14,8 @@ EXTRA_DIST += \
|
||||||
expected/cff-japanese \
|
expected/cff-japanese \
|
||||||
expected/layout \
|
expected/layout \
|
||||||
expected/layout.gpos \
|
expected/layout.gpos \
|
||||||
|
expected/layout.gpos3 \
|
||||||
|
expected/cmap14 \
|
||||||
fonts \
|
fonts \
|
||||||
profiles \
|
profiles \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -6,6 +6,8 @@ TESTS = \
|
||||||
tests/cff-japanese.tests \
|
tests/cff-japanese.tests \
|
||||||
tests/layout.tests \
|
tests/layout.tests \
|
||||||
tests/layout.gpos.tests \
|
tests/layout.gpos.tests \
|
||||||
|
tests/layout.gpos3.tests \
|
||||||
|
tests/cmap14.tests \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
XFAIL_TESTS = \
|
XFAIL_TESTS = \
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue