Merge remote-tracking branch 'upstream/master' into var-subset
This commit is contained in:
commit
19d45dcab7
|
@ -22,15 +22,16 @@ jobs:
|
|||
- run: make -j4
|
||||
- run: make check || .ci/fail.sh
|
||||
|
||||
macos-10.14.3-aat-fonts:
|
||||
macos-10.14.4-aat-fonts:
|
||||
macos:
|
||||
xcode: "10.2.0"
|
||||
xcode: "11.0.0"
|
||||
steps:
|
||||
- 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: make -j4
|
||||
- run: make check || .ci/fail.sh
|
||||
- run: cmake -Bbuild -H. -DHB_HAVE_CORETEXT=1 -DHB_BUILD_TESTS=0 && cmake --build build
|
||||
|
||||
distcheck:
|
||||
docker:
|
||||
|
@ -127,7 +128,7 @@ jobs:
|
|||
- 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: 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 check CPPFLAGS="-Werror" || .ci/fail.sh
|
||||
|
||||
|
@ -193,9 +194,9 @@ jobs:
|
|||
- 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: 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 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:
|
||||
docker:
|
||||
|
@ -203,8 +204,8 @@ jobs:
|
|||
steps:
|
||||
- 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: CFLAGS="-O0" CXXFLAGS="-O0" CPPFLAGS="-DHB_DEBUG" NOCONFIGURE=1 ./autogen.sh --with-freetype --with-glib --with-gobject --with-cairo --with-icu --with-graphite2
|
||||
- run: mkdir build && cd build && ../configure && make -j32 && (make check || ../.ci/fail.sh)
|
||||
- run: NOCONFIGURE=1 ./autogen.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: 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
|
||||
|
@ -306,7 +307,7 @@ workflows:
|
|||
# macOS
|
||||
- macos-10.12.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
|
||||
- distcheck
|
||||
|
|
|
@ -6,7 +6,7 @@ trim_trailing_whitespace = true
|
|||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{c,cc,h,hh}]
|
||||
[*.{c,cc,h,hh,rl}]
|
||||
tab_width = 8
|
||||
indent_size = 2
|
||||
indent_style = tab # should be space
|
||||
|
|
|
@ -108,7 +108,7 @@ endmacro ()
|
|||
if (UNIX)
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES m)
|
||||
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)
|
||||
if (${HAVE_UNISTD_H})
|
||||
add_definitions(-DHAVE_UNISTD_H)
|
||||
|
|
6
NEWS
6
NEWS
|
@ -1,3 +1,9 @@
|
|||
Overview of changes leading to 2.6.2
|
||||
Monday, September 30, 2019
|
||||
====================================
|
||||
- Misc small fixes, mostly to build-related issues.
|
||||
|
||||
|
||||
Overview of changes leading to 2.6.1
|
||||
Thursday, August 22, 2019
|
||||
====================================
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
[](https://app.codacy.com/app/behdad/harfbuzz)
|
||||
[](https://codecov.io/gh/harfbuzz/harfbuzz)
|
||||
[](https://coveralls.io/r/harfbuzz/harfbuzz)
|
||||
[](https://repology.org/project/harfbuzz/versions)
|
||||
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
|
||||
|
||||
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).
|
||||
|
||||
Documentation: https://harfbuzz.github.io
|
||||
|
||||
|
||||
<details>
|
||||
<summary>Packaging status of HarfBuzz</summary
|
||||
|
||||
[](https://repology.org/project/harfbuzz/versions)
|
||||
|
||||
</details>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
AC_PREREQ([2.64])
|
||||
AC_INIT([HarfBuzz],
|
||||
[2.6.1],
|
||||
[2.6.2],
|
||||
[https://github.com/harfbuzz/harfbuzz/issues/new],
|
||||
[harfbuzz],
|
||||
[http://harfbuzz.org/])
|
||||
|
@ -77,7 +77,7 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
|
|||
])
|
||||
|
||||
# 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)
|
||||
|
||||
# Compiler flags
|
||||
|
|
|
@ -612,14 +612,14 @@ hb_ot_math_get_glyph_assembly
|
|||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-meta</FILE>
|
||||
hb_ot_meta_t
|
||||
hb_ot_meta_tag_t
|
||||
hb_ot_meta_get_entry_tags
|
||||
hb_ot_meta_reference_entry
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-metrics</FILE>
|
||||
hb_ot_metrics_t
|
||||
hb_ot_metrics_tag_t
|
||||
hb_ot_metrics_get_position
|
||||
hb_ot_metrics_get_variation
|
||||
hb_ot_metrics_get_x_variation
|
||||
|
|
|
@ -411,7 +411,7 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
|
|||
dump_use_data_CPPFLAGS = $(HBCFLAGS)
|
||||
dump_use_data_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_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
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_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_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
|
|
@ -49,6 +49,8 @@ HB_BASE_sources = \
|
|||
hb-meta.hh \
|
||||
hb-mutex.hh \
|
||||
hb-null.hh \
|
||||
hb-number.cc \
|
||||
hb-number.hh \
|
||||
hb-object.hh \
|
||||
hb-open-file.hh \
|
||||
hb-open-type.hh \
|
||||
|
@ -169,6 +171,7 @@ HB_BASE_sources = \
|
|||
HB_BASE_RAGEL_GENERATED_sources = \
|
||||
hb-buffer-deserialize-json.hh \
|
||||
hb-buffer-deserialize-text.hh \
|
||||
hb-number-parser.hh \
|
||||
hb-ot-shape-complex-indic-machine.hh \
|
||||
hb-ot-shape-complex-khmer-machine.hh \
|
||||
hb-ot-shape-complex-myanmar-machine.hh \
|
||||
|
@ -177,6 +180,7 @@ HB_BASE_RAGEL_GENERATED_sources = \
|
|||
HB_BASE_RAGEL_sources = \
|
||||
hb-buffer-deserialize-json.rl \
|
||||
hb-buffer-deserialize-text.rl \
|
||||
hb-number-parser.rl \
|
||||
hb-ot-shape-complex-indic-machine.rl \
|
||||
hb-ot-shape-complex-khmer-machine.rl \
|
||||
hb-ot-shape-complex-myanmar-machine.rl \
|
||||
|
@ -243,6 +247,8 @@ HB_ICU_headers = hb-icu.h
|
|||
|
||||
# Sources for libharfbuzz-subset
|
||||
HB_SUBSET_sources = \
|
||||
hb-number.cc \
|
||||
hb-number.hh \
|
||||
hb-ot-cff1-table.cc \
|
||||
hb-ot-cff2-table.cc \
|
||||
hb-static.cc \
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "hb-fallback-shape.cc"
|
||||
#include "hb-font.cc"
|
||||
#include "hb-map.cc"
|
||||
#include "hb-number.cc"
|
||||
#include "hb-ot-cff1-table.cc"
|
||||
#include "hb-ot-cff2-table.cc"
|
||||
#include "hb-ot-color.cc"
|
||||
|
|
|
@ -65,7 +65,7 @@ struct FontDescriptor
|
|||
protected:
|
||||
Tag tag; /* The 4-byte table tag name. */
|
||||
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 */
|
||||
} u;
|
||||
public:
|
||||
|
@ -108,7 +108,7 @@ struct fdsc
|
|||
}
|
||||
|
||||
protected:
|
||||
Fixed version; /* Version number of the font descriptors
|
||||
HBFixed version; /* Version number of the font descriptors
|
||||
* table (0x00010000 for the current version). */
|
||||
LArrayOf<FontDescriptor>
|
||||
descriptors; /* List of tagged-coordinate pairs style descriptors
|
||||
|
|
|
@ -82,7 +82,7 @@ struct BaselineTableFormat2Part
|
|||
}
|
||||
|
||||
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.
|
||||
* This is the standard glyph.
|
||||
* This glyph must contain a set of control points
|
||||
|
@ -105,7 +105,7 @@ struct BaselineTableFormat3Part
|
|||
}
|
||||
|
||||
protected:
|
||||
GlyphID stdGlyph; /* ditto */
|
||||
HBGlyphID stdGlyph; /* ditto */
|
||||
HBUINT16 ctlPoints[32]; /* ditto */
|
||||
Lookup<HBUINT16>
|
||||
lookupTable; /* Lookup table that maps glyphs to their
|
||||
|
|
|
@ -93,8 +93,8 @@ struct LookupSegmentSingle
|
|||
return_trace (c->check_struct (this) && value.sanitize (c, base));
|
||||
}
|
||||
|
||||
GlyphID last; /* Last GlyphID in this segment */
|
||||
GlyphID first; /* First GlyphID in this segment */
|
||||
HBGlyphID last; /* Last GlyphID in this segment */
|
||||
HBGlyphID first; /* First GlyphID in this segment */
|
||||
T value; /* The lookup value (only one) */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4 + T::static_size);
|
||||
|
@ -162,8 +162,8 @@ struct LookupSegmentArray
|
|||
valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...));
|
||||
}
|
||||
|
||||
GlyphID last; /* Last GlyphID in this segment */
|
||||
GlyphID first; /* First GlyphID in this segment */
|
||||
HBGlyphID last; /* Last GlyphID in this segment */
|
||||
HBGlyphID first; /* First GlyphID in this segment */
|
||||
NNOffsetTo<UnsizedArrayOf<T>>
|
||||
valuesZ; /* A 16-bit offset from the start of
|
||||
* the table to the data. */
|
||||
|
@ -222,7 +222,7 @@ struct LookupSingle
|
|||
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) */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (2 + T::static_size);
|
||||
|
@ -284,7 +284,7 @@ struct LookupFormat8
|
|||
|
||||
protected:
|
||||
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
|
||||
* glyph minus the value of firstGlyph plus 1). */
|
||||
UnsizedArrayOf<T>
|
||||
|
@ -326,7 +326,7 @@ struct LookupFormat10
|
|||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 8 */
|
||||
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
|
||||
* glyph minus the value of firstGlyph plus 1). */
|
||||
UnsizedArrayOf<HBUINT8>
|
||||
|
@ -658,7 +658,7 @@ struct ClassTable
|
|||
return_trace (c->check_struct (this) && classArray.sanitize (c));
|
||||
}
|
||||
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
|
||||
* firstGlyph). */
|
||||
public:
|
||||
|
@ -678,7 +678,7 @@ struct ObsoleteTypes
|
|||
const void *base,
|
||||
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>
|
||||
static unsigned int byteOffsetToIndex (unsigned int offset,
|
||||
|
|
|
@ -206,7 +206,7 @@ struct feat
|
|||
SortedUnsizedArrayOf<FeatureName>
|
||||
namesZ; /* The feature name array. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (24);
|
||||
DEFINE_SIZE_ARRAY (12, namesZ);
|
||||
};
|
||||
|
||||
} /* namespace AAT */
|
||||
|
|
|
@ -70,9 +70,9 @@ struct DecompositionAction
|
|||
|
||||
ActionSubrecordHeader
|
||||
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. */
|
||||
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. */
|
||||
HBUINT16 order; /* Numerical order in which this ligature will
|
||||
* be decomposed; you may want infrequent ligatures
|
||||
|
@ -100,7 +100,7 @@ struct UnconditionalAddGlyphAction
|
|||
protected:
|
||||
ActionSubrecordHeader
|
||||
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. */
|
||||
|
||||
public:
|
||||
|
@ -118,14 +118,14 @@ struct ConditionalAddGlyphAction
|
|||
protected:
|
||||
ActionSubrecordHeader
|
||||
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
|
||||
* 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
|
||||
* generally when a glyph is added, justification
|
||||
* 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
|
||||
* substThreshold. */
|
||||
public:
|
||||
|
@ -146,13 +146,13 @@ struct DuctileGlyphAction
|
|||
HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
|
||||
* This would normally be 0x64756374 ('duct'),
|
||||
* 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
|
||||
* 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
|
||||
* 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. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (22);
|
||||
|
@ -170,7 +170,7 @@ struct RepeatedAddGlyphAction
|
|||
ActionSubrecordHeader
|
||||
header;
|
||||
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. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
|
@ -271,14 +271,14 @@ struct JustWidthDeltaEntry
|
|||
};
|
||||
|
||||
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. */
|
||||
Fixed beforeShrinkLimit;
|
||||
HBFixed beforeShrinkLimit;
|
||||
/* The ratio by which the advance width of the
|
||||
* 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. */
|
||||
Fixed afterShrinkLimit;
|
||||
HBFixed afterShrinkLimit;
|
||||
/* The ratio by which the advance width of the glyph
|
||||
* is at most permitted to shrink on the right or
|
||||
* bottom side. */
|
||||
|
|
|
@ -82,8 +82,8 @@ struct KernPair
|
|||
}
|
||||
|
||||
protected:
|
||||
GlyphID left;
|
||||
GlyphID right;
|
||||
HBGlyphID left;
|
||||
HBGlyphID right;
|
||||
FWORD value;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
|
@ -392,7 +392,7 @@ struct KerxSubTableFormat2
|
|||
|
||||
const UnsizedArrayOf<FWORD> &arrayZ = this+array;
|
||||
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];
|
||||
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
||||
|
||||
|
@ -733,8 +733,8 @@ struct KerxSubTableHeader
|
|||
{
|
||||
typedef ExtendedTypes Types;
|
||||
|
||||
unsigned int tuple_count () const { return tupleCount; }
|
||||
bool is_horizontal () const { return !(coverage & Vertical); }
|
||||
unsigned tuple_count () const { return tupleCount; }
|
||||
bool is_horizontal () const { return !(coverage & Vertical); }
|
||||
|
||||
enum Coverage
|
||||
{
|
||||
|
|
|
@ -240,21 +240,21 @@ struct ContextualSubtable
|
|||
if (buffer->idx == buffer->len && !mark_set)
|
||||
return;
|
||||
|
||||
const GlyphID *replacement;
|
||||
const HBGlyphID *replacement;
|
||||
|
||||
replacement = nullptr;
|
||||
if (Types::extended)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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)];
|
||||
if (!replacement->sanitize (&c->sanitizer) || !*replacement)
|
||||
replacement = nullptr;
|
||||
|
@ -272,14 +272,14 @@ struct ContextualSubtable
|
|||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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)];
|
||||
if (!replacement->sanitize (&c->sanitizer) || !*replacement)
|
||||
replacement = nullptr;
|
||||
|
@ -304,7 +304,7 @@ struct ContextualSubtable
|
|||
bool mark_set;
|
||||
unsigned int mark;
|
||||
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
|
||||
|
@ -348,7 +348,7 @@ struct ContextualSubtable
|
|||
protected:
|
||||
StateTable<Types, EntryData>
|
||||
machine;
|
||||
NNOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false>, HBUINT>
|
||||
NNOffsetTo<UnsizedOffsetListOf<Lookup<HBGlyphID>, HBUINT, false>, HBUINT>
|
||||
substitutionTables;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (20);
|
||||
|
@ -520,7 +520,7 @@ struct LigatureSubtable
|
|||
if (action & (LigActionStore | LigActionLast))
|
||||
{
|
||||
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;
|
||||
hb_codepoint_t lig = ligatureData;
|
||||
|
||||
|
@ -554,7 +554,7 @@ struct LigatureSubtable
|
|||
const LigatureSubtable *table;
|
||||
const UnsizedArrayOf<HBUINT32> &ligAction;
|
||||
const UnsizedArrayOf<HBUINT16> &component;
|
||||
const UnsizedArrayOf<GlyphID> &ligature;
|
||||
const UnsizedArrayOf<HBGlyphID> &ligature;
|
||||
unsigned int match_length;
|
||||
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
|
||||
};
|
||||
|
@ -586,7 +586,7 @@ struct LigatureSubtable
|
|||
ligAction; /* Offset to the ligature action table. */
|
||||
NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT>
|
||||
component; /* Offset to the component table. */
|
||||
NNOffsetTo<UnsizedArrayOf<GlyphID>, HBUINT>
|
||||
NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT>
|
||||
ligature; /* Offset to the actual ligature lists. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (28);
|
||||
|
@ -606,7 +606,7 @@ struct NoncontextualSubtable
|
|||
unsigned int count = c->buffer->len;
|
||||
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)
|
||||
{
|
||||
info[i].codepoint = *replacement;
|
||||
|
@ -624,7 +624,7 @@ struct NoncontextualSubtable
|
|||
}
|
||||
|
||||
protected:
|
||||
Lookup<GlyphID> substitute;
|
||||
Lookup<HBGlyphID> substitute;
|
||||
public:
|
||||
DEFINE_SIZE_MIN (2);
|
||||
};
|
||||
|
@ -726,7 +726,7 @@ struct InsertionSubtable
|
|||
{
|
||||
unsigned int count = (flags & MarkedInsertCount);
|
||||
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;
|
||||
|
||||
bool before = flags & MarkedInsertBefore;
|
||||
|
@ -754,7 +754,7 @@ struct InsertionSubtable
|
|||
{
|
||||
unsigned int count = (flags & CurrentInsertCount) >> 5;
|
||||
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;
|
||||
|
||||
bool before = flags & CurrentInsertBefore;
|
||||
|
@ -793,7 +793,7 @@ struct InsertionSubtable
|
|||
private:
|
||||
hb_aat_apply_context_t *c;
|
||||
unsigned int mark;
|
||||
const UnsizedArrayOf<GlyphID> &insertionAction;
|
||||
const UnsizedArrayOf<HBGlyphID> &insertionAction;
|
||||
};
|
||||
|
||||
bool apply (hb_aat_apply_context_t *c) const
|
||||
|
@ -819,7 +819,7 @@ struct InsertionSubtable
|
|||
protected:
|
||||
StateTable<Types, EntryData>
|
||||
machine;
|
||||
NNOffsetTo<UnsizedArrayOf<GlyphID>, HBUINT>
|
||||
NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT>
|
||||
insertionAction; /* Byte offset from stateHeader to the start of
|
||||
* the insertion glyph table. */
|
||||
public:
|
||||
|
@ -1080,10 +1080,10 @@ struct Chain
|
|||
* The 'mort'/'morx' Table
|
||||
*/
|
||||
|
||||
template <typename Types>
|
||||
template <typename Types, hb_tag_t TAG>
|
||||
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; }
|
||||
|
||||
|
@ -1143,14 +1143,8 @@ struct mortmorx
|
|||
DEFINE_SIZE_MIN (8);
|
||||
};
|
||||
|
||||
struct morx : mortmorx<ExtendedTypes>
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_AAT_TAG_morx;
|
||||
};
|
||||
struct mort : mortmorx<ObsoleteTypes>
|
||||
{
|
||||
static constexpr hb_tag_t tableTag = HB_AAT_TAG_mort;
|
||||
};
|
||||
struct morx : mortmorx<ExtendedTypes, HB_AAT_TAG_morx> {};
|
||||
struct mort : mortmorx<ObsoleteTypes, HB_AAT_TAG_mort> {};
|
||||
|
||||
|
||||
} /* namespace AAT */
|
||||
|
|
|
@ -62,7 +62,7 @@ struct TrackTableEntry
|
|||
}
|
||||
|
||||
protected:
|
||||
Fixed track; /* Track value for this record. */
|
||||
HBFixed track; /* Track value for this record. */
|
||||
NameID trackNameID; /* The 'name' table index for this track.
|
||||
* (a short word or phrase like "loose"
|
||||
* or "very tight") */
|
||||
|
@ -82,7 +82,7 @@ struct TrackData
|
|||
const void *base) const
|
||||
{
|
||||
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 s1 = size_table[idx + 1].to_float ();
|
||||
|
@ -120,7 +120,7 @@ struct TrackData
|
|||
if (!sizes) return 0.;
|
||||
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;
|
||||
for (size_index = 0; size_index < sizes - 1; size_index++)
|
||||
if (size_table[size_index].to_float () >= ptem)
|
||||
|
@ -141,7 +141,7 @@ struct TrackData
|
|||
protected:
|
||||
HBUINT16 nTracks; /* Number of separate tracks 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
|
||||
* Array[nSizes] of size values.. */
|
||||
UnsizedArrayOf<TrackTableEntry>
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "hb.hh"
|
||||
#include "hb-meta.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,
|
||||
|
@ -82,6 +83,7 @@ HB_FUNCOBJ (hb_bool);
|
|||
struct
|
||||
{
|
||||
private:
|
||||
|
||||
template <typename T> constexpr auto
|
||||
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
|
||||
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. */
|
||||
char buf[64];
|
||||
len = hb_min (ARRAY_LENGTH (buf) - 1, len);
|
||||
strncpy (buf, s, len);
|
||||
buf[len] = '\0';
|
||||
unsigned int v;
|
||||
const char *p = s;
|
||||
const char *end = p + len;
|
||||
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, base)))
|
||||
return false;
|
||||
|
||||
char *end;
|
||||
errno = 0;
|
||||
unsigned long v = strtoul (buf, &end, base);
|
||||
if (errno) return false;
|
||||
if (*end) return false;
|
||||
*out = v;
|
||||
return true;
|
||||
}
|
||||
|
@ -994,6 +991,18 @@ struct
|
|||
operator () (const T &a) const HB_AUTO_RETURN (-a)
|
||||
}
|
||||
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. */
|
||||
|
|
|
@ -50,7 +50,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
|||
template <typename U,
|
||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||
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) {}
|
||||
template <typename U,
|
||||
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. */
|
||||
int cmp (const hb_array_t<Type> &a) const
|
||||
int cmp (const hb_array_t &a) const
|
||||
{
|
||||
if (length != a.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_array_t<Type> *a = (hb_array_t<Type> *) pa;
|
||||
hb_array_t<Type> *b = (hb_array_t<Type> *) pb;
|
||||
hb_array_t *a = (hb_array_t *) pa;
|
||||
hb_array_t *b = (hb_array_t *) pb;
|
||||
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*))
|
||||
{
|
||||
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);
|
||||
}
|
||||
hb_sorted_array_t<Type> qsort ()
|
||||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
assert (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.
|
||||
*/
|
||||
|
||||
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)
|
||||
return *this;
|
||||
|
@ -176,11 +176,13 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
|||
count -= start_offset;
|
||||
if (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); }
|
||||
|
||||
hb_array_t truncate (unsigned length) const { return sub_array (0, length); }
|
||||
|
||||
template <typename T,
|
||||
unsigned P = sizeof (Type),
|
||||
hb_enable_if (P == 1)>
|
||||
|
@ -234,7 +236,7 @@ struct hb_sorted_array_t :
|
|||
hb_iter_t<hb_sorted_array_t<Type>, 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);
|
||||
static constexpr bool is_random_access_iterator = true;
|
||||
static constexpr bool is_sorted_iterator = true;
|
||||
|
@ -247,7 +249,7 @@ struct hb_sorted_array_t :
|
|||
template <typename U,
|
||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||
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) {}
|
||||
template <typename U,
|
||||
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
|
||||
{ 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
|
||||
{ return hb_sorted_array_t<Type> (((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 /* IN/OUT */) const
|
||||
{ return hb_sorted_array_t (((const hb_array_t<Type> *) (this))->sub_array (start_offset, seg_count)); }
|
||||
hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const
|
||||
{ return sub_array (start_offset, &seg_count); }
|
||||
|
||||
hb_sorted_array_t truncate (unsigned length) const { return sub_array (0, length); }
|
||||
|
||||
template <typename T>
|
||||
Type *bsearch (const T &x, Type *not_found = nullptr)
|
||||
{
|
||||
|
@ -277,8 +281,8 @@ struct hb_sorted_array_t :
|
|||
}
|
||||
template <typename T>
|
||||
bool bfind (const T &x, unsigned int *i = nullptr,
|
||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||
unsigned int to_store = (unsigned int) -1) const
|
||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||
unsigned int to_store = (unsigned int) -1) const
|
||||
{
|
||||
int min = 0, max = (int) this->length - 1;
|
||||
const Type *array = this->arrayZ;
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#endif /* HAVE_SYS_MMAN_H */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
|
|
|
@ -379,43 +379,24 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
static hb_bool_t
|
||||
parse_uint (const char *pp, const char *end, uint32_t *pv)
|
||||
static bool
|
||||
parse_int (const char *pp, const char *end, int32_t *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;
|
||||
uint32_t v;
|
||||
|
||||
errno = 0;
|
||||
v = strtol (p, &pend, 10);
|
||||
if (errno || p == pend || pend - p != end - pp)
|
||||
int v;
|
||||
const char *p = pp;
|
||||
if (unlikely (!hb_parse_int (&p, end, &v, true/* whole buffer */)))
|
||||
return false;
|
||||
|
||||
*pv = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
parse_int (const char *pp, const char *end, int32_t *pv)
|
||||
static bool
|
||||
parse_uint (const char *pp, const char *end, uint32_t *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;
|
||||
int32_t v;
|
||||
|
||||
errno = 0;
|
||||
v = strtol (p, &pend, 10);
|
||||
if (errno || p == pend || pend - p != end - pp)
|
||||
unsigned int v;
|
||||
const char *p = pp;
|
||||
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */)))
|
||||
return false;
|
||||
|
||||
*pv = v;
|
||||
|
|
|
@ -324,7 +324,8 @@ hb_buffer_t::clear_positions ()
|
|||
out_len = 0;
|
||||
out_info = info;
|
||||
|
||||
memset (pos, 0, sizeof (pos[0]) * len);
|
||||
if (likely (len))
|
||||
memset (pos, 0, sizeof (pos[0]) * len);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -408,8 +408,7 @@ struct hb_buffer_t
|
|||
}
|
||||
}
|
||||
|
||||
void unsafe_to_break_all ()
|
||||
{ unsafe_to_break_impl (0, len); }
|
||||
void unsafe_to_break_all () { unsafe_to_break_impl (0, len); }
|
||||
void safe_to_break_all ()
|
||||
{
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
|
|
|
@ -94,130 +94,52 @@ struct dict_opset_t : opset_t<number_t>
|
|||
}
|
||||
}
|
||||
|
||||
/* Turns CFF's BCD format into strtod understandable string */
|
||||
static double parse_bcd (byte_str_ref_t& str_ref)
|
||||
{
|
||||
bool neg = false;
|
||||
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 */
|
||||
if (unlikely (str_ref.in_error ())) return .0;
|
||||
|
||||
double value = 0.0;
|
||||
enum Nibble { DECIMAL=10, EXP_POS, EXP_NEG, RESERVED, NEG, END };
|
||||
|
||||
char buf[32];
|
||||
unsigned char byte = 0;
|
||||
for (uint32_t i = 0;; i++)
|
||||
for (unsigned i = 0, count = 0; count < ARRAY_LENGTH (buf); ++i, ++count)
|
||||
{
|
||||
char d;
|
||||
if ((i & 1) == 0)
|
||||
unsigned nibble;
|
||||
if (!(i & 1))
|
||||
{
|
||||
if (!str_ref.avail ())
|
||||
{
|
||||
str_ref.set_error ();
|
||||
return 0.0;
|
||||
}
|
||||
if (unlikely (!str_ref.avail ())) break;
|
||||
|
||||
byte = str_ref[0];
|
||||
str_ref.inc ();
|
||||
d = byte >> 4;
|
||||
nibble = byte >> 4;
|
||||
}
|
||||
else
|
||||
d = byte & 0x0F;
|
||||
nibble = byte & 0x0F;
|
||||
|
||||
switch (d)
|
||||
if (unlikely (nibble == RESERVED)) break;
|
||||
else if (nibble == END)
|
||||
{
|
||||
case RESERVED:
|
||||
str_ref.set_error ();
|
||||
return value;
|
||||
|
||||
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;
|
||||
const char *p = buf;
|
||||
double pv;
|
||||
if (unlikely (!hb_parse_double (&p, p + count, &pv, true/* whole buffer */)))
|
||||
break;
|
||||
|
||||
case DECIMAL:
|
||||
if (part != INT_PART)
|
||||
{
|
||||
str_ref.set_error ();
|
||||
return value;
|
||||
}
|
||||
part = FRAC_PART;
|
||||
break;
|
||||
|
||||
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 pv;
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[count] = "0123456789.EE?-?"[nibble];
|
||||
if (nibble == EXP_NEG)
|
||||
{
|
||||
++count;
|
||||
if (unlikely (count == ARRAY_LENGTH (buf))) break;
|
||||
buf[count] = '-';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return value;
|
||||
str_ref.set_error ();
|
||||
return .0;
|
||||
}
|
||||
|
||||
static bool is_hint_op (op_code_t op)
|
||||
|
|
136
src/hb-common.cc
136
src/hb-common.cc
|
@ -27,13 +27,9 @@
|
|||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#include "hb-machinery.hh"
|
||||
|
||||
#include <locale.h>
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
|
||||
#ifdef HB_NO_SETLOCALE
|
||||
#define setlocale(Category, Locale) "C"
|
||||
|
@ -385,7 +381,8 @@ hb_language_from_string (const char *str, int len)
|
|||
const char *
|
||||
hb_language_to_string (hb_language_t language)
|
||||
{
|
||||
/* This is actually nullptr-safe! */
|
||||
if (unlikely (!language)) return nullptr;
|
||||
|
||||
return language->s;
|
||||
}
|
||||
|
||||
|
@ -722,131 +719,24 @@ parse_char (const char **pp, const char *end, char c)
|
|||
static bool
|
||||
parse_uint (const char **pp, const char *end, unsigned int *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;
|
||||
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;
|
||||
/* Intentionally use hb_parse_int inside instead of hb_parse_uint,
|
||||
* such that -1 turns into "big number"... */
|
||||
int v;
|
||||
if (unlikely (!hb_parse_int (pp, end, &v))) return false;
|
||||
|
||||
*pv = v;
|
||||
*pp += pend - p;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
parse_uint32 (const char **pp, const char *end, uint32_t *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;
|
||||
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;
|
||||
/* Intentionally use hb_parse_int inside instead of hb_parse_uint,
|
||||
* such that -1 turns into "big number"... */
|
||||
int v;
|
||||
if (unlikely (!hb_parse_int (pp, end, &v))) return false;
|
||||
|
||||
*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;
|
||||
}
|
||||
|
||||
|
@ -1099,7 +989,11 @@ static bool
|
|||
parse_variation_value (const char **pp, const char *end, hb_variation_t *variation)
|
||||
{
|
||||
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
|
||||
|
|
|
@ -63,6 +63,8 @@ typedef __int32 int32_t;
|
|||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#elif defined (__KERNEL__)
|
||||
# include <linux/types.h>
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#define HB_NO_BITMAP
|
||||
#define HB_NO_CFF
|
||||
#define HB_NO_COLOR
|
||||
#define HB_NO_ERRNO
|
||||
#define HB_NO_FACE_COLLECT_UNICODES
|
||||
#define HB_NO_GETENV
|
||||
#define HB_NO_HINTING
|
||||
|
|
|
@ -302,7 +302,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
|
|||
if (unlikely (!face_data)) return nullptr;
|
||||
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);
|
||||
|
||||
if (unlikely (!ct_font))
|
||||
|
@ -327,7 +327,7 @@ retry:
|
|||
const hb_coretext_font_data_t *data = font->data.coretext;
|
||||
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
|
||||
* Note that evaluating condition above can be dangerous if another thread
|
||||
|
|
|
@ -625,7 +625,7 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
|||
HB_STMT_START { \
|
||||
DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
|
||||
return false; \
|
||||
} HB_STMT_END;
|
||||
} HB_STMT_END
|
||||
|
||||
if (FAILED (hr))
|
||||
FAIL ("Analyzer failed to generate results.");
|
||||
|
|
|
@ -367,6 +367,9 @@ hb_blob_t *
|
|||
hb_face_reference_table (const hb_face_t *face,
|
||||
hb_tag_t tag)
|
||||
{
|
||||
if (unlikely (tag == HB_TAG_NONE))
|
||||
return hb_blob_get_empty ();
|
||||
|
||||
return face->reference_table (tag);
|
||||
}
|
||||
|
||||
|
|
|
@ -649,8 +649,8 @@ hb_font_set_funcs (hb_font_t *font,
|
|||
/* Be *very* careful with this function! */
|
||||
HB_EXTERN void
|
||||
hb_font_set_funcs_data (hb_font_t *font,
|
||||
void *font_data,
|
||||
hb_destroy_func_t destroy);
|
||||
void *font_data,
|
||||
hb_destroy_func_t destroy);
|
||||
|
||||
|
||||
HB_EXTERN void
|
||||
|
|
|
@ -216,7 +216,7 @@ struct hb_font_t
|
|||
}
|
||||
|
||||
hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph)
|
||||
hb_codepoint_t *glyph)
|
||||
{
|
||||
*glyph = 0;
|
||||
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_position_t *x, hb_position_t *y)
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
*x = *y = 0;
|
||||
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_glyph_extents_t *extents)
|
||||
hb_glyph_extents_t *extents)
|
||||
{
|
||||
memset (extents, 0, sizeof (*extents));
|
||||
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,
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
hb_position_t origin_x, origin_y;
|
||||
|
||||
|
|
|
@ -840,8 +840,8 @@ hb_ft_font_set_funcs (hb_font_t *font)
|
|||
return;
|
||||
}
|
||||
|
||||
if (FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE))
|
||||
FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL);
|
||||
if (FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL))
|
||||
FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
|
||||
|
||||
FT_Set_Char_Size (ft_face,
|
||||
abs (font->x_scale), abs (font->y_scale),
|
||||
|
@ -866,7 +866,7 @@ hb_ft_font_set_funcs (hb_font_t *font)
|
|||
if (ft_coords)
|
||||
{
|
||||
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);
|
||||
free (ft_coords);
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ fail:
|
|||
|
||||
/**
|
||||
* hb_gdi_face_create:
|
||||
* @hdc: a HFONT object.
|
||||
* @hfont: a HFONT object.
|
||||
*
|
||||
* Return value: #hb_face_t object corresponding to the given input
|
||||
*
|
||||
|
|
|
@ -41,6 +41,12 @@
|
|||
#include <unicode/utf16.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
|
||||
|
@ -51,10 +57,6 @@
|
|||
* 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_icu_script_to_script (UScriptCode script)
|
||||
{
|
||||
|
@ -188,9 +190,9 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||
|
||||
len = 0;
|
||||
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;
|
||||
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;
|
||||
|
||||
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))
|
||||
return false;
|
||||
if (u_countChar32 (normalized, len) == 1) {
|
||||
HB_ICU_STMT (U16_GET_UNSAFE (normalized, 0, *ab));
|
||||
U16_GET_UNSAFE (normalized, 0, *ab);
|
||||
ret = true;
|
||||
} else {
|
||||
ret = false;
|
||||
|
@ -226,13 +228,13 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||
|
||||
len = u_countChar32 (decomposed, len);
|
||||
if (len == 1) {
|
||||
HB_ICU_STMT (U16_GET_UNSAFE (decomposed, 0, *a));
|
||||
U16_GET_UNSAFE (decomposed, 0, *a);
|
||||
*b = 0;
|
||||
return *a != ab;
|
||||
} else if (len == 2) {
|
||||
len =0;
|
||||
HB_ICU_STMT (U16_NEXT_UNSAFE (decomposed, len, *a));
|
||||
HB_ICU_STMT (U16_NEXT_UNSAFE (decomposed, len, *b));
|
||||
len = 0;
|
||||
U16_NEXT_UNSAFE (decomposed, len, *a);
|
||||
U16_NEXT_UNSAFE (decomposed, len, *b);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -252,7 +254,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||
|
||||
len = 0;
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
if (len == 1) {
|
||||
HB_ICU_STMT (U16_GET_UNSAFE (normalized, 0, *a));
|
||||
U16_GET_UNSAFE (normalized, 0, *a);
|
||||
*b = 0;
|
||||
ret = *a != ab;
|
||||
} else if (len == 2) {
|
||||
len =0;
|
||||
HB_ICU_STMT (U16_NEXT_UNSAFE (normalized, len, *a));
|
||||
HB_ICU_STMT (U16_NEXT_UNSAFE (normalized, len, *b));
|
||||
len = 0;
|
||||
U16_NEXT_UNSAFE (normalized, len, *a);
|
||||
U16_NEXT_UNSAFE (normalized, len, *b);
|
||||
|
||||
/* Here's the ugly part: if ab decomposes to a single character and
|
||||
* 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))
|
||||
return false;
|
||||
hb_codepoint_t c;
|
||||
HB_ICU_STMT (U16_GET_UNSAFE (recomposed, 0, c));
|
||||
U16_GET_UNSAFE (recomposed, 0, c);
|
||||
if (c != *a && c != ab) {
|
||||
*a = c;
|
||||
*b = 0;
|
||||
|
@ -289,7 +291,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||
} else {
|
||||
/* If decomposed to more than two characters, take the last one,
|
||||
* 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];
|
||||
icu_err = U_ZERO_ERROR;
|
||||
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. */
|
||||
if (unlikely (u_countChar32 (recomposed, len) != 1))
|
||||
return false;
|
||||
HB_ICU_STMT (U16_GET_UNSAFE (recomposed, 0, *a));
|
||||
U16_GET_UNSAFE (recomposed, 0, *a);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
|
@ -354,5 +356,8 @@ hb_icu_get_unicode_funcs ()
|
|||
return static_icu_funcs.get_unconst ();
|
||||
}
|
||||
|
||||
#ifdef HB_ICU_EXTRA_SEMI_IGNORED
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
153
src/hb-iter.hh
153
src/hb-iter.hh
|
@ -64,7 +64,7 @@ template <typename iter_t, typename Item = typename iter_t::__item_t__>
|
|||
struct hb_iter_t
|
||||
{
|
||||
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_random_access_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 Name::begin; \
|
||||
using Name::end; \
|
||||
using Name::item_size; \
|
||||
using Name::get_item_size; \
|
||||
using Name::is_iterator; \
|
||||
using Name::iter; \
|
||||
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_sorted_array_t;
|
||||
|
||||
struct
|
||||
{
|
||||
|
@ -175,6 +176,14 @@ struct
|
|||
|
||||
}
|
||||
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. */
|
||||
template <typename iter_t, typename item_t = typename iter_t::__item_t__>
|
||||
|
@ -563,7 +572,7 @@ struct hb_zip_iter_t :
|
|||
B b;
|
||||
};
|
||||
struct
|
||||
{
|
||||
{ HB_PARTIALIZE(2);
|
||||
template <typename A, typename B,
|
||||
hb_requires (hb_is_iterable (A) && hb_is_iterable (B))>
|
||||
hb_zip_iter_t<hb_iter_type<A>, hb_iter_type<B>>
|
||||
|
@ -602,18 +611,18 @@ struct
|
|||
}
|
||||
HB_FUNCOBJ (hb_apply);
|
||||
|
||||
/* hb_iota()/hb_range() */
|
||||
/* hb_range()/hb_iota()/hb_repeat() */
|
||||
|
||||
template <typename T, typename S>
|
||||
struct hb_counter_iter_t :
|
||||
hb_iter_t<hb_counter_iter_t<T, S>, T>
|
||||
struct hb_range_iter_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__;
|
||||
static constexpr bool is_random_access_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; }
|
||||
bool __more__ () const { return v != end_; }
|
||||
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 __prev__ () { v -= step; }
|
||||
void __rewind__ (unsigned n) { v -= n * step; }
|
||||
hb_counter_iter_t __end__ () const { return hb_counter_iter_t (end_, end_, step); }
|
||||
bool operator != (const hb_counter_iter_t& o) const
|
||||
hb_range_iter_t __end__ () const { return hb_range_iter_t (end_, end_, step); }
|
||||
bool operator != (const hb_range_iter_t& o) const
|
||||
{ return v != o.v; }
|
||||
|
||||
private:
|
||||
|
@ -644,24 +653,91 @@ struct hb_counter_iter_t :
|
|||
};
|
||||
struct
|
||||
{
|
||||
template <typename T = unsigned, typename S = unsigned> hb_counter_iter_t<T, S>
|
||||
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>
|
||||
template <typename T = unsigned> hb_range_iter_t<T, unsigned>
|
||||
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>
|
||||
operator () (T start, T end, S&& step = 1u) const
|
||||
{ return hb_counter_iter_t<T, S> (start, end, step); }
|
||||
template <typename T, typename S = unsigned> hb_range_iter_t<T, S>
|
||||
operator () (T start, T end, S step = 1u) const
|
||||
{ return hb_range_iter_t<T, S> (start, end, step); }
|
||||
}
|
||||
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
|
||||
{
|
||||
|
@ -673,6 +749,37 @@ struct
|
|||
}
|
||||
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() */
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ static inline Type& StructAfter(TObject &X)
|
|||
|
||||
#define DEFINE_SIZE_ARRAY(size, array) \
|
||||
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 min_size = (size)
|
||||
|
||||
|
|
|
@ -0,0 +1,240 @@
|
|||
|
||||
#line 1 "hb-number-parser.rl"
|
||||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_NUMBER_PARSER_HH
|
||||
#define HB_NUMBER_PARSER_HH
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
|
||||
#line 37 "hb-number-parser.hh"
|
||||
static const unsigned char _double_parser_trans_keys[] = {
|
||||
0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
|
||||
46u, 101u, 0
|
||||
};
|
||||
|
||||
static const char _double_parser_key_spans[] = {
|
||||
0, 15, 12, 10, 15, 10, 54, 10,
|
||||
56
|
||||
};
|
||||
|
||||
static const unsigned char _double_parser_index_offsets[] = {
|
||||
0, 0, 16, 29, 40, 56, 67, 122,
|
||||
133
|
||||
};
|
||||
|
||||
static const char _double_parser_indicies[] = {
|
||||
0, 1, 2, 3, 1, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
1, 3, 1, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 1, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
1, 6, 1, 7, 1, 1, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
1, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 1, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 9, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 9, 1, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 1, 3, 1,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 9, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 9, 1, 0
|
||||
};
|
||||
|
||||
static const char _double_parser_trans_targs[] = {
|
||||
2, 0, 2, 3, 8, 6, 5, 5,
|
||||
7, 4
|
||||
};
|
||||
|
||||
static const char _double_parser_trans_actions[] = {
|
||||
0, 0, 1, 0, 2, 3, 0, 4,
|
||||
5, 0
|
||||
};
|
||||
|
||||
static const int double_parser_start = 1;
|
||||
static const int double_parser_first_final = 6;
|
||||
static const int double_parser_error = 0;
|
||||
|
||||
static const int double_parser_en_main = 1;
|
||||
|
||||
|
||||
#line 70 "hb-number-parser.rl"
|
||||
|
||||
|
||||
/* Works only for n < 512 */
|
||||
static inline double
|
||||
_pow10 (unsigned int exponent)
|
||||
{
|
||||
static const double _powers_of_10[] =
|
||||
{
|
||||
1.0e+256,
|
||||
1.0e+128,
|
||||
1.0e+64,
|
||||
1.0e+32,
|
||||
1.0e+16,
|
||||
1.0e+8,
|
||||
10000.,
|
||||
100.,
|
||||
10.
|
||||
};
|
||||
unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
|
||||
double result = 1;
|
||||
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
|
||||
if (exponent & mask) result *= *power;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline double
|
||||
strtod_rl (const char *buf, char **end_ptr)
|
||||
{
|
||||
const char *p, *pe;
|
||||
double value = 0;
|
||||
double frac = 0;
|
||||
double frac_count = 0;
|
||||
unsigned int exp = 0;
|
||||
bool neg = false, exp_neg = false, exp_overflow = false;
|
||||
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
||||
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||
p = buf;
|
||||
pe = p + strlen (p);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
|
||||
int cs;
|
||||
|
||||
#line 142 "hb-number-parser.hh"
|
||||
{
|
||||
cs = double_parser_start;
|
||||
}
|
||||
|
||||
#line 147 "hb-number-parser.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
_resume:
|
||||
_keys = _double_parser_trans_keys + (cs<<1);
|
||||
_inds = _double_parser_indicies + _double_parser_index_offsets[cs];
|
||||
|
||||
_slen = _double_parser_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
|
||||
(*p) <= _keys[1] ?
|
||||
(*p) - _keys[0] : _slen ];
|
||||
|
||||
cs = _double_parser_trans_targs[_trans];
|
||||
|
||||
if ( _double_parser_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _double_parser_trans_actions[_trans] ) {
|
||||
case 1:
|
||||
#line 39 "hb-number-parser.rl"
|
||||
{ neg = true; }
|
||||
break;
|
||||
case 4:
|
||||
#line 40 "hb-number-parser.rl"
|
||||
{ exp_neg = true; }
|
||||
break;
|
||||
case 2:
|
||||
#line 42 "hb-number-parser.rl"
|
||||
{
|
||||
value = value * 10. + ((*p) - '0');
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
#line 45 "hb-number-parser.rl"
|
||||
{
|
||||
if (likely (frac <= MAX_FRACT / 10))
|
||||
{
|
||||
frac = frac * 10. + ((*p) - '0');
|
||||
++frac_count;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 52 "hb-number-parser.rl"
|
||||
{
|
||||
if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
|
||||
exp = exp * 10 + ((*p) - '0');
|
||||
else
|
||||
exp_overflow = true;
|
||||
}
|
||||
break;
|
||||
#line 205 "hb-number-parser.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
_out: {}
|
||||
}
|
||||
|
||||
#line 116 "hb-number-parser.rl"
|
||||
|
||||
|
||||
*end_ptr = (char *) p;
|
||||
|
||||
if (frac_count) value += frac / _pow10 (frac_count);
|
||||
if (neg) value *= -1.;
|
||||
|
||||
if (unlikely (exp_overflow))
|
||||
{
|
||||
if (value == 0) return value;
|
||||
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
|
||||
else return neg ? -DBL_MAX : DBL_MAX;
|
||||
}
|
||||
|
||||
if (exp)
|
||||
{
|
||||
if (exp_neg) value /= _pow10 (exp);
|
||||
else value *= _pow10 (exp);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif /* HB_NUMBER_PARSER_HH */
|
|
@ -0,0 +1,139 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_NUMBER_PARSER_HH
|
||||
#define HB_NUMBER_PARSER_HH
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
%%{
|
||||
|
||||
machine double_parser;
|
||||
alphtype unsigned char;
|
||||
write data;
|
||||
|
||||
action see_neg { neg = true; }
|
||||
action see_exp_neg { exp_neg = true; }
|
||||
|
||||
action add_int {
|
||||
value = value * 10. + (fc - '0');
|
||||
}
|
||||
action add_frac {
|
||||
if (likely (frac <= MAX_FRACT / 10))
|
||||
{
|
||||
frac = frac * 10. + (fc - '0');
|
||||
++frac_count;
|
||||
}
|
||||
}
|
||||
action add_exp {
|
||||
if (likely (exp * 10 + (fc - '0') <= MAX_EXP))
|
||||
exp = exp * 10 + (fc - '0');
|
||||
else
|
||||
exp_overflow = true;
|
||||
}
|
||||
|
||||
num = [0-9]+;
|
||||
|
||||
main := (
|
||||
(
|
||||
(('+'|'-'@see_neg)? num @add_int) ('.' num @add_frac)?
|
||||
|
|
||||
(('+'|'-'@see_neg)? '.' num @add_frac)
|
||||
)
|
||||
(('e'|'E') (('+'|'-'@see_exp_neg)? num @add_exp))?
|
||||
);
|
||||
|
||||
}%%
|
||||
|
||||
/* Works only for n < 512 */
|
||||
static inline double
|
||||
_pow10 (unsigned int exponent)
|
||||
{
|
||||
static const double _powers_of_10[] =
|
||||
{
|
||||
1.0e+256,
|
||||
1.0e+128,
|
||||
1.0e+64,
|
||||
1.0e+32,
|
||||
1.0e+16,
|
||||
1.0e+8,
|
||||
10000.,
|
||||
100.,
|
||||
10.
|
||||
};
|
||||
unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
|
||||
double result = 1;
|
||||
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
|
||||
if (exponent & mask) result *= *power;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline double
|
||||
strtod_rl (const char *buf, char **end_ptr)
|
||||
{
|
||||
const char *p, *pe;
|
||||
double value = 0;
|
||||
double frac = 0;
|
||||
double frac_count = 0;
|
||||
unsigned int exp = 0;
|
||||
bool neg = false, exp_neg = false, exp_overflow = false;
|
||||
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
||||
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||
p = buf;
|
||||
pe = p + strlen (p);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
|
||||
int cs;
|
||||
%%{
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
*end_ptr = (char *) p;
|
||||
|
||||
if (frac_count) value += frac / _pow10 (frac_count);
|
||||
if (neg) value *= -1.;
|
||||
|
||||
if (unlikely (exp_overflow))
|
||||
{
|
||||
if (value == 0) return value;
|
||||
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
|
||||
else return neg ? -DBL_MAX : DBL_MAX;
|
||||
}
|
||||
|
||||
if (exp)
|
||||
{
|
||||
if (exp_neg) value /= _pow10 (exp);
|
||||
else value *= _pow10 (exp);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif /* HB_NUMBER_PARSER_HH */
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
#include "hb-machinery.hh"
|
||||
#include "hb-number-parser.hh"
|
||||
|
||||
#include <locale.h>
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
|
||||
template<typename T, typename Func>
|
||||
static bool
|
||||
_parse_number (const char **pp, const char *end, T *pv,
|
||||
bool whole_buffer, Func f)
|
||||
{
|
||||
char buf[32];
|
||||
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1,
|
||||
(unsigned int) (end - *pp));
|
||||
strncpy (buf, *pp, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
char *p = buf;
|
||||
char *pend = p;
|
||||
|
||||
errno = 0;
|
||||
*pv = f (p, &pend);
|
||||
if (unlikely (errno || p == pend ||
|
||||
/* Check if consumed whole buffer if is requested */
|
||||
(whole_buffer && pend - p != end - *pp))) return false;
|
||||
|
||||
*pp += pend - p;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
hb_parse_int (const char **pp, const char *end, int *pv, bool whole_buffer)
|
||||
{
|
||||
return _parse_number<int> (pp, end, pv, whole_buffer,
|
||||
[] (const char *p, char **end)
|
||||
{ return strtol (p, end, 10); });
|
||||
}
|
||||
|
||||
bool
|
||||
hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
|
||||
bool whole_buffer, int base)
|
||||
{
|
||||
return _parse_number<unsigned int> (pp, end, pv, whole_buffer,
|
||||
[base] (const char *p, char **end)
|
||||
{ return strtoul (p, end, base); });
|
||||
}
|
||||
|
||||
|
||||
#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
|
||||
#define USE_XLOCALE 1
|
||||
#define HB_LOCALE_T locale_t
|
||||
#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
|
||||
#define HB_FREE_LOCALE(loc) freelocale (loc)
|
||||
#elif defined(_MSC_VER)
|
||||
#define USE_XLOCALE 1
|
||||
#define HB_LOCALE_T _locale_t
|
||||
#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
|
||||
#define HB_FREE_LOCALE(loc) _free_locale (loc)
|
||||
#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
|
||||
#endif
|
||||
|
||||
#ifdef USE_XLOCALE
|
||||
|
||||
#if HB_USE_ATEXIT
|
||||
static void free_static_C_locale ();
|
||||
#endif
|
||||
|
||||
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
|
||||
hb_C_locale_lazy_loader_t>
|
||||
{
|
||||
static HB_LOCALE_T create ()
|
||||
{
|
||||
HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
|
||||
|
||||
#if HB_USE_ATEXIT
|
||||
atexit (free_static_C_locale);
|
||||
#endif
|
||||
|
||||
return C_locale;
|
||||
}
|
||||
static void destroy (HB_LOCALE_T p)
|
||||
{
|
||||
HB_FREE_LOCALE (p);
|
||||
}
|
||||
static HB_LOCALE_T get_null ()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
} static_C_locale;
|
||||
|
||||
#if HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_C_locale ()
|
||||
{
|
||||
static_C_locale.free_instance ();
|
||||
}
|
||||
#endif
|
||||
|
||||
static HB_LOCALE_T
|
||||
get_C_locale ()
|
||||
{
|
||||
return static_C_locale.get_unconst ();
|
||||
}
|
||||
#endif /* USE_XLOCALE */
|
||||
|
||||
bool
|
||||
hb_parse_double (const char **pp, const char *end, double *pv,
|
||||
bool whole_buffer)
|
||||
{
|
||||
return _parse_number<double> (pp, end, pv, whole_buffer,
|
||||
[] (const char *p, char **end)
|
||||
{
|
||||
#ifdef USE_XLOCALE
|
||||
return strtod_l (p, end, get_C_locale ());
|
||||
#else
|
||||
return strtod_rl (p, end);
|
||||
#endif
|
||||
});
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_NUMBER_HH
|
||||
#define HB_NUMBER_HH
|
||||
|
||||
HB_INTERNAL bool
|
||||
hb_parse_int (const char **pp, const char *end, int *pv,
|
||||
bool whole_buffer = false);
|
||||
|
||||
HB_INTERNAL bool
|
||||
hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
|
||||
bool whole_buffer = false, int base = 10);
|
||||
|
||||
HB_INTERNAL bool
|
||||
hb_parse_double (const char **pp, const char *end, double *pv,
|
||||
bool whole_buffer = false);
|
||||
|
||||
#endif /* HB_NUMBER_HH */
|
|
@ -287,7 +287,7 @@ struct ResourceRecord
|
|||
{ return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c,
|
||||
const void *data_base) const
|
||||
const void *data_base) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
|
|
|
@ -124,9 +124,9 @@ struct F2DOT14 : HBINT16
|
|||
};
|
||||
|
||||
/* 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
|
||||
float to_float () const { return ((int32_t) v) / 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) */
|
||||
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 */
|
||||
|
@ -264,8 +264,8 @@ struct _hb_has_null
|
|||
template <typename Type>
|
||||
struct _hb_has_null<Type, true>
|
||||
{
|
||||
static const Type *get_null () { return &Null(Type); }
|
||||
static Type *get_crap () { return &Crap(Type); }
|
||||
static const Type *get_null () { return &Null (Type); }
|
||||
static Type *get_crap () { return &Crap (Type); }
|
||||
};
|
||||
|
||||
template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
|
||||
|
@ -423,7 +423,7 @@ struct UnsizedArrayOf
|
|||
{ return hb_array (arrayZ, len); }
|
||||
hb_array_t<const Type> as_array (unsigned int len) const
|
||||
{ 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 (); }
|
||||
|
||||
template <typename T>
|
||||
|
@ -483,7 +483,7 @@ struct UnsizedArrayOf
|
|||
}
|
||||
|
||||
public:
|
||||
Type arrayZ[VAR];
|
||||
Type arrayZ[HB_VAR_ARRAY];
|
||||
public:
|
||||
DEFINE_SIZE_UNBOUNDED (0);
|
||||
};
|
||||
|
@ -669,7 +669,7 @@ struct ArrayOf
|
|||
|
||||
public:
|
||||
LenType len;
|
||||
Type arrayZ[VAR];
|
||||
Type arrayZ[HB_VAR_ARRAY];
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
||||
};
|
||||
|
@ -802,7 +802,7 @@ struct HeadlessArrayOf
|
|||
|
||||
public:
|
||||
LenType lenP1;
|
||||
Type arrayZ[VAR];
|
||||
Type arrayZ[HB_VAR_ARRAY];
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
||||
};
|
||||
|
@ -850,7 +850,7 @@ struct ArrayOfM1
|
|||
|
||||
public:
|
||||
LenType lenM1;
|
||||
Type arrayZ[VAR];
|
||||
Type arrayZ[HB_VAR_ARRAY];
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
|
||||
};
|
||||
|
@ -902,8 +902,8 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
|
|||
{ return *as_array ().bsearch (x, ¬_found); }
|
||||
template <typename T>
|
||||
bool bfind (const T &x, unsigned int *i = nullptr,
|
||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||
unsigned int to_store = (unsigned int) -1) const
|
||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||
unsigned int to_store = (unsigned int) -1) const
|
||||
{ return as_array ().bfind (x, i, not_found, to_store); }
|
||||
};
|
||||
|
||||
|
|
|
@ -237,8 +237,8 @@ struct CFFIndex
|
|||
public:
|
||||
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 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
|
||||
/* HBUINT8 data[VAR]; Object data */
|
||||
HBUINT8 offsets[HB_VAR_ARRAY]; /* The array of (count + 1) offsets into objects array (1-base). */
|
||||
/* HBUINT8 data[HB_VAR_ARRAY]; Object data */
|
||||
public:
|
||||
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
|
||||
{ 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>
|
||||
|
@ -564,13 +564,13 @@ struct FDSelect3_4
|
|||
if (glyph < ranges[i].first)
|
||||
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 () const { return ranges.len; }
|
||||
GID_TYPE &sentinel () { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
|
||||
const GID_TYPE &sentinel () const { return StructAfter<GID_TYPE> (ranges[nRanges () - 1]); }
|
||||
GID_TYPE &nRanges () { return ranges.len; }
|
||||
GID_TYPE nRanges () const { return ranges.len; }
|
||||
GID_TYPE &sentinel () { 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;
|
||||
/* GID_TYPE sentinel */
|
||||
|
@ -608,8 +608,8 @@ struct FDSelect
|
|||
|
||||
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (this == &Null (FDSelect))
|
||||
return 0;
|
||||
if (this == &Null (FDSelect)) return 0;
|
||||
|
||||
switch (format)
|
||||
{
|
||||
case 0: return u.format0.get_fd (glyph);
|
||||
|
|
|
@ -203,8 +203,7 @@ struct bounds_t
|
|||
}
|
||||
}
|
||||
|
||||
bool empty () const
|
||||
{ return (min.x >= max.x) || (min.y >= max.y); }
|
||||
bool empty () const { return (min.x >= max.x) || (min.y >= max.y); }
|
||||
|
||||
point_t min;
|
||||
point_t max;
|
||||
|
@ -219,12 +218,12 @@ struct cff1_extents_param_t
|
|||
bounds.init ();
|
||||
}
|
||||
|
||||
void start_path () { path_open = true; }
|
||||
void end_path () { path_open = false; }
|
||||
void start_path () { path_open = true; }
|
||||
void end_path () { path_open = false; }
|
||||
bool is_path_open () const { return path_open; }
|
||||
|
||||
bool path_open;
|
||||
bounds_t bounds;
|
||||
bool path_open;
|
||||
bounds_t bounds;
|
||||
|
||||
const OT::cff1::accelerator_t *cff;
|
||||
};
|
||||
|
|
|
@ -357,7 +357,7 @@ struct Charset0 {
|
|||
return HBUINT16::static_size * (num_glyphs - 1);
|
||||
}
|
||||
|
||||
HBUINT16 sids[VAR];
|
||||
HBUINT16 sids[HB_VAR_ARRAY];
|
||||
|
||||
DEFINE_SIZE_ARRAY(0, sids);
|
||||
};
|
||||
|
@ -439,7 +439,7 @@ struct Charset1_2 {
|
|||
return size;
|
||||
}
|
||||
|
||||
Charset_Range<TYPE> ranges[VAR];
|
||||
Charset_Range<TYPE> ranges[HB_VAR_ARRAY];
|
||||
|
||||
DEFINE_SIZE_ARRAY (0, ranges);
|
||||
};
|
||||
|
@ -1155,7 +1155,7 @@ struct cff1
|
|||
}
|
||||
|
||||
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; }
|
||||
|
||||
|
@ -1225,25 +1225,25 @@ struct cff1
|
|||
|
||||
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))
|
||||
return encoding->get_code (glyph);
|
||||
else
|
||||
{
|
||||
hb_codepoint_t sid = glyph_to_sid (glyph);
|
||||
hb_codepoint_t sid = glyph_to_sid (glyph);
|
||||
if (sid == 0) return 0;
|
||||
hb_codepoint_t code = 0;
|
||||
hb_codepoint_t code = 0;
|
||||
switch (topDict.EncodingOffset)
|
||||
{
|
||||
case StandardEncoding:
|
||||
code = lookup_standard_encoding_for_code (sid);
|
||||
break;
|
||||
case ExpertEncoding:
|
||||
code = lookup_expert_encoding_for_code (sid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case StandardEncoding:
|
||||
code = lookup_standard_encoding_for_code (sid);
|
||||
break;
|
||||
case ExpertEncoding:
|
||||
code = lookup_expert_encoding_for_code (sid);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -44,8 +44,8 @@ struct cff2_extents_param_t
|
|||
max_y.set_int (INT_MIN);
|
||||
}
|
||||
|
||||
void start_path () { path_open = true; }
|
||||
void end_path () { path_open = false; }
|
||||
void start_path () { path_open = true; }
|
||||
void end_path () { path_open = false; }
|
||||
bool is_path_open () const { return path_open; }
|
||||
|
||||
void update_bounds (const point_t &pt)
|
||||
|
|
|
@ -334,9 +334,7 @@ struct CmapSubtableFormat4
|
|||
return true;
|
||||
}
|
||||
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
|
||||
{
|
||||
unsigned int count = this->segCount;
|
||||
|
@ -498,7 +496,7 @@ struct CmapSubtableTrimmed
|
|||
UINT length; /* Byte length of this subtable. */
|
||||
UINT language; /* Ignore. */
|
||||
UINT startCharCode; /* First character code covered. */
|
||||
ArrayOf<GlyphID, UINT>
|
||||
ArrayOf<HBGlyphID, UINT>
|
||||
glyphIdArray; /* Array of glyph index values for character
|
||||
* codes in the range. */
|
||||
public:
|
||||
|
@ -609,11 +607,9 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
|
|||
}
|
||||
|
||||
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,
|
||||
hb_codepoint_t startCharCode,
|
||||
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:
|
||||
DEFINE_SIZE_ARRAY (4, *this);
|
||||
};
|
||||
|
@ -683,9 +736,7 @@ struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32>
|
|||
struct UVSMapping
|
||||
{
|
||||
int cmp (const hb_codepoint_t &codepoint) const
|
||||
{
|
||||
return unicodeValue.cmp (codepoint);
|
||||
}
|
||||
{ return unicodeValue.cmp (codepoint); }
|
||||
|
||||
bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
|
@ -694,7 +745,7 @@ struct UVSMapping
|
|||
}
|
||||
|
||||
HBUINT24 unicodeValue; /* Base Unicode value of the UVS */
|
||||
GlyphID glyphID; /* Glyph ID of the UVS */
|
||||
HBGlyphID glyphID; /* Glyph ID of the UVS */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (5);
|
||||
};
|
||||
|
@ -708,6 +759,49 @@ struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32>
|
|||
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:
|
||||
DEFINE_SIZE_ARRAY (4, *this);
|
||||
};
|
||||
|
@ -736,9 +830,7 @@ struct VariationSelectorRecord
|
|||
}
|
||||
|
||||
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
|
||||
{
|
||||
|
@ -748,6 +840,52 @@ struct VariationSelectorRecord
|
|||
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. */
|
||||
LOffsetTo<DefaultUVS>
|
||||
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,
|
||||
hb_codepoint_t variation_selector,
|
||||
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
|
||||
{
|
||||
|
@ -774,8 +910,44 @@ struct CmapSubtableFormat14
|
|||
}
|
||||
void collect_variation_unicodes (hb_codepoint_t variation_selector,
|
||||
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
|
||||
|
@ -831,11 +1003,14 @@ struct CmapSubtable
|
|||
hb_requires (hb_is_iterator (Iterator))>
|
||||
void serialize (hb_serialize_context_t *c,
|
||||
Iterator it,
|
||||
unsigned format)
|
||||
unsigned format,
|
||||
const hb_subset_plan_t *plan,
|
||||
const void *src_base)
|
||||
{
|
||||
switch (format) {
|
||||
case 4: u.format4.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;
|
||||
}
|
||||
}
|
||||
|
@ -896,10 +1071,13 @@ struct EncodingRecord
|
|||
EncodingRecord* copy (hb_serialize_context_t *c,
|
||||
Iterator it,
|
||||
unsigned format,
|
||||
void *base,
|
||||
const void *src_base,
|
||||
const void *dst_base,
|
||||
const hb_subset_plan_t *plan,
|
||||
/* INOUT */ unsigned *objidx) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
auto snap = c->snapshot ();
|
||||
auto *out = c->embed (this);
|
||||
if (unlikely (!out)) return_trace (nullptr);
|
||||
out->subtable = 0;
|
||||
|
@ -908,12 +1086,18 @@ struct EncodingRecord
|
|||
{
|
||||
CmapSubtable *cmapsubtable = c->push<CmapSubtable> ();
|
||||
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 ();
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -929,27 +1113,40 @@ struct 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))>
|
||||
void serialize (hb_serialize_context_t *c,
|
||||
Iterator it,
|
||||
const EncodingRecord *unicode_bmp,
|
||||
const EncodingRecord *unicode_ucs4,
|
||||
const EncodingRecord *ms_bmp,
|
||||
const EncodingRecord *ms_ucs4)
|
||||
EncodingRecIter encodingrec_iter,
|
||||
const void *src_base,
|
||||
const hb_subset_plan_t *plan)
|
||||
{
|
||||
if (unlikely (!c->extend_min ((*this)))) return;
|
||||
this->version = 0;
|
||||
|
||||
unsigned numTables = (unicode_bmp ? 1 : 0) + (unicode_ucs4 ? 1 : 0) + (ms_bmp ? 1 : 0) + (ms_ucs4 ? 1 : 0);
|
||||
if (unlikely (!c->check_assign(this->encodingRecord.len, numTables))) return;
|
||||
unsigned format4objidx = 0, format12objidx = 0, format14objidx = 0;
|
||||
|
||||
unsigned format4objidx = 0, format12objidx = 0;
|
||||
if (unicode_bmp) c->copy (unicode_bmp, it, 4u, this, &format4objidx);
|
||||
if (unicode_ucs4) c->copy (unicode_ucs4, it, 12u, this, &format12objidx);
|
||||
if (ms_bmp) c->copy (ms_bmp, it, 4u, this, &format4objidx);
|
||||
if (ms_ucs4) c->copy (ms_ucs4, it, 12u, this, &format12objidx);
|
||||
for (const EncodingRecord& _ : encodingrec_iter)
|
||||
{
|
||||
unsigned format = (src_base+_.subtable).u.format;
|
||||
|
||||
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
|
||||
|
@ -959,31 +1156,55 @@ struct cmap
|
|||
cmap *cmap_prime = c->serializer->start_embed<cmap> ();
|
||||
if (unlikely (!c->serializer->check_success (cmap_prime))) return_trace (false);
|
||||
|
||||
const EncodingRecord *unicode_bmp = find_encodingrec (0, 3);
|
||||
const EncodingRecord *unicode_ucs4 = find_encodingrec (0, 4);
|
||||
const EncodingRecord *ms_bmp = find_encodingrec (3, 1);
|
||||
const EncodingRecord *ms_ucs4 = find_encodingrec (3, 10);
|
||||
bool has_format12 = find_subtable (12);
|
||||
auto encodingrec_iter =
|
||||
+ hb_iter (encodingRecord)
|
||||
| hb_filter ([&] (const EncodingRecord& _)
|
||||
{
|
||||
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 (has_format12 && (!unicode_ucs4 && !ms_ucs4))) return_trace (false);
|
||||
|
||||
|
||||
auto it =
|
||||
+ hb_iter (c->plan->unicodes)
|
||||
| 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);
|
||||
}
|
||||
|
||||
|
@ -1034,9 +1255,9 @@ struct cmap
|
|||
|
||||
this->get_glyph_data = subtable;
|
||||
if (unlikely (symbol))
|
||||
{
|
||||
this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>;
|
||||
} else {
|
||||
else
|
||||
{
|
||||
switch (subtable->u.format) {
|
||||
/* Accelerate format 4 and format 12. */
|
||||
default:
|
||||
|
@ -1046,20 +1267,20 @@ struct cmap
|
|||
this->get_glyph_funcZ = get_glyph_from<CmapSubtableFormat12>;
|
||||
break;
|
||||
case 4:
|
||||
{
|
||||
this->format4_accel.init (&subtable->u.format4);
|
||||
this->get_glyph_data = &this->format4_accel;
|
||||
this->get_glyph_funcZ = this->format4_accel.get_glyph_func;
|
||||
}
|
||||
{
|
||||
this->format4_accel.init (&subtable->u.format4);
|
||||
this->get_glyph_data = &this->format4_accel;
|
||||
this->get_glyph_funcZ = this->format4_accel.get_glyph_func;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fini () { this->table.destroy (); }
|
||||
|
||||
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;
|
||||
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
|
||||
{
|
||||
subtable->collect_unicodes (out);
|
||||
}
|
||||
{ subtable->collect_unicodes (out); }
|
||||
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,
|
||||
hb_set_t *out) const
|
||||
{
|
||||
subtable_uvs->collect_variation_unicodes (variation_selector, out);
|
||||
}
|
||||
{ subtable_uvs->collect_variation_unicodes (variation_selector, out); }
|
||||
|
||||
protected:
|
||||
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
|
||||
|
@ -1161,6 +1376,7 @@ struct cmap
|
|||
|
||||
CmapSubtableFormat4::accelerator_t format4_accel;
|
||||
|
||||
public:
|
||||
hb_blob_ptr_t<cmap> table;
|
||||
};
|
||||
|
||||
|
|
|
@ -226,8 +226,8 @@ struct IndexSubtableRecord
|
|||
offset, length, format);
|
||||
}
|
||||
|
||||
GlyphID firstGlyphIndex;
|
||||
GlyphID lastGlyphIndex;
|
||||
HBGlyphID firstGlyphIndex;
|
||||
HBGlyphID lastGlyphIndex;
|
||||
LOffsetTo<IndexSubtable> offsetToSubtable;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC(8);
|
||||
|
@ -290,8 +290,8 @@ struct BitmapSizeTable
|
|||
HBUINT32 colorRef;
|
||||
SBitLineMetrics horizontal;
|
||||
SBitLineMetrics vertical;
|
||||
GlyphID startGlyphIndex;
|
||||
GlyphID endGlyphIndex;
|
||||
HBGlyphID startGlyphIndex;
|
||||
HBGlyphID endGlyphIndex;
|
||||
HBUINT8 ppemX;
|
||||
HBUINT8 ppemY;
|
||||
HBUINT8 bitDepth;
|
||||
|
@ -453,7 +453,7 @@ struct CBDT
|
|||
}
|
||||
|
||||
hb_blob_t* reference_png (hb_font_t *font,
|
||||
hb_codepoint_t glyph) const
|
||||
hb_codepoint_t glyph) const
|
||||
{
|
||||
const void *base;
|
||||
const BitmapSizeTable &strike = this->cblc->choose_strike (font);
|
||||
|
|
|
@ -48,7 +48,7 @@ struct LayerRecord
|
|||
}
|
||||
|
||||
protected:
|
||||
GlyphID glyphId; /* Glyph ID of layer glyph */
|
||||
HBGlyphID glyphId; /* Glyph ID of layer glyph */
|
||||
Index colorIdx; /* Index value to use with a
|
||||
* selected color palette.
|
||||
* An index value of 0xFFFF
|
||||
|
@ -75,7 +75,7 @@ struct BaseGlyphRecord
|
|||
}
|
||||
|
||||
public:
|
||||
GlyphID glyphId; /* Glyph ID of reference glyph */
|
||||
HBGlyphID glyphId; /* Glyph ID of reference glyph */
|
||||
HBUINT16 firstLayerIdx; /* Index (from beginning of
|
||||
* the Layer Records) to the
|
||||
* layer record. There will be
|
||||
|
|
|
@ -115,7 +115,7 @@ struct CPAL
|
|||
{ return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
|
||||
|
||||
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
|
||||
{ return v1 ().get_palette_flags (this, palette_index, numPalettes); }
|
||||
|
|
|
@ -125,7 +125,7 @@ struct SBIXStrike
|
|||
imageOffsetsZ; /* Offset from the beginning of the strike data header
|
||||
* to bitmap data for an individual glyph ID. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
DEFINE_SIZE_ARRAY (4, imageOffsetsZ);
|
||||
};
|
||||
|
||||
struct sbix
|
||||
|
|
|
@ -147,11 +147,7 @@ struct glyf
|
|||
const hb_subset_plan_t *plan)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
|
||||
+ it
|
||||
| hb_apply ([=] (const SubsetGlyph& _) { _.serialize (c, plan); })
|
||||
;
|
||||
|
||||
for (const auto &_ : it) _.serialize (c, plan);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
@ -326,7 +322,7 @@ struct glyf
|
|||
};
|
||||
|
||||
HBUINT16 flags;
|
||||
GlyphID glyphIndex;
|
||||
HBGlyphID glyphIndex;
|
||||
|
||||
unsigned int get_size () const
|
||||
{
|
||||
|
|
|
@ -197,8 +197,6 @@ struct hmtxvmtx
|
|||
var_table.destroy ();
|
||||
}
|
||||
|
||||
bool has_data () const { return table.get () != nullptr; }
|
||||
|
||||
int get_side_bearing (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (glyph < num_advances)
|
||||
|
@ -214,17 +212,14 @@ struct hmtxvmtx
|
|||
int get_side_bearing (hb_font_t *font, hb_codepoint_t glyph) const
|
||||
{
|
||||
int side_bearing = get_side_bearing (glyph);
|
||||
if (likely (glyph < num_metrics))
|
||||
{
|
||||
if (font->num_coords)
|
||||
{
|
||||
if (var_table.get_blob () != hb_blob_get_empty ())
|
||||
side_bearing += var_table->get_side_bearing_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
|
||||
else
|
||||
side_bearing = get_side_bearing_var_tt (font, glyph, T::tableTag==HB_OT_TAG_vmtx);
|
||||
}
|
||||
}
|
||||
return side_bearing;
|
||||
|
||||
if (unlikely (glyph >= num_metrics) || !font->num_coords)
|
||||
return side_bearing;
|
||||
|
||||
if (var_table.get_blob () == &Null (hb_blob_t))
|
||||
return 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?!
|
||||
}
|
||||
|
||||
unsigned int get_advance (hb_codepoint_t glyph) const
|
||||
|
@ -247,17 +242,14 @@ struct hmtxvmtx
|
|||
hb_font_t *font) const
|
||||
{
|
||||
unsigned int advance = get_advance (glyph);
|
||||
if (likely (glyph < num_metrics))
|
||||
{
|
||||
if (font->num_coords)
|
||||
{
|
||||
if (var_table.get_blob () != hb_blob_get_empty ())
|
||||
advance += roundf (var_table->get_advance_var (glyph, font->coords, font->num_coords)); // TODO Optimize?!
|
||||
else
|
||||
advance = get_advance_var_tt (font, glyph, T::tableTag==HB_OT_TAG_vmtx);
|
||||
}
|
||||
}
|
||||
return advance;
|
||||
|
||||
if (unlikely (glyph >= num_metrics) || !font->num_coords)
|
||||
return advance;
|
||||
|
||||
if (var_table.get_blob () == &Null (hb_blob_t))
|
||||
return 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?!
|
||||
}
|
||||
|
||||
unsigned int num_advances_for_subset (const hb_subset_plan_t *plan) const
|
||||
|
|
|
@ -167,8 +167,8 @@ struct KernOTSubTableHeader
|
|||
static constexpr bool apple = false;
|
||||
typedef AAT::ObsoleteTypes Types;
|
||||
|
||||
unsigned int tuple_count () const { return 0; }
|
||||
bool is_horizontal () const { return (coverage & Horizontal); }
|
||||
unsigned tuple_count () const { return 0; }
|
||||
bool is_horizontal () const { return (coverage & Horizontal); }
|
||||
|
||||
enum Coverage
|
||||
{
|
||||
|
@ -222,8 +222,8 @@ struct KernAATSubTableHeader
|
|||
static constexpr bool apple = true;
|
||||
typedef AAT::ObsoleteTypes Types;
|
||||
|
||||
unsigned int tuple_count () const { return 0; }
|
||||
bool is_horizontal () const { return !(coverage & Vertical); }
|
||||
unsigned tuple_count () const { return 0; }
|
||||
bool is_horizontal () const { return !(coverage & Vertical); }
|
||||
|
||||
enum Coverage
|
||||
{
|
||||
|
@ -275,8 +275,8 @@ struct kern
|
|||
{
|
||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
|
||||
|
||||
bool has_data () const { return u.version32; }
|
||||
unsigned int get_type () const { return u.major; }
|
||||
bool has_data () const { return u.version32; }
|
||||
unsigned get_type () const { return u.major; }
|
||||
|
||||
bool has_state_machine () const
|
||||
{
|
||||
|
|
|
@ -73,7 +73,7 @@ struct BaseCoordFormat2
|
|||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 2 */
|
||||
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
|
||||
* reference glyph */
|
||||
public:
|
||||
|
|
|
@ -173,8 +173,8 @@ struct RangeRecord
|
|||
bool add_coverage (set_t *glyphs) const
|
||||
{ return glyphs->add_range (start, end); }
|
||||
|
||||
GlyphID start; /* First GlyphID in the range */
|
||||
GlyphID end; /* Last GlyphID in the range */
|
||||
HBGlyphID start; /* First GlyphID in the range */
|
||||
HBGlyphID end; /* Last GlyphID in the range */
|
||||
HBUINT16 value; /* Value */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
|
@ -541,7 +541,7 @@ struct FeatureParams
|
|||
FeatureParamsCharacterVariants characterVariants;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (17);
|
||||
DEFINE_SIZE_MIN (0);
|
||||
};
|
||||
|
||||
struct Feature
|
||||
|
@ -781,7 +781,7 @@ struct Lookup
|
|||
HBUINT16 lookupFlag; /* Lookup qualifiers */
|
||||
ArrayOf<Offset16>
|
||||
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
|
||||
* UseMarkFilteringSet of lookup flags is set. */
|
||||
public:
|
||||
|
@ -857,7 +857,7 @@ struct CoverageFormat1
|
|||
|
||||
protected:
|
||||
HBUINT16 coverageFormat; /* Format identifier--format = 1 */
|
||||
SortedArrayOf<GlyphID>
|
||||
SortedArrayOf<HBGlyphID>
|
||||
glyphArray; /* Array of GlyphIDs--in numerical order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, glyphArray);
|
||||
|
@ -1063,7 +1063,7 @@ struct Coverage
|
|||
last = g;
|
||||
count++;
|
||||
}
|
||||
u.format = count * 2 < num_ranges * 3 ? 1 : 2;
|
||||
u.format = count <= num_ranges * 3 ? 1 : 2;
|
||||
|
||||
switch (u.format)
|
||||
{
|
||||
|
@ -1197,7 +1197,7 @@ struct Coverage
|
|||
*/
|
||||
|
||||
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);
|
||||
|
||||
struct ClassDefFormat1
|
||||
|
@ -1211,7 +1211,7 @@ struct ClassDefFormat1
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
|
@ -1242,7 +1242,7 @@ struct ClassDefFormat1
|
|||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->glyphset ();
|
||||
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_codepoint_t start = startGlyph;
|
||||
|
@ -1329,7 +1329,7 @@ struct ClassDefFormat1
|
|||
|
||||
protected:
|
||||
HBUINT16 classFormat; /* Format identifier--format = 1 */
|
||||
GlyphID startGlyph; /* First GlyphID of the classValueArray */
|
||||
HBGlyphID startGlyph; /* First GlyphID of the classValueArray */
|
||||
ArrayOf<HBUINT16>
|
||||
classValue; /* Array of Class Values--one per GlyphID */
|
||||
public:
|
||||
|
@ -1347,7 +1347,7 @@ struct ClassDefFormat2
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
|
@ -1391,7 +1391,7 @@ struct ClassDefFormat2
|
|||
TRACE_SUBSET (this);
|
||||
const hb_set_t &glyphset = *c->plan->glyphset ();
|
||||
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;
|
||||
|
||||
unsigned int count = rangeRecord.len;
|
||||
|
@ -1507,7 +1507,7 @@ struct ClassDef
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
|
@ -1612,7 +1612,7 @@ struct ClassDef
|
|||
};
|
||||
|
||||
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)
|
||||
{ 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
|
||||
{ return get_delta (font->y_ppem, font->y_scale); }
|
||||
|
||||
public:
|
||||
|
||||
unsigned int get_size () const
|
||||
{
|
||||
unsigned int f = deltaFormat;
|
||||
|
@ -2231,6 +2233,12 @@ struct HintingDevice
|
|||
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:
|
||||
|
||||
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
|
||||
{ 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
|
||||
{
|
||||
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:
|
||||
union {
|
||||
DeviceHeader b;
|
||||
|
|
|
@ -101,10 +101,10 @@ struct ValueFormat : HBUINT16
|
|||
unsigned int get_len () const { return hb_popcount ((unsigned int) *this); }
|
||||
unsigned int get_size () const { return get_len () * Value::static_size; }
|
||||
|
||||
bool apply_value (hb_ot_apply_context_t *c,
|
||||
const void *base,
|
||||
const Value *values,
|
||||
hb_glyph_position_t &glyph_pos) const
|
||||
bool apply_value (hb_ot_apply_context_t *c,
|
||||
const void *base,
|
||||
const Value *values,
|
||||
hb_glyph_position_t &glyph_pos) const
|
||||
{
|
||||
bool ret = false;
|
||||
unsigned int format = *this;
|
||||
|
@ -258,6 +258,12 @@ struct AnchorFormat1
|
|||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
AnchorFormat1* copy (hb_serialize_context_t *c) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
return_trace (c->embed<AnchorFormat1> (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 1 */
|
||||
FWORD xCoordinate; /* Horizontal value--in design units */
|
||||
|
@ -296,6 +302,12 @@ struct AnchorFormat2
|
|||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
AnchorFormat2* copy (hb_serialize_context_t *c) const
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
return_trace (c->embed<AnchorFormat2> (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 2 */
|
||||
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));
|
||||
}
|
||||
|
||||
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:
|
||||
HBUINT16 format; /* Format identifier--format = 3 */
|
||||
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:
|
||||
union {
|
||||
HBUINT16 format; /* Format identifier */
|
||||
|
@ -510,11 +544,8 @@ struct SinglePosFormat1
|
|||
if (unlikely (!c->extend_min (*this))) return;
|
||||
if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
|
||||
|
||||
auto vals = hb_second (*it);
|
||||
|
||||
+ vals
|
||||
| hb_apply ([=] (const Value& _) { c->copy (_); })
|
||||
;
|
||||
for (const auto &_ : hb_second (*it))
|
||||
c->copy (_);
|
||||
|
||||
auto glyphs =
|
||||
+ it
|
||||
|
@ -530,15 +561,11 @@ struct SinglePosFormat1
|
|||
const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
|
||||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||
|
||||
unsigned length = valueFormat.get_len ();
|
||||
|
||||
auto it =
|
||||
+ hb_iter (this+coverage)
|
||||
| hb_filter (glyphset)
|
||||
| hb_map_retains_sorting ([&] (hb_codepoint_t p)
|
||||
{
|
||||
return hb_pair (glyph_map[p], values.as_array (length));
|
||||
})
|
||||
| hb_map_retains_sorting (glyph_map)
|
||||
| hb_zip (hb_repeat (values.as_array (valueFormat.get_len ())))
|
||||
;
|
||||
|
||||
bool ret = bool (it);
|
||||
|
@ -605,15 +632,9 @@ struct SinglePosFormat2
|
|||
if (unlikely (!c->check_assign (valueFormat, valFormat))) return;
|
||||
if (unlikely (!c->check_assign (valueCount, it.len ()))) return;
|
||||
|
||||
+ it
|
||||
| hb_map (hb_second)
|
||||
| hb_apply ([=] (hb_array_t<const Value> val_iter)
|
||||
{
|
||||
+ val_iter
|
||||
| hb_apply ([=] (const Value& _) { c->copy (_); })
|
||||
;
|
||||
})
|
||||
;
|
||||
for (const auto iter : it)
|
||||
for (const auto &_ : iter.second)
|
||||
c->copy (_);
|
||||
|
||||
auto glyphs =
|
||||
+ it
|
||||
|
@ -630,14 +651,16 @@ struct SinglePosFormat2
|
|||
const hb_map_t &glyph_map = *c->plan->glyph_map;
|
||||
|
||||
unsigned sub_length = valueFormat.get_len ();
|
||||
unsigned total_length = (unsigned)valueCount * sub_length;
|
||||
auto values_array = values.as_array (valueCount * sub_length);
|
||||
|
||||
auto it =
|
||||
+ hb_zip (this+coverage, hb_range ((unsigned) valueCount))
|
||||
| hb_filter (glyphset, hb_first)
|
||||
| hb_map_retains_sorting ([&] (const hb_pair_t<hb_codepoint_t, unsigned>& _)
|
||||
{
|
||||
return hb_pair (glyph_map[_.first], values.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))>
|
||||
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);
|
||||
|
||||
+ glyph_val_iter_pairs
|
||||
| hb_map (hb_second)
|
||||
| hb_apply ([&] (hb_array_t<const Value> val_iter)
|
||||
{
|
||||
+ hb_zip (val_iter, first_val_iter)
|
||||
| hb_apply ([&] (const hb_pair_t<Value, Value>& _)
|
||||
{
|
||||
if (_.first != _.second)
|
||||
{
|
||||
subset_format = 2;
|
||||
return;
|
||||
}
|
||||
})
|
||||
;
|
||||
})
|
||||
;
|
||||
for (const auto iter : glyph_val_iter_pairs)
|
||||
for (const auto _ : hb_zip (iter.second, first_val_iter))
|
||||
if (_.first != _.second)
|
||||
return 2;
|
||||
|
||||
return subset_format;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -752,7 +762,7 @@ struct PairValueRecord
|
|||
friend struct PairSet;
|
||||
|
||||
protected:
|
||||
GlyphID secondGlyph; /* GlyphID of second glyph in the
|
||||
HBGlyphID secondGlyph; /* GlyphID of second glyph in the
|
||||
* pair--first glyph is listed in the
|
||||
* Coverage table */
|
||||
ValueRecord values; /* Positioning data for the first glyph
|
||||
|
@ -1088,6 +1098,19 @@ struct EntryExitRecord
|
|||
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:
|
||||
OffsetTo<Anchor>
|
||||
entryAnchor; /* Offset to EntryAnchor table--from
|
||||
|
@ -1215,11 +1238,47 @@ struct CursivePosFormat1
|
|||
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
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
// TODO(subset)
|
||||
return_trace (false);
|
||||
const hb_set_t &glyphset = *c->plan->glyphset ();
|
||||
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
|
||||
|
|
|
@ -111,8 +111,11 @@ struct SingleSubstFormat1
|
|||
+ hb_iter (this+coverage)
|
||||
| hb_filter (glyphset)
|
||||
| hb_map_retains_sorting ([&] (hb_codepoint_t g) {
|
||||
return hb_codepoint_pair_t (glyph_map[g],
|
||||
glyph_map[(g + delta) & 0xFFFF]); })
|
||||
return hb_codepoint_pair_t (g,
|
||||
(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);
|
||||
|
@ -208,7 +211,8 @@ struct SingleSubstFormat2
|
|||
auto it =
|
||||
+ hb_zip (this+coverage, substitute)
|
||||
| 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]); })
|
||||
;
|
||||
|
||||
|
@ -228,7 +232,7 @@ struct SingleSubstFormat2
|
|||
OffsetTo<Coverage>
|
||||
coverage; /* Offset to Coverage table--from
|
||||
* beginning of Substitution table */
|
||||
ArrayOf<GlyphID>
|
||||
ArrayOf<HBGlyphID>
|
||||
substitute; /* Array of substitute
|
||||
* GlyphIDs--ordered by Coverage Index */
|
||||
public:
|
||||
|
@ -370,7 +374,7 @@ struct Sequence
|
|||
}
|
||||
|
||||
protected:
|
||||
ArrayOf<GlyphID>
|
||||
ArrayOf<HBGlyphID>
|
||||
substitute; /* String of GlyphIDs to substitute */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, substitute);
|
||||
|
@ -417,9 +421,9 @@ struct MultipleSubstFormat1
|
|||
}
|
||||
|
||||
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 GlyphID> substitute_glyphs_list)
|
||||
hb_array_t<const HBGlyphID> substitute_glyphs_list)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||
|
@ -492,9 +496,9 @@ struct MultipleSubstFormat1
|
|||
struct MultipleSubst
|
||||
{
|
||||
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 GlyphID> substitute_glyphs_list)
|
||||
hb_array_t<const HBGlyphID> substitute_glyphs_list)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
||||
|
@ -593,7 +597,7 @@ struct AlternateSet
|
|||
}
|
||||
|
||||
protected:
|
||||
ArrayOf<GlyphID>
|
||||
ArrayOf<HBGlyphID>
|
||||
alternates; /* Array of alternate GlyphIDs--in
|
||||
* arbitrary order */
|
||||
public:
|
||||
|
@ -640,9 +644,9 @@ struct AlternateSubstFormat1
|
|||
}
|
||||
|
||||
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 GlyphID> alternate_glyphs_list)
|
||||
hb_array_t<const HBGlyphID> alternate_glyphs_list)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||
|
@ -715,9 +719,9 @@ struct AlternateSubstFormat1
|
|||
struct AlternateSubst
|
||||
{
|
||||
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 GlyphID> alternate_glyphs_list)
|
||||
hb_array_t<const HBGlyphID> alternate_glyphs_list)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
||||
|
@ -856,8 +860,8 @@ struct Ligature
|
|||
}
|
||||
|
||||
protected:
|
||||
GlyphID ligGlyph; /* GlyphID of ligature to substitute */
|
||||
HeadlessArrayOf<GlyphID>
|
||||
HBGlyphID ligGlyph; /* GlyphID of ligature to substitute */
|
||||
HeadlessArrayOf<HBGlyphID>
|
||||
component; /* Array of component GlyphIDs--start
|
||||
* with the second component--ordered
|
||||
* in writing direction */
|
||||
|
@ -917,9 +921,9 @@ struct LigatureSet
|
|||
}
|
||||
|
||||
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 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);
|
||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||
|
@ -1034,11 +1038,11 @@ struct LigatureSubstFormat1
|
|||
}
|
||||
|
||||
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 GlyphID> ligatures_list,
|
||||
hb_array_t<const HBGlyphID> ligatures_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);
|
||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||
|
@ -1114,11 +1118,11 @@ struct LigatureSubstFormat1
|
|||
struct LigatureSubst
|
||||
{
|
||||
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 GlyphID> ligatures_list,
|
||||
hb_array_t<const HBGlyphID> ligatures_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);
|
||||
if (unlikely (!c->extend_min (u.format))) return_trace (false);
|
||||
|
@ -1195,7 +1199,7 @@ struct ReverseChainSingleSubstFormat1
|
|||
if (!intersects (c->glyphs)) return;
|
||||
|
||||
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_filter (*c->glyphs, hb_first)
|
||||
|
@ -1219,7 +1223,7 @@ struct ReverseChainSingleSubstFormat1
|
|||
for (unsigned int i = 0; i < count; i++)
|
||||
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;
|
||||
c->output->add_array (substitute.arrayZ, substitute.len);
|
||||
}
|
||||
|
@ -1239,7 +1243,7 @@ struct ReverseChainSingleSubstFormat1
|
|||
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
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;
|
||||
if (match_backtrack (c,
|
||||
|
@ -1277,7 +1281,7 @@ struct ReverseChainSingleSubstFormat1
|
|||
const OffsetArrayOf<Coverage> &lookahead = StructAfter<OffsetArrayOf<Coverage>> (backtrack);
|
||||
if (!lookahead.sanitize (c, this))
|
||||
return_trace (false);
|
||||
const ArrayOf<GlyphID> &substitute = StructAfter<ArrayOf<GlyphID>> (lookahead);
|
||||
const ArrayOf<HBGlyphID> &substitute = StructAfter<ArrayOf<HBGlyphID>> (lookahead);
|
||||
return_trace (substitute.sanitize (c));
|
||||
}
|
||||
|
||||
|
@ -1294,7 +1298,7 @@ struct ReverseChainSingleSubstFormat1
|
|||
lookaheadX; /* Array of coverage tables
|
||||
* in lookahead sequence, in glyph
|
||||
* sequence order */
|
||||
ArrayOf<GlyphID>
|
||||
ArrayOf<HBGlyphID>
|
||||
substituteX; /* Array of substitute
|
||||
* GlyphIDs--ordered by Coverage Index */
|
||||
public:
|
||||
|
@ -1449,8 +1453,8 @@ struct SubstLookup : Lookup
|
|||
|
||||
bool serialize_single (hb_serialize_context_t *c,
|
||||
uint32_t lookup_props,
|
||||
hb_sorted_array_t<const GlyphID> glyphs,
|
||||
hb_array_t<const GlyphID> substitutes)
|
||||
hb_sorted_array_t<const HBGlyphID> glyphs,
|
||||
hb_array_t<const HBGlyphID> substitutes)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
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,
|
||||
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 GlyphID> substitute_glyphs_list)
|
||||
hb_array_t<const HBGlyphID> substitute_glyphs_list)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
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,
|
||||
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 GlyphID> alternate_glyphs_list)
|
||||
hb_array_t<const HBGlyphID> alternate_glyphs_list)
|
||||
{
|
||||
TRACE_SERIALIZE (this);
|
||||
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,
|
||||
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 GlyphID> ligatures_list,
|
||||
hb_array_t<const HBGlyphID> ligatures_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);
|
||||
if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
|
||||
|
|
|
@ -136,7 +136,7 @@ struct JstfLangSys : OffsetListOf<JstfPriority>
|
|||
* ExtenderGlyphs -- Extender Glyph Table
|
||||
*/
|
||||
|
||||
typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
|
||||
typedef SortedArrayOf<HBGlyphID> ExtenderGlyphs;
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -1227,7 +1227,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
|
|||
* @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
|
||||
*
|
||||
* 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
|
||||
**/
|
||||
|
@ -1949,7 +1949,7 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
|
|||
/**
|
||||
* hb_ot_layout_get_baseline:
|
||||
* @font: a font
|
||||
* @baseline: a baseline tag
|
||||
* @baseline_tag: a baseline tag
|
||||
* @direction: text direction.
|
||||
* @script_tag: script tag.
|
||||
* @language_tag: language tag.
|
||||
|
|
|
@ -191,7 +191,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
|||
feature_infos[j].max_value = feature_infos[i].max_value;
|
||||
feature_infos[j].default_value = feature_infos[i].default_value;
|
||||
} 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);
|
||||
/* Inherit default_value from j */
|
||||
}
|
||||
|
|
|
@ -423,7 +423,7 @@ struct MathGlyphVariantRecord
|
|||
}
|
||||
|
||||
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
|
||||
* variant, in the direction of requested
|
||||
* glyph extension. */
|
||||
|
@ -471,7 +471,7 @@ struct MathGlyphPartRecord
|
|||
}
|
||||
|
||||
protected:
|
||||
GlyphID glyph; /* Glyph ID for the part. */
|
||||
HBGlyphID glyph; /* Glyph ID for the part. */
|
||||
HBUINT16 startConnectorLength; /* Advance width/ height of the straight bar
|
||||
* connector material, in design units, is at
|
||||
* the beginning of the glyph, in the
|
||||
|
|
|
@ -129,7 +129,7 @@ struct maxp
|
|||
FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0),
|
||||
* 0x00005000u or 0x00010000u. */
|
||||
HBUINT16 numGlyphs; /* The number of glyphs in the font. */
|
||||
/*maxpV1Tail v1Tail[VAR]; */
|
||||
/*maxpV1Tail v1Tail[HB_VAR_ARRAY]; */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
|
|
@ -191,9 +191,7 @@ struct name
|
|||
|
||||
const void *dst_string_pool = &(this + this->stringOffset);
|
||||
|
||||
+ it
|
||||
| hb_apply ([=] (const NameRecord& _) { c->copy (_, src_string_pool, dst_string_pool); })
|
||||
;
|
||||
for (const auto &_ : it) c->copy (_, src_string_pool, dst_string_pool);
|
||||
|
||||
if (unlikely (c->ran_out_of_room)) return_trace (false);
|
||||
|
||||
|
@ -330,6 +328,9 @@ struct name
|
|||
DEFINE_SIZE_ARRAY (6, nameRecordZ);
|
||||
};
|
||||
|
||||
#undef entry_index
|
||||
#undef entry_score
|
||||
|
||||
struct name_accelerator_t : name::accelerator_t {};
|
||||
|
||||
} /* namespace OT */
|
||||
|
|
|
@ -134,8 +134,8 @@ struct OS2
|
|||
OBLIQUE = 1u<<9
|
||||
};
|
||||
|
||||
bool is_italic () const { return fsSelection & ITALIC; }
|
||||
bool is_oblique () const { return fsSelection & OBLIQUE; }
|
||||
bool is_italic () const { return fsSelection & ITALIC; }
|
||||
bool is_oblique () const { return fsSelection & OBLIQUE; }
|
||||
bool use_typo_metrics () const { return fsSelection & USE_TYPO_METRICS; }
|
||||
|
||||
enum width_class_t {
|
||||
|
|
|
@ -262,7 +262,7 @@ struct post
|
|||
* 0x00020000 for version 2.0
|
||||
* 0x00025000 for version 2.5 (deprecated)
|
||||
* 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,
|
||||
* negative for text that leans to the right
|
||||
* (forward). */
|
||||
|
|
|
@ -49,8 +49,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
|
|||
hb_font_t *font,
|
||||
unsigned int feature_index)
|
||||
{
|
||||
OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
OT::HBGlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
OT::HBGlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
unsigned int num_glyphs = 0;
|
||||
|
||||
/* 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!
|
||||
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
||||
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]);
|
||||
|
||||
|
||||
|
@ -99,15 +99,15 @@ static OT::SubstLookup *
|
|||
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
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 ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
|
||||
unsigned int num_first_glyphs = 0;
|
||||
|
||||
/* 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)];
|
||||
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;
|
||||
|
||||
/* Populate arrays */
|
||||
|
@ -125,7 +125,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
|
|||
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]);
|
||||
|
||||
/* 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;
|
||||
|
||||
const Manifest &manifest = reinterpret_cast<const Manifest&> (arabic_win1256_gsub_lookups.manifest);
|
||||
static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) / sizeof (ManifestLookup)
|
||||
<= ARABIC_FALLBACK_MAX_LOOKUPS, "");
|
||||
static_assert (sizeof (arabic_win1256_gsub_lookups.manifestData) ==
|
||||
ARABIC_FALLBACK_MAX_LOOKUPS * sizeof (ManifestLookup), "");
|
||||
/* TODO sanitize the table? */
|
||||
|
||||
unsigned j = 0;
|
||||
|
|
|
@ -116,8 +116,8 @@ enum myanmar_syllable_type_t {
|
|||
|
||||
static void
|
||||
setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font HB_UNUSED)
|
||||
hb_buffer_t *buffer,
|
||||
hb_font_t *font HB_UNUSED)
|
||||
{
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_category);
|
||||
HB_BUFFER_ALLOCATE_VAR (buffer, myanmar_position);
|
||||
|
|
|
@ -77,7 +77,7 @@ struct AxisValueFormat1
|
|||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||
* that provide a display string for this
|
||||
* attribute value. */
|
||||
Fixed value; /* A numeric value for this attribute value. */
|
||||
HBFixed value; /* A numeric value for this attribute value. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (12);
|
||||
};
|
||||
|
@ -102,10 +102,10 @@ struct AxisValueFormat2
|
|||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||
* that provide a display string for this
|
||||
* attribute value. */
|
||||
Fixed nominalValue; /* A numeric value for this attribute value. */
|
||||
Fixed rangeMinValue; /* The minimum value for a range associated
|
||||
HBFixed nominalValue; /* A numeric value for this attribute value. */
|
||||
HBFixed rangeMinValue; /* The minimum value for a range associated
|
||||
* 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. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (20);
|
||||
|
@ -131,8 +131,8 @@ struct AxisValueFormat3
|
|||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||
* that provide a display string for this
|
||||
* attribute value. */
|
||||
Fixed value; /* A numeric value for this attribute value. */
|
||||
Fixed linkedValue; /* The numeric value for a style-linked mapping
|
||||
HBFixed value; /* A numeric value for this attribute value. */
|
||||
HBFixed linkedValue; /* The numeric value for a style-linked mapping
|
||||
* from this value. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (16);
|
||||
|
@ -150,7 +150,7 @@ struct AxisValueRecord
|
|||
HBUINT16 axisIndex; /* Zero-base index into the axis record array
|
||||
* identifying the axis to which this value
|
||||
* 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:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
|
|
@ -44,7 +44,7 @@ struct InstanceRecord
|
|||
{
|
||||
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); }
|
||||
|
||||
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
|
||||
* that provide subfamily names for this instance. */
|
||||
HBUINT16 flags; /* Reserved for future use — set to 0. */
|
||||
UnsizedArrayOf<Fixed>
|
||||
UnsizedArrayOf<HBFixed>
|
||||
coordinatesZ; /* The coordinates array for this instance. */
|
||||
//NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
|
||||
// * table that provide PostScript names for this
|
||||
|
@ -83,9 +83,9 @@ struct AxisRecord
|
|||
|
||||
public:
|
||||
Tag axisTag; /* Tag identifying the design variation for the axis. */
|
||||
Fixed minValue; /* The minimum coordinate value for the axis. */
|
||||
Fixed defaultValue; /* The default coordinate value for the axis. */
|
||||
Fixed maxValue; /* The maximum coordinate value for the axis. */
|
||||
HBFixed minValue; /* The minimum coordinate value for the axis. */
|
||||
HBFixed defaultValue; /* The default coordinate value for the axis. */
|
||||
HBFixed maxValue; /* The maximum coordinate value for the axis. */
|
||||
HBUINT16 flags; /* Axis flags. */
|
||||
NameID axisNameID; /* The name ID for entries in the 'name' table that
|
||||
* provide a display name for this axis. */
|
||||
|
@ -286,7 +286,7 @@ struct fvar
|
|||
|
||||
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);
|
||||
for (unsigned int i = 0; i < instanceCoords.length; i++)
|
||||
coords[i] = instanceCoords.arrayZ[i].to_float ();
|
||||
|
@ -340,8 +340,8 @@ struct fvar
|
|||
HBUINT16 instanceCount; /* The number of named instances defined in the font
|
||||
* (the number of records in the instances array). */
|
||||
HBUINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
|
||||
* to either axisCount * sizeof(Fixed) + 4, or to
|
||||
* axisCount * sizeof(Fixed) + 6. */
|
||||
* to either axisCount * sizeof(HBFixed) + 4, or to
|
||||
* axisCount * sizeof(HBFixed) + 6. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (16);
|
||||
|
|
|
@ -48,7 +48,7 @@ struct VertOriginMetric
|
|||
}
|
||||
|
||||
public:
|
||||
GlyphID glyph;
|
||||
HBGlyphID glyph;
|
||||
FWORD vertOriginY;
|
||||
|
||||
public:
|
||||
|
@ -84,9 +84,7 @@ struct VORG
|
|||
this->defaultVertOriginY = defaultVertOriginY;
|
||||
this->vertYOrigins.len = it.len ();
|
||||
|
||||
+ it
|
||||
| hb_apply ([c] (const VertOriginMetric& _) { c->copy (_); })
|
||||
;
|
||||
for (const auto _ : it) c->copy (_);
|
||||
}
|
||||
|
||||
bool subset (hb_subset_context_t *c) const
|
||||
|
|
|
@ -91,9 +91,7 @@ struct hb_serialize_context_t
|
|||
|
||||
void fini ()
|
||||
{
|
||||
++ hb_iter (packed)
|
||||
| hb_apply ([] (object_t *_) { _->fini (); })
|
||||
;
|
||||
for (object_t *_ : ++hb_iter (packed)) _->fini ();
|
||||
packed.fini ();
|
||||
this->packed_map.fini ();
|
||||
|
||||
|
@ -194,6 +192,7 @@ struct hb_serialize_context_t
|
|||
if (unlikely (!obj)) return;
|
||||
current = current->next;
|
||||
revert (*obj);
|
||||
obj->fini ();
|
||||
object_pool.free (obj);
|
||||
}
|
||||
objidx_t pop_pack ()
|
||||
|
@ -291,7 +290,6 @@ struct hb_serialize_context_t
|
|||
assert (packed.length > 1);
|
||||
|
||||
for (const object_t* parent : ++hb_iter (packed))
|
||||
{
|
||||
for (const object_t::link_t &link : parent->links)
|
||||
{
|
||||
const object_t* child = packed[link.objidx];
|
||||
|
@ -311,7 +309,6 @@ struct hb_serialize_context_t
|
|||
check_assign (off, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int length () const { return this->head - current->head; }
|
||||
|
@ -353,9 +350,7 @@ struct hb_serialize_context_t
|
|||
|
||||
template <typename Type>
|
||||
Type *allocate_min ()
|
||||
{
|
||||
return this->allocate_size<Type> (Type::min_size);
|
||||
}
|
||||
{ return this->allocate_size<Type> (Type::min_size); }
|
||||
|
||||
template <typename Type>
|
||||
Type *embed (const Type *obj)
|
||||
|
@ -427,14 +422,12 @@ struct hb_serialize_context_t
|
|||
/* Copy both items from head side and tail side... */
|
||||
unsigned int len = (this->head - this->start)
|
||||
+ (this->end - this->tail);
|
||||
|
||||
char *p = (char *) malloc (len);
|
||||
if (p)
|
||||
{
|
||||
memcpy (p, this->start, this->head - this->start);
|
||||
memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
|
||||
}
|
||||
else
|
||||
return hb_bytes_t ();
|
||||
if (unlikely (!p)) return hb_bytes_t ();
|
||||
|
||||
memcpy (p, this->start, this->head - this->start);
|
||||
memcpy (p + (this->head - this->start), this->tail, this->end - this->tail);
|
||||
return hb_bytes_t (p, len);
|
||||
}
|
||||
template <typename Type>
|
||||
|
|
|
@ -136,12 +136,17 @@ struct hb_set_t
|
|||
unsigned int j = m & ELT_MASK;
|
||||
|
||||
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)
|
||||
{
|
||||
*codepoint = i * ELT_BITS + elt_get_max (*p);
|
||||
return true;
|
||||
}
|
||||
if ((int) i <= 0) break;
|
||||
p = &v[--i];
|
||||
}
|
||||
|
||||
*codepoint = INVALID;
|
||||
return false;
|
||||
|
|
|
@ -48,7 +48,7 @@ static const union HB_STRING_ARRAY_TYPE_NAME {
|
|||
#include HB_STRING_ARRAY_LIST
|
||||
#undef _S
|
||||
} st;
|
||||
char str[VAR];
|
||||
char str[HB_VAR_ARRAY];
|
||||
}
|
||||
HB_STRING_ARRAY_POOL_NAME =
|
||||
{
|
||||
|
|
|
@ -39,7 +39,7 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
|
|||
hb_codepoint_t gid,
|
||||
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.
|
||||
return;
|
||||
|
||||
|
@ -87,6 +87,14 @@ _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
|
|||
}
|
||||
#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
|
||||
_remove_invalid_gids (hb_set_t *glyphs,
|
||||
unsigned int num_glyphs)
|
||||
|
@ -129,6 +137,8 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
|||
plan->_glyphset_gsub->add (gid);
|
||||
}
|
||||
|
||||
_cmap_closure (plan->source, plan->unicodes, plan->_glyphset_gsub);
|
||||
|
||||
#ifndef HB_NO_SUBSET_LAYOUT
|
||||
if (close_over_gsub)
|
||||
// Add all glyphs needed for GSUB substitutions.
|
||||
|
|
|
@ -249,11 +249,6 @@ _subset_table (hb_subset_plan_t *plan,
|
|||
static bool
|
||||
_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))
|
||||
return true;
|
||||
|
||||
|
@ -301,17 +296,19 @@ hb_subset (hb_face_t *source,
|
|||
hb_tag_t table_tags[32];
|
||||
unsigned int offset = 0, count;
|
||||
bool success = true;
|
||||
hb_set_t tags_set;
|
||||
do {
|
||||
count = ARRAY_LENGTH (table_tags);
|
||||
hb_face_get_table_tags (source, offset, &count, table_tags);
|
||||
for (unsigned int i = 0; i < count; 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));
|
||||
continue;
|
||||
}
|
||||
tags_set.add (tag);
|
||||
success = success && _subset_table (plan, tag);
|
||||
}
|
||||
offset += count;
|
||||
|
|
|
@ -270,9 +270,9 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
|
|||
**/
|
||||
hb_bool_t
|
||||
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t 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 *
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -200,15 +200,15 @@ hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs);
|
|||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_user_data_key_t *key,
|
||||
void * data,
|
||||
hb_destroy_func_t destroy,
|
||||
hb_bool_t replace);
|
||||
|
||||
|
||||
HB_EXTERN void *
|
||||
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
|
||||
|
@ -260,7 +260,7 @@ typedef hb_bool_t (*hb_unicode_decompose_func_t) (hb_unicode_funcs_t *ufuncs,
|
|||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
|
@ -276,7 +276,7 @@ hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
|
|||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
|
@ -292,7 +292,7 @@ hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
|
|||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
|
@ -308,7 +308,7 @@ hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
|
|||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
|
@ -324,7 +324,7 @@ hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
|
|||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
|
@ -340,7 +340,7 @@ hb_unicode_funcs_set_compose_func (hb_unicode_funcs_t *ufuncs,
|
|||
* @user_data:
|
||||
* @destroy:
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
|
|
|
@ -302,8 +302,8 @@ struct hb_sorted_vector_t : hb_vector_t<Type>
|
|||
{ return as_array ().bsearch (x, not_found); }
|
||||
template <typename T>
|
||||
bool bfind (const T &x, unsigned int *i = nullptr,
|
||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||
unsigned int to_store = (unsigned int) -1) const
|
||||
hb_bfind_not_found_t not_found = HB_BFIND_NOT_FOUND_DONT_STORE,
|
||||
unsigned int to_store = (unsigned int) -1) const
|
||||
{ return as_array ().bfind (x, i, not_found, to_store); }
|
||||
};
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@ HB_BEGIN_DECLS
|
|||
|
||||
#define HB_VERSION_MAJOR 2
|
||||
#define HB_VERSION_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) \
|
||||
((major)*10000+(minor)*100+(micro) <= \
|
||||
|
|
27
src/hb.hh
27
src/hb.hh
|
@ -180,7 +180,6 @@
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
@ -242,7 +241,7 @@ extern "C" void hb_free_impl(void *ptr);
|
|||
#define HB_CONST_FUNC
|
||||
#define HB_PRINTF_FUNC(format_idx, arg_idx)
|
||||
#endif
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) || (__clang__)
|
||||
#define HB_UNUSED __attribute__((unused))
|
||||
#elif defined(_MSC_VER) /* https://github.com/harfbuzz/harfbuzz/issues/635 */
|
||||
#define HB_UNUSED __pragma(warning(suppress: 4100 4101))
|
||||
|
@ -355,7 +354,7 @@ extern "C" void hb_free_impl(void *ptr);
|
|||
# endif
|
||||
# if _WIN32_WCE < 0x800
|
||||
# define HB_NO_SETLOCALE
|
||||
static int errno = 0; /* Use something better? */
|
||||
# define HB_NO_ERRNO
|
||||
# endif
|
||||
# elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
|
||||
# ifndef HB_NO_GETENV
|
||||
|
@ -371,6 +370,12 @@ static int errno = 0; /* Use something better? */
|
|||
#define getenv(Name) nullptr
|
||||
#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)
|
||||
/* atexit() is only safe to be called from shared libraries on certain
|
||||
* platforms. Whitelist.
|
||||
|
@ -475,7 +480,18 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
|
|||
|
||||
|
||||
/* 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 */
|
||||
static inline uint16_t hb_uint16_swap (const uint16_t v)
|
||||
|
@ -585,9 +601,10 @@ struct BEInt<Type, 4>
|
|||
* them directly.*/
|
||||
#include "hb-meta.hh"
|
||||
#include "hb-mutex.hh"
|
||||
#include "hb-number.hh"
|
||||
#include "hb-atomic.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-debug.hh" // Requires: hb-algs hb-atomic
|
||||
#include "hb-array.hh" // Requires: hb-algs hb-iter hb-null
|
||||
|
|
37
src/main.cc
37
src/main.cc
|
@ -45,7 +45,8 @@ using namespace OT;
|
|||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
if (argc != 2) {
|
||||
if (argc != 2)
|
||||
{
|
||||
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
|
||||
exit (1);
|
||||
}
|
||||
|
@ -65,7 +66,8 @@ main (int argc, char **argv)
|
|||
const OpenTypeFontFile& ot = *sanitized;
|
||||
|
||||
|
||||
switch (ot.get_tag ()) {
|
||||
switch (ot.get_tag ())
|
||||
{
|
||||
case OpenTypeFontFile::TrueTypeTag:
|
||||
printf ("OpenType font with TrueType outlines\n");
|
||||
break;
|
||||
|
@ -91,20 +93,23 @@ main (int argc, char **argv)
|
|||
|
||||
int num_fonts = ot.get_face_count ();
|
||||
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);
|
||||
printf ("Font %d of %d:\n", n_font, num_fonts);
|
||||
|
||||
int num_tables = font.get_table_count ();
|
||||
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);
|
||||
printf (" Table %2d of %2d: %.4s (0x%08x+0x%08x)\n", n_table, num_tables,
|
||||
(const char *) table.tag,
|
||||
(unsigned int) table.offset,
|
||||
(unsigned int) table.length);
|
||||
|
||||
switch (table.tag) {
|
||||
switch (table.tag)
|
||||
{
|
||||
|
||||
case HB_OT_TAG_GSUB:
|
||||
case HB_OT_TAG_GPOS:
|
||||
|
@ -114,10 +119,11 @@ main (int argc, char **argv)
|
|||
|
||||
int num_scripts = g.get_script_count ();
|
||||
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);
|
||||
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())
|
||||
printf (" No default language system\n");
|
||||
|
@ -140,34 +146,37 @@ main (int argc, char **argv)
|
|||
|
||||
int num_features = langsys.get_feature_count ();
|
||||
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,
|
||||
langsys.get_feature_index (n_feature));
|
||||
langsys.get_feature_index (n_feature));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int num_features = g.get_feature_count ();
|
||||
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);
|
||||
int num_lookups = feature.get_lookup_count ();
|
||||
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);
|
||||
for (int n_lookup = 0; n_lookup < num_lookups; n_lookup++) {
|
||||
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 ();
|
||||
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);
|
||||
printf (" Lookup %2d of %2d: type %d, props 0x%04X\n", n_lookup, num_lookups,
|
||||
lookup.get_type(), lookup.get_props());
|
||||
lookup.get_type(), lookup.get_props());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -87,5 +87,9 @@ main (int argc, char **argv)
|
|||
assert (hb_add (2) (5) == 7);
|
||||
assert (hb_add (5) (2) == 7);
|
||||
|
||||
x = 1;
|
||||
assert (++hb_inc (x) == 3);
|
||||
assert (x == 3);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -234,7 +234,7 @@ main (int argc, char **argv)
|
|||
{
|
||||
hb_set_t *set = hb_set_create ();
|
||||
for (unsigned int i = 0; i < temp1; ++i)
|
||||
hb_set_add (set, i);
|
||||
hb_set_add (set, i);
|
||||
temp1++;
|
||||
return set;
|
||||
})
|
||||
|
@ -267,7 +267,12 @@ main (int argc, char **argv)
|
|||
hb_iota ();
|
||||
hb_iota (3);
|
||||
hb_iota (3, 2);
|
||||
assert ((&vl) + 1 == *++hb_iota (&vl, hb_inc));
|
||||
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 (2, 9).len () == 7);
|
||||
assert (hb_range (2, 9, 3).len () == 3);
|
||||
|
|
|
@ -0,0 +1,253 @@
|
|||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
#include "hb-number.hh"
|
||||
#include "hb-number-parser.hh"
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
{
|
||||
const char str[] = "123";
|
||||
const char *pp = str;
|
||||
const char *end = str + 3;
|
||||
|
||||
int pv;
|
||||
assert (hb_parse_int (&pp, end, &pv));
|
||||
assert (pv == 123);
|
||||
assert (pp - str == 3);
|
||||
assert (end - pp == 0);
|
||||
assert (!*end);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "123";
|
||||
const char *pp = str;
|
||||
const char *end = str + strlen (str);
|
||||
|
||||
unsigned int pv;
|
||||
assert (hb_parse_uint (&pp, end, &pv));
|
||||
assert (pv == 123);
|
||||
assert (pp - str == 3);
|
||||
assert (end - pp == 0);
|
||||
assert (!*end);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "12F";
|
||||
const char *pp = str;
|
||||
const char *end = str + 3;
|
||||
|
||||
unsigned int pv;
|
||||
assert (hb_parse_uint (&pp, end, &pv, true, 16));
|
||||
assert (pv == 0x12F);
|
||||
assert (pp - str == 3);
|
||||
assert (end - pp == 0);
|
||||
assert (!*end);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "12Fq";
|
||||
const char *pp = str;
|
||||
const char *end = str + 4;
|
||||
|
||||
unsigned int pv;
|
||||
assert (!hb_parse_uint (&pp, end, &pv, true, 16));
|
||||
assert (hb_parse_uint (&pp, end, &pv, false, 16));
|
||||
assert (pv == 0x12F);
|
||||
assert (pp - str == 3);
|
||||
assert (end - pp == 1);
|
||||
assert (!*end);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "-123";
|
||||
const char *pp = str;
|
||||
const char *end = str + 4;
|
||||
|
||||
int pv;
|
||||
assert (hb_parse_int (&pp, end, &pv));
|
||||
assert (pv == -123);
|
||||
assert (pp - str == 4);
|
||||
assert (end - pp == 0);
|
||||
assert (!*end);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "123";
|
||||
const char *pp = str;
|
||||
assert (ARRAY_LENGTH (str) == 4);
|
||||
const char *end = str + ARRAY_LENGTH (str);
|
||||
|
||||
unsigned int pv;
|
||||
assert (hb_parse_uint (&pp, end, &pv));
|
||||
assert (pv == 123);
|
||||
assert (pp - str == 3);
|
||||
assert (end - pp == 1);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "123\0";
|
||||
const char *pp = str;
|
||||
assert (ARRAY_LENGTH (str) == 5);
|
||||
const char *end = str + ARRAY_LENGTH (str);
|
||||
|
||||
unsigned int pv;
|
||||
assert (hb_parse_uint (&pp, end, &pv));
|
||||
assert (pv == 123);
|
||||
assert (pp - str == 3);
|
||||
assert (end - pp == 2);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "123V";
|
||||
const char *pp = str;
|
||||
assert (ARRAY_LENGTH (str) == 5);
|
||||
const char *end = str + ARRAY_LENGTH (str);
|
||||
|
||||
unsigned int pv;
|
||||
assert (hb_parse_uint (&pp, end, &pv));
|
||||
assert (pv == 123);
|
||||
assert (pp - str == 3);
|
||||
assert (end - pp == 2);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = ".123";
|
||||
const char *pp = str;
|
||||
const char *end = str + ARRAY_LENGTH (str);
|
||||
|
||||
double pv;
|
||||
assert (hb_parse_double (&pp, end, &pv));
|
||||
assert ((int) roundf (pv * 1000.) == 123);
|
||||
assert (pp - str == 4);
|
||||
assert (end - pp == 1);
|
||||
|
||||
/* Test strtod_rl even if libc's strtod_l is used */
|
||||
char *pend;
|
||||
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||
assert (pend - str == 4);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "0.123";
|
||||
const char *pp = str;
|
||||
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||
|
||||
double pv;
|
||||
assert (hb_parse_double (&pp, end, &pv));
|
||||
assert ((int) roundf (pv * 1000.) == 123);
|
||||
assert (pp - str == 5);
|
||||
assert (end - pp == 0);
|
||||
|
||||
char *pend;
|
||||
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||
assert (pend - str == 5);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "0.123e0";
|
||||
const char *pp = str;
|
||||
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||
|
||||
double pv;
|
||||
assert (hb_parse_double (&pp, end, &pv));
|
||||
assert ((int) roundf (pv * 1000.) == 123);
|
||||
assert (pp - str == 7);
|
||||
assert (end - pp == 0);
|
||||
|
||||
char *pend;
|
||||
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||
assert (pend - str == 7);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "123e-3";
|
||||
const char *pp = str;
|
||||
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||
|
||||
double pv;
|
||||
assert (hb_parse_double (&pp, end, &pv));
|
||||
assert ((int) roundf (pv * 1000.) == 123);
|
||||
assert (pp - str == 6);
|
||||
assert (end - pp == 0);
|
||||
|
||||
char *pend;
|
||||
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||
assert (pend - str == 6);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = ".000123e+3";
|
||||
const char *pp = str;
|
||||
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||
|
||||
double pv;
|
||||
assert (hb_parse_double (&pp, end, &pv));
|
||||
assert ((int) roundf (pv * 1000.) == 123);
|
||||
assert (pp - str == 10);
|
||||
assert (end - pp == 0);
|
||||
|
||||
char *pend;
|
||||
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
|
||||
assert (pend - str == 10);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "-.000000123e6";
|
||||
const char *pp = str;
|
||||
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||
|
||||
double pv;
|
||||
assert (hb_parse_double (&pp, end, &pv));
|
||||
assert ((int) roundf (pv * 1000.) == -123);
|
||||
assert (pp - str == 13);
|
||||
assert (end - pp == 0);
|
||||
|
||||
char *pend;
|
||||
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
|
||||
assert (pend - str == 13);
|
||||
}
|
||||
|
||||
{
|
||||
const char str[] = "-1.23E-1";
|
||||
const char *pp = str;
|
||||
const char *end = str + ARRAY_LENGTH (str) - 1;
|
||||
|
||||
double pv;
|
||||
assert (hb_parse_double (&pp, end, &pv));
|
||||
assert ((int) roundf (pv * 1000.) == -123);
|
||||
assert (pp - str == 8);
|
||||
assert (end - pp == 0);
|
||||
|
||||
char *pend;
|
||||
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
|
||||
assert (pend - str == 8);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -351,9 +351,6 @@ test_ot_tag_language (void)
|
|||
test_tag_from_language ("ZHH", "yue-Hant");
|
||||
test_tag_from_language ("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 ("ABCD", "x-hbotabcd");
|
||||
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc");
|
||||
|
|
Binary file not shown.
|
@ -39,7 +39,12 @@ def cmd (command):
|
|||
timer.start()
|
||||
p.wait ()
|
||||
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
|
||||
finally:
|
||||
timer.cancel()
|
||||
|
|
|
@ -39,7 +39,12 @@ def cmd(command):
|
|||
timer.start()
|
||||
p.wait ()
|
||||
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
|
||||
finally:
|
||||
timer.cancel()
|
||||
|
|
|
@ -6,7 +6,8 @@ CLEANFILES =
|
|||
SUBDIRS = data
|
||||
|
||||
# Convenience targets:
|
||||
lib:
|
||||
lib: libs # Always build subsetter lib in this subdir
|
||||
libs:
|
||||
@$(MAKE) $(AM_MAKEFLAGS) -C $(top_builddir)/src libs
|
||||
|
||||
EXTRA_DIST += \
|
||||
|
|
|
@ -14,6 +14,8 @@ EXTRA_DIST += \
|
|||
expected/cff-japanese \
|
||||
expected/layout \
|
||||
expected/layout.gpos \
|
||||
expected/layout.gpos3 \
|
||||
expected/cmap14 \
|
||||
fonts \
|
||||
profiles \
|
||||
$(NULL)
|
||||
|
|
|
@ -6,6 +6,8 @@ TESTS = \
|
|||
tests/cff-japanese.tests \
|
||||
tests/layout.tests \
|
||||
tests/layout.gpos.tests \
|
||||
tests/layout.gpos3.tests \
|
||||
tests/cmap14.tests \
|
||||
$(NULL)
|
||||
|
||||
XFAIL_TESTS = \
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue