Bug 1585138 - Update HarfBuzz to 2.6.2. r=jfkthame

Differential Revision: https://phabricator.services.mozilla.com/D47665

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ryan VanderMeulen 2019-10-01 09:18:54 +00:00
parent c23b90b0da
commit 5611980e6c
109 changed files with 2746 additions and 1402 deletions

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

@ -1,7 +1,7 @@
This directory contains the HarfBuzz source from the upstream repo:
https://github.com/harfbuzz/harfbuzz
Current version: 2.6.1 [commit be97e9d678017d4ec66625fa2b17ef3485552cad]
Current version: 2.6.2 [commit e48ef0804ad7e4abd35ff3646fa6ed10ad32f1ef]
UPDATING:

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

@ -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 \
@ -167,6 +169,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 \
@ -175,6 +178,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 \
@ -241,6 +245,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

@ -133,8 +133,8 @@ what = ["INDIC_SYLLABIC_CATEGORY", "INDIC_MATRA_CATEGORY"]
what_short = ["ISC", "IMC"]
print ('#pragma GCC diagnostic push')
print ('#pragma GCC diagnostic ignored "-Wunused-macros"')
cat_defs = []
for i in range (2):
print ()
vv = sorted (values[i].keys ())
for v in vv:
v_no_and = v.replace ('_And_', '_')
@ -146,10 +146,17 @@ for i in range (2):
raise Exception ("Duplicate short value alias", v, all_shorts[i][s])
all_shorts[i][s] = v
short[i][v] = s
print ("#define %s_%s %s_%s %s/* %3d chars; %s */" %
(what_short[i], s, what[i], v.upper (),
' '* ((48-1 - len (what[i]) - 1 - len (v)) // 8),
values[i][v], v))
cat_defs.append ((what_short[i] + '_' + s, what[i] + '_' + v.upper (), str (values[i][v]), v))
maxlen_s = max ([len (c[0]) for c in cat_defs])
maxlen_l = max ([len (c[1]) for c in cat_defs])
maxlen_n = max ([len (c[2]) for c in cat_defs])
for s in what_short:
print ()
for c in [c for c in cat_defs if s in c[0]]:
print ("#define %s %s /* %s chars; %s */" %
(c[0].ljust (maxlen_s), c[1].ljust (maxlen_l), c[2].rjust (maxlen_n), c[3]))
print ()
print ('#pragma GCC diagnostic pop')
print ()
print ("#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)")
@ -249,14 +256,14 @@ print ("}")
print ()
print ("#undef _")
for i in range (2):
print
print ()
vv = sorted (values[i].keys ())
for v in vv:
print ("#undef %s_%s" %
(what_short[i], short[i][v]))
print ()
print ()
print ('#endif')
print ()
print ("/* == End of generated table == */")
# Maintain at least 30% occupancy in the table */

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;
@ -830,7 +830,7 @@ struct KerxTable
for (unsigned int i = 0; i < count; i++)
{
if (st->get_type () == 1)
return true;
return true;
st = &StructAfter<SubTable> (*st);
}
return false;
@ -845,7 +845,7 @@ struct KerxTable
for (unsigned int i = 0; i < count; i++)
{
if (st->u.header.coverage & st->u.header.CrossStream)
return true;
return true;
st = &StructAfter<SubTable> (*st);
}
return false;
@ -862,7 +862,7 @@ struct KerxTable
{
if ((st->u.header.coverage & (st->u.header.Variation | st->u.header.CrossStream)) ||
!st->u.header.is_horizontal ())
continue;
continue;
v += st->get_kerning (left, right);
st = &StructAfter<SubTable> (*st);
}
@ -883,7 +883,7 @@ struct KerxTable
bool reverse;
if (!T::Types::extended && (st->u.header.coverage & st->u.header.Variation))
goto skip;
goto skip;
if (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) != st->u.header.is_horizontal ())
goto skip;
@ -897,8 +897,8 @@ struct KerxTable
if (!seenCrossStream &&
(st->u.header.coverage & st->u.header.CrossStream))
{
/* Attach all glyphs into a chain. */
seenCrossStream = true;
/* Attach all glyphs into a chain. */
seenCrossStream = true;
hb_glyph_position_t *pos = c->buffer->pos;
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++)

View File

@ -226,7 +226,7 @@ struct ContextualSubtable
hb_buffer_t *buffer = driver->buffer;
if (buffer->idx == buffer->len && !mark_set)
return false;
return false;
return entry.data.markIndex != 0xFFFF || entry.data.currentIndex != 0xFFFF;
}
@ -238,23 +238,23 @@ struct ContextualSubtable
/* Looks like CoreText applies neither mark nor current substitution for
* end-of-text if mark was not explicitly set. */
if (buffer->idx == buffer->len && !mark_set)
return;
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);
@ -488,7 +488,7 @@ struct LigatureSubtable
unsigned int ligature_idx = 0;
unsigned int action;
do
do
{
if (unlikely (!cursor))
{
@ -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:
@ -976,12 +976,12 @@ struct Chain
bool reverse;
if (!(subtable->subFeatureFlags & flags))
goto skip;
goto skip;
if (!(subtable->get_coverage() & ChainSubtable<Types>::AllDirections) &&
HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
bool (subtable->get_coverage() & ChainSubtable<Types>::Vertical))
goto skip;
goto skip;
/* Buffer contents is always in logical direction. Determine if
* we need to reverse before applying this subtable. We reverse
@ -1016,15 +1016,15 @@ struct Chain
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
goto skip;
goto skip;
if (reverse)
c->buffer->reverse ();
c->buffer->reverse ();
subtable->apply (c);
if (reverse)
c->buffer->reverse ();
c->buffer->reverse ();
(void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index);
@ -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,11 +120,11 @@ 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)
break;
break;
return roundf (interpolate_at (size_index ? size_index - 1 : 0, ptem,
*trackTableEntry, base));
@ -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>
@ -176,7 +176,7 @@ struct trak
hb_position_t advance_to_add = c->font->em_scalef_x (tracking);
foreach_grapheme (buffer, start, end)
{
if (!(buffer->info[start].mask & trak_mask)) continue;
if (!(buffer->info[start].mask & trak_mask)) continue;
buffer->pos[start].x_advance += advance_to_add;
buffer->pos[start].x_offset += offset_to_add;
}
@ -189,7 +189,7 @@ struct trak
hb_position_t advance_to_add = c->font->em_scalef_y (tracking);
foreach_grapheme (buffer, start, end)
{
if (!(buffer->info[start].mask & trak_mask)) continue;
if (!(buffer->info[start].mask & trak_mask)) continue;
buffer->pos[start].y_advance += advance_to_add;
buffer->pos[start].y_offset += offset_to_add;
}

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,19 @@ 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)>
const T *as () const
{ return length < hb_null_size (T) ? &Null (T) : reinterpret_cast<const T *> (arrayZ); }
/* Only call if you allocated the underlying array using malloc() or similar. */
void free ()
{ ::free ((void *) arrayZ); arrayZ = nullptr; length = 0; }
@ -228,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;
@ -241,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))>
@ -252,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)
{
@ -281,9 +291,9 @@ struct hb_sorted_array_t :
int mid = ((unsigned int) min + (unsigned int) max) / 2;
int c = array[mid].cmp (x);
if (c < 0)
max = mid - 1;
max = mid - 1;
else if (c > 0)
min = mid + 1;
min = mid + 1;
else
{
if (i)

View File

@ -48,7 +48,6 @@
#endif /* HAVE_SYS_MMAN_H */
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
@ -592,7 +591,7 @@ fail_without_close:
ceparams.lpSecurityAttributes = nullptr;
ceparams.hTemplateFile = nullptr;
fd = CreateFile2 (wchar_file_name, GENERIC_READ, FILE_SHARE_READ,
OPEN_EXISTING, &ceparams);
OPEN_EXISTING, &ceparams);
}
#else
fd = CreateFileW (wchar_file_name, GENERIC_READ, FILE_SHARE_READ, nullptr,
@ -669,7 +668,7 @@ fail_without_close:
}
return hb_blob_create (data, len, HB_MEMORY_MODE_WRITABLE, data,
(hb_destroy_func_t) free);
(hb_destroy_func_t) free);
fread_fail:
fclose (fp);

View File

@ -54,13 +54,9 @@ struct hb_blob_t
HB_INTERNAL bool try_make_writable_inplace ();
HB_INTERNAL bool try_make_writable_inplace_unix ();
hb_bytes_t as_bytes () const { return hb_bytes_t (data, length); }
template <typename Type>
const Type* as () const
{
return length < hb_null_size (Type) ? &Null(Type) : reinterpret_cast<const Type *> (data);
}
hb_bytes_t as_bytes () const
{ return hb_bytes_t (data, length); }
const Type* as () const { return as_bytes ().as<Type> (); }
public:
hb_object_header_t header;

View File

