Merge pull request #3704 from harfbuzz/64k
Towards breaking the 64k in GSUB/GPOS
This commit is contained in:
commit
87167acfe3
|
@ -12,7 +12,10 @@ struct MarkBasePos
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
MarkBasePosFormat1 format1;
|
MarkBasePosFormat1_2<SmallTypes> format1;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
MarkBasePosFormat1_2<MediumTypes> format2;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -23,6 +26,9 @@ struct MarkBasePos
|
||||||
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,26 +12,27 @@ typedef AnchorMatrix BaseArray; /* base-major--
|
||||||
* mark-minor--
|
* mark-minor--
|
||||||
* ordered by class--zero-based. */
|
* ordered by class--zero-based. */
|
||||||
|
|
||||||
struct MarkBasePosFormat1
|
template <typename Types>
|
||||||
|
struct MarkBasePosFormat1_2
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
markCoverage; /* Offset to MarkCoverage table--from
|
markCoverage; /* Offset to MarkCoverage table--from
|
||||||
* beginning of MarkBasePos subtable */
|
* beginning of MarkBasePos subtable */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
baseCoverage; /* Offset to BaseCoverage table--from
|
baseCoverage; /* Offset to BaseCoverage table--from
|
||||||
* beginning of MarkBasePos subtable */
|
* beginning of MarkBasePos subtable */
|
||||||
HBUINT16 classCount; /* Number of classes defined for marks */
|
HBUINT16 classCount; /* Number of classes defined for marks */
|
||||||
Offset16To<MarkArray>
|
typename Types::template OffsetTo<MarkArray>
|
||||||
markArray; /* Offset to MarkArray table--from
|
markArray; /* Offset to MarkArray table--from
|
||||||
* beginning of MarkBasePos subtable */
|
* beginning of MarkBasePos subtable */
|
||||||
Offset16To<BaseArray>
|
typename Types::template OffsetTo<BaseArray>
|
||||||
baseArray; /* Offset to BaseArray table--from
|
baseArray; /* Offset to BaseArray table--from
|
||||||
* beginning of MarkBasePos subtable */
|
* beginning of MarkBasePos subtable */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (12);
|
DEFINE_SIZE_STATIC (4 + 4 * Types::size);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,10 @@ struct MarkLigPos
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
MarkLigPosFormat1 format1;
|
MarkLigPosFormat1_2<SmallTypes> format1;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
MarkLigPosFormat1_2<MediumTypes> format2;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -23,6 +26,9 @@ struct MarkLigPos
|
||||||
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,26 +8,27 @@ namespace Layout {
|
||||||
namespace GPOS_impl {
|
namespace GPOS_impl {
|
||||||
|
|
||||||
|
|
||||||
struct MarkLigPosFormat1
|
template <typename Types>
|
||||||
|
struct MarkLigPosFormat1_2
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
markCoverage; /* Offset to Mark Coverage table--from
|
markCoverage; /* Offset to Mark Coverage table--from
|
||||||
* beginning of MarkLigPos subtable */
|
* beginning of MarkLigPos subtable */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
ligatureCoverage; /* Offset to Ligature Coverage
|
ligatureCoverage; /* Offset to Ligature Coverage
|
||||||
* table--from beginning of MarkLigPos
|
* table--from beginning of MarkLigPos
|
||||||
* subtable */
|
* subtable */
|
||||||
HBUINT16 classCount; /* Number of defined mark classes */
|
HBUINT16 classCount; /* Number of defined mark classes */
|
||||||
Offset16To<MarkArray>
|
typename Types::template OffsetTo<MarkArray>
|
||||||
markArray; /* Offset to MarkArray table--from
|
markArray; /* Offset to MarkArray table--from
|
||||||
* beginning of MarkLigPos subtable */
|
* beginning of MarkLigPos subtable */
|
||||||
Offset16To<LigatureArray>
|
typename Types::template OffsetTo<LigatureArray>
|
||||||
ligatureArray; /* Offset to LigatureArray table--from
|
ligatureArray; /* Offset to LigatureArray table--from
|
||||||
* beginning of MarkLigPos subtable */
|
* beginning of MarkLigPos subtable */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (12);
|
DEFINE_SIZE_STATIC (4 + 4 * Types::size);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,7 +12,10 @@ struct MarkMarkPos
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
MarkMarkPosFormat1 format1;
|
MarkMarkPosFormat1_2<SmallTypes> format1;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
MarkMarkPosFormat1_2<MediumTypes> format2;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -23,6 +26,9 @@ struct MarkMarkPos
|
||||||
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,27 +12,28 @@ typedef AnchorMatrix Mark2Array; /* mark2-major--
|
||||||
* mark1-minor--
|
* mark1-minor--
|
||||||
* ordered by class--zero-based. */
|
* ordered by class--zero-based. */
|
||||||
|
|
||||||
struct MarkMarkPosFormat1
|
template <typename Types>
|
||||||
|
struct MarkMarkPosFormat1_2
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
mark1Coverage; /* Offset to Combining Mark1 Coverage
|
mark1Coverage; /* Offset to Combining Mark1 Coverage
|
||||||
* table--from beginning of MarkMarkPos
|
* table--from beginning of MarkMarkPos
|
||||||
* subtable */
|
* subtable */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
mark2Coverage; /* Offset to Combining Mark2 Coverage
|
mark2Coverage; /* Offset to Combining Mark2 Coverage
|
||||||
* table--from beginning of MarkMarkPos
|
* table--from beginning of MarkMarkPos
|
||||||
* subtable */
|
* subtable */
|
||||||
HBUINT16 classCount; /* Number of defined mark classes */
|
HBUINT16 classCount; /* Number of defined mark classes */
|
||||||
Offset16To<MarkArray>
|
typename Types::template OffsetTo<MarkArray>
|
||||||
mark1Array; /* Offset to Mark1Array table--from
|
mark1Array; /* Offset to Mark1Array table--from
|
||||||
* beginning of MarkMarkPos subtable */
|
* beginning of MarkMarkPos subtable */
|
||||||
Offset16To<Mark2Array>
|
typename Types::template OffsetTo<Mark2Array>
|
||||||
mark2Array; /* Offset to Mark2Array table--from
|
mark2Array; /* Offset to Mark2Array table--from
|
||||||
* beginning of MarkMarkPos subtable */
|
* beginning of MarkMarkPos subtable */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (12);
|
DEFINE_SIZE_STATIC (4 + 4 * Types::size);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -13,8 +13,12 @@ struct PairPos
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
PairPosFormat1 format1;
|
PairPosFormat1_3<SmallTypes> format1;
|
||||||
PairPosFormat2 format2;
|
PairPosFormat2_4<SmallTypes> format2;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
PairPosFormat1_3<MediumTypes> format3;
|
||||||
|
PairPosFormat2_4<MediumTypes> format4;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -26,6 +30,10 @@ struct PairPos
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
|
||||||
|
case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,15 @@ namespace Layout {
|
||||||
namespace GPOS_impl {
|
namespace GPOS_impl {
|
||||||
|
|
||||||
|
|
||||||
struct PairPosFormat1
|
template <typename Types>
|
||||||
|
struct PairPosFormat1_3
|
||||||
{
|
{
|
||||||
|
using PairSet = GPOS_impl::PairSet<Types>;
|
||||||
|
using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
coverage; /* Offset to Coverage table--from
|
coverage; /* Offset to Coverage table--from
|
||||||
* beginning of subtable */
|
* beginning of subtable */
|
||||||
ValueFormat valueFormat[2]; /* [0] Defines the types of data in
|
ValueFormat valueFormat[2]; /* [0] Defines the types of data in
|
||||||
|
@ -21,11 +25,11 @@ struct PairPosFormat1
|
||||||
/* [1] Defines the types of data in
|
/* [1] Defines the types of data in
|
||||||
* ValueRecord2--for the second glyph
|
* ValueRecord2--for the second glyph
|
||||||
* in the pair--may be zero (0) */
|
* in the pair--may be zero (0) */
|
||||||
Array16OfOffset16To<PairSet>
|
Array16Of<typename Types::template OffsetTo<PairSet>>
|
||||||
pairSet; /* Array of PairSet tables
|
pairSet; /* Array of PairSet tables
|
||||||
* ordered by Coverage Index */
|
* ordered by Coverage Index */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (10, pairSet);
|
DEFINE_SIZE_ARRAY (8 + Types::size, pairSet);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
@ -35,7 +39,7 @@ struct PairPosFormat1
|
||||||
|
|
||||||
unsigned int len1 = valueFormat[0].get_len ();
|
unsigned int len1 = valueFormat[0].get_len ();
|
||||||
unsigned int len2 = valueFormat[1].get_len ();
|
unsigned int len2 = valueFormat[1].get_len ();
|
||||||
PairSet::sanitize_closure_t closure =
|
typename PairSet::sanitize_closure_t closure =
|
||||||
{
|
{
|
||||||
valueFormat,
|
valueFormat,
|
||||||
len1,
|
len1,
|
||||||
|
@ -51,7 +55,7 @@ struct PairPosFormat1
|
||||||
+ hb_zip (this+coverage, pairSet)
|
+ hb_zip (this+coverage, pairSet)
|
||||||
| hb_filter (*glyphs, hb_first)
|
| hb_filter (*glyphs, hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map ([glyphs, this] (const Offset16To<PairSet> &_)
|
| hb_map ([glyphs, this] (const typename Types::template OffsetTo<PairSet> &_)
|
||||||
{ return (this+_).intersects (glyphs, valueFormat); })
|
{ return (this+_).intersects (glyphs, valueFormat); })
|
||||||
| hb_any
|
| hb_any
|
||||||
;
|
;
|
||||||
|
@ -127,7 +131,7 @@ struct PairPosFormat1
|
||||||
|
|
||||||
+ hb_zip (this+coverage, pairSet)
|
+ hb_zip (this+coverage, pairSet)
|
||||||
| hb_filter (glyphset, hb_first)
|
| hb_filter (glyphset, hb_first)
|
||||||
| hb_filter ([this, c, out] (const Offset16To<PairSet>& _)
|
| hb_filter ([this, c, out] (const typename Types::template OffsetTo<PairSet>& _)
|
||||||
{
|
{
|
||||||
auto snap = c->serializer->snapshot ();
|
auto snap = c->serializer->snapshot ();
|
||||||
auto *o = out->pairSet.serialize_append (c->serializer);
|
auto *o = out->pairSet.serialize_append (c->serializer);
|
||||||
|
@ -160,7 +164,7 @@ struct PairPosFormat1
|
||||||
|
|
||||||
unsigned format1 = 0;
|
unsigned format1 = 0;
|
||||||
unsigned format2 = 0;
|
unsigned format2 = 0;
|
||||||
for (const Offset16To<PairSet>& _ :
|
for (const auto & _ :
|
||||||
+ hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second))
|
+ hb_zip (this+coverage, pairSet) | hb_filter (glyphset, hb_first) | hb_map (hb_second))
|
||||||
{
|
{
|
||||||
const PairSet& set = (this + _);
|
const PairSet& set = (this + _);
|
||||||
|
|
|
@ -7,11 +7,12 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GPOS_impl {
|
namespace GPOS_impl {
|
||||||
|
|
||||||
struct PairPosFormat2
|
template <typename Types>
|
||||||
|
struct PairPosFormat2_4
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 2 */
|
HBUINT16 format; /* Format identifier--format = 2 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
coverage; /* Offset to Coverage table--from
|
coverage; /* Offset to Coverage table--from
|
||||||
* beginning of subtable */
|
* beginning of subtable */
|
||||||
ValueFormat valueFormat1; /* ValueRecord definition--for the
|
ValueFormat valueFormat1; /* ValueRecord definition--for the
|
||||||
|
@ -20,11 +21,11 @@ struct PairPosFormat2
|
||||||
ValueFormat valueFormat2; /* ValueRecord definition--for the
|
ValueFormat valueFormat2; /* ValueRecord definition--for the
|
||||||
* second glyph of the pair--may be
|
* second glyph of the pair--may be
|
||||||
* zero (0) */
|
* zero (0) */
|
||||||
Offset16To<ClassDef>
|
typename Types::template OffsetTo<ClassDef>
|
||||||
classDef1; /* Offset to ClassDef table--from
|
classDef1; /* Offset to ClassDef table--from
|
||||||
* beginning of PairPos subtable--for
|
* beginning of PairPos subtable--for
|
||||||
* the first glyph of the pair */
|
* the first glyph of the pair */
|
||||||
Offset16To<ClassDef>
|
typename Types::template OffsetTo<ClassDef>
|
||||||
classDef2; /* Offset to ClassDef table--from
|
classDef2; /* Offset to ClassDef table--from
|
||||||
* beginning of PairPos subtable--for
|
* beginning of PairPos subtable--for
|
||||||
* the second glyph of the pair */
|
* the second glyph of the pair */
|
||||||
|
@ -36,7 +37,7 @@ struct PairPosFormat2
|
||||||
* class1-major, class2-minor,
|
* class1-major, class2-minor,
|
||||||
* Each entry has value1 and value2 */
|
* Each entry has value1 and value2 */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (16, values);
|
DEFINE_SIZE_ARRAY (10 + 3 * Types::size, values);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,9 +8,13 @@ namespace Layout {
|
||||||
namespace GPOS_impl {
|
namespace GPOS_impl {
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Types>
|
||||||
struct PairSet
|
struct PairSet
|
||||||
{
|
{
|
||||||
friend struct PairPosFormat1;
|
template <typename Types2>
|
||||||
|
friend struct PairPosFormat1_3;
|
||||||
|
|
||||||
|
using PairValueRecord = GPOS_impl::PairValueRecord<Types>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 len; /* Number of PairValueRecords */
|
HBUINT16 len; /* Number of PairValueRecords */
|
||||||
|
@ -136,7 +140,7 @@ struct PairSet
|
||||||
unsigned len2 = valueFormats[1].get_len ();
|
unsigned len2 = valueFormats[1].get_len ();
|
||||||
unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
|
unsigned record_size = HBUINT16::static_size + Value::static_size * (len1 + len2);
|
||||||
|
|
||||||
PairValueRecord::context_t context =
|
typename PairValueRecord::context_t context =
|
||||||
{
|
{
|
||||||
this,
|
this,
|
||||||
valueFormats,
|
valueFormats,
|
||||||
|
|
|
@ -6,18 +6,21 @@ namespace Layout {
|
||||||
namespace GPOS_impl {
|
namespace GPOS_impl {
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Types>
|
||||||
struct PairValueRecord
|
struct PairValueRecord
|
||||||
{
|
{
|
||||||
|
template <typename Types2>
|
||||||
friend struct PairSet;
|
friend struct PairSet;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBGlyphID16 secondGlyph; /* GlyphID of second glyph in the
|
typename Types::HBGlyphID
|
||||||
|
secondGlyph; /* GlyphID of second glyph in the
|
||||||
* pair--first glyph is listed in the
|
* pair--first glyph is listed in the
|
||||||
* Coverage table */
|
* Coverage table */
|
||||||
ValueRecord values; /* Positioning data for the first glyph
|
ValueRecord values; /* Positioning data for the first glyph
|
||||||
* followed by for second glyph */
|
* followed by for second glyph */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (2, values);
|
DEFINE_SIZE_ARRAY (Types::size, values);
|
||||||
|
|
||||||
int cmp (hb_codepoint_t k) const
|
int cmp (hb_codepoint_t k) const
|
||||||
{ return secondGlyph.cmp (k); }
|
{ return secondGlyph.cmp (k); }
|
||||||
|
|
|
@ -7,10 +7,11 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
|
template <typename Types>
|
||||||
struct AlternateSet
|
struct AlternateSet
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Array16Of<HBGlyphID16>
|
Array16Of<typename Types::HBGlyphID>
|
||||||
alternates; /* Array of alternate GlyphIDs--in
|
alternates; /* Array of alternate GlyphIDs--in
|
||||||
* arbitrary order */
|
* arbitrary order */
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -13,7 +13,10 @@ struct AlternateSubst
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
AlternateSubstFormat1 format1;
|
AlternateSubstFormat1_2<SmallTypes> format1;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
AlternateSubstFormat1_2<MediumTypes> format2;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -24,10 +27,15 @@ struct AlternateSubst
|
||||||
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO This function is unused and not updated to 24bit GIDs. Should be done by using
|
||||||
|
* iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const HBGlyphID16> glyphs,
|
hb_sorted_array_t<const HBGlyphID16> glyphs,
|
||||||
hb_array_t<const unsigned int> alternate_len_list,
|
hb_array_t<const unsigned int> alternate_len_list,
|
||||||
|
@ -42,6 +50,9 @@ struct AlternateSubst
|
||||||
default:return_trace (false);
|
default:return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO subset() should choose format. */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,18 +8,19 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
struct AlternateSubstFormat1
|
template <typename Types>
|
||||||
|
struct AlternateSubstFormat1_2
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
coverage; /* Offset to Coverage table--from
|
coverage; /* Offset to Coverage table--from
|
||||||
* beginning of Substitution table */
|
* beginning of Substitution table */
|
||||||
Array16OfOffset16To<AlternateSet>
|
Array16Of<typename Types::template OffsetTo<AlternateSet<Types>>>
|
||||||
alternateSet; /* Array of AlternateSet tables
|
alternateSet; /* Array of AlternateSet tables
|
||||||
* ordered by Coverage Index */
|
* ordered by Coverage Index */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (6, alternateSet);
|
DEFINE_SIZE_ARRAY (2 + 2 * Types::size, alternateSet);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
@ -39,7 +40,7 @@ struct AlternateSubstFormat1
|
||||||
| hb_filter (c->parent_active_glyphs (), hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
|
| hb_apply ([c] (const AlternateSet<Types> &_) { _.closure (c); })
|
||||||
;
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,7 +53,7 @@ struct AlternateSubstFormat1
|
||||||
+ hb_zip (this+coverage, alternateSet)
|
+ hb_zip (this+coverage, alternateSet)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
|
| hb_apply ([c] (const AlternateSet<Types> &_) { _.collect_glyphs (c); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,18 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
|
template <typename Types>
|
||||||
struct Ligature
|
struct Ligature
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBGlyphID16 ligGlyph; /* GlyphID of ligature to substitute */
|
typename Types::HBGlyphID
|
||||||
HeadlessArrayOf<HBGlyphID16>
|
ligGlyph; /* GlyphID of ligature to substitute */
|
||||||
|
HeadlessArrayOf<typename Types::HBGlyphID>
|
||||||
component; /* Array of component GlyphIDs--start
|
component; /* Array of component GlyphIDs--start
|
||||||
* with the second component--ordered
|
* with the second component--ordered
|
||||||
* in writing direction */
|
* in writing direction */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (4, component);
|
DEFINE_SIZE_ARRAY (Types::size + 2, component);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,10 +8,11 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
|
template <typename Types>
|
||||||
struct LigatureSet
|
struct LigatureSet
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Array16OfOffset16To<Ligature>
|
Array16OfOffset16To<Ligature<Types>>
|
||||||
ligature; /* Array LigatureSet tables
|
ligature; /* Array LigatureSet tables
|
||||||
* ordered by preference */
|
* ordered by preference */
|
||||||
public:
|
public:
|
||||||
|
@ -28,7 +29,7 @@ struct LigatureSet
|
||||||
return
|
return
|
||||||
+ hb_iter (ligature)
|
+ hb_iter (ligature)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
|
| hb_map ([glyphs] (const Ligature<Types> &_) { return _.intersects (glyphs); })
|
||||||
| hb_any
|
| hb_any
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -37,7 +38,7 @@ struct LigatureSet
|
||||||
{
|
{
|
||||||
+ hb_iter (ligature)
|
+ hb_iter (ligature)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const Ligature &_) { _.closure (c); })
|
| hb_apply ([c] (const Ligature<Types> &_) { _.closure (c); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,7 +46,7 @@ struct LigatureSet
|
||||||
{
|
{
|
||||||
+ hb_iter (ligature)
|
+ hb_iter (ligature)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
|
| hb_apply ([c] (const Ligature<Types> &_) { _.collect_glyphs (c); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +55,7 @@ struct LigatureSet
|
||||||
return
|
return
|
||||||
+ hb_iter (ligature)
|
+ hb_iter (ligature)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
|
| hb_map ([c] (const Ligature<Types> &_) { return _.would_apply (c); })
|
||||||
| hb_any
|
| hb_any
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
@ -65,7 +66,7 @@ struct LigatureSet
|
||||||
unsigned int num_ligs = ligature.len;
|
unsigned int num_ligs = ligature.len;
|
||||||
for (unsigned int i = 0; i < num_ligs; i++)
|
for (unsigned int i = 0; i < num_ligs; i++)
|
||||||
{
|
{
|
||||||
const Ligature &lig = this+ligature[i];
|
const auto &lig = this+ligature[i];
|
||||||
if (lig.apply (c)) return_trace (true);
|
if (lig.apply (c)) return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,10 @@ struct LigatureSubst
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
LigatureSubstFormat1 format1;
|
LigatureSubstFormat1_2<SmallTypes> format1;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
LigatureSubstFormat1_2<MediumTypes> format2;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -24,10 +27,16 @@ struct LigatureSubst
|
||||||
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO This function is only used by small GIDs, and not updated to 24bit GIDs. Should
|
||||||
|
* be done by using iterators. While at it perhaps using iterator of arrays of hb_codepoint_t
|
||||||
|
* instead. */
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const HBGlyphID16> first_glyphs,
|
hb_sorted_array_t<const HBGlyphID16> first_glyphs,
|
||||||
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
hb_array_t<const unsigned int> ligature_per_first_glyph_count_list,
|
||||||
|
@ -49,6 +58,9 @@ struct LigatureSubst
|
||||||
default:return_trace (false);
|
default:return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO subset() should choose format. */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,19 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
struct LigatureSubstFormat1
|
template <typename Types>
|
||||||
|
struct LigatureSubstFormat1_2
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
coverage; /* Offset to Coverage table--from
|
coverage; /* Offset to Coverage table--from
|
||||||
* beginning of Substitution table */
|
* beginning of Substitution table */
|
||||||
Array16OfOffset16To<LigatureSet>
|
Array16Of<typename Types::template OffsetTo<LigatureSet<Types>>>
|
||||||
ligatureSet; /* Array LigatureSet tables
|
ligatureSet; /* Array LigatureSet tables
|
||||||
* ordered by Coverage Index */
|
* ordered by Coverage Index */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (6, ligatureSet);
|
DEFINE_SIZE_ARRAY (4 + Types::size, ligatureSet);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
@ -33,7 +34,7 @@ struct LigatureSubstFormat1
|
||||||
+ hb_zip (this+coverage, ligatureSet)
|
+ hb_zip (this+coverage, ligatureSet)
|
||||||
| hb_filter (*glyphs, hb_first)
|
| hb_filter (*glyphs, hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map ([this, glyphs] (const Offset16To<LigatureSet> &_)
|
| hb_map ([this, glyphs] (const typename Types::template OffsetTo<LigatureSet<Types>> &_)
|
||||||
{ return (this+_).intersects (glyphs); })
|
{ return (this+_).intersects (glyphs); })
|
||||||
| hb_any
|
| hb_any
|
||||||
;
|
;
|
||||||
|
@ -48,7 +49,7 @@ struct LigatureSubstFormat1
|
||||||
| hb_filter (c->parent_active_glyphs (), hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
|
| hb_apply ([c] (const LigatureSet<Types> &_) { _.closure (c); })
|
||||||
;
|
;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,7 +63,7 @@ struct LigatureSubstFormat1
|
||||||
+ hb_zip (this+coverage, ligatureSet)
|
+ hb_zip (this+coverage, ligatureSet)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); })
|
| hb_apply ([c] (const LigatureSet<Types> &_) { _.collect_glyphs (c); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +74,7 @@ struct LigatureSubstFormat1
|
||||||
unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
|
unsigned int index = (this+coverage).get_coverage (c->glyphs[0]);
|
||||||
if (likely (index == NOT_COVERED)) return false;
|
if (likely (index == NOT_COVERED)) return false;
|
||||||
|
|
||||||
const LigatureSet &lig_set = this+ligatureSet[index];
|
const auto &lig_set = this+ligatureSet[index];
|
||||||
return lig_set.would_apply (c);
|
return lig_set.would_apply (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ struct LigatureSubstFormat1
|
||||||
unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
|
unsigned int index = (this+coverage).get_coverage (c->buffer->cur ().codepoint);
|
||||||
if (likely (index == NOT_COVERED)) return_trace (false);
|
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||||
|
|
||||||
const LigatureSet &lig_set = this+ligatureSet[index];
|
const auto &lig_set = this+ligatureSet[index];
|
||||||
return_trace (lig_set.apply (c));
|
return_trace (lig_set.apply (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ struct LigatureSubstFormat1
|
||||||
hb_set_t new_coverage;
|
hb_set_t new_coverage;
|
||||||
+ hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
|
+ hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
|
||||||
| hb_filter (glyphset, hb_first)
|
| hb_filter (glyphset, hb_first)
|
||||||
| hb_filter ([&] (const LigatureSet& _) {
|
| hb_filter ([&] (const LigatureSet<Types>& _) {
|
||||||
return _.intersects (&glyphset);
|
return _.intersects (&glyphset);
|
||||||
}, hb_second)
|
}, hb_second)
|
||||||
| hb_map (hb_first)
|
| hb_map (hb_first)
|
||||||
|
|
|
@ -13,7 +13,10 @@ struct MultipleSubst
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
MultipleSubstFormat1 format1;
|
MultipleSubstFormat1_2<SmallTypes> format1;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
MultipleSubstFormat1_2<MediumTypes> format2;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -25,10 +28,15 @@ struct MultipleSubst
|
||||||
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
if (unlikely (!c->may_dispatch (this, &u.format))) return_trace (c->no_dispatch_return_value ());
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO This function is unused and not updated to 24bit GIDs. Should be done by using
|
||||||
|
* iterators. While at it perhaps using iterator of arrays of hb_codepoint_t instead. */
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
hb_sorted_array_t<const HBGlyphID16> glyphs,
|
hb_sorted_array_t<const HBGlyphID16> glyphs,
|
||||||
hb_array_t<const unsigned int> substitute_len_list,
|
hb_array_t<const unsigned int> substitute_len_list,
|
||||||
|
@ -43,6 +51,9 @@ struct MultipleSubst
|
||||||
default:return_trace (false);
|
default:return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* TODO subset() should choose format. */
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,18 +8,19 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
struct MultipleSubstFormat1
|
template <typename Types>
|
||||||
|
struct MultipleSubstFormat1_2
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
coverage; /* Offset to Coverage table--from
|
coverage; /* Offset to Coverage table--from
|
||||||
* beginning of Substitution table */
|
* beginning of Substitution table */
|
||||||
Array16OfOffset16To<Sequence>
|
Array16Of<typename Types::template OffsetTo<Sequence<Types>>>
|
||||||
sequence; /* Array of Sequence tables
|
sequence; /* Array of Sequence tables
|
||||||
* ordered by Coverage Index */
|
* ordered by Coverage Index */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (6, sequence);
|
DEFINE_SIZE_ARRAY (4 + Types::size, sequence);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
@ -39,7 +40,7 @@ struct MultipleSubstFormat1
|
||||||
| hb_filter (c->parent_active_glyphs (), hb_first)
|
| hb_filter (c->parent_active_glyphs (), hb_first)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const Sequence &_) { _.closure (c); })
|
| hb_apply ([c] (const Sequence<Types> &_) { _.closure (c); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ struct MultipleSubstFormat1
|
||||||
+ hb_zip (this+coverage, sequence)
|
+ hb_zip (this+coverage, sequence)
|
||||||
| hb_map (hb_second)
|
| hb_map (hb_second)
|
||||||
| hb_map (hb_add (this))
|
| hb_map (hb_add (this))
|
||||||
| hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); })
|
| hb_apply ([c] (const Sequence<Types> &_) { _.collect_glyphs (c); })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,11 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
|
template <typename Types>
|
||||||
struct Sequence
|
struct Sequence
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
Array16Of<HBGlyphID16>
|
Array16Of<typename Types::HBGlyphID>
|
||||||
substitute; /* String of GlyphIDs to substitute */
|
substitute; /* String of GlyphIDs to substitute */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (2, substitute);
|
DEFINE_SIZE_ARRAY (2, substitute);
|
||||||
|
|
|
@ -14,8 +14,12 @@ struct SingleSubst
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
SingleSubstFormat1 format1;
|
SingleSubstFormat1_3<SmallTypes> format1;
|
||||||
SingleSubstFormat2 format2;
|
SingleSubstFormat2_4<SmallTypes> format2;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
SingleSubstFormat1_3<MediumTypes> format3;
|
||||||
|
SingleSubstFormat2_4<MediumTypes> format4;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -28,6 +32,10 @@ struct SingleSubst
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
|
||||||
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
|
||||||
|
case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
|
||||||
|
#endif
|
||||||
default:return_trace (c->default_return_value ());
|
default:return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,11 +53,24 @@ struct SingleSubst
|
||||||
if (glyphs)
|
if (glyphs)
|
||||||
{
|
{
|
||||||
format = 1;
|
format = 1;
|
||||||
auto get_delta = [=] (hb_codepoint_pair_t _)
|
hb_codepoint_t mask = 0xFFFFu;
|
||||||
{ return (unsigned) (_.second - _.first) & 0xFFFF; };
|
|
||||||
delta = get_delta (*glyphs);
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
|
if (+ glyphs
|
||||||
|
| hb_map_retains_sorting (hb_first)
|
||||||
|
| hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
|
||||||
|
{
|
||||||
|
format += 2;
|
||||||
|
mask = 0xFFFFFFu;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
auto get_delta = [=] (hb_codepoint_pair_t _)
|
||||||
|
{ return (unsigned) (_.second - _.first) & mask; };
|
||||||
|
delta = get_delta (*glyphs);
|
||||||
|
if (!hb_all (++(+glyphs), delta, get_delta)) format += 1;
|
||||||
|
}
|
||||||
|
|
||||||
u.format = format;
|
u.format = format;
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (u.format1.serialize (c,
|
case 1: return_trace (u.format1.serialize (c,
|
||||||
|
@ -57,6 +78,13 @@ struct SingleSubst
|
||||||
| hb_map_retains_sorting (hb_first),
|
| hb_map_retains_sorting (hb_first),
|
||||||
delta));
|
delta));
|
||||||
case 2: return_trace (u.format2.serialize (c, glyphs));
|
case 2: return_trace (u.format2.serialize (c, glyphs));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (u.format3.serialize (c,
|
||||||
|
+ glyphs
|
||||||
|
| hb_map_retains_sorting (hb_first),
|
||||||
|
delta));
|
||||||
|
case 4: return_trace (u.format4.serialize (c, glyphs));
|
||||||
|
#endif
|
||||||
default:return_trace (false);
|
default:return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,18 +7,20 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
struct SingleSubstFormat1
|
template <typename Types>
|
||||||
|
struct SingleSubstFormat1_3
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 1 */
|
HBUINT16 format; /* Format identifier--format = 1 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
coverage; /* Offset to Coverage table--from
|
coverage; /* Offset to Coverage table--from
|
||||||
* beginning of Substitution table */
|
* beginning of Substitution table */
|
||||||
HBUINT16 deltaGlyphID; /* Add to original GlyphID to get
|
typename Types::HBUINT
|
||||||
|
deltaGlyphID; /* Add to original GlyphID to get
|
||||||
* substitute GlyphID, modulo 0x10000 */
|
* substitute GlyphID, modulo 0x10000 */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (2 + 2 * Types::size);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,19 +7,20 @@ namespace OT {
|
||||||
namespace Layout {
|
namespace Layout {
|
||||||
namespace GSUB_impl {
|
namespace GSUB_impl {
|
||||||
|
|
||||||
struct SingleSubstFormat2
|
template <typename Types>
|
||||||
|
struct SingleSubstFormat2_4
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format identifier--format = 2 */
|
HBUINT16 format; /* Format identifier--format = 2 */
|
||||||
Offset16To<Coverage>
|
typename Types::template OffsetTo<Coverage>
|
||||||
coverage; /* Offset to Coverage table--from
|
coverage; /* Offset to Coverage table--from
|
||||||
* beginning of Substitution table */
|
* beginning of Substitution table */
|
||||||
Array16Of<HBGlyphID16>
|
Array16Of<typename Types::HBGlyphID>
|
||||||
substitute; /* Array of substitute
|
substitute; /* Array of substitute
|
||||||
* GlyphIDs--ordered by Coverage Index */
|
* GlyphIDs--ordered by Coverage Index */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (6, substitute);
|
DEFINE_SIZE_ARRAY (4 + Types::size, substitute);
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
@ -103,7 +104,7 @@ struct SingleSubstFormat2
|
||||||
+ hb_zip (this+coverage, substitute)
|
+ hb_zip (this+coverage, substitute)
|
||||||
| hb_filter (glyphset, hb_first)
|
| hb_filter (glyphset, hb_first)
|
||||||
| hb_filter (glyphset, hb_second)
|
| hb_filter (glyphset, hb_second)
|
||||||
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> p) -> hb_codepoint_pair_t
|
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const typename Types::HBGlyphID &> p) -> hb_codepoint_pair_t
|
||||||
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
|
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
|
@ -25,13 +25,16 @@ struct CompositeGlyphRecord
|
||||||
USE_MY_METRICS = 0x0200,
|
USE_MY_METRICS = 0x0200,
|
||||||
OVERLAP_COMPOUND = 0x0400,
|
OVERLAP_COMPOUND = 0x0400,
|
||||||
SCALED_COMPONENT_OFFSET = 0x0800,
|
SCALED_COMPONENT_OFFSET = 0x0800,
|
||||||
UNSCALED_COMPONENT_OFFSET = 0x1000
|
UNSCALED_COMPONENT_OFFSET = 0x1000,
|
||||||
|
GID_IS_24BIT = 0x2000
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
unsigned int get_size () const
|
unsigned int get_size () const
|
||||||
{
|
{
|
||||||
unsigned int size = min_size;
|
unsigned int size = min_size;
|
||||||
|
/* glyphIndex is 24bit instead of 16bit */
|
||||||
|
if (flags & GID_IS_24BIT) size += HBGlyphID24::static_size - HBGlyphID16::static_size;
|
||||||
/* arg1 and 2 are int16 */
|
/* arg1 and 2 are int16 */
|
||||||
if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
|
if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
|
||||||
/* arg1 and 2 are int8 */
|
/* arg1 and 2 are int8 */
|
||||||
|
@ -60,7 +63,11 @@ struct CompositeGlyphRecord
|
||||||
bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); }
|
bool is_anchored () const { return !(flags & ARGS_ARE_XY_VALUES); }
|
||||||
void get_anchor_points (unsigned int &point1, unsigned int &point2) const
|
void get_anchor_points (unsigned int &point1, unsigned int &point2) const
|
||||||
{
|
{
|
||||||
const HBUINT8 *p = &StructAfter<const HBUINT8> (glyphIndex);
|
const auto *p = &StructAfter<const HBUINT8> (flags);
|
||||||
|
if (flags & GID_IS_24BIT)
|
||||||
|
p += HBGlyphID24::static_size;
|
||||||
|
else
|
||||||
|
p += HBGlyphID16::static_size;
|
||||||
if (flags & ARG_1_AND_2_ARE_WORDS)
|
if (flags & ARG_1_AND_2_ARE_WORDS)
|
||||||
{
|
{
|
||||||
point1 = ((const HBUINT16 *) p)[0];
|
point1 = ((const HBUINT16 *) p)[0];
|
||||||
|
@ -101,8 +108,12 @@ struct CompositeGlyphRecord
|
||||||
matrix[0] = matrix[3] = 1.f;
|
matrix[0] = matrix[3] = 1.f;
|
||||||
matrix[1] = matrix[2] = 0.f;
|
matrix[1] = matrix[2] = 0.f;
|
||||||
|
|
||||||
|
const auto *p = &StructAfter<const HBINT8> (flags);
|
||||||
|
if (flags & GID_IS_24BIT)
|
||||||
|
p += HBGlyphID24::static_size;
|
||||||
|
else
|
||||||
|
p += HBGlyphID16::static_size;
|
||||||
int tx, ty;
|
int tx, ty;
|
||||||
const HBINT8 *p = &StructAfter<const HBINT8> (glyphIndex);
|
|
||||||
if (flags & ARG_1_AND_2_ARE_WORDS)
|
if (flags & ARG_1_AND_2_ARE_WORDS)
|
||||||
{
|
{
|
||||||
tx = *(const HBINT16 *) p;
|
tx = *(const HBINT16 *) p;
|
||||||
|
@ -145,8 +156,25 @@ struct CompositeGlyphRecord
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
hb_codepoint_t get_gid () const
|
||||||
|
{
|
||||||
|
if (flags & GID_IS_24BIT)
|
||||||
|
return StructAfter<const HBGlyphID24> (flags);
|
||||||
|
else
|
||||||
|
return StructAfter<const HBGlyphID16> (flags);
|
||||||
|
}
|
||||||
|
void set_gid (hb_codepoint_t gid)
|
||||||
|
{
|
||||||
|
if (flags & GID_IS_24BIT)
|
||||||
|
StructAfter<HBGlyphID24> (flags) = gid;
|
||||||
|
else
|
||||||
|
/* TODO assert? */
|
||||||
|
StructAfter<HBGlyphID16> (flags) = gid;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
HBUINT16 flags;
|
HBUINT16 flags;
|
||||||
HBGlyphID16 glyphIndex;
|
HBUINT24 pad;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_MIN (4);
|
DEFINE_SIZE_MIN (4);
|
||||||
};
|
};
|
||||||
|
|
|
@ -146,7 +146,7 @@ struct Glyph
|
||||||
for (auto &item : get_composite_iterator ())
|
for (auto &item : get_composite_iterator ())
|
||||||
{
|
{
|
||||||
comp_points.reset ();
|
comp_points.reset ();
|
||||||
if (unlikely (!glyf_accelerator.glyph_for_gid (item.glyphIndex)
|
if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
|
||||||
.get_points (font, glyf_accelerator, comp_points,
|
.get_points (font, glyf_accelerator, comp_points,
|
||||||
phantom_only, depth + 1)))
|
phantom_only, depth + 1)))
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -42,8 +42,8 @@ struct SubsetGlyph
|
||||||
for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
|
for (auto &_ : Glyph (dest_glyph).get_composite_iterator ())
|
||||||
{
|
{
|
||||||
hb_codepoint_t new_gid;
|
hb_codepoint_t new_gid;
|
||||||
if (plan->new_gid_for_old_gid (_.glyphIndex, &new_gid))
|
if (plan->new_gid_for_old_gid (_.get_gid(), &new_gid))
|
||||||
const_cast<CompositeGlyphRecord &> (_).glyphIndex = new_gid;
|
const_cast<CompositeGlyphRecord &> (_).set_gid (new_gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
||||||
|
|
|
@ -743,8 +743,8 @@ template <typename Type> using Array16OfOffset32To = ArrayOf<OffsetTo<Type, HBUI
|
||||||
template <typename Type> using Array32OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>;
|
template <typename Type> using Array32OfOffset32To = ArrayOf<OffsetTo<Type, HBUINT32>, HBUINT32>;
|
||||||
|
|
||||||
/* Array of offsets relative to the beginning of the array itself. */
|
/* Array of offsets relative to the beginning of the array itself. */
|
||||||
template <typename Type>
|
template <typename Type, typename OffsetType>
|
||||||
struct List16OfOffset16To : Array16OfOffset16To<Type>
|
struct List16OfOffsetTo : ArrayOf<OffsetTo<Type, OffsetType>, HBUINT16>
|
||||||
{
|
{
|
||||||
const Type& operator [] (int i_) const
|
const Type& operator [] (int i_) const
|
||||||
{
|
{
|
||||||
|
@ -762,7 +762,7 @@ struct List16OfOffset16To : Array16OfOffset16To<Type>
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
struct List16OfOffset16To<Type> *out = c->serializer->embed (*this);
|
struct List16OfOffsetTo *out = c->serializer->embed (*this);
|
||||||
if (unlikely (!out)) return_trace (false);
|
if (unlikely (!out)) return_trace (false);
|
||||||
unsigned int count = this->len;
|
unsigned int count = this->len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
@ -774,10 +774,13 @@ struct List16OfOffset16To : Array16OfOffset16To<Type>
|
||||||
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
|
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (Array16OfOffset16To<Type>::sanitize (c, this, std::forward<Ts> (ds)...));
|
return_trace ((Array16Of<OffsetTo<Type, OffsetType>>::sanitize (c, this, std::forward<Ts> (ds)...)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
using List16OfOffset16To = List16OfOffsetTo<Type, HBUINT16>;
|
||||||
|
|
||||||
/* An array starting at second element. */
|
/* An array starting at second element. */
|
||||||
template <typename Type, typename LenType=HBUINT16>
|
template <typename Type, typename LenType=HBUINT16>
|
||||||
struct HeadlessArrayOf
|
struct HeadlessArrayOf
|
||||||
|
|
|
@ -80,8 +80,34 @@
|
||||||
namespace OT {
|
namespace OT {
|
||||||
|
|
||||||
|
|
||||||
#define NOT_COVERED ((unsigned int) -1)
|
struct SmallTypes {
|
||||||
|
static constexpr unsigned size = 2;
|
||||||
|
using HBUINT = HBUINT16;
|
||||||
|
using HBGlyphID = HBGlyphID16;
|
||||||
|
using Offset = Offset16;
|
||||||
|
template <typename Type, bool has_null=true>
|
||||||
|
using OffsetTo = OT::Offset16To<Type, has_null>;
|
||||||
|
template <typename Type>
|
||||||
|
using ArrayOf = OT::Array16Of<Type>;
|
||||||
|
template <typename Type>
|
||||||
|
using SortedArrayOf = OT::SortedArray16Of<Type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MediumTypes {
|
||||||
|
static constexpr unsigned size = 3;
|
||||||
|
using HBUINT = HBUINT24;
|
||||||
|
using HBGlyphID = HBGlyphID24;
|
||||||
|
using Offset = Offset24;
|
||||||
|
template <typename Type, bool has_null=true>
|
||||||
|
using OffsetTo = OT::Offset24To<Type, has_null>;
|
||||||
|
template <typename Type>
|
||||||
|
using ArrayOf = OT::Array24Of<Type>;
|
||||||
|
template <typename Type>
|
||||||
|
using SortedArrayOf = OT::SortedArray24Of<Type>;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define NOT_COVERED ((unsigned int) -1)
|
||||||
|
|
||||||
template<typename Iterator>
|
template<typename Iterator>
|
||||||
static inline void Coverage_serialize (hb_serialize_context_t *c,
|
static inline void Coverage_serialize (hb_serialize_context_t *c,
|
||||||
|
@ -510,6 +536,7 @@ struct RecordListOfScript : RecordListOf<Script>
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Types>
|
||||||
struct RangeRecord
|
struct RangeRecord
|
||||||
{
|
{
|
||||||
int cmp (hb_codepoint_t g) const
|
int cmp (hb_codepoint_t g) const
|
||||||
|
@ -528,13 +555,13 @@ struct RangeRecord
|
||||||
bool collect_coverage (set_t *glyphs) const
|
bool collect_coverage (set_t *glyphs) const
|
||||||
{ return glyphs->add_range (first, last); }
|
{ return glyphs->add_range (first, last); }
|
||||||
|
|
||||||
HBGlyphID16 first; /* First GlyphID in the range */
|
typename Types::HBGlyphID first; /* First GlyphID in the range */
|
||||||
HBGlyphID16 last; /* Last GlyphID in the range */
|
typename Types::HBGlyphID last; /* Last GlyphID in the range */
|
||||||
HBUINT16 value; /* Value */
|
HBUINT16 value; /* Value */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (2 + 2 * Types::size);
|
||||||
};
|
};
|
||||||
DECLARE_NULL_NAMESPACE_BYTES (OT, RangeRecord);
|
DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (OT, RangeRecord, 9);
|
||||||
|
|
||||||
|
|
||||||
struct IndexArray : Array16Of<Index>
|
struct IndexArray : Array16Of<Index>
|
||||||
|
@ -1377,10 +1404,11 @@ struct Lookup
|
||||||
DEFINE_SIZE_ARRAY (6, subTable);
|
DEFINE_SIZE_ARRAY (6, subTable);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef List16OfOffset16To<Lookup> LookupList;
|
template <typename Types>
|
||||||
|
using LookupList = List16OfOffsetTo<Lookup, typename Types::HBUINT>;
|
||||||
|
|
||||||
template <typename TLookup>
|
template <typename TLookup, typename OffsetType>
|
||||||
struct LookupOffsetList : List16OfOffset16To<TLookup>
|
struct LookupOffsetList : List16OfOffsetTo<TLookup, OffsetType>
|
||||||
{
|
{
|
||||||
bool subset (hb_subset_context_t *c,
|
bool subset (hb_subset_context_t *c,
|
||||||
hb_subset_layout_context_t *l) const
|
hb_subset_layout_context_t *l) const
|
||||||
|
@ -1410,7 +1438,8 @@ struct LookupOffsetList : List16OfOffset16To<TLookup>
|
||||||
* Coverage Table
|
* Coverage Table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct CoverageFormat1
|
template <typename Types>
|
||||||
|
struct CoverageFormat1_3
|
||||||
{
|
{
|
||||||
friend struct Coverage;
|
friend struct Coverage;
|
||||||
|
|
||||||
|
@ -1463,7 +1492,7 @@ struct CoverageFormat1
|
||||||
/* Older compilers need this to be public. */
|
/* Older compilers need this to be public. */
|
||||||
struct iter_t
|
struct iter_t
|
||||||
{
|
{
|
||||||
void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }
|
void init (const struct CoverageFormat1_3 &c_) { c = &c_; i = 0; }
|
||||||
void fini () {}
|
void fini () {}
|
||||||
bool more () const { return i < c->glyphArray.len; }
|
bool more () const { return i < c->glyphArray.len; }
|
||||||
void next () { i++; }
|
void next () { i++; }
|
||||||
|
@ -1473,27 +1502,28 @@ struct CoverageFormat1
|
||||||
iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; }
|
iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const struct CoverageFormat1 *c;
|
const struct CoverageFormat1_3 *c;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 coverageFormat; /* Format identifier--format = 1 */
|
HBUINT16 coverageFormat; /* Format identifier--format = 1 */
|
||||||
SortedArray16Of<HBGlyphID16>
|
SortedArray16Of<typename Types::HBGlyphID>
|
||||||
glyphArray; /* Array of GlyphIDs--in numerical order */
|
glyphArray; /* Array of GlyphIDs--in numerical order */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (4, glyphArray);
|
DEFINE_SIZE_ARRAY (4, glyphArray);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CoverageFormat2
|
template <typename Types>
|
||||||
|
struct CoverageFormat2_4
|
||||||
{
|
{
|
||||||
friend struct Coverage;
|
friend struct Coverage;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
unsigned int get_coverage (hb_codepoint_t glyph_id) const
|
||||||
{
|
{
|
||||||
const RangeRecord &range = rangeRecord.bsearch (glyph_id);
|
const RangeRecord<Types> &range = rangeRecord.bsearch (glyph_id);
|
||||||
return likely (range.first <= range.last)
|
return likely (range.first <= range.last)
|
||||||
? (unsigned int) range.value + (glyph_id - range.first)
|
? (unsigned int) range.value + (glyph_id - range.first)
|
||||||
: NOT_COVERED;
|
: NOT_COVERED;
|
||||||
|
@ -1548,14 +1578,14 @@ struct CoverageFormat2
|
||||||
bool intersects (const hb_set_t *glyphs) const
|
bool intersects (const hb_set_t *glyphs) const
|
||||||
{
|
{
|
||||||
return hb_any (+ hb_iter (rangeRecord.as_array ())
|
return hb_any (+ hb_iter (rangeRecord.as_array ())
|
||||||
| hb_map ([glyphs] (const RangeRecord &range) { return range.intersects (glyphs); }));
|
| hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (glyphs); }));
|
||||||
}
|
}
|
||||||
bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
||||||
{
|
{
|
||||||
auto cmp = [] (const void *pk, const void *pr) -> int
|
auto cmp = [] (const void *pk, const void *pr) -> int
|
||||||
{
|
{
|
||||||
unsigned index = * (const unsigned *) pk;
|
unsigned index = * (const unsigned *) pk;
|
||||||
const RangeRecord &range = * (const RangeRecord *) pr;
|
const RangeRecord<Types> &range = * (const RangeRecord<Types> *) pr;
|
||||||
if (index < range.value) return -1;
|
if (index < range.value) return -1;
|
||||||
if (index > (unsigned int) range.value + (range.last - range.first)) return +1;
|
if (index > (unsigned int) range.value + (range.last - range.first)) return +1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1596,7 +1626,7 @@ struct CoverageFormat2
|
||||||
/* Older compilers need this to be public. */
|
/* Older compilers need this to be public. */
|
||||||
struct iter_t
|
struct iter_t
|
||||||
{
|
{
|
||||||
void init (const CoverageFormat2 &c_)
|
void init (const CoverageFormat2_4 &c_)
|
||||||
{
|
{
|
||||||
c = &c_;
|
c = &c_;
|
||||||
coverage = 0;
|
coverage = 0;
|
||||||
|
@ -1650,7 +1680,7 @@ struct CoverageFormat2
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const struct CoverageFormat2 *c;
|
const struct CoverageFormat2_4 *c;
|
||||||
unsigned int i, coverage;
|
unsigned int i, coverage;
|
||||||
hb_codepoint_t j;
|
hb_codepoint_t j;
|
||||||
};
|
};
|
||||||
|
@ -1658,7 +1688,7 @@ struct CoverageFormat2
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 coverageFormat; /* Format identifier--format = 2 */
|
HBUINT16 coverageFormat; /* Format identifier--format = 2 */
|
||||||
SortedArray16Of<RangeRecord>
|
SortedArray16Of<RangeRecord<Types>>
|
||||||
rangeRecord; /* Array of glyph ranges--ordered by
|
rangeRecord; /* Array of glyph ranges--ordered by
|
||||||
* Start GlyphID. rangeCount entries
|
* Start GlyphID. rangeCount entries
|
||||||
* long */
|
* long */
|
||||||
|
@ -1682,6 +1712,10 @@ struct Coverage
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.get_coverage (glyph_id);
|
case 1: return u.format1.get_coverage (glyph_id);
|
||||||
case 2: return u.format2.get_coverage (glyph_id);
|
case 2: return u.format2.get_coverage (glyph_id);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.get_coverage (glyph_id);
|
||||||
|
case 4: return u.format4.get_coverage (glyph_id);
|
||||||
|
#endif
|
||||||
default:return NOT_COVERED;
|
default:return NOT_COVERED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1705,10 +1739,19 @@ struct Coverage
|
||||||
}
|
}
|
||||||
u.format = count <= num_ranges * 3 ? 1 : 2;
|
u.format = count <= num_ranges * 3 ? 1 : 2;
|
||||||
|
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
if (count && last > 0xFFFFu)
|
||||||
|
u.format += 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (u.format)
|
switch (u.format)
|
||||||
{
|
{
|
||||||
case 1: return_trace (u.format1.serialize (c, glyphs));
|
case 1: return_trace (u.format1.serialize (c, glyphs));
|
||||||
case 2: return_trace (u.format2.serialize (c, glyphs));
|
case 2: return_trace (u.format2.serialize (c, glyphs));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (u.format3.serialize (c, glyphs));
|
||||||
|
case 4: return_trace (u.format4.serialize (c, glyphs));
|
||||||
|
#endif
|
||||||
default:return_trace (false);
|
default:return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1737,6 +1780,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: return_trace (u.format1.sanitize (c));
|
case 1: return_trace (u.format1.sanitize (c));
|
||||||
case 2: return_trace (u.format2.sanitize (c));
|
case 2: return_trace (u.format2.sanitize (c));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (u.format3.sanitize (c));
|
||||||
|
case 4: return_trace (u.format4.sanitize (c));
|
||||||
|
#endif
|
||||||
default:return_trace (true);
|
default:return_trace (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1747,6 +1794,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: return u.format1.intersects (glyphs);
|
case 1: return u.format1.intersects (glyphs);
|
||||||
case 2: return u.format2.intersects (glyphs);
|
case 2: return u.format2.intersects (glyphs);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.intersects (glyphs);
|
||||||
|
case 4: return u.format4.intersects (glyphs);
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1756,6 +1807,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: return u.format1.intersects_coverage (glyphs, index);
|
case 1: return u.format1.intersects_coverage (glyphs, index);
|
||||||
case 2: return u.format2.intersects_coverage (glyphs, index);
|
case 2: return u.format2.intersects_coverage (glyphs, index);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.intersects_coverage (glyphs, index);
|
||||||
|
case 4: return u.format4.intersects_coverage (glyphs, index);
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1769,6 +1824,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: return u.format1.collect_coverage (glyphs);
|
case 1: return u.format1.collect_coverage (glyphs);
|
||||||
case 2: return u.format2.collect_coverage (glyphs);
|
case 2: return u.format2.collect_coverage (glyphs);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.collect_coverage (glyphs);
|
||||||
|
case 4: return u.format4.collect_coverage (glyphs);
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1779,6 +1838,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: return u.format1.intersected_coverage_glyphs (glyphs, intersect_glyphs);
|
case 1: return u.format1.intersected_coverage_glyphs (glyphs, intersect_glyphs);
|
||||||
case 2: return u.format2.intersected_coverage_glyphs (glyphs, intersect_glyphs);
|
case 2: return u.format2.intersected_coverage_glyphs (glyphs, intersect_glyphs);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.intersected_coverage_glyphs (glyphs, intersect_glyphs);
|
||||||
|
case 4: return u.format4.intersected_coverage_glyphs (glyphs, intersect_glyphs);
|
||||||
|
#endif
|
||||||
default:return ;
|
default:return ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1794,6 +1857,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: u.format1.init (c_.u.format1); return;
|
case 1: u.format1.init (c_.u.format1); return;
|
||||||
case 2: u.format2.init (c_.u.format2); return;
|
case 2: u.format2.init (c_.u.format2); return;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: u.format3.init (c_.u.format3); return;
|
||||||
|
case 4: u.format4.init (c_.u.format4); return;
|
||||||
|
#endif
|
||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1803,6 +1870,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: return u.format1.more ();
|
case 1: return u.format1.more ();
|
||||||
case 2: return u.format2.more ();
|
case 2: return u.format2.more ();
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.more ();
|
||||||
|
case 4: return u.format4.more ();
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1812,6 +1883,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: u.format1.next (); break;
|
case 1: u.format1.next (); break;
|
||||||
case 2: u.format2.next (); break;
|
case 2: u.format2.next (); break;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: u.format3.next (); break;
|
||||||
|
case 4: u.format4.next (); break;
|
||||||
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1824,6 +1899,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: return u.format1.get_glyph ();
|
case 1: return u.format1.get_glyph ();
|
||||||
case 2: return u.format2.get_glyph ();
|
case 2: return u.format2.get_glyph ();
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.get_glyph ();
|
||||||
|
case 4: return u.format4.get_glyph ();
|
||||||
|
#endif
|
||||||
default:return 0;
|
default:return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1834,6 +1913,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: return u.format1 != o.u.format1;
|
case 1: return u.format1 != o.u.format1;
|
||||||
case 2: return u.format2 != o.u.format2;
|
case 2: return u.format2 != o.u.format2;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3 != o.u.format3;
|
||||||
|
case 4: return u.format4 != o.u.format4;
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1845,6 +1928,10 @@ struct Coverage
|
||||||
{
|
{
|
||||||
case 1: it.u.format1 = u.format1.__end__ (); break;
|
case 1: it.u.format1 = u.format1.__end__ (); break;
|
||||||
case 2: it.u.format2 = u.format2.__end__ (); break;
|
case 2: it.u.format2 = u.format2.__end__ (); break;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: it.u.format3 = u.format3.__end__ (); break;
|
||||||
|
case 4: it.u.format4 = u.format4.__end__ (); break;
|
||||||
|
#endif
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
return it;
|
return it;
|
||||||
|
@ -1853,8 +1940,12 @@ struct Coverage
|
||||||
private:
|
private:
|
||||||
unsigned int format;
|
unsigned int format;
|
||||||
union {
|
union {
|
||||||
CoverageFormat2::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
CoverageFormat1::iter_t format1;
|
CoverageFormat2_4<MediumTypes>::iter_t format4; /* Put this one first since it's larger; helps shut up compiler. */
|
||||||
|
CoverageFormat1_3<MediumTypes>::iter_t format3;
|
||||||
|
#endif
|
||||||
|
CoverageFormat2_4<SmallTypes>::iter_t format2; /* Put this one first since it's larger; helps shut up compiler. */
|
||||||
|
CoverageFormat1_3<SmallTypes>::iter_t format1;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
iter_t iter () const { return iter_t (*this); }
|
iter_t iter () const { return iter_t (*this); }
|
||||||
|
@ -1862,8 +1953,12 @@ struct Coverage
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
CoverageFormat1 format1;
|
CoverageFormat1_3<SmallTypes> format1;
|
||||||
CoverageFormat2 format2;
|
CoverageFormat2_4<SmallTypes> format2;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
CoverageFormat1_3<MediumTypes>format3;
|
||||||
|
CoverageFormat2_4<MediumTypes>format4;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_UNION (2, format);
|
DEFINE_SIZE_UNION (2, format);
|
||||||
|
@ -1915,7 +2010,8 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
|
||||||
* Class Definition Table
|
* Class Definition Table
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct ClassDefFormat1
|
template <typename Types>
|
||||||
|
struct ClassDefFormat1_3
|
||||||
{
|
{
|
||||||
friend struct ClassDef;
|
friend struct ClassDef;
|
||||||
|
|
||||||
|
@ -2120,14 +2216,16 @@ struct ClassDefFormat1
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 classFormat; /* Format identifier--format = 1 */
|
HBUINT16 classFormat; /* Format identifier--format = 1 */
|
||||||
HBGlyphID16 startGlyph; /* First GlyphID of the classValueArray */
|
typename Types::HBGlyphID
|
||||||
Array16Of<HBUINT16>
|
startGlyph; /* First GlyphID of the classValueArray */
|
||||||
|
typename Types::template ArrayOf<HBUINT16>
|
||||||
classValue; /* Array of Class Values--one per GlyphID */
|
classValue; /* Array of Class Values--one per GlyphID */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (6, classValue);
|
DEFINE_SIZE_ARRAY (2 + 2 * Types::size, classValue);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClassDefFormat2
|
template <typename Types>
|
||||||
|
struct ClassDefFormat2_4
|
||||||
{
|
{
|
||||||
friend struct ClassDef;
|
friend struct ClassDef;
|
||||||
|
|
||||||
|
@ -2156,12 +2254,12 @@ struct ClassDefFormat2
|
||||||
hb_codepoint_t prev_gid = (*it).first;
|
hb_codepoint_t prev_gid = (*it).first;
|
||||||
unsigned prev_klass = (*it).second;
|
unsigned prev_klass = (*it).second;
|
||||||
|
|
||||||
RangeRecord range_rec;
|
RangeRecord<Types> range_rec;
|
||||||
range_rec.first = prev_gid;
|
range_rec.first = prev_gid;
|
||||||
range_rec.last = prev_gid;
|
range_rec.last = prev_gid;
|
||||||
range_rec.value = prev_klass;
|
range_rec.value = prev_klass;
|
||||||
|
|
||||||
RangeRecord *record = c->copy (range_rec);
|
auto *record = c->copy (range_rec);
|
||||||
if (unlikely (!record)) return_trace (false);
|
if (unlikely (!record)) return_trace (false);
|
||||||
|
|
||||||
for (const auto gid_klass_pair : + (++it))
|
for (const auto gid_klass_pair : + (++it))
|
||||||
|
@ -2300,7 +2398,7 @@ struct ClassDefFormat2
|
||||||
}
|
}
|
||||||
/* TODO Speed up, using set overlap first? */
|
/* TODO Speed up, using set overlap first? */
|
||||||
/* TODO(iter) Rewrite as dagger. */
|
/* TODO(iter) Rewrite as dagger. */
|
||||||
const RangeRecord *arr = rangeRecord.arrayZ;
|
const auto *arr = rangeRecord.arrayZ;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (arr[i].value == klass && arr[i].intersects (glyphs))
|
if (arr[i].value == klass && arr[i].intersects (glyphs))
|
||||||
return true;
|
return true;
|
||||||
|
@ -2376,18 +2474,18 @@ struct ClassDefFormat2
|
||||||
if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
|
if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
|
||||||
intersect_classes->add (0);
|
intersect_classes->add (0);
|
||||||
|
|
||||||
for (const RangeRecord& record : rangeRecord.iter ())
|
for (const auto& record : rangeRecord.iter ())
|
||||||
if (record.intersects (glyphs))
|
if (record.intersects (glyphs))
|
||||||
intersect_classes->add (record.value);
|
intersect_classes->add (record.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 classFormat; /* Format identifier--format = 2 */
|
HBUINT16 classFormat; /* Format identifier--format = 2 */
|
||||||
SortedArray16Of<RangeRecord>
|
typename Types::template SortedArrayOf<RangeRecord<Types>>
|
||||||
rangeRecord; /* Array of glyph ranges--ordered by
|
rangeRecord; /* Array of glyph ranges--ordered by
|
||||||
* Start GlyphID */
|
* Start GlyphID */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (4, rangeRecord);
|
DEFINE_SIZE_ARRAY (2 + Types::size, rangeRecord);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ClassDef
|
struct ClassDef
|
||||||
|
@ -2406,6 +2504,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.get_class (glyph_id);
|
case 1: return u.format1.get_class (glyph_id);
|
||||||
case 2: return u.format2.get_class (glyph_id);
|
case 2: return u.format2.get_class (glyph_id);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.get_class (glyph_id);
|
||||||
|
case 4: return u.format4.get_class (glyph_id);
|
||||||
|
#endif
|
||||||
default:return 0;
|
default:return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2420,10 +2522,11 @@ struct ClassDef
|
||||||
auto it = + it_with_class_zero | hb_filter (hb_second);
|
auto it = + it_with_class_zero | hb_filter (hb_second);
|
||||||
|
|
||||||
unsigned format = 2;
|
unsigned format = 2;
|
||||||
|
hb_codepoint_t glyph_max = 0;
|
||||||
if (likely (it))
|
if (likely (it))
|
||||||
{
|
{
|
||||||
hb_codepoint_t glyph_min = (*it).first;
|
hb_codepoint_t glyph_min = (*it).first;
|
||||||
hb_codepoint_t glyph_max = glyph_min;
|
glyph_max = glyph_min;
|
||||||
|
|
||||||
unsigned num_glyphs = 0;
|
unsigned num_glyphs = 0;
|
||||||
unsigned num_ranges = 1;
|
unsigned num_ranges = 1;
|
||||||
|
@ -2448,12 +2551,22 @@ struct ClassDef
|
||||||
if (num_glyphs && 1 + (glyph_max - glyph_min + 1) <= num_ranges * 3)
|
if (num_glyphs && 1 + (glyph_max - glyph_min + 1) <= num_ranges * 3)
|
||||||
format = 1;
|
format = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
if (glyph_max > 0xFFFFu)
|
||||||
|
format += 2;
|
||||||
|
#endif
|
||||||
|
|
||||||
u.format = format;
|
u.format = format;
|
||||||
|
|
||||||
switch (u.format)
|
switch (u.format)
|
||||||
{
|
{
|
||||||
case 1: return_trace (u.format1.serialize (c, it));
|
case 1: return_trace (u.format1.serialize (c, it));
|
||||||
case 2: return_trace (u.format2.serialize (c, it));
|
case 2: return_trace (u.format2.serialize (c, it));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (u.format3.serialize (c, it));
|
||||||
|
case 4: return_trace (u.format4.serialize (c, it));
|
||||||
|
#endif
|
||||||
default:return_trace (false);
|
default:return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2468,6 +2581,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
|
case 1: return_trace (u.format1.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
|
||||||
case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
|
case 2: return_trace (u.format2.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (u.format3.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
|
||||||
|
case 4: return_trace (u.format4.subset (c, klass_map, keep_empty_table, use_class_zero, glyph_filter));
|
||||||
|
#endif
|
||||||
default:return_trace (false);
|
default:return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2479,6 +2596,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return_trace (u.format1.sanitize (c));
|
case 1: return_trace (u.format1.sanitize (c));
|
||||||
case 2: return_trace (u.format2.sanitize (c));
|
case 2: return_trace (u.format2.sanitize (c));
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return_trace (u.format3.sanitize (c));
|
||||||
|
case 4: return_trace (u.format4.sanitize (c));
|
||||||
|
#endif
|
||||||
default:return_trace (true);
|
default:return_trace (true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2488,6 +2609,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.cost ();
|
case 1: return u.format1.cost ();
|
||||||
case 2: return u.format2.cost ();
|
case 2: return u.format2.cost ();
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.cost ();
|
||||||
|
case 4: return u.format4.cost ();
|
||||||
|
#endif
|
||||||
default:return 0u;
|
default:return 0u;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2500,6 +2625,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.collect_coverage (glyphs);
|
case 1: return u.format1.collect_coverage (glyphs);
|
||||||
case 2: return u.format2.collect_coverage (glyphs);
|
case 2: return u.format2.collect_coverage (glyphs);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.collect_coverage (glyphs);
|
||||||
|
case 4: return u.format4.collect_coverage (glyphs);
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2512,6 +2641,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.collect_class (glyphs, klass);
|
case 1: return u.format1.collect_class (glyphs, klass);
|
||||||
case 2: return u.format2.collect_class (glyphs, klass);
|
case 2: return u.format2.collect_class (glyphs, klass);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.collect_class (glyphs, klass);
|
||||||
|
case 4: return u.format4.collect_class (glyphs, klass);
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2521,6 +2654,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.intersects (glyphs);
|
case 1: return u.format1.intersects (glyphs);
|
||||||
case 2: return u.format2.intersects (glyphs);
|
case 2: return u.format2.intersects (glyphs);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.intersects (glyphs);
|
||||||
|
case 4: return u.format4.intersects (glyphs);
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2529,6 +2666,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.intersects_class (glyphs, klass);
|
case 1: return u.format1.intersects_class (glyphs, klass);
|
||||||
case 2: return u.format2.intersects_class (glyphs, klass);
|
case 2: return u.format2.intersects_class (glyphs, klass);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.intersects_class (glyphs, klass);
|
||||||
|
case 4: return u.format4.intersects_class (glyphs, klass);
|
||||||
|
#endif
|
||||||
default:return false;
|
default:return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2538,6 +2679,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
|
case 1: return u.format1.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
|
||||||
case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
|
case 2: return u.format2.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
|
||||||
|
case 4: return u.format4.intersected_class_glyphs (glyphs, klass, intersect_glyphs);
|
||||||
|
#endif
|
||||||
default:return;
|
default:return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2547,6 +2692,10 @@ struct ClassDef
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1: return u.format1.intersected_classes (glyphs, intersect_classes);
|
case 1: return u.format1.intersected_classes (glyphs, intersect_classes);
|
||||||
case 2: return u.format2.intersected_classes (glyphs, intersect_classes);
|
case 2: return u.format2.intersected_classes (glyphs, intersect_classes);
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
case 3: return u.format3.intersected_classes (glyphs, intersect_classes);
|
||||||
|
case 4: return u.format4.intersected_classes (glyphs, intersect_classes);
|
||||||
|
#endif
|
||||||
default:return;
|
default:return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2555,8 +2704,12 @@ struct ClassDef
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 format; /* Format identifier */
|
HBUINT16 format; /* Format identifier */
|
||||||
ClassDefFormat1 format1;
|
ClassDefFormat1_3<SmallTypes> format1;
|
||||||
ClassDefFormat2 format2;
|
ClassDefFormat2_4<SmallTypes> format2;
|
||||||
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
|
ClassDefFormat1_3<MediumTypes>format3;
|
||||||
|
ClassDefFormat2_4<MediumTypes>format4;
|
||||||
|
#endif
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_UNION (2, format);
|
DEFINE_SIZE_UNION (2, format);
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -156,6 +156,71 @@ static void _collect_layout_indices (hb_subset_plan_t *plan,
|
||||||
indices);
|
indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g,
|
||||||
|
const hb_map_t *lookup_indices,
|
||||||
|
const hb_set_t *feature_indices,
|
||||||
|
hb_map_t *duplicate_feature_map /* OUT */)
|
||||||
|
{
|
||||||
|
if (feature_indices->is_empty ()) return;
|
||||||
|
hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_set_t>> unique_features;
|
||||||
|
//find out duplicate features after subset
|
||||||
|
for (unsigned i : feature_indices->iter ())
|
||||||
|
{
|
||||||
|
hb_tag_t t = g.get_feature_tag (i);
|
||||||
|
if (t == HB_MAP_VALUE_INVALID) continue;
|
||||||
|
if (!unique_features.has (t))
|
||||||
|
{
|
||||||
|
if (unlikely (!unique_features.set (t, hb::unique_ptr<hb_set_t> {hb_set_create ()})))
|
||||||
|
return;
|
||||||
|
if (unique_features.has (t))
|
||||||
|
unique_features.get (t)->add (i);
|
||||||
|
duplicate_feature_map->set (i, i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
|
||||||
|
hb_set_t* same_tag_features = unique_features.get (t);
|
||||||
|
for (unsigned other_f_index : same_tag_features->iter ())
|
||||||
|
{
|
||||||
|
const OT::Feature& f = g.get_feature (i);
|
||||||
|
const OT::Feature& other_f = g.get_feature (other_f_index);
|
||||||
|
|
||||||
|
auto f_iter =
|
||||||
|
+ hb_iter (f.lookupIndex)
|
||||||
|
| hb_filter (lookup_indices)
|
||||||
|
;
|
||||||
|
|
||||||
|
auto other_f_iter =
|
||||||
|
+ hb_iter (other_f.lookupIndex)
|
||||||
|
| hb_filter (lookup_indices)
|
||||||
|
;
|
||||||
|
|
||||||
|
bool is_equal = true;
|
||||||
|
for (; f_iter && other_f_iter; f_iter++, other_f_iter++)
|
||||||
|
{
|
||||||
|
unsigned a = *f_iter;
|
||||||
|
unsigned b = *other_f_iter;
|
||||||
|
if (a != b) { is_equal = false; break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_equal == false || f_iter || other_f_iter) continue;
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
duplicate_feature_map->set (i, other_f_index);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found == false)
|
||||||
|
{
|
||||||
|
same_tag_features->add (i);
|
||||||
|
duplicate_feature_map->set (i, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static inline void
|
static inline void
|
||||||
_closure_glyphs_lookups_features (hb_subset_plan_t *plan,
|
_closure_glyphs_lookups_features (hb_subset_plan_t *plan,
|
||||||
|
@ -190,7 +255,7 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan,
|
||||||
|
|
||||||
table->prune_features (lookups, &feature_indices);
|
table->prune_features (lookups, &feature_indices);
|
||||||
hb_map_t duplicate_feature_map;
|
hb_map_t duplicate_feature_map;
|
||||||
table->find_duplicate_features (lookups, &feature_indices, &duplicate_feature_map);
|
_GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, &duplicate_feature_map);
|
||||||
|
|
||||||
feature_indices.clear ();
|
feature_indices.clear ();
|
||||||
table->prune_langsys (&duplicate_feature_map, langsys_map, &feature_indices);
|
table->prune_langsys (&duplicate_feature_map, langsys_map, &feature_indices);
|
||||||
|
@ -374,7 +439,7 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf,
|
||||||
for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ())
|
for (auto item : glyf.glyph_for_gid (gid).get_composite_iterator ())
|
||||||
operation_count =
|
operation_count =
|
||||||
_glyf_add_gid_and_children (glyf,
|
_glyf_add_gid_and_children (glyf,
|
||||||
item.glyphIndex,
|
item.get_gid (),
|
||||||
gids_to_retain,
|
gids_to_retain,
|
||||||
operation_count,
|
operation_count,
|
||||||
depth);
|
depth);
|
||||||
|
|
Loading…
Reference in New Issue