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

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

View File

@ -22,15 +22,16 @@ jobs:
- run: make -j4
- run: make 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

View File

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

View File

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

@ -1,3 +1,9 @@
Overview of changes leading to 2.6.2
Monday, September 30, 2019
====================================
- Misc small fixes, mostly to build-related issues.
Overview of changes leading to 2.6.1
Thursday, August 22, 2019
====================================

View File

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

View File

@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_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

View File

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

View File

@ -411,7 +411,7 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
dump_use_data_CPPFLAGS = $(HBCFLAGS)
dump_use_data_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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -48,7 +48,6 @@
#endif /* HAVE_SYS_MMAN_H */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>

View File

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

View File

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

View File

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

View File

@ -94,130 +94,52 @@ struct dict_opset_t : opset_t<number_t>
}
}
/* Turns CFF's BCD format into strtod understandable string */
static double parse_bcd (byte_str_ref_t& str_ref)
{
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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

@ -0,0 +1,240 @@
#line 1 "hb-number-parser.rl"
/*
* Copyright © 2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
#ifndef HB_NUMBER_PARSER_HH
#define HB_NUMBER_PARSER_HH
#include "hb.hh"
#include <float.h>
#line 37 "hb-number-parser.hh"
static const unsigned char _double_parser_trans_keys[] = {
0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
46u, 101u, 0
};
static const char _double_parser_key_spans[] = {
0, 15, 12, 10, 15, 10, 54, 10,
56
};
static const unsigned char _double_parser_index_offsets[] = {
0, 0, 16, 29, 40, 56, 67, 122,
133
};
static const char _double_parser_indicies[] = {
0, 1, 2, 3, 1, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4,
1, 3, 1, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 1, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5,
1, 6, 1, 7, 1, 1, 8, 8,
8, 8, 8, 8, 8, 8, 8, 8,
1, 8, 8, 8, 8, 8, 8, 8,
8, 8, 8, 1, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 9, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 9, 1, 8, 8, 8, 8, 8,
8, 8, 8, 8, 8, 1, 3, 1,
4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 9, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 9, 1, 0
};
static const char _double_parser_trans_targs[] = {
2, 0, 2, 3, 8, 6, 5, 5,
7, 4
};
static const char _double_parser_trans_actions[] = {
0, 0, 1, 0, 2, 3, 0, 4,
5, 0
};
static const int double_parser_start = 1;
static const int double_parser_first_final = 6;
static const int double_parser_error = 0;
static const int double_parser_en_main = 1;
#line 70 "hb-number-parser.rl"
/* Works only for n < 512 */
static inline double
_pow10 (unsigned int exponent)
{
static const double _powers_of_10[] =
{
1.0e+256,
1.0e+128,
1.0e+64,
1.0e+32,
1.0e+16,
1.0e+8,
10000.,
100.,
10.
};
unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
double result = 1;
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
if (exponent & mask) result *= *power;
return result;
}
static inline double
strtod_rl (const char *buf, char **end_ptr)
{
const char *p, *pe;
double value = 0;
double frac = 0;
double frac_count = 0;
unsigned int exp = 0;
bool neg = false, exp_neg = false, exp_overflow = false;
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
p = buf;
pe = p + strlen (p);
while (p < pe && ISSPACE (*p))
p++;
int cs;
#line 142 "hb-number-parser.hh"
{
cs = double_parser_start;
}
#line 147 "hb-number-parser.hh"
{
int _slen;
int _trans;
const unsigned char *_keys;
const char *_inds;
if ( p == pe )
goto _test_eof;
if ( cs == 0 )
goto _out;
_resume:
_keys = _double_parser_trans_keys + (cs<<1);
_inds = _double_parser_indicies + _double_parser_index_offsets[cs];
_slen = _double_parser_key_spans[cs];
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
(*p) <= _keys[1] ?
(*p) - _keys[0] : _slen ];
cs = _double_parser_trans_targs[_trans];
if ( _double_parser_trans_actions[_trans] == 0 )
goto _again;
switch ( _double_parser_trans_actions[_trans] ) {
case 1:
#line 39 "hb-number-parser.rl"
{ neg = true; }
break;
case 4:
#line 40 "hb-number-parser.rl"
{ exp_neg = true; }
break;
case 2:
#line 42 "hb-number-parser.rl"
{
value = value * 10. + ((*p) - '0');
}
break;
case 3:
#line 45 "hb-number-parser.rl"
{
if (likely (frac <= MAX_FRACT / 10))
{
frac = frac * 10. + ((*p) - '0');
++frac_count;
}
}
break;
case 5:
#line 52 "hb-number-parser.rl"
{
if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
exp = exp * 10 + ((*p) - '0');
else
exp_overflow = true;
}
break;
#line 205 "hb-number-parser.hh"
}
_again:
if ( cs == 0 )
goto _out;
if ( ++p != pe )
goto _resume;
_test_eof: {}
_out: {}
}
#line 116 "hb-number-parser.rl"
*end_ptr = (char *) p;
if (frac_count) value += frac / _pow10 (frac_count);
if (neg) value *= -1.;
if (unlikely (exp_overflow))
{
if (value == 0) return value;
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
else return neg ? -DBL_MAX : DBL_MAX;
}
if (exp)
{
if (exp_neg) value /= _pow10 (exp);
else value *= _pow10 (exp);
}
return value;
}
#endif /* HB_NUMBER_PARSER_HH */

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