@ -135,7 +135,7 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
hb_font_glyph_to_string (font, info[i].codepoint, g, sizeof (g));
*p++ = '"';
for (char *q = g; *q; q++) {
if (*q == '"')
if (*q == '"')
*p++ = '\\';
*p++ = *q;
}
@ -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
@ -648,8 +649,8 @@ hb_buffer_t::guess_segment_properties ()
if (likely (script != HB_SCRIPT_COMMON &&
script != HB_SCRIPT_INHERITED &&
script != HB_SCRIPT_UNKNOWN)) {
props.script = script;
break;
props.script = script;
break;
}
}
}
@ -1388,7 +1389,7 @@ hb_buffer_get_length (hb_buffer_t *buffer)
**/
hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
unsigned int *length)
unsigned int *length)
{
if (length)
*length = buffer->len;
@ -1412,7 +1413,7 @@ hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
**/
hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
unsigned int *length)
unsigned int *length)
{
if (!buffer->have_positions)
buffer->clear_positions ();
@ -1936,9 +1937,9 @@ hb_buffer_diff (hb_buffer_t *buffer,
for (i = 0; i < count; i++)
{
if (contains && info[i].codepoint == dottedcircle_glyph)
result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
result |= HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT;
if (contains && info[i].codepoint == 0)
result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
result |= HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT;
}
result |= HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH;
return hb_buffer_diff_flags_t (result);
@ -1973,12 +1974,12 @@ hb_buffer_diff (hb_buffer_t *buffer,
for (unsigned int i = 0; i < count; i++)
{
if ((unsigned int) abs (buf_pos->x_advance - ref_pos->x_advance) > position_fuzz ||
(unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
(unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
(unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
(unsigned int) abs (buf_pos->y_advance - ref_pos->y_advance) > position_fuzz ||
(unsigned int) abs (buf_pos->x_offset - ref_pos->x_offset) > position_fuzz ||
(unsigned int) abs (buf_pos->y_offset - ref_pos->y_offset) > position_fuzz)
{
result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
break;
result |= HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH;
break;
}
buf_pos++;
ref_pos++;

View File

@ -441,11 +441,11 @@ hb_buffer_get_length (hb_buffer_t *buffer);
HB_EXTERN hb_glyph_info_t *
hb_buffer_get_glyph_infos (hb_buffer_t *buffer,
unsigned int *length);
unsigned int *length);
HB_EXTERN hb_glyph_position_t *
hb_buffer_get_glyph_positions (hb_buffer_t *buffer,
unsigned int *length);
unsigned int *length);
HB_EXTERN void

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"
@ -67,7 +63,7 @@ _hb_options_init ()
{
const char *p = strchr (c, ':');
if (!p)
p = c + strlen (c);
p = c + strlen (c);
#define OPTION(name, symbol) \
if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast<size_t>(p - c)) do { u.opts.symbol = true; } while (0)
@ -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;
}
@ -956,7 +846,7 @@ parse_feature_value_postfix (const char **pp, const char *end, hb_feature_t *fea
{
bool had_equal = parse_char (pp, end, '=');
bool had_value = parse_uint32 (pp, end, &feature->value) ||
parse_bool (pp, end, &feature->value);
parse_bool (pp, end, &feature->value);
/* CSS doesn't use equal-sign between tag and value.
* If there was an equal-sign, then there *must* be a value.
* A value without an equal-sign is ok, but not required. */
@ -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

@ -111,7 +111,7 @@ static void
release_data (void *info, const void *data, size_t size)
{
assert (hb_blob_get_length ((hb_blob_t *) info) == size &&
hb_blob_get_data ((hb_blob_t *) info, nullptr) == data);
hb_blob_get_data ((hb_blob_t *) info, nullptr) == data);
hb_blob_destroy ((hb_blob_t *) info);
}
@ -233,21 +233,21 @@ create_ct_font (CGFontRef cg_font, CGFloat font_size)
atsFont = CTFontGetPlatformFont (new_ct_font, NULL);
status = ATSFontGetFileReference (atsFont, &fsref);
if (status == noErr)
new_url = CFURLCreateFromFSRef (NULL, &fsref);
new_url = CFURLCreateFromFSRef (NULL, &fsref);
#else
new_url = (CFURLRef) CTFontCopyAttribute (new_ct_font, kCTFontURLAttribute);
#endif
// Keep reconfigured font if URL cannot be retrieved (seems to be the case
// on Mac OS 10.12 Sierra), speculative fix for crbug.com/625606
if (!original_url || !new_url || CFEqual (original_url, new_url)) {
CFRelease (ct_font);
ct_font = new_ct_font;
CFRelease (ct_font);
ct_font = new_ct_font;
} else {
CFRelease (new_ct_font);
DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
CFRelease (new_ct_font);
DEBUG_MSG (CORETEXT, ct_font, "Discarding reconfigured CTFont, location changed.");
}
if (new_url)
CFRelease (new_url);
CFRelease (new_url);
}
else
DEBUG_MSG (CORETEXT, ct_font, "Font copy with empty cascade list failed");
@ -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
@ -433,9 +433,9 @@ struct range_record_t {
hb_bool_t
_hb_coretext_shape (hb_shape_plan_t *shape_plan,
hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features)
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features)
{
hb_face_t *face = font->face;
CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
@ -477,7 +477,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
{
const hb_aat_feature_mapping_t * mapping = hb_aat_layout_find_feature_mapping (features[i].tag);
if (!mapping)
continue;
continue;
active_feature_t feature;
feature.rec.feature = mapping->aatFeatureType;
@ -519,7 +519,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
if (event->index != last_index)
{
/* Save a snapshot of active features and the range. */
/* Save a snapshot of active features and the range. */
range_record_t *range = range_records.push ();
if (active_features.length)
@ -580,9 +580,9 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
if (event->start)
{
active_features.push (event->feature);
active_features.push (event->feature);
} else {
active_feature_t *feature = active_features.find (&event->feature);
active_feature_t *feature = active_features.find (&event->feature);
if (feature)
active_features.remove (feature - active_features.arrayZ);
}
@ -700,15 +700,15 @@ resize_and_retry:
#if !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) && MAC_OS_X_VERSION_MIN_REQUIRED < 1090
# define kCTLanguageAttributeName CFSTR ("NSLanguage")
#endif
CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
CFStringRef lang = CFStringCreateWithCStringNoCopy (kCFAllocatorDefault,
hb_language_to_string (buffer->props.language),
kCFStringEncodingUTF8,
kCFAllocatorNull);
if (unlikely (!lang))
{
{
CFRelease (attr_string);
FAIL ("CFStringCreateWithCStringNoCopy failed");
}
}
CFAttributedStringSetAttribute (attr_string, CFRangeMake (0, chars_len),
kCTLanguageAttributeName, lang);
CFRelease (lang);
@ -757,7 +757,7 @@ resize_and_retry:
feature.start < chars_len && feature.start < feature.end)
{
CFRange feature_range = CFRangeMake (feature.start,
hb_min (feature.end, chars_len) - feature.start);
hb_min (feature.end, chars_len) - feature.start);
if (feature.value)
CFAttributedStringRemoveAttribute (attr_string, feature_range, kCTKernAttributeName);
else
@ -781,8 +781,8 @@ resize_and_retry:
CFRelease (level_number);
if (unlikely (!options))
{
CFRelease (attr_string);
FAIL ("CFDictionaryCreate failed");
CFRelease (attr_string);
FAIL ("CFDictionaryCreate failed");
}
CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedStringAndOptions (attr_string, options);
@ -893,7 +893,7 @@ resize_and_retry:
if (!matched)
{
CFRange range = CTRunGetStringRange (run);
DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
DEBUG_MSG (CORETEXT, run, "Run used fallback font: %ld..%ld",
range.location, range.location + range.length);
if (!buffer->ensure_inplace (buffer->len + range.length))
goto resize_and_retry;
@ -921,7 +921,7 @@ resize_and_retry:
continue;
}
if (buffer->unicode->is_default_ignorable (ch))
continue;
continue;
info->codepoint = notdef;
info->cluster = log_clusters[j];
@ -966,7 +966,7 @@ resize_and_retry:
scratch = scratch_saved
{ /* Setup glyphs */
SCRATCH_SAVE();
SCRATCH_SAVE();
const CGGlyph* glyphs = USE_PTR ? CTRunGetGlyphsPtr (run) : nullptr;
if (!glyphs) {
ALLOCATE_ARRAY (CGGlyph, glyph_buf, num_glyphs, goto resize_and_retry);
@ -989,12 +989,12 @@ resize_and_retry:
SCRATCH_RESTORE();
}
{
/* Setup positions.
/* Setup positions.
* Note that CoreText does not return advances for glyphs. As such,
* for all but last glyph, we use the delta position to next glyph as
* advance (in the advance direction only), and for last glyph we set
* whatever is needed to make the whole run's advance add up. */
SCRATCH_SAVE();
SCRATCH_SAVE();
const CGPoint* positions = USE_PTR ? CTRunGetPositionsPtr (run) : nullptr;
if (!positions) {
ALLOCATE_ARRAY (CGPoint, position_buf, num_glyphs, goto resize_and_retry);

View File

@ -296,22 +296,23 @@ struct hb_auto_trace_t
if (plevel) --*plevel;
}
ret_t ret (ret_t v,
const char *func = "",
unsigned int line = 0)
template <typename T>
T ret (T&& v,
const char *func = "",
unsigned int line = 0)
{
if (unlikely (returned)) {
fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n");
return v;
return hb_forward<T> (v);
}
_hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1,
"return %s (line %d)",
hb_printer_t<ret_t>().print (v), line);
hb_printer_t<decltype (v)>().print (v), line);
if (plevel) --*plevel;
plevel = nullptr;
returned = true;
return v;
return hb_forward<T> (v);
}
private:
@ -413,7 +414,7 @@ struct hb_no_trace_t {
#define TRACE_SANITIZE(this) \
hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
" ");
" ")
#else
#define TRACE_SANITIZE(this) hb_no_trace_t<bool> trace
#endif
@ -425,7 +426,7 @@ struct hb_no_trace_t {
#define TRACE_SERIALIZE(this) \
hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
(&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
" ");
" ")
#else
#define TRACE_SERIALIZE(this) hb_no_trace_t<bool> trace
#endif
@ -437,7 +438,7 @@ struct hb_no_trace_t {
#define TRACE_SUBSET(this) \
hb_auto_trace_t<HB_DEBUG_SUBSET, bool> trace \
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
" ");
" ")
#else
#define TRACE_SUBSET(this) hb_no_trace_t<bool> trace
#endif
@ -454,7 +455,7 @@ struct hb_no_trace_t {
#define TRACE_DISPATCH(this, format) \
hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
"format %d", (int) format);
"format %d", (int) format)
#else
#define TRACE_DISPATCH(this, format) hb_no_trace_t<typename context_t::return_t> trace
#endif

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

@ -41,7 +41,7 @@ struct hb_dispatch_context_t
private:
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
const Context* thiz () const { return static_cast<const Context *> (this); }
Context* thiz () { return static_cast< Context *> (this); }
Context* thiz () { return static_cast< Context *> (this); }
public:
static constexpr unsigned max_debug_depth = MaxDebugDepth;
typedef Return return_t;

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

@ -667,22 +667,22 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
#define HB_FONT_FUNC_IMPLEMENT(name) \
\
\
void \
hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
hb_font_get_##name##_func_t func, \
void *user_data, \
hb_destroy_func_t destroy) \
hb_font_get_##name##_func_t func, \
void *user_data, \
hb_destroy_func_t destroy) \
{ \
if (hb_object_is_immutable (ffuncs)) { \
if (destroy) \
destroy (user_data); \
return; \
} \
\
\
if (ffuncs->destroy.name) \
ffuncs->destroy.name (ffuncs->user_data.name); \
\
\
if (func) { \
ffuncs->get.f.name = func; \
ffuncs->user_data.name = user_data; \
@ -1676,8 +1676,8 @@ hb_font_set_funcs (hb_font_t *font,
**/
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)
{
/* Destroy user_data? */
if (hb_object_is_immutable (font))

View File

@ -471,7 +471,7 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
/* Check whether the given name was actually the name of glyph 0. */
char buf[128];
if (!FT_Get_Glyph_Name(ft_face, 0, buf, sizeof (buf)) &&
len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len))
len < 0 ? !strcmp (buf, name) : !strncmp (buf, name, len))
return true;
}
@ -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

@ -340,14 +340,14 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
c->num_glyphs = 0;
if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
{
c->advance = curradv - gr_slot_origin_X(is) * xscale;
curradv -= c->advance;
c->advance = curradv - gr_slot_origin_X(is) * xscale;
curradv -= c->advance;
}
else
{
c->advance = 0;
clusters[ci].advance += gr_slot_origin_X(is) * xscale - curradv;
curradv += clusters[ci].advance;
c->advance = 0;
clusters[ci].advance += gr_slot_origin_X(is) * xscale - curradv;
curradv += clusters[ci].advance;
}
ci++;
}

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;
@ -72,7 +72,7 @@ struct hb_iter_t
private:
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
const iter_t* thiz () const { return static_cast<const iter_t *> (this); }
iter_t* thiz () { return static_cast< iter_t *> (this); }
iter_t* thiz () { return static_cast< iter_t *> (this); }
public:
/* TODO:
@ -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__>
@ -183,7 +192,7 @@ struct hb_iter_fallback_mixin_t
private:
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
const iter_t* thiz () const { return static_cast<const iter_t *> (this); }
iter_t* thiz () { return static_cast< iter_t *> (this); }
iter_t* thiz () { return static_cast< iter_t *> (this); }
public:
/* Access: Implement __item__(), or __item_at__() if random-access. */
@ -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

@ -82,11 +82,11 @@ struct hb_kern_machine_t
if (likely (!kern))
goto skip;
goto skip;
if (horizontal)
{
if (scale)
if (scale)
kern = font->em_scale_x (kern);
if (crossStream)
{
@ -104,7 +104,7 @@ struct hb_kern_machine_t
}
else
{
if (scale)
if (scale)
kern = font->em_scale_y (kern);
if (crossStream)
{

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)
@ -225,7 +225,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
if (unlikely (!cmpexch (nullptr, p)))
{
do_destroy (p);
do_destroy (p);
goto retry;
}
}

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

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

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

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

@ -62,7 +62,7 @@ struct hb_lockable_set_t
old.fini ();
}
else {
item = nullptr;
item = nullptr;
l.unlock ();
}
} else {

View File

@ -92,9 +92,9 @@ typedef struct OffsetTable
if (table_count)
{
if (start_offset >= tables.len)
*table_count = 0;
*table_count = 0;
else
*table_count = hb_min (*table_count, tables.len - start_offset);
*table_count = hb_min (*table_count, tables.len - start_offset);
const TableRecord *sub_tables = tables.arrayZ + start_offset;
unsigned int count = *table_count;

View File

@ -63,6 +63,14 @@ struct IntType
operator wide_type () const { return v; }
bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
bool operator != (const IntType &o) const { return !(*this == o); }
IntType& operator += (unsigned count) { *this = *this + count; return *this; }
IntType& operator -= (unsigned count) { *this = *this - count; return *this; }
IntType& operator ++ () { *this += 1; return *this; }
IntType& operator -- () { *this -= 1; return *this; }
IntType operator ++ (int) { IntType c (*this); ++*this; return c; }
IntType operator -- (int) { IntType c (*this); --*this; return c; }
HB_INTERNAL static int cmp (const IntType *a, const IntType *b)
{ return b->cmp (*a); }
template <typename Type2>
@ -116,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); }
@ -155,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 */
@ -475,7 +483,7 @@ struct UnsizedArrayOf
}
public:
Type arrayZ[VAR];
Type arrayZ[HB_VAR_ARRAY];
public:
DEFINE_SIZE_UNBOUNDED (0);
};
@ -564,6 +572,8 @@ struct ArrayOf
explicit operator bool () const { return len; }
void pop () { len--; }
hb_array_t< Type> as_array () { return hb_array (arrayZ, len); }
hb_array_t<const Type> as_array () const { return hb_array (arrayZ, len); }
@ -606,6 +616,18 @@ struct ArrayOf
return_trace (true);
}
Type* serialize_append (hb_serialize_context_t *c)
{
TRACE_SERIALIZE (this);
len++;
if (unlikely (!len || !c->extend (*this)))
{
len--;
return_trace (nullptr);
}
return_trace (&arrayZ[len - 1]);
}
ArrayOf* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
@ -647,7 +669,7 @@ struct ArrayOf
public:
LenType len;
Type arrayZ[VAR];
Type arrayZ[HB_VAR_ARRAY];
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
};
@ -720,17 +742,40 @@ struct HeadlessArrayOf
return arrayZ[i-1];
}
unsigned int get_size () const
{ return lenP1.static_size + (lenP1 ? lenP1 - 1 : 0) * Type::static_size; }
{ return lenP1.static_size + get_length () * Type::static_size; }
bool serialize (hb_serialize_context_t *c,
hb_array_t<const Type> items)
unsigned get_length () const { return lenP1 ? lenP1 - 1 : 0; }
hb_array_t< Type> as_array () { return hb_array (arrayZ, get_length ()); }
hb_array_t<const Type> as_array () const { return hb_array (arrayZ, get_length ()); }
/* Iterator. */
typedef hb_array_t<const Type> iter_t;
typedef hb_array_t< Type> writer_t;
iter_t iter () const { return as_array (); }
writer_t writer () { return as_array (); }
operator iter_t () const { return iter (); }
operator writer_t () { return writer (); }
bool serialize (hb_serialize_context_t *c, unsigned int items_len)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
c->check_assign (lenP1, items.length + 1);
c->check_assign (lenP1, items_len + 1);
if (unlikely (!c->extend (*this))) return_trace (false);
for (unsigned int i = 0; i < items.length; i++)
arrayZ[i] = items[i];
return_trace (true);
}
template <typename Iterator,
hb_requires (hb_is_source_of (Iterator, Type))>
bool serialize (hb_serialize_context_t *c, Iterator items)
{
TRACE_SERIALIZE (this);
unsigned count = items.len ();
if (unlikely (!serialize (c, count))) return_trace (false);
/* TODO Umm. Just exhaust the iterator instead? Being extra
* cautious right now.. */
for (unsigned i = 0; i < count; i++, ++items)
arrayZ[i] = *items;
return_trace (true);
}
@ -740,7 +785,7 @@ struct HeadlessArrayOf
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
unsigned int count = lenP1 ? lenP1 - 1 : 0;
unsigned int count = get_length ();
for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
return_trace (false);
@ -757,7 +802,7 @@ struct HeadlessArrayOf
public:
LenType lenP1;
Type arrayZ[VAR];
Type arrayZ[HB_VAR_ARRAY];
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
};
@ -805,7 +850,7 @@ struct ArrayOfM1
public:
LenType lenM1;
Type arrayZ[VAR];
Type arrayZ[HB_VAR_ARRAY];
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), arrayZ);
};
@ -944,7 +989,7 @@ struct VarSizedBinSearchArrayOf
unsigned int count = Type::TerminationWordCount;
for (unsigned int i = 0; i < count; i++)
if (words[i] != 0xFFFFu)
return false;
return false;
return true;
}

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>

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

View File

