mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 12:25:53 +00:00
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:
parent
c23b90b0da
commit
5611980e6c
@ -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
|
||||
====================================
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -411,7 +411,7 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc
|
||||
dump_use_data_CPPFLAGS = $(HBCFLAGS)
|
||||
dump_use_data_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
|
||||
COMPILED_TESTS = test-algs test-iter test-meta test-ot-tag test-unicode-ranges test-bimap
|
||||
COMPILED_TESTS = test-algs test-iter test-meta test-number test-ot-tag test-unicode-ranges test-bimap
|
||||
COMPILED_TESTS_CPPFLAGS = $(HBCFLAGS) -DMAIN -UNDEBUG
|
||||
COMPILED_TESTS_LDADD = libharfbuzz.la $(HBLIBS)
|
||||
check_PROGRAMS += $(COMPILED_TESTS)
|
||||
@ -429,6 +429,10 @@ test_meta_SOURCES = test-meta.cc hb-static.cc
|
||||
test_meta_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_meta_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_number_SOURCES = test-number.cc hb-number.cc
|
||||
test_number_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_number_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
||||
test_ot_tag_SOURCES = hb-ot-tag.cc
|
||||
test_ot_tag_CPPFLAGS = $(COMPILED_TESTS_CPPFLAGS)
|
||||
test_ot_tag_LDADD = $(COMPILED_TESTS_LDADD)
|
||||
|
@ -49,6 +49,8 @@ HB_BASE_sources = \
|
||||
hb-meta.hh \
|
||||
hb-mutex.hh \
|
||||
hb-null.hh \
|
||||
hb-number.cc \
|
||||
hb-number.hh \
|
||||
hb-object.hh \
|
||||
hb-open-file.hh \
|
||||
hb-open-type.hh \
|
||||
@ -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 \
|
||||
|
@ -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 */
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "hb-fallback-shape.cc"
|
||||
#include "hb-font.cc"
|
||||
#include "hb-map.cc"
|
||||
#include "hb-number.cc"
|
||||
#include "hb-ot-cff1-table.cc"
|
||||
#include "hb-ot-cff2-table.cc"
|
||||
#include "hb-ot-color.cc"
|
||||
|
@ -65,7 +65,7 @@ struct FontDescriptor
|
||||
protected:
|
||||
Tag tag; /* The 4-byte table tag name. */
|
||||
union {
|
||||
Fixed value; /* The value for the descriptor tag. */
|
||||
HBFixed value; /* The value for the descriptor tag. */
|
||||
HBUINT32 nalfType; /* If the tag is `nalf`, see non_alphabetic_value_t */
|
||||
} u;
|
||||
public:
|
||||
@ -108,7 +108,7 @@ struct fdsc
|
||||
}
|
||||
|
||||
protected:
|
||||
Fixed version; /* Version number of the font descriptors
|
||||
HBFixed version; /* Version number of the font descriptors
|
||||
* table (0x00010000 for the current version). */
|
||||
LArrayOf<FontDescriptor>
|
||||
descriptors; /* List of tagged-coordinate pairs style descriptors
|
||||
|
@ -82,7 +82,7 @@ struct BaselineTableFormat2Part
|
||||
}
|
||||
|
||||
protected:
|
||||
GlyphID stdGlyph; /* The specific glyph index number in this
|
||||
HBGlyphID stdGlyph; /* The specific glyph index number in this
|
||||
* font that is used to set the baseline values.
|
||||
* This is the standard glyph.
|
||||
* This glyph must contain a set of control points
|
||||
@ -105,7 +105,7 @@ struct BaselineTableFormat3Part
|
||||
}
|
||||
|
||||
protected:
|
||||
GlyphID stdGlyph; /* ditto */
|
||||
HBGlyphID stdGlyph; /* ditto */
|
||||
HBUINT16 ctlPoints[32]; /* ditto */
|
||||
Lookup<HBUINT16>
|
||||
lookupTable; /* Lookup table that maps glyphs to their
|
||||
|
@ -93,8 +93,8 @@ struct LookupSegmentSingle
|
||||
return_trace (c->check_struct (this) && value.sanitize (c, base));
|
||||
}
|
||||
|
||||
GlyphID last; /* Last GlyphID in this segment */
|
||||
GlyphID first; /* First GlyphID in this segment */
|
||||
HBGlyphID last; /* Last GlyphID in this segment */
|
||||
HBGlyphID first; /* First GlyphID in this segment */
|
||||
T value; /* The lookup value (only one) */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4 + T::static_size);
|
||||
@ -162,8 +162,8 @@ struct LookupSegmentArray
|
||||
valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...));
|
||||
}
|
||||
|
||||
GlyphID last; /* Last GlyphID in this segment */
|
||||
GlyphID first; /* First GlyphID in this segment */
|
||||
HBGlyphID last; /* Last GlyphID in this segment */
|
||||
HBGlyphID first; /* First GlyphID in this segment */
|
||||
NNOffsetTo<UnsizedArrayOf<T>>
|
||||
valuesZ; /* A 16-bit offset from the start of
|
||||
* the table to the data. */
|
||||
@ -222,7 +222,7 @@ struct LookupSingle
|
||||
return_trace (c->check_struct (this) && value.sanitize (c, base));
|
||||
}
|
||||
|
||||
GlyphID glyph; /* Last GlyphID */
|
||||
HBGlyphID glyph; /* Last GlyphID */
|
||||
T value; /* The lookup value (only one) */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (2 + T::static_size);
|
||||
@ -284,7 +284,7 @@ struct LookupFormat8
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 8 */
|
||||
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
|
||||
* glyph minus the value of firstGlyph plus 1). */
|
||||
UnsizedArrayOf<T>
|
||||
@ -326,7 +326,7 @@ struct LookupFormat10
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 8 */
|
||||
HBUINT16 valueSize; /* Byte size of each value. */
|
||||
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
|
||||
* glyph minus the value of firstGlyph plus 1). */
|
||||
UnsizedArrayOf<HBUINT8>
|
||||
@ -658,7 +658,7 @@ struct ClassTable
|
||||
return_trace (c->check_struct (this) && classArray.sanitize (c));
|
||||
}
|
||||
protected:
|
||||
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||
ArrayOf<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus
|
||||
* firstGlyph). */
|
||||
public:
|
||||
@ -678,7 +678,7 @@ struct ObsoleteTypes
|
||||
const void *base,
|
||||
const T *array)
|
||||
{
|
||||
return (offset - ((const char *) array - (const char *) base)) / sizeof (T);
|
||||
return (offset - ((const char *) array - (const char *) base)) / T::static_size;
|
||||
}
|
||||
template <typename T>
|
||||
static unsigned int byteOffsetToIndex (unsigned int offset,
|
||||
|
@ -206,7 +206,7 @@ struct feat
|
||||
SortedUnsizedArrayOf<FeatureName>
|
||||
namesZ; /* The feature name array. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (24);
|
||||
DEFINE_SIZE_ARRAY (12, namesZ);
|
||||
};
|
||||
|
||||
} /* namespace AAT */
|
||||
|
@ -70,9 +70,9 @@ struct DecompositionAction
|
||||
|
||||
ActionSubrecordHeader
|
||||
header;
|
||||
Fixed lowerLimit; /* If the distance factor is less than this value,
|
||||
HBFixed lowerLimit; /* If the distance factor is less than this value,
|
||||
* then the ligature is decomposed. */
|
||||
Fixed upperLimit; /* If the distance factor is greater than this value,
|
||||
HBFixed upperLimit; /* If the distance factor is greater than this value,
|
||||
* then the ligature is decomposed. */
|
||||
HBUINT16 order; /* Numerical order in which this ligature will
|
||||
* be decomposed; you may want infrequent ligatures
|
||||
@ -100,7 +100,7 @@ struct UnconditionalAddGlyphAction
|
||||
protected:
|
||||
ActionSubrecordHeader
|
||||
header;
|
||||
GlyphID addGlyph; /* Glyph that should be added if the distance factor
|
||||
HBGlyphID addGlyph; /* Glyph that should be added if the distance factor
|
||||
* is growing. */
|
||||
|
||||
public:
|
||||
@ -118,14 +118,14 @@ struct ConditionalAddGlyphAction
|
||||
protected:
|
||||
ActionSubrecordHeader
|
||||
header;
|
||||
Fixed substThreshold; /* Distance growth factor (in ems) at which
|
||||
HBFixed substThreshold; /* Distance growth factor (in ems) at which
|
||||
* this glyph is replaced and the growth factor
|
||||
* recalculated. */
|
||||
GlyphID addGlyph; /* Glyph to be added as kashida. If this value is
|
||||
HBGlyphID addGlyph; /* Glyph to be added as kashida. If this value is
|
||||
* 0xFFFF, no extra glyph will be added. Note that
|
||||
* generally when a glyph is added, justification
|
||||
* will need to be redone. */
|
||||
GlyphID substGlyph; /* Glyph to be substituted for this glyph if the
|
||||
HBGlyphID substGlyph; /* Glyph to be substituted for this glyph if the
|
||||
* growth factor equals or exceeds the value of
|
||||
* substThreshold. */
|
||||
public:
|
||||
@ -146,13 +146,13 @@ struct DuctileGlyphAction
|
||||
HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
|
||||
* This would normally be 0x64756374 ('duct'),
|
||||
* but you may use any axis the font contains. */
|
||||
Fixed minimumLimit; /* The lowest value for the ductility axis tha
|
||||
HBFixed minimumLimit; /* The lowest value for the ductility axis tha
|
||||
* still yields an acceptable appearance. Normally
|
||||
* this will be 1.0. */
|
||||
Fixed noStretchValue; /* This is the default value that corresponds to
|
||||
HBFixed noStretchValue; /* This is the default value that corresponds to
|
||||
* no change in appearance. Normally, this will
|
||||
* be 1.0. */
|
||||
Fixed maximumLimit; /* The highest value for the ductility axis that
|
||||
HBFixed maximumLimit; /* The highest value for the ductility axis that
|
||||
* still yields an acceptable appearance. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (22);
|
||||
@ -170,7 +170,7 @@ struct RepeatedAddGlyphAction
|
||||
ActionSubrecordHeader
|
||||
header;
|
||||
HBUINT16 flags; /* Currently unused; set to 0. */
|
||||
GlyphID glyph; /* Glyph that should be added if the distance factor
|
||||
HBGlyphID glyph; /* Glyph that should be added if the distance factor
|
||||
* is growing. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (10);
|
||||
@ -271,14 +271,14 @@ struct JustWidthDeltaEntry
|
||||
};
|
||||
|
||||
protected:
|
||||
Fixed beforeGrowLimit;/* The ratio by which the advance width of the
|
||||
HBFixed beforeGrowLimit;/* The ratio by which the advance width of the
|
||||
* glyph is permitted to grow on the left or top side. */
|
||||
Fixed beforeShrinkLimit;
|
||||
HBFixed beforeShrinkLimit;
|
||||
/* The ratio by which the advance width of the
|
||||
* glyph is permitted to shrink on the left or top side. */
|
||||
Fixed afterGrowLimit; /* The ratio by which the advance width of the glyph
|
||||
HBFixed afterGrowLimit; /* The ratio by which the advance width of the glyph
|
||||
* is permitted to shrink on the left or top side. */
|
||||
Fixed afterShrinkLimit;
|
||||
HBFixed afterShrinkLimit;
|
||||
/* The ratio by which the advance width of the glyph
|
||||
* is at most permitted to shrink on the right or
|
||||
* bottom side. */
|
||||
|
@ -82,8 +82,8 @@ struct KernPair
|
||||
}
|
||||
|
||||
protected:
|
||||
GlyphID left;
|
||||
GlyphID right;
|
||||
HBGlyphID left;
|
||||
HBGlyphID right;
|
||||
FWORD value;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
@ -392,7 +392,7 @@ struct KerxSubTableFormat2
|
||||
|
||||
const UnsizedArrayOf<FWORD> &arrayZ = this+array;
|
||||
unsigned int kern_idx = l + r;
|
||||
kern_idx = Types::offsetToIndex (kern_idx, this, &arrayZ);
|
||||
kern_idx = Types::offsetToIndex (kern_idx, this, arrayZ.arrayZ);
|
||||
const FWORD *v = &arrayZ[kern_idx];
|
||||
if (unlikely (!v->sanitize (&c->sanitizer))) return 0;
|
||||
|
||||
@ -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++)
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "hb.hh"
|
||||
#include "hb-meta.hh"
|
||||
#include "hb-null.hh"
|
||||
#include "hb-number.hh"
|
||||
|
||||
|
||||
/* Encodes three unsigned integers in one 64-bit number. If the inputs have more than 21 bits,
|
||||
@ -82,6 +83,7 @@ HB_FUNCOBJ (hb_bool);
|
||||
struct
|
||||
{
|
||||
private:
|
||||
|
||||
template <typename T> constexpr auto
|
||||
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
|
||||
|
||||
@ -895,17 +897,12 @@ hb_stable_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
|
||||
static inline hb_bool_t
|
||||
hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *out)
|
||||
{
|
||||
/* Pain because we don't know whether s is nul-terminated. */
|
||||
char buf[64];
|
||||
len = hb_min (ARRAY_LENGTH (buf) - 1, len);
|
||||
strncpy (buf, s, len);
|
||||
buf[len] = '\0';
|
||||
unsigned int v;
|
||||
const char *p = s;
|
||||
const char *end = p + len;
|
||||
if (unlikely (!hb_parse_uint (&p, end, &v, true/* whole buffer */, base)))
|
||||
return false;
|
||||
|
||||
char *end;
|
||||
errno = 0;
|
||||
unsigned long v = strtoul (buf, &end, base);
|
||||
if (errno) return false;
|
||||
if (*end) return false;
|
||||
*out = v;
|
||||
return true;
|
||||
}
|
||||
@ -994,6 +991,18 @@ struct
|
||||
operator () (const T &a) const HB_AUTO_RETURN (-a)
|
||||
}
|
||||
HB_FUNCOBJ (hb_neg);
|
||||
struct
|
||||
{
|
||||
template <typename T> constexpr auto
|
||||
operator () (T &a) const HB_AUTO_RETURN (++a)
|
||||
}
|
||||
HB_FUNCOBJ (hb_inc);
|
||||
struct
|
||||
{
|
||||
template <typename T> constexpr auto
|
||||
operator () (T &a) const HB_AUTO_RETURN (--a)
|
||||
}
|
||||
HB_FUNCOBJ (hb_dec);
|
||||
|
||||
|
||||
/* Compiler-assisted vectorization. */
|
||||
|
@ -50,7 +50,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||
template <typename U,
|
||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||
hb_array_t (const hb_array_t<U> &o) :
|
||||
hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (),
|
||||
hb_iter_with_fallback_t<hb_array_t, Type&> (),
|
||||
arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
|
||||
template <typename U,
|
||||
hb_enable_if (hb_is_cr_convertible(U, Type))>
|
||||
@ -106,7 +106,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||
*/
|
||||
|
||||
/* Note: our compare is NOT lexicographic; it also does NOT call Type::cmp. */
|
||||
int cmp (const hb_array_t<Type> &a) const
|
||||
int cmp (const hb_array_t &a) const
|
||||
{
|
||||
if (length != a.length)
|
||||
return (int) a.length - (int) length;
|
||||
@ -114,8 +114,8 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||
}
|
||||
HB_INTERNAL static int cmp (const void *pa, const void *pb)
|
||||
{
|
||||
hb_array_t<Type> *a = (hb_array_t<Type> *) pa;
|
||||
hb_array_t<Type> *b = (hb_array_t<Type> *) pb;
|
||||
hb_array_t *a = (hb_array_t *) pa;
|
||||
hb_array_t *b = (hb_array_t *) pb;
|
||||
return b->cmp (*a);
|
||||
}
|
||||
|
||||
@ -141,13 +141,13 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||
hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*))
|
||||
{
|
||||
if (likely (length))
|
||||
hb_qsort (arrayZ, length, this->item_size, cmp_);
|
||||
hb_qsort (arrayZ, length, this->get_item_size (), cmp_);
|
||||
return hb_sorted_array_t<Type> (*this);
|
||||
}
|
||||
hb_sorted_array_t<Type> qsort ()
|
||||
{
|
||||
if (likely (length))
|
||||
hb_qsort (arrayZ, length, this->item_size, Type::cmp);
|
||||
hb_qsort (arrayZ, length, this->get_item_size (), Type::cmp);
|
||||
return hb_sorted_array_t<Type> (*this);
|
||||
}
|
||||
void qsort (unsigned int start, unsigned int end)
|
||||
@ -155,16 +155,16 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
|
||||
end = hb_min (end, length);
|
||||
assert (start <= end);
|
||||
if (likely (start < end))
|
||||
hb_qsort (arrayZ + start, end - start, this->item_size, Type::cmp);
|
||||
hb_qsort (arrayZ + start, end - start, this->get_item_size (), Type::cmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Other methods.
|
||||
*/
|
||||
|
||||
unsigned int get_size () const { return length * this->item_size; }
|
||||
unsigned int get_size () const { return length * this->get_item_size (); }
|
||||
|
||||
hb_array_t<Type> sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const
|
||||
hb_array_t sub_array (unsigned int start_offset = 0, unsigned int *seg_count = nullptr /* IN/OUT */) const
|
||||
{
|
||||
if (!start_offset && !seg_count)
|
||||
return *this;
|
||||
@ -176,11 +176,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)
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -63,6 +63,8 @@ typedef __int32 int32_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
#elif defined (__KERNEL__)
|
||||
# include <linux/types.h>
|
||||
#else
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
|
@ -58,6 +58,7 @@
|
||||
#define HB_NO_BITMAP
|
||||
#define HB_NO_CFF
|
||||
#define HB_NO_COLOR
|
||||
#define HB_NO_ERRNO
|
||||
#define HB_NO_FACE_COLLECT_UNICODES
|
||||
#define HB_NO_GETENV
|
||||
#define HB_NO_HINTING
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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.");
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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++;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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() */
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
240
gfx/harfbuzz/src/hb-number-parser.hh
Normal file
240
gfx/harfbuzz/src/hb-number-parser.hh
Normal file
@ -0,0 +1,240 @@
|
||||
|
||||
#line 1 "hb-number-parser.rl"
|
||||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_NUMBER_PARSER_HH
|
||||
#define HB_NUMBER_PARSER_HH
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
|
||||
#line 37 "hb-number-parser.hh"
|
||||
static const unsigned char _double_parser_trans_keys[] = {
|
||||
0u, 0u, 43u, 57u, 46u, 57u, 48u, 57u, 43u, 57u, 48u, 57u, 48u, 101u, 48u, 57u,
|
||||
46u, 101u, 0
|
||||
};
|
||||
|
||||
static const char _double_parser_key_spans[] = {
|
||||
0, 15, 12, 10, 15, 10, 54, 10,
|
||||
56
|
||||
};
|
||||
|
||||
static const unsigned char _double_parser_index_offsets[] = {
|
||||
0, 0, 16, 29, 40, 56, 67, 122,
|
||||
133
|
||||
};
|
||||
|
||||
static const char _double_parser_indicies[] = {
|
||||
0, 1, 2, 3, 1, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
1, 3, 1, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 1, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5,
|
||||
1, 6, 1, 7, 1, 1, 8, 8,
|
||||
8, 8, 8, 8, 8, 8, 8, 8,
|
||||
1, 8, 8, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 1, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 9, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 9, 1, 8, 8, 8, 8, 8,
|
||||
8, 8, 8, 8, 8, 1, 3, 1,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 9, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 9, 1, 0
|
||||
};
|
||||
|
||||
static const char _double_parser_trans_targs[] = {
|
||||
2, 0, 2, 3, 8, 6, 5, 5,
|
||||
7, 4
|
||||
};
|
||||
|
||||
static const char _double_parser_trans_actions[] = {
|
||||
0, 0, 1, 0, 2, 3, 0, 4,
|
||||
5, 0
|
||||
};
|
||||
|
||||
static const int double_parser_start = 1;
|
||||
static const int double_parser_first_final = 6;
|
||||
static const int double_parser_error = 0;
|
||||
|
||||
static const int double_parser_en_main = 1;
|
||||
|
||||
|
||||
#line 70 "hb-number-parser.rl"
|
||||
|
||||
|
||||
/* Works only for n < 512 */
|
||||
static inline double
|
||||
_pow10 (unsigned int exponent)
|
||||
{
|
||||
static const double _powers_of_10[] =
|
||||
{
|
||||
1.0e+256,
|
||||
1.0e+128,
|
||||
1.0e+64,
|
||||
1.0e+32,
|
||||
1.0e+16,
|
||||
1.0e+8,
|
||||
10000.,
|
||||
100.,
|
||||
10.
|
||||
};
|
||||
unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
|
||||
double result = 1;
|
||||
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
|
||||
if (exponent & mask) result *= *power;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline double
|
||||
strtod_rl (const char *buf, char **end_ptr)
|
||||
{
|
||||
const char *p, *pe;
|
||||
double value = 0;
|
||||
double frac = 0;
|
||||
double frac_count = 0;
|
||||
unsigned int exp = 0;
|
||||
bool neg = false, exp_neg = false, exp_overflow = false;
|
||||
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
||||
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||
p = buf;
|
||||
pe = p + strlen (p);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
|
||||
int cs;
|
||||
|
||||
#line 142 "hb-number-parser.hh"
|
||||
{
|
||||
cs = double_parser_start;
|
||||
}
|
||||
|
||||
#line 147 "hb-number-parser.hh"
|
||||
{
|
||||
int _slen;
|
||||
int _trans;
|
||||
const unsigned char *_keys;
|
||||
const char *_inds;
|
||||
if ( p == pe )
|
||||
goto _test_eof;
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
_resume:
|
||||
_keys = _double_parser_trans_keys + (cs<<1);
|
||||
_inds = _double_parser_indicies + _double_parser_index_offsets[cs];
|
||||
|
||||
_slen = _double_parser_key_spans[cs];
|
||||
_trans = _inds[ _slen > 0 && _keys[0] <=(*p) &&
|
||||
(*p) <= _keys[1] ?
|
||||
(*p) - _keys[0] : _slen ];
|
||||
|
||||
cs = _double_parser_trans_targs[_trans];
|
||||
|
||||
if ( _double_parser_trans_actions[_trans] == 0 )
|
||||
goto _again;
|
||||
|
||||
switch ( _double_parser_trans_actions[_trans] ) {
|
||||
case 1:
|
||||
#line 39 "hb-number-parser.rl"
|
||||
{ neg = true; }
|
||||
break;
|
||||
case 4:
|
||||
#line 40 "hb-number-parser.rl"
|
||||
{ exp_neg = true; }
|
||||
break;
|
||||
case 2:
|
||||
#line 42 "hb-number-parser.rl"
|
||||
{
|
||||
value = value * 10. + ((*p) - '0');
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
#line 45 "hb-number-parser.rl"
|
||||
{
|
||||
if (likely (frac <= MAX_FRACT / 10))
|
||||
{
|
||||
frac = frac * 10. + ((*p) - '0');
|
||||
++frac_count;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
#line 52 "hb-number-parser.rl"
|
||||
{
|
||||
if (likely (exp * 10 + ((*p) - '0') <= MAX_EXP))
|
||||
exp = exp * 10 + ((*p) - '0');
|
||||
else
|
||||
exp_overflow = true;
|
||||
}
|
||||
break;
|
||||
#line 205 "hb-number-parser.hh"
|
||||
}
|
||||
|
||||
_again:
|
||||
if ( cs == 0 )
|
||||
goto _out;
|
||||
if ( ++p != pe )
|
||||
goto _resume;
|
||||
_test_eof: {}
|
||||
_out: {}
|
||||
}
|
||||
|
||||
#line 116 "hb-number-parser.rl"
|
||||
|
||||
|
||||
*end_ptr = (char *) p;
|
||||
|
||||
if (frac_count) value += frac / _pow10 (frac_count);
|
||||
if (neg) value *= -1.;
|
||||
|
||||
if (unlikely (exp_overflow))
|
||||
{
|
||||
if (value == 0) return value;
|
||||
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
|
||||
else return neg ? -DBL_MAX : DBL_MAX;
|
||||
}
|
||||
|
||||
if (exp)
|
||||
{
|
||||
if (exp_neg) value /= _pow10 (exp);
|
||||
else value *= _pow10 (exp);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif /* HB_NUMBER_PARSER_HH */
|
139
gfx/harfbuzz/src/hb-number-parser.rl
Normal file
139
gfx/harfbuzz/src/hb-number-parser.rl
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HB_NUMBER_PARSER_HH
|
||||
#define HB_NUMBER_PARSER_HH
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
#include <float.h>
|
||||
|
||||
%%{
|
||||
|
||||
machine double_parser;
|
||||
alphtype unsigned char;
|
||||
write data;
|
||||
|
||||
action see_neg { neg = true; }
|
||||
action see_exp_neg { exp_neg = true; }
|
||||
|
||||
action add_int {
|
||||
value = value * 10. + (fc - '0');
|
||||
}
|
||||
action add_frac {
|
||||
if (likely (frac <= MAX_FRACT / 10))
|
||||
{
|
||||
frac = frac * 10. + (fc - '0');
|
||||
++frac_count;
|
||||
}
|
||||
}
|
||||
action add_exp {
|
||||
if (likely (exp * 10 + (fc - '0') <= MAX_EXP))
|
||||
exp = exp * 10 + (fc - '0');
|
||||
else
|
||||
exp_overflow = true;
|
||||
}
|
||||
|
||||
num = [0-9]+;
|
||||
|
||||
main := (
|
||||
(
|
||||
(('+'|'-'@see_neg)? num @add_int) ('.' num @add_frac)?
|
||||
|
|
||||
(('+'|'-'@see_neg)? '.' num @add_frac)
|
||||
)
|
||||
(('e'|'E') (('+'|'-'@see_exp_neg)? num @add_exp))?
|
||||
);
|
||||
|
||||
}%%
|
||||
|
||||
/* Works only for n < 512 */
|
||||
static inline double
|
||||
_pow10 (unsigned int exponent)
|
||||
{
|
||||
static const double _powers_of_10[] =
|
||||
{
|
||||
1.0e+256,
|
||||
1.0e+128,
|
||||
1.0e+64,
|
||||
1.0e+32,
|
||||
1.0e+16,
|
||||
1.0e+8,
|
||||
10000.,
|
||||
100.,
|
||||
10.
|
||||
};
|
||||
unsigned int mask = 1 << (ARRAY_LENGTH (_powers_of_10) - 1);
|
||||
double result = 1;
|
||||
for (const double *power = _powers_of_10; mask; ++power, mask >>= 1)
|
||||
if (exponent & mask) result *= *power;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline double
|
||||
strtod_rl (const char *buf, char **end_ptr)
|
||||
{
|
||||
const char *p, *pe;
|
||||
double value = 0;
|
||||
double frac = 0;
|
||||
double frac_count = 0;
|
||||
unsigned int exp = 0;
|
||||
bool neg = false, exp_neg = false, exp_overflow = false;
|
||||
const unsigned long long MAX_FRACT = 0xFFFFFFFFFFFFFull; /* 1^52-1 */
|
||||
const unsigned int MAX_EXP = 0x7FFu; /* 1^11-1 */
|
||||
p = buf;
|
||||
pe = p + strlen (p);
|
||||
|
||||
while (p < pe && ISSPACE (*p))
|
||||
p++;
|
||||
|
||||
int cs;
|
||||
%%{
|
||||
write init;
|
||||
write exec;
|
||||
}%%
|
||||
|
||||
*end_ptr = (char *) p;
|
||||
|
||||
if (frac_count) value += frac / _pow10 (frac_count);
|
||||
if (neg) value *= -1.;
|
||||
|
||||
if (unlikely (exp_overflow))
|
||||
{
|
||||
if (value == 0) return value;
|
||||
if (exp_neg) return neg ? -DBL_MIN : DBL_MIN;
|
||||
else return neg ? -DBL_MAX : DBL_MAX;
|
||||
}
|
||||
|
||||
if (exp)
|
||||
{
|
||||
if (exp_neg) value /= _pow10 (exp);
|
||||
else value *= _pow10 (exp);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif /* HB_NUMBER_PARSER_HH */
|
147
gfx/harfbuzz/src/hb-number.cc
Normal file
147
gfx/harfbuzz/src/hb-number.cc
Normal file
@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright © 2019 Ebrahim Byagowi
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "hb.hh"
|
||||
#include "hb-machinery.hh"
|
||||
#include "hb-number-parser.hh"
|
||||
|
||||
#include <locale.h>
|
||||
#ifdef HAVE_XLOCALE_H
|
||||
#include <xlocale.h>
|
||||
#endif
|
||||
|
||||
template<typename T, typename Func>
|
||||
static bool
|
||||
_parse_number (const char **pp, const char *end, T *pv,
|
||||
bool whole_buffer, Func f)
|
||||
{
|
||||
char buf[32];
|
||||
unsigned int len = hb_min (ARRAY_LENGTH (buf) - 1,
|
||||
(unsigned int) (end - *pp));
|
||||
strncpy (buf, *pp, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
char *p = buf;
|
||||
char *pend = p;
|
||||
|
||||
errno = 0;
|
||||
*pv = f (p, &pend);
|
||||
if (unlikely (errno || p == pend ||
|
||||
/* Check if consumed whole buffer if is requested */
|
||||
(whole_buffer && pend - p != end - *pp))) return false;
|
||||
|
||||
*pp += pend - p;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
hb_parse_int (const char **pp, const char *end, int *pv, bool whole_buffer)
|
||||
{
|
||||
return _parse_number<int> (pp, end, pv, whole_buffer,
|
||||
[] (const char *p, char **end)
|
||||
{ return strtol (p, end, 10); });
|
||||
}
|
||||
|
||||
bool
|
||||
hb_parse_uint (const char **pp, const char *end, unsigned int *pv,
|
||||
bool whole_buffer, int base)
|
||||
{
|
||||
return _parse_number<unsigned int> (pp, end, pv, whole_buffer,
|
||||
[base] (const char *p, char **end)
|
||||
{ return strtoul (p, end, base); });
|
||||
}
|
||||
|
||||
|
||||
#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
|
||||
#define USE_XLOCALE 1
|
||||
#define HB_LOCALE_T locale_t
|
||||
#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
|
||||
#define HB_FREE_LOCALE(loc) freelocale (loc)
|
||||
#elif defined(_MSC_VER)
|
||||
#define USE_XLOCALE 1
|
||||
#define HB_LOCALE_T _locale_t
|
||||
#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
|
||||
#define HB_FREE_LOCALE(loc) _free_locale (loc)
|
||||
#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
|
||||
#endif
|
||||
|
||||
#ifdef USE_XLOCALE
|
||||
|
||||
#if HB_USE_ATEXIT
|
||||
static void free_static_C_locale ();
|
||||
#endif
|
||||
|
||||
static struct hb_C_locale_lazy_loader_t : hb_lazy_loader_t<hb_remove_pointer<HB_LOCALE_T>,
|
||||
hb_C_locale_lazy_loader_t>
|
||||
{
|
||||
static HB_LOCALE_T create ()
|
||||
{
|
||||
HB_LOCALE_T C_locale = HB_CREATE_LOCALE ("C");
|
||||
|
||||
#if HB_USE_ATEXIT
|
||||
atexit (free_static_C_locale);
|
||||
#endif
|
||||
|
||||
return C_locale;
|
||||
}
|
||||
static void destroy (HB_LOCALE_T p)
|
||||
{
|
||||
HB_FREE_LOCALE (p);
|
||||
}
|
||||
static HB_LOCALE_T get_null ()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
} static_C_locale;
|
||||
|
||||
#if HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_C_locale ()
|
||||
{
|
||||
static_C_locale.free_instance ();
|
||||
}
|
||||
#endif
|
||||
|
||||
static HB_LOCALE_T
|
||||
get_C_locale ()
|
||||
{
|
||||
return static_C_locale.get_unconst ();
|
||||
}
|
||||
#endif /* USE_XLOCALE */
|
||||
|
||||
bool
|
||||
hb_parse_double (const char **pp, const char *end, double *pv,
|
||||
bool whole_buffer)
|
||||
{
|
||||
return _parse_number<double> (pp, end, pv, whole_buffer,
|
||||
[] (const char *p, char **end)
|
||||
{
|
||||
#ifdef USE_XLOCALE
|
||||
return strtod_l (p, end, get_C_locale ());
|
||||
#else
|
||||
return strtod_rl (p, end);
|
||||
#endif
|
||||
});
|
||||
}
|
41
gfx/harfbuzz/src/hb-number.hh
Normal file
41
gfx/harfbuzz/src/hb-number.hh
Normal 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 */
|
@ -62,7 +62,7 @@ struct hb_lockable_set_t
|
||||
old.fini ();
|
||||
}
|
||||
else {
|
||||
item = nullptr;
|
||||
item = nullptr;
|
||||
l.unlock ();
|
||||
}
|
||||
} else {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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 {};
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
@ -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 ®ions,
|
||||
float *scalars /*OUT */,
|
||||
unsigned int num_scalars) const
|
||||
const VarRegionList ®ions,
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -136,7 +136,7 @@ struct JstfLangSys : OffsetListOf<JstfPriority>
|
||||
* ExtenderGlyphs -- Extender Glyph Table
|
||||
*/
|
||||
|
||||
typedef SortedArrayOf<GlyphID> ExtenderGlyphs;
|
||||
typedef SortedArrayOf<HBGlyphID> ExtenderGlyphs;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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],
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -262,7 +262,7 @@ struct post
|
||||
* 0x00020000 for version 2.0
|
||||
* 0x00025000 for version 2.5 (deprecated)
|
||||
* 0x00030000 for version 3.0 */
|
||||
Fixed italicAngle; /* Italic angle in counter-clockwise degrees
|
||||
HBFixed italicAngle; /* Italic angle in counter-clockwise degrees
|
||||
* from the vertical. Zero for upright text,
|
||||
* negative for text that leans to the right
|
||||
* (forward). */
|
||||
|
@ -49,8 +49,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
|
||||
hb_font_t *font,
|
||||
unsigned int feature_index)
|
||||
{
|
||||
OT::GlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
OT::GlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
OT::HBGlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
OT::HBGlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
|
||||
unsigned int num_glyphs = 0;
|
||||
|
||||
/* Populate arrays */
|
||||
@ -78,7 +78,7 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
|
||||
/* Bubble-sort or something equally good!
|
||||
* May not be good-enough for presidential candidate interviews, but good-enough for us... */
|
||||
hb_stable_sort (&glyphs[0], num_glyphs,
|
||||
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::GlyphID::cmp,
|
||||
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp,
|
||||
&substitutes[0]);
|
||||
|
||||
|
||||
@ -99,15 +99,15 @@ static OT::SubstLookup *
|
||||
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_font_t *font)
|
||||
{
|
||||
OT::GlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
|
||||
OT::HBGlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
|
||||
unsigned int first_glyphs_indirection[ARRAY_LENGTH_CONST (ligature_table)];
|
||||
unsigned int ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
|
||||
unsigned int num_first_glyphs = 0;
|
||||
|
||||
/* We know that all our ligatures are 2-component */
|
||||
OT::GlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
|
||||
OT::HBGlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
|
||||
unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
|
||||
OT::GlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
|
||||
OT::HBGlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
|
||||
unsigned int num_ligatures = 0;
|
||||
|
||||
/* Populate arrays */
|
||||
@ -125,7 +125,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
|
||||
num_first_glyphs++;
|
||||
}
|
||||
hb_stable_sort (&first_glyphs[0], num_first_glyphs,
|
||||
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::GlyphID::cmp,
|
||||
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp,
|
||||
&first_glyphs_indirection[0]);
|
||||
|
||||
/* Now that the first-glyphs are sorted, walk again, populate ligatures. */
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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 == */
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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(),
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 =
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user