@ -0,0 +1,139 @@
/*
* Copyright © 2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
#ifndef HB_NUMBER_PARSER_HH
#define HB_NUMBER_PARSER_HH
#include "hb.hh"
#include <float.h>
%%{
machine double_parser;
alphtype unsigned char;
write data;
action see_neg { neg = true; }
action see_exp_neg { exp_neg = true; }
action add_int {
value = value * 10. + (fc - '0');
}
action add_frac {
if (likely (frac <= MAX_FRACT / 10))
{
frac = frac * 10. + (fc - '0');
++frac_count;
}
}
action add_exp {
if (likely (exp * 10 + (fc - '0') <= MAX_EXP))
exp = exp * 10 + (fc - '0');
else
exp_overflow = true;
}
num = [0-9]+;
main := (
(
(('+'|'-'@see_neg)? num @add_int) ('.' num @add_frac)?
|
(('+'|'-'@see_neg)? '.' num @add_frac)
)
(('e'|'E') (('+'|'-'@see_exp_neg)? num @add_exp))?
);
}%%
/* Works only for n < 512 */
static inline double
_pow10 (unsigned int exponent)
{
static const double _powers_of_10[] =
{
1.0e+256,
1.0e+128,
1.0e+64,
1.0e+32,
1.0e+16,
1.0e+8,
10000.,
100.,
10.
};
unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
double result = 1;
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
if (exponent & mask) result *= *power;
return result;
}
static inline double
strtod_rl (const char *buf, char **end_ptr)
{
const char *p, *pe;
double value = 0;
double frac = 0;
double frac_count = 0;
unsigned int exp = 0;
bool neg = false, exp_neg = false, exp_overflow = false;
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
p = buf;
pe = p + strlen (p);
while (p < pe && ISSPACE (*p))
p++;
int cs;
%%{
write init;
write exec;
}%%
*end_ptr = (char *) p;
if (frac_count) value += frac / _pow10 (frac_count);
if (neg) value *= -1.;
if (unlikely (exp_overflow))
{
if (value == 0) return value;
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
else return neg ? -DBL_MAX : DBL_MAX;
}
if (exp)
{
if (exp_neg) value /= _pow10 (exp);
else value *= _pow10 (exp);
}
return value;
}
#endif /* HB_NUMBER_PARSER_HH */

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