@ -76,24 +76,24 @@ struct CmapSubtableFormat4
{
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
HBUINT16* serialize_endcode_array (hb_serialize_context_t *c,
Iterator it)
Iterator it)
{
HBUINT16 *endCode = c->start_embed<HBUINT16> ();
hb_codepoint_t prev_endcp = 0xFFFF;
+ it
| hb_apply ([&] (const hb_item_type<Iterator> _)
{
if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first)
{
HBUINT16 end_code;
end_code = prev_endcp;
c->copy<HBUINT16> (end_code);
}
prev_endcp = _.first;
})
{
if (prev_endcp != 0xFFFF && prev_endcp + 1u != _.first)
{
HBUINT16 end_code;
end_code = prev_endcp;
c->copy<HBUINT16> (end_code);
}
prev_endcp = _.first;
})
;
{
@ -104,9 +104,9 @@ struct CmapSubtableFormat4
// There must be a final entry with end_code == 0xFFFF.
if (prev_endcp != 0xFFFF)
{
HBUINT16 finalcode;
finalcode = 0xFFFF;
if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr;
HBUINT16 finalcode;
finalcode = 0xFFFF;
if (unlikely (!c->copy<HBUINT16> (finalcode))) return nullptr;
}
}
@ -114,25 +114,25 @@ struct CmapSubtableFormat4
}
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
HBUINT16* serialize_startcode_array (hb_serialize_context_t *c,
Iterator it)
Iterator it)
{
HBUINT16 *startCode = c->start_embed<HBUINT16> ();
hb_codepoint_t prev_cp = 0xFFFF;
+ it
| hb_apply ([&] (const hb_item_type<Iterator> _)
{
if (prev_cp == 0xFFFF || prev_cp + 1u != _.first)
{
HBUINT16 start_code;
start_code = _.first;
c->copy<HBUINT16> (start_code);
}
{
if (prev_cp == 0xFFFF || prev_cp + 1u != _.first)
{
HBUINT16 start_code;
start_code = _.first;
c->copy<HBUINT16> (start_code);
}
prev_cp = _.first;
})
prev_cp = _.first;
})
;
// There must be a final entry with end_code == 0xFFFF.
@ -147,44 +147,44 @@ struct CmapSubtableFormat4
}
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
HBINT16* serialize_idDelta_array (hb_serialize_context_t *c,
Iterator it,
HBUINT16 *endCode,
HBUINT16 *startCode,
unsigned segcount)
Iterator it,
HBUINT16 *endCode,
HBUINT16 *startCode,
unsigned segcount)
{
unsigned i = 0;
hb_codepoint_t last_gid = 0, start_gid = 0, last_cp = 0xFFFF;
bool use_delta = true;
HBINT16 *idDelta = c->start_embed<HBINT16> ();
if ((char *)idDelta - (char *)startCode != (int) segcount * (int) HBINT16::static_size)
return nullptr;
+ it
| hb_apply ([&] (const hb_item_type<Iterator> _)
{
if (_.first == startCode[i])
{
use_delta = true;
start_gid = _.second;
}
else if (_.second != last_gid + 1) use_delta = false;
{
if (_.first == startCode[i])
{
use_delta = true;
start_gid = _.second;
}
else if (_.second != last_gid + 1) use_delta = false;
if (_.first == endCode[i])
{
HBINT16 delta;
if (use_delta) delta = (int)start_gid - (int)startCode[i];
else delta = 0;
c->copy<HBINT16> (delta);
if (_.first == endCode[i])
{
HBINT16 delta;
if (use_delta) delta = (int)start_gid - (int)startCode[i];
else delta = 0;
c->copy<HBINT16> (delta);
i++;
}
i++;
}
last_gid = _.second;
last_cp = _.first;
})
last_gid = _.second;
last_cp = _.first;
})
;
if (it.len () == 0 || last_cp != 0xFFFF)
@ -198,43 +198,43 @@ struct CmapSubtableFormat4
}
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
HBUINT16* serialize_rangeoffset_glyid (hb_serialize_context_t *c,
Iterator it,
HBUINT16 *endCode,
HBUINT16 *startCode,
HBINT16 *idDelta,
unsigned segcount)
Iterator it,
HBUINT16 *endCode,
HBUINT16 *startCode,
HBINT16 *idDelta,
unsigned segcount)
{
HBUINT16 *idRangeOffset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segcount);
if (unlikely (!c->check_success (idRangeOffset))) return nullptr;
if (unlikely ((char *)idRangeOffset - (char *)idDelta != (int) segcount * (int) HBINT16::static_size)) return nullptr;
+ hb_range (segcount)
| hb_filter ([&] (const unsigned _) { return idDelta[_] == 0; })
| hb_apply ([&] (const unsigned i)
{
idRangeOffset[i] = 2 * (c->start_embed<HBUINT16> () - idRangeOffset - i);
{
idRangeOffset[i] = 2 * (c->start_embed<HBUINT16> () - idRangeOffset - i);
+ it
| hb_filter ([&] (const hb_item_type<Iterator> _) { return _.first >= startCode[i] && _.first <= endCode[i]; })
| hb_apply ([&] (const hb_item_type<Iterator> _)
{
HBUINT16 glyID;
glyID = _.second;
c->copy<HBUINT16> (glyID);
})
;
+ it
| hb_filter ([&] (const hb_item_type<Iterator> _) { return _.first >= startCode[i] && _.first <= endCode[i]; })
| hb_apply ([&] (const hb_item_type<Iterator> _)
{
HBUINT16 glyID;
glyID = _.second;
c->copy<HBUINT16> (glyID);
})
;
})
})
;
return idRangeOffset;
}
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it)
{
@ -247,21 +247,21 @@ struct CmapSubtableFormat4
if (unlikely (!endCode)) return;
unsigned segcount = (c->length () - min_size) / HBUINT16::static_size;
// 2 bytes of padding.
if (unlikely (!c->allocate_size<HBUINT16> (HBUINT16::static_size))) return; // 2 bytes of padding.
// serialize startCode[]
HBUINT16 *startCode = serialize_startcode_array (c, it);
if (unlikely (!startCode)) return;
//serialize idDelta[]
HBINT16 *idDelta = serialize_idDelta_array (c, it, endCode, startCode, segcount);
if (unlikely (!idDelta)) return;
HBUINT16 *idRangeOffset = serialize_rangeoffset_glyid (c, it, endCode, startCode, idDelta, segcount);
if (unlikely (!c->check_success (idRangeOffset))) return;
if (unlikely (!c->check_assign(this->length, c->length () - table_initpos))) return;
this->segCountX2 = segcount * 2;
this->entrySelector = hb_max (1u, hb_bit_storage (segcount)) - 1;
@ -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:
@ -557,7 +555,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it)
{
@ -570,30 +568,30 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
+ it
| hb_apply ([&] (const hb_item_type<Iterator> _)
{
if (startCharCode == 0xFFFF)
{
startCharCode = _.first;
endCharCode = _.first;
glyphID = _.second;
}
else if (!_is_gid_consecutive (endCharCode, startCharCode, glyphID, _.first, _.second))
{
CmapSubtableLongGroup grouprecord;
grouprecord.startCharCode = startCharCode;
grouprecord.endCharCode = endCharCode;
grouprecord.glyphID = glyphID;
c->copy<CmapSubtableLongGroup> (grouprecord);
{
if (startCharCode == 0xFFFF)
{
startCharCode = _.first;
endCharCode = _.first;
glyphID = _.second;
}
else if (!_is_gid_consecutive (endCharCode, startCharCode, glyphID, _.first, _.second))
{
CmapSubtableLongGroup grouprecord;
grouprecord.startCharCode = startCharCode;
grouprecord.endCharCode = endCharCode;
grouprecord.glyphID = glyphID;
c->copy<CmapSubtableLongGroup> (grouprecord);
startCharCode = _.first;
endCharCode = _.first;
glyphID = _.second;
}
else
{
endCharCode = _.first;
}
})
startCharCode = _.first;
endCharCode = _.first;
glyphID = _.second;
}
else
{
endCharCode = _.first;
}
})
;
CmapSubtableLongGroup record;
@ -609,14 +607,12 @@ 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,
hb_codepoint_t startCharCode,
hb_codepoint_t glyphID,
hb_codepoint_t cp,
hb_codepoint_t new_gid)
{
@ -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);
};
@ -694,7 +747,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 +761,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 +832,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 +842,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 +902,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 +912,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
@ -828,14 +1002,17 @@ struct CmapSubtable
}
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
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;
}
}
@ -892,14 +1069,17 @@ struct EncodingRecord
}
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
EncodingRecord* copy (hb_serialize_context_t *c,
Iterator it,
unsigned format,
void *base,
/* INOUT */ unsigned *objidx) const
Iterator it,
unsigned format,
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 +1088,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 +1115,40 @@ struct cmap
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
template<typename Iterator,
hb_requires (hb_is_iterator (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)
Iterator it,
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 +1158,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_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);
})
{ 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 +1257,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 +1269,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 +1326,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 +1378,7 @@ struct cmap
CmapSubtableFormat4::accelerator_t format4_accel;
public:
hb_blob_ptr_t<cmap> table;
};
@ -1181,7 +1399,7 @@ struct cmap
}
const EncodingRecord *find_encodingrec (unsigned int platform_id,
unsigned int encoding_id) const
unsigned int encoding_id) const
{
EncodingRecord key;
key.platformID = platform_id;

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);
@ -251,7 +251,7 @@ struct IndexSubtableArray
unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex)
return &indexSubtablesZ[i];
return &indexSubtablesZ[i];
}
return nullptr;
}
@ -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;

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

