Merge remote-tracking branch 'upstream/master' into var-subset

This commit is contained in:
Ebrahim Byagowi 2019-10-03 13:39:17 +03:30
commit 19d45dcab7
156 changed files with 1946 additions and 794 deletions

View File

@ -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

View File

@ -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

View File

@ -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
View File

@ -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
==================================== ====================================

View File

@ -6,6 +6,7 @@
[![Codacy Code Health](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz) [![Codacy Code Health](https://api.codacy.com/project/badge/Grade/f17f1708783c447488bc8dd317150eaa)](https://app.codacy.com/app/behdad/harfbuzz)
[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/master/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz) [![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/master/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
[![Coverals Code Coverage](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz) [![Coverals Code Coverage](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
[![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions)
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/) [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
[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)
</details>

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 \

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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 */

View File

@ -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. */

View File

@ -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
{ {

View File

@ -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 */

View File

@ -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>

View File

@ -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. */

View File

@ -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;

View File

@ -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>

View File

@ -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;

View File

@ -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

View File

@ -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++)

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.");

View File

@ -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);
} }

View File

@ -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

View File

@ -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;

View File

@ -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);
} }

View File

@ -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
* *

View File

@ -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

View File

@ -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() */

View File

@ -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)

240
src/hb-number-parser.hh Normal file
View File

@ -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 */

139
src/hb-number-parser.rl Normal file
View File

@ -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 */

147
src/hb-number.cc Normal file
View File

@ -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
});
}

41
src/hb-number.hh Normal file
View File

@ -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 */

View File

@ -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) &&

View File

@ -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, &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); }
}; };

View File

@ -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);

View File

@ -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;
}; };

View File

@ -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;
} }

View File

@ -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)

View File

@ -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;
}; };

View File

@ -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);

View File

@ -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

View File

@ -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); }

View File

@ -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

View File

@ -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
{ {

View File

@ -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

View File

@ -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
{ {

View File

@ -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:

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -136,7 +136,7 @@ struct JstfLangSys : OffsetListOf<JstfPriority>
* ExtenderGlyphs -- Extender Glyph Table * ExtenderGlyphs -- Extender Glyph Table
*/ */
typedef SortedArrayOf<GlyphID> ExtenderGlyphs; typedef SortedArrayOf<HBGlyphID> ExtenderGlyphs;
/* /*

View File

@ -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.

View File

@ -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 */
} }

View File

@ -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

View File

@ -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);
}; };

View File

@ -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 */

View File

@ -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 {

View File

@ -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). */

View File

@ -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;

View File

@ -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);

View File

@ -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);
}; };

View File

@ -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);

View File

@ -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

View File

@ -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>

View File

@ -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;

View File

@ -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 =
{ {

View File

@ -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.

View File

@ -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;

View File

@ -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);
} }

View File

@ -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
**/ **/

View File

@ -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); }
}; };

View File

@ -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) <= \

View File

@ -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

View File

@ -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());
} }
} }

View File

@ -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;
} }

View File

@ -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);

253
src/test-number.cc Normal file
View File

@ -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;
}

View File

@ -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");

View File

@ -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()

View File

@ -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()

View File

@ -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 += \

View File

@ -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)

View File

@ -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 = \

Some files were not shown because too many files have changed in this diff Show More