@ -0,0 +1,147 @@
/*
* Copyright © 2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
#include "hb.hh"
#include "hb-machinery.hh"
#include "hb-number-parser.hh"
#include <locale.h>
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>
#endif
template<typename T, typename Func>
static bool
_parse_number (const char **pp, const char *end, T *pv,
bool whole_buffer, Func f)
{
char buf[32];
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1,
(unsigned int) (end - *pp));
strncpy (buf, *pp, len);
buf[len] = '\0';
char *p = buf;
char *pend = p;
errno = 0;
*pv = f (p, &pend);
if (unlikely (errno || p == pend ||
/* Check if consumed whole buffer if is requested */
(whole_buffer && pend - p != end - *pp))) return false;
*pp += pend - p;
return true;
}
bool
hb_parse_int (const char **pp, const char *end, int *pv, bool whole_buffer)
{
return _parse_number<int> (pp, end, pv, whole_buffer,
[] (const char *p, char **end)
{ return strtol (p, end, 10); });
}
bool
hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
bool whole_buffer, int base)
{
return _parse_number<unsigned int> (pp, end, pv, whole_buffer,
[base] (const char *p, char **end)
{ return strtoul (p, end, base); });
}
#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
#define USE_XLOCALE 1
#define HB_LOCALE_T locale_t
#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
#define HB_FREE_LOCALE(loc) freelocale (loc)
#elif defined(_MSC_VER)
#define USE_XLOCALE 1
#define HB_LOCALE_T _locale_t
#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
#define HB_FREE_LOCALE(loc) _free_locale (loc)
#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
#endif
#ifdef USE_XLOCALE
#if HB_USE_ATEXIT
static void free_static_C_locale ();
#endif
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
hb_C_locale_lazy_loader_t>
{
static HB_LOCALE_T create ()
{
HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
#if HB_USE_ATEXIT
atexit (free_static_C_locale);
#endif
return C_locale;
}
static void destroy (HB_LOCALE_T p)
{
HB_FREE_LOCALE (p);
}
static HB_LOCALE_T get_null ()
{
return nullptr;
}
} static_C_locale;
#if HB_USE_ATEXIT
static
void free_static_C_locale ()
{
static_C_locale.free_instance ();
}
#endif
static HB_LOCALE_T
get_C_locale ()
{
return static_C_locale.get_unconst ();
}
#endif /* USE_XLOCALE */
bool
hb_parse_double (const char **pp, const char *end, double *pv,
bool whole_buffer)
{
return _parse_number<double> (pp, end, pv, whole_buffer,
[] (const char *p, char **end)
{
#ifdef USE_XLOCALE
return strtod_l (p, end, get_C_locale ());
#else
return strtod_rl (p, end);
#endif
});
}

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

@ -0,0 +1,41 @@
/*
* Copyright © 2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
#ifndef HB_NUMBER_HH
#define HB_NUMBER_HH
HB_INTERNAL bool
hb_parse_int (const char **pp, const char *end, int *pv,
bool whole_buffer = false);
HB_INTERNAL bool
hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
bool whole_buffer = false, int base = 10);
HB_INTERNAL bool
hb_parse_double (const char **pp, const char *end, double *pv,
bool whole_buffer = false);
#endif /* HB_NUMBER_HH */

View File

@ -287,7 +287,7 @@ struct ResourceRecord
{ return CastR<OpenTypeFontFace> ((data_base+offset).arrayZ); }
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) &&

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1227,7 +1227,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
* @glyphs_output: (out): Array of glyphs that would be the substitued output of the lookup
*
* 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.

View File

@ -191,7 +191,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
feature_infos[j].max_value = feature_infos[i].max_value;
feature_infos[j].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 */
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