@ -147,7 +147,7 @@ struct CPAL
unsigned int count = hb_min ((unsigned) hb_max ((int) (numColors - start_offset), 0), *color_count);
*color_count = count;
for (unsigned int i = 0; i < count; i++)
colors[i] = segment_colors[i]; /* Bound-checked read. */
colors[i] = segment_colors[i]; /* Bound-checked read. */
}
return numColors;
}

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
@ -173,11 +173,11 @@ struct sbix
{
unsigned count = table->strikes.len;
if (unlikely (!count))
return Null(SBIXStrike);
return Null(SBIXStrike);
unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
if (!requested_ppem)
requested_ppem = 1<<30; /* Choose largest strike. */
requested_ppem = 1<<30; /* Choose largest strike. */
/* TODO Add DPI sensitivity as well? */
unsigned int best_i = 0;
unsigned int best_ppem = table->get_strike (0).ppem;
@ -201,7 +201,7 @@ struct sbix
HBUINT8 signature[8];
struct
{
struct
struct
{
HBUINT32 length;
Tag type;
@ -226,7 +226,7 @@ struct sbix
/* Following code is safe to call even without data.
* But faster to short-circuit. */
if (!has_data ())
return false;
return false;
int x_offset = 0, y_offset = 0;
unsigned int strike_ppem = 0;

View File

@ -208,20 +208,20 @@ hb_ot_get_glyph_extents (hb_font_t *font,
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
static hb_bool_t
hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
char *name, unsigned int size,
void *user_data HB_UNUSED)
void *font_data,
hb_codepoint_t glyph,
char *name, unsigned int size,
void *user_data HB_UNUSED)
{
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
return ot_face->post->get_glyph_name (glyph, name, size);
}
static hb_bool_t
hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
void *font_data,
const char *name, int len,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
void *font_data,
const char *name, int len,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
{
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
return ot_face->post->get_glyph_from_name (name, len, glyph);

View File

@ -1,5 +1,6 @@
/*
* Copyright © 2015 Google, Inc.
* Copyright © 2019 Ebrahim Byagowi
*
* This is part of HarfBuzz, a text shaping library.
*
@ -53,11 +54,12 @@ struct loca
}
protected:
UnsizedArrayOf<HBUINT8> dataZ; /* Location data. */
UnsizedArrayOf<HBUINT8>
dataZ; /* Location data. */
public:
DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
* check the size externally, allow Null() object of it by
* defining it _MIN instead. */
DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
* check the size externally, allow Null() object of it by
* defining it _MIN instead. */
};
@ -93,7 +95,9 @@ struct glyf
if (unlikely (!loca_prime_data)) return false;
DEBUG_MSG(SUBSET, nullptr, "loca entry_size %d num_offsets %d max_offset %d size %d", entry_size, num_offsets, max_offset, entry_size * num_offsets);
DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d "
"max_offset %d size %d",
entry_size, num_offsets, max_offset, entry_size * num_offsets);
if (use_short_loca)
_write_loca (padded_offsets, 1, hb_array ((HBUINT16*) loca_prime_data, num_offsets));
@ -122,27 +126,24 @@ struct glyf
unsigned int offset = 0;
dest << 0;
+ it
| hb_map ([=, &offset] (unsigned int padded_size) {
offset += padded_size;
DEBUG_MSG(SUBSET, nullptr, "loca entry offset %d", offset);
return offset >> right_shift;
})
| hb_map ([=, &offset] (unsigned int padded_size)
{
offset += padded_size;
DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset);
return offset >> right_shift;
})
| hb_sink (dest)
;
}
// requires source of SubsetGlyph complains the identifier isn't declared
template <typename Iterator>
bool serialize(hb_serialize_context_t *c,
Iterator it,
const hb_subset_plan_t *plan)
bool serialize (hb_serialize_context_t *c,
Iterator it,
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);
}
@ -167,7 +168,8 @@ struct glyf
;
if (c->serializer->in_error ()) return_trace (false);
return_trace (c->serializer->check_success (_add_loca_and_head (c->plan, padded_offsets)));
return_trace (c->serializer->check_success (_add_loca_and_head (c->plan,
padded_offsets)));
}
template <typename SubsetGlyph>
@ -179,23 +181,26 @@ struct glyf
glyf.init (plan->source);
+ hb_range (plan->num_output_glyphs ())
| hb_map ([&] (hb_codepoint_t new_gid) {
SubsetGlyph subset_glyph = {0};
subset_glyph.new_gid = new_gid;
| hb_map ([&] (hb_codepoint_t new_gid)
{
SubsetGlyph subset_glyph = {0};
subset_glyph.new_gid = new_gid;
// should never fail: all old gids should be mapped
if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) return subset_glyph;
// should never fail: all old gids should be mapped
if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
return subset_glyph;
subset_glyph.source_glyph = glyf.bytes_for_glyph ((const char *) this, subset_glyph.old_gid);
if (plan->drop_hints) subset_glyph.drop_hints (glyf);
else subset_glyph.dest_start = subset_glyph.source_glyph;
subset_glyph.source_glyph = glyf.bytes_for_glyph ((const char *) this,
subset_glyph.old_gid);
if (plan->drop_hints) subset_glyph.drop_hints (glyf);
else subset_glyph.dest_start = subset_glyph.source_glyph;
return subset_glyph;
})
return subset_glyph;
})
| hb_sink (glyphs)
;
glyf.fini();
glyf.fini ();
}
static void
@ -221,30 +226,34 @@ struct glyf
static void
_zero_instruction_length (hb_bytes_t glyph)
{
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
if (num_contours <= 0) return; // only for simple glyphs
const GlyphHeader &glyph_header = *glyph.as<GlyphHeader> ();
if (!glyph_header.is_simple_glyph ()) return; // only for simple glyphs
const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (&glyph, GlyphHeader::static_size + 2 * num_contours);
(HBUINT16 &) instruction_length = 0;
unsigned int instruction_len_offset = glyph_header.simple_instruction_len_offset ();
const HBUINT16 &instruction_len = StructAtOffset<HBUINT16> (&glyph,
instruction_len_offset);
(HBUINT16 &) instruction_len = 0;
}
static bool _remove_composite_instruction_flag (hb_bytes_t glyph)
{
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
if (glyph_header.numberOfContours >= 0) return true; // only for composites
const GlyphHeader &glyph_header = *glyph.as<GlyphHeader> ();
if (!glyph_header.is_composite_glyph ()) return true; // only for composites
/* remove WE_HAVE_INSTRUCTIONS from flags in dest */
OT::glyf::CompositeGlyphHeader::Iterator composite_it;
if (unlikely (!OT::glyf::CompositeGlyphHeader::get_iterator (&glyph, glyph.length, &composite_it))) return false;
if (unlikely (!OT::glyf::CompositeGlyphHeader::get_iterator (&glyph, glyph.length,
&composite_it)))
return false;
const OT::glyf::CompositeGlyphHeader *composite_header;
do {
do
{
composite_header = composite_it.current;
OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&composite_header->flags);
*flags = (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS;
} while (composite_it.move_to_next ());
return true;
}
}
static bool
_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
@ -266,21 +275,42 @@ struct glyf
struct GlyphHeader
{
HBINT16 numberOfContours; /* If the number of contours is
* greater than or equal to zero,
* this is a simple glyph; if negative,
* this is a composite glyph. */
FWORD xMin; /* Minimum x for coordinate data. */
FWORD yMin; /* Minimum y for coordinate data. */
FWORD xMax; /* Maximum x for coordinate data. */
FWORD yMax; /* Maximum y for coordinate data. */
unsigned int simple_instruction_len_offset () const
{ return static_size + 2 * numberOfContours; }
unsigned int simple_length (unsigned int instruction_len) const
{ return simple_instruction_len_offset () + 2 + instruction_len; }
bool is_composite_glyph () const { return numberOfContours < 0; }
bool is_simple_glyph () const { return numberOfContours > 0; }
void get_extents (hb_glyph_extents_t *extents) const
{
extents->x_bearing = hb_min (xMin, xMax);
extents->y_bearing = hb_max (yMin, yMax);
extents->width = hb_max (xMin, xMax) - extents->x_bearing;
extents->height = hb_min (yMin, yMax) - extents->y_bearing;
}
bool has_data () const { return numberOfContours; }
protected:
HBINT16 numberOfContours;/* If the number of contours is
* greater than or equal to zero,
* this is a simple glyph; if negative,
* this is a composite glyph. */
FWORD xMin; /* Minimum x for coordinate data. */
FWORD yMin; /* Minimum y for coordinate data. */
FWORD xMax; /* Maximum x for coordinate data. */
FWORD yMax; /* Maximum y for coordinate data. */
public:
DEFINE_SIZE_STATIC (10);
};
struct CompositeGlyphHeader
{
enum composite_glyph_flag_t {
enum composite_glyph_flag_t
{
ARG_1_AND_2_ARE_WORDS = 0x0001,
ARGS_ARE_XY_VALUES = 0x0002,
ROUND_XY_TO_GRID = 0x0004,
@ -296,7 +326,7 @@ struct glyf
};
HBUINT16 flags;
GlyphID glyphIndex;
HBGlyphID glyphIndex;
unsigned int get_size () const
{
@ -340,8 +370,8 @@ struct glyf
bool in_range (const CompositeGlyphHeader *composite) const
{
return (const char *) composite >= glyph_start
&& ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
&& ((const char *) composite + composite->get_size ()) <= glyph_end;
&& ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
&& ((const char *) composite + composite->get_size ()) <= glyph_end;
}
};
@ -349,11 +379,10 @@ struct glyf
unsigned int length,
CompositeGlyphHeader::Iterator *iterator /* OUT */)
{
if (length < GlyphHeader::static_size)
return false; /* Empty glyph; zero extents. */
const GlyphHeader &glyph_header = *hb_bytes_t (glyph_data, length).as<GlyphHeader> ();
if (!glyph_header.has_data ()) return false; /* Empty glyph; zero extents. */
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0);
if (glyph_header.numberOfContours < 0)
if (glyph_header.is_composite_glyph ())
{
const CompositeGlyphHeader *possible =
&StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
@ -416,7 +445,8 @@ struct glyf
composite);
}
enum simple_glyph_flag_t {
enum simple_glyph_flag_t
{
FLAG_ON_CURVE = 0x01,
FLAG_X_SHORT = 0x02,
FLAG_Y_SHORT = 0x04,
@ -431,21 +461,20 @@ struct glyf
bool remove_padding (unsigned int start_offset,
unsigned int *end_offset) const
{
if (*end_offset - start_offset < GlyphHeader::static_size) return true;
const char *glyph = ((const char *) glyf_table) + start_offset;
const char * const glyph_end = glyph + (*end_offset - start_offset);
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph, 0);
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
unsigned int glyph_length = *end_offset - start_offset;
const GlyphHeader &glyph_header = *hb_bytes_t (glyph, glyph_length).as<GlyphHeader> ();
if (!glyph_header.has_data ()) return true;
if (num_contours < 0)
const char *glyph_end = glyph + glyph_length;
if (glyph_header.is_composite_glyph ())
/* Trimming for composites not implemented.
* If removing hints it falls out of that. */
return true;
else if (num_contours > 0)
else
{
/* simple glyph w/contours, possibly trimmable */
glyph += GlyphHeader::static_size + 2 * num_contours;
glyph += glyph_header.simple_instruction_len_offset ();
if (unlikely (glyph + 2 >= glyph_end)) return false;
uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
@ -466,7 +495,7 @@ struct glyf
{
if (glyph >= glyph_end)
{
DEBUG_MSG(SUBSET, nullptr, "Bad flag");
DEBUG_MSG (SUBSET, nullptr, "Bad flag");
return false;
}
repeat = ((uint8_t) *glyph) + 1;
@ -489,7 +518,8 @@ struct glyf
if (coordsWithFlags != nCoordinates)
{
DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags);
DEBUG_MSG (SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d",
nCoordinates, coordsWithFlags);
return false;
}
glyph += coordBytes;
@ -530,52 +560,60 @@ struct glyf
bool get_instruction_length (hb_bytes_t glyph,
unsigned int * length /* OUT */) const
{
const GlyphHeader &glyph_header = *glyph.as<GlyphHeader> ();
/* Empty glyph; no instructions. */
if (glyph.length < GlyphHeader::static_size)
if (!glyph_header.has_data ())
{
*length = 0;
// only 0 byte glyphs are healthy when missing GlyphHeader
return glyph.length == 0;
}
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (&glyph, 0);
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
if (num_contours < 0)
if (glyph_header.is_composite_glyph ())
{
unsigned int start = glyph.length;
unsigned int end = glyph.length;
unsigned int glyph_offset = &glyph - glyf_table;
CompositeGlyphHeader::Iterator composite_it;
if (unlikely (!CompositeGlyphHeader::get_iterator (&glyph, glyph.length, &composite_it))) return false;
if (unlikely (!CompositeGlyphHeader::get_iterator (&glyph, glyph.length,
&composite_it)))
return false;
const CompositeGlyphHeader *last;
do {
do
{
last = composite_it.current;
} while (composite_it.move_to_next ());
if ((uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size () - glyph_offset;
start = ((char *) last - (char *) glyf_table->dataZ.arrayZ)
+ last->get_size () - glyph_offset;
if (unlikely (start > end))
{
DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside %d byte buffer", start, glyph.length);
DEBUG_MSG (SUBSET, nullptr, "Invalid instruction offset, %d is outside "
"%d byte buffer", start, glyph.length);
return false;
}
*length = end - start;
}
else
{
unsigned int instruction_length_offset = GlyphHeader::static_size + 2 * num_contours;
if (unlikely (instruction_length_offset + 2 > glyph.length))
unsigned int instruction_len_offset = glyph_header.simple_instruction_len_offset ();
if (unlikely (instruction_len_offset + 2 > glyph.length))
{
DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength.");
DEBUG_MSG (SUBSET, nullptr, "Glyph size is too short, missing field "
"instructionLength.");
return false;
}
const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (&glyph, instruction_length_offset);
if (unlikely (instruction_length_offset + instruction_length > glyph.length)) // Out of bounds of the current glyph
const HBUINT16 &instruction_len = StructAtOffset<HBUINT16> (&glyph,
instruction_len_offset);
/* Out of bounds of the current glyph */
if (unlikely (glyph_header.simple_length (instruction_len) > glyph.length))
{
DEBUG_MSG(SUBSET, nullptr, "The instructions array overruns the glyph's boundaries.");
DEBUG_MSG (SUBSET, nullptr, "The instructions array overruns the "
"glyph's boundaries.");
return false;
}
*length = (uint16_t) instruction_length;
*length = (uint16_t) instruction_len;
}
return true;
}
@ -586,37 +624,28 @@ struct glyf
if (!get_offsets (glyph, &start_offset, &end_offset))
return false;
if (end_offset - start_offset < GlyphHeader::static_size)
return true; /* Empty glyph; zero extents. */
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
extents->x_bearing = hb_min (glyph_header.xMin, glyph_header.xMax);
extents->y_bearing = hb_max (glyph_header.yMin, glyph_header.yMax);
extents->width = hb_max (glyph_header.xMin, glyph_header.xMax) - extents->x_bearing;
extents->height = hb_min (glyph_header.yMin, glyph_header.yMax) - extents->y_bearing;
hb_bytes_t ((const char *) glyf_table + start_offset,
end_offset - start_offset).as<GlyphHeader> ()->get_extents (extents);
return true;
}
hb_bytes_t bytes_for_glyph (const char * glyf, hb_codepoint_t gid)
{
unsigned int start_offset, end_offset;
if (unlikely (!(get_offsets (gid, &start_offset, &end_offset) &&
remove_padding (start_offset, &end_offset))))
hb_bytes_t bytes_for_glyph (const char *glyf, hb_codepoint_t gid)
{
DEBUG_MSG(SUBSET, nullptr, "Unable to get offset or remove padding for %d", gid);
return hb_bytes_t ();
unsigned int start_offset, end_offset;
if (unlikely (!(get_offsets (gid, &start_offset, &end_offset) &&
remove_padding (start_offset, &end_offset))))
{
DEBUG_MSG (SUBSET, nullptr, "Unable to get offset or remove padding for %d", gid);
return hb_bytes_t ();
}
hb_bytes_t glyph_bytes = hb_bytes_t (glyf + start_offset, end_offset - start_offset);
if (!glyph_bytes.as<GlyphHeader> ()->has_data ())
{
DEBUG_MSG (SUBSET, nullptr, "Empty or invalid glyph size, %d", gid);
return hb_bytes_t ();
}
return glyph_bytes;
}
hb_bytes_t glyph = hb_bytes_t (glyf + start_offset, end_offset - start_offset);
if (glyph.length == 0) return glyph;
if (unlikely (glyph.length < GlyphHeader::static_size))
{
DEBUG_MSG(SUBSET, nullptr, "Glyph size smaller than minimum header %d", gid);
return hb_bytes_t ();
}
return glyph;
}
private:
bool short_offset;
@ -625,99 +654,93 @@ struct glyf
hb_blob_ptr_t<glyf> glyf_table;
};
struct SubsetGlyph
{
hb_codepoint_t new_gid;
hb_codepoint_t old_gid;
hb_bytes_t source_glyph;
hb_bytes_t dest_start; // region of source_glyph to copy first
hb_bytes_t dest_end; // region of source_glyph to copy second
hb_bytes_t dest_start; /* region of source_glyph to copy first */
hb_bytes_t dest_end; /* region of source_glyph to copy second */
bool serialize (hb_serialize_context_t *c,
const hb_subset_plan_t *plan) const
{
TRACE_SERIALIZE (this);
hb_bytes_t dest_glyph = dest_start.copy(c);
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy(c).length);
unsigned int pad_length = padding ();
DEBUG_MSG(SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d", dest_glyph.length, dest_glyph.length + pad_length, pad_length);
HBUINT8 pad;
pad = 0;
while (pad_length > 0)
bool serialize (hb_serialize_context_t *c,
const hb_subset_plan_t *plan) const
{
c->embed(pad);
pad_length--;
}
TRACE_SERIALIZE (this);
if (dest_glyph.length)
{
_fix_component_gids (plan, dest_glyph);
if (plan->drop_hints)
hb_bytes_t dest_glyph = dest_start.copy (c);
dest_glyph = hb_bytes_t (&dest_glyph, dest_glyph.length + dest_end.copy (c).length);
unsigned int pad_length = padding ();
DEBUG_MSG (SUBSET, nullptr, "serialize %d byte glyph, width %d pad %d",
dest_glyph.length, dest_glyph.length + pad_length, pad_length);
HBUINT8 pad;
pad = 0;
while (pad_length > 0)
{
_zero_instruction_length (dest_glyph);
c->check_success (_remove_composite_instruction_flag (dest_glyph));
c->embed (pad);
pad_length--;
}
}
return_trace (true);
}
if (dest_glyph.length)
{
_fix_component_gids (plan, dest_glyph);
if (plan->drop_hints)
{
_zero_instruction_length (dest_glyph);
c->check_success (_remove_composite_instruction_flag (dest_glyph));
}
}
return_trace (true);
}
void drop_hints (const OT::glyf::accelerator_t& glyf)
{
if (source_glyph.length == 0) return;
unsigned int instruction_length = 0;
if (!glyf.get_instruction_length (source_glyph, &instruction_length))
unsigned int instruction_len = 0;
if (!glyf.get_instruction_length (source_glyph, &instruction_len))
{
DEBUG_MSG(SUBSET, nullptr, "Unable to read instruction length for new_gid %d", new_gid);
DEBUG_MSG (SUBSET, nullptr, "Unable to read instruction length for new_gid %d",
new_gid);
return ;
}
const GlyphHeader& header = StructAtOffset<GlyphHeader> (&source_glyph, 0);
int16_t num_contours = (int16_t) header.numberOfContours;
DEBUG_MSG(SUBSET, nullptr, "new_gid %d (%d contours) drop %d instruction bytes from %d byte source glyph", new_gid, num_contours, instruction_length, source_glyph.length);
if (num_contours < 0)
const GlyphHeader& header = *source_glyph.as<GlyphHeader> ();
DEBUG_MSG (SUBSET, nullptr, "new_gid %d drop %d instruction bytes "
"from %d byte source glyph",
new_gid, instruction_len, source_glyph.length);
if (header.is_composite_glyph ())
{
// composite, just chop instructions off the end
dest_start = hb_bytes_t (&source_glyph, source_glyph.length - instruction_length);
/* just chop instructions off the end for composite glyphs */
dest_start = hb_bytes_t (&source_glyph, source_glyph.length - instruction_len);
}
else
{
// simple glyph
dest_start = hb_bytes_t (&source_glyph, GlyphHeader::static_size + 2 * header.numberOfContours + 2);
dest_end = hb_bytes_t (&source_glyph + dest_start.length + instruction_length,
source_glyph.length - dest_start.length - instruction_length);
DEBUG_MSG(SUBSET, nullptr, "source_len %d start len %d instruction_len %d end len %d", source_glyph.length, dest_start.length, instruction_length, dest_end.length);
unsigned int glyph_length = header.simple_length (instruction_len);
dest_start = hb_bytes_t (&source_glyph, glyph_length - instruction_len);
dest_end = hb_bytes_t (&source_glyph + glyph_length,
source_glyph.length - glyph_length);
DEBUG_MSG (SUBSET, nullptr, "source_len %d start len %d glyph_len %d "
"instruction_len %d end len %d",
source_glyph.length, dest_start.length, glyph_length,
instruction_len, dest_end.length);
}
}
unsigned int length () const
{
return dest_start.length + dest_end.length;
}
// pad to 2 to ensure 2-byte loca will be ok
unsigned int padding () const
{
return length () % 2;
}
unsigned int padded_size () const
{
return length () + padding ();
}
unsigned int length () const { return dest_start.length + dest_end.length; }
/* pad to 2 to ensure 2-byte loca will be ok */
unsigned int padding () const { return length () % 2; }
unsigned int padded_size () const { return length () + padding (); }
};
protected:
UnsizedArrayOf<HBUINT8> dataZ; /* Glyphs data. */
UnsizedArrayOf<HBUINT8>
dataZ; /* Glyphs data. */
public:
DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
* check the size externally, allow Null() object of it by
* defining it _MIN instead. */
DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
* check the size externally, allow Null() object of it by
* defining it _MIN instead. */
};
struct glyf_accelerator_t : glyf::accelerator_t {};

View File

@ -66,7 +66,7 @@ struct hmtxvmtx
bool subset_update_header (hb_subset_plan_t *plan,
unsigned int num_hmetrics) const
unsigned int num_hmetrics) const
{
hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (plan->source, H::tableTag);
hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
@ -87,30 +87,30 @@ struct hmtxvmtx
}
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it,
unsigned num_advances)
Iterator it,
unsigned num_advances)
{
unsigned idx = 0;
+ it
| hb_apply ([c, &idx, num_advances] (const hb_item_type<Iterator>& _)
{
if (idx < num_advances)
{
LongMetric lm;
lm.advance = _.first;
lm.sb = _.second;
if (unlikely (!c->embed<LongMetric> (&lm))) return;
}
else
{
FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
if (unlikely (!sb)) return;
*sb = _.second;
}
idx++;
})
{
if (idx < num_advances)
{
LongMetric lm;
lm.advance = _.first;
lm.sb = _.second;
if (unlikely (!c->embed<LongMetric> (&lm))) return;
}
else
{
FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
if (unlikely (!sb)) return;
*sb = _.second;
}
idx++;
})
;
}
@ -131,8 +131,8 @@ struct hmtxvmtx
{
hb_codepoint_t old_gid;
if (c->plan->old_gid_for_new_gid (_, &old_gid))
return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
else
return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
else
return hb_pair (0u, 0u);
})
;
@ -158,7 +158,7 @@ struct hmtxvmtx
friend struct hmtxvmtx;
void init (hb_face_t *face,
unsigned int default_advance_ = 0)
unsigned int default_advance_ = 0)
{
default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face);
@ -194,10 +194,10 @@ struct hmtxvmtx
unsigned int get_side_bearing (hb_codepoint_t glyph) const
{
if (glyph < num_advances)
return table->longMetricZ[glyph].sb;
return table->longMetricZ[glyph].sb;
if (unlikely (glyph >= num_metrics))
return 0;
return 0;
const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances];
return bearings[glyph - num_advances];
@ -234,12 +234,12 @@ struct hmtxvmtx
{
unsigned int num_advances = plan->num_output_glyphs ();
unsigned int last_advance = _advance_for_new_gid (plan,
num_advances - 1);
num_advances - 1);
while (num_advances > 1 &&
last_advance == _advance_for_new_gid (plan,
num_advances - 2))
last_advance == _advance_for_new_gid (plan,
num_advances - 2))
{
num_advances--;
num_advances--;
}
return num_advances;
@ -247,11 +247,11 @@ struct hmtxvmtx
private:
unsigned int _advance_for_new_gid (const hb_subset_plan_t *plan,
hb_codepoint_t new_gid) const
hb_codepoint_t new_gid) const
{
hb_codepoint_t old_gid;
if (!plan->old_gid_for_new_gid (new_gid, &old_gid))
return 0;
return 0;
return get_advance (old_gid);
}

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

@ -172,8 +172,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);
@ -540,7 +540,7 @@ struct FeatureParams
FeatureParamsCharacterVariants characterVariants;
} u;
public:
DEFINE_SIZE_STATIC (17);
DEFINE_SIZE_MIN (0);
};
struct Feature
@ -780,7 +780,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:
@ -856,7 +856,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);
@ -895,7 +895,7 @@ struct CoverageFormat2
for (auto g: glyphs)
{
if (last + 1 != g)
num_ranges++;
num_ranges++;
last = g;
}
@ -908,7 +908,7 @@ struct CoverageFormat2
{
if (last + 1 != g)
{
range++;
range++;
rangeRecord[range].start = g;
rangeRecord[range].value = count;
}
@ -1058,11 +1058,11 @@ struct Coverage
for (auto g: glyphs)
{
if (last + 1 != g)
num_ranges++;
num_ranges++;
last = g;
count++;
}
u.format = count * 2 < num_ranges * 3 ? 1 : 2;
u.format = count <= num_ranges * 3 ? 1 : 2;
switch (u.format)
{
@ -1196,7 +1196,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
@ -1210,7 +1210,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);
@ -1241,7 +1241,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;
@ -1328,7 +1328,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:
@ -1346,7 +1346,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);
@ -1390,7 +1390,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;
@ -1506,7 +1506,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);
@ -1526,7 +1526,7 @@ struct ClassDef
num_ranges++;
if (1 + (glyph_max - glyph_min + 1) < num_ranges * 3)
format = 1;
format = 1;
}
u.format = format;
@ -1611,7 +1611,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); }
@ -1746,9 +1746,9 @@ struct VarData
}
void get_scalars (int *coords, unsigned int coord_count,
const VarRegionList &regions,
float *scalars /*OUT */,
unsigned int num_scalars) const
const VarRegionList &regions,
float *scalars /*OUT */,
unsigned int num_scalars) const
{
unsigned count = hb_min (num_scalars, regionIndices.len);
for (unsigned int i = 0; i < count; i++)
@ -1830,7 +1830,7 @@ struct VariationStore
#endif
(this+dataSets[ivs]).get_scalars (coords, coord_count, this+regions,
&scalars[0], num_scalars);
&scalars[0], num_scalars);
}
protected:
@ -2057,6 +2057,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;
@ -2070,6 +2072,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
@ -2131,6 +2139,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);
@ -2216,6 +2230,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

@ -149,8 +149,8 @@ struct CaretValueFormat3
const VariationStore &var_store) const
{
return HB_DIRECTION_IS_HORIZONTAL (direction) ?
font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
}
bool sanitize (hb_sanitize_context_t *c) const

View File

@ -238,8 +238,8 @@ struct ValueFormat : HBUINT16
template<typename Iterator>
static inline void SinglePos_serialize (hb_serialize_context_t *c,
Iterator it,
ValueFormat valFormat);
Iterator it,
ValueFormat valFormat);
struct AnchorFormat1
@ -257,6 +257,12 @@ struct AnchorFormat1
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
AnchorFormat1* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
return_trace (c->embed<AnchorFormat1> (this));
}
protected:
HBUINT16 format; /* Format identifier--format = 1 */
@ -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,14 +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
@ -533,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);
@ -602,30 +626,21 @@ struct SinglePosFormat2
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it,
ValueFormat valFormat)
ValueFormat valFormat)
{
if (unlikely (!c->extend_min (*this))) return;
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
| hb_map_retains_sorting (hb_first)
;
coverage.serialize (c, this).serialize (c, glyphs);
}
@ -636,15 +651,17 @@ 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));
})
;
bool ret = bool (it);
@ -680,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;
}
@ -708,7 +712,7 @@ struct SinglePos
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator glyph_val_iter_pairs,
ValueFormat valFormat)
ValueFormat valFormat)
{
if (unlikely (!c->extend_min (u.format))) return;
unsigned format = 2;
@ -718,9 +722,9 @@ struct SinglePos
u.format = format;
switch (u.format) {
case 1: u.format1.serialize (c, glyph_val_iter_pairs, valFormat);
return;
return;
case 2: u.format2.serialize (c, glyph_val_iter_pairs, valFormat);
return;
return;
default:return;
}
}
@ -748,8 +752,8 @@ struct SinglePos
template<typename Iterator>
static inline void
SinglePos_serialize (hb_serialize_context_t *c,
Iterator it,
ValueFormat valFormat)
Iterator it,
ValueFormat valFormat)
{ c->start_embed<SinglePos> ()->serialize (c, it, valFormat); }
@ -758,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
@ -1094,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
@ -1221,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:
@ -296,12 +300,11 @@ SingleSubst_serialize (hb_serialize_context_t *c,
struct Sequence
{
bool intersects (const hb_set_t *glyphs) const
{ return hb_all (substitute, glyphs); }
void closure (hb_closure_context_t *c) const
{
unsigned int count = substitute.len;
for (unsigned int i = 0; i < count; i++)
c->output->add (substitute[i]);
}
{ c->output->add_array (substitute.arrayZ, substitute.len); }
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{ c->output->add_array (substitute.arrayZ, substitute.len); }
@ -347,6 +350,23 @@ struct Sequence
return_trace (substitute.serialize (c, subst));
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
if (!intersects (&glyphset)) return_trace (false);
auto it =
+ hb_iter (substitute)
| hb_map (glyph_map)
;
auto *out = c->serializer->start_embed (*this);
return_trace (out->serialize (c->serializer, it));
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -354,7 +374,7 @@ struct Sequence
}
protected:
ArrayOf<GlyphID>
ArrayOf<HBGlyphID>
substitute; /* String of GlyphIDs to substitute */
public:
DEFINE_SIZE_ARRAY (2, substitute);
@ -401,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);
@ -422,8 +442,37 @@ struct MultipleSubstFormat1
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 (!c->serializer->extend_min (out))) return_trace (false);
out->format = format;
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, sequence)
| hb_filter (glyphset, hb_first)
| hb_filter ([this, c, out] (const OffsetTo<Sequence>& _)
{
auto *o = out->sequence.serialize_append (c->serializer);
if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, out);
if (!ret)
{
out->sequence.pop ();
c->serializer->revert (snap);
}
return ret;
},
hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
out->coverage.serialize (c->serializer, out)
.serialize (c->serializer, new_coverage.iter ());
return_trace (bool (new_coverage));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -447,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);
@ -481,12 +530,11 @@ struct MultipleSubst
struct AlternateSet
{
bool intersects (const hb_set_t *glyphs) const
{ return hb_any (alternates, glyphs); }
void closure (hb_closure_context_t *c) const
{
unsigned int count = alternates.len;
for (unsigned int i = 0; i < count; i++)
c->output->add (alternates[i]);
}
{ c->output->add_array (alternates.arrayZ, alternates.len); }
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{ c->output->add_array (alternates.arrayZ, alternates.len); }
@ -525,6 +573,23 @@ struct AlternateSet
return_trace (alternates.serialize (c, alts));
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto it =
+ hb_iter (alternates)
| hb_filter (glyphset)
| hb_map (glyph_map)
;
auto *out = c->serializer->start_embed (*this);
return_trace (out->serialize (c->serializer, it) &&
out->alternates);
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -532,7 +597,7 @@ struct AlternateSet
}
protected:
ArrayOf<GlyphID>
ArrayOf<HBGlyphID>
alternates; /* Array of alternate GlyphIDs--in
* arbitrary order */
public:
@ -579,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);
@ -600,8 +665,37 @@ struct AlternateSubstFormat1
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 (!c->serializer->extend_min (out))) return_trace (false);
out->format = format;
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, alternateSet)
| hb_filter (glyphset, hb_first)
| hb_filter ([this, c, out] (const OffsetTo<AlternateSet>& _)
{
auto *o = out->alternateSet.serialize_append (c->serializer);
if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, out);
if (!ret)
{
out->alternateSet.pop ();
c->serializer->revert (snap);
}
return ret;
},
hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
out->coverage.serialize (c->serializer, out)
.serialize (c->serializer, new_coverage.iter ());
return_trace (bool (new_coverage));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -625,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);
@ -661,13 +755,7 @@ struct AlternateSubst
struct Ligature
{
bool intersects (const hb_set_t *glyphs) const
{
unsigned int count = component.lenP1;
for (unsigned int i = 1; i < count; i++)
if (!glyphs->has (component[i]))
return false;
return true;
}
{ return hb_all (component, glyphs); }
void closure (hb_closure_context_t *c) const
{
@ -677,7 +765,7 @@ struct Ligature
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
c->input->add_array (component.arrayZ, component.lenP1 ? component.lenP1 - 1 : 0);
c->input->add_array (component.arrayZ, component.get_length ());
c->output->add (ligGlyph);
}
@ -735,7 +823,7 @@ struct Ligature
template <typename Iterator,
hb_requires (hb_is_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c,
GlyphID ligature,
hb_codepoint_t ligature,
Iterator components /* Starting from second */)
{
TRACE_SERIALIZE (this);
@ -745,6 +833,25 @@ struct Ligature
return_trace (true);
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false);
auto it =
+ hb_iter (component)
| hb_map (glyph_map)
;
auto *out = c->serializer->start_embed (*this);
return_trace (out->serialize (c->serializer,
glyph_map[ligGlyph],
it));
}
public:
bool sanitize (hb_sanitize_context_t *c) const
{
@ -753,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 */
@ -814,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);
@ -834,6 +941,31 @@ struct LigatureSet
return_trace (true);
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ hb_iter (ligature)
| hb_filter ([this, c, out] (const OffsetTo<Ligature>& _)
{
auto *o = out->ligature.serialize_append (c->serializer);
if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, out);
if (!ret)
{
out->ligature.pop ();
c->serializer->revert (snap);
}
return ret;
})
| hb_drain
;
return_trace (bool (out->ligature));
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -906,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);
@ -932,8 +1064,37 @@ struct LigatureSubstFormat1
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 (!c->serializer->extend_min (out))) return_trace (false);
out->format = format;
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, ligatureSet)
| hb_filter (glyphset, hb_first)
| hb_filter ([this, c, out] (const OffsetTo<LigatureSet>& _)
{
auto *o = out->ligatureSet.serialize_append (c->serializer);
if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, out);
if (!ret)
{
out->ligatureSet.pop ();
c->serializer->revert (snap);
}
return ret;
},
hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
out->coverage.serialize (c->serializer, out)
.serialize (c->serializer, new_coverage.iter ());
return_trace (bool (new_coverage));
}
bool sanitize (hb_sanitize_context_t *c) const
@ -957,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);
@ -1038,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)
@ -1062,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);
}
@ -1082,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,
@ -1120,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));
}
@ -1137,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:
@ -1292,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);
@ -1303,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);
@ -1318,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);
@ -1333,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