@ -0,0 +1,253 @@
/*
* Copyright © 2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
*/
#include "hb.hh"
#include "hb-number.hh"
#include "hb-number-parser.hh"
int
main (int argc, char **argv)
{
{
const char str[] = "123";
const char *pp = str;
const char *end = str + 3;
int pv;
assert (hb_parse_int (&pp, end, &pv));
assert (pv == 123);
assert (pp - str == 3);
assert (end - pp == 0);
assert (!*end);
}
{
const char str[] = "123";
const char *pp = str;
const char *end = str + strlen (str);
unsigned int pv;
assert (hb_parse_uint (&pp, end, &pv));
assert (pv == 123);
assert (pp - str == 3);
assert (end - pp == 0);
assert (!*end);
}
{
const char str[] = "12F";
const char *pp = str;
const char *end = str + 3;
unsigned int pv;
assert (hb_parse_uint (&pp, end, &pv, true, 16));
assert (pv == 0x12F);
assert (pp - str == 3);
assert (end - pp == 0);
assert (!*end);
}
{
const char str[] = "12Fq";
const char *pp = str;
const char *end = str + 4;
unsigned int pv;
assert (!hb_parse_uint (&pp, end, &pv, true, 16));
assert (hb_parse_uint (&pp, end, &pv, false, 16));
assert (pv == 0x12F);
assert (pp - str == 3);
assert (end - pp == 1);
assert (!*end);
}
{
const char str[] = "-123";
const char *pp = str;
const char *end = str + 4;
int pv;
assert (hb_parse_int (&pp, end, &pv));
assert (pv == -123);
assert (pp - str == 4);
assert (end - pp == 0);
assert (!*end);
}
{
const char str[] = "123";
const char *pp = str;
assert (ARRAY_LENGTH (str) == 4);
const char *end = str + ARRAY_LENGTH (str);
unsigned int pv;
assert (hb_parse_uint (&pp, end, &pv));
assert (pv == 123);
assert (pp - str == 3);
assert (end - pp == 1);
}
{
const char str[] = "123\0";
const char *pp = str;
assert (ARRAY_LENGTH (str) == 5);
const char *end = str + ARRAY_LENGTH (str);
unsigned int pv;
assert (hb_parse_uint (&pp, end, &pv));
assert (pv == 123);
assert (pp - str == 3);
assert (end - pp == 2);
}
{
const char str[] = "123V";
const char *pp = str;
assert (ARRAY_LENGTH (str) == 5);
const char *end = str + ARRAY_LENGTH (str);
unsigned int pv;
assert (hb_parse_uint (&pp, end, &pv));
assert (pv == 123);
assert (pp - str == 3);
assert (end - pp == 2);
}
{
const char str[] = ".123";
const char *pp = str;
const char *end = str + ARRAY_LENGTH (str);
double pv;
assert (hb_parse_double (&pp, end, &pv));
assert ((int) roundf (pv * 1000.) == 123);
assert (pp - str == 4);
assert (end - pp == 1);
/* Test strtod_rl even if libc's strtod_l is used */
char *pend;
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
assert (pend - str == 4);
}
{
const char str[] = "0.123";
const char *pp = str;
const char *end = str + ARRAY_LENGTH (str) - 1;
double pv;
assert (hb_parse_double (&pp, end, &pv));
assert ((int) roundf (pv * 1000.) == 123);
assert (pp - str == 5);
assert (end - pp == 0);
char *pend;
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
assert (pend - str == 5);
}
{
const char str[] = "0.123e0";
const char *pp = str;
const char *end = str + ARRAY_LENGTH (str) - 1;
double pv;
assert (hb_parse_double (&pp, end, &pv));
assert ((int) roundf (pv * 1000.) == 123);
assert (pp - str == 7);
assert (end - pp == 0);
char *pend;
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
assert (pend - str == 7);
}
{
const char str[] = "123e-3";
const char *pp = str;
const char *end = str + ARRAY_LENGTH (str) - 1;
double pv;
assert (hb_parse_double (&pp, end, &pv));
assert ((int) roundf (pv * 1000.) == 123);
assert (pp - str == 6);
assert (end - pp == 0);
char *pend;
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
assert (pend - str == 6);
}
{
const char str[] = ".000123e+3";
const char *pp = str;
const char *end = str + ARRAY_LENGTH (str) - 1;
double pv;
assert (hb_parse_double (&pp, end, &pv));
assert ((int) roundf (pv * 1000.) == 123);
assert (pp - str == 10);
assert (end - pp == 0);
char *pend;
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == 123);
assert (pend - str == 10);
}
{
const char str[] = "-.000000123e6";
const char *pp = str;
const char *end = str + ARRAY_LENGTH (str) - 1;
double pv;
assert (hb_parse_double (&pp, end, &pv));
assert ((int) roundf (pv * 1000.) == -123);
assert (pp - str == 13);
assert (end - pp == 0);
char *pend;
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
assert (pend - str == 13);
}
{
const char str[] = "-1.23E-1";
const char *pp = str;
const char *end = str + ARRAY_LENGTH (str) - 1;
double pv;
assert (hb_parse_double (&pp, end, &pv));
assert ((int) roundf (pv * 1000.) == -123);
assert (pp - str == 8);
assert (end - pp == 0);
char *pend;
assert ((int) roundf (strtod_rl (str, &pend) * 1000.) == -123);
assert (pend - str == 8);
}
return 0;
}

View File

@ -351,9 +351,6 @@ test_ot_tag_language (void)
test_tag_from_language ("ZHH", "yue-Hant");
test_tag_from_language ("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");

View File

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

View File

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

View File

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

View File

@ -14,6 +14,8 @@ EXTRA_DIST += \
expected/cff-japanese \
expected/layout \
expected/layout.gpos \
expected/layout.gpos3 \
expected/cmap14 \
fonts \
profiles \
$(NULL)

View File

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

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