@ -567,7 +567,7 @@ hb_ot_layout_table_select_script (hb_face_t *face,
if (g.find_script_index (script_tags[i], script_index))
{
if (chosen_script)
*chosen_script = script_tags[i];
*chosen_script = script_tags[i];
return true;
}
}
@ -999,9 +999,9 @@ hb_ot_layout_table_get_lookup_count (hb_face_t *face,
struct hb_collect_features_context_t
{
hb_collect_features_context_t (hb_face_t *face,
hb_tag_t table_tag,
hb_set_t *feature_indexes_)
hb_collect_features_context_t (hb_face_t *face,
hb_tag_t table_tag,
hb_set_t *feature_indexes_)
: g (get_gsubgpos_table (face, table_tag)),
feature_indexes (feature_indexes_),
script_count(0),langsys_count(0) {}
@ -1147,11 +1147,11 @@ script_collect_features (hb_collect_features_context_t *c,
**/
void
hb_ot_layout_collect_features (hb_face_t *face,
hb_tag_t table_tag,
const hb_tag_t *scripts,
const hb_tag_t *languages,
const hb_tag_t *features,
hb_set_t *feature_indexes /* OUT */)
hb_tag_t table_tag,
const hb_tag_t *scripts,
const hb_tag_t *languages,
const hb_tag_t *features,
hb_set_t *feature_indexes /* OUT */)
{
hb_collect_features_context_t c (face, table_tag, feature_indexes);
if (!scripts)
@ -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
**/
@ -1482,8 +1482,8 @@ hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
**/
void
hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
const hb_set_t *lookups,
hb_set_t *glyphs /* OUT */)
const hb_set_t *lookups,
hb_set_t *glyphs /* OUT */)
{
hb_map_t done_lookups;
OT::hb_closure_context_t c (face, glyphs, &done_lookups);
@ -1497,12 +1497,12 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
if (lookups != nullptr)
{
for (hb_codepoint_t lookup_index = HB_SET_VALUE_INVALID; hb_set_next (lookups, &lookup_index);)
gsub.get_lookup (lookup_index).closure (&c, lookup_index);
gsub.get_lookup (lookup_index).closure (&c, lookup_index);
}
else
{
for (unsigned int i = 0; i < gsub.get_lookup_count (); i++)
gsub.get_lookup (i).closure (&c, i);
gsub.get_lookup (i).closure (&c, i);
}
} while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
glyphs_length != glyphs->get_population ());
@ -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

@ -249,11 +249,11 @@ hb_ot_layout_table_get_lookup_count (hb_face_t *face,
HB_EXTERN void
hb_ot_layout_collect_features (hb_face_t *face,
hb_tag_t table_tag,
const hb_tag_t *scripts,
const hb_tag_t *languages,
const hb_tag_t *features,
hb_set_t *feature_indexes /* OUT */);
hb_tag_t table_tag,
const hb_tag_t *scripts,
const hb_tag_t *languages,
const hb_tag_t *features,
hb_set_t *feature_indexes /* OUT */);
HB_EXTERN void
hb_ot_layout_collect_lookups (hb_face_t *face,
@ -333,14 +333,14 @@ hb_ot_layout_lookup_would_substitute (hb_face_t *face,
HB_EXTERN void
hb_ot_layout_lookup_substitute_closure (hb_face_t *face,
unsigned int lookup_index,
hb_set_t *glyphs
unsigned int lookup_index,
hb_set_t *glyphs
/*TODO , hb_bool_t inclusive */);
HB_EXTERN void
hb_ot_layout_lookups_substitute_closure (hb_face_t *face,
const hb_set_t *lookups,
hb_set_t *glyphs);
const hb_set_t *lookups,
hb_set_t *glyphs);
#ifdef HB_NOT_IMPLEMENTED

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 */
}
@ -297,7 +298,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
global_bit_mask);
for (unsigned i = 0; i < m.features.length; i++)
if (m.features[i].stage[table_index] == stage)
if (m.features[i].stage[table_index] == stage)
add_lookups (m, table_index,
m.features[i].index[table_index],
key.variations_index[table_index],

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

@ -108,7 +108,7 @@ struct maxp
if (unlikely (!dest_v1)) return_trace (false);
if (c->plan->drop_hints)
drop_hint_fields (dest_v1);
drop_hint_fields (dest_v1);
}
return_trace (true);
@ -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);
@ -265,10 +263,10 @@ struct name
unsigned int j = 0;
for (unsigned int i = 0; i < this->names.length; i++)
{
if (this->names[i].entry_score == UNSUPPORTED ||
if (this->names[i].entry_score == UNSUPPORTED ||
this->names[i].language == HB_LANGUAGE_INVALID)
continue;
if (i &&
if (i &&
this->names[i - 1].name_id == this->names[i].name_id &&
this->names[i - 1].language == this->names[i].language)
continue;
@ -295,10 +293,10 @@ struct name
sizeof (key),
_hb_ot_name_entry_cmp_key);
if (!entry)
return -1;
return -1;
if (width)
*width = entry->entry_score < 10 ? 2 : 1;
*width = entry->entry_score < 10 ? 2 : 1;
return entry->entry_index;
}
@ -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

@ -90,7 +90,7 @@ hb_ot_name_convert_utf (hb_bytes_t bytes,
const typename in_utf_t::codepoint_t *src_next = in_utf_t::next (src, src_end, &unicode, replacement);
typename out_utf_t::codepoint_t *dst_next = out_utf_t::encode (dst, dst_end, unicode);
if (dst_next == dst)
break; /* Out-of-room. */
break; /* Out-of-room. */
dst = dst_next;
src = src_next;

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

View File

@ -476,13 +476,13 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
{
if (!hb_in_range<uint8_t> (info[i - 1].arabic_shaping_action(), STCH_FIXED, STCH_REPEATING))
{
if (step == CUT)
if (step == CUT)
{
--j;
info[j] = info[i - 1];
pos[j] = pos[i - 1];
}
continue;
continue;
}
/* Yay, justification! */
@ -540,10 +540,10 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_position_t shortfall = sign * w_remaining - sign * w_repeating * (n_copies + 1);
if (shortfall > 0 && n_repeating > 0)
{
++n_copies;
hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
if (excess > 0)
extra_repeat_overlap = excess / (n_copies * n_repeating);
++n_copies;
hb_position_t excess = (n_copies + 1) * sign * w_repeating - sign * w_remaining;
if (excess > 0)
extra_repeat_overlap = excess / (n_copies * n_repeating);
}
if (step == MEASURE)
@ -583,7 +583,7 @@ apply_stch (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (step == MEASURE)
{
if (unlikely (!buffer->ensure (count + extra_glyphs_needed)))
break;
break;
}
else
{

View File

@ -204,7 +204,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (start < end && end == buffer->out_len)
{
/* Tone mark follows a valid syllable; move it in front, unless it's zero width. */
buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
buffer->unsafe_to_break_from_outbuffer (start, buffer->idx);
buffer->next_glyph ();
if (!is_zero_width_char (font, u))
{
@ -354,9 +354,9 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
*/
if (has_glyph && !tindex)
{
buffer->next_glyph ();
s_len++;
}
buffer->next_glyph ();
s_len++;
}
if (unlikely (!buffer->successful))
return;
@ -365,7 +365,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
* that are now in buffer->out_info.
*/
hb_glyph_info_t *info = buffer->out_info;
end = start + s_len;
end = start + s_len;
unsigned int i = start;
info[i++].hangul_shaping_feature() = LJMO;
@ -383,7 +383,7 @@ preprocess_text_hangul (const hb_ot_shape_plan_t *plan HB_UNUSED,
if (has_glyph)
{
/* We didn't decompose the S, so just advance past it. */
/* We didn't decompose the S, so just advance past it. */
end = start + 1;
buffer->next_glyph ();
continue;

View File

@ -23,58 +23,59 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros"
#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 17 chars; Avagraha */
#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 86 chars; Bindu */
#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */
#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 59 chars; Cantillation_Mark */
#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2160 chars; Consonant */
#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 12 chars; Consonant_Dead */
#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 67 chars; Consonant_Final */
#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */
#define ISC_CIP INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED /* 1 chars; Consonant_Initial_Postfixed */
#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */
#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 29 chars; Consonant_Medial */
#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 22 chars; Consonant_Placeholder */
#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 2 chars; Consonant_Preceding_Repha */
#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 9 chars; Consonant_Prefixed */
#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 94 chars; Consonant_Subjoined */
#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */
#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 6 chars; Consonant_With_Stacker */
#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */
#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 11 chars; Invisible_Stacker */
#define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */
#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */
#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 30 chars; Nukta */
#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 481 chars; Number */
#define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */
#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 21 chars; Pure_Killer */
#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */
#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 25 chars; Syllable_Modifier */
#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */
#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */
#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 27 chars; Virama */
#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 35 chars; Visarga */
#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */
#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 673 chars; Vowel_Dependent */
#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 476 chars; Vowel_Independent */
#define ISC_A INDIC_SYLLABIC_CATEGORY_AVAGRAHA /* 17 chars; Avagraha */
#define ISC_Bi INDIC_SYLLABIC_CATEGORY_BINDU /* 86 chars; Bindu */
#define ISC_BJN INDIC_SYLLABIC_CATEGORY_BRAHMI_JOINING_NUMBER /* 20 chars; Brahmi_Joining_Number */
#define ISC_Ca INDIC_SYLLABIC_CATEGORY_CANTILLATION_MARK /* 59 chars; Cantillation_Mark */
#define ISC_C INDIC_SYLLABIC_CATEGORY_CONSONANT /* 2160 chars; Consonant */
#define ISC_CD INDIC_SYLLABIC_CATEGORY_CONSONANT_DEAD /* 12 chars; Consonant_Dead */
#define ISC_CF INDIC_SYLLABIC_CATEGORY_CONSONANT_FINAL /* 67 chars; Consonant_Final */
#define ISC_CHL INDIC_SYLLABIC_CATEGORY_CONSONANT_HEAD_LETTER /* 5 chars; Consonant_Head_Letter */
#define ISC_CIP INDIC_SYLLABIC_CATEGORY_CONSONANT_INITIAL_POSTFIXED /* 1 chars; Consonant_Initial_Postfixed */
#define ISC_CK INDIC_SYLLABIC_CATEGORY_CONSONANT_KILLER /* 2 chars; Consonant_Killer */
#define ISC_CM INDIC_SYLLABIC_CATEGORY_CONSONANT_MEDIAL /* 29 chars; Consonant_Medial */
#define ISC_CP INDIC_SYLLABIC_CATEGORY_CONSONANT_PLACEHOLDER /* 22 chars; Consonant_Placeholder */
#define ISC_CPR INDIC_SYLLABIC_CATEGORY_CONSONANT_PRECEDING_REPHA /* 2 chars; Consonant_Preceding_Repha */
#define ISC_CPrf INDIC_SYLLABIC_CATEGORY_CONSONANT_PREFIXED /* 9 chars; Consonant_Prefixed */
#define ISC_CS INDIC_SYLLABIC_CATEGORY_CONSONANT_SUBJOINED /* 94 chars; Consonant_Subjoined */
#define ISC_CSR INDIC_SYLLABIC_CATEGORY_CONSONANT_SUCCEEDING_REPHA /* 4 chars; Consonant_Succeeding_Repha */
#define ISC_CWS INDIC_SYLLABIC_CATEGORY_CONSONANT_WITH_STACKER /* 6 chars; Consonant_With_Stacker */
#define ISC_GM INDIC_SYLLABIC_CATEGORY_GEMINATION_MARK /* 3 chars; Gemination_Mark */
#define ISC_IS INDIC_SYLLABIC_CATEGORY_INVISIBLE_STACKER /* 11 chars; Invisible_Stacker */
#define ISC_ZWJ INDIC_SYLLABIC_CATEGORY_JOINER /* 1 chars; Joiner */
#define ISC_ML INDIC_SYLLABIC_CATEGORY_MODIFYING_LETTER /* 1 chars; Modifying_Letter */
#define ISC_ZWNJ INDIC_SYLLABIC_CATEGORY_NON_JOINER /* 1 chars; Non_Joiner */
#define ISC_N INDIC_SYLLABIC_CATEGORY_NUKTA /* 30 chars; Nukta */
#define ISC_Nd INDIC_SYLLABIC_CATEGORY_NUMBER /* 481 chars; Number */
#define ISC_NJ INDIC_SYLLABIC_CATEGORY_NUMBER_JOINER /* 1 chars; Number_Joiner */
#define ISC_x INDIC_SYLLABIC_CATEGORY_OTHER /* 1 chars; Other */
#define ISC_PK INDIC_SYLLABIC_CATEGORY_PURE_KILLER /* 21 chars; Pure_Killer */
#define ISC_RS INDIC_SYLLABIC_CATEGORY_REGISTER_SHIFTER /* 2 chars; Register_Shifter */
#define ISC_SM INDIC_SYLLABIC_CATEGORY_SYLLABLE_MODIFIER /* 25 chars; Syllable_Modifier */
#define ISC_TL INDIC_SYLLABIC_CATEGORY_TONE_LETTER /* 7 chars; Tone_Letter */
#define ISC_TM INDIC_SYLLABIC_CATEGORY_TONE_MARK /* 42 chars; Tone_Mark */
#define ISC_V INDIC_SYLLABIC_CATEGORY_VIRAMA /* 27 chars; Virama */
#define ISC_Vs INDIC_SYLLABIC_CATEGORY_VISARGA /* 35 chars; Visarga */
#define ISC_Vo INDIC_SYLLABIC_CATEGORY_VOWEL /* 30 chars; Vowel */
#define ISC_M INDIC_SYLLABIC_CATEGORY_VOWEL_DEPENDENT /* 673 chars; Vowel_Dependent */
#define ISC_VI INDIC_SYLLABIC_CATEGORY_VOWEL_INDEPENDENT /* 476 chars; Vowel_Independent */
#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 349 chars; Bottom */
#define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */
#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */
#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 61 chars; Left */
#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */
#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */
#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 281 chars; Right */
#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 398 chars; Top */
#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */
#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */
#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */
#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */
#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */
#define IMC_B INDIC_MATRA_CATEGORY_BOTTOM /* 349 chars; Bottom */
#define IMC_BL INDIC_MATRA_CATEGORY_BOTTOM_AND_LEFT /* 1 chars; Bottom_And_Left */
#define IMC_BR INDIC_MATRA_CATEGORY_BOTTOM_AND_RIGHT /* 2 chars; Bottom_And_Right */
#define IMC_L INDIC_MATRA_CATEGORY_LEFT /* 61 chars; Left */
#define IMC_LR INDIC_MATRA_CATEGORY_LEFT_AND_RIGHT /* 21 chars; Left_And_Right */
#define IMC_x INDIC_MATRA_CATEGORY_NOT_APPLICABLE /* 1 chars; Not_Applicable */
#define IMC_O INDIC_MATRA_CATEGORY_OVERSTRUCK /* 10 chars; Overstruck */
#define IMC_R INDIC_MATRA_CATEGORY_RIGHT /* 281 chars; Right */
#define IMC_T INDIC_MATRA_CATEGORY_TOP /* 398 chars; Top */
#define IMC_TB INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM /* 10 chars; Top_And_Bottom */
#define IMC_TBR INDIC_MATRA_CATEGORY_TOP_AND_BOTTOM_AND_RIGHT /* 1 chars; Top_And_Bottom_And_Right */
#define IMC_TL INDIC_MATRA_CATEGORY_TOP_AND_LEFT /* 6 chars; Top_And_Left */
#define IMC_TLR INDIC_MATRA_CATEGORY_TOP_AND_LEFT_AND_RIGHT /* 4 chars; Top_And_Left_And_Right */
#define IMC_TR INDIC_MATRA_CATEGORY_TOP_AND_RIGHT /* 13 chars; Top_And_Right */
#define IMC_VOL INDIC_MATRA_CATEGORY_VISUAL_ORDER_LEFT /* 19 chars; Visual_Order_Left */
#pragma GCC diagnostic pop
#define _(S,M) INDIC_COMBINE_CATEGORIES (ISC_##S, IMC_##M)
@ -439,6 +440,7 @@ hb_indic_get_categories (hb_codepoint_t u)
}
#undef _
#undef ISC_A
#undef ISC_Bi
#undef ISC_BJN
@ -475,6 +477,7 @@ hb_indic_get_categories (hb_codepoint_t u)
#undef ISC_Vo
#undef ISC_M
#undef ISC_VI
#undef IMC_B
#undef IMC_BL
#undef IMC_BR
@ -491,6 +494,6 @@ hb_indic_get_categories (hb_codepoint_t u)
#undef IMC_TR
#undef IMC_VOL
#endif
/* == End of generated table == */

View File

@ -540,7 +540,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
case BASE_POS_LAST_SINHALA:
{
/* Sinhala base positioning is slightly different from main Indic, in that:
/* Sinhala base positioning is slightly different from main Indic, in that:
* 1. Its ZWJ behavior is different,
* 2. We don't need to look into the font for consonant positions.
*/
@ -669,8 +669,8 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
for (unsigned int i = base + 1; i < end; i++)
if (info[i].indic_category() == OT_H)
{
unsigned int j;
for (j = end - 1; j > i; j--)
unsigned int j;
for (j = end - 1; j > i; j--)
if (is_consonant (info[j]) ||
(disallow_double_halants && info[j].indic_category() == OT_H))
break;
@ -680,7 +680,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
memmove (&info[i], &info[i + 1], (j - i) * sizeof (info[0]));
info[j] = t;
}
break;
break;
}
}
@ -711,7 +711,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
}
}
} else if (info[i].indic_position() != POS_SMVD) {
last_pos = (indic_position_t) info[i].indic_position();
last_pos = (indic_position_t) info[i].indic_position();
}
}
}
@ -727,7 +727,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
info[j].indic_position() = info[i].indic_position();
last = i;
} else if (info[i].indic_category() == OT_M)
last = i;
last = i;
}
@ -764,7 +764,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
{
/* Note! syllable() is a one-byte field. */
for (unsigned int i = base; i < end; i++)
if (info[i].syllable() != 255)
if (info[i].syllable() != 255)
{
unsigned int max = i;
unsigned int j = start + info[i].syllable();
@ -852,7 +852,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
hb_codepoint_t glyphs[2];
for (unsigned int j = 0; j < pref_len; j++)
glyphs[j] = info[i + j].codepoint;
glyphs[j] = info[i + j].codepoint;
if (indic_plan->pref.would_substitute (glyphs, pref_len, face))
{
for (unsigned int j = 0; j < pref_len; j++)
@ -983,7 +983,7 @@ insert_dotted_circles_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() &&
buffer->cur().indic_category() == OT_Repha)
buffer->next_glyph ();
buffer->next_glyph ();
buffer->output_info (ginfo);
}
@ -1029,7 +1029,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
_hb_glyph_info_ligated (&info[i]) &&
_hb_glyph_info_multiplied (&info[i]))
{
/* This will make sure that this glyph passes is_halant() test. */
/* This will make sure that this glyph passes is_halant() test. */
info[i].indic_category() = OT_H;
_hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
}
@ -1092,7 +1092,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
}
if (start < base && info[base].indic_position() > POS_BASE_C)
base--;
base--;
break;
}
if (base == end && start < base &&
@ -1182,7 +1182,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
}
}
else
new_pos = start; /* No move. */
new_pos = start; /* No move. */
}
if (start < new_pos && info[new_pos].indic_position () != POS_PRE_M)
@ -1284,7 +1284,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
while (new_reph_pos + 1 < end && info[new_reph_pos + 1].indic_position() <= POS_AFTER_MAIN)
new_reph_pos++;
if (new_reph_pos < end)
goto reph_move;
goto reph_move;
}
/* 4. If reph should be positioned before post-base consonant, find
@ -1300,7 +1300,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
!( FLAG_UNSAFE (info[new_reph_pos + 1].indic_position()) & (FLAG (POS_POST_C) | FLAG (POS_AFTER_POST) | FLAG (POS_SMVD))))
new_reph_pos++;
if (new_reph_pos < end)
goto reph_move;
goto reph_move;
}
/* 5. If no consonant is found in steps 3 or 4, move reph to a position
@ -1382,7 +1382,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
* of the <pref> feature. (Note that a font may shape a Ra consonant with
* the feature generally but block it in certain contexts.)
*/
/* Note: We just check that something got substituted. We don't check that
/* Note: We just check that something got substituted. We don't check that
* the <pref> feature actually did it...
*
* Reorder pref only if it ligated. */
@ -1428,7 +1428,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
}
}
break;
break;
}
}
@ -1454,7 +1454,7 @@ final_reordering_syllable_indic (const hb_ot_shape_plan_t *plan,
{
case HB_SCRIPT_TAMIL:
case HB_SCRIPT_SINHALA:
break;
break;
default:
/* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.

View File

@ -378,7 +378,7 @@ insert_dotted_circles_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() &&
buffer->cur().khmer_category() == OT_Repha)
buffer->next_glyph ();
buffer->next_glyph ();
buffer->output_info (ginfo);
}

View File

@ -239,7 +239,7 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
}
if (pos == POS_BELOW_C && info[i].myanmar_category() != OT_A)
{
pos = POS_AFTER_SUB;
pos = POS_AFTER_SUB;
info[i].myanmar_position() = pos;
continue;
}

View File

@ -534,7 +534,7 @@ insert_dotted_circles_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful &&
last_syllable == buffer->cur().syllable() &&
buffer->cur().use_category() == USE_R)
buffer->next_glyph ();
buffer->next_glyph ();
buffer->output_info (ginfo);
}

View File

@ -45,30 +45,30 @@ recategorize_combining_class (hb_codepoint_t u,
{
switch (u)
{
case 0x0E31u:
case 0x0E34u:
case 0x0E35u:
case 0x0E36u:
case 0x0E37u:
case 0x0E47u:
case 0x0E4Cu:
case 0x0E4Du:
case 0x0E4Eu:
case 0x0E31u:
case 0x0E34u:
case 0x0E35u:
case 0x0E36u:
case 0x0E37u:
case 0x0E47u:
case 0x0E4Cu:
case 0x0E4Du:
case 0x0E4Eu:
klass = HB_UNICODE_COMBINING_CLASS_ABOVE_RIGHT;
break;
case 0x0EB1u:
case 0x0EB4u:
case 0x0EB5u:
case 0x0EB6u:
case 0x0EB7u:
case 0x0EBBu:
case 0x0ECCu:
case 0x0ECDu:
case 0x0EB1u:
case 0x0EB4u:
case 0x0EB5u:
case 0x0EB6u:
case 0x0EB7u:
case 0x0EBBu:
case 0x0ECCu:
case 0x0ECDu:
klass = HB_UNICODE_COMBINING_CLASS_ABOVE;
break;
case 0x0EBCu:
case 0x0EBCu:
klass = HB_UNICODE_COMBINING_CLASS_BELOW;
break;
}
@ -167,8 +167,8 @@ recategorize_combining_class (hb_codepoint_t u,
void
_hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
#ifdef HB_NO_OT_SHAPE_FALLBACK
return;
@ -232,10 +232,10 @@ position_mark (const hb_ot_shape_plan_t *plan HB_UNUSED,
case HB_UNICODE_COMBINING_CLASS_DOUBLE_ABOVE:
if (buffer->props.direction == HB_DIRECTION_LTR) {
pos.x_offset += base_extents.x_bearing + base_extents.width - mark_extents.width / 2 - mark_extents.x_bearing;
break;
break;
} else if (buffer->props.direction == HB_DIRECTION_RTL) {
pos.x_offset += base_extents.x_bearing - mark_extents.width / 2 - mark_extents.x_bearing;
break;
break;
}
HB_FALLTHROUGH;
@ -387,7 +387,7 @@ position_around_base (const hb_ot_shape_plan_t *plan,
if (last_combining_class != this_combining_class)
{
last_combining_class = this_combining_class;
cluster_extents = component_extents;
cluster_extents = component_extents;
}
position_mark (plan, font, buffer, cluster_extents, i, this_combining_class);

View File

@ -233,7 +233,7 @@ handle_variation_selector_cluster (const hb_ot_shape_normalize_context_t *c,
}
else
{
/* Just pass on the two characters separately, let GSUB do its magic. */
/* Just pass on the two characters separately, let GSUB do its magic. */
set_glyph (buffer->cur(), font);
buffer->next_glyph ();
set_glyph (buffer->cur(), font);
@ -343,7 +343,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
/* From idx to end are simple clusters. */
if (might_short_circuit)
{
unsigned int done = font->get_nominal_glyphs (end - buffer->idx,
unsigned int done = font->get_nominal_glyphs (end - buffer->idx,
&buffer->cur().codepoint,
sizeof (buffer->info[0]),
&buffer->cur().glyph_index(),

View File

@ -489,7 +489,7 @@ hb_set_unicode_props (hb_buffer_t *buffer)
if (i + 1 < count &&
_hb_unicode_is_emoji_Extended_Pictographic (info[i + 1].codepoint))
{
i++;
i++;
_hb_glyph_info_set_unicode_props (&info[i], buffer);
_hb_glyph_info_set_continuation (&info[i]);
}
@ -650,19 +650,19 @@ hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
while (start &&
_hb_glyph_info_get_general_category (&info[start - 1]) ==
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
start--;
start--;
while (end < count &&
_hb_glyph_info_get_general_category (&info[end]) ==
HB_UNICODE_GENERAL_CATEGORY_DECIMAL_NUMBER)
end++;
end++;
buffer->unsafe_to_break (start, end);
for (unsigned int j = start; j < i; j++)
info[j].mask |= pre_mask;
info[j].mask |= pre_mask;
info[i].mask |= c->plan->frac_mask;
for (unsigned int j = i + 1; j < end; j++)
info[j].mask |= post_mask;
info[j].mask |= post_mask;
i = end - 1;
}
@ -869,7 +869,7 @@ zero_mark_widths_by_gdef (hb_buffer_t *buffer, bool adjust_offsets)
if (_hb_glyph_info_is_mark (&info[i]))
{
if (adjust_offsets)
adjust_mark_offsets (&buffer->pos[i]);
adjust_mark_offsets (&buffer->pos[i]);
zero_mark_width (&buffer->pos[i]);
}
}
@ -885,7 +885,7 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
if (HB_DIRECTION_IS_HORIZONTAL (direction))
{
c->font->get_glyph_h_advances (count, &info[0].codepoint, sizeof(info[0]),
&pos[0].x_advance, sizeof(pos[0]));
&pos[0].x_advance, sizeof(pos[0]));
/* The nil glyph_h_origin() func returns 0, so no need to apply it. */
if (c->font->has_glyph_h_origin_func ())
for (unsigned int i = 0; i < count; i++)
@ -896,7 +896,7 @@ hb_ot_position_default (const hb_ot_shape_context_t *c)
else
{
c->font->get_glyph_v_advances (count, &info[0].codepoint, sizeof(info[0]),
&pos[0].y_advance, sizeof(pos[0]));
&pos[0].y_advance, sizeof(pos[0]));
for (unsigned int i = 0; i < count; i++)
{
c->font->subtract_glyph_v_origin (info[i].codepoint,

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);
};
@ -304,8 +304,8 @@ struct STAT
protected:
FixedVersion<>version; /* Version of the stat table
* initially set to 0x00010002u */
FixedVersion<>version; /* Version of the stat table
* initially set to 0x00010002u */
HBUINT16 designAxisSize; /* The size in bytes of each axis record. */
HBUINT16 designAxisCount;/* The number of design axis records. In a
* font with an 'fvar' table, this value must be

View File

@ -120,7 +120,7 @@ struct avar
for (unsigned int i = 0; i < count; i++)
{
if (unlikely (!map->sanitize (c)))
return_trace (false);
return_trace (false);
map = &StructAfter<SegmentMaps> (*map);
}

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. */
@ -199,7 +199,7 @@ struct fvar
for (unsigned int i = 0; i < count; i++)
if (axes[i].axisTag == tag)
{
if (axis_index)
if (axis_index)
*axis_index = i;
get_axis_deprecated (i, info);
return true;
@ -280,16 +280,16 @@ struct fvar
if (unlikely (!instance))
{
if (coords_length)
*coords_length = 0;
*coords_length = 0;
return 0;
}
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 ();
coords[i] = instanceCoords.arrayZ[i].to_float ();
}
return axisCount;
}
@ -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:
@ -70,10 +70,10 @@ struct VORG
}
template <typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it,
FWORD defaultVertOriginY)
Iterator it,
FWORD defaultVertOriginY)
{
if (unlikely (!c->extend_min ((*this)))) return;
@ -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
@ -99,15 +97,15 @@ struct VORG
+ vertYOrigins.as_array ()
| hb_filter (c->plan->glyphset (), &VertOriginMetric::glyph)
| hb_map ([&] (const VertOriginMetric& _)
{
hb_codepoint_t new_glyph = HB_SET_VALUE_INVALID;
c->plan->new_gid_for_old_gid (_.glyph, &new_glyph);
{
hb_codepoint_t new_glyph = HB_SET_VALUE_INVALID;
c->plan->new_gid_for_old_gid (_.glyph, &new_glyph);
VertOriginMetric metric;
metric.glyph = new_glyph;
metric.vertOriginY = _.vertOriginY;
return metric;
})
VertOriginMetric metric;
metric.glyph = new_glyph;
metric.vertOriginY = _.vertOriginY;
return metric;
})
;
/* serialize the new table */
@ -119,8 +117,8 @@ struct VORG
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
version.major == 1 &&
vertYOrigins.sanitize (c));
version.major == 1 &&
vertYOrigins.sanitize (c));
}
protected:

View File

@ -84,7 +84,7 @@ struct hb_pool_t
T* thread ()
{
for (unsigned i = 0; i < ARRAY_LENGTH (arrayZ) - 1; i++)
* (T**) &arrayZ[i] = &arrayZ[i + 1];
* (T**) &arrayZ[i] = &arrayZ[i + 1];
* (T**) &arrayZ[ARRAY_LENGTH (arrayZ) - 1] = nullptr;

View File

@ -326,8 +326,8 @@ struct hb_sanitize_context_t :
{
DEBUG_MSG_FUNC (SANITIZE, start, "passed first round with %d edits; going for second round", edit_count);
/* sanitize again to ensure no toe-stepping */
edit_count = 0;
/* sanitize again to ensure no toe-stepping */
edit_count = 0;
sane = t->sanitize (this);
if (edit_count) {
DEBUG_MSG_FUNC (SANITIZE, start, "requested %d edits in second round; FAILLING", edit_count);
@ -338,7 +338,7 @@ struct hb_sanitize_context_t :
else
{
if (edit_count && !writable) {
start = hb_blob_get_data_writable (blob, nullptr);
start = hb_blob_get_data_writable (blob, nullptr);
end = start + blob->length;
if (start)

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

@ -63,7 +63,7 @@ struct hb_set_t
bool is_empty () const
{
for (unsigned int i = 0; i < len (); i++)
if (v[i])
if (v[i])
return false;
return true;
}
@ -77,7 +77,7 @@ struct hb_set_t
elt_t *la = &elt (a);
elt_t *lb = &elt (b);
if (la == lb)
*la |= (mask (b) << 1) - mask(a);
*la |= (mask (b) << 1) - mask(a);
else
{
*la |= ~(mask (a) - 1);
@ -98,7 +98,7 @@ struct hb_set_t
{
unsigned int pop = 0;
for (unsigned int i = 0; i < len (); i++)
pop += hb_popcount (v[i]);
pop += hb_popcount (v[i]);
return pop;
}
@ -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;
@ -149,14 +154,14 @@ struct hb_set_t
hb_codepoint_t get_min () const
{
for (unsigned int i = 0; i < len (); i++)
if (v[i])
if (v[i])
return i * ELT_BITS + elt_get_min (v[i]);
return INVALID;
}
hb_codepoint_t get_max () const
{
for (int i = len () - 1; i >= 0; i--)
if (v[i])
if (v[i])
return i * ELT_BITS + elt_get_max (v[i]);
return 0;
}
@ -249,7 +254,7 @@ struct hb_set_t
unsigned int count = pages.length;
for (unsigned int i = 0; i < count; i++)
if (!pages[i].is_empty ())
return false;
return false;
return true;
}
@ -333,9 +338,9 @@ struct hb_set_t
unsigned int end = major_start (m + 1);
do
{
/* If we try harder we can change the following comparison to <=;
/* If we try harder we can change the following comparison to <=;
* Not sure if it's worth it. */
if (g < last_g) return false;
if (g < last_g) return false;
last_g = g;
page->add (g);
@ -415,7 +420,7 @@ struct hb_set_t
if (other->page_at (b).is_empty ()) { b++; continue; }
if (page_map[a].major != other->page_map[b].major ||
!page_at (a).is_equal (&other->page_at (b)))
return false;
return false;
a++;
b++;
}
@ -436,7 +441,7 @@ struct hb_set_t
hb_codepoint_t c = INVALID;
while (next (&c))
if (!larger_set->has (c))
return false;
return false;
return true;
}
@ -458,21 +463,21 @@ struct hb_set_t
{
if (page_map[a].major == other->page_map[b].major)
{
count++;
count++;
a++;
b++;
}
else if (page_map[a].major < other->page_map[b].major)
{
if (Op::passthru_left)
if (Op::passthru_left)
count++;
a++;
a++;
}
else
{
if (Op::passthru_right)
if (Op::passthru_right)
count++;
b++;
b++;
}
}
if (Op::passthru_left)
@ -482,7 +487,7 @@ struct hb_set_t
if (count > pages.length)
if (!resize (count))
return;
return;
newCount = count;
/* Process in-place backward. */
@ -673,7 +678,7 @@ struct hb_set_t
unsigned int count = pages.length;
for (unsigned int i = 0; i < count; i++)
if (!page_at (i).is_empty ())
return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min ();
return page_map[i].major * page_t::PAGE_BITS + page_at (i).get_min ();
return INVALID;
}
hb_codepoint_t get_max () const
@ -681,7 +686,7 @@ struct hb_set_t
unsigned int count = pages.length;
for (int i = count - 1; i >= 0; i++)
if (!page_at (i).is_empty ())
return page_map[(unsigned) i].major * page_t::PAGE_BITS + page_at (i).get_max ();
return page_map[(unsigned) i].major * page_t::PAGE_BITS + page_at (i).get_max ();
return INVALID;
}

View File

@ -164,13 +164,13 @@ hb_shape_plan_key_t::equal (const hb_shape_plan_key_t *other)
/**
* hb_shape_plan_create: (Xconstructor)
* @face:
* @props:
* @face:
* @props:
* @user_features: (array length=num_user_features):
* @num_user_features:
* @num_user_features:
* @shaper_list: (array zero-terminated=1):
*
*
*
*
* Return value: (transfer full):
*
@ -248,7 +248,7 @@ bail:
/**
* hb_shape_plan_get_empty:
*
*
*
*
* Return value: (transfer full):
*
@ -264,7 +264,7 @@ hb_shape_plan_get_empty ()
* hb_shape_plan_reference: (skip)
* @shape_plan: a shape plan.
*
*
*
*
* Return value: (transfer full):
*
@ -280,7 +280,7 @@ hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
* hb_shape_plan_destroy: (skip)
* @shape_plan: a shape plan.
*
*
*
*
* Since: 0.9.7
**/
@ -299,14 +299,14 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
/**
* hb_shape_plan_set_user_data: (skip)
* @shape_plan: a shape plan.
* @key:
* @data:
* @destroy:
* @replace:
* @key:
* @data:
* @destroy:
* @replace:
*
*
*
* Return value:
*
* Return value:
*
* Since: 0.9.7
**/
@ -323,9 +323,9 @@ hb_shape_plan_set_user_data (hb_shape_plan_t *shape_plan,
/**
* hb_shape_plan_get_user_data: (skip)
* @shape_plan: a shape plan.
* @key:
* @key:
*
*
*
*
* Return value: (transfer none):
*
@ -342,7 +342,7 @@ hb_shape_plan_get_user_data (hb_shape_plan_t *shape_plan,
* hb_shape_plan_get_shaper:
* @shape_plan: a shape plan.
*
*
*
*
* Return value: (transfer none):
*
@ -361,11 +361,11 @@ hb_shape_plan_get_shaper (hb_shape_plan_t *shape_plan)
* @font: a font.
* @buffer: a buffer.
* @features: (array length=num_features):
* @num_features:
* @num_features:
*
*
*
* Return value:
*
* Return value:
*
* Since: 0.9.7
**/
@ -420,13 +420,13 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
/**
* hb_shape_plan_create_cached:
* @face:
* @props:
* @face:
* @props:
* @user_features: (array length=num_user_features):
* @num_user_features:
* @num_user_features:
* @shaper_list: (array zero-terminated=1):
*
*
*
*
* Return value: (transfer full):
*
@ -481,8 +481,8 @@ retry:
for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
if (node->shape_plan->key.equal (&key))
{
DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
return hb_shape_plan_reference (node->shape_plan);
DEBUG_MSG_FUNC (SHAPE_PLAN, node->shape_plan, "fulfilled from cache");
return hb_shape_plan_reference (node->shape_plan);
}
}

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

@ -330,15 +330,15 @@ struct cff2_subset_plan {
{
subset_localsubrs[fd].init ();
offsets.localSubrsInfos[fd].init ();
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
return false;
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
return false;
unsigned int dataSize = subset_localsubrs[fd].total_size ();
if (dataSize > 0)
{
offsets.localSubrsInfos[fd].offset = final_size;
offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
unsigned int dataSize = subset_localsubrs[fd].total_size ();
if (dataSize > 0)
{
offsets.localSubrsInfos[fd].offset = final_size;
offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
}
}
}

View File

@ -172,7 +172,7 @@ hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input)
HB_EXTERN void
hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input,
hb_bool_t desubroutinize)
hb_bool_t desubroutinize)
{
subset_input->desubroutinize = desubroutinize;
}

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;
@ -58,8 +58,8 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
#ifndef HB_NO_SUBSET_CFF
static inline void
_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
hb_codepoint_t gid,
hb_set_t *gids_to_retain)
hb_codepoint_t gid,
hb_set_t *gids_to_retain)
{
hb_codepoint_t base_gid, accent_gid;
if (cff.get_seac_components (gid, &base_gid, &accent_gid))
@ -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)
@ -102,7 +110,7 @@ _remove_invalid_gids (hb_set_t *glyphs,
static void
_populate_gids_to_retain (hb_subset_plan_t* plan,
const hb_set_t *unicodes,
const hb_set_t *input_glyphs_to_retain,
const hb_set_t *input_glyphs_to_retain,
bool close_over_gsub)
{
OT::cmap::accelerator_t cmap;
@ -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.
@ -157,11 +167,11 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
static void
_create_old_gid_to_new_gid_map (const hb_face_t *face,
bool retain_gids,
bool retain_gids,
const hb_set_t *all_gids_to_retain,
hb_map_t *glyph_map, /* OUT */
hb_map_t *reverse_glyph_map, /* OUT */
unsigned int *num_glyphs /* OUT */)
hb_map_t *glyph_map, /* OUT */
hb_map_t *reverse_glyph_map, /* OUT */
unsigned int *num_glyphs /* OUT */)
{
if (!retain_gids)
{
@ -191,8 +201,8 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
}
static void
_nameid_closure (hb_face_t *face,
hb_set_t *nameids)
_nameid_closure (hb_face_t *face,
hb_set_t *nameids)
{
#ifndef HB_NO_STAT
face->table.STAT->collect_name_ids (nameids);
@ -213,8 +223,8 @@ _nameid_closure (hb_face_t *face,
* Since: 1.7.5
**/
hb_subset_plan_t *
hb_subset_plan_create (hb_face_t *face,
hb_subset_input_t *input)
hb_subset_plan_create (hb_face_t *face,
hb_subset_input_t *input)
{
hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
@ -235,16 +245,16 @@ hb_subset_plan_create (hb_face_t *face,
plan->reverse_glyph_map = hb_map_create ();
_populate_gids_to_retain (plan,
input->unicodes,
input->glyphs,
!input->drop_tables->has (HB_OT_TAG_GSUB));
input->unicodes,
input->glyphs,
!input->drop_tables->has (HB_OT_TAG_GSUB));
_create_old_gid_to_new_gid_map (face,
input->retain_gids,
input->retain_gids,
plan->_glyphset,
plan->glyph_map,
plan->reverse_glyph_map,
&plan->_num_output_glyphs);
plan->reverse_glyph_map,
&plan->_num_output_glyphs);
return plan;
}

View File

@ -108,7 +108,7 @@ struct hb_subset_plan_t
}
inline bool new_gid_for_codepoint (hb_codepoint_t codepoint,
hb_codepoint_t *new_gid) const
hb_codepoint_t *new_gid) const
{
hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
if (old_gid == HB_MAP_VALUE_INVALID)
@ -118,7 +118,7 @@ struct hb_subset_plan_t
}
inline bool new_gid_for_old_gid (hb_codepoint_t old_gid,
hb_codepoint_t *new_gid) const
hb_codepoint_t *new_gid) const
{
hb_codepoint_t gid = glyph_map->get (old_gid);
if (gid == HB_MAP_VALUE_INVALID)
@ -129,7 +129,7 @@ struct hb_subset_plan_t
}
inline bool old_gid_for_new_gid (hb_codepoint_t new_gid,
hb_codepoint_t *old_gid) const
hb_codepoint_t *old_gid) const
{
hb_codepoint_t gid = reverse_glyph_map->get (new_gid);
if (gid == HB_MAP_VALUE_INVALID)
@ -157,7 +157,7 @@ typedef struct hb_subset_plan_t hb_subset_plan_t;
HB_INTERNAL hb_subset_plan_t *
hb_subset_plan_create (hb_face_t *face,
hb_subset_input_t *input);
hb_subset_input_t *input);
HB_INTERNAL void
hb_subset_plan_destroy (hb_subset_plan_t *plan);

View File

@ -82,6 +82,7 @@ _subset2 (hb_subset_plan_t *plan)
if (unlikely (!buf.alloc (buf_size)))
{
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
hb_blob_destroy (source_blob);
return false;
}
retry:
@ -96,6 +97,7 @@ _subset2 (hb_subset_plan_t *plan)
if (unlikely (!buf.alloc (buf_size)))
{
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size);
hb_blob_destroy (source_blob);
return false;
}
goto retry;
@ -283,17 +285,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

@ -68,7 +68,7 @@ hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input);
HB_EXTERN void
hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input,
hb_bool_t desubroutinize);
hb_bool_t desubroutinize);
HB_EXTERN hb_bool_t
hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input);

View File

@ -385,8 +385,8 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
static const uint16_t name_IDs[] = { 1, 2, 3, 4, 6 };
unsigned int name_table_length = OT::name::min_size +
ARRAY_LENGTH (name_IDs) * OT::NameRecord::static_size +
name_str_len * 2; /* for name data in UTF16BE form */
ARRAY_LENGTH (name_IDs) * OT::NameRecord::static_size +
name_str_len * 2; /* for name data in UTF16BE form */
unsigned int padded_name_table_length = ((name_table_length + 3) & ~3);
unsigned int name_table_offset = (length + 3) & ~3;
@ -666,7 +666,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
if (event->index != last_index)
{
/* Save a snapshot of active features and the range. */
/* Save a snapshot of active features and the range. */
range_record_t *range = range_records.push ();
unsigned int offset = feature_records.length;
@ -701,7 +701,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
}
else
{
active_feature_t *feature = active_features.find (&event->feature);
active_feature_t *feature = active_features.find (&event->feature);
if (feature)
active_features.remove (feature - active_features.arrayZ);
}

View File

@ -235,10 +235,10 @@ struct hb_utf16_xe_t
hb_codepoint_t h = text[-1];
if (likely (hb_in_range<hb_codepoint_t> (h, 0xD800u, 0xDBFFu)))
{
/* High-surrogate in h */
*unicode = (h << 10) + c - ((0xD800u << 10) - 0x10000u + 0xDC00u);
text--;
return text;
/* High-surrogate in h */
*unicode = (h << 10) + c - ((0xD800u << 10) - 0x10000u + 0xDC00u);
text--;
return text;
}
}

View File

@ -290,7 +290,7 @@ struct hb_sorted_vector_t : hb_vector_t<Type>
typedef hb_sorted_array_t< Type> iter_t;
const_iter_t iter () const { return as_array (); }
const_iter_t citer () const { return as_array (); }
iter_t iter () { return as_array (); }
iter_t iter () { return as_array (); }
operator iter_t () { return iter (); }
operator const_iter_t () const { return iter (); }

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