HarfBuzz: Update to version 3.1.1

This commit is contained in:
bruvzg 2021-11-04 10:01:30 +02:00
parent ce634e03d5
commit da8aedfc17
74 changed files with 3546 additions and 1848 deletions

View File

@ -189,7 +189,7 @@ Files extracted from upstream source:
## harfbuzz ## harfbuzz
- Upstream: https://github.com/harfbuzz/harfbuzz - Upstream: https://github.com/harfbuzz/harfbuzz
- Version: 3.0.0 (9c387e20d65a7a366ac270d789f6ad266014c9e0, 2021) - Version: 3.1.1 (cd5c6cd0419ac5e4de975d6c476fb760bf06d2ce, 2021)
- License: MIT - License: MIT
Files extracted from upstream source: Files extracted from upstream source:

View File

@ -82,7 +82,7 @@ struct BaselineTableFormat2Part
} }
protected: protected:
HBGlyphID stdGlyph; /* The specific glyph index number in this HBGlyphID16 stdGlyph; /* The specific glyph index number in this
* font that is used to set the baseline values. * font that is used to set the baseline values.
* This is the standard glyph. * This is the standard glyph.
* This glyph must contain a set of control points * This glyph must contain a set of control points
@ -105,7 +105,7 @@ struct BaselineTableFormat3Part
} }
protected: protected:
HBGlyphID stdGlyph; /* ditto */ HBGlyphID16 stdGlyph; /* ditto */
HBUINT16 ctlPoints[32]; /* ditto */ HBUINT16 ctlPoints[32]; /* ditto */
Lookup<HBUINT16> Lookup<HBUINT16>
lookupTable; /* Lookup table that maps glyphs to their lookupTable; /* Lookup table that maps glyphs to their

View File

@ -96,8 +96,8 @@ struct LookupSegmentSingle
return_trace (c->check_struct (this) && value.sanitize (c, base)); return_trace (c->check_struct (this) && value.sanitize (c, base));
} }
HBGlyphID last; /* Last GlyphID in this segment */ HBGlyphID16 last; /* Last GlyphID in this segment */
HBGlyphID first; /* First GlyphID in this segment */ HBGlyphID16 first; /* First GlyphID in this segment */
T value; /* The lookup value (only one) */ T value; /* The lookup value (only one) */
public: public:
DEFINE_SIZE_STATIC (4 + T::static_size); DEFINE_SIZE_STATIC (4 + T::static_size);
@ -162,11 +162,11 @@ struct LookupSegmentArray
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && return_trace (c->check_struct (this) &&
first <= last && first <= last &&
valuesZ.sanitize (c, base, last - first + 1, hb_forward<Ts> (ds)...)); valuesZ.sanitize (c, base, last - first + 1, std::forward<Ts> (ds)...));
} }
HBGlyphID last; /* Last GlyphID in this segment */ HBGlyphID16 last; /* Last GlyphID in this segment */
HBGlyphID first; /* First GlyphID in this segment */ HBGlyphID16 first; /* First GlyphID in this segment */
NNOffset16To<UnsizedArrayOf<T>> NNOffset16To<UnsizedArrayOf<T>>
valuesZ; /* A 16-bit offset from the start of valuesZ; /* A 16-bit offset from the start of
* the table to the data. */ * the table to the data. */
@ -225,7 +225,7 @@ struct LookupSingle
return_trace (c->check_struct (this) && value.sanitize (c, base)); return_trace (c->check_struct (this) && value.sanitize (c, base));
} }
HBGlyphID glyph; /* Last GlyphID */ HBGlyphID16 glyph; /* Last GlyphID */
T value; /* The lookup value (only one) */ T value; /* The lookup value (only one) */
public: public:
DEFINE_SIZE_STATIC (2 + T::static_size); DEFINE_SIZE_STATIC (2 + T::static_size);
@ -287,7 +287,7 @@ struct LookupFormat8
protected: protected:
HBUINT16 format; /* Format identifier--format = 8 */ HBUINT16 format; /* Format identifier--format = 8 */
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */ HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
* glyph minus the value of firstGlyph plus 1). */ * glyph minus the value of firstGlyph plus 1). */
UnsizedArrayOf<T> UnsizedArrayOf<T>
@ -329,7 +329,7 @@ struct LookupFormat10
protected: protected:
HBUINT16 format; /* Format identifier--format = 8 */ HBUINT16 format; /* Format identifier--format = 8 */
HBUINT16 valueSize; /* Byte size of each value. */ HBUINT16 valueSize; /* Byte size of each value. */
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */ HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
* glyph minus the value of firstGlyph plus 1). */ * glyph minus the value of firstGlyph plus 1). */
UnsizedArrayOf<HBUINT8> UnsizedArrayOf<HBUINT8>
@ -661,7 +661,7 @@ struct ClassTable
return_trace (c->check_struct (this) && classArray.sanitize (c)); return_trace (c->check_struct (this) && classArray.sanitize (c));
} }
protected: protected:
HBGlyphID firstGlyph; /* First glyph index included in the trimmed array. */ HBGlyphID16 firstGlyph; /* First glyph index included in the trimmed array. */
Array16Of<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus Array16Of<HBUCHAR> classArray; /* The class codes (indexed by glyph index minus
* firstGlyph). */ * firstGlyph). */
public: public:

View File

@ -100,7 +100,7 @@ struct UnconditionalAddGlyphAction
protected: protected:
ActionSubrecordHeader ActionSubrecordHeader
header; header;
HBGlyphID addGlyph; /* Glyph that should be added if the distance factor HBGlyphID16 addGlyph; /* Glyph that should be added if the distance factor
* is growing. */ * is growing. */
public: public:
@ -121,11 +121,11 @@ struct ConditionalAddGlyphAction
HBFixed 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 * this glyph is replaced and the growth factor
* recalculated. */ * recalculated. */
HBGlyphID addGlyph; /* Glyph to be added as kashida. If this value is HBGlyphID16 addGlyph; /* Glyph to be added as kashida. If this value is
* 0xFFFF, no extra glyph will be added. Note that * 0xFFFF, no extra glyph will be added. Note that
* generally when a glyph is added, justification * generally when a glyph is added, justification
* will need to be redone. */ * will need to be redone. */
HBGlyphID substGlyph; /* Glyph to be substituted for this glyph if the HBGlyphID16 substGlyph; /* Glyph to be substituted for this glyph if the
* growth factor equals or exceeds the value of * growth factor equals or exceeds the value of
* substThreshold. */ * substThreshold. */
public: public:
@ -170,7 +170,7 @@ struct RepeatedAddGlyphAction
ActionSubrecordHeader ActionSubrecordHeader
header; header;
HBUINT16 flags; /* Currently unused; set to 0. */ HBUINT16 flags; /* Currently unused; set to 0. */
HBGlyphID glyph; /* Glyph that should be added if the distance factor HBGlyphID16 glyph; /* Glyph that should be added if the distance factor
* is growing. */ * is growing. */
public: public:
DEFINE_SIZE_STATIC (10); DEFINE_SIZE_STATIC (10);

View File

@ -82,8 +82,8 @@ struct KernPair
} }
protected: protected:
HBGlyphID left; HBGlyphID16 left;
HBGlyphID right; HBGlyphID16 right;
FWORD value; FWORD value;
public: public:
DEFINE_SIZE_STATIC (6); DEFINE_SIZE_STATIC (6);
@ -775,11 +775,11 @@ struct KerxSubTable
unsigned int subtable_type = get_type (); unsigned int subtable_type = get_type ();
TRACE_DISPATCH (this, subtable_type); TRACE_DISPATCH (this, subtable_type);
switch (subtable_type) { switch (subtable_type) {
case 0: return_trace (c->dispatch (u.format0, hb_forward<Ts> (ds)...)); case 0: return_trace (c->dispatch (u.format0, std::forward<Ts> (ds)...));
case 1: return_trace (c->dispatch (u.format1, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
case 4: return_trace (c->dispatch (u.format4, hb_forward<Ts> (ds)...)); case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
case 6: return_trace (c->dispatch (u.format6, hb_forward<Ts> (ds)...)); case 6: return_trace (c->dispatch (u.format6, std::forward<Ts> (ds)...));
default: return_trace (c->default_return_value ()); default: return_trace (c->default_return_value ());
} }
} }

View File

@ -243,21 +243,21 @@ struct ContextualSubtable
if (buffer->idx == buffer->len && !mark_set) if (buffer->idx == buffer->len && !mark_set)
return; return;
const HBGlyphID *replacement; const HBGlyphID16 *replacement;
replacement = nullptr; replacement = nullptr;
if (Types::extended) if (Types::extended)
{ {
if (entry.data.markIndex != 0xFFFF) if (entry.data.markIndex != 0xFFFF)
{ {
const Lookup<HBGlyphID> &lookup = subs[entry.data.markIndex]; const Lookup<HBGlyphID16> &lookup = subs[entry.data.markIndex];
replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs); replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs);
} }
} }
else else
{ {
unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint; unsigned int offset = entry.data.markIndex + buffer->info[mark].codepoint;
const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs; const UnsizedArrayOf<HBGlyphID16> &subs_old = (const UnsizedArrayOf<HBGlyphID16> &) subs;
replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
if (!replacement->sanitize (&c->sanitizer) || !*replacement) if (!replacement->sanitize (&c->sanitizer) || !*replacement)
replacement = nullptr; replacement = nullptr;
@ -278,14 +278,14 @@ struct ContextualSubtable
{ {
if (entry.data.currentIndex != 0xFFFF) if (entry.data.currentIndex != 0xFFFF)
{ {
const Lookup<HBGlyphID> &lookup = subs[entry.data.currentIndex]; const Lookup<HBGlyphID16> &lookup = subs[entry.data.currentIndex];
replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs); replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs);
} }
} }
else else
{ {
unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint; unsigned int offset = entry.data.currentIndex + buffer->info[idx].codepoint;
const UnsizedArrayOf<HBGlyphID> &subs_old = (const UnsizedArrayOf<HBGlyphID> &) subs; const UnsizedArrayOf<HBGlyphID16> &subs_old = (const UnsizedArrayOf<HBGlyphID16> &) subs;
replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)]; replacement = &subs_old[Types::wordOffsetToIndex (offset, table, subs_old.arrayZ)];
if (!replacement->sanitize (&c->sanitizer) || !*replacement) if (!replacement->sanitize (&c->sanitizer) || !*replacement)
replacement = nullptr; replacement = nullptr;
@ -315,7 +315,7 @@ struct ContextualSubtable
bool has_glyph_classes; bool has_glyph_classes;
unsigned int mark; unsigned int mark;
const ContextualSubtable *table; const ContextualSubtable *table;
const UnsizedListOfOffset16To<Lookup<HBGlyphID>, HBUINT, false> &subs; const UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, false> &subs;
}; };
bool apply (hb_aat_apply_context_t *c) const bool apply (hb_aat_apply_context_t *c) const
@ -359,7 +359,7 @@ struct ContextualSubtable
protected: protected:
StateTable<Types, EntryData> StateTable<Types, EntryData>
machine; machine;
NNOffsetTo<UnsizedListOfOffset16To<Lookup<HBGlyphID>, HBUINT, false>, HBUINT> NNOffsetTo<UnsizedListOfOffset16To<Lookup<HBGlyphID16>, HBUINT, false>, HBUINT>
substitutionTables; substitutionTables;
public: public:
DEFINE_SIZE_STATIC (20); DEFINE_SIZE_STATIC (20);
@ -531,7 +531,7 @@ struct LigatureSubtable
if (action & (LigActionStore | LigActionLast)) if (action & (LigActionStore | LigActionLast))
{ {
ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ); ligature_idx = Types::offsetToIndex (ligature_idx, table, ligature.arrayZ);
const HBGlyphID &ligatureData = ligature[ligature_idx]; const HBGlyphID16 &ligatureData = ligature[ligature_idx];
if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break; if (unlikely (!ligatureData.sanitize (&c->sanitizer))) break;
hb_codepoint_t lig = ligatureData; hb_codepoint_t lig = ligatureData;
@ -565,7 +565,7 @@ struct LigatureSubtable
const LigatureSubtable *table; const LigatureSubtable *table;
const UnsizedArrayOf<HBUINT32> &ligAction; const UnsizedArrayOf<HBUINT32> &ligAction;
const UnsizedArrayOf<HBUINT16> &component; const UnsizedArrayOf<HBUINT16> &component;
const UnsizedArrayOf<HBGlyphID> &ligature; const UnsizedArrayOf<HBGlyphID16> &ligature;
unsigned int match_length; unsigned int match_length;
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH]; unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
}; };
@ -597,7 +597,7 @@ struct LigatureSubtable
ligAction; /* Offset to the ligature action table. */ ligAction; /* Offset to the ligature action table. */
NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT> NNOffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT>
component; /* Offset to the component table. */ component; /* Offset to the component table. */
NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT> NNOffsetTo<UnsizedArrayOf<HBGlyphID16>, HBUINT>
ligature; /* Offset to the actual ligature lists. */ ligature; /* Offset to the actual ligature lists. */
public: public:
DEFINE_SIZE_STATIC (28); DEFINE_SIZE_STATIC (28);
@ -620,7 +620,7 @@ struct NoncontextualSubtable
unsigned int count = c->buffer->len; unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
{ {
const HBGlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs); const HBGlyphID16 *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
if (replacement) if (replacement)
{ {
info[i].codepoint = *replacement; info[i].codepoint = *replacement;
@ -641,7 +641,7 @@ struct NoncontextualSubtable
} }
protected: protected:
Lookup<HBGlyphID> substitute; Lookup<HBGlyphID16> substitute;
public: public:
DEFINE_SIZE_MIN (2); DEFINE_SIZE_MIN (2);
}; };
@ -744,7 +744,7 @@ struct InsertionSubtable
unsigned int count = (flags & MarkedInsertCount); unsigned int count = (flags & MarkedInsertCount);
if (unlikely ((buffer->max_ops -= count) <= 0)) return; if (unlikely ((buffer->max_ops -= count) <= 0)) return;
unsigned int start = entry.data.markedInsertIndex; unsigned int start = entry.data.markedInsertIndex;
const HBGlyphID *glyphs = &insertionAction[start]; const HBGlyphID16 *glyphs = &insertionAction[start];
if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
bool before = flags & MarkedInsertBefore; bool before = flags & MarkedInsertBefore;
@ -772,7 +772,7 @@ struct InsertionSubtable
unsigned int count = (flags & CurrentInsertCount) >> 5; unsigned int count = (flags & CurrentInsertCount) >> 5;
if (unlikely ((buffer->max_ops -= count) <= 0)) return; if (unlikely ((buffer->max_ops -= count) <= 0)) return;
unsigned int start = entry.data.currentInsertIndex; unsigned int start = entry.data.currentInsertIndex;
const HBGlyphID *glyphs = &insertionAction[start]; const HBGlyphID16 *glyphs = &insertionAction[start];
if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0; if (unlikely (!c->sanitizer.check_array (glyphs, count))) count = 0;
bool before = flags & CurrentInsertBefore; bool before = flags & CurrentInsertBefore;
@ -810,7 +810,7 @@ struct InsertionSubtable
private: private:
hb_aat_apply_context_t *c; hb_aat_apply_context_t *c;
unsigned int mark; unsigned int mark;
const UnsizedArrayOf<HBGlyphID> &insertionAction; const UnsizedArrayOf<HBGlyphID16> &insertionAction;
}; };
bool apply (hb_aat_apply_context_t *c) const bool apply (hb_aat_apply_context_t *c) const
@ -836,7 +836,7 @@ struct InsertionSubtable
protected: protected:
StateTable<Types, EntryData> StateTable<Types, EntryData>
machine; machine;
NNOffsetTo<UnsizedArrayOf<HBGlyphID>, HBUINT> NNOffsetTo<UnsizedArrayOf<HBGlyphID16>, HBUINT>
insertionAction; /* Byte offset from stateHeader to the start of insertionAction; /* Byte offset from stateHeader to the start of
* the insertion glyph table. */ * the insertion glyph table. */
public: public:
@ -906,11 +906,11 @@ struct ChainSubtable
unsigned int subtable_type = get_type (); unsigned int subtable_type = get_type ();
TRACE_DISPATCH (this, subtable_type); TRACE_DISPATCH (this, subtable_type);
switch (subtable_type) { switch (subtable_type) {
case Rearrangement: return_trace (c->dispatch (u.rearrangement, hb_forward<Ts> (ds)...)); case Rearrangement: return_trace (c->dispatch (u.rearrangement, std::forward<Ts> (ds)...));
case Contextual: return_trace (c->dispatch (u.contextual, hb_forward<Ts> (ds)...)); case Contextual: return_trace (c->dispatch (u.contextual, std::forward<Ts> (ds)...));
case Ligature: return_trace (c->dispatch (u.ligature, hb_forward<Ts> (ds)...)); case Ligature: return_trace (c->dispatch (u.ligature, std::forward<Ts> (ds)...));
case Noncontextual: return_trace (c->dispatch (u.noncontextual, hb_forward<Ts> (ds)...)); case Noncontextual: return_trace (c->dispatch (u.noncontextual, std::forward<Ts> (ds)...));
case Insertion: return_trace (c->dispatch (u.insertion, hb_forward<Ts> (ds)...)); case Insertion: return_trace (c->dispatch (u.insertion, std::forward<Ts> (ds)...));
default: return_trace (c->default_return_value ()); default: return_trace (c->default_return_value ());
} }
} }

View File

@ -34,6 +34,9 @@
#include "hb-null.hh" #include "hb-null.hh"
#include "hb-number.hh" #include "hb-number.hh"
#include <algorithm>
#include <initializer_list>
#include <new>
/* /*
* Flags * Flags
@ -125,7 +128,7 @@ struct BEInt<Type, 2>
template <typename Type> template <typename Type>
struct BEInt<Type, 3> struct BEInt<Type, 3>
{ {
static_assert (!hb_is_signed (Type), ""); static_assert (!std::is_signed<Type>::value, "");
public: public:
BEInt () = default; BEInt () = default;
constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF), constexpr BEInt (Type V) : v {uint8_t ((V >> 16) & 0xFF),
@ -179,7 +182,7 @@ struct
{ {
/* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */ /* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */
template <typename T> constexpr auto template <typename T> constexpr auto
operator () (T&& v) const HB_AUTO_RETURN ( hb_forward<T> (v) ) operator () (T&& v) const HB_AUTO_RETURN ( std::forward<T> (v) )
} }
HB_FUNCOBJ (hb_identity); HB_FUNCOBJ (hb_identity);
struct struct
@ -203,7 +206,7 @@ HB_FUNCOBJ (hb_ridentity);
struct struct
{ {
template <typename T> constexpr bool template <typename T> constexpr bool
operator () (T&& v) const { return bool (hb_forward<T> (v)); } operator () (T&& v) const { return bool (std::forward<T> (v)); }
} }
HB_FUNCOBJ (hb_bool); HB_FUNCOBJ (hb_bool);
@ -215,7 +218,7 @@ struct
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ()) impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
template <typename T, template <typename T,
hb_enable_if (hb_is_integral (T))> constexpr auto hb_enable_if (std::is_integral<T>::value)> constexpr auto
impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
( (
/* Knuth's multiplicative method: */ /* Knuth's multiplicative method: */
@ -237,26 +240,26 @@ struct
/* Pointer-to-member-function. */ /* Pointer-to-member-function. */
template <typename Appl, typename T, typename ...Ts> auto template <typename Appl, typename T, typename ...Ts> auto
impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN impl (Appl&& a, hb_priority<2>, T &&v, Ts&&... ds) const HB_AUTO_RETURN
((hb_deref (hb_forward<T> (v)).*hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...)) ((hb_deref (std::forward<T> (v)).*std::forward<Appl> (a)) (std::forward<Ts> (ds)...))
/* Pointer-to-member. */ /* Pointer-to-member. */
template <typename Appl, typename T> auto template <typename Appl, typename T> auto
impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN impl (Appl&& a, hb_priority<1>, T &&v) const HB_AUTO_RETURN
((hb_deref (hb_forward<T> (v))).*hb_forward<Appl> (a)) ((hb_deref (std::forward<T> (v))).*std::forward<Appl> (a))
/* Operator(). */ /* Operator(). */
template <typename Appl, typename ...Ts> auto template <typename Appl, typename ...Ts> auto
impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN impl (Appl&& a, hb_priority<0>, Ts&&... ds) const HB_AUTO_RETURN
(hb_deref (hb_forward<Appl> (a)) (hb_forward<Ts> (ds)...)) (hb_deref (std::forward<Appl> (a)) (std::forward<Ts> (ds)...))
public: public:
template <typename Appl, typename ...Ts> auto template <typename Appl, typename ...Ts> auto
operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN operator () (Appl&& a, Ts&&... ds) const HB_AUTO_RETURN
( (
impl (hb_forward<Appl> (a), impl (std::forward<Appl> (a),
hb_prioritize, hb_prioritize,
hb_forward<Ts> (ds)...) std::forward<Ts> (ds)...)
) )
} }
HB_FUNCOBJ (hb_invoke); HB_FUNCOBJ (hb_invoke);
@ -275,9 +278,9 @@ struct hb_partial_t
hb_declval (V), hb_declval (V),
hb_declval (Ts)...)) hb_declval (Ts)...))
{ {
return hb_invoke (hb_forward<Appl> (a), return hb_invoke (std::forward<Appl> (a),
hb_forward<V> (v), std::forward<V> (v),
hb_forward<Ts> (ds)...); std::forward<Ts> (ds)...);
} }
template <typename T0, typename ...Ts, template <typename T0, typename ...Ts,
unsigned P = Pos, unsigned P = Pos,
@ -287,10 +290,10 @@ struct hb_partial_t
hb_declval (V), hb_declval (V),
hb_declval (Ts)...)) hb_declval (Ts)...))
{ {
return hb_invoke (hb_forward<Appl> (a), return hb_invoke (std::forward<Appl> (a),
hb_forward<T0> (d0), std::forward<T0> (d0),
hb_forward<V> (v), std::forward<V> (v),
hb_forward<Ts> (ds)...); std::forward<Ts> (ds)...);
} }
private: private:
@ -324,14 +327,14 @@ auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN
#define HB_PARTIALIZE(Pos) \ #define HB_PARTIALIZE(Pos) \
template <typename _T> \ template <typename _T> \
decltype(auto) operator () (_T&& _v) const \ decltype(auto) operator () (_T&& _v) const \
{ return hb_partial<Pos> (this, hb_forward<_T> (_v)); } \ { return hb_partial<Pos> (this, std::forward<_T> (_v)); } \
static_assert (true, "") static_assert (true, "")
#else #else
/* https://github.com/harfbuzz/harfbuzz/issues/1724 */ /* https://github.com/harfbuzz/harfbuzz/issues/1724 */
#define HB_PARTIALIZE(Pos) \ #define HB_PARTIALIZE(Pos) \
template <typename _T> \ template <typename _T> \
auto operator () (_T&& _v) const HB_AUTO_RETURN \ auto operator () (_T&& _v) const HB_AUTO_RETURN \
(hb_partial<Pos> (+this, hb_forward<_T> (_v))) \ (hb_partial<Pos> (+this, std::forward<_T> (_v))) \
static_assert (true, "") static_assert (true, "")
#endif #endif
@ -343,22 +346,22 @@ struct
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
( (
hb_deref (hb_forward<Pred> (p)).has (hb_forward<Val> (v)) hb_deref (std::forward<Pred> (p)).has (std::forward<Val> (v))
) )
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
( (
hb_invoke (hb_forward<Pred> (p), hb_invoke (std::forward<Pred> (p),
hb_forward<Val> (v)) std::forward<Val> (v))
) )
public: public:
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
operator () (Pred&& p, Val &&v) const HB_RETURN (bool, operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
impl (hb_forward<Pred> (p), impl (std::forward<Pred> (p),
hb_forward<Val> (v), std::forward<Val> (v),
hb_prioritize) hb_prioritize)
) )
} }
@ -371,22 +374,22 @@ struct
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
( (
hb_has (hb_forward<Pred> (p), hb_has (std::forward<Pred> (p),
hb_forward<Val> (v)) std::forward<Val> (v))
) )
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
( (
hb_forward<Pred> (p) == hb_forward<Val> (v) std::forward<Pred> (p) == std::forward<Val> (v)
) )
public: public:
template <typename Pred, typename Val> auto template <typename Pred, typename Val> auto
operator () (Pred&& p, Val &&v) const HB_RETURN (bool, operator () (Pred&& p, Val &&v) const HB_RETURN (bool,
impl (hb_forward<Pred> (p), impl (std::forward<Pred> (p),
hb_forward<Val> (v), std::forward<Val> (v),
hb_prioritize) hb_prioritize)
) )
} }
@ -399,20 +402,20 @@ struct
template <typename Proj, typename Val> auto template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN impl (Proj&& f, Val &&v, hb_priority<2>) const HB_AUTO_RETURN
( (
hb_deref (hb_forward<Proj> (f)).get (hb_forward<Val> (v)) hb_deref (std::forward<Proj> (f)).get (std::forward<Val> (v))
) )
template <typename Proj, typename Val> auto template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN
( (
hb_invoke (hb_forward<Proj> (f), hb_invoke (std::forward<Proj> (f),
hb_forward<Val> (v)) std::forward<Val> (v))
) )
template <typename Proj, typename Val> auto template <typename Proj, typename Val> auto
impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN
( (
hb_forward<Proj> (f)[hb_forward<Val> (v)] std::forward<Proj> (f)[std::forward<Val> (v)]
) )
public: public:
@ -420,8 +423,8 @@ struct
template <typename Proj, typename Val> auto template <typename Proj, typename Val> auto
operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN operator () (Proj&& f, Val &&v) const HB_AUTO_RETURN
( (
impl (hb_forward<Proj> (f), impl (std::forward<Proj> (f),
hb_forward<Val> (v), std::forward<Val> (v),
hb_prioritize) hb_prioritize)
) )
} }
@ -434,19 +437,19 @@ struct
template <typename T1, typename T2> auto template <typename T1, typename T2> auto
impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN impl (T1&& v1, T2 &&v2, hb_priority<2>) const HB_AUTO_RETURN
( (
hb_forward<T2> (v2).cmp (hb_forward<T1> (v1)) == 0 std::forward<T2> (v2).cmp (std::forward<T1> (v1)) == 0
) )
template <typename T1, typename T2> auto template <typename T1, typename T2> auto
impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN impl (T1&& v1, T2 &&v2, hb_priority<1>) const HB_AUTO_RETURN
( (
hb_forward<T1> (v1).cmp (hb_forward<T2> (v2)) == 0 std::forward<T1> (v1).cmp (std::forward<T2> (v2)) == 0
) )
template <typename T1, typename T2> auto template <typename T1, typename T2> auto
impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN impl (T1&& v1, T2 &&v2, hb_priority<0>) const HB_AUTO_RETURN
( (
hb_forward<T1> (v1) == hb_forward<T2> (v2) std::forward<T1> (v1) == std::forward<T2> (v2)
) )
public: public:
@ -454,8 +457,8 @@ struct
template <typename T1, typename T2> auto template <typename T1, typename T2> auto
operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN operator () (T1&& v1, T2 &&v2) const HB_AUTO_RETURN
( (
impl (hb_forward<T1> (v1), impl (std::forward<T1> (v1),
hb_forward<T2> (v2), std::forward<T2> (v2),
hb_prioritize) hb_prioritize)
) )
} }
@ -515,24 +518,34 @@ struct
{ {
template <typename T, typename T2> constexpr auto template <typename T, typename T2> constexpr auto
operator () (T&& a, T2&& b) const HB_AUTO_RETURN operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(a <= b ? hb_forward<T> (a) : hb_forward<T2> (b)) (a <= b ? std::forward<T> (a) : std::forward<T2> (b))
} }
HB_FUNCOBJ (hb_min); HB_FUNCOBJ (hb_min);
struct struct
{ {
template <typename T, typename T2> constexpr auto template <typename T, typename T2> constexpr auto
operator () (T&& a, T2&& b) const HB_AUTO_RETURN operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(a >= b ? hb_forward<T> (a) : hb_forward<T2> (b)) (a >= b ? std::forward<T> (a) : std::forward<T2> (b))
} }
HB_FUNCOBJ (hb_max); HB_FUNCOBJ (hb_max);
struct struct
{ {
template <typename T, typename T2, typename T3> constexpr auto template <typename T, typename T2, typename T3> constexpr auto
operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN
(hb_min (hb_max (hb_forward<T> (x), hb_forward<T2> (min)), hb_forward<T3> (max))) (hb_min (hb_max (std::forward<T> (x), std::forward<T2> (min)), std::forward<T3> (max)))
} }
HB_FUNCOBJ (hb_clamp); HB_FUNCOBJ (hb_clamp);
struct
{
template <typename T> void
operator () (T& a, T& b) const
{
using std::swap; // allow ADL
swap (a, b);
}
}
HB_FUNCOBJ (hb_swap);
/* /*
* Bithacks. * Bithacks.
@ -795,7 +808,7 @@ hb_ceil_to_4 (unsigned int v)
template <typename T> static inline bool template <typename T> static inline bool
hb_in_range (T u, T lo, T hi) hb_in_range (T u, T lo, T hi)
{ {
static_assert (!hb_is_signed<T>::value, ""); static_assert (!std::is_signed<T>::value, "");
/* The casts below are important as if T is smaller than int, /* The casts below are important as if T is smaller than int,
* the subtract results will become a signed int! */ * the subtract results will become a signed int! */

View File

@ -50,10 +50,10 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
/* /*
* Constructors. * Constructors.
*/ */
hb_array_t () : arrayZ (nullptr), length (0), backwards_length (0) {} hb_array_t () = default;
hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_), backwards_length (0) {} hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
template <unsigned int length_> template <unsigned int length_>
hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {} hb_array_t (Type (&array_)[length_]) : hb_array_t (array_, length_) {}
template <typename U, template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))> hb_enable_if (hb_is_cr_convertible(U, Type))>
@ -281,9 +281,9 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
*/ */
public: public:
Type *arrayZ; Type *arrayZ = nullptr;
unsigned int length; unsigned int length = 0;
unsigned int backwards_length; unsigned int backwards_length = 0;
}; };
template <typename T> inline hb_array_t<T> template <typename T> inline hb_array_t<T>
hb_array (T *array, unsigned int length) hb_array (T *array, unsigned int length)
@ -302,7 +302,7 @@ struct hb_sorted_array_t :
static constexpr bool is_random_access_iterator = true; static constexpr bool is_random_access_iterator = true;
static constexpr bool is_sorted_iterator = true; static constexpr bool is_sorted_iterator = true;
hb_sorted_array_t () : hb_array_t<Type> () {} hb_sorted_array_t () = default;
hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {} hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t<Type> (array_, length_) {}
template <unsigned int length_> template <unsigned int length_>
hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {} hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t<Type> (array_) {}

View File

@ -102,20 +102,12 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
#define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N)) #define hb_atomic_ptr_impl_cmpexch(P,O,N) _hb_atomic_ptr_impl_cmplexch ((const void **) (P), (O), (N))
#elif defined(HB_NO_MT) #else /* defined(HB_NO_MT) */
#define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V)) #define hb_atomic_int_impl_add(AI, V) ((*(AI) += (V)) - (V))
#define _hb_memory_barrier() do {} while (0) #define _hb_memory_barrier() do {} while (0)
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false) #define hb_atomic_ptr_impl_cmpexch(P,O,N) (* (void **) (P) == (void *) (O) ? (* (void **) (P) = (void *) (N), true) : false)
#else
#error "Could not find any system to define atomic_int macros."
#error "Check hb-atomic.hh for possible resolutions."
#endif #endif

View File

@ -33,15 +33,14 @@
/* Bi-directional map */ /* Bi-directional map */
struct hb_bimap_t struct hb_bimap_t
{ {
hb_bimap_t () { init (); } /* XXX(remove) */
~hb_bimap_t () { fini (); }
void init () void init ()
{ {
forw_map.init (); forw_map.init ();
back_map.init (); back_map.init ();
} }
/* XXX(remove) */
void fini () void fini ()
{ {
forw_map.fini (); forw_map.fini ();
@ -99,14 +98,6 @@ struct hb_bimap_t
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */ /* Inremental bimap: only lhs is given, rhs is incrementally assigned */
struct hb_inc_bimap_t : hb_bimap_t struct hb_inc_bimap_t : hb_bimap_t
{ {
hb_inc_bimap_t () { init (); }
void init ()
{
hb_bimap_t::init ();
next_value = 0;
}
/* Add a mapping from lhs to rhs with a unique value if lhs is unknown. /* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
* Return the rhs value as the result. * Return the rhs value as the result.
*/ */
@ -165,7 +156,7 @@ struct hb_inc_bimap_t : hb_bimap_t
} }
protected: protected:
unsigned int next_value; unsigned int next_value = 0;
}; };
#endif /* HB_BIMAP_HH */ #endif /* HB_BIMAP_HH */

View File

@ -35,10 +35,20 @@
struct hb_bit_set_invertible_t struct hb_bit_set_invertible_t
{ {
hb_bit_set_t s; hb_bit_set_t s;
bool inverted; bool inverted = false;
hb_bit_set_invertible_t () { init (); } hb_bit_set_invertible_t () = default;
~hb_bit_set_invertible_t () { fini (); } hb_bit_set_invertible_t (hb_bit_set_invertible_t& o) = default;
hb_bit_set_invertible_t (hb_bit_set_invertible_t&& o) = default;
hb_bit_set_invertible_t& operator= (const hb_bit_set_invertible_t& o) = default;
hb_bit_set_invertible_t& operator= (hb_bit_set_invertible_t&& o) = default;
friend void swap (hb_bit_set_invertible_t &a, hb_bit_set_invertible_t &b)
{
if (likely (!a.s.successful || !b.s.successful))
return;
hb_swap (a.inverted, b.inverted);
hb_swap (a.s, b.s);
}
void init () { s.init (); inverted = false; } void init () { s.init (); inverted = false; }
void fini () { s.fini (); } void fini () { s.fini (); }

View File

@ -35,13 +35,22 @@
struct hb_bit_set_t struct hb_bit_set_t
{ {
hb_bit_set_t () { init (); } hb_bit_set_t () = default;
~hb_bit_set_t () { fini (); } ~hb_bit_set_t () = default;
hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other); } hb_bit_set_t (const hb_bit_set_t& other) : hb_bit_set_t () { set (other); }
void operator= (const hb_bit_set_t& other) { set (other); } hb_bit_set_t ( hb_bit_set_t&& other) : hb_bit_set_t () { hb_swap (*this, other); }
// TODO Add move construtor/assign hb_bit_set_t& operator= (const hb_bit_set_t& other) { set (other); return *this; }
// TODO Add constructor for Iterator; with specialization for (sorted) vector / array? hb_bit_set_t& operator= (hb_bit_set_t&& other) { hb_swap (*this, other); return *this; }
friend void swap (hb_bit_set_t &a, hb_bit_set_t &b)
{
if (likely (!a.successful || !b.successful))
return;
hb_swap (a.population, b.population);
hb_swap (a.last_page_lookup, b.last_page_lookup);
hb_swap (a.page_map, b.page_map);
hb_swap (a.pages, b.pages);
}
void init () void init ()
{ {
@ -67,9 +76,9 @@ struct hb_bit_set_t
uint32_t index; uint32_t index;
}; };
bool successful; /* Allocations successful */ bool successful = true; /* Allocations successful */
mutable unsigned int population; mutable unsigned int population = 0;
mutable unsigned int last_page_lookup; mutable unsigned int last_page_lookup = 0;
hb_sorted_vector_t<page_map_t> page_map; hb_sorted_vector_t<page_map_t> page_map;
hb_vector_t<page_t> pages; hb_vector_t<page_t> pages;

View File

@ -224,6 +224,7 @@ hb_buffer_t::reset ()
flags = HB_BUFFER_FLAG_DEFAULT; flags = HB_BUFFER_FLAG_DEFAULT;
replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT; replacement = HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT;
invisible = 0; invisible = 0;
not_found = 0;
clear (); clear ();
} }
@ -608,6 +609,7 @@ DEFINE_NULL_INSTANCE (hb_buffer_t) =
HB_BUFFER_CLUSTER_LEVEL_DEFAULT, HB_BUFFER_CLUSTER_LEVEL_DEFAULT,
HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT,
0, /* invisible */ 0, /* invisible */
0, /* not_found */
HB_BUFFER_SCRATCH_FLAG_DEFAULT, HB_BUFFER_SCRATCH_FLAG_DEFAULT,
HB_BUFFER_MAX_LEN_DEFAULT, HB_BUFFER_MAX_LEN_DEFAULT,
HB_BUFFER_MAX_OPS_DEFAULT, HB_BUFFER_MAX_OPS_DEFAULT,
@ -1158,6 +1160,46 @@ hb_buffer_get_invisible_glyph (hb_buffer_t *buffer)
return buffer->invisible; return buffer->invisible;
} }
/**
* hb_buffer_set_not_found_glyph:
* @buffer: An #hb_buffer_t
* @not_found: the not-found #hb_codepoint_t
*
* Sets the #hb_codepoint_t that replaces characters not found in
* the font during shaping.
*
* The not-found glyph defaults to zero, sometimes knows as the
* ".notdef" glyph. This API allows for differentiating the two.
*
* Since: 3.1.0
**/
void
hb_buffer_set_not_found_glyph (hb_buffer_t *buffer,
hb_codepoint_t not_found)
{
if (unlikely (hb_object_is_immutable (buffer)))
return;
buffer->not_found = not_found;
}
/**
* hb_buffer_get_not_found_glyph:
* @buffer: An #hb_buffer_t
*
* See hb_buffer_set_not_found_glyph().
*
* Return value:
* The @buffer not-found #hb_codepoint_t
*
* Since: 3.1.0
**/
hb_codepoint_t
hb_buffer_get_not_found_glyph (hb_buffer_t *buffer)
{
return buffer->not_found;
}
/** /**
* hb_buffer_reset: * hb_buffer_reset:

View File

@ -383,6 +383,13 @@ hb_buffer_set_invisible_glyph (hb_buffer_t *buffer,
HB_EXTERN hb_codepoint_t HB_EXTERN hb_codepoint_t
hb_buffer_get_invisible_glyph (hb_buffer_t *buffer); hb_buffer_get_invisible_glyph (hb_buffer_t *buffer);
HB_EXTERN void
hb_buffer_set_not_found_glyph (hb_buffer_t *buffer,
hb_codepoint_t not_found);
HB_EXTERN hb_codepoint_t
hb_buffer_get_not_found_glyph (hb_buffer_t *buffer);
HB_EXTERN void HB_EXTERN void
hb_buffer_reset (hb_buffer_t *buffer); hb_buffer_reset (hb_buffer_t *buffer);

View File

@ -93,6 +93,7 @@ struct hb_buffer_t
hb_buffer_cluster_level_t cluster_level; hb_buffer_cluster_level_t cluster_level;
hb_codepoint_t replacement; /* U+FFFD or something else. */ hb_codepoint_t replacement; /* U+FFFD or something else. */
hb_codepoint_t invisible; /* 0 or something else. */ hb_codepoint_t invisible; /* 0 or something else. */
hb_codepoint_t not_found; /* 0 or something else. */
hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */ hb_buffer_scratch_flags_t scratch_flags; /* Have space-fallback, etc. */
unsigned int max_len; /* Maximum allowed len. */ unsigned int max_len; /* Maximum allowed len. */
int max_ops; /* Maximum allowed operations. */ int max_ops; /* Maximum allowed operations. */

View File

@ -302,7 +302,7 @@ struct hb_auto_trace_t
{ {
if (unlikely (returned)) { if (unlikely (returned)) {
fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n"); fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n");
return hb_forward<T> (v); return std::forward<T> (v);
} }
_hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1, _hb_debug_msg<max_level> (what, obj, func, true, plevel ? *plevel : 1, -1,
@ -311,7 +311,7 @@ struct hb_auto_trace_t
if (plevel) --*plevel; if (plevel) --*plevel;
plevel = nullptr; plevel = nullptr;
returned = true; returned = true;
return hb_forward<T> (v); return std::forward<T> (v);
} }
private: private:
@ -333,7 +333,7 @@ struct hb_auto_trace_t<0, ret_t>
template <typename T> template <typename T>
T ret (T&& v, T ret (T&& v,
const char *func HB_UNUSED = nullptr, const char *func HB_UNUSED = nullptr,
unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); } unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); }
}; };
/* For disabled tracing; optimize out everything. /* For disabled tracing; optimize out everything.
@ -343,7 +343,7 @@ struct hb_no_trace_t {
template <typename T> template <typename T>
T ret (T&& v, T ret (T&& v,
const char *func HB_UNUSED = nullptr, const char *func HB_UNUSED = nullptr,
unsigned int line HB_UNUSED = 0) { return hb_forward<T> (v); } unsigned int line HB_UNUSED = 0) { return std::forward<T> (v); }
}; };
#define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__) #define return_trace(RET) return trace.ret (RET, HB_FUNC, __LINE__)

View File

@ -43,6 +43,14 @@
* Functions for using HarfBuzz with DirectWrite fonts. * Functions for using HarfBuzz with DirectWrite fonts.
**/ **/
/* Declare object creator for dynamic support of DWRITE */
typedef HRESULT (* WINAPI t_DWriteCreateFactory)(
DWRITE_FACTORY_TYPE factoryType,
REFIID iid,
IUnknown **factory
);
/* /*
* DirectWrite font stream helpers * DirectWrite font stream helpers
*/ */
@ -137,6 +145,7 @@ public:
struct hb_directwrite_face_data_t struct hb_directwrite_face_data_t
{ {
HMODULE dwrite_dll;
IDWriteFactory *dwriteFactory; IDWriteFactory *dwriteFactory;
IDWriteFontFile *fontFile; IDWriteFontFile *fontFile;
DWriteFontFileStream *fontFileStream; DWriteFontFileStream *fontFileStream;
@ -158,12 +167,33 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
return nullptr; \ return nullptr; \
} HB_STMT_END } HB_STMT_END
data->dwrite_dll = LoadLibrary (TEXT ("DWRITE"));
if (unlikely (!data->dwrite_dll))
FAIL ("Cannot find DWrite.DLL");
t_DWriteCreateFactory p_DWriteCreateFactory;
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
p_DWriteCreateFactory = (t_DWriteCreateFactory)
GetProcAddress (data->dwrite_dll, "DWriteCreateFactory");
#if defined(__GNUC__)
#pragma GCC diagnostic pop
#endif
if (unlikely (!p_DWriteCreateFactory))
FAIL ("Cannot find DWriteCreateFactory().");
HRESULT hr; HRESULT hr;
// TODO: factory and fontFileLoader should be cached separately // TODO: factory and fontFileLoader should be cached separately
IDWriteFactory* dwriteFactory; IDWriteFactory* dwriteFactory;
hr = DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory), hr = p_DWriteCreateFactory (DWRITE_FACTORY_TYPE_SHARED, __uuidof (IDWriteFactory),
(IUnknown**) &dwriteFactory); (IUnknown**) &dwriteFactory);
if (unlikely (hr != S_OK)) if (unlikely (hr != S_OK))
FAIL ("Failed to run DWriteCreateFactory()."); FAIL ("Failed to run DWriteCreateFactory().");
@ -227,6 +257,8 @@ _hb_directwrite_shaper_face_data_destroy (hb_directwrite_face_data_t *data)
delete data->fontFileStream; delete data->fontFileStream;
if (data->faceBlob) if (data->faceBlob)
hb_blob_destroy (data->faceBlob); hb_blob_destroy (data->faceBlob);
if (data->dwrite_dll)
FreeLibrary (data->dwrite_dll);
if (data) if (data)
delete data; delete data;
} }

View File

@ -50,7 +50,7 @@ struct hb_dispatch_context_t
bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; } bool may_dispatch (const T *obj HB_UNUSED, const F *format HB_UNUSED) { return true; }
template <typename T, typename ...Ts> template <typename T, typename ...Ts>
return_t dispatch (const T &obj, Ts&&... ds) return_t dispatch (const T &obj, Ts&&... ds)
{ return obj.dispatch (thiz (), hb_forward<Ts> (ds)...); } { return obj.dispatch (thiz (), std::forward<Ts> (ds)...); }
static return_t no_dispatch_return_value () { return Context::default_return_value (); } static return_t no_dispatch_return_value () { return Context::default_return_value (); }
static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; } static bool stop_sublookup_iteration (const return_t r HB_UNUSED) { return false; }
unsigned debug_depth = 0; unsigned debug_depth = 0;

View File

@ -217,9 +217,10 @@ struct hb_font_t
} }
hb_bool_t get_nominal_glyph (hb_codepoint_t unicode, hb_bool_t get_nominal_glyph (hb_codepoint_t unicode,
hb_codepoint_t *glyph) hb_codepoint_t *glyph,
hb_codepoint_t not_found = 0)
{ {
*glyph = 0; *glyph = not_found;
return klass->get.f.nominal_glyph (this, user_data, return klass->get.f.nominal_glyph (this, user_data,
unicode, glyph, unicode, glyph,
klass->user_data.nominal_glyph); klass->user_data.nominal_glyph);
@ -238,9 +239,10 @@ struct hb_font_t
} }
hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph) hb_codepoint_t *glyph,
hb_codepoint_t not_found = 0)
{ {
*glyph = 0; *glyph = not_found;
return klass->get.f.variation_glyph (this, user_data, return klass->get.f.variation_glyph (this, user_data,
unicode, variation_selector, glyph, unicode, variation_selector, glyph,
klass->user_data.variation_glyph); klass->user_data.variation_glyph);
@ -618,9 +620,7 @@ struct hb_font_t
} }
hb_position_t em_mult (int16_t v, int64_t mult) hb_position_t em_mult (int16_t v, int64_t mult)
{ { return (hb_position_t) ((v * mult + 32768) >> 16); }
return (hb_position_t) ((v * mult) >> 16);
}
hb_position_t em_scalef (float v, int scale) hb_position_t em_scalef (float v, int scale)
{ return (hb_position_t) roundf (v * scale / face->get_upem ()); } { return (hb_position_t) roundf (v * scale / face->get_upem ()); }
float em_fscale (int16_t v, int scale) float em_fscale (int16_t v, int scale)

View File

@ -162,7 +162,7 @@ struct
{ {
template <typename T> hb_iter_type<T> template <typename T> hb_iter_type<T>
operator () (T&& c) const operator () (T&& c) const
{ return hb_deref (hb_forward<T> (c)).iter (); } { return hb_deref (std::forward<T> (c)).iter (); }
/* Specialization for C arrays. */ /* Specialization for C arrays. */
@ -353,7 +353,7 @@ static inline auto end (Iterable&& iterable) HB_AUTO_RETURN (hb_iter (iterable).
template <typename Lhs, typename Rhs, template <typename Lhs, typename Rhs,
hb_requires (hb_is_iterator (Lhs))> hb_requires (hb_is_iterator (Lhs))>
static inline auto static inline auto
operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (hb_forward<Rhs> (rhs) (hb_forward<Lhs> (lhs))) operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (std::forward<Rhs> (rhs) (std::forward<Lhs> (lhs)))
/* hb_map(), hb_filter(), hb_reduce() */ /* hb_map(), hb_filter(), hb_reduce() */
@ -674,8 +674,8 @@ struct hb_iota_iter_t :
template <typename S2 = S> template <typename S2 = S>
auto auto
inc (hb_type_identity<S2> s, hb_priority<1>) inc (hb_type_identity<S2> s, hb_priority<1>)
-> hb_void_t<decltype (hb_invoke (hb_forward<S2> (s), hb_declval<T&> ()))> -> hb_void_t<decltype (hb_invoke (std::forward<S2> (s), hb_declval<T&> ()))>
{ v = hb_invoke (hb_forward<S2> (s), v); } { v = hb_invoke (std::forward<S2> (s), v); }
void void
inc (S s, hb_priority<0>) inc (S s, hb_priority<0>)
@ -874,7 +874,7 @@ struct
Proj&& f = hb_identity) const Proj&& f = hb_identity) const
{ {
for (auto it = hb_iter (c); it; ++it) for (auto it = hb_iter (c); it; ++it)
if (!hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it))) if (!hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
return false; return false;
return true; return true;
} }
@ -891,7 +891,7 @@ struct
Proj&& f = hb_identity) const Proj&& f = hb_identity) const
{ {
for (auto it = hb_iter (c); it; ++it) for (auto it = hb_iter (c); it; ++it)
if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it))) if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
return true; return true;
return false; return false;
} }
@ -908,7 +908,7 @@ struct
Proj&& f = hb_identity) const Proj&& f = hb_identity) const
{ {
for (auto it = hb_iter (c); it; ++it) for (auto it = hb_iter (c); it; ++it)
if (hb_match (hb_forward<Pred> (p), hb_get (hb_forward<Proj> (f), *it))) if (hb_match (std::forward<Pred> (p), hb_get (std::forward<Proj> (f), *it)))
return false; return false;
return true; return true;
} }

View File

@ -35,16 +35,35 @@
*/ */
template <typename K, typename V, template <typename K, typename V,
K kINVALID = hb_is_pointer (K) ? 0 : hb_is_signed (K) ? hb_int_min (K) : (K) -1, K kINVALID = hb_is_pointer (K) ? 0 : std::is_signed<K>::value ? hb_int_min (K) : (K) -1,
V vINVALID = hb_is_pointer (V) ? 0 : hb_is_signed (V) ? hb_int_min (V) : (V) -1> V vINVALID = hb_is_pointer (V) ? 0 : std::is_signed<V>::value ? hb_int_min (V) : (V) -1>
struct hb_hashmap_t struct hb_hashmap_t
{ {
HB_DELETE_COPY_ASSIGN (hb_hashmap_t); static constexpr K INVALID_KEY = kINVALID;
static constexpr V INVALID_VALUE = vINVALID;
hb_hashmap_t () { init (); } hb_hashmap_t () { init (); }
~hb_hashmap_t () { fini (); } ~hb_hashmap_t () { fini (); }
static_assert (hb_is_integral (K) || hb_is_pointer (K), ""); hb_hashmap_t (const hb_hashmap_t& o) : hb_hashmap_t () { hb_copy (o, *this); }
static_assert (hb_is_integral (V) || hb_is_pointer (V), ""); hb_hashmap_t (hb_hashmap_t&& o) : hb_hashmap_t () { hb_swap (*this, o); }
hb_hashmap_t& operator= (const hb_hashmap_t& o) { hb_copy (o, *this); return *this; }
hb_hashmap_t& operator= (hb_hashmap_t&& o) { hb_swap (*this, o); return *this; }
hb_hashmap_t (std::initializer_list<hb_pair_t<K, V>> lst) : hb_hashmap_t ()
{
for (auto&& item : lst)
set (item.first, item.second);
}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
hb_hashmap_t (const Iterable &o) : hb_hashmap_t ()
{
hb_copy (o, *this);
}
static_assert (std::is_integral<K>::value || hb_is_pointer (K), "");
static_assert (std::is_integral<V>::value || hb_is_pointer (V), "");
struct item_t struct item_t
{ {
@ -70,6 +89,16 @@ struct hb_hashmap_t
unsigned int prime; unsigned int prime;
item_t *items; item_t *items;
friend void swap (hb_hashmap_t& a, hb_hashmap_t& b)
{
if (unlikely (!a.successful || !b.successful))
return;
hb_swap (a.population, b.population);
hb_swap (a.occupancy, b.occupancy);
hb_swap (a.mask, b.mask);
hb_swap (a.prime, b.prime);
hb_swap (a.items, b.items);
}
void init_shallow () void init_shallow ()
{ {
successful = true; successful = true;
@ -133,17 +162,15 @@ struct hb_hashmap_t
if (old_items[i].is_real ()) if (old_items[i].is_real ())
set_with_hash (old_items[i].key, set_with_hash (old_items[i].key,
old_items[i].hash, old_items[i].hash,
old_items[i].value); std::move (old_items[i].value));
hb_free (old_items); hb_free (old_items);
return true; return true;
} }
bool set (K key, V value) bool set (K key, const V& value) { return set_with_hash (key, hb_hash (key), value); }
{ bool set (K key, V&& value) { return set_with_hash (key, hb_hash (key), std::move (value)); }
return set_with_hash (key, hb_hash (key), value);
}
V get (K key) const V get (K key) const
{ {
@ -213,7 +240,8 @@ struct hb_hashmap_t
protected: protected:
bool set_with_hash (K key, uint32_t hash, V value) template <typename VV>
bool set_with_hash (K key, uint32_t hash, VV&& value)
{ {
if (unlikely (!successful)) return false; if (unlikely (!successful)) return false;
if (unlikely (key == kINVALID)) return true; if (unlikely (key == kINVALID)) return true;
@ -321,7 +349,22 @@ struct hb_hashmap_t
struct hb_map_t : hb_hashmap_t<hb_codepoint_t, struct hb_map_t : hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t, hb_codepoint_t,
HB_MAP_VALUE_INVALID, HB_MAP_VALUE_INVALID,
HB_MAP_VALUE_INVALID> {}; HB_MAP_VALUE_INVALID>
{
using hashmap = hb_hashmap_t<hb_codepoint_t,
hb_codepoint_t,
HB_MAP_VALUE_INVALID,
HB_MAP_VALUE_INVALID>;
hb_map_t () = default;
~hb_map_t () = default;
hb_map_t (hb_map_t& o) = default;
hb_map_t& operator= (const hb_map_t& other) = default;
hb_map_t& operator= (hb_map_t&& other) = default;
hb_map_t (std::initializer_list<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> lst) : hashmap (lst) {}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
hb_map_t (const Iterable &o) : hashmap (o) {}
};
#endif /* HB_MAP_HH */ #endif /* HB_MAP_HH */

View File

@ -29,6 +29,9 @@
#include "hb.hh" #include "hb.hh"
#include <type_traits>
#include <utility>
/* /*
* C++ template meta-programming & fundamentals used with them. * C++ template meta-programming & fundamentals used with them.
@ -129,40 +132,7 @@ template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (h
/* TODO Add feature-parity to std::decay. */ /* TODO Add feature-parity to std::decay. */
template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>; template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
#define hb_is_convertible(From,To) std::is_convertible<From, To>::value
template<bool B, class T, class F>
struct _hb_conditional { typedef T type; };
template<class T, class F>
struct _hb_conditional<false, T, F> { typedef F type; };
template<bool B, class T, class F>
using hb_conditional = typename _hb_conditional<B, T, F>::type;
template <typename From, typename To>
struct hb_is_convertible
{
private:
static constexpr bool from_void = hb_is_same (void, hb_decay<From>);
static constexpr bool to_void = hb_is_same (void, hb_decay<To> );
static constexpr bool either_void = from_void || to_void;
static constexpr bool both_void = from_void && to_void;
static hb_true_type impl2 (hb_conditional<to_void, int, To>);
template <typename T>
static auto impl (hb_priority<1>) -> decltype (impl2 (hb_declval (T)));
template <typename T>
static hb_false_type impl (hb_priority<0>);
public:
static constexpr bool value = both_void ||
(!either_void &&
decltype (impl<hb_conditional<from_void, int, From>> (hb_prioritize))::value);
};
#define hb_is_convertible(From,To) hb_is_convertible<From, To>::value
template <typename Base, typename Derived>
using hb_is_base_of = hb_is_convertible<hb_decay<Derived> *, hb_decay<Base> *>;
#define hb_is_base_of(Base,Derived) hb_is_base_of<Base, Derived>::value
template <typename From, typename To> template <typename From, typename To>
using hb_is_cr_convertible = hb_bool_constant< using hb_is_cr_convertible = hb_bool_constant<
@ -172,20 +142,11 @@ using hb_is_cr_convertible = hb_bool_constant<
>; >;
#define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value #define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
/* std::move and std::forward */
template <typename T>
static constexpr hb_remove_reference<T>&& hb_move (T&& t) { return (hb_remove_reference<T>&&) (t); }
template <typename T>
static constexpr T&& hb_forward (hb_remove_reference<T>& t) { return (T&&) t; }
template <typename T>
static constexpr T&& hb_forward (hb_remove_reference<T>&& t) { return (T&&) t; }
struct struct
{ {
template <typename T> constexpr auto template <typename T> constexpr auto
operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v)) operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v))
template <typename T> constexpr auto template <typename T> constexpr auto
operator () (T *v) const HB_AUTO_RETURN (*v) operator () (T *v) const HB_AUTO_RETURN (*v)
@ -195,7 +156,7 @@ HB_FUNCOBJ (hb_deref);
struct struct
{ {
template <typename T> constexpr auto template <typename T> constexpr auto
operator () (T&& v) const HB_AUTO_RETURN (hb_forward<T> (v)) operator () (T&& v) const HB_AUTO_RETURN (std::forward<T> (v))
template <typename T> constexpr auto template <typename T> constexpr auto
operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v)) operator () (T& v) const HB_AUTO_RETURN (hb_addressof (v))
@ -226,50 +187,6 @@ struct hb_reference_wrapper<T&>
/* Type traits */ /* Type traits */
template <typename T>
using hb_is_integral = hb_bool_constant<
hb_is_same (hb_decay<T>, char) ||
hb_is_same (hb_decay<T>, signed char) ||
hb_is_same (hb_decay<T>, unsigned char) ||
hb_is_same (hb_decay<T>, signed int) ||
hb_is_same (hb_decay<T>, unsigned int) ||
hb_is_same (hb_decay<T>, signed short) ||
hb_is_same (hb_decay<T>, unsigned short) ||
hb_is_same (hb_decay<T>, signed long) ||
hb_is_same (hb_decay<T>, unsigned long) ||
hb_is_same (hb_decay<T>, signed long long) ||
hb_is_same (hb_decay<T>, unsigned long long) ||
false
>;
#define hb_is_integral(T) hb_is_integral<T>::value
template <typename T>
using hb_is_floating_point = hb_bool_constant<
hb_is_same (hb_decay<T>, float) ||
hb_is_same (hb_decay<T>, double) ||
hb_is_same (hb_decay<T>, long double) ||
false
>;
#define hb_is_floating_point(T) hb_is_floating_point<T>::value
template <typename T>
using hb_is_arithmetic = hb_bool_constant<
hb_is_integral (T) ||
hb_is_floating_point (T) ||
false
>;
#define hb_is_arithmetic(T) hb_is_arithmetic<T>::value
template <typename T, bool is_arithmetic> struct hb_is_signed_;
template <typename T> struct hb_is_signed_<T, false> : hb_false_type {};
template <typename T> struct hb_is_signed_<T, true> : hb_bool_constant<(T) -1 < (T) 0> {};
template <typename T> struct hb_is_signed : hb_is_signed_<T, hb_is_arithmetic (T)> {};
#define hb_is_signed(T) hb_is_signed<T>::value
template <typename T, bool is_arithmetic> struct hb_is_unsigned_;
template <typename T> struct hb_is_unsigned_<T, false> : hb_false_type {};
template <typename T> struct hb_is_unsigned_<T, true> : hb_bool_constant<(T) 0 < (T) -1> {};
template <typename T> struct hb_is_unsigned : hb_is_unsigned_<T, hb_is_arithmetic (T)> {};
#define hb_is_unsigned(T) hb_is_unsigned<T>::value
template <typename T> struct hb_int_min; template <typename T> struct hb_int_min;
template <> struct hb_int_min<char> : hb_integral_constant<char, CHAR_MIN> {}; template <> struct hb_int_min<char> : hb_integral_constant<char, CHAR_MIN> {};
template <> struct hb_int_min<signed char> : hb_integral_constant<signed char, SCHAR_MIN> {}; template <> struct hb_int_min<signed char> : hb_integral_constant<signed char, SCHAR_MIN> {};
@ -309,108 +226,6 @@ template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigne
TypeName(const TypeName&) = delete; \ TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete void operator=(const TypeName&) = delete
template <typename T, typename>
struct _hb_is_destructible : hb_false_type {};
template <typename T>
struct _hb_is_destructible<T, hb_void_t<decltype (hb_declval (T).~T ())>> : hb_true_type {};
template <typename T>
using hb_is_destructible = _hb_is_destructible<T, void>;
#define hb_is_destructible(T) hb_is_destructible<T>::value
template <typename T, typename, typename ...Ts>
struct _hb_is_constructible : hb_false_type {};
template <typename T, typename ...Ts>
struct _hb_is_constructible<T, hb_void_t<decltype (T (hb_declval (Ts)...))>, Ts...> : hb_true_type {};
template <typename T, typename ...Ts>
using hb_is_constructible = _hb_is_constructible<T, void, Ts...>;
#define hb_is_constructible(...) hb_is_constructible<__VA_ARGS__>::value
template <typename T>
using hb_is_default_constructible = hb_is_constructible<T>;
#define hb_is_default_constructible(T) hb_is_default_constructible<T>::value
template <typename T>
using hb_is_copy_constructible = hb_is_constructible<T, hb_add_lvalue_reference<hb_add_const<T>>>;
#define hb_is_copy_constructible(T) hb_is_copy_constructible<T>::value
template <typename T>
using hb_is_move_constructible = hb_is_constructible<T, hb_add_rvalue_reference<hb_add_const<T>>>;
#define hb_is_move_constructible(T) hb_is_move_constructible<T>::value
template <typename T, typename U, typename>
struct _hb_is_assignable : hb_false_type {};
template <typename T, typename U>
struct _hb_is_assignable<T, U, hb_void_t<decltype (hb_declval (T) = hb_declval (U))>> : hb_true_type {};
template <typename T, typename U>
using hb_is_assignable = _hb_is_assignable<T, U, void>;
#define hb_is_assignable(T,U) hb_is_assignable<T, U>::value
template <typename T>
using hb_is_copy_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
hb_add_lvalue_reference<hb_add_const<T>>>;
#define hb_is_copy_assignable(T) hb_is_copy_assignable<T>::value
template <typename T>
using hb_is_move_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
hb_add_rvalue_reference<T>>;
#define hb_is_move_assignable(T) hb_is_move_assignable<T>::value
/* Trivial versions. */
template <typename T> union hb_trivial { T value; };
template <typename T>
using hb_is_trivially_destructible= hb_is_destructible<hb_trivial<T>>;
#define hb_is_trivially_destructible(T) hb_is_trivially_destructible<T>::value
/* Don't know how to do the following. */
//template <typename T, typename ...Ts>
//using hb_is_trivially_constructible= hb_is_constructible<hb_trivial<T>, hb_trivial<Ts>...>;
//#define hb_is_trivially_constructible(...) hb_is_trivially_constructible<__VA_ARGS__>::value
template <typename T>
using hb_is_trivially_default_constructible= hb_is_default_constructible<hb_trivial<T>>;
#define hb_is_trivially_default_constructible(T) hb_is_trivially_default_constructible<T>::value
template <typename T>
using hb_is_trivially_copy_constructible= hb_is_copy_constructible<hb_trivial<T>>;
#define hb_is_trivially_copy_constructible(T) hb_is_trivially_copy_constructible<T>::value
template <typename T>
using hb_is_trivially_move_constructible= hb_is_move_constructible<hb_trivial<T>>;
#define hb_is_trivially_move_constructible(T) hb_is_trivially_move_constructible<T>::value
/* Don't know how to do the following. */
//template <typename T, typename U>
//using hb_is_trivially_assignable= hb_is_assignable<hb_trivial<T>, hb_trivial<U>>;
//#define hb_is_trivially_assignable(T,U) hb_is_trivially_assignable<T, U>::value
template <typename T>
using hb_is_trivially_copy_assignable= hb_is_copy_assignable<hb_trivial<T>>;
#define hb_is_trivially_copy_assignable(T) hb_is_trivially_copy_assignable<T>::value
template <typename T>
using hb_is_trivially_move_assignable= hb_is_move_assignable<hb_trivial<T>>;
#define hb_is_trivially_move_assignable(T) hb_is_trivially_move_assignable<T>::value
template <typename T>
using hb_is_trivially_copyable= hb_bool_constant<
hb_is_trivially_destructible (T) &&
(!hb_is_move_assignable (T) || hb_is_trivially_move_assignable (T)) &&
(!hb_is_move_constructible (T) || hb_is_trivially_move_constructible (T)) &&
(!hb_is_copy_assignable (T) || hb_is_trivially_copy_assignable (T)) &&
(!hb_is_copy_constructible (T) || hb_is_trivially_copy_constructible (T)) &&
true
>;
#define hb_is_trivially_copyable(T) hb_is_trivially_copyable<T>::value
template <typename T>
using hb_is_trivial= hb_bool_constant<
hb_is_trivially_copyable (T) &&
hb_is_trivially_default_constructible (T)
>;
#define hb_is_trivial(T) hb_is_trivial<T>::value
/* hb_unwrap_type (T) /* hb_unwrap_type (T)
* If T has no T::type, returns T. Otherwise calls itself on T::type recursively. * If T has no T::type, returns T. Otherwise calls itself on T::type recursively.
*/ */

View File

@ -47,7 +47,7 @@
/* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */ /* Defined externally, i.e. in config.h; must have typedef'ed hb_mutex_impl_t as well. */
#elif !defined(HB_NO_MT) && (defined(HAVE_PTHREAD) || defined(__APPLE__)) #elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && (defined(HAVE_PTHREAD) || defined(__APPLE__))
#include <pthread.h> #include <pthread.h>
typedef pthread_mutex_t hb_mutex_impl_t; typedef pthread_mutex_t hb_mutex_impl_t;
@ -57,7 +57,7 @@ typedef pthread_mutex_t hb_mutex_impl_t;
#define hb_mutex_impl_finish(M) pthread_mutex_destroy (M) #define hb_mutex_impl_finish(M) pthread_mutex_destroy (M)
#elif !defined(HB_NO_MT) && defined(_WIN32) #elif !defined(HB_NO_MT) && !defined(HB_MUTEX_IMPL_STD_MUTEX) && defined(_WIN32)
typedef CRITICAL_SECTION hb_mutex_impl_t; typedef CRITICAL_SECTION hb_mutex_impl_t;
#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
@ -70,7 +70,17 @@ typedef CRITICAL_SECTION hb_mutex_impl_t;
#define hb_mutex_impl_finish(M) DeleteCriticalSection (M) #define hb_mutex_impl_finish(M) DeleteCriticalSection (M)
#elif defined(HB_NO_MT) #elif !defined(HB_NO_MT)
#include <mutex>
typedef std::mutex hb_mutex_impl_t;
#define hb_mutex_impl_init(M) HB_STMT_START { new (M) hb_mutex_impl_t; } HB_STMT_END
#define hb_mutex_impl_lock(M) (M)->lock ()
#define hb_mutex_impl_unlock(M) (M)->unlock ()
#define hb_mutex_impl_finish(M) HB_STMT_START { (M)->~hb_mutex_impl_t(); } HB_STMT_END
#else /* defined(HB_NO_MT) */
typedef int hb_mutex_impl_t; typedef int hb_mutex_impl_t;
#define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END #define hb_mutex_impl_init(M) HB_STMT_START {} HB_STMT_END
@ -79,22 +89,21 @@ typedef int hb_mutex_impl_t;
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END #define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END
#else
#error "Could not find any system to define mutex macros."
#error "Check hb-mutex.hh for possible resolutions."
#endif #endif
struct hb_mutex_t struct hb_mutex_t
{ {
hb_mutex_impl_t m; /* Create space for, but do not initialize m. */
alignas(hb_mutex_impl_t) char m[sizeof (hb_mutex_impl_t)];
void init () { hb_mutex_impl_init (&m); } #pragma GCC diagnostic push
void lock () { hb_mutex_impl_lock (&m); } #pragma GCC diagnostic ignored "-Wcast-align"
void unlock () { hb_mutex_impl_unlock (&m); } void init () { hb_mutex_impl_init ((hb_mutex_impl_t *) m); }
void fini () { hb_mutex_impl_finish (&m); } void lock () { hb_mutex_impl_lock ((hb_mutex_impl_t *) m); }
void unlock () { hb_mutex_impl_unlock ((hb_mutex_impl_t *) m); }
void fini () { hb_mutex_impl_finish ((hb_mutex_impl_t *) m); }
#pragma GCC diagnostic pop
}; };
struct hb_lock_t struct hb_lock_t

View File

@ -64,7 +64,7 @@ struct IntType
IntType& operator = (Type i) { v = i; return *this; } IntType& operator = (Type i) { v = i; return *this; }
/* For reason we define cast out operator for signed/unsigned, instead of Type, see: /* For reason we define cast out operator for signed/unsigned, instead of Type, see:
* https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */ * https://github.com/harfbuzz/harfbuzz/pull/2875/commits/09836013995cab2b9f07577a179ad7b024130467 */
operator hb_conditional<hb_is_signed (Type), signed, unsigned> () const { return v; } operator typename std::conditional<std::is_signed<Type>::value, signed, unsigned>::type () const { return v; }
bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; } bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
bool operator != (const IntType &o) const { return !(*this == o); } bool operator != (const IntType &o) const { return !(*this == o); }
@ -86,7 +86,7 @@ struct IntType
return pb->cmp (*pa); return pb->cmp (*pa);
} }
template <typename Type2, template <typename Type2,
hb_enable_if (hb_is_integral (Type2) && hb_enable_if (std::is_integral<Type2>::value &&
sizeof (Type2) < sizeof (int) && sizeof (Type2) < sizeof (int) &&
sizeof (Type) < sizeof (int))> sizeof (Type) < sizeof (int))>
int cmp (Type2 a) const int cmp (Type2 a) const
@ -122,6 +122,15 @@ typedef IntType<int32_t> HBINT32; /* 32-bit signed integer. */
* Works for unsigned, but not signed, since we rely on compiler for sign-extension. */ * Works for unsigned, but not signed, since we rely on compiler for sign-extension. */
typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */ typedef IntType<uint32_t, 3> HBUINT24; /* 24-bit unsigned integer. */
/* 15-bit unsigned number; top bit used for extension. */
struct HBUINT15 : HBUINT16
{
/* TODO Flesh out; actually mask top bit. */
HBUINT15& operator = (uint16_t i ) { HBUINT16::operator= (i); return *this; }
public:
DEFINE_SIZE_STATIC (2);
};
/* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */ /* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
typedef HBINT16 FWORD; typedef HBINT16 FWORD;
@ -182,9 +191,9 @@ struct Tag : HBUINT32
}; };
/* Glyph index number, same as uint16 (length = 16 bits) */ /* Glyph index number, same as uint16 (length = 16 bits) */
struct HBGlyphID : HBUINT16 struct HBGlyphID16 : HBUINT16
{ {
HBGlyphID& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; } HBGlyphID16& operator = (uint16_t i) { HBUINT16::operator= (i); return *this; }
}; };
/* Script/language-system/feature index */ /* Script/language-system/feature index */
@ -332,7 +341,7 @@ struct OffsetTo : Offset<OffsetType, has_null>
s->push (); s->push ();
bool ret = c->dispatch (src_base+src, hb_forward<Ts> (ds)...); bool ret = c->dispatch (src_base+src, std::forward<Ts> (ds)...);
if (ret || !has_null) if (ret || !has_null)
s->add_link (*this, s->pop_pack ()); s->add_link (*this, s->pop_pack ());
@ -349,7 +358,7 @@ struct OffsetTo : Offset<OffsetType, has_null>
*this = 0; *this = 0;
Type* obj = c->push<Type> (); Type* obj = c->push<Type> ();
bool ret = obj->serialize (c, hb_forward<Ts> (ds)...); bool ret = obj->serialize (c, std::forward<Ts> (ds)...);
if (ret) if (ret)
c->add_link (*this, c->pop_pack ()); c->add_link (*this, c->pop_pack ());
@ -375,7 +384,7 @@ struct OffsetTo : Offset<OffsetType, has_null>
c->push (); c->push ();
bool ret = c->copy (src_base+src, hb_forward<Ts> (ds)...); bool ret = c->copy (src_base+src, std::forward<Ts> (ds)...);
c->add_link (*this, c->pop_pack (), whence, dst_bias); c->add_link (*this, c->pop_pack (), whence, dst_bias);
@ -401,7 +410,7 @@ struct OffsetTo : Offset<OffsetType, has_null>
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (sanitize_shallow (c, base) && return_trace (sanitize_shallow (c, base) &&
(this->is_null () || (this->is_null () ||
c->dispatch (StructAtOffset<Type> (base, *this), hb_forward<Ts> (ds)...) || c->dispatch (StructAtOffset<Type> (base, *this), std::forward<Ts> (ds)...) ||
neuter (c))); neuter (c)));
} }
@ -509,9 +518,9 @@ struct UnsizedArrayOf
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c, count))) return_trace (false); if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...))) if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
return_trace (false); return_trace (false);
return_trace (true); return_trace (true);
} }
@ -556,7 +565,7 @@ struct UnsizedListOfOffset16To : UnsizedArray16OfOffsetTo<Type, OffsetType, has_
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace ((UnsizedArray16OfOffsetTo<Type, OffsetType, has_null> return_trace ((UnsizedArray16OfOffsetTo<Type, OffsetType, has_null>
::sanitize (c, count, this, hb_forward<Ts> (ds)...))); ::sanitize (c, count, this, std::forward<Ts> (ds)...)));
} }
}; };
@ -698,10 +707,10 @@ struct ArrayOf
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false); if (unlikely (!sanitize_shallow (c))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
unsigned int count = len; unsigned int count = len;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...))) if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
return_trace (false); return_trace (false);
return_trace (true); return_trace (true);
} }
@ -759,7 +768,7 @@ 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, hb_forward<Ts> (ds)...)); return_trace (Array16OfOffset16To<Type>::sanitize (c, this, std::forward<Ts> (ds)...));
} }
}; };
@ -826,10 +835,10 @@ struct HeadlessArrayOf
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false); if (unlikely (!sanitize_shallow (c))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
unsigned int count = get_length (); unsigned int count = get_length ();
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...))) if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
return_trace (false); return_trace (false);
return_trace (true); return_trace (true);
} }
@ -875,10 +884,10 @@ struct ArrayOfM1
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false); if (unlikely (!sanitize_shallow (c))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
unsigned int count = lenM1 + 1; unsigned int count = lenM1 + 1;
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...))) if (unlikely (!c->dispatch (arrayZ[i], std::forward<Ts> (ds)...)))
return_trace (false); return_trace (false);
return_trace (true); return_trace (true);
} }
@ -1061,10 +1070,10 @@ struct VarSizedBinSearchArrayOf
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false); if (unlikely (!sanitize_shallow (c))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true); if (!sizeof... (Ts) && std::is_trivially_copyable<Type>::value) return_trace (true);
unsigned int count = get_length (); unsigned int count = get_length ();
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (unlikely (!(*this)[i].sanitize (c, hb_forward<Ts> (ds)...))) if (unlikely (!(*this)[i].sanitize (c, std::forward<Ts> (ds)...)))
return_trace (false); return_trace (false);
return_trace (true); return_trace (true);
} }

View File

@ -373,7 +373,7 @@ struct Dict : UnsizedByteStr
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
for (unsigned int i = 0; i < dictval.get_count (); i++) for (unsigned int i = 0; i < dictval.get_count (); i++)
if (unlikely (!opszr.serialize (c, dictval[i], hb_forward<Ts> (ds)...))) if (unlikely (!opszr.serialize (c, dictval[i], std::forward<Ts> (ds)...)))
return_trace (false); return_trace (false);
return_trace (true); return_trace (true);

View File

@ -604,7 +604,7 @@ struct CmapSubtableTrimmed
UINT length; /* Byte length of this subtable. */ UINT length; /* Byte length of this subtable. */
UINT language; /* Ignore. */ UINT language; /* Ignore. */
UINT startCharCode; /* First character code covered. */ UINT startCharCode; /* First character code covered. */
ArrayOf<HBGlyphID, UINT> ArrayOf<HBGlyphID16, UINT>
glyphIdArray; /* Array of glyph index values for character glyphIdArray; /* Array of glyph index values for character
* codes in the range. */ * codes in the range. */
public: public:
@ -900,7 +900,7 @@ struct UVSMapping
} }
HBUINT24 unicodeValue; /* Base Unicode value of the UVS */ HBUINT24 unicodeValue; /* Base Unicode value of the UVS */
HBGlyphID glyphID; /* Glyph ID of the UVS */ HBGlyphID16 glyphID; /* Glyph ID of the UVS */
public: public:
DEFINE_SIZE_STATIC (5); DEFINE_SIZE_STATIC (5);
}; };

View File

@ -508,8 +508,8 @@ struct IndexSubtableRecord
offset, length, format); offset, length, format);
} }
HBGlyphID firstGlyphIndex; HBGlyphID16 firstGlyphIndex;
HBGlyphID lastGlyphIndex; HBGlyphID16 lastGlyphIndex;
Offset32To<IndexSubtable> offsetToSubtable; Offset32To<IndexSubtable> offsetToSubtable;
public: public:
DEFINE_SIZE_STATIC (8); DEFINE_SIZE_STATIC (8);
@ -679,8 +679,8 @@ struct BitmapSizeTable
HBUINT32 colorRef; HBUINT32 colorRef;
SBitLineMetrics horizontal; SBitLineMetrics horizontal;
SBitLineMetrics vertical; SBitLineMetrics vertical;
HBGlyphID startGlyphIndex; HBGlyphID16 startGlyphIndex;
HBGlyphID endGlyphIndex; HBGlyphID16 endGlyphIndex;
HBUINT8 ppemX; HBUINT8 ppemX;
HBUINT8 ppemY; HBUINT8 ppemY;
HBUINT8 bitDepth; HBUINT8 bitDepth;

File diff suppressed because it is too large Load Diff

View File

@ -40,7 +40,7 @@ namespace OT {
HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const
{ {
c->add_layer_indices (firstLayerIndex, numLayers); c->add_layer_indices (firstLayerIndex, numLayers);
const LayerV1List &paint_offset_lists = c->get_colr_table ()->get_layerV1List (); const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++) for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
{ {
const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i]; const Paint &paint = hb_addressof (paint_offset_lists) + paint_offset_lists[i];
@ -57,37 +57,44 @@ HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
{ {
const COLR *colr_table = c->get_colr_table (); const COLR *colr_table = c->get_colr_table ();
const BaseGlyphV1Record* baseglyphV1_record = colr_table->get_base_glyphV1_record (gid); const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid);
if (!baseglyphV1_record) return; if (!baseglyph_paintrecord) return;
c->add_glyph (gid); c->add_glyph (gid);
const BaseGlyphV1List &baseglyphV1_list = colr_table->get_baseglyphV1List (); const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList ();
(&baseglyphV1_list+baseglyphV1_record->paint).dispatch (c); (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c);
} }
template <template<typename> class Var> template <template<typename> class Var>
HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
{ { (this+src).dispatch (c); }
(this+src).dispatch (c);
}
template <template<typename> class Var> HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const
HB_INTERNAL void PaintTranslate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const { (this+src).dispatch (c); }
{
(this+src).dispatch (c);
}
template <template<typename> class Var> HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const
HB_INTERNAL void PaintRotate<Var>::closurev1 (hb_colrv1_closure_context_t* c) const { (this+src).dispatch (c); }
{
(this+src).dispatch (c);
}
template <template<typename> class Var> HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
HB_INTERNAL void PaintSkew<Var>::closurev1 (hb_colrv1_closure_context_t* c) const { (this+src).dispatch (c); }
{
(this+src).dispatch (c); HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const
} { (this+src).dispatch (c); }
HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+src).dispatch (c); }
HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+src).dispatch (c); }
HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+src).dispatch (c); }
HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+src).dispatch (c); }
HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
{ (this+src).dispatch (c); }
HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
{ {

View File

@ -388,7 +388,7 @@ struct glyf
protected: protected:
HBUINT16 flags; HBUINT16 flags;
HBGlyphID glyphIndex; HBGlyphID16 glyphIndex;
public: public:
DEFINE_SIZE_MIN (4); DEFINE_SIZE_MIN (4);
}; };
@ -1118,7 +1118,7 @@ struct glyf
while (it) while (it)
{ {
auto item = *(it++); auto item = *(it++);
operation_count += operation_count =
add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth, operation_count); add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth, operation_count);
} }

View File

@ -72,12 +72,14 @@ struct head
UNDERLINE = 1u<<2, UNDERLINE = 1u<<2,
OUTLINE = 1u<<3, OUTLINE = 1u<<3,
SHADOW = 1u<<4, SHADOW = 1u<<4,
CONDENSED = 1u<<5 CONDENSED = 1u<<5,
EXPANDED = 1u<<6,
}; };
bool is_bold () const { return macStyle & BOLD; } bool is_bold () const { return macStyle & BOLD; }
bool is_italic () const { return macStyle & ITALIC; } bool is_italic () const { return macStyle & ITALIC; }
bool is_condensed () const { return macStyle & CONDENSED; } bool is_condensed () const { return macStyle & CONDENSED; }
bool is_expanded () const { return macStyle & EXPANDED; }
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {

View File

@ -134,11 +134,11 @@ struct KernSubTable
switch (subtable_type) { switch (subtable_type) {
case 0: return_trace (c->dispatch (u.format0)); case 0: return_trace (c->dispatch (u.format0));
#ifndef HB_NO_AAT_SHAPE #ifndef HB_NO_AAT_SHAPE
case 1: return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ()); case 1: return_trace (u.header.apple ? c->dispatch (u.format1, std::forward<Ts> (ds)...) : c->default_return_value ());
#endif #endif
case 2: return_trace (c->dispatch (u.format2)); case 2: return_trace (c->dispatch (u.format2));
#ifndef HB_NO_AAT_SHAPE #ifndef HB_NO_AAT_SHAPE
case 3: return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ()); case 3: return_trace (u.header.apple ? c->dispatch (u.format3, std::forward<Ts> (ds)...) : c->default_return_value ());
#endif #endif
default: return_trace (c->default_return_value ()); default: return_trace (c->default_return_value ());
} }
@ -325,9 +325,9 @@ struct kern
unsigned int subtable_type = get_type (); unsigned int subtable_type = get_type ();
TRACE_DISPATCH (this, subtable_type); TRACE_DISPATCH (this, subtable_type);
switch (subtable_type) { switch (subtable_type) {
case 0: return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...)); case 0: return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
#ifndef HB_NO_AAT_SHAPE #ifndef HB_NO_AAT_SHAPE
case 1: return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
#endif #endif
default: return_trace (c->default_return_value ()); default: return_trace (c->default_return_value ());
} }

View File

@ -73,7 +73,7 @@ struct BaseCoordFormat2
protected: protected:
HBUINT16 format; /* Format identifier--format = 2 */ HBUINT16 format; /* Format identifier--format = 2 */
FWORD coordinate; /* X or Y value, in design units */ FWORD coordinate; /* X or Y value, in design units */
HBGlyphID referenceGlyph; /* Glyph ID of control glyph */ HBGlyphID16 referenceGlyph; /* Glyph ID of control glyph */
HBUINT16 coordPoint; /* Index of contour point on the HBUINT16 coordPoint; /* Index of contour point on the
* reference glyph */ * reference glyph */
public: public:

View File

@ -89,7 +89,7 @@ static inline void ClassDef_serialize (hb_serialize_context_t *c,
static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
const hb_map_t &gid_klass_map, const hb_map_t &gid_klass_map,
hb_sorted_vector_t<HBGlyphID> &glyphs, hb_sorted_vector_t<HBGlyphID16> &glyphs,
const hb_set_t &klasses, const hb_set_t &klasses,
bool use_class_zero, bool use_class_zero,
hb_map_t *klass_map /*INOUT*/); hb_map_t *klass_map /*INOUT*/);
@ -237,9 +237,9 @@ struct subset_offset_array_t
template <typename T> template <typename T>
bool operator () (T&& offset) bool operator () (T&& offset)
{ {
auto snap = subset_context->serializer->snapshot ();
auto *o = out.serialize_append (subset_context->serializer); auto *o = out.serialize_append (subset_context->serializer);
if (unlikely (!o)) return false; if (unlikely (!o)) return false;
auto snap = subset_context->serializer->snapshot ();
bool ret = o->serialize_subset (subset_context, offset, base); bool ret = o->serialize_subset (subset_context, offset, base);
if (!ret) if (!ret)
{ {
@ -268,9 +268,9 @@ struct subset_offset_array_arg_t
template <typename T> template <typename T>
bool operator () (T&& offset) bool operator () (T&& offset)
{ {
auto snap = subset_context->serializer->snapshot ();
auto *o = out.serialize_append (subset_context->serializer); auto *o = out.serialize_append (subset_context->serializer);
if (unlikely (!o)) return false; if (unlikely (!o)) return false;
auto snap = subset_context->serializer->snapshot ();
bool ret = o->serialize_subset (subset_context, offset, base, arg); bool ret = o->serialize_subset (subset_context, offset, base, arg);
if (!ret) if (!ret)
{ {
@ -346,6 +346,43 @@ struct
} }
HB_FUNCOBJ (subset_record_array); HB_FUNCOBJ (subset_record_array);
template<typename OutputArray>
struct serialize_math_record_array_t
{
serialize_math_record_array_t (hb_serialize_context_t *serialize_context_,
OutputArray& out_,
const void *base_) : serialize_context (serialize_context_),
out (out_), base (base_) {}
template <typename T>
bool operator () (T&& record)
{
if (!serialize_context->copy (record, base)) return false;
out.len++;
return true;
}
private:
hb_serialize_context_t *serialize_context;
OutputArray &out;
const void *base;
};
/*
* Helper to serialize an array of MATH records.
*/
struct
{
template<typename OutputArray>
serialize_math_record_array_t<OutputArray>
operator () (hb_serialize_context_t *serialize_context, OutputArray& out,
const void *base) const
{ return serialize_math_record_array_t<OutputArray> (serialize_context, out, base); }
}
HB_FUNCOBJ (serialize_math_record_array);
/* /*
* *
* OpenType Layout Common Table Formats * OpenType Layout Common Table Formats
@ -508,8 +545,8 @@ 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); }
HBGlyphID first; /* First GlyphID in the range */ HBGlyphID16 first; /* First GlyphID in the range */
HBGlyphID last; /* Last GlyphID in the range */ HBGlyphID16 last; /* Last GlyphID in the range */
HBUINT16 value; /* Value */ HBUINT16 value; /* Value */
public: public:
DEFINE_SIZE_STATIC (6); DEFINE_SIZE_STATIC (6);
@ -1249,7 +1286,7 @@ struct Lookup
TRACE_DISPATCH (this, lookup_type); TRACE_DISPATCH (this, lookup_type);
unsigned int count = get_subtable_count (); unsigned int count = get_subtable_count ();
for (unsigned int i = 0; i < count; i++) { for (unsigned int i = 0; i < count; i++) {
typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, hb_forward<Ts> (ds)...); typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type, std::forward<Ts> (ds)...);
if (c->stop_sublookup_iteration (r)) if (c->stop_sublookup_iteration (r))
return_trace (r); return_trace (r);
} }
@ -1299,7 +1336,7 @@ struct Lookup
outMarkFilteringSet = markFilteringSet; outMarkFilteringSet = markFilteringSet;
} }
return_trace (true); return_trace (out->subTable.len);
} }
template <typename TSubTable> template <typename TSubTable>
@ -1454,7 +1491,7 @@ struct CoverageFormat1
protected: protected:
HBUINT16 coverageFormat; /* Format identifier--format = 1 */ HBUINT16 coverageFormat; /* Format identifier--format = 1 */
SortedArray16Of<HBGlyphID> SortedArray16Of<HBGlyphID16>
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);
@ -1832,7 +1869,7 @@ Coverage_serialize (hb_serialize_context_t *c,
static void ClassDef_remap_and_serialize (hb_serialize_context_t *c, static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
const hb_map_t &gid_klass_map, const hb_map_t &gid_klass_map,
hb_sorted_vector_t<HBGlyphID> &glyphs, hb_sorted_vector_t<HBGlyphID16> &glyphs,
const hb_set_t &klasses, const hb_set_t &klasses,
bool use_class_zero, bool use_class_zero,
hb_map_t *klass_map /*INOUT*/) hb_map_t *klass_map /*INOUT*/)
@ -1859,7 +1896,7 @@ static void ClassDef_remap_and_serialize (hb_serialize_context_t *c,
auto it = auto it =
+ glyphs.iter () + glyphs.iter ()
| hb_map_retains_sorting ([&] (const HBGlyphID& gid) -> hb_pair_t<hb_codepoint_t, unsigned> | hb_map_retains_sorting ([&] (const HBGlyphID16& gid) -> hb_pair_t<hb_codepoint_t, unsigned>
{ {
unsigned new_klass = klass_map->get (gid_klass_map[gid]); unsigned new_klass = klass_map->get (gid_klass_map[gid]);
return hb_pair ((hb_codepoint_t)gid, new_klass); return hb_pair ((hb_codepoint_t)gid, new_klass);
@ -1926,7 +1963,7 @@ struct ClassDefFormat1
const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map; const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_sorted_vector_t<HBGlyphID> glyphs; hb_sorted_vector_t<HBGlyphID16> glyphs;
hb_set_t orig_klasses; hb_set_t orig_klasses;
hb_map_t gid_org_klass_map; hb_map_t gid_org_klass_map;
@ -2044,9 +2081,25 @@ struct ClassDefFormat1
intersect_glyphs->add (startGlyph + i); intersect_glyphs->add (startGlyph + i);
} }
void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
{
if (glyphs->is_empty ()) return;
hb_codepoint_t end_glyph = startGlyph + classValue.len - 1;
if (glyphs->get_min () < startGlyph ||
glyphs->get_max () > end_glyph)
intersect_classes->add (0);
for (const auto& _ : + hb_enumerate (classValue))
{
hb_codepoint_t g = startGlyph + _.first;
if (glyphs->has (g))
intersect_classes->add (_.second);
}
}
protected: protected:
HBUINT16 classFormat; /* Format identifier--format = 1 */ HBUINT16 classFormat; /* Format identifier--format = 1 */
HBGlyphID startGlyph; /* First GlyphID of the classValueArray */ HBGlyphID16 startGlyph; /* First GlyphID of the classValueArray */
Array16Of<HBUINT16> Array16Of<HBUINT16>
classValue; /* Array of Class Values--one per GlyphID */ classValue; /* Array of Class Values--one per GlyphID */
public: public:
@ -2128,7 +2181,7 @@ struct ClassDefFormat2
const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map; const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_sorted_vector_t<HBGlyphID> glyphs; hb_sorted_vector_t<HBGlyphID16> glyphs;
hb_set_t orig_klasses; hb_set_t orig_klasses;
hb_map_t gid_org_klass_map; hb_map_t gid_org_klass_map;
@ -2277,6 +2330,31 @@ struct ClassDefFormat2
} }
} }
void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
{
if (glyphs->is_empty ()) return;
unsigned count = rangeRecord.len;
hb_codepoint_t g = HB_SET_VALUE_INVALID;
for (unsigned int i = 0; i < count; i++)
{
if (!hb_set_next (glyphs, &g))
break;
if (g < rangeRecord[i].first)
{
intersect_classes->add (0);
break;
}
g = rangeRecord[i].last;
}
if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
intersect_classes->add (0);
for (const RangeRecord& record : rangeRecord.iter ())
if (record.intersects (glyphs))
intersect_classes->add (record.value);
}
protected: protected:
HBUINT16 classFormat; /* Format identifier--format = 2 */ HBUINT16 classFormat; /* Format identifier--format = 2 */
SortedArray16Of<RangeRecord> SortedArray16Of<RangeRecord>
@ -2429,6 +2507,16 @@ struct ClassDef
} }
} }
void intersected_classes (const hb_set_t *glyphs, hb_set_t *intersect_classes) const
{
switch (u.format) {
case 1: return u.format1.intersected_classes (glyphs, intersect_classes);
case 2: return u.format2.intersected_classes (glyphs, intersect_classes);
default:return;
}
}
protected: protected:
union { union {
HBUINT16 format; /* Format identifier */ HBUINT16 format; /* Format identifier */
@ -2543,7 +2631,7 @@ struct VarRegionList
public: public:
HBUINT16 axisCount; HBUINT16 axisCount;
HBUINT16 regionCount; HBUINT15 regionCount;
protected: protected:
UnsizedArrayOf<VarRegionAxis> UnsizedArrayOf<VarRegionAxis>
axesZ; axesZ;
@ -2947,7 +3035,7 @@ struct Condition
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }

View File

@ -84,7 +84,7 @@ struct AttachList
bool subset (hb_subset_context_t *c) const bool subset (hb_subset_context_t *c) const
{ {
TRACE_SUBSET (this); TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset (); const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map; const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this); auto *out = c->serializer->start_embed (*this);
@ -248,9 +248,9 @@ struct CaretValue
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -371,7 +371,7 @@ struct LigCaretList
bool subset (hb_subset_context_t *c) const bool subset (hb_subset_context_t *c) const
{ {
TRACE_SUBSET (this); TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset (); const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map; const hb_map_t &glyph_map = *c->plan->glyph_map;
auto *out = c->serializer->start_embed (*this); auto *out = c->serializer->start_embed (*this);

View File

@ -1050,8 +1050,8 @@ struct SinglePos
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -1144,7 +1144,7 @@ struct PairValueRecord
} }
protected: protected:
HBGlyphID secondGlyph; /* GlyphID of second glyph in the HBGlyphID16 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
@ -1220,9 +1220,9 @@ struct PairSet
record_size); record_size);
if (record) if (record)
{ {
/* Note the intentional use of "|" instead of short-circuit "||". */ bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
if (valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos()) | bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos])) if (applied_first || applied_second)
buffer->unsafe_to_break (buffer->idx, pos + 1); buffer->unsafe_to_break (buffer->idx, pos + 1);
if (len2) if (len2)
pos++; pos++;
@ -1386,9 +1386,9 @@ struct PairPosFormat1
| hb_filter (glyphset, hb_first) | hb_filter (glyphset, hb_first)
| hb_filter ([this, c, out] (const Offset16To<PairSet>& _) | hb_filter ([this, c, out] (const Offset16To<PairSet>& _)
{ {
auto snap = c->serializer->snapshot ();
auto *o = out->pairSet.serialize_append (c->serializer); auto *o = out->pairSet.serialize_append (c->serializer);
if (unlikely (!o)) return false; if (unlikely (!o)) return false;
auto snap = c->serializer->snapshot ();
bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat); bool ret = o->serialize_subset (c, _, this, valueFormat, out->valueFormat);
if (!ret) if (!ret)
{ {
@ -1560,9 +1560,9 @@ struct PairPosFormat2
if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false); if (unlikely (klass1 >= class1Count || klass2 >= class2Count)) return_trace (false);
const Value *v = &values[record_len * (klass1 * class2Count + klass2)]; const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
/* Note the intentional use of "|" instead of short-circuit "||". */ bool applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
if (valueFormat1.apply_value (c, this, v, buffer->cur_pos()) | bool applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx])) if (applied_first || applied_second)
buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1); buffer->unsafe_to_break (buffer->idx, skippy_iter.idx + 1);
buffer->idx = skippy_iter.idx; buffer->idx = skippy_iter.idx;
@ -1702,8 +1702,8 @@ struct PairPos
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -1959,7 +1959,7 @@ struct CursivePos
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -2194,7 +2194,7 @@ struct MarkBasePos
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -2434,7 +2434,7 @@ struct MarkLigPos
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -2653,7 +2653,7 @@ struct MarkMarkPos
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -2704,15 +2704,15 @@ struct PosLookupSubTable
{ {
TRACE_DISPATCH (this, lookup_type); TRACE_DISPATCH (this, lookup_type);
switch (lookup_type) { switch (lookup_type) {
case Single: return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...)); case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
case Pair: return_trace (u.pair.dispatch (c, hb_forward<Ts> (ds)...)); case Pair: return_trace (u.pair.dispatch (c, std::forward<Ts> (ds)...));
case Cursive: return_trace (u.cursive.dispatch (c, hb_forward<Ts> (ds)...)); case Cursive: return_trace (u.cursive.dispatch (c, std::forward<Ts> (ds)...));
case MarkBase: return_trace (u.markBase.dispatch (c, hb_forward<Ts> (ds)...)); case MarkBase: return_trace (u.markBase.dispatch (c, std::forward<Ts> (ds)...));
case MarkLig: return_trace (u.markLig.dispatch (c, hb_forward<Ts> (ds)...)); case MarkLig: return_trace (u.markLig.dispatch (c, std::forward<Ts> (ds)...));
case MarkMark: return_trace (u.markMark.dispatch (c, hb_forward<Ts> (ds)...)); case MarkMark: return_trace (u.markMark.dispatch (c, std::forward<Ts> (ds)...));
case Context: return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...)); case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
case ChainContext: return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...)); case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
case Extension: return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...)); case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
default: return_trace (c->default_return_value ()); default: return_trace (c->default_return_value ());
} }
} }
@ -2800,7 +2800,7 @@ struct PosLookup : Lookup
template <typename context_t, typename ...Ts> template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{ return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); } { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
bool subset (hb_subset_context_t *c) const bool subset (hb_subset_context_t *c) const
{ return Lookup::subset<SubTable> (c); } { return Lookup::subset<SubTable> (c); }

View File

@ -225,7 +225,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 HBGlyphID &> p) -> hb_codepoint_pair_t | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> 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]); })
; ;
@ -245,7 +245,7 @@ struct SingleSubstFormat2
Offset16To<Coverage> Offset16To<Coverage>
coverage; /* Offset to Coverage table--from coverage; /* Offset to Coverage table--from
* beginning of Substitution table */ * beginning of Substitution table */
Array16Of<HBGlyphID> Array16Of<HBGlyphID16>
substitute; /* Array of substitute substitute; /* Array of substitute
* GlyphIDs--ordered by Coverage Index */ * GlyphIDs--ordered by Coverage Index */
public: public:
@ -290,8 +290,8 @@ struct SingleSubst
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -391,7 +391,7 @@ struct Sequence
} }
protected: protected:
Array16Of<HBGlyphID> Array16Of<HBGlyphID16>
substitute; /* String of GlyphIDs to substitute */ substitute; /* String of GlyphIDs to substitute */
public: public:
DEFINE_SIZE_ARRAY (2, substitute); DEFINE_SIZE_ARRAY (2, substitute);
@ -443,9 +443,9 @@ struct MultipleSubstFormat1
} }
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> substitute_glyphs_list) hb_array_t<const HBGlyphID16> substitute_glyphs_list)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!c->extend_min (this))) return_trace (false);
@ -504,9 +504,9 @@ struct MultipleSubstFormat1
struct MultipleSubst struct MultipleSubst
{ {
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> substitute_glyphs_list) hb_array_t<const HBGlyphID16> substitute_glyphs_list)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return_trace (false); if (unlikely (!c->extend_min (u.format))) return_trace (false);
@ -524,7 +524,7 @@ struct MultipleSubst
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -624,7 +624,7 @@ struct AlternateSet
} }
protected: protected:
Array16Of<HBGlyphID> Array16Of<HBGlyphID16>
alternates; /* Array of alternate GlyphIDs--in alternates; /* Array of alternate GlyphIDs--in
* arbitrary order */ * arbitrary order */
public: public:
@ -686,9 +686,9 @@ struct AlternateSubstFormat1
} }
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> alternate_glyphs_list) hb_array_t<const HBGlyphID16> alternate_glyphs_list)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!c->extend_min (this))) return_trace (false);
@ -747,9 +747,9 @@ struct AlternateSubstFormat1
struct AlternateSubst struct AlternateSubst
{ {
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> alternate_glyphs_list) hb_array_t<const HBGlyphID16> alternate_glyphs_list)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return_trace (false); if (unlikely (!c->extend_min (u.format))) return_trace (false);
@ -767,7 +767,7 @@ struct AlternateSubst
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -861,13 +861,15 @@ struct Ligature
return_trace (true); return_trace (true);
} }
bool subset (hb_subset_context_t *c) const bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
{ {
TRACE_SUBSET (this); TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->glyphset_gsub (); const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
const hb_map_t &glyph_map = *c->plan->glyph_map; const hb_map_t &glyph_map = *c->plan->glyph_map;
if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false); if (!intersects (&glyphset) || !glyphset.has (ligGlyph)) return_trace (false);
// Ensure Coverage table is always packed after this.
c->serializer->add_virtual_link (coverage_idx);
auto it = auto it =
+ hb_iter (component) + hb_iter (component)
@ -888,8 +890,8 @@ struct Ligature
} }
protected: protected:
HBGlyphID ligGlyph; /* GlyphID of ligature to substitute */ HBGlyphID16 ligGlyph; /* GlyphID of ligature to substitute */
HeadlessArrayOf<HBGlyphID> HeadlessArrayOf<HBGlyphID16>
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 */
@ -949,9 +951,9 @@ struct LigatureSet
} }
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
hb_array_t<const HBGlyphID> ligatures, hb_array_t<const HBGlyphID16> ligatures,
hb_array_t<const unsigned int> component_count_list, hb_array_t<const unsigned int> component_count_list,
hb_array_t<const HBGlyphID> &component_list /* Starting from second for each ligature */) hb_array_t<const HBGlyphID16> &component_list /* Starting from second for each ligature */)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!c->extend_min (this))) return_trace (false);
@ -968,16 +970,21 @@ struct LigatureSet
return_trace (true); return_trace (true);
} }
bool subset (hb_subset_context_t *c) const bool subset (hb_subset_context_t *c, unsigned coverage_idx) const
{ {
TRACE_SUBSET (this); TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this); auto *out = c->serializer->start_embed (*this);
if (unlikely (!c->serializer->extend_min (out))) return_trace (false); if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+ hb_iter (ligature) + hb_iter (ligature)
| hb_filter (subset_offset_array (c, out->ligature, this)) | hb_filter (subset_offset_array (c, out->ligature, this, coverage_idx))
| hb_drain | hb_drain
; ;
if (bool (out->ligature))
// Ensure Coverage table is always packed after this.
c->serializer->add_virtual_link (coverage_idx);
return_trace (bool (out->ligature)); return_trace (bool (out->ligature));
} }
@ -1059,11 +1066,11 @@ struct LigatureSubstFormat1
} }
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> ligatures_list, hb_array_t<const HBGlyphID16> ligatures_list,
hb_array_t<const unsigned int> component_count_list, hb_array_t<const unsigned int> component_count_list,
hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */) hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false); if (unlikely (!c->extend_min (this))) return_trace (false);
@ -1092,15 +1099,38 @@ struct LigatureSubstFormat1
if (unlikely (!c->serializer->extend_min (out))) return_trace (false); if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
out->format = format; out->format = format;
hb_sorted_vector_t<hb_codepoint_t> new_coverage; // Due to a bug in some older versions of windows 7 the Coverage table must be
+ hb_zip (this+coverage, ligatureSet) // packed after the LigatureSet and Ligature tables, so serialize Coverage first
// which places it last in the packed order.
hb_set_t new_coverage;
+ hb_zip (this+coverage, hb_iter (ligatureSet) | hb_map (hb_add (this)))
| hb_filter (glyphset, hb_first) | hb_filter (glyphset, hb_first)
| hb_filter (subset_offset_array (c, out->ligatureSet, this), hb_second) | hb_filter ([&] (const LigatureSet& _) {
return _.intersects (&glyphset);
}, hb_second)
| hb_map (hb_first) | hb_map (hb_first)
| hb_map (glyph_map) | hb_sink (new_coverage);
| hb_sink (new_coverage)
if (!c->serializer->push<Coverage> ()
->serialize (c->serializer,
+ new_coverage.iter () | hb_map_retains_sorting (glyph_map)))
{
c->serializer->pop_discard ();
return_trace (false);
}
unsigned coverage_idx = c->serializer->pop_pack ();
c->serializer->add_link (out->coverage, coverage_idx);
+ hb_zip (this+coverage, ligatureSet)
| hb_filter (new_coverage, hb_first)
| hb_map (hb_second)
// to ensure that the repacker always orders the coverage table after the LigatureSet
// and LigatureSubtable's they will be linked to the Coverage table via a virtual link
// the coverage table object idx is passed down to facilitate this.
| hb_apply (subset_offset_array (c, out->ligatureSet, this, coverage_idx))
; ;
out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
return_trace (bool (new_coverage)); return_trace (bool (new_coverage));
} }
@ -1125,11 +1155,11 @@ struct LigatureSubstFormat1
struct LigatureSubst struct LigatureSubst
{ {
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> ligatures_list, hb_array_t<const HBGlyphID16> ligatures_list,
hb_array_t<const unsigned int> component_count_list, hb_array_t<const unsigned int> component_count_list,
hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */) hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return_trace (false); if (unlikely (!c->extend_min (u.format))) return_trace (false);
@ -1152,7 +1182,7 @@ struct LigatureSubst
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -1208,7 +1238,7 @@ struct ReverseChainSingleSubstFormat1
if (!intersects (c->glyphs)) return; if (!intersects (c->glyphs)) return;
const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
+ hb_zip (this+coverage, substitute) + hb_zip (this+coverage, substitute)
| hb_filter (c->parent_active_glyphs (), hb_first) | hb_filter (c->parent_active_glyphs (), hb_first)
@ -1234,7 +1264,7 @@ struct ReverseChainSingleSubstFormat1
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return; if (unlikely (!(this+lookahead[i]).collect_coverage (c->after))) return;
const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
count = substitute.len; count = substitute.len;
c->output->add_array (substitute.arrayZ, substitute.len); c->output->add_array (substitute.arrayZ, substitute.len);
} }
@ -1254,7 +1284,7 @@ struct ReverseChainSingleSubstFormat1
if (likely (index == NOT_COVERED)) return_trace (false); if (likely (index == NOT_COVERED)) return_trace (false);
const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
if (unlikely (index >= substitute.len)) return_trace (false); if (unlikely (index >= substitute.len)) return_trace (false);
@ -1317,7 +1347,7 @@ struct ReverseChainSingleSubstFormat1
if (!serialize_coverage_offset_array (c, backtrack_iter)) return_trace (false); if (!serialize_coverage_offset_array (c, backtrack_iter)) return_trace (false);
if (!serialize_coverage_offset_array (c, lookahead_iter)) return_trace (false); if (!serialize_coverage_offset_array (c, lookahead_iter)) return_trace (false);
auto *substitute_out = c->serializer->start_embed<Array16Of<HBGlyphID>> (); auto *substitute_out = c->serializer->start_embed<Array16Of<HBGlyphID16>> ();
auto substitutes = auto substitutes =
+ coverage_subst_iter + coverage_subst_iter
| hb_map (hb_second) | hb_map (hb_second)
@ -1342,13 +1372,13 @@ struct ReverseChainSingleSubstFormat1
const hb_map_t &glyph_map = *c->plan->glyph_map; const hb_map_t &glyph_map = *c->plan->glyph_map;
const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
auto it = auto it =
+ 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 HBGlyphID &> p) -> hb_codepoint_pair_t | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const HBGlyphID16 &> 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]); })
; ;
@ -1363,7 +1393,7 @@ struct ReverseChainSingleSubstFormat1
const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack); const Array16OfOffset16To<Coverage> &lookahead = StructAfter<Array16OfOffset16To<Coverage>> (backtrack);
if (!lookahead.sanitize (c, this)) if (!lookahead.sanitize (c, this))
return_trace (false); return_trace (false);
const Array16Of<HBGlyphID> &substitute = StructAfter<Array16Of<HBGlyphID>> (lookahead); const Array16Of<HBGlyphID16> &substitute = StructAfter<Array16Of<HBGlyphID16>> (lookahead);
return_trace (substitute.sanitize (c)); return_trace (substitute.sanitize (c));
} }
@ -1380,7 +1410,7 @@ struct ReverseChainSingleSubstFormat1
lookaheadX; /* Array of coverage tables lookaheadX; /* Array of coverage tables
* in lookahead sequence, in glyph * in lookahead sequence, in glyph
* sequence order */ * sequence order */
Array16Of<HBGlyphID> Array16Of<HBGlyphID16>
substituteX; /* Array of substitute substituteX; /* Array of substitute
* GlyphIDs--ordered by Coverage Index */ * GlyphIDs--ordered by Coverage Index */
public: public:
@ -1395,7 +1425,7 @@ struct ReverseChainSingleSubst
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -1434,14 +1464,14 @@ struct SubstLookupSubTable
{ {
TRACE_DISPATCH (this, lookup_type); TRACE_DISPATCH (this, lookup_type);
switch (lookup_type) { switch (lookup_type) {
case Single: return_trace (u.single.dispatch (c, hb_forward<Ts> (ds)...)); case Single: return_trace (u.single.dispatch (c, std::forward<Ts> (ds)...));
case Multiple: return_trace (u.multiple.dispatch (c, hb_forward<Ts> (ds)...)); case Multiple: return_trace (u.multiple.dispatch (c, std::forward<Ts> (ds)...));
case Alternate: return_trace (u.alternate.dispatch (c, hb_forward<Ts> (ds)...)); case Alternate: return_trace (u.alternate.dispatch (c, std::forward<Ts> (ds)...));
case Ligature: return_trace (u.ligature.dispatch (c, hb_forward<Ts> (ds)...)); case Ligature: return_trace (u.ligature.dispatch (c, std::forward<Ts> (ds)...));
case Context: return_trace (u.context.dispatch (c, hb_forward<Ts> (ds)...)); case Context: return_trace (u.context.dispatch (c, std::forward<Ts> (ds)...));
case ChainContext: return_trace (u.chainContext.dispatch (c, hb_forward<Ts> (ds)...)); case ChainContext: return_trace (u.chainContext.dispatch (c, std::forward<Ts> (ds)...));
case Extension: return_trace (u.extension.dispatch (c, hb_forward<Ts> (ds)...)); case Extension: return_trace (u.extension.dispatch (c, std::forward<Ts> (ds)...));
case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c, hb_forward<Ts> (ds)...)); case ReverseChainSingle: return_trace (u.reverseChainContextSingle.dispatch (c, std::forward<Ts> (ds)...));
default: return_trace (c->default_return_value ()); default: return_trace (c->default_return_value ());
} }
} }
@ -1561,8 +1591,8 @@ struct SubstLookup : Lookup
bool serialize_single (hb_serialize_context_t *c, bool serialize_single (hb_serialize_context_t *c,
uint32_t lookup_props, uint32_t lookup_props,
hb_sorted_array_t<const HBGlyphID> glyphs, hb_sorted_array_t<const HBGlyphID16> glyphs,
hb_array_t<const HBGlyphID> substitutes) hb_array_t<const HBGlyphID16> substitutes)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false); if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
@ -1577,9 +1607,9 @@ struct SubstLookup : Lookup
bool serialize_multiple (hb_serialize_context_t *c, bool serialize_multiple (hb_serialize_context_t *c,
uint32_t lookup_props, uint32_t lookup_props,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> substitute_glyphs_list) hb_array_t<const HBGlyphID16> substitute_glyphs_list)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false); if (unlikely (!Lookup::serialize (c, SubTable::Multiple, lookup_props, 1))) return_trace (false);
@ -1598,9 +1628,9 @@ struct SubstLookup : Lookup
bool serialize_alternate (hb_serialize_context_t *c, bool serialize_alternate (hb_serialize_context_t *c,
uint32_t lookup_props, uint32_t lookup_props,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> alternate_glyphs_list) hb_array_t<const HBGlyphID16> alternate_glyphs_list)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false); if (unlikely (!Lookup::serialize (c, SubTable::Alternate, lookup_props, 1))) return_trace (false);
@ -1620,11 +1650,11 @@ struct SubstLookup : Lookup
bool serialize_ligature (hb_serialize_context_t *c, bool serialize_ligature (hb_serialize_context_t *c,
uint32_t lookup_props, uint32_t lookup_props,
hb_sorted_array_t<const HBGlyphID> 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,
hb_array_t<const HBGlyphID> ligatures_list, hb_array_t<const HBGlyphID16> ligatures_list,
hb_array_t<const unsigned int> component_count_list, hb_array_t<const unsigned int> component_count_list,
hb_array_t<const HBGlyphID> component_list /* Starting from second for each ligature */) hb_array_t<const HBGlyphID16> component_list /* Starting from second for each ligature */)
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false); if (unlikely (!Lookup::serialize (c, SubTable::Ligature, lookup_props, 1))) return_trace (false);
@ -1667,7 +1697,7 @@ struct SubstLookup : Lookup
template <typename context_t, typename ...Ts> template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
{ return Lookup::dispatch<SubTable> (c, hb_forward<Ts> (ds)...); } { return Lookup::dispatch<SubTable> (c, std::forward<Ts> (ds)...); }
bool subset (hb_subset_context_t *c) const bool subset (hb_subset_context_t *c) const
{ return Lookup::subset<SubTable> (c); } { return Lookup::subset<SubTable> (c); }

View File

@ -1210,15 +1210,14 @@ static inline bool match_lookahead (hb_ot_apply_context_t *c,
struct LookupRecord struct LookupRecord
{ {
LookupRecord* copy (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
const hb_map_t *lookup_map) const const hb_map_t *lookup_map) const
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
auto *out = c->embed (*this); auto *out = c->embed (*this);
if (unlikely (!out)) return_trace (nullptr); if (unlikely (!out)) return_trace (false);
out->lookupListIndex = hb_map_get (lookup_map, lookupListIndex); return_trace (c->check_assign (out->lookupListIndex, lookup_map->get (lookupListIndex), HB_SERIALIZE_ERROR_INT_OVERFLOW));
return_trace (out);
} }
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
@ -1235,6 +1234,24 @@ struct LookupRecord
DEFINE_SIZE_STATIC (4); DEFINE_SIZE_STATIC (4);
}; };
static unsigned serialize_lookuprecord_array (hb_serialize_context_t *c,
const hb_array_t<const LookupRecord> lookupRecords,
const hb_map_t *lookup_map)
{
unsigned count = 0;
for (const LookupRecord& r : lookupRecords)
{
if (!lookup_map->has (r.lookupListIndex))
continue;
if (!r.serialize (c, lookup_map))
return 0;
count++;
}
return count;
}
enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 }; enum ContextFormat { SimpleContext = 1, ClassBasedContext = 2, CoverageBasedContext = 3 };
static void context_closure_recurse_lookups (hb_closure_context_t *c, static void context_closure_recurse_lookups (hb_closure_context_t *c,
@ -1605,8 +1622,6 @@ struct Rule
if (unlikely (!c->extend_min (out))) return_trace (false); if (unlikely (!c->extend_min (out))) return_trace (false);
out->inputCount = inputCount; out->inputCount = inputCount;
out->lookupCount = lookupCount;
const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1); const hb_array_t<const HBUINT16> input = inputZ.as_array (inputCount - 1);
for (const auto org : input) for (const auto org : input)
{ {
@ -1617,17 +1632,9 @@ struct Rule
const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>>
(inputZ.as_array ((inputCount ? inputCount - 1 : 0))); (inputZ.as_array ((inputCount ? inputCount - 1 : 0)));
for (unsigned i = 0; i < (unsigned) lookupCount; i++)
{
if (!lookup_map->has (lookupRecord[i].lookupListIndex))
{
out->lookupCount--;
continue;
}
c->copy (lookupRecord[i], lookup_map);
}
return_trace (true); unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (lookupCount), lookup_map);
return_trace (c->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
} }
bool subset (hb_subset_context_t *c, bool subset (hb_subset_context_t *c,
@ -1752,10 +1759,10 @@ struct RuleSet
for (const Offset16To<Rule>& _ : rule) for (const Offset16To<Rule>& _ : rule)
{ {
if (!_) continue; if (!_) continue;
auto o_snap = c->serializer->snapshot ();
auto *o = out->rule.serialize_append (c->serializer); auto *o = out->rule.serialize_append (c->serializer);
if (unlikely (!o)) continue; if (unlikely (!o)) continue;
auto o_snap = c->serializer->snapshot ();
if (!o->serialize_subset (c, _, this, lookup_map, klass_map)) if (!o->serialize_subset (c, _, this, lookup_map, klass_map))
{ {
out->rule.pop (); out->rule.pop ();
@ -1943,12 +1950,20 @@ struct ContextFormat2
&class_def &class_def
}; };
hb_set_t retained_coverage_glyphs;
(this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs);
hb_set_t coverage_glyph_classes;
class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
return return
+ hb_iter (ruleSet) + hb_iter (ruleSet)
| hb_map (hb_add (this)) | hb_map (hb_add (this))
| hb_enumerate | hb_enumerate
| hb_map ([&] (const hb_pair_t<unsigned, const RuleSet &> p) | hb_map ([&] (const hb_pair_t<unsigned, const RuleSet &> p)
{ return class_def.intersects_class (glyphs, p.first) && { return class_def.intersects_class (glyphs, p.first) &&
coverage_glyph_classes.has (p.first) &&
p.second.intersects (glyphs, lookup_context); }) p.second.intersects (glyphs, lookup_context); })
| hb_any | hb_any
; ;
@ -2069,9 +2084,16 @@ struct ContextFormat2
hb_map_t klass_map; hb_map_t klass_map;
out->classDef.serialize_subset (c, classDef, this, &klass_map); out->classDef.serialize_subset (c, classDef, this, &klass_map);
const hb_set_t* glyphset = c->plan->glyphset_gsub ();
hb_set_t retained_coverage_glyphs;
(this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs);
hb_set_t coverage_glyph_classes;
(this+classDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
bool ret = true; bool ret = true;
int non_zero_index = 0, index = 0; int non_zero_index = -1, index = 0;
for (const auto& _ : + hb_enumerate (ruleSet) for (const auto& _ : + hb_enumerate (ruleSet)
| hb_filter (klass_map, hb_first)) | hb_filter (klass_map, hb_first))
{ {
@ -2082,13 +2104,14 @@ struct ContextFormat2
break; break;
} }
if (o->serialize_subset (c, _.second, this, lookup_map, &klass_map)) if (coverage_glyph_classes.has (_.first) &&
o->serialize_subset (c, _.second, this, lookup_map, &klass_map))
non_zero_index = index; non_zero_index = index;
index++; index++;
} }
if (!ret) return_trace (ret); if (!ret || non_zero_index == -1) return_trace (false);
//prune empty trailing ruleSets //prune empty trailing ruleSets
--index; --index;
@ -2226,7 +2249,6 @@ struct ContextFormat3
out->format = format; out->format = format;
out->glyphCount = glyphCount; out->glyphCount = glyphCount;
out->lookupCount = lookupCount;
auto coverages = coverageZ.as_array (glyphCount); auto coverages = coverageZ.as_array (glyphCount);
@ -2238,19 +2260,12 @@ struct ContextFormat3
if (!o->serialize_subset (c, offset, this)) return_trace (false); if (!o->serialize_subset (c, offset, this)) return_trace (false);
} }
const LookupRecord *lookupRecord = &StructAfter<LookupRecord> (coverageZ.as_array (glyphCount)); const UnsizedArrayOf<LookupRecord>& lookupRecord = StructAfter<UnsizedArrayOf<LookupRecord>> (coverageZ.as_array (glyphCount));
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
for (unsigned i = 0; i < (unsigned) lookupCount; i++)
{
if (!lookup_map->has (lookupRecord[i].lookupListIndex))
{
out->lookupCount--;
continue;
}
c->serializer->copy (lookupRecord[i], lookup_map);
}
return_trace (true);
unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (lookupCount), lookup_map);
return_trace (c->serializer->check_assign (out->lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
} }
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
@ -2289,9 +2304,9 @@ struct Context
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -2539,15 +2554,15 @@ struct ChainRule
c->copy ((HBUINT16) g); c->copy ((HBUINT16) g);
} }
ChainRule* copy (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
const hb_map_t *lookup_map, const hb_map_t *lookup_map,
const hb_map_t *backtrack_map, const hb_map_t *backtrack_map,
const hb_map_t *input_map = nullptr, const hb_map_t *input_map = nullptr,
const hb_map_t *lookahead_map = nullptr) const const hb_map_t *lookahead_map = nullptr) const
{ {
TRACE_SERIALIZE (this); TRACE_SERIALIZE (this);
auto *out = c->start_embed (this); auto *out = c->start_embed (this);
if (unlikely (!out)) return_trace (nullptr); if (unlikely (!out)) return_trace (false);
const hb_map_t *mapping = backtrack_map; const hb_map_t *mapping = backtrack_map;
serialize_array (c, backtrack.len, + backtrack.iter () serialize_array (c, backtrack.len, + backtrack.iter ()
@ -2566,19 +2581,10 @@ struct ChainRule
const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead);
HBUINT16* lookupCount = c->embed (&(lookupRecord.len)); HBUINT16* lookupCount = c->embed (&(lookupRecord.len));
if (!lookupCount) return_trace (nullptr); if (!lookupCount) return_trace (false);
for (unsigned i = 0; i < lookupRecord.len; i++) unsigned count = serialize_lookuprecord_array (c, lookupRecord.as_array (), lookup_map);
{ return_trace (c->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
if (!lookup_map->has (lookupRecord[i].lookupListIndex))
{
(*lookupCount)--;
continue;
}
if (!c->copy (lookupRecord[i], lookup_map)) return_trace (nullptr);
}
return_trace (out);
} }
bool subset (hb_subset_context_t *c, bool subset (hb_subset_context_t *c,
@ -2600,7 +2606,7 @@ struct ChainRule
!hb_all (lookahead, glyphset)) !hb_all (lookahead, glyphset))
return_trace (false); return_trace (false);
copy (c->serializer, lookup_map, c->plan->glyph_map); serialize (c->serializer, lookup_map, c->plan->glyph_map);
} }
else else
{ {
@ -2609,7 +2615,7 @@ struct ChainRule
!hb_all (lookahead, lookahead_map)) !hb_all (lookahead, lookahead_map))
return_trace (false); return_trace (false);
copy (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map); serialize (c->serializer, lookup_map, backtrack_map, input_map, lookahead_map);
} }
return_trace (true); return_trace (true);
@ -2724,10 +2730,10 @@ struct ChainRuleSet
for (const Offset16To<ChainRule>& _ : rule) for (const Offset16To<ChainRule>& _ : rule)
{ {
if (!_) continue; if (!_) continue;
auto o_snap = c->serializer->snapshot ();
auto *o = out->rule.serialize_append (c->serializer); auto *o = out->rule.serialize_append (c->serializer);
if (unlikely (!o)) continue; if (unlikely (!o)) continue;
auto o_snap = c->serializer->snapshot ();
if (!o->serialize_subset (c, _, this, if (!o->serialize_subset (c, _, this,
lookup_map, lookup_map,
backtrack_klass_map, backtrack_klass_map,
@ -2920,12 +2926,19 @@ struct ChainContextFormat2
&lookahead_class_def} &lookahead_class_def}
}; };
hb_set_t retained_coverage_glyphs;
(this+coverage).intersected_coverage_glyphs (glyphs, &retained_coverage_glyphs);
hb_set_t coverage_glyph_classes;
input_class_def.intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
return return
+ hb_iter (ruleSet) + hb_iter (ruleSet)
| hb_map (hb_add (this)) | hb_map (hb_add (this))
| hb_enumerate | hb_enumerate
| hb_map ([&] (const hb_pair_t<unsigned, const ChainRuleSet &> p) | hb_map ([&] (const hb_pair_t<unsigned, const ChainRuleSet &> p)
{ return input_class_def.intersects_class (glyphs, p.first) && { return input_class_def.intersects_class (glyphs, p.first) &&
coverage_glyph_classes.has (p.first) &&
p.second.intersects (glyphs, lookup_context); }) p.second.intersects (glyphs, lookup_context); })
| hb_any | hb_any
; ;
@ -3080,13 +3093,19 @@ struct ChainContextFormat2
lookahead_klass_map))) lookahead_klass_map)))
return_trace (false); return_trace (false);
const hb_set_t* glyphset = c->plan->glyphset_gsub ();
hb_set_t retained_coverage_glyphs;
(this+coverage).intersected_coverage_glyphs (glyphset, &retained_coverage_glyphs);
hb_set_t coverage_glyph_classes;
(this+inputClassDef).intersected_classes (&retained_coverage_glyphs, &coverage_glyph_classes);
int non_zero_index = -1, index = 0; int non_zero_index = -1, index = 0;
bool ret = true; bool ret = true;
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
auto last_non_zero = c->serializer->snapshot (); auto last_non_zero = c->serializer->snapshot ();
for (const Offset16To<ChainRuleSet>& _ : + hb_enumerate (ruleSet) for (const auto& _ : + hb_enumerate (ruleSet)
| hb_filter (input_klass_map, hb_first) | hb_filter (input_klass_map, hb_first))
| hb_map (hb_second))
{ {
auto *o = out->ruleSet.serialize_append (c->serializer); auto *o = out->ruleSet.serialize_append (c->serializer);
if (unlikely (!o)) if (unlikely (!o))
@ -3094,7 +3113,8 @@ struct ChainContextFormat2
ret = false; ret = false;
break; break;
} }
if (o->serialize_subset (c, _, this, if (coverage_glyph_classes.has (_.first) &&
o->serialize_subset (c, _.second, this,
lookup_map, lookup_map,
&backtrack_klass_map, &backtrack_klass_map,
&input_klass_map, &input_klass_map,
@ -3107,7 +3127,7 @@ struct ChainContextFormat2
index++; index++;
} }
if (!ret) return_trace (ret); if (!ret || non_zero_index == -1) return_trace (false);
// prune empty trailing ruleSets // prune empty trailing ruleSets
if (index > non_zero_index) { if (index > non_zero_index) {
@ -3318,22 +3338,12 @@ struct ChainContextFormat3
const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead); const Array16Of<LookupRecord> &lookupRecord = StructAfter<Array16Of<LookupRecord>> (lookahead);
const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups; const hb_map_t *lookup_map = c->table_tag == HB_OT_TAG_GSUB ? c->plan->gsub_lookups : c->plan->gpos_lookups;
hb_set_t lookup_indices;
for (unsigned i = 0; i < (unsigned) lookupRecord.len; i++)
if (lookup_map->has (lookupRecord[i].lookupListIndex))
lookup_indices.add (i);
HBUINT16 lookupCount; HBUINT16 *lookupCount = c->serializer->copy<HBUINT16> (lookupRecord.len);
lookupCount = lookup_indices.get_population (); if (!lookupCount) return_trace (false);
if (!c->serializer->copy (lookupCount)) return_trace (false);
for (unsigned i : lookup_indices.iter ()) unsigned count = serialize_lookuprecord_array (c->serializer, lookupRecord.as_array (), lookup_map);
{ return_trace (c->serializer->check_assign (*lookupCount, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
if (!c->serializer->copy (lookupRecord[i], lookup_map))
return_trace (false);
}
return_trace (true);
} }
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
@ -3378,9 +3388,9 @@ struct ChainContext
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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, hb_forward<Ts> (ds)...)); case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
case 2: return_trace (c->dispatch (u.format2, hb_forward<Ts> (ds)...)); case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
case 3: return_trace (c->dispatch (u.format3, hb_forward<Ts> (ds)...)); case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -3409,7 +3419,7 @@ struct ExtensionFormat1
{ {
TRACE_DISPATCH (this, format); TRACE_DISPATCH (this, format);
if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ()); if (unlikely (!c->may_dispatch (this, this))) return_trace (c->no_dispatch_return_value ());
return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), hb_forward<Ts> (ds)...)); return_trace (get_subtable<typename T::SubTable> ().dispatch (c, get_type (), std::forward<Ts> (ds)...));
} }
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
@ -3489,7 +3499,7 @@ struct Extension
TRACE_DISPATCH (this, u.format); TRACE_DISPATCH (this, u.format);
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 (u.format1.dispatch (c, hb_forward<Ts> (ds)...)); case 1: return_trace (u.format1.dispatch (c, std::forward<Ts> (ds)...));
default:return_trace (c->default_return_value ()); default:return_trace (c->default_return_value ());
} }
} }
@ -3678,57 +3688,72 @@ struct GSUBGPOS
const hb_set_t *feature_indices, const hb_set_t *feature_indices,
hb_map_t *duplicate_feature_map /* OUT */) const hb_map_t *duplicate_feature_map /* OUT */) const
{ {
if (feature_indices->is_empty ()) return;
hb_hashmap_t<hb_tag_t, hb_set_t *, (unsigned)-1, nullptr> unique_features;
//find out duplicate features after subset //find out duplicate features after subset
unsigned prev = 0xFFFFu;
for (unsigned i : feature_indices->iter ()) for (unsigned i : feature_indices->iter ())
{ {
if (prev == 0xFFFFu)
{
duplicate_feature_map->set (i, i);
prev = i;
continue;
}
hb_tag_t t = get_feature_tag (i); hb_tag_t t = get_feature_tag (i);
hb_tag_t prev_t = get_feature_tag (prev); if (t == unique_features.INVALID_KEY) continue;
if (t != prev_t) if (!unique_features.has (t))
{ {
hb_set_t* indices = hb_set_create ();
if (unlikely (indices == hb_set_get_empty () ||
!unique_features.set (t, indices)))
{
hb_set_destroy (indices);
for (auto _ : unique_features.iter ())
hb_set_destroy (_.second);
return;
}
if (unique_features.get (t))
unique_features.get (t)->add (i);
duplicate_feature_map->set (i, i); duplicate_feature_map->set (i, i);
prev = i;
continue; continue;
} }
const Feature& f = get_feature (i); bool found = false;
const Feature& prev_f = get_feature (prev);
auto f_iter = hb_set_t* same_tag_features = unique_features.get (t);
+ hb_iter (f.lookupIndex) for (unsigned other_f_index : same_tag_features->iter ())
| hb_filter (lookup_indices)
;
auto prev_iter =
+ hb_iter (prev_f.lookupIndex)
| hb_filter (lookup_indices)
;
if (f_iter.len () != prev_iter.len ())
{ {
duplicate_feature_map->set (i, i); const Feature& f = get_feature (i);
prev = i; const Feature& other_f = get_feature (other_f_index);
continue;
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;
} }
bool is_equal = true; if (found == false)
for (auto _ : + hb_zip (f_iter, prev_iter))
if (_.first != _.second) { is_equal = false; break; }
if (is_equal == true) duplicate_feature_map->set (i, prev);
else
{ {
same_tag_features->add (i);
duplicate_feature_map->set (i, i); duplicate_feature_map->set (i, i);
prev = i;
} }
} }
for (auto _ : unique_features.iter ())
hb_set_destroy (_.second);
} }
void prune_features (const hb_map_t *lookup_indices, /* IN */ void prune_features (const hb_map_t *lookup_indices, /* IN */

View File

@ -136,7 +136,7 @@ struct JstfLangSys : List16OfOffset16To<JstfPriority>
* ExtenderGlyphs -- Extender Glyph Table * ExtenderGlyphs -- Extender Glyph Table
*/ */
typedef SortedArray16Of<HBGlyphID> ExtenderGlyphs; typedef SortedArray16Of<HBGlyphID16> ExtenderGlyphs;
/* /*

View File

@ -613,7 +613,7 @@ hb_ot_layout_table_get_feature_tags (hb_face_t *face,
* hb_ot_layout_table_find_feature: * hb_ot_layout_table_find_feature:
* @face: #hb_face_t to work upon * @face: #hb_face_t to work upon
* @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS * @table_tag: #HB_OT_TAG_GSUB or #HB_OT_TAG_GPOS
* @feature_tag: The #hb_tag_t og the requested feature tag * @feature_tag: The #hb_tag_t of the requested feature tag
* @feature_index: (out): The index of the requested feature * @feature_index: (out): The index of the requested feature
* *
* Fetches the index for a given feature tag in the specified face's GSUB table * Fetches the index for a given feature tag in the specified face's GSUB table
@ -688,8 +688,8 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
* *
* Return value: %true if the language tag is found, %false otherwise * Return value: %true if the language tag is found, %false otherwise
* *
* Since: ?? * Since: 0.6.0
* Deprecated: ?? * Deprecated: 2.0.0
**/ **/
hb_bool_t hb_bool_t
hb_ot_layout_script_find_language (hb_face_t *face, hb_ot_layout_script_find_language (hb_face_t *face,
@ -717,10 +717,14 @@ hb_ot_layout_script_find_language (hb_face_t *face,
* @language_tags: The array of language tags * @language_tags: The array of language tags
* @language_index: (out): The index of the requested language * @language_index: (out): The index of the requested language
* *
* Fetches the index of a given language tag in the specified face's GSUB table * Fetches the index of the first language tag fom @language_tags that is present
* or GPOS table, underneath the specified script index. * in the specified face's GSUB or GPOS table, underneath the specified script
* index.
* *
* Return value: %true if the language tag is found, %false otherwise * If none of the given language tags is found, %false is returned and
* @language_index is set to the default language index.
*
* Return value: %true if one of the given language tags is found, %false otherwise
* *
* Since: 2.0.0 * Since: 2.0.0
**/ **/
@ -746,7 +750,8 @@ hb_ot_layout_script_select_language (hb_face_t *face,
if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index)) if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
return false; return false;
if (language_index) *language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX; if (language_index)
*language_index = HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX;
return false; return false;
} }
@ -1013,24 +1018,15 @@ struct hb_collect_features_context_t
} }
has_feature_filter = true; has_feature_filter = true;
hb_set_t features_set;
for (; *features; features++) for (; *features; features++)
{ features_set.add (*features);
hb_tag_t tag = *features;
unsigned index;
g.find_feature_index (tag, &index);
if (index == OT::Index::NOT_FOUND_INDEX) continue;
feature_indices_filter.add(index); for (unsigned i = 0; i < g.get_feature_count (); i++)
for (int i = (int) index - 1; i >= 0; i--) {
{ hb_tag_t tag = g.get_feature_tag (i);
if (g.get_feature_tag (i) != tag) break; if (features_set.has (tag))
feature_indices_filter.add(i); feature_indices_filter.add(i);
}
for (unsigned i = index + 1; i < g.get_feature_count (); i++)
{
if (g.get_feature_tag (i) != tag) break;
feature_indices_filter.add(i);
}
} }
} }
@ -2011,14 +2007,14 @@ struct hb_get_glyph_alternates_dispatch_t :
private: private:
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
( obj.get_glyph_alternates (hb_forward<Ts> (ds)...) ) ( obj.get_glyph_alternates (std::forward<Ts> (ds)...) )
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
( default_return_value () ) ( default_return_value () )
public: public:
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) ) ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
}; };
/** /**

View File

@ -187,7 +187,7 @@ _hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
* - General_Category: 5 bits. * - General_Category: 5 bits.
* - A bit each for: * - A bit each for:
* * Is it Default_Ignorable(); we have a modified Default_Ignorable(). * * Is it Default_Ignorable(); we have a modified Default_Ignorable().
* * Whether it's one of the three Mongolian Free Variation Selectors, * * Whether it's one of the four Mongolian Free Variation Selectors,
* CGJ, or other characters that are hidden but should not be ignored * CGJ, or other characters that are hidden but should not be ignored
* like most other Default_Ignorable()s do during matching. * like most other Default_Ignorable()s do during matching.
* * Whether it's a grapheme continuation. * * Whether it's a grapheme continuation.
@ -202,7 +202,7 @@ _hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
enum hb_unicode_props_flags_t { enum hb_unicode_props_flags_t {
UPROPS_MASK_GEN_CAT = 0x001Fu, UPROPS_MASK_GEN_CAT = 0x001Fu,
UPROPS_MASK_IGNORABLE = 0x0020u, UPROPS_MASK_IGNORABLE = 0x0020u,
UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..3, or TAG characters */ UPROPS_MASK_HIDDEN = 0x0040u, /* MONGOLIAN FREE VARIATION SELECTOR 1..4, or TAG characters */
UPROPS_MASK_CONTINUATION=0x0080u, UPROPS_MASK_CONTINUATION=0x0080u,
/* If GEN_CAT=FORMAT, top byte masks: */ /* If GEN_CAT=FORMAT, top byte masks: */
@ -236,7 +236,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
* FVSes are GC=Mn, we have use a separate bit to remember them. * FVSes are GC=Mn, we have use a separate bit to remember them.
* Fixes: * Fixes:
* https://github.com/harfbuzz/harfbuzz/issues/234 */ * https://github.com/harfbuzz/harfbuzz/issues/234 */
else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x180Bu, 0x180Du))) props |= UPROPS_MASK_HIDDEN; else if (unlikely (hb_in_ranges<hb_codepoint_t> (u, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu))) props |= UPROPS_MASK_HIDDEN;
/* TAG characters need similar treatment. Fixes: /* TAG characters need similar treatment. Fixes:
* https://github.com/harfbuzz/harfbuzz/issues/463 */ * https://github.com/harfbuzz/harfbuzz/issues/463 */
else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN; else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN;

View File

@ -41,6 +41,16 @@ struct MathValueRecord
hb_position_t get_y_value (hb_font_t *font, const void *base) const hb_position_t get_y_value (hb_font_t *font, const void *base) const
{ return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); } { return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); }
MathValueRecord* copy (hb_serialize_context_t *c, const void *base) const
{
TRACE_SERIALIZE (this);
auto *out = c->embed (this);
if (unlikely (!out)) return_trace (nullptr);
out->deviceTable.serialize_copy (c, deviceTable, base, 0, hb_serialize_context_t::Head);
return_trace (out);
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const bool sanitize (hb_sanitize_context_t *c, const void *base) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -59,6 +69,29 @@ struct MathValueRecord
struct MathConstants struct MathConstants
{ {
MathConstants* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
auto *out = c->start_embed (this);
if (unlikely (!out)) return_trace (nullptr);
HBINT16 *p = c->allocate_size<HBINT16> (HBINT16::static_size * 2);
if (unlikely (!p)) return_trace (nullptr);
memcpy (p, percentScaleDown, HBINT16::static_size * 2);
HBUINT16 *m = c->allocate_size<HBUINT16> (HBUINT16::static_size * 2);
if (unlikely (!m)) return_trace (nullptr);
memcpy (m, minHeight, HBUINT16::static_size * 2);
unsigned count = ARRAY_LENGTH (mathValueRecords);
for (unsigned i = 0; i < count; i++)
if (!c->copy (mathValueRecords[i], this))
return_trace (nullptr);
if (!c->embed (radicalDegreeBottomRaisePercent)) return_trace (nullptr);
return_trace (out);
}
bool sanitize_math_value_records (hb_sanitize_context_t *c) const bool sanitize_math_value_records (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -165,6 +198,28 @@ struct MathConstants
struct MathItalicsCorrectionInfo struct MathItalicsCorrectionInfo
{ {
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
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);
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+coverage, italicsCorrection)
| hb_filter (glyphset, hb_first)
| hb_filter (serialize_math_record_array (c->serializer, out->italicsCorrection, this), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -196,6 +251,28 @@ struct MathItalicsCorrectionInfo
struct MathTopAccentAttachment struct MathTopAccentAttachment
{ {
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
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);
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+topAccentCoverage, topAccentAttachment)
| hb_filter (glyphset, hb_first)
| hb_filter (serialize_math_record_array (c->serializer, out->topAccentAttachment, this), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
out->topAccentCoverage.serialize_serialize (c->serializer, new_coverage.iter ());
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -229,6 +306,22 @@ struct MathTopAccentAttachment
struct MathKern struct MathKern
{ {
MathKern* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
auto *out = c->start_embed (this);
if (unlikely (!out)) return_trace (nullptr);
if (unlikely (!c->embed (heightCount))) return_trace (nullptr);
unsigned count = 2 * heightCount + 1;
for (unsigned i = 0; i < count; i++)
if (!c->copy (mathValueRecordsZ.arrayZ[i], this))
return_trace (nullptr);
return_trace (out);
}
bool sanitize_math_value_records (hb_sanitize_context_t *c) const bool sanitize_math_value_records (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -295,6 +388,19 @@ struct MathKern
struct MathKernInfoRecord struct MathKernInfoRecord
{ {
MathKernInfoRecord* copy (hb_serialize_context_t *c, const void *base) const
{
TRACE_SERIALIZE (this);
auto *out = c->embed (this);
if (unlikely (!out)) return_trace (nullptr);
unsigned count = ARRAY_LENGTH (mathKern);
for (unsigned i = 0; i < count; i++)
out->mathKern[i].serialize_copy (c, mathKern[i], base, 0, hb_serialize_context_t::Head);
return_trace (out);
}
bool sanitize (hb_sanitize_context_t *c, const void *base) const bool sanitize (hb_sanitize_context_t *c, const void *base) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -328,6 +434,28 @@ struct MathKernInfoRecord
struct MathKernInfo struct MathKernInfo
{ {
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
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);
hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+ hb_zip (this+mathKernCoverage, mathKernInfoRecords)
| hb_filter (glyphset, hb_first)
| hb_filter (serialize_math_record_array (c->serializer, out->mathKernInfoRecords, this), hb_second)
| hb_map (hb_first)
| hb_map (glyph_map)
| hb_sink (new_coverage)
;
out->mathKernCoverage.serialize_serialize (c->serializer, new_coverage.iter ());
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -365,6 +493,30 @@ struct MathKernInfo
struct MathGlyphInfo struct MathGlyphInfo
{ {
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
out->mathItalicsCorrectionInfo.serialize_subset (c, mathItalicsCorrectionInfo, this);
out->mathTopAccentAttachment.serialize_subset (c, mathTopAccentAttachment, this);
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
const hb_map_t &glyph_map = *c->plan->glyph_map;
auto it =
+ hb_iter (this+extendedShapeCoverage)
| hb_filter (glyphset)
| hb_map_retains_sorting (glyph_map)
;
out->extendedShapeCoverage.serialize_serialize (c->serializer, it);
out->mathKernInfo.serialize_subset (c, mathKernInfo, this);
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -420,14 +572,27 @@ struct MathGlyphVariantRecord
{ {
friend struct MathGlyphConstruction; friend struct MathGlyphConstruction;
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
const hb_map_t& glyph_map = *c->plan->glyph_map;
return_trace (c->serializer->check_assign (out->variantGlyph, glyph_map.get (variantGlyph), HB_SERIALIZE_ERROR_INT_OVERFLOW));
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this)); return_trace (c->check_struct (this));
} }
void closure_glyphs (hb_set_t *variant_glyphs) const
{ variant_glyphs->add (variantGlyph); }
protected: protected:
HBGlyphID variantGlyph; /* Glyph ID for the variant. */ HBGlyphID16 variantGlyph; /* Glyph ID for the variant. */
HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the
* variant, in the direction of requested * variant, in the direction of requested
* glyph extension. */ * glyph extension. */
@ -450,6 +615,16 @@ struct PartFlags : HBUINT16
struct MathGlyphPartRecord struct MathGlyphPartRecord
{ {
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (this);
if (unlikely (!out)) return_trace (false);
const hb_map_t& glyph_map = *c->plan->glyph_map;
return_trace (c->serializer->check_assign (out->glyph, glyph_map.get (glyph), HB_SERIALIZE_ERROR_INT_OVERFLOW));
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -474,8 +649,11 @@ struct MathGlyphPartRecord
(partFlags & PartFlags::Defined); (partFlags & PartFlags::Defined);
} }
void closure_glyphs (hb_set_t *variant_glyphs) const
{ variant_glyphs->add (glyph); }
protected: protected:
HBGlyphID glyph; /* Glyph ID for the part. */ HBGlyphID16 glyph; /* Glyph ID for the part. */
HBUINT16 startConnectorLength; HBUINT16 startConnectorLength;
/* Advance width/ height of the straight bar /* Advance width/ height of the straight bar
* connector material, in design units, is at * connector material, in design units, is at
@ -497,6 +675,20 @@ struct MathGlyphPartRecord
struct MathGlyphAssembly struct MathGlyphAssembly
{ {
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->start_embed (*this);
if (unlikely (!out)) return_trace (false);
if (!c->serializer->copy (italicsCorrection, this)) return_trace (false);
if (!c->serializer->copy<HBUINT16> (partRecords.len)) return_trace (false);
for (const auto& record : partRecords.iter ())
if (!record.subset (c)) return_trace (false);
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -526,6 +718,12 @@ struct MathGlyphAssembly
return partRecords.len; return partRecords.len;
} }
void closure_glyphs (hb_set_t *variant_glyphs) const
{
for (const auto& _ : partRecords.iter ())
_.closure_glyphs (variant_glyphs);
}
protected: protected:
MathValueRecord MathValueRecord
italicsCorrection; italicsCorrection;
@ -543,6 +741,22 @@ struct MathGlyphAssembly
struct MathGlyphConstruction struct MathGlyphConstruction
{ {
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);
out->glyphAssembly.serialize_subset (c, glyphAssembly, this);
if (!c->serializer->check_assign (out->mathGlyphVariantRecord.len, mathGlyphVariantRecord.len, HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
for (const auto& record : mathGlyphVariantRecord.iter ())
if (!record.subset (c)) return_trace (false);
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -569,6 +783,14 @@ struct MathGlyphConstruction
return mathGlyphVariantRecord.len; return mathGlyphVariantRecord.len;
} }
void closure_glyphs (hb_set_t *variant_glyphs) const
{
(this+glyphAssembly).closure_glyphs (variant_glyphs);
for (const auto& _ : mathGlyphVariantRecord.iter ())
_.closure_glyphs (variant_glyphs);
}
protected: protected:
/* Offset to MathGlyphAssembly table for this shape - from the beginning of /* Offset to MathGlyphAssembly table for this shape - from the beginning of
MathGlyphConstruction table. May be NULL. */ MathGlyphConstruction table. May be NULL. */
@ -583,6 +805,91 @@ struct MathGlyphConstruction
struct MathVariants struct MathVariants
{ {
void closure_glyphs (const hb_set_t *glyph_set,
hb_set_t *variant_glyphs) const
{
const hb_array_t<const Offset16To<MathGlyphConstruction>> glyph_construction_offsets = glyphConstruction.as_array (vertGlyphCount + horizGlyphCount);
if (vertGlyphCoverage)
{
const auto vert_offsets = glyph_construction_offsets.sub_array (0, vertGlyphCount);
+ hb_zip (this+vertGlyphCoverage, vert_offsets)
| hb_filter (glyph_set, hb_first)
| hb_map (hb_second)
| hb_map (hb_add (this))
| hb_apply ([=] (const MathGlyphConstruction &_) { _.closure_glyphs (variant_glyphs); })
;
}
if (horizGlyphCoverage)
{
const auto hori_offsets = glyph_construction_offsets.sub_array (vertGlyphCount, horizGlyphCount);
+ hb_zip (this+horizGlyphCoverage, hori_offsets)
| hb_filter (glyph_set, hb_first)
| hb_map (hb_second)
| hb_map (hb_add (this))
| hb_apply ([=] (const MathGlyphConstruction &_) { _.closure_glyphs (variant_glyphs); })
;
}
}
void collect_coverage_and_indices (hb_sorted_vector_t<hb_codepoint_t>& new_coverage,
const Offset16To<Coverage>& coverage,
unsigned i,
unsigned end_index,
hb_set_t& indices,
const hb_set_t& glyphset,
const hb_map_t& glyph_map) const
{
if (!coverage) return;
for (const auto _ : (this+coverage).iter ())
{
if (i >= end_index) return;
if (glyphset.has (_))
{
unsigned new_gid = glyph_map.get (_);
new_coverage.push (new_gid);
indices.add (i);
}
i++;
}
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
const hb_set_t &glyphset = *c->plan->_glyphset_mathed;
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);
if (!c->serializer->check_assign (out->minConnectorOverlap, minConnectorOverlap, HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
hb_sorted_vector_t<hb_codepoint_t> new_vert_coverage;
hb_sorted_vector_t<hb_codepoint_t> new_hori_coverage;
hb_set_t indices;
collect_coverage_and_indices (new_vert_coverage, vertGlyphCoverage, 0, vertGlyphCount, indices, glyphset, glyph_map);
collect_coverage_and_indices (new_hori_coverage, horizGlyphCoverage, vertGlyphCount, vertGlyphCount + horizGlyphCount, indices, glyphset, glyph_map);
if (!c->serializer->check_assign (out->vertGlyphCount, new_vert_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
if (!c->serializer->check_assign (out->horizGlyphCount, new_hori_coverage.length, HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false);
for (unsigned i : indices.iter ())
{
auto *o = c->serializer->embed (glyphConstruction[i]);
if (!o) return_trace (false);
o->serialize_subset (c, glyphConstruction[i], this);
}
out->vertGlyphCoverage.serialize_serialize (c->serializer, new_vert_coverage.iter ());
out->horizGlyphCoverage.serialize_serialize (c->serializer, new_hori_coverage.iter ());
return_trace (true);
}
bool sanitize_offsets (hb_sanitize_context_t *c) const bool sanitize_offsets (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
@ -690,6 +997,28 @@ struct MATH
bool has_data () const { return version.to_int (); } bool has_data () const { return version.to_int (); }
void closure_glyphs (hb_set_t *glyph_set) const
{
if (mathVariants)
{
hb_set_t variant_glyphs;
(this+mathVariants).closure_glyphs (glyph_set, &variant_glyphs);
hb_set_union (glyph_set, &variant_glyphs);
}
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
out->mathConstants.serialize_copy (c->serializer, mathConstants, this, 0, hb_serialize_context_t::Head);
out->mathGlyphInfo.serialize_subset (c, mathGlyphInfo, this);
out->mathVariants.serialize_subset (c, mathVariants, this);
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);

View File

@ -36,12 +36,42 @@ HB_BEGIN_DECLS
/** /**
* hb_ot_name_id_t: * hb_ot_name_id_t:
* @HB_OT_NAME_ID_COPYRIGHT: Copyright notice
* @HB_OT_NAME_ID_FONT_FAMILY: Font Family name
* @HB_OT_NAME_ID_FONT_SUBFAMILY: Font Subfamily name
* @HB_OT_NAME_ID_UNIQUE_ID: Unique font identifier
* @HB_OT_NAME_ID_FULL_NAME: Full font name that reflects
* all family and relevant subfamily descriptors
* @HB_OT_NAME_ID_VERSION_STRING: Version string
* @HB_OT_NAME_ID_POSTSCRIPT_NAME: PostScript name for the font
* @HB_OT_NAME_ID_TRADEMARK: Trademark
* @HB_OT_NAME_ID_MANUFACTURER: Manufacturer Name
* @HB_OT_NAME_ID_DESIGNER: Designer
* @HB_OT_NAME_ID_DESCRIPTION: Description
* @HB_OT_NAME_ID_VENDOR_URL: URL of font vendor
* @HB_OT_NAME_ID_DESIGNER_URL: URL of typeface designer
* @HB_OT_NAME_ID_LICENSE: License Description
* @HB_OT_NAME_ID_LICENSE_URL: URL where additional licensing
* information can be found
* @HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY: Typographic Family name
* @HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY: Typographic Subfamily name
* @HB_OT_NAME_ID_MAC_FULL_NAME: Compatible Full Name for MacOS
* @HB_OT_NAME_ID_SAMPLE_TEXT: Sample text
* @HB_OT_NAME_ID_CID_FINDFONT_NAME: PostScript CID findfont name
* @HB_OT_NAME_ID_WWS_FAMILY: WWS Family Name
* @HB_OT_NAME_ID_WWS_SUBFAMILY: WWS Subfamily Name
* @HB_OT_NAME_ID_LIGHT_BACKGROUND: Light Background Palette
* @HB_OT_NAME_ID_DARK_BACKGROUND: Dark Background Palette
* @HB_OT_NAME_ID_VARIATIONS_PS_PREFIX: Variations PostScript Name Prefix
* @HB_OT_NAME_ID_INVALID: Value to represent a nonexistent name ID. * @HB_OT_NAME_ID_INVALID: Value to represent a nonexistent name ID.
* *
* An integral type representing an OpenType 'name' table name identifier. * An integral type representing an OpenType 'name' table name identifier.
* There are predefined name IDs, as well as name IDs return from other * There are predefined name IDs, as well as name IDs return from other
* API. These can be used to fetch name strings from a font face. * API. These can be used to fetch name strings from a font face.
* *
* For more information on these fields, see the
* [OpenType spec](https://docs.microsoft.com/en-us/typography/opentype/spec/name#name-ids).
*
* Since: 2.0.0 * Since: 2.0.0
**/ **/
enum enum

View File

@ -49,8 +49,8 @@ arabic_fallback_synthesize_lookup_single (const hb_ot_shape_plan_t *plan HB_UNUS
hb_font_t *font, hb_font_t *font,
unsigned int feature_index) unsigned int feature_index)
{ {
OT::HBGlyphID glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1]; OT::HBGlyphID16 glyphs[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
OT::HBGlyphID substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1]; OT::HBGlyphID16 substitutes[SHAPING_TABLE_LAST - SHAPING_TABLE_FIRST + 1];
unsigned int num_glyphs = 0; unsigned int num_glyphs = 0;
/* Populate arrays */ /* 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! /* Bubble-sort or something equally good!
* May not be good-enough for presidential candidate interviews, but good-enough for us... */ * May not be good-enough for presidential candidate interviews, but good-enough for us... */
hb_stable_sort (&glyphs[0], num_glyphs, hb_stable_sort (&glyphs[0], num_glyphs,
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp, (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID16::cmp,
&substitutes[0]); &substitutes[0]);
@ -99,15 +99,15 @@ static OT::SubstLookup *
arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED, arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font) hb_font_t *font)
{ {
OT::HBGlyphID first_glyphs[ARRAY_LENGTH_CONST (ligature_table)]; OT::HBGlyphID16 first_glyphs[ARRAY_LENGTH_CONST (ligature_table)];
unsigned int first_glyphs_indirection[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 ligature_per_first_glyph_count_list[ARRAY_LENGTH_CONST (first_glyphs)];
unsigned int num_first_glyphs = 0; unsigned int num_first_glyphs = 0;
/* We know that all our ligatures are 2-component */ /* We know that all our ligatures are 2-component */
OT::HBGlyphID ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)]; OT::HBGlyphID16 ligature_list[ARRAY_LENGTH_CONST (first_glyphs) * ARRAY_LENGTH_CONST(ligature_table[0].ligatures)];
unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)]; unsigned int component_count_list[ARRAY_LENGTH_CONST (ligature_list)];
OT::HBGlyphID component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */]; OT::HBGlyphID16 component_list[ARRAY_LENGTH_CONST (ligature_list) * 1/* One extra component per ligature */];
unsigned int num_ligatures = 0; unsigned int num_ligatures = 0;
/* Populate arrays */ /* Populate arrays */
@ -125,7 +125,7 @@ arabic_fallback_synthesize_lookup_ligature (const hb_ot_shape_plan_t *plan HB_UN
num_first_glyphs++; num_first_glyphs++;
} }
hb_stable_sort (&first_glyphs[0], num_first_glyphs, hb_stable_sort (&first_glyphs[0], num_first_glyphs,
(int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID::cmp, (int(*)(const OT::HBUINT16*, const OT::HBUINT16 *)) OT::HBGlyphID16::cmp,
&first_glyphs_indirection[0]); &first_glyphs_indirection[0]);
/* Now that the first-glyphs are sorted, walk again, populate ligatures. */ /* Now that the first-glyphs are sorted, walk again, populate ligatures. */

View File

@ -349,7 +349,7 @@ mongolian_variation_selectors (hb_buffer_t *buffer)
unsigned int count = buffer->len; unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 1; i < count; i++) for (unsigned int i = 1; i < count; i++)
if (unlikely (hb_in_range<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du))) if (unlikely (hb_in_ranges<hb_codepoint_t> (info[i].codepoint, 0x180Bu, 0x180Du, 0x180Fu, 0x180Fu)))
info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action(); info[i].arabic_shaping_action() = info[i - 1].arabic_shaping_action();
} }

View File

@ -202,9 +202,6 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
for (; i < INDIC_NUM_FEATURES; i++) for (; i < INDIC_NUM_FEATURES; i++)
map->add_feature (indic_features[i]); map->add_feature (indic_features[i]);
map->enable_feature (HB_TAG('c','a','l','t'));
map->enable_feature (HB_TAG('c','l','i','g'));
map->add_gsub_pause (_hb_clear_syllables); map->add_gsub_pause (_hb_clear_syllables);
} }

View File

@ -49,13 +49,15 @@ enum khmer_category_t
//OT_VPst = 29, //OT_VPst = 29,
}; };
using khmer_position_t = indic_position_t;
static inline void static inline void
set_khmer_properties (hb_glyph_info_t &info) set_khmer_properties (hb_glyph_info_t &info)
{ {
hb_codepoint_t u = info.codepoint; hb_codepoint_t u = info.codepoint;
unsigned int type = hb_indic_get_categories (u); unsigned int type = hb_indic_get_categories (u);
khmer_category_t cat = (khmer_category_t) (type & 0xFFu); khmer_category_t cat = (khmer_category_t) (type & 0xFFu);
indic_position_t pos = (indic_position_t) (type >> 8); khmer_position_t pos = (khmer_position_t) (type >> 8);
/* /*

View File

@ -51,6 +51,7 @@ enum myanmar_syllable_type_t {
#define myanmar_syllable_machine_ex_H 4u #define myanmar_syllable_machine_ex_H 4u
#define myanmar_syllable_machine_ex_IV 2u #define myanmar_syllable_machine_ex_IV 2u
#define myanmar_syllable_machine_ex_MH 21u #define myanmar_syllable_machine_ex_MH 21u
#define myanmar_syllable_machine_ex_ML 33u
#define myanmar_syllable_machine_ex_MR 22u #define myanmar_syllable_machine_ex_MR 22u
#define myanmar_syllable_machine_ex_MW 23u #define myanmar_syllable_machine_ex_MW 23u
#define myanmar_syllable_machine_ex_MY 24u #define myanmar_syllable_machine_ex_MY 24u
@ -67,35 +68,36 @@ enum myanmar_syllable_type_t {
#define myanmar_syllable_machine_ex_ZWNJ 5u #define myanmar_syllable_machine_ex_ZWNJ 5u
#line 71 "hb-ot-shape-complex-myanmar-machine.hh" #line 72 "hb-ot-shape-complex-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = { static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 1u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u,
3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u, 3u, 33u,
5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 33u, 3u, 33u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 33u, 1u, 16u, 3u, 33u, 3u, 33u,
3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 33u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 33u, 3u, 33u,
3u, 29u, 1u, 32u, 1u, 32u, 8u, 8u, 0 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 3u, 33u, 1u, 33u, 1u, 32u, 8u, 8u,
0
}; };
static const char _myanmar_syllable_machine_key_spans[] = { static const char _myanmar_syllable_machine_key_spans[] = {
32, 28, 25, 4, 25, 23, 21, 21, 33, 31, 25, 4, 25, 23, 21, 21,
27, 27, 27, 27, 16, 27, 27, 27, 31, 27, 27, 27, 31, 16, 31, 31,
27, 27, 28, 27, 27, 27, 27, 27, 27, 27, 27, 28, 27, 31, 31, 31,
25, 4, 25, 23, 21, 21, 27, 27, 31, 31, 25, 4, 25, 23, 21, 21,
27, 27, 16, 28, 27, 27, 27, 27, 31, 27, 27, 27, 31, 16, 31, 31,
27, 28, 27, 27, 27, 27, 27, 28, 31, 27, 27, 27, 28, 27, 31, 31,
27, 32, 32, 1 31, 31, 31, 31, 31, 33, 32, 1
}; };
static const short _myanmar_syllable_machine_index_offsets[] = { static const short _myanmar_syllable_machine_index_offsets[] = {
0, 33, 62, 88, 93, 119, 143, 165, 0, 34, 66, 92, 97, 123, 147, 169,
187, 215, 243, 271, 299, 316, 344, 372, 191, 223, 251, 279, 307, 339, 356, 388,
400, 428, 456, 485, 513, 541, 569, 597, 420, 448, 476, 504, 533, 561, 593, 625,
625, 651, 656, 682, 706, 728, 750, 778, 657, 689, 721, 747, 752, 778, 802, 824,
806, 834, 862, 879, 908, 936, 964, 992, 846, 878, 906, 934, 962, 994, 1011, 1043,
1020, 1048, 1077, 1105, 1133, 1161, 1189, 1217, 1075, 1107, 1135, 1163, 1191, 1220, 1248, 1280,
1246, 1274, 1307, 1340 1312, 1344, 1376, 1408, 1440, 1472, 1506, 1539
}; };
static const char _myanmar_syllable_machine_indicies[] = { static const char _myanmar_syllable_machine_indicies[] = {
@ -103,192 +105,217 @@ static const char _myanmar_syllable_machine_indicies[] = {
0, 6, 1, 0, 0, 0, 0, 7, 0, 6, 1, 0, 0, 0, 0, 7,
0, 8, 9, 0, 10, 11, 12, 13, 0, 8, 9, 0, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 1, 14, 15, 16, 17, 18, 19, 20, 1,
0, 22, 23, 24, 24, 21, 25, 21, 21, 0, 23, 24, 25, 25, 22, 26,
26, 21, 21, 21, 21, 21, 21, 21, 22, 27, 22, 22, 22, 22, 22, 22,
27, 21, 21, 28, 29, 30, 31, 32, 22, 28, 22, 22, 29, 30, 31, 32,
33, 34, 35, 36, 37, 21, 24, 24, 33, 34, 35, 36, 37, 38, 22, 22,
21, 25, 21, 21, 21, 21, 21, 21, 39, 22, 25, 25, 22, 26, 22, 22,
21, 21, 21, 38, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 40,
21, 21, 32, 21, 21, 21, 36, 21, 22, 22, 22, 22, 22, 22, 33, 22,
24, 24, 21, 25, 21, 24, 24, 21, 22, 22, 37, 22, 25, 25, 22, 26,
25, 21, 21, 21, 21, 21, 21, 21, 22, 25, 25, 22, 26, 22, 22, 22,
21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
21, 32, 21, 21, 21, 36, 21, 39, 22, 22, 22, 22, 22, 33, 22, 22,
21, 24, 24, 21, 25, 21, 32, 21, 22, 37, 22, 41, 22, 25, 25, 22,
21, 21, 21, 21, 21, 21, 40, 21, 26, 22, 33, 22, 22, 22, 22, 22,
21, 21, 21, 21, 21, 32, 21, 24, 22, 22, 42, 22, 22, 22, 22, 22,
24, 21, 25, 21, 21, 21, 21, 21, 22, 33, 22, 25, 25, 22, 26, 22,
21, 21, 21, 21, 40, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
21, 21, 21, 32, 21, 24, 24, 21, 42, 22, 22, 22, 22, 22, 22, 33,
25, 21, 21, 21, 21, 21, 21, 21, 22, 25, 25, 22, 26, 22, 22, 22,
21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
21, 32, 21, 22, 21, 24, 24, 21, 22, 22, 22, 22, 22, 33, 22, 23,
25, 21, 26, 21, 21, 21, 21, 21, 22, 25, 25, 22, 26, 22, 27, 22,
21, 21, 41, 21, 21, 41, 21, 21, 22, 22, 22, 22, 22, 22, 43, 22,
21, 32, 42, 21, 21, 36, 21, 22, 22, 44, 22, 22, 22, 33, 45, 22,
21, 24, 24, 21, 25, 21, 26, 21, 22, 37, 22, 22, 22, 43, 22, 23,
21, 21, 21, 21, 21, 21, 21, 21, 22, 25, 25, 22, 26, 22, 27, 22,
21, 21, 21, 21, 21, 32, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
21, 36, 21, 22, 21, 24, 24, 21, 22, 22, 22, 22, 22, 33, 22, 22,
25, 21, 26, 21, 21, 21, 21, 21, 22, 37, 22, 23, 22, 25, 25, 22,
21, 21, 41, 21, 21, 21, 21, 21, 26, 22, 27, 22, 22, 22, 22, 22,
21, 32, 42, 21, 21, 36, 21, 22, 22, 22, 43, 22, 22, 22, 22, 22,
21, 24, 24, 21, 25, 21, 26, 21, 22, 33, 45, 22, 22, 37, 22, 23,
21, 21, 21, 21, 21, 21, 21, 21, 22, 25, 25, 22, 26, 22, 27, 22,
21, 21, 21, 21, 21, 32, 42, 21, 22, 22, 22, 22, 22, 22, 22, 22,
21, 36, 21, 1, 1, 21, 21, 21, 22, 22, 22, 22, 22, 33, 45, 22,
21, 21, 21, 21, 21, 21, 21, 21, 22, 37, 22, 23, 22, 25, 25, 22,
21, 21, 1, 21, 22, 21, 24, 24, 26, 22, 27, 22, 22, 22, 22, 22,
21, 25, 21, 26, 21, 21, 21, 21, 22, 22, 43, 22, 22, 22, 22, 22,
21, 21, 21, 27, 21, 21, 28, 29, 22, 33, 45, 22, 22, 37, 22, 22,
30, 31, 32, 33, 34, 35, 36, 21, 22, 43, 22, 1, 1, 22, 22, 22,
22, 21, 24, 24, 21, 25, 21, 26, 22, 22, 22, 22, 22, 22, 22, 22,
21, 21, 21, 21, 21, 21, 21, 43, 22, 22, 1, 22, 23, 22, 25, 25,
21, 21, 21, 21, 21, 21, 32, 33, 22, 26, 22, 27, 22, 22, 22, 22,
34, 35, 36, 21, 22, 21, 24, 24, 22, 22, 22, 28, 22, 22, 29, 30,
21, 25, 21, 26, 21, 21, 21, 21, 31, 32, 33, 34, 35, 36, 37, 22,
21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 39, 22, 23, 22, 25, 25,
21, 21, 32, 33, 34, 35, 36, 21, 22, 26, 22, 27, 22, 22, 22, 22,
22, 21, 24, 24, 21, 25, 21, 26, 22, 22, 22, 46, 22, 22, 22, 22,
21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 33, 34, 35, 36, 37, 22,
21, 21, 21, 21, 21, 21, 32, 33, 22, 22, 39, 22, 23, 22, 25, 25,
34, 21, 36, 21, 22, 21, 24, 24, 22, 26, 22, 27, 22, 22, 22, 22,
21, 25, 21, 26, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 33, 34, 35, 36, 37, 22,
21, 21, 32, 21, 34, 21, 36, 21, 23, 22, 25, 25, 22, 26, 22, 27,
22, 21, 24, 24, 21, 25, 21, 26, 22, 22, 22, 22, 22, 22, 22, 22,
21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 33, 34,
21, 21, 21, 21, 21, 21, 32, 33, 35, 22, 37, 22, 23, 22, 25, 25,
34, 35, 36, 43, 21, 22, 21, 24, 22, 26, 22, 27, 22, 22, 22, 22,
24, 21, 25, 21, 26, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
21, 21, 21, 21, 21, 21, 21, 28, 22, 22, 33, 22, 35, 22, 37, 22,
21, 30, 21, 32, 33, 34, 35, 36, 23, 22, 25, 25, 22, 26, 22, 27,
21, 22, 21, 24, 24, 21, 25, 21, 22, 22, 22, 22, 22, 22, 22, 22,
26, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 33, 34,
43, 21, 21, 28, 21, 21, 21, 32, 35, 36, 37, 46, 22, 23, 22, 25,
33, 34, 35, 36, 21, 22, 21, 24, 25, 22, 26, 22, 27, 22, 22, 22,
24, 21, 25, 21, 26, 21, 21, 21, 22, 22, 22, 22, 46, 22, 22, 22,
21, 21, 21, 21, 44, 21, 21, 28, 22, 22, 22, 33, 34, 35, 36, 37,
29, 30, 21, 32, 33, 34, 35, 36, 22, 23, 22, 25, 25, 22, 26, 22,
21, 22, 21, 24, 24, 21, 25, 21, 27, 22, 22, 22, 22, 22, 22, 22,
26, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 29, 22, 31, 22, 33,
21, 21, 21, 28, 29, 30, 21, 32, 34, 35, 36, 37, 22, 22, 22, 39,
33, 34, 35, 36, 21, 22, 23, 24, 22, 23, 22, 25, 25, 22, 26, 22,
24, 21, 25, 21, 26, 21, 21, 21, 27, 22, 22, 22, 22, 22, 22, 22,
21, 21, 21, 21, 27, 21, 21, 28, 46, 22, 22, 29, 22, 22, 22, 33,
29, 30, 31, 32, 33, 34, 35, 36, 34, 35, 36, 37, 22, 22, 22, 39,
21, 46, 46, 45, 5, 45, 45, 45, 22, 23, 22, 25, 25, 22, 26, 22,
45, 45, 45, 45, 45, 45, 47, 45, 27, 22, 22, 22, 22, 22, 22, 22,
45, 45, 45, 45, 45, 14, 45, 45, 47, 22, 22, 29, 30, 31, 22, 33,
45, 18, 45, 46, 46, 45, 5, 45, 34, 35, 36, 37, 22, 22, 22, 39,
46, 46, 45, 5, 45, 45, 45, 45, 22, 23, 22, 25, 25, 22, 26, 22,
45, 45, 45, 45, 45, 45, 45, 45, 27, 22, 22, 22, 22, 22, 22, 22,
45, 45, 45, 45, 14, 45, 45, 45, 22, 22, 22, 29, 30, 31, 22, 33,
18, 45, 48, 45, 46, 46, 45, 5, 34, 35, 36, 37, 22, 22, 22, 39,
45, 14, 45, 45, 45, 45, 45, 45, 22, 23, 24, 25, 25, 22, 26, 22,
45, 49, 45, 45, 45, 45, 45, 45, 27, 22, 22, 22, 22, 22, 22, 22,
14, 45, 46, 46, 45, 5, 45, 45, 28, 22, 22, 29, 30, 31, 32, 33,
45, 45, 45, 45, 45, 45, 45, 49, 34, 35, 36, 37, 22, 22, 22, 39,
45, 45, 45, 45, 45, 45, 14, 45, 22, 49, 49, 48, 5, 48, 48, 48,
46, 46, 45, 5, 45, 45, 45, 45, 48, 48, 48, 48, 48, 48, 50, 48,
45, 45, 45, 45, 45, 45, 45, 45, 48, 48, 48, 48, 48, 14, 48, 48,
45, 45, 45, 45, 14, 45, 2, 45, 48, 18, 48, 49, 49, 48, 5, 48,
46, 46, 45, 5, 45, 6, 45, 45, 49, 49, 48, 5, 48, 48, 48, 48,
45, 45, 45, 45, 45, 50, 45, 45, 48, 48, 48, 48, 48, 48, 48, 48,
50, 45, 45, 45, 14, 51, 45, 45, 48, 48, 48, 48, 14, 48, 48, 48,
18, 45, 2, 45, 46, 46, 45, 5, 18, 48, 51, 48, 49, 49, 48, 5,
45, 6, 45, 45, 45, 45, 45, 45, 48, 14, 48, 48, 48, 48, 48, 48,
45, 45, 45, 45, 45, 45, 45, 45, 48, 52, 48, 48, 48, 48, 48, 48,
14, 45, 45, 45, 18, 45, 2, 45, 14, 48, 49, 49, 48, 5, 48, 48,
46, 46, 45, 5, 45, 6, 45, 45, 48, 48, 48, 48, 48, 48, 48, 52,
45, 45, 45, 45, 45, 50, 45, 45, 48, 48, 48, 48, 48, 48, 14, 48,
45, 45, 45, 45, 14, 51, 45, 45, 49, 49, 48, 5, 48, 48, 48, 48,
18, 45, 2, 45, 46, 46, 45, 5, 48, 48, 48, 48, 48, 48, 48, 48,
45, 6, 45, 45, 45, 45, 45, 45, 48, 48, 48, 48, 14, 48, 2, 48,
45, 45, 45, 45, 45, 45, 45, 45, 49, 49, 48, 5, 48, 6, 48, 48,
14, 51, 45, 45, 18, 45, 52, 52, 48, 48, 48, 48, 48, 53, 48, 48,
45, 45, 45, 45, 45, 45, 45, 45, 54, 48, 48, 48, 14, 55, 48, 48,
45, 45, 45, 45, 45, 52, 45, 2, 18, 48, 48, 48, 53, 48, 2, 48,
3, 46, 46, 45, 5, 45, 6, 45, 49, 49, 48, 5, 48, 6, 48, 48,
45, 45, 45, 45, 45, 45, 8, 45, 48, 48, 48, 48, 48, 48, 48, 48,
45, 10, 11, 12, 13, 14, 15, 16, 48, 48, 48, 48, 14, 48, 48, 48,
17, 18, 19, 45, 2, 45, 46, 46, 18, 48, 2, 48, 49, 49, 48, 5,
45, 5, 45, 6, 45, 45, 45, 45, 48, 6, 48, 48, 48, 48, 48, 48,
45, 45, 45, 8, 45, 45, 10, 11, 48, 53, 48, 48, 48, 48, 48, 48,
12, 13, 14, 15, 16, 17, 18, 45, 14, 55, 48, 48, 18, 48, 2, 48,
2, 45, 46, 46, 45, 5, 45, 6, 49, 49, 48, 5, 48, 6, 48, 48,
45, 45, 45, 45, 45, 45, 45, 53, 48, 48, 48, 48, 48, 48, 48, 48,
45, 45, 45, 45, 45, 45, 14, 15, 48, 48, 48, 48, 14, 55, 48, 48,
16, 17, 18, 45, 2, 45, 46, 46, 18, 48, 2, 48, 49, 49, 48, 5,
45, 5, 45, 6, 45, 45, 45, 45, 48, 6, 48, 48, 48, 48, 48, 48,
45, 45, 45, 45, 45, 45, 45, 45, 48, 53, 48, 48, 48, 48, 48, 48,
45, 45, 14, 15, 16, 17, 18, 45, 14, 55, 48, 48, 18, 48, 48, 48,
2, 45, 46, 46, 45, 5, 45, 6, 53, 48, 56, 56, 48, 48, 48, 48,
45, 45, 45, 45, 45, 45, 45, 45, 48, 48, 48, 48, 48, 48, 48, 48,
45, 45, 45, 45, 45, 45, 14, 15, 48, 56, 48, 2, 3, 49, 49, 48,
16, 45, 18, 45, 2, 45, 46, 46, 5, 48, 6, 48, 48, 48, 48, 48,
45, 5, 45, 6, 45, 45, 45, 45, 48, 48, 8, 48, 48, 10, 11, 12,
45, 45, 45, 45, 45, 45, 45, 45, 13, 14, 15, 16, 17, 18, 19, 48,
45, 45, 14, 45, 16, 45, 18, 45, 48, 21, 48, 2, 48, 49, 49, 48,
2, 45, 46, 46, 45, 5, 45, 6, 5, 48, 6, 48, 48, 48, 48, 48,
45, 45, 45, 45, 45, 45, 45, 45, 48, 48, 8, 48, 48, 10, 11, 12,
45, 45, 45, 45, 45, 45, 14, 15, 13, 14, 15, 16, 17, 18, 48, 48,
16, 17, 18, 53, 45, 2, 45, 46, 48, 21, 48, 2, 48, 49, 49, 48,
46, 45, 5, 45, 6, 45, 45, 45, 5, 48, 6, 48, 48, 48, 48, 48,
45, 45, 45, 45, 45, 45, 45, 10, 48, 48, 57, 48, 48, 48, 48, 48,
45, 12, 45, 14, 15, 16, 17, 18, 48, 14, 15, 16, 17, 18, 48, 48,
45, 2, 45, 46, 46, 45, 5, 45, 48, 21, 48, 2, 48, 49, 49, 48,
6, 45, 45, 45, 45, 45, 45, 45, 5, 48, 6, 48, 48, 48, 48, 48,
53, 45, 45, 10, 45, 45, 45, 14, 48, 48, 48, 48, 48, 48, 48, 48,
15, 16, 17, 18, 45, 2, 45, 46, 48, 14, 15, 16, 17, 18, 48, 2,
46, 45, 5, 45, 6, 45, 45, 45, 48, 49, 49, 48, 5, 48, 6, 48,
45, 45, 45, 45, 54, 45, 45, 10, 48, 48, 48, 48, 48, 48, 48, 48,
11, 12, 45, 14, 15, 16, 17, 18, 48, 48, 48, 48, 48, 14, 15, 16,
45, 2, 45, 46, 46, 45, 5, 45, 48, 18, 48, 2, 48, 49, 49, 48,
6, 45, 45, 45, 45, 45, 45, 45, 5, 48, 6, 48, 48, 48, 48, 48,
45, 45, 45, 10, 11, 12, 45, 14, 48, 48, 48, 48, 48, 48, 48, 48,
15, 16, 17, 18, 45, 2, 3, 46, 48, 14, 48, 16, 48, 18, 48, 2,
46, 45, 5, 45, 6, 45, 45, 45, 48, 49, 49, 48, 5, 48, 6, 48,
45, 45, 45, 45, 8, 45, 45, 10, 48, 48, 48, 48, 48, 48, 48, 48,
11, 12, 13, 14, 15, 16, 17, 18, 48, 48, 48, 48, 48, 14, 15, 16,
45, 22, 23, 24, 24, 21, 25, 21, 17, 18, 57, 48, 2, 48, 49, 49,
26, 21, 21, 21, 21, 21, 21, 21, 48, 5, 48, 6, 48, 48, 48, 48,
55, 21, 21, 28, 29, 30, 31, 32, 48, 48, 48, 57, 48, 48, 48, 48,
33, 34, 35, 36, 37, 21, 22, 56, 48, 48, 14, 15, 16, 17, 18, 48,
24, 24, 21, 25, 21, 26, 21, 21, 2, 48, 49, 49, 48, 5, 48, 6,
21, 21, 21, 21, 21, 27, 21, 21, 48, 48, 48, 48, 48, 48, 48, 48,
28, 29, 30, 31, 32, 33, 34, 35, 48, 48, 10, 48, 12, 48, 14, 15,
36, 21, 1, 1, 2, 3, 46, 46, 16, 17, 18, 48, 48, 48, 21, 48,
45, 5, 45, 6, 1, 45, 45, 45, 2, 48, 49, 49, 48, 5, 48, 6,
45, 1, 45, 8, 45, 45, 10, 11, 48, 48, 48, 48, 48, 48, 48, 57,
12, 13, 14, 15, 16, 17, 18, 19, 48, 48, 10, 48, 48, 48, 14, 15,
45, 1, 45, 1, 1, 57, 57, 57, 16, 17, 18, 48, 48, 48, 21, 48,
57, 57, 57, 57, 57, 1, 57, 57, 2, 48, 49, 49, 48, 5, 48, 6,
57, 57, 1, 57, 57, 57, 57, 57, 48, 48, 48, 48, 48, 48, 48, 58,
57, 57, 57, 57, 57, 57, 57, 57, 48, 48, 10, 11, 12, 48, 14, 15,
57, 57, 1, 57, 58, 57, 0 16, 17, 18, 48, 48, 48, 21, 48,
2, 48, 49, 49, 48, 5, 48, 6,
48, 48, 48, 48, 48, 48, 48, 48,
48, 48, 10, 11, 12, 48, 14, 15,
16, 17, 18, 48, 48, 48, 21, 48,
2, 3, 49, 49, 48, 5, 48, 6,
48, 48, 48, 48, 48, 48, 48, 8,
48, 48, 10, 11, 12, 13, 14, 15,
16, 17, 18, 48, 48, 48, 21, 48,
23, 24, 25, 25, 22, 26, 22, 27,
22, 22, 22, 22, 22, 22, 22, 59,
22, 22, 29, 30, 31, 32, 33, 34,
35, 36, 37, 38, 22, 22, 39, 22,
23, 60, 25, 25, 22, 26, 22, 27,
22, 22, 22, 22, 22, 22, 22, 28,
22, 22, 29, 30, 31, 32, 33, 34,
35, 36, 37, 22, 22, 22, 39, 22,
1, 1, 2, 3, 49, 49, 48, 5,
48, 6, 1, 48, 48, 48, 48, 1,
48, 8, 48, 48, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 48, 1,
21, 48, 1, 1, 61, 61, 61, 61,
61, 61, 61, 61, 1, 61, 61, 61,
61, 1, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61,
61, 1, 61, 62, 61, 0
}; };
static const char _myanmar_syllable_machine_trans_targs[] = { static const char _myanmar_syllable_machine_trans_targs[] = {
0, 1, 24, 34, 0, 25, 31, 47, 0, 1, 26, 37, 0, 27, 33, 51,
36, 50, 37, 42, 43, 44, 27, 39, 39, 54, 40, 46, 47, 48, 29, 42,
40, 41, 30, 46, 51, 0, 2, 12, 43, 44, 32, 50, 55, 45, 0, 2,
0, 3, 9, 13, 14, 19, 20, 21, 13, 0, 3, 9, 14, 15, 21, 22,
5, 16, 17, 18, 8, 23, 4, 6, 23, 5, 17, 18, 19, 8, 25, 20,
7, 10, 11, 15, 22, 0, 0, 26, 4, 6, 7, 10, 12, 11, 16, 24,
28, 29, 32, 33, 35, 38, 45, 48, 0, 0, 28, 30, 31, 34, 36, 35,
49, 0, 0 38, 41, 49, 52, 53, 0, 0
}; };
static const char _myanmar_syllable_machine_trans_actions[] = { static const char _myanmar_syllable_machine_trans_actions[] = {
3, 0, 0, 0, 4, 0, 0, 0, 3, 0, 0, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0,
6, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 7, 8, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 9, 10 7, 8, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 9, 10
}; };
static const char _myanmar_syllable_machine_to_state_actions[] = { static const char _myanmar_syllable_machine_to_state_actions[] = {
@ -298,7 +325,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0
}; };
static const char _myanmar_syllable_machine_from_state_actions[] = { static const char _myanmar_syllable_machine_from_state_actions[] = {
@ -308,17 +335,17 @@ static const char _myanmar_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0
}; };
static const short _myanmar_syllable_machine_eof_trans[] = { static const short _myanmar_syllable_machine_eof_trans[] = {
0, 22, 22, 22, 22, 22, 22, 22, 0, 23, 23, 23, 23, 23, 23, 23,
22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
46, 46, 46, 46, 46, 46, 46, 46, 23, 23, 49, 49, 49, 49, 49, 49,
46, 46, 46, 46, 46, 46, 46, 46, 49, 49, 49, 49, 49, 49, 49, 49,
46, 46, 46, 46, 46, 46, 46, 22, 49, 49, 49, 49, 49, 49, 49, 49,
22, 46, 58, 58 49, 49, 49, 23, 23, 49, 62, 62
}; };
static const int myanmar_syllable_machine_start = 0; static const int myanmar_syllable_machine_start = 0;
@ -332,7 +359,7 @@ static const int myanmar_syllable_machine_en_main = 0;
#line 101 "hb-ot-shape-complex-myanmar-machine.rl" #line 102 "hb-ot-shape-complex-myanmar-machine.rl"
#define found_syllable(syllable_type) \ #define found_syllable(syllable_type) \
@ -351,7 +378,7 @@ find_syllables_myanmar (hb_buffer_t *buffer)
int cs; int cs;
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
#line 355 "hb-ot-shape-complex-myanmar-machine.hh" #line 382 "hb-ot-shape-complex-myanmar-machine.hh"
{ {
cs = myanmar_syllable_machine_start; cs = myanmar_syllable_machine_start;
ts = 0; ts = 0;
@ -359,7 +386,7 @@ find_syllables_myanmar (hb_buffer_t *buffer)
act = 0; act = 0;
} }
#line 121 "hb-ot-shape-complex-myanmar-machine.rl" #line 122 "hb-ot-shape-complex-myanmar-machine.rl"
p = 0; p = 0;
@ -367,7 +394,7 @@ find_syllables_myanmar (hb_buffer_t *buffer)
unsigned int syllable_serial = 1; unsigned int syllable_serial = 1;
#line 371 "hb-ot-shape-complex-myanmar-machine.hh" #line 398 "hb-ot-shape-complex-myanmar-machine.hh"
{ {
int _slen; int _slen;
int _trans; int _trans;
@ -381,7 +408,7 @@ _resume:
#line 1 "NONE" #line 1 "NONE"
{ts = p;} {ts = p;}
break; break;
#line 385 "hb-ot-shape-complex-myanmar-machine.hh" #line 412 "hb-ot-shape-complex-myanmar-machine.hh"
} }
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1); _keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@ -400,38 +427,38 @@ _eof_trans:
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) { switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
case 6: case 6:
#line 93 "hb-ot-shape-complex-myanmar-machine.rl" #line 94 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_consonant_syllable); }} {te = p+1;{ found_syllable (myanmar_consonant_syllable); }}
break; break;
case 4: case 4:
#line 94 "hb-ot-shape-complex-myanmar-machine.rl" #line 95 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
break; break;
case 10: case 10:
#line 95 "hb-ot-shape-complex-myanmar-machine.rl" #line 96 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_punctuation_cluster); }} {te = p+1;{ found_syllable (myanmar_punctuation_cluster); }}
break; break;
case 8: case 8:
#line 96 "hb-ot-shape-complex-myanmar-machine.rl" #line 97 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_broken_cluster); }} {te = p+1;{ found_syllable (myanmar_broken_cluster); }}
break; break;
case 3: case 3:
#line 97 "hb-ot-shape-complex-myanmar-machine.rl" #line 98 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }} {te = p+1;{ found_syllable (myanmar_non_myanmar_cluster); }}
break; break;
case 5: case 5:
#line 93 "hb-ot-shape-complex-myanmar-machine.rl" #line 94 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (myanmar_consonant_syllable); }} {te = p;p--;{ found_syllable (myanmar_consonant_syllable); }}
break; break;
case 7: case 7:
#line 96 "hb-ot-shape-complex-myanmar-machine.rl" #line 97 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (myanmar_broken_cluster); }} {te = p;p--;{ found_syllable (myanmar_broken_cluster); }}
break; break;
case 9: case 9:
#line 97 "hb-ot-shape-complex-myanmar-machine.rl" #line 98 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }} {te = p;p--;{ found_syllable (myanmar_non_myanmar_cluster); }}
break; break;
#line 435 "hb-ot-shape-complex-myanmar-machine.hh" #line 462 "hb-ot-shape-complex-myanmar-machine.hh"
} }
_again: _again:
@ -440,7 +467,7 @@ _again:
#line 1 "NONE" #line 1 "NONE"
{ts = 0;} {ts = 0;}
break; break;
#line 444 "hb-ot-shape-complex-myanmar-machine.hh" #line 471 "hb-ot-shape-complex-myanmar-machine.hh"
} }
if ( ++p != pe ) if ( ++p != pe )
@ -456,7 +483,7 @@ _again:
} }
#line 129 "hb-ot-shape-complex-myanmar-machine.rl" #line 130 "hb-ot-shape-complex-myanmar-machine.rl"
} }

View File

@ -185,7 +185,7 @@ initial_reordering_consonant_syllable (hb_buffer_t *buffer,
info[i].myanmar_position() = POS_BASE_C; info[i].myanmar_position() = POS_BASE_C;
i++; i++;
} }
indic_position_t pos = POS_AFTER_MAIN; myanmar_position_t pos = POS_AFTER_MAIN;
/* The following loop may be ugly, but it implements all of /* The following loop may be ugly, but it implements all of
* Myanmar reordering! */ * Myanmar reordering! */
for (; i < end; i++) for (; i < end; i++)

View File

@ -56,8 +56,10 @@ enum myanmar_category_t {
OT_VS = 30, /* Variation selectors */ OT_VS = 30, /* Variation selectors */
OT_P = 31, /* Punctuation */ OT_P = 31, /* Punctuation */
OT_D = 32, /* Digits except zero */ OT_D = 32, /* Digits except zero */
OT_ML = 33, /* Various consonant medial types */
}; };
using myanmar_position_t = indic_position_t;
static inline void static inline void
set_myanmar_properties (hb_glyph_info_t &info) set_myanmar_properties (hb_glyph_info_t &info)
@ -65,7 +67,7 @@ set_myanmar_properties (hb_glyph_info_t &info)
hb_codepoint_t u = info.codepoint; hb_codepoint_t u = info.codepoint;
unsigned int type = hb_indic_get_categories (u); unsigned int type = hb_indic_get_categories (u);
unsigned int cat = type & 0xFFu; unsigned int cat = type & 0xFFu;
indic_position_t pos = (indic_position_t) (type >> 8); myanmar_position_t pos = (myanmar_position_t) (type >> 8);
/* Myanmar /* Myanmar
* https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze * https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze
@ -114,10 +116,14 @@ set_myanmar_properties (hb_glyph_info_t &info)
cat = OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ cat = OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */
break; break;
case 0x103Eu: case 0x1060u: case 0x103Eu:
cat = OT_MH; cat = OT_MH;
break; break;
case 0x1060u:
cat = OT_ML;
break;
case 0x103Cu: case 0x103Cu:
cat = OT_MR; cat = OT_MR;
break; break;

View File

@ -41,7 +41,6 @@
#define USE(Cat) use_syllable_machine_ex_##Cat #define USE(Cat) use_syllable_machine_ex_##Cat
enum use_syllable_type_t { enum use_syllable_type_t {
use_independent_cluster,
use_virama_terminated_cluster, use_virama_terminated_cluster,
use_sakot_terminated_cluster, use_sakot_terminated_cluster,
use_standard_cluster, use_standard_cluster,
@ -54,8 +53,9 @@ enum use_syllable_type_t {
}; };
#line 58 "hb-ot-shape-complex-use-machine.hh" #line 57 "hb-ot-shape-complex-use-machine.hh"
#define use_syllable_machine_ex_B 1u #define use_syllable_machine_ex_B 1u
#define use_syllable_machine_ex_CGJ 6u
#define use_syllable_machine_ex_CMAbv 31u #define use_syllable_machine_ex_CMAbv 31u
#define use_syllable_machine_ex_CMBlw 32u #define use_syllable_machine_ex_CMBlw 32u
#define use_syllable_machine_ex_CS 43u #define use_syllable_machine_ex_CS 43u
@ -78,7 +78,6 @@ enum use_syllable_type_t {
#define use_syllable_machine_ex_N 4u #define use_syllable_machine_ex_N 4u
#define use_syllable_machine_ex_O 0u #define use_syllable_machine_ex_O 0u
#define use_syllable_machine_ex_R 18u #define use_syllable_machine_ex_R 18u
#define use_syllable_machine_ex_S 19u
#define use_syllable_machine_ex_SB 51u #define use_syllable_machine_ex_SB 51u
#define use_syllable_machine_ex_SE 52u #define use_syllable_machine_ex_SE 52u
#define use_syllable_machine_ex_SMAbv 41u #define use_syllable_machine_ex_SMAbv 41u
@ -96,280 +95,278 @@ enum use_syllable_type_t {
#define use_syllable_machine_ex_ZWNJ 14u #define use_syllable_machine_ex_ZWNJ 14u
#line 100 "hb-ot-shape-complex-use-machine.hh" #line 99 "hb-ot-shape-complex-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = { static const unsigned char _use_syllable_machine_trans_keys[] = {
1u, 1u, 1u, 1u, 0u, 51u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u, 0u, 51u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u, 23u, 48u,
24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u, 24u, 48u,
1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u, 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 22u, 48u,
11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 41u, 42u, 42u, 42u, 11u, 48u, 11u, 48u, 1u, 48u, 13u, 13u, 4u, 4u, 11u, 48u, 11u, 48u, 1u, 1u, 22u, 48u,
22u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 23u, 48u, 24u, 47u, 25u, 47u, 26u, 47u, 45u, 46u, 46u, 46u, 24u, 48u, 24u, 48u,
24u, 48u, 24u, 48u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u, 24u, 48u, 1u, 1u, 24u, 48u, 23u, 48u, 23u, 48u, 23u, 48u, 22u, 48u, 22u, 48u,
22u, 48u, 11u, 48u, 1u, 48u, 1u, 1u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u, 22u, 48u, 11u, 48u, 1u, 48u, 4u, 4u, 13u, 13u, 1u, 48u, 11u, 48u, 41u, 42u,
41u, 42u, 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0 42u, 42u, 1u, 5u, 50u, 52u, 49u, 52u, 49u, 51u, 0
}; };
static const char _use_syllable_machine_key_spans[] = { static const char _use_syllable_machine_key_spans[] = {
1, 1, 52, 38, 38, 1, 27, 26, 52, 2, 1, 38, 38, 1, 27, 26,
24, 23, 22, 2, 1, 25, 25, 25, 24, 23, 22, 2, 1, 25, 25, 25,
1, 25, 26, 26, 26, 27, 27, 27, 1, 25, 26, 26, 26, 27, 27, 27,
38, 48, 1, 1, 38, 2, 1, 38, 38, 48, 1, 1, 38, 38, 1, 27,
27, 26, 24, 23, 22, 2, 1, 25, 26, 24, 23, 22, 2, 1, 25, 25,
25, 25, 25, 26, 26, 26, 27, 27, 25, 1, 25, 26, 26, 26, 27, 27,
27, 38, 48, 1, 1, 1, 48, 38, 27, 38, 48, 1, 1, 48, 38, 2,
2, 1, 5, 3, 4, 3 1, 5, 3, 4, 3
}; };
static const short _use_syllable_machine_index_offsets[] = { static const short _use_syllable_machine_index_offsets[] = {
0, 2, 4, 57, 96, 135, 137, 165, 0, 53, 56, 58, 97, 136, 138, 166,
192, 217, 241, 264, 267, 269, 295, 321, 193, 218, 242, 265, 268, 270, 296, 322,
347, 349, 375, 402, 429, 456, 484, 512, 348, 350, 376, 403, 430, 457, 485, 513,
540, 579, 628, 630, 632, 671, 674, 676, 541, 580, 629, 631, 633, 672, 711, 713,
715, 743, 770, 795, 819, 842, 845, 847, 741, 768, 793, 817, 840, 843, 845, 871,
873, 899, 925, 951, 978, 1005, 1032, 1060, 897, 923, 925, 951, 978, 1005, 1032, 1060,
1088, 1116, 1155, 1204, 1206, 1208, 1210, 1259, 1088, 1116, 1155, 1204, 1206, 1208, 1257, 1296,
1298, 1301, 1303, 1309, 1313, 1318 1299, 1301, 1307, 1311, 1316
}; };
static const char _use_syllable_machine_indicies[] = { static const char _use_syllable_machine_indicies[] = {
1, 0, 2, 0, 3, 4, 5, 5, 0, 1, 2, 2, 3, 4, 2, 2,
6, 7, 5, 5, 5, 5, 5, 1, 2, 2, 2, 5, 6, 7, 2, 2,
8, 9, 5, 5, 5, 5, 10, 11, 2, 2, 8, 2, 2, 2, 9, 10,
5, 5, 12, 13, 14, 15, 16, 17, 11, 12, 13, 14, 15, 9, 16, 17,
18, 12, 19, 20, 21, 22, 23, 24, 18, 19, 20, 21, 2, 22, 23, 24,
5, 25, 26, 27, 5, 28, 29, 30, 2, 25, 26, 27, 28, 29, 30, 31,
31, 32, 33, 34, 8, 35, 5, 36, 6, 32, 2, 33, 2, 0, 35, 34,
5, 38, 39, 37, 37, 37, 37, 37, 35, 34, 37, 38, 36, 36, 36, 36,
37, 37, 37, 37, 40, 41, 42, 43, 36, 36, 36, 36, 36, 39, 40, 41,
44, 45, 46, 40, 47, 4, 48, 49, 42, 43, 44, 45, 39, 46, 1, 47,
50, 51, 37, 52, 53, 54, 37, 37, 48, 49, 50, 36, 51, 52, 53, 36,
37, 37, 55, 56, 57, 58, 39, 37, 36, 36, 36, 54, 55, 56, 57, 38,
38, 39, 37, 37, 37, 37, 37, 37, 36, 37, 38, 36, 36, 36, 36, 36,
37, 37, 37, 40, 41, 42, 43, 44, 36, 36, 36, 36, 39, 40, 41, 42,
45, 46, 40, 47, 48, 48, 49, 50, 43, 44, 45, 39, 46, 47, 47, 48,
51, 37, 52, 53, 54, 37, 37, 37, 49, 50, 36, 51, 52, 53, 36, 36,
37, 55, 56, 57, 58, 39, 37, 38, 36, 36, 54, 55, 56, 57, 38, 36,
59, 40, 41, 42, 43, 44, 37, 37, 37, 58, 39, 40, 41, 42, 43, 36,
37, 37, 37, 37, 49, 50, 51, 37, 36, 36, 36, 36, 36, 48, 49, 50,
52, 53, 54, 37, 37, 37, 37, 41, 36, 51, 52, 53, 36, 36, 36, 36,
56, 57, 58, 60, 37, 41, 42, 43, 40, 55, 56, 57, 59, 36, 40, 41,
44, 37, 37, 37, 37, 37, 37, 37, 42, 43, 36, 36, 36, 36, 36, 36,
37, 37, 37, 52, 53, 54, 37, 37, 36, 36, 36, 36, 51, 52, 53, 36,
37, 37, 37, 56, 57, 58, 60, 37, 36, 36, 36, 36, 55, 56, 57, 59,
42, 43, 44, 37, 37, 37, 37, 37, 36, 41, 42, 43, 36, 36, 36, 36,
37, 37, 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, 36,
37, 37, 37, 37, 37, 56, 57, 58, 36, 36, 36, 36, 36, 36, 55, 56,
37, 43, 44, 37, 37, 37, 37, 37, 57, 36, 42, 43, 36, 36, 36, 36,
37, 37, 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, 36,
37, 37, 37, 37, 37, 56, 57, 58, 36, 36, 36, 36, 36, 36, 55, 56,
37, 44, 37, 37, 37, 37, 37, 37, 57, 36, 43, 36, 36, 36, 36, 36,
37, 37, 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, 36,
37, 37, 37, 37, 56, 57, 58, 37, 36, 36, 36, 36, 36, 55, 56, 57,
56, 57, 37, 57, 37, 42, 43, 44, 36, 55, 56, 36, 56, 36, 41, 42,
37, 37, 37, 37, 37, 37, 37, 37, 43, 36, 36, 36, 36, 36, 36, 36,
37, 37, 52, 53, 54, 37, 37, 37, 36, 36, 36, 51, 52, 53, 36, 36,
37, 37, 56, 57, 58, 60, 37, 42, 36, 36, 36, 55, 56, 57, 59, 36,
43, 44, 37, 37, 37, 37, 37, 37, 41, 42, 43, 36, 36, 36, 36, 36,
37, 37, 37, 37, 37, 53, 54, 37, 36, 36, 36, 36, 36, 36, 52, 53,
37, 37, 37, 37, 56, 57, 58, 60, 36, 36, 36, 36, 36, 55, 56, 57,
37, 42, 43, 44, 37, 37, 37, 37, 59, 36, 41, 42, 43, 36, 36, 36,
37, 37, 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, 36,
54, 37, 37, 37, 37, 37, 56, 57, 36, 53, 36, 36, 36, 36, 36, 55,
58, 60, 37, 62, 61, 42, 43, 44, 56, 57, 59, 36, 61, 60, 41, 42,
37, 37, 37, 37, 37, 37, 37, 37, 43, 36, 36, 36, 36, 36, 36, 36,
37, 37, 37, 37, 37, 37, 37, 37, 36, 36, 36, 36, 36, 36, 36, 36,
37, 37, 56, 57, 58, 60, 37, 41, 36, 36, 36, 55, 56, 57, 59, 36,
42, 43, 44, 37, 37, 37, 37, 37, 40, 41, 42, 43, 36, 36, 36, 36,
37, 49, 50, 51, 37, 52, 53, 54, 36, 36, 48, 49, 50, 36, 51, 52,
37, 37, 37, 37, 41, 56, 57, 58, 53, 36, 36, 36, 36, 40, 55, 56,
60, 37, 41, 42, 43, 44, 37, 37, 57, 59, 36, 40, 41, 42, 43, 36,
37, 37, 37, 37, 37, 50, 51, 37, 36, 36, 36, 36, 36, 36, 49, 50,
52, 53, 54, 37, 37, 37, 37, 41, 36, 51, 52, 53, 36, 36, 36, 36,
56, 57, 58, 60, 37, 41, 42, 43, 40, 55, 56, 57, 59, 36, 40, 41,
44, 37, 37, 37, 37, 37, 37, 37, 42, 43, 36, 36, 36, 36, 36, 36,
37, 51, 37, 52, 53, 54, 37, 37, 36, 36, 50, 36, 51, 52, 53, 36,
37, 37, 41, 56, 57, 58, 60, 37, 36, 36, 36, 40, 55, 56, 57, 59,
40, 41, 42, 43, 44, 37, 46, 40, 36, 39, 40, 41, 42, 43, 36, 45,
37, 37, 37, 49, 50, 51, 37, 52, 39, 36, 36, 36, 48, 49, 50, 36,
53, 54, 37, 37, 37, 37, 41, 56, 51, 52, 53, 36, 36, 36, 36, 40,
57, 58, 60, 37, 40, 41, 42, 43, 55, 56, 57, 59, 36, 39, 40, 41,
44, 37, 37, 40, 37, 37, 37, 49, 42, 43, 36, 36, 39, 36, 36, 36,
50, 51, 37, 52, 53, 54, 37, 37, 48, 49, 50, 36, 51, 52, 53, 36,
37, 37, 41, 56, 57, 58, 60, 37, 36, 36, 36, 40, 55, 56, 57, 59,
40, 41, 42, 43, 44, 45, 46, 40, 36, 39, 40, 41, 42, 43, 44, 45,
37, 37, 37, 49, 50, 51, 37, 52, 39, 36, 36, 36, 48, 49, 50, 36,
53, 54, 37, 37, 37, 37, 41, 56, 51, 52, 53, 36, 36, 36, 36, 40,
57, 58, 60, 37, 38, 39, 37, 37, 55, 56, 57, 59, 36, 37, 38, 36,
37, 37, 37, 37, 37, 37, 37, 40, 36, 36, 36, 36, 36, 36, 36, 36,
41, 42, 43, 44, 45, 46, 40, 47, 39, 40, 41, 42, 43, 44, 45, 39,
37, 48, 49, 50, 51, 37, 52, 53, 46, 36, 47, 48, 49, 50, 36, 51,
54, 37, 37, 37, 37, 55, 56, 57, 52, 53, 36, 36, 36, 36, 54, 55,
58, 39, 37, 38, 59, 59, 59, 59, 56, 57, 38, 36, 37, 58, 58, 58,
59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 58, 58, 58, 58, 58,
59, 59, 59, 59, 59, 59, 59, 59, 58, 58, 58, 58, 58, 58, 58, 58,
59, 41, 42, 43, 44, 59, 59, 59, 58, 58, 40, 41, 42, 43, 58, 58,
59, 59, 59, 59, 59, 59, 59, 52, 58, 58, 58, 58, 58, 58, 58, 58,
53, 54, 59, 59, 59, 59, 59, 56, 51, 52, 53, 58, 58, 58, 58, 58,
57, 58, 60, 59, 64, 63, 6, 65, 55, 56, 57, 59, 58, 63, 62, 3,
38, 39, 37, 37, 37, 37, 37, 37, 64, 37, 38, 36, 36, 36, 36, 36,
37, 37, 37, 40, 41, 42, 43, 44, 36, 36, 36, 36, 39, 40, 41, 42,
45, 46, 40, 47, 4, 48, 49, 50, 43, 44, 45, 39, 46, 1, 47, 48,
51, 37, 52, 53, 54, 37, 11, 66, 49, 50, 36, 51, 52, 53, 36, 0,
37, 55, 56, 57, 58, 39, 37, 11, 35, 36, 54, 55, 56, 57, 38, 36,
66, 67, 66, 67, 1, 69, 68, 68, 5, 6, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 12, 65, 65, 65, 9, 10, 11, 12, 13,
13, 14, 15, 16, 17, 18, 12, 19, 14, 15, 9, 16, 18, 18, 19, 20,
21, 21, 22, 23, 24, 68, 25, 26, 21, 65, 22, 23, 24, 65, 65, 65,
27, 68, 68, 68, 68, 31, 32, 33, 65, 28, 29, 30, 31, 6, 65, 5,
34, 69, 68, 12, 13, 14, 15, 16, 65, 9, 10, 11, 12, 13, 65, 65,
68, 68, 68, 68, 68, 68, 22, 23, 65, 65, 65, 65, 19, 20, 21, 65,
24, 68, 25, 26, 27, 68, 68, 68, 22, 23, 24, 65, 65, 65, 65, 10,
68, 13, 32, 33, 34, 70, 68, 13, 29, 30, 31, 66, 65, 10, 11, 12,
14, 15, 16, 68, 68, 68, 68, 68, 13, 65, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 25, 26, 27, 65, 65, 65, 22, 23, 24, 65, 65,
68, 68, 68, 68, 68, 32, 33, 34, 65, 65, 65, 29, 30, 31, 66, 65,
70, 68, 14, 15, 16, 68, 68, 68, 11, 12, 13, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 32, 65, 65, 65, 65, 65, 29, 30, 31,
33, 34, 68, 15, 16, 68, 68, 68, 65, 12, 13, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 32, 65, 65, 65, 65, 65, 29, 30, 31,
33, 34, 68, 16, 68, 68, 68, 68, 65, 13, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 32, 33, 65, 65, 65, 65, 29, 30, 31, 65,
34, 68, 32, 33, 68, 33, 68, 14, 29, 30, 65, 30, 65, 11, 12, 13,
15, 16, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 25, 26, 27, 68, 65, 65, 22, 23, 24, 65, 65, 65,
68, 68, 68, 68, 32, 33, 34, 70, 65, 65, 29, 30, 31, 66, 65, 11,
68, 14, 15, 16, 68, 68, 68, 68, 12, 13, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 26, 65, 65, 65, 65, 65, 23, 24, 65,
27, 68, 68, 68, 68, 68, 32, 33, 65, 65, 65, 65, 29, 30, 31, 66,
34, 70, 68, 14, 15, 16, 68, 68, 65, 11, 12, 13, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 68, 27, 68, 68, 68, 68, 68, 24, 65, 65, 65, 65, 65, 29, 30,
32, 33, 34, 70, 68, 14, 15, 16, 31, 66, 65, 67, 65, 11, 12, 13,
68, 68, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 68, 32, 33, 34, 70, 68, 13, 65, 65, 29, 30, 31, 66, 65, 10,
14, 15, 16, 68, 68, 68, 68, 68, 11, 12, 13, 65, 65, 65, 65, 65,
68, 22, 23, 24, 68, 25, 26, 27, 65, 19, 20, 21, 65, 22, 23, 24,
68, 68, 68, 68, 13, 32, 33, 34, 65, 65, 65, 65, 10, 29, 30, 31,
70, 68, 13, 14, 15, 16, 68, 68, 66, 65, 10, 11, 12, 13, 65, 65,
68, 68, 68, 68, 68, 23, 24, 68, 65, 65, 65, 65, 65, 20, 21, 65,
25, 26, 27, 68, 68, 68, 68, 13, 22, 23, 24, 65, 65, 65, 65, 10,
32, 33, 34, 70, 68, 13, 14, 15, 29, 30, 31, 66, 65, 10, 11, 12,
16, 68, 68, 68, 68, 68, 68, 68, 13, 65, 65, 65, 65, 65, 65, 65,
68, 24, 68, 25, 26, 27, 68, 68, 65, 21, 65, 22, 23, 24, 65, 65,
68, 68, 13, 32, 33, 34, 70, 68, 65, 65, 10, 29, 30, 31, 66, 65,
12, 13, 14, 15, 16, 68, 18, 12, 9, 10, 11, 12, 13, 65, 15, 9,
68, 68, 68, 22, 23, 24, 68, 25, 65, 65, 65, 19, 20, 21, 65, 22,
26, 27, 68, 68, 68, 68, 13, 32, 23, 24, 65, 65, 65, 65, 10, 29,
33, 34, 70, 68, 12, 13, 14, 15, 30, 31, 66, 65, 9, 10, 11, 12,
16, 68, 68, 12, 68, 68, 68, 22, 13, 65, 65, 9, 65, 65, 65, 19,
23, 24, 68, 25, 26, 27, 68, 68, 20, 21, 65, 22, 23, 24, 65, 65,
68, 68, 13, 32, 33, 34, 70, 68, 65, 65, 10, 29, 30, 31, 66, 65,
12, 13, 14, 15, 16, 17, 18, 12, 9, 10, 11, 12, 13, 14, 15, 9,
68, 68, 68, 22, 23, 24, 68, 25, 65, 65, 65, 19, 20, 21, 65, 22,
26, 27, 68, 68, 68, 68, 13, 32, 23, 24, 65, 65, 65, 65, 10, 29,
33, 34, 70, 68, 1, 69, 68, 68, 30, 31, 66, 65, 5, 6, 65, 65,
68, 68, 68, 68, 68, 68, 68, 12, 65, 65, 65, 65, 65, 65, 65, 9,
13, 14, 15, 16, 17, 18, 12, 19, 10, 11, 12, 13, 14, 15, 9, 16,
68, 21, 22, 23, 24, 68, 25, 26, 65, 18, 19, 20, 21, 65, 22, 23,
27, 68, 68, 68, 68, 31, 32, 33, 24, 65, 65, 65, 65, 28, 29, 30,
34, 69, 68, 1, 68, 68, 68, 68, 31, 6, 65, 5, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 68, 65, 65, 65, 65, 65, 65, 65, 65,
68, 13, 14, 15, 16, 68, 68, 68, 65, 10, 11, 12, 13, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 25, 65, 65, 65, 65, 65, 65, 65, 22,
26, 27, 68, 68, 68, 68, 68, 32, 23, 24, 65, 65, 65, 65, 65, 29,
33, 34, 70, 68, 1, 71, 72, 68, 30, 31, 66, 65, 68, 65, 7, 65,
9, 68, 4, 68, 68, 68, 4, 68, 1, 65, 65, 65, 1, 65, 65, 65,
68, 68, 68, 68, 1, 69, 9, 68, 65, 65, 5, 6, 7, 65, 65, 65,
68, 68, 68, 68, 68, 68, 68, 12, 65, 65, 65, 65, 65, 9, 10, 11,
13, 14, 15, 16, 17, 18, 12, 19, 12, 13, 14, 15, 9, 16, 17, 18,
20, 21, 22, 23, 24, 68, 25, 26, 19, 20, 21, 65, 22, 23, 24, 65,
27, 68, 28, 29, 68, 31, 32, 33, 25, 26, 65, 28, 29, 30, 31, 6,
34, 69, 68, 1, 69, 68, 68, 68, 65, 5, 6, 65, 65, 65, 65, 65,
68, 68, 68, 68, 68, 68, 12, 13, 65, 65, 65, 65, 9, 10, 11, 12,
14, 15, 16, 17, 18, 12, 19, 20, 13, 14, 15, 9, 16, 17, 18, 19,
21, 22, 23, 24, 68, 25, 26, 27, 20, 21, 65, 22, 23, 24, 65, 65,
68, 68, 68, 68, 31, 32, 33, 34, 65, 65, 28, 29, 30, 31, 6, 65,
69, 68, 28, 29, 68, 29, 68, 4, 25, 26, 65, 26, 65, 1, 69, 69,
71, 71, 71, 4, 71, 74, 73, 35, 69, 1, 69, 71, 70, 32, 70, 32,
73, 35, 74, 73, 74, 73, 35, 73, 71, 70, 71, 70, 32, 70, 33, 70,
36, 73, 0 0
}; };
static const char _use_syllable_machine_trans_targs[] = { static const char _use_syllable_machine_trans_targs[] = {
2, 31, 42, 2, 3, 2, 26, 28, 1, 3, 0, 26, 28, 29, 30, 51,
51, 52, 54, 29, 32, 33, 34, 35, 53, 31, 32, 33, 34, 35, 46, 47,
36, 46, 47, 48, 55, 49, 43, 44, 48, 54, 49, 43, 44, 45, 38, 39,
45, 39, 40, 41, 56, 57, 58, 50, 40, 55, 56, 57, 50, 36, 37, 0,
37, 38, 2, 59, 61, 2, 4, 5, 58, 60, 0, 2, 0, 4, 5, 6,
6, 7, 8, 9, 10, 21, 22, 23, 7, 8, 9, 10, 21, 22, 23, 24,
24, 18, 19, 20, 13, 14, 15, 25, 18, 19, 20, 13, 14, 15, 25, 11,
11, 12, 2, 2, 16, 2, 17, 2, 12, 0, 0, 16, 0, 17, 0, 27,
27, 2, 30, 2, 2, 0, 1, 2, 0, 0, 41, 42, 52, 0, 0, 59
53, 2, 60
}; };
static const char _use_syllable_machine_trans_actions[] = { static const char _use_syllable_machine_trans_actions[] = {
1, 2, 2, 5, 0, 6, 0, 0,
0, 0, 2, 0, 2, 2, 0, 0,
0, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 0, 0, 0, 2,
0, 0, 7, 0, 0, 8, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 9, 10, 0, 11, 0, 12,
0, 13, 0, 14, 15, 0, 0, 16,
0, 17, 0
};
static const char _use_syllable_machine_to_state_actions[] = {
0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 4,
0, 0, 5, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 7, 8, 0, 9, 0, 10, 0,
11, 12, 0, 0, 0, 13, 14, 0
};
static const char _use_syllable_machine_to_state_actions[] = {
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0
}; };
static const char _use_syllable_machine_from_state_actions[] = { static const char _use_syllable_machine_from_state_actions[] = {
0, 0, 4, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0 0, 0, 0, 0, 0
}; };
static const short _use_syllable_machine_eof_trans[] = { static const short _use_syllable_machine_eof_trans[] = {
1, 1, 0, 38, 38, 60, 38, 38, 0, 35, 35, 37, 37, 59, 37, 37,
38, 38, 38, 38, 38, 38, 38, 38, 37, 37, 37, 37, 37, 37, 37, 37,
62, 38, 38, 38, 38, 38, 38, 38, 61, 37, 37, 37, 37, 37, 37, 37,
38, 60, 64, 66, 38, 68, 68, 69, 37, 59, 63, 65, 37, 66, 66, 66,
69, 69, 69, 69, 69, 69, 69, 69, 66, 66, 66, 66, 66, 66, 66, 66,
69, 69, 69, 69, 69, 69, 69, 69, 66, 66, 66, 66, 66, 66, 66, 66,
69, 69, 69, 72, 69, 69, 69, 69, 66, 66, 66, 66, 66, 66, 66, 66,
69, 69, 72, 74, 74, 74 66, 70, 71, 71, 71
}; };
static const int use_syllable_machine_start = 2; static const int use_syllable_machine_start = 0;
static const int use_syllable_machine_first_final = 2; static const int use_syllable_machine_first_final = 0;
static const int use_syllable_machine_error = -1; static const int use_syllable_machine_error = -1;
static const int use_syllable_machine_en_main = 2; static const int use_syllable_machine_en_main = 0;
#line 59 "hb-ot-shape-complex-use-machine.rl" #line 58 "hb-ot-shape-complex-use-machine.rl"
#line 176 "hb-ot-shape-complex-use-machine.rl" #line 179 "hb-ot-shape-complex-use-machine.rl"
#define found_syllable(syllable_type) \ #define found_syllable(syllable_type) \
@ -422,8 +419,8 @@ HB_FUNCOBJ (machine_index);
static bool static bool
not_standard_default_ignorable (const hb_glyph_info_t &i) not_ccs_default_ignorable (const hb_glyph_info_t &i)
{ return !(i.use_category() == USE(O) && _hb_glyph_info_is_default_ignorable (&i)); } { return !(i.use_category() == USE(CGJ) && _hb_glyph_info_is_default_ignorable (&i)); }
static inline void static inline void
find_syllables_use (hb_buffer_t *buffer) find_syllables_use (hb_buffer_t *buffer)
@ -432,13 +429,13 @@ find_syllables_use (hb_buffer_t *buffer)
auto p = auto p =
+ hb_iter (info, buffer->len) + hb_iter (info, buffer->len)
| hb_enumerate | hb_enumerate
| hb_filter ([] (const hb_glyph_info_t &i) { return not_standard_default_ignorable (i); }, | hb_filter ([] (const hb_glyph_info_t &i) { return not_ccs_default_ignorable (i); },
hb_second) hb_second)
| hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p) | hb_filter ([&] (const hb_pair_t<unsigned, const hb_glyph_info_t &> p)
{ {
if (p.second.use_category() == USE(ZWNJ)) if (p.second.use_category() == USE(ZWNJ))
for (unsigned i = p.first + 1; i < buffer->len; ++i) for (unsigned i = p.first + 1; i < buffer->len; ++i)
if (not_standard_default_ignorable (info[i])) if (not_ccs_default_ignorable (info[i]))
return !_hb_glyph_info_is_unicode_mark (&info[i]); return !_hb_glyph_info_is_unicode_mark (&info[i]);
return true; return true;
}) })
@ -452,7 +449,7 @@ find_syllables_use (hb_buffer_t *buffer)
unsigned int act HB_UNUSED; unsigned int act HB_UNUSED;
int cs; int cs;
#line 456 "hb-ot-shape-complex-use-machine.hh" #line 453 "hb-ot-shape-complex-use-machine.hh"
{ {
cs = use_syllable_machine_start; cs = use_syllable_machine_start;
ts = 0; ts = 0;
@ -460,12 +457,12 @@ find_syllables_use (hb_buffer_t *buffer)
act = 0; act = 0;
} }
#line 260 "hb-ot-shape-complex-use-machine.rl" #line 263 "hb-ot-shape-complex-use-machine.rl"
unsigned int syllable_serial = 1; unsigned int syllable_serial = 1;
#line 469 "hb-ot-shape-complex-use-machine.hh" #line 466 "hb-ot-shape-complex-use-machine.hh"
{ {
int _slen; int _slen;
int _trans; int _trans;
@ -475,11 +472,11 @@ find_syllables_use (hb_buffer_t *buffer)
goto _test_eof; goto _test_eof;
_resume: _resume:
switch ( _use_syllable_machine_from_state_actions[cs] ) { switch ( _use_syllable_machine_from_state_actions[cs] ) {
case 4: case 2:
#line 1 "NONE" #line 1 "NONE"
{ts = p;} {ts = p;}
break; break;
#line 483 "hb-ot-shape-complex-use-machine.hh" #line 480 "hb-ot-shape-complex-use-machine.hh"
} }
_keys = _use_syllable_machine_trans_keys + (cs<<1); _keys = _use_syllable_machine_trans_keys + (cs<<1);
@ -497,76 +494,64 @@ _eof_trans:
goto _again; goto _again;
switch ( _use_syllable_machine_trans_actions[_trans] ) { switch ( _use_syllable_machine_trans_actions[_trans] ) {
case 2: case 7:
#line 1 "NONE" #line 169 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;}
break;
case 5:
#line 163 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (use_independent_cluster); }}
break;
case 9:
#line 166 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (use_standard_cluster); }} {te = p+1;{ found_syllable (use_standard_cluster); }}
break; break;
case 7: case 4:
#line 171 "hb-ot-shape-complex-use-machine.rl" #line 174 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (use_broken_cluster); }} {te = p+1;{ found_syllable (use_broken_cluster); }}
break; break;
case 6: case 3:
#line 172 "hb-ot-shape-complex-use-machine.rl" #line 175 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (use_non_cluster); }} {te = p+1;{ found_syllable (use_non_cluster); }}
break; break;
case 10: case 8:
#line 164 "hb-ot-shape-complex-use-machine.rl" #line 167 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_virama_terminated_cluster); }} {te = p;p--;{ found_syllable (use_virama_terminated_cluster); }}
break; break;
case 11: case 9:
#line 165 "hb-ot-shape-complex-use-machine.rl" #line 168 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }} {te = p;p--;{ found_syllable (use_sakot_terminated_cluster); }}
break; break;
case 8: case 6:
#line 166 "hb-ot-shape-complex-use-machine.rl" #line 169 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_standard_cluster); }} {te = p;p--;{ found_syllable (use_standard_cluster); }}
break; break;
case 13: case 11:
#line 167 "hb-ot-shape-complex-use-machine.rl" #line 170 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }} {te = p;p--;{ found_syllable (use_number_joiner_terminated_cluster); }}
break; break;
case 12: case 10:
#line 168 "hb-ot-shape-complex-use-machine.rl" #line 171 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_numeral_cluster); }} {te = p;p--;{ found_syllable (use_numeral_cluster); }}
break; break;
case 14: case 5:
#line 169 "hb-ot-shape-complex-use-machine.rl" #line 172 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_symbol_cluster); }} {te = p;p--;{ found_syllable (use_symbol_cluster); }}
break; break;
case 17: case 14:
#line 170 "hb-ot-shape-complex-use-machine.rl" #line 173 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_hieroglyph_cluster); }} {te = p;p--;{ found_syllable (use_hieroglyph_cluster); }}
break; break;
case 15: case 12:
#line 171 "hb-ot-shape-complex-use-machine.rl" #line 174 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_broken_cluster); }} {te = p;p--;{ found_syllable (use_broken_cluster); }}
break; break;
case 16: case 13:
#line 172 "hb-ot-shape-complex-use-machine.rl" #line 175 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (use_non_cluster); }} {te = p;p--;{ found_syllable (use_non_cluster); }}
break; break;
case 1: #line 546 "hb-ot-shape-complex-use-machine.hh"
#line 171 "hb-ot-shape-complex-use-machine.rl"
{{p = ((te))-1;}{ found_syllable (use_broken_cluster); }}
break;
#line 561 "hb-ot-shape-complex-use-machine.hh"
} }
_again: _again:
switch ( _use_syllable_machine_to_state_actions[cs] ) { switch ( _use_syllable_machine_to_state_actions[cs] ) {
case 3: case 1:
#line 1 "NONE" #line 1 "NONE"
{ts = 0;} {ts = 0;}
break; break;
#line 570 "hb-ot-shape-complex-use-machine.hh" #line 555 "hb-ot-shape-complex-use-machine.hh"
} }
if ( ++p != pe ) if ( ++p != pe )
@ -582,7 +567,7 @@ _again:
} }
#line 265 "hb-ot-shape-complex-use-machine.rl" #line 268 "hb-ot-shape-complex-use-machine.rl"
} }

View File

@ -2,7 +2,7 @@
/* /*
* The following table is generated by running: * The following table is generated by running:
* *
* ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt ArabicShaping.txt Blocks.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt * ./gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt ArabicShaping.txt DerivedCoreProperties.txt UnicodeData.txt Blocks.txt Scripts.txt IndicSyllabicCategory-Additional.txt IndicPositionalCategory-Additional.txt
* *
* on files with these headers: * on files with these headers:
* *
@ -12,22 +12,28 @@
* # Date: 2021-05-22, 01:01:00 GMT [KW, RP] * # Date: 2021-05-22, 01:01:00 GMT [KW, RP]
* # ArabicShaping-14.0.0.txt * # ArabicShaping-14.0.0.txt
* # Date: 2021-05-21, 01:54:00 GMT [KW, RP] * # Date: 2021-05-21, 01:54:00 GMT [KW, RP]
* # DerivedCoreProperties-14.0.0.txt
* # Date: 2021-08-12, 23:12:53 GMT
* # Blocks-14.0.0.txt * # Blocks-14.0.0.txt
* # Date: 2021-01-22, 23:29:00 GMT [KW] * # Date: 2021-01-22, 23:29:00 GMT [KW]
* # Scripts-14.0.0.txt
* # Date: 2021-07-10, 00:35:31 GMT
* # Override values For Indic_Syllabic_Category * # Override values For Indic_Syllabic_Category
* # Not derivable * # Not derivable
* # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
* # Updated for Unicode 10.0 by Andrew Glass 2017-07-25 * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
* # Updated for Unicode 12.1 by Andrew Glass 2019-05-24 * # Updated for Unicode 12.1 by Andrew Glass 2019-05-24
* # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
* # Updated for Unicode 14.0 by Andrew Glass 2021-09-25
* # Override values For Indic_Positional_Category * # Override values For Indic_Positional_Category
* # Not derivable * # Not derivable
* # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17 * # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
* # Updated for Unicode 10.0 by Andrew Glass 2017-07-25 * # Updated for Unicode 10.0 by Andrew Glass 2017-07-25
* # Ammended for Unicode 10.0 by Andrew Glass 2018-09-21 * # Ammended for Unicode 10.0 by Andrew Glass 2018-09-21
* # Updated for L2/19-083 by Andrew Glass 2019-05-06 * # Updated for L2/19-083 by Andrew Glass 2019-05-06
* # Updated for Unicode 12.1 by Andrew Glass 2019-05-30 * # Updated for Unicode 12.1 by Andrew Glass 2019-05-30
* # Updated for Unicode 13.0 by Andrew Glass 2020-07-28 * # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
* # Updated for Unicode 14.0 by Andrew Glass 2021-09-28
* UnicodeData.txt does not have a header. * UnicodeData.txt does not have a header.
*/ */
@ -41,6 +47,7 @@
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-macros" #pragma GCC diagnostic ignored "-Wunused-macros"
#define B USE(B) /* BASE */ #define B USE(B) /* BASE */
#define CGJ USE(CGJ) /* CGJ */
#define CS USE(CS) /* CONS_WITH_STACKER */ #define CS USE(CS) /* CONS_WITH_STACKER */
#define G USE(G) /* HIEROGLYPH */ #define G USE(G) /* HIEROGLYPH */
#define GB USE(GB) /* BASE_OTHER */ #define GB USE(GB) /* BASE_OTHER */
@ -51,7 +58,6 @@
#define N USE(N) /* BASE_NUM */ #define N USE(N) /* BASE_NUM */
#define O USE(O) /* OTHER */ #define O USE(O) /* OTHER */
#define R USE(R) /* REPHA */ #define R USE(R) /* REPHA */
#define S USE(S) /* SYM */
#define SB USE(SB) /* HIEROGLYPH_SEGMENT_BEGIN */ #define SB USE(SB) /* HIEROGLYPH_SEGMENT_BEGIN */
#define SE USE(SE) /* HIEROGLYPH_SEGMENT_END */ #define SE USE(SE) /* HIEROGLYPH_SEGMENT_END */
#define SUB USE(SUB) /* CONS_SUB */ #define SUB USE(SUB) /* CONS_SUB */
@ -101,14 +107,20 @@ static const uint8_t use_table[] = {
/* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 00D0 */ O, O, O, O, O, O, O, GB, /* 00D0 */ O, O, O, O, O, O, O, GB,
#define use_offset_0x0640u 80 #define use_offset_0x0348u 80
/* Combining Diacritical Marks */
O, O, O, O, O, O, O, CGJ,
#define use_offset_0x0640u 88
/* Arabic */ /* Arabic */
/* 0640 */ B, O, O, O, O, O, O, O, /* 0640 */ B, O, O, O, O, O, O, O,
#define use_offset_0x07c8u 88 #define use_offset_0x07c8u 96
/* NKo */ /* NKo */
@ -117,7 +129,7 @@ static const uint8_t use_table[] = {
/* 07E0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, /* 07E0 */ B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv,
/* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, O, O, O, B, O, O, VMAbv, O, O, /* 07F0 */ VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, O, O, O, B, O, O, VMAbv, O, O,
#define use_offset_0x0840u 144 #define use_offset_0x0840u 152
/* Mandaic */ /* Mandaic */
@ -125,7 +137,7 @@ static const uint8_t use_table[] = {
/* 0840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 0840 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 0850 */ B, B, B, B, B, B, B, B, B, CMBlw, CMBlw, CMBlw, O, O, O, O, /* 0850 */ B, B, B, B, B, B, B, B, B, CMBlw, CMBlw, CMBlw, O, O, O, O,
#define use_offset_0x0900u 176 #define use_offset_0x0900u 184
/* Devanagari */ /* Devanagari */
@ -238,7 +250,7 @@ static const uint8_t use_table[] = {
/* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B, /* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0DF0 */ O, O, VPst, VPst, O, O, O, O, /* 0DF0 */ O, O, VPst, VPst, O, O, O, O,
#define use_offset_0x0f00u 1448 #define use_offset_0x0f00u 1456
/* Tibetan */ /* Tibetan */
@ -257,7 +269,7 @@ static const uint8_t use_table[] = {
/* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O, /* 0FB0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, O, O,
/* 0FC0 */ O, O, O, O, O, O, FBlw, O, /* 0FC0 */ O, O, O, O, O, O, FBlw, O,
#define use_offset_0x1000u 1648 #define use_offset_0x1000u 1656
/* Myanmar */ /* Myanmar */
@ -273,7 +285,7 @@ static const uint8_t use_table[] = {
/* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst, /* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst,
/* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O, /* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O,
#define use_offset_0x1700u 1808 #define use_offset_0x1700u 1816
/* Tagalog */ /* Tagalog */
@ -301,7 +313,7 @@ static const uint8_t use_table[] = {
/* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1780 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1790 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 17A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 17B0 */ B, B, B, B, O, O, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre, /* 17B0 */ B, B, B, B, CGJ, CGJ, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VPre, VPre,
/* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, VMAbv, /* 17C0 */ VPre, VPre, VPre, VPre, VPre, VPre, VMAbv, VMPst, VPst, VMAbv, VMAbv, FMAbv, FAbv, CMAbv, FMAbv, VMAbv,
/* 17D0 */ FMAbv, VAbv, H, FMAbv, O, O, O, O, O, O, O, O, B, FMAbv, O, O, /* 17D0 */ FMAbv, VAbv, H, FMAbv, O, O, O, O, O, O, O, O, B, FMAbv, O, O,
/* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
@ -309,7 +321,7 @@ static const uint8_t use_table[] = {
/* Mongolian */ /* Mongolian */
/* 1800 */ B, O, O, O, O, O, O, B, O, O, B, O, O, O, O, O, /* 1800 */ B, O, O, O, O, O, O, B, O, O, B, CGJ, CGJ, CGJ, O, CGJ,
/* 1810 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 1810 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 1820 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1820 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1830 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1830 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
@ -321,7 +333,7 @@ static const uint8_t use_table[] = {
/* 1890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1890 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18A0 */ B, B, B, B, B, B, B, B, B, CMBlw, B, O, O, O, O, O, /* 18A0 */ B, B, B, B, B, B, B, B, B, CMBlw, B, O, O, O, O, O,
#define use_offset_0x1900u 2240 #define use_offset_0x1900u 2248
/* Limbu */ /* Limbu */
@ -365,7 +377,7 @@ static const uint8_t use_table[] = {
/* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x1b00u 2656 #define use_offset_0x1b00u 2664
/* Balinese */ /* Balinese */
@ -376,7 +388,7 @@ static const uint8_t use_table[] = {
/* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre,
/* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, B, O, O, O, /* 1B40 */ VPre, VPre, VAbv, VAbv, H, B, B, B, B, B, B, B, B, O, O, O,
/* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB, /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB,
/* 1B60 */ O, S, GB, S, S, S, S, S, GB, S, S, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, /* 1B60 */ O, O, GB, O, O, O, O, O, GB, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv,
/* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O,
/* Sundanese */ /* Sundanese */
@ -401,7 +413,7 @@ static const uint8_t use_table[] = {
/* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, O, O, O, O, O, O, O, O, /* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FMAbv, CMBlw, O, O, O, O, O, O, O, O,
/* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B, /* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B,
#define use_offset_0x1cd0u 2992 #define use_offset_0x1cd0u 3000
/* Vedic Extensions */ /* Vedic Extensions */
@ -410,20 +422,20 @@ static const uint8_t use_table[] = {
/* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O, /* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O,
/* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O, /* 1CF0 */ O, O, O, O, VMAbv, CS, CS, VMPst, VMAbv, VMAbv, GB, O, O, O, O, O,
#define use_offset_0x1df8u 3040 #define use_offset_0x1df8u 3048
/* Combining Diacritical Marks Supplement */ /* Combining Diacritical Marks Supplement */
O, O, O, FMAbv, O, O, O, O, O, O, O, FMAbv, O, O, O, O,
#define use_offset_0x2008u 3048 #define use_offset_0x2008u 3056
/* General Punctuation */ /* General Punctuation */
O, O, O, O, ZWNJ, O, O, O, O, O, O, O, ZWNJ, CGJ, O, O,
/* 2010 */ GB, GB, GB, GB, GB, O, O, O, /* 2010 */ GB, GB, GB, GB, GB, O, O, O,
#define use_offset_0x2070u 3064 #define use_offset_0x2070u 3072
/* Superscripts and Subscripts */ /* Superscripts and Subscripts */
@ -431,20 +443,20 @@ static const uint8_t use_table[] = {
/* 2070 */ O, O, O, O, FMPst, O, O, O, O, O, O, O, O, O, O, O, /* 2070 */ O, O, O, O, FMPst, O, O, O, O, O, O, O, O, O, O, O,
/* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O, /* 2080 */ O, O, FMPst, FMPst, FMPst, O, O, O,
#define use_offset_0x20f0u 3088 #define use_offset_0x20f0u 3096
/* Combining Diacritical Marks for Symbols */ /* Combining Diacritical Marks for Symbols */
/* 20F0 */ VMAbv, O, O, O, O, O, O, O, /* 20F0 */ VMAbv, O, O, O, O, O, O, O,
#define use_offset_0x25c8u 3096 #define use_offset_0x25c8u 3104
/* Geometric Shapes */ /* Geometric Shapes */
O, O, O, O, B, O, O, O, O, O, O, O, B, O, O, O,
#define use_offset_0x2d30u 3104 #define use_offset_0x2d30u 3112
/* Tifinagh */ /* Tifinagh */
@ -455,7 +467,7 @@ static const uint8_t use_table[] = {
/* 2D60 */ B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, B, /* 2D60 */ B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, B,
/* 2D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, H, /* 2D70 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, H,
#define use_offset_0xa800u 3184 #define use_offset_0xa800u 3192
/* Syloti Nagri */ /* Syloti Nagri */
@ -542,7 +554,7 @@ static const uint8_t use_table[] = {
/* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst, /* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst,
/* AAF0 */ O, O, O, O, O, VMPst, H, O, /* AAF0 */ O, O, O, O, O, VMPst, H, O,
#define use_offset_0xabc0u 3944 #define use_offset_0xabc0u 3952
/* Meetei Mayek */ /* Meetei Mayek */
@ -552,7 +564,25 @@ static const uint8_t use_table[] = {
/* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O, /* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O,
/* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x10a00u 4008 #define use_offset_0xfe00u 4016
/* Variation Selectors */
/* FE00 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
#define use_offset_0x10570u 4032
/* Vithkuqi */
/* 10570 */ B, B, B, B, B, B, B, B, B, B, B, O, B, B, B, B,
/* 10580 */ B, B, B, B, B, B, B, B, B, B, B, O, B, B, B, B,
/* 10590 */ B, B, B, O, B, B, O, B, B, B, B, B, B, B, B, B,
/* 105A0 */ B, B, O, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 105B0 */ B, B, O, B, B, B, B, B, B, B, O, B, B, O, O, O,
#define use_offset_0x10a00u 4112
/* Kharoshthi */ /* Kharoshthi */
@ -563,16 +593,16 @@ static const uint8_t use_table[] = {
/* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H, /* 10A30 */ B, B, B, B, B, B, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H,
/* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, /* 10A40 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
#define use_offset_0x10ac0u 4088 #define use_offset_0x10ac0u 4192
/* Manichaean */ /* Manichaean */
/* 10AC0 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B, /* 10AC0 */ B, B, B, B, B, B, B, B, O, B, B, B, B, B, B, B,
/* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 10AD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O, /* 10AE0 */ B, B, B, B, B, CMBlw, CMBlw, O, O, O, O, B, B, B, B, B,
#define use_offset_0x10b80u 4128 #define use_offset_0x10b80u 4240
/* Psalter Pahlavi */ /* Psalter Pahlavi */
@ -581,7 +611,7 @@ static const uint8_t use_table[] = {
/* 10B90 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O, /* 10B90 */ B, B, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 10BA0 */ O, O, O, O, O, O, O, O, O, B, B, B, B, B, B, O, /* 10BA0 */ O, O, O, O, O, O, O, O, O, B, B, B, B, B, B, O,
#define use_offset_0x10d00u 4176 #define use_offset_0x10d00u 4288
/* Hanifi Rohingya */ /* Hanifi Rohingya */
@ -591,7 +621,7 @@ static const uint8_t use_table[] = {
/* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, O, O, O, O, O, O, O, O, /* 10D20 */ B, B, B, B, VMAbv, VMAbv, VMAbv, CMAbv, O, O, O, O, O, O, O, O,
/* 10D30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 10D30 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x10e80u 4240 #define use_offset_0x10e80u 4352
/* Yezidi */ /* Yezidi */
@ -601,17 +631,22 @@ static const uint8_t use_table[] = {
/* 10EA0 */ B, B, B, B, B, B, B, B, B, B, O, VAbv, VAbv, O, O, O, /* 10EA0 */ B, B, B, B, B, B, B, B, B, B, O, VAbv, VAbv, O, O, O,
/* 10EB0 */ B, B, O, O, O, O, O, O, /* 10EB0 */ B, B, O, O, O, O, O, O,
#define use_offset_0x10f30u 4296 #define use_offset_0x10f30u 4408
/* Sogdian */ /* Sogdian */
/* 10F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 10F30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, /* 10F40 */ B, B, B, B, B, B, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw,
/* 10F50 */ VMBlw, B, B, B, B, O, O, O, /* 10F50 */ VMBlw, B, B, B, B, O, O, O, O, O, O, O, O, O, O, O,
/* 10F60 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
#define use_offset_0x10fb0u 4336 /* Old Uyghur */
/* 10F70 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 10F80 */ B, B, CMBlw, CMBlw, CMBlw, CMBlw, O, O, O, O, O, O, O, O, O, O,
/* 10F90 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 10FA0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Chorasmian */ /* Chorasmian */
@ -627,7 +662,7 @@ static const uint8_t use_table[] = {
/* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, /* 11030 */ B, B, B, B, B, B, B, B, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw,
/* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, HVM, O, O, O, O, O, O, O, O, O, /* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O,
/* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N, /* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
/* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B, /* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B,
/* 11070 */ VAbv, B, B, VAbv, VAbv, B, O, O, O, O, O, O, O, O, O, HN, /* 11070 */ VAbv, B, B, VAbv, VAbv, B, O, O, O, O, O, O, O, O, O, HN,
@ -640,7 +675,7 @@ static const uint8_t use_table[] = {
/* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O, /* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O,
/* 110C0 */ O, O, VBlw, O, O, O, O, O, /* 110C0 */ O, O, VBlw, O, O, O, O, O,
#define use_offset_0x11100u 4616 #define use_offset_0x11100u 4816
/* Chakma */ /* Chakma */
@ -678,7 +713,7 @@ static const uint8_t use_table[] = {
/* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw, /* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw,
/* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O, /* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O,
#define use_offset_0x11280u 4936 #define use_offset_0x11280u 5136
/* Multani */ /* Multani */
@ -706,7 +741,7 @@ static const uint8_t use_table[] = {
/* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
/* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O, /* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
#define use_offset_0x11400u 5184 #define use_offset_0x11400u 5384
/* Newa */ /* Newa */
@ -729,7 +764,7 @@ static const uint8_t use_table[] = {
/* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O, /* 114C0 */ VMAbv, VMAbv, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O,
/* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x11580u 5408 #define use_offset_0x11580u 5608
/* Siddham */ /* Siddham */
@ -773,7 +808,7 @@ static const uint8_t use_table[] = {
/* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O, /* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O,
/* 11740 */ B, B, B, B, B, B, B, O, /* 11740 */ B, B, B, B, B, B, B, O,
#define use_offset_0x11800u 5864 #define use_offset_0x11800u 6064
/* Dogra */ /* Dogra */
@ -783,7 +818,7 @@ static const uint8_t use_table[] = {
/* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw, /* 11820 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPre, VPst, VBlw,
/* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O, /* 11830 */ VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, VMAbv, VMPst, H, CMBlw, O, O, O, O, O,
#define use_offset_0x11900u 5928 #define use_offset_0x11900u 6128
/* Dives Akuru */ /* Dives Akuru */
@ -795,7 +830,7 @@ static const uint8_t use_table[] = {
/* 11940 */ MPst, R, MPst, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O, /* 11940 */ MPst, R, MPst, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O,
/* 11950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 11950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x119a0u 6024 #define use_offset_0x119a0u 6224
/* Nandinagari */ /* Nandinagari */
@ -823,7 +858,7 @@ static const uint8_t use_table[] = {
/* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, /* 11A80 */ B, B, B, B, R, R, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw,
/* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O, /* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, B, O, O,
#define use_offset_0x11c00u 6280 #define use_offset_0x11c00u 6480
/* Bhaiksuki */ /* Bhaiksuki */
@ -844,7 +879,7 @@ static const uint8_t use_table[] = {
/* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB, /* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O, /* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O,
#define use_offset_0x11d00u 6464 #define use_offset_0x11d00u 6664
/* Masaram Gondi */ /* Masaram Gondi */
@ -864,7 +899,7 @@ static const uint8_t use_table[] = {
/* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O, /* 11D90 */ VAbv, VAbv, O, VPst, VPst, VMAbv, VMPst, H, O, O, O, O, O, O, O, O,
/* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 11DA0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x11ee0u 6640 #define use_offset_0x11ee0u 6840
/* Makasar */ /* Makasar */
@ -872,86 +907,93 @@ static const uint8_t use_table[] = {
/* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 11EE0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O, /* 11EF0 */ B, B, GB, VAbv, VBlw, VPre, VPst, O,
#define use_offset_0x13000u 6664 #define use_offset_0x13000u 6864
/* Egyptian Hieroglyphs */ /* Egyptian Hieroglyphs */
/* 13000 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13000 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13010 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13010 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13020 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13020 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13030 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13030 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13040 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13040 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13050 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13050 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13060 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13060 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13070 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13070 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13080 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13080 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13090 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13090 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 130A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 130A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 130B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 130B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 130C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 130C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 130D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 130D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 130E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 130E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 130F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 130F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13100 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13100 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13110 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13110 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13120 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13120 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13130 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13130 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13140 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13140 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13150 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13150 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13160 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13160 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13170 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13170 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13180 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13180 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13190 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13190 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 131A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 131A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 131B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 131B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 131C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 131C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 131D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 131D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 131E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 131E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 131F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 131F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13200 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13200 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13210 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13210 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13220 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13220 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13230 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13230 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13240 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13240 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13250 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13250 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13260 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13260 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13270 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13270 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13280 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13280 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13290 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 132A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 132A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 132B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 132B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 132C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 132C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 132D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 132D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 132E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 132E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 132F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 132F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13300 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13300 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13310 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13310 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13320 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13320 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13330 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13330 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13340 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13340 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13350 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13350 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13360 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13360 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13370 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13370 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13380 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13380 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13390 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13390 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 133A0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 133A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 133B0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 133B0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 133C0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 133C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 133D0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 133D0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 133E0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 133E0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 133F0 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 133F0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13400 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13400 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13410 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, /* 13410 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 13420 */ G, G, G, G, G, G, G, G, G, G, G, G, G, G, G, O, /* 13420 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, O,
/* Egyptian Hieroglyph Format Controls */ /* Egyptian Hieroglyph Format Controls */
/* 13430 */ J, J, J, J, J, J, J, SB, SE, O, O, O, O, O, O, O, /* 13430 */ H, H, H, H, H, H, H, B, B, O, O, O, O, O, O, O,
#define use_offset_0x16b00u 7752 #define use_offset_0x16ac0u 7952
/* Tangsa */
/* 16AC0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 16AD0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 16AE0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 16AF0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Pahawh Hmong */ /* Pahawh Hmong */
/* 16B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 16B00 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
@ -959,7 +1001,7 @@ static const uint8_t use_table[] = {
/* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 16B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, /* 16B30 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O,
#define use_offset_0x16f00u 7808 #define use_offset_0x16f00u 8072
/* Miao */ /* Miao */
@ -975,14 +1017,14 @@ static const uint8_t use_table[] = {
/* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, O, O, O, O, O, O, O, VMBlw, /* 16F80 */ VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, VBlw, O, O, O, O, O, O, O, VMBlw,
/* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O, /* 16F90 */ VMBlw, VMBlw, VMBlw, O, O, O, O, O,
#define use_offset_0x16fe0u 7960 #define use_offset_0x16fe0u 8224
/* Ideographic Symbols and Punctuation */ /* Ideographic Symbols and Punctuation */
/* 16FE0 */ O, O, O, O, B, O, O, O, /* 16FE0 */ O, O, O, O, B, O, O, O,
#define use_offset_0x18b00u 7968 #define use_offset_0x18b00u 8232
/* Khitan Small Script */ /* Khitan Small Script */
@ -1018,7 +1060,7 @@ static const uint8_t use_table[] = {
/* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 18CC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 18CD0 */ B, B, B, B, B, B, O, O, /* 18CD0 */ B, B, B, B, B, B, O, O,
#define use_offset_0x1bc00u 8440 #define use_offset_0x1bc00u 8704
/* Duployan */ /* Duployan */
@ -1034,7 +1076,7 @@ static const uint8_t use_table[] = {
/* 1BC80 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O, /* 1BC80 */ B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, O,
/* 1BC90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, CMBlw, CMBlw, O, /* 1BC90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, CMBlw, CMBlw, O,
#define use_offset_0x1e100u 8600 #define use_offset_0x1e100u 8864
/* Nyiakeng Puachue Hmong */ /* Nyiakeng Puachue Hmong */
@ -1045,9 +1087,15 @@ static const uint8_t use_table[] = {
/* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, O, O, /* 1E130 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, B, B, B, B, B, B, B, O, O,
/* 1E140 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, B, B, /* 1E140 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, B, B,
#define use_offset_0x1e2c0u 8680 #define use_offset_0x1e290u 8944
/* Toto */
/* 1E290 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1E2A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, O,
/* 1E2B0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* Wancho */ /* Wancho */
/* 1E2C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1E2C0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
@ -1055,7 +1103,7 @@ static const uint8_t use_table[] = {
/* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv, /* 1E2E0 */ B, B, B, B, B, B, B, B, B, B, B, B, VMAbv, VMAbv, VMAbv, VMAbv,
/* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1E2F0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x1e900u 8744 #define use_offset_0x1e900u 9056
/* Adlam */ /* Adlam */
@ -1067,7 +1115,28 @@ static const uint8_t use_table[] = {
/* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, O, O, O, O, /* 1E940 */ B, B, B, B, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, CMAbv, B, O, O, O, O,
/* 1E950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, /* 1E950 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
}; /* Table items: 8840; occupancy: 79% */ #define use_offset_0xe0100u 9152
/* Variation Selectors Supplement */
/* E0100 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0110 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0120 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0130 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0140 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0150 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0160 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0170 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0180 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E0190 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E01A0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E01B0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E01C0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E01D0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
/* E01E0 */ CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ, CGJ,
}; /* Table items: 9392; occupancy: 79% */
static inline uint8_t static inline uint8_t
hb_use_get_category (hb_codepoint_t u) hb_use_get_category (hb_codepoint_t u)
@ -1077,6 +1146,7 @@ hb_use_get_category (hb_codepoint_t u)
case 0x0u: case 0x0u:
if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u]; if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u]; if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u];
if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u]; if (hb_in_range<hb_codepoint_t> (u, 0x0640u, 0x0647u)) return use_table[u - 0x0640u + use_offset_0x0640u];
if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u]; if (hb_in_range<hb_codepoint_t> (u, 0x07C8u, 0x07FFu)) return use_table[u - 0x07C8u + use_offset_0x07c8u];
if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u]; if (hb_in_range<hb_codepoint_t> (u, 0x0840u, 0x085Fu)) return use_table[u - 0x0840u + use_offset_0x0840u];
@ -1106,18 +1176,22 @@ hb_use_get_category (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u]; if (hb_in_range<hb_codepoint_t> (u, 0xABC0u, 0xABFFu)) return use_table[u - 0xABC0u + use_offset_0xabc0u];
break; break;
case 0xFu:
if (hb_in_range<hb_codepoint_t> (u, 0xFE00u, 0xFE0Fu)) return use_table[u - 0xFE00u + use_offset_0xfe00u];
break;
case 0x10u: case 0x10u:
if (hb_in_range<hb_codepoint_t> (u, 0x10570u, 0x105BFu)) return use_table[u - 0x10570u + use_offset_0x10570u];
if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u]; if (hb_in_range<hb_codepoint_t> (u, 0x10A00u, 0x10A4Fu)) return use_table[u - 0x10A00u + use_offset_0x10a00u];
if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AE7u)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u]; if (hb_in_range<hb_codepoint_t> (u, 0x10AC0u, 0x10AEFu)) return use_table[u - 0x10AC0u + use_offset_0x10ac0u];
if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u]; if (hb_in_range<hb_codepoint_t> (u, 0x10B80u, 0x10BAFu)) return use_table[u - 0x10B80u + use_offset_0x10b80u];
if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u]; if (hb_in_range<hb_codepoint_t> (u, 0x10D00u, 0x10D3Fu)) return use_table[u - 0x10D00u + use_offset_0x10d00u];
if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u]; if (hb_in_range<hb_codepoint_t> (u, 0x10E80u, 0x10EB7u)) return use_table[u - 0x10E80u + use_offset_0x10e80u];
if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x10F57u)) return use_table[u - 0x10F30u + use_offset_0x10f30u]; if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u];
if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110C7u)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u];
break; break;
case 0x11u: case 0x11u:
if (hb_in_range<hb_codepoint_t> (u, 0x10FB0u, 0x110C7u)) return use_table[u - 0x10FB0u + use_offset_0x10fb0u]; if (hb_in_range<hb_codepoint_t> (u, 0x10F30u, 0x110C7u)) return use_table[u - 0x10F30u + use_offset_0x10f30u];
if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u]; if (hb_in_range<hb_codepoint_t> (u, 0x11100u, 0x1123Fu)) return use_table[u - 0x11100u + use_offset_0x11100u];
if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u]; if (hb_in_range<hb_codepoint_t> (u, 0x11280u, 0x11377u)) return use_table[u - 0x11280u + use_offset_0x11280u];
if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u]; if (hb_in_range<hb_codepoint_t> (u, 0x11400u, 0x114DFu)) return use_table[u - 0x11400u + use_offset_0x11400u];
@ -1135,7 +1209,7 @@ hb_use_get_category (hb_codepoint_t u)
break; break;
case 0x16u: case 0x16u:
if (hb_in_range<hb_codepoint_t> (u, 0x16B00u, 0x16B37u)) return use_table[u - 0x16B00u + use_offset_0x16b00u]; if (hb_in_range<hb_codepoint_t> (u, 0x16AC0u, 0x16B37u)) return use_table[u - 0x16AC0u + use_offset_0x16ac0u];
if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u]; if (hb_in_range<hb_codepoint_t> (u, 0x16F00u, 0x16F97u)) return use_table[u - 0x16F00u + use_offset_0x16f00u];
if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u]; if (hb_in_range<hb_codepoint_t> (u, 0x16FE0u, 0x16FE7u)) return use_table[u - 0x16FE0u + use_offset_0x16fe0u];
break; break;
@ -1150,10 +1224,14 @@ hb_use_get_category (hb_codepoint_t u)
case 0x1Eu: case 0x1Eu:
if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u]; if (hb_in_range<hb_codepoint_t> (u, 0x1E100u, 0x1E14Fu)) return use_table[u - 0x1E100u + use_offset_0x1e100u];
if (hb_in_range<hb_codepoint_t> (u, 0x1E2C0u, 0x1E2FFu)) return use_table[u - 0x1E2C0u + use_offset_0x1e2c0u]; if (hb_in_range<hb_codepoint_t> (u, 0x1E290u, 0x1E2FFu)) return use_table[u - 0x1E290u + use_offset_0x1e290u];
if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u]; if (hb_in_range<hb_codepoint_t> (u, 0x1E900u, 0x1E95Fu)) return use_table[u - 0x1E900u + use_offset_0x1e900u];
break; break;
case 0xE0u:
if (hb_in_range<hb_codepoint_t> (u, 0xE0100u, 0xE01EFu)) return use_table[u - 0xE0100u + use_offset_0xe0100u];
break;
default: default:
break; break;
} }
@ -1161,6 +1239,7 @@ hb_use_get_category (hb_codepoint_t u)
} }
#undef B #undef B
#undef CGJ
#undef CS #undef CS
#undef G #undef G
#undef GB #undef GB
@ -1171,7 +1250,6 @@ hb_use_get_category (hb_codepoint_t u)
#undef N #undef N
#undef O #undef O
#undef R #undef R
#undef S
#undef SB #undef SB
#undef SE #undef SE
#undef SUB #undef SUB

View File

@ -257,7 +257,6 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F); use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
switch (syllable_type) switch (syllable_type)
{ {
case use_independent_cluster:
case use_symbol_cluster: case use_symbol_cluster:
case use_hieroglyph_cluster: case use_hieroglyph_cluster:
case use_non_cluster: case use_non_cluster:

View File

@ -171,7 +171,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
hb_codepoint_t u = buffer->cur().codepoint; hb_codepoint_t u = buffer->cur().codepoint;
hb_codepoint_t glyph = 0; hb_codepoint_t glyph = 0;
if (shortest && c->font->get_nominal_glyph (u, &glyph)) if (shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found))
{ {
next_char (buffer, glyph); next_char (buffer, glyph);
return; return;
@ -183,7 +183,7 @@ decompose_current_character (const hb_ot_shape_normalize_context_t *c, bool shor
return; return;
} }
if (!shortest && c->font->get_nominal_glyph (u, &glyph)) if (!shortest && c->font->get_nominal_glyph (u, &glyph, c->not_found))
{ {
next_char (buffer, glyph); next_char (buffer, glyph);
return; return;
@ -312,6 +312,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
buffer, buffer,
font, font,
buffer->unicode, buffer->unicode,
buffer->not_found,
plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode, plan->shaper->decompose ? plan->shaper->decompose : decompose_unicode,
plan->shaper->compose ? plan->shaper->compose : compose_unicode plan->shaper->compose ? plan->shaper->compose : compose_unicode
}; };

View File

@ -56,6 +56,7 @@ struct hb_ot_shape_normalize_context_t
hb_buffer_t *buffer; hb_buffer_t *buffer;
hb_font_t *font; hb_font_t *font;
hb_unicode_funcs_t *unicode; hb_unicode_funcs_t *unicode;
const hb_codepoint_t not_found;
bool (*decompose) (const hb_ot_shape_normalize_context_t *c, bool (*decompose) (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t ab, hb_codepoint_t ab,
hb_codepoint_t *a, hb_codepoint_t *a,

View File

@ -150,23 +150,25 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
*/ */
#ifndef HB_NO_AAT_SHAPE #ifndef HB_NO_AAT_SHAPE
bool has_gsub = hb_ot_layout_has_substitution (face); bool has_kerx = hb_aat_layout_has_positioning (face);
bool has_gsub = !apply_morx && hb_ot_layout_has_substitution (face);
#endif #endif
bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face); bool has_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
if (false) if (false)
; ;
#ifndef HB_NO_AAT_SHAPE #ifndef HB_NO_AAT_SHAPE
else if (hb_aat_layout_has_positioning (face) && !(has_gsub && has_gpos)) /* Prefer GPOS over kerx if GSUB is present;
* https://github.com/harfbuzz/harfbuzz/issues/3008 */
else if (has_kerx && !(has_gsub && has_gpos))
plan.apply_kerx = true; plan.apply_kerx = true;
#endif #endif
else if (!apply_morx && has_gpos) else if (has_gpos)
plan.apply_gpos = true; plan.apply_gpos = true;
if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos)) if (!plan.apply_kerx && (!has_gpos_kern || !plan.apply_gpos))
{ {
/* Apparently Apple applies kerx if GPOS kern was not applied. */
#ifndef HB_NO_AAT_SHAPE #ifndef HB_NO_AAT_SHAPE
if (hb_aat_layout_has_positioning (face)) if (has_kerx)
plan.apply_kerx = true; plan.apply_kerx = true;
else else
#endif #endif

View File

@ -0,0 +1,264 @@
/*
* Copyright © 2021 Google, Inc.
*
* 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_OT_VAR_COMMON_HH
#define HB_OT_VAR_COMMON_HH
#include "hb-ot-layout-common.hh"
namespace OT {
struct DeltaSetIndexMapFormat0
{
friend struct DeltaSetIndexMap;
private:
DeltaSetIndexMapFormat0* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
auto *out = c->start_embed (this);
if (unlikely (!out)) return_trace (nullptr);
unsigned total_size = min_size + mapCount * get_width ();
HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
if (unlikely (!p)) return_trace (nullptr);
memcpy (p, this, HBUINT8::static_size * total_size);
return_trace (out);
}
template <typename T>
bool serialize (hb_serialize_context_t *c, const T &plan)
{
unsigned int width = plan.get_width ();
unsigned int inner_bit_count = plan.get_inner_bit_count ();
const hb_array_t<const uint32_t> output_map = plan.get_output_map ();
TRACE_SERIALIZE (this);
if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0))))
return_trace (false);
if (unlikely (!c->extend_min (this))) return_trace (false);
entryFormat = ((width-1)<<4)|(inner_bit_count-1);
mapCount = output_map.length;
HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length);
if (unlikely (!p)) return_trace (false);
for (unsigned int i = 0; i < output_map.length; i++)
{
unsigned int v = output_map[i];
unsigned int outer = v >> 16;
unsigned int inner = v & 0xFFFF;
unsigned int u = (outer << inner_bit_count) | inner;
for (unsigned int w = width; w > 0;)
{
p[--w] = u;
u >>= 8;
}
p += width;
}
return_trace (true);
}
uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */
{
/* If count is zero, pass value unchanged. This takes
* care of direct mapping for advance map. */
if (!mapCount)
return v;
if (v >= mapCount)
v = mapCount - 1;
unsigned int u = 0;
{ /* Fetch it. */
unsigned int w = get_width ();
const HBUINT8 *p = mapDataZ.arrayZ + w * v;
for (; w; w--)
u = (u << 8) + *p++;
}
{ /* Repack it. */
unsigned int n = get_inner_bit_count ();
unsigned int outer = u >> n;
unsigned int inner = u & ((1 << n) - 1);
u = (outer<<16) | inner;
}
return u;
}
unsigned get_map_count () const { return mapCount; }
unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; }
unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
c->check_range (mapDataZ.arrayZ,
mapCount,
get_width ()));
}
protected:
HBUINT8 format; /* Format identifier--format = 0 */
HBUINT8 entryFormat; /* A packed field that describes the compressed
* representation of delta-set indices. */
HBUINT16 mapCount; /* The number of mapping entries. */
UnsizedArrayOf<HBUINT8>
mapDataZ; /* The delta-set index mapping data. */
public:
DEFINE_SIZE_ARRAY (4, mapDataZ);
};
struct DeltaSetIndexMapFormat1
{
friend struct DeltaSetIndexMap;
private:
DeltaSetIndexMapFormat1* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
auto *out = c->start_embed (this);
if (unlikely (!out)) return_trace (nullptr);
unsigned total_size = min_size + mapCount * get_width ();
HBUINT8 *p = c->allocate_size<HBUINT8> (total_size);
if (unlikely (!p)) return_trace (nullptr);
memcpy (p, this, HBUINT8::static_size * total_size);
return_trace (out);
}
unsigned get_map_count () const { return mapCount; }
unsigned get_width () const { return ((entryFormat >> 4) & 3) + 1; }
unsigned get_inner_bit_count () const { return (entryFormat & 0xF) + 1; }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
c->check_range (mapDataZ.arrayZ,
mapCount,
get_width ()));
}
protected:
HBUINT8 format; /* Format identifier--format = 1 */
HBUINT8 entryFormat; /* A packed field that describes the compressed
* representation of delta-set indices. */
HBUINT32 mapCount; /* The number of mapping entries. */
UnsizedArrayOf<HBUINT8>
mapDataZ; /* The delta-set index mapping data. */
public:
DEFINE_SIZE_ARRAY (6, mapDataZ);
};
struct DeltaSetIndexMap
{
template <typename T>
bool serialize (hb_serialize_context_t *c, const T &plan)
{
TRACE_SERIALIZE (this);
switch (u.format) {
case 0: return_trace (u.format0.serialize (c, plan));
default:return_trace (false);
}
}
uint32_t map (unsigned v) const
{
switch (u.format) {
case 0: return (u.format0.map (v));
default:return v;
}
}
unsigned get_map_count () const
{
switch (u.format) {
case 0: return u.format0.get_map_count ();
case 1: return u.format1.get_map_count ();
default:return 0;
}
}
unsigned get_width () const
{
switch (u.format) {
case 0: return u.format0.get_width ();
case 1: return u.format1.get_width ();
default:return 0;
}
}
unsigned get_inner_bit_count () const
{
switch (u.format) {
case 0: return u.format0.get_inner_bit_count ();
case 1: return u.format1.get_inner_bit_count ();
default:return 0;
}
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
switch (u.format) {
case 0: return_trace (u.format0.sanitize (c));
case 1: return_trace (u.format1.sanitize (c));
default:return_trace (true);
}
}
DeltaSetIndexMap* copy (hb_serialize_context_t *c) const
{
TRACE_SERIALIZE (this);
switch (u.format) {
case 0: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format0.copy (c)));
case 1: return_trace (reinterpret_cast<DeltaSetIndexMap *> (u.format1.copy (c)));
default:return_trace (nullptr);
}
}
protected:
union {
HBUINT8 format; /* Format identifier */
DeltaSetIndexMapFormat0 format0;
DeltaSetIndexMapFormat1 format1;
} u;
public:
DEFINE_SIZE_UNION (1, format);
};
} /* namespace OT */
#endif /* HB_OT_VAR_COMMON_HH */

View File

@ -28,97 +28,11 @@
#define HB_OT_VAR_HVAR_TABLE_HH #define HB_OT_VAR_HVAR_TABLE_HH
#include "hb-ot-layout-common.hh" #include "hb-ot-layout-common.hh"
#include "hb-ot-var-common.hh"
namespace OT { namespace OT {
struct DeltaSetIndexMap
{
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
c->check_range (mapDataZ.arrayZ,
mapCount,
get_width ()));
}
template <typename T>
bool serialize (hb_serialize_context_t *c, const T &plan)
{
unsigned int width = plan.get_width ();
unsigned int inner_bit_count = plan.get_inner_bit_count ();
const hb_array_t<const uint32_t> output_map = plan.get_output_map ();
TRACE_SERIALIZE (this);
if (unlikely (output_map.length && ((((inner_bit_count-1)&~0xF)!=0) || (((width-1)&~0x3)!=0))))
return_trace (false);
if (unlikely (!c->extend_min (this))) return_trace (false);
format = ((width-1)<<4)|(inner_bit_count-1);
mapCount = output_map.length;
HBUINT8 *p = c->allocate_size<HBUINT8> (width * output_map.length);
if (unlikely (!p)) return_trace (false);
for (unsigned int i = 0; i < output_map.length; i++)
{
unsigned int v = output_map[i];
unsigned int outer = v >> 16;
unsigned int inner = v & 0xFFFF;
unsigned int u = (outer << inner_bit_count) | inner;
for (unsigned int w = width; w > 0;)
{
p[--w] = u;
u >>= 8;
}
p += width;
}
return_trace (true);
}
uint32_t map (unsigned int v) const /* Returns 16.16 outer.inner. */
{
/* If count is zero, pass value unchanged. This takes
* care of direct mapping for advance map. */
if (!mapCount)
return v;
if (v >= mapCount)
v = mapCount - 1;
unsigned int u = 0;
{ /* Fetch it. */
unsigned int w = get_width ();
const HBUINT8 *p = mapDataZ.arrayZ + w * v;
for (; w; w--)
u = (u << 8) + *p++;
}
{ /* Repack it. */
unsigned int n = get_inner_bit_count ();
unsigned int outer = u >> n;
unsigned int inner = u & ((1 << n) - 1);
u = (outer<<16) | inner;
}
return u;
}
unsigned int get_map_count () const { return mapCount; }
unsigned int get_width () const { return ((format >> 4) & 3) + 1; }
unsigned int get_inner_bit_count () const { return (format & 0xF) + 1; }
protected:
HBUINT16 format; /* A packed field that describes the compressed
* representation of delta-set indices. */
HBUINT16 mapCount; /* The number of mapping entries. */
UnsizedArrayOf<HBUINT8>
mapDataZ; /* The delta-set index mapping data. */
public:
DEFINE_SIZE_ARRAY (4, mapDataZ);
};
struct index_map_subset_plan_t struct index_map_subset_plan_t
{ {
enum index_map_index_t { enum index_map_index_t {

View File

@ -48,7 +48,7 @@ struct VertOriginMetric
} }
public: public:
HBGlyphID glyph; HBGlyphID16 glyph;
FWORD vertOriginY; FWORD vertOriginY;
public: public:

File diff suppressed because it is too large Load Diff

View File

@ -145,14 +145,14 @@ struct hb_sanitize_context_t :
private: private:
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
( obj.sanitize (this, hb_forward<Ts> (ds)...) ) ( obj.sanitize (this, std::forward<Ts> (ds)...) )
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
( obj.dispatch (this, hb_forward<Ts> (ds)...) ) ( obj.dispatch (this, std::forward<Ts> (ds)...) )
public: public:
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) ) ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
void init (hb_blob_t *b) void init (hb_blob_t *b)

View File

@ -189,8 +189,8 @@ struct hb_serialize_context_t
{ return check_success (!hb_deref (obj).in_error ()); } { return check_success (!hb_deref (obj).in_error ()); }
template <typename T1, typename... Ts> bool propagate_error (T1 &&o1, Ts&&... os) template <typename T1, typename... Ts> bool propagate_error (T1 &&o1, Ts&&... os)
{ return propagate_error (hb_forward<T1> (o1)) && { return propagate_error (std::forward<T1> (o1)) &&
propagate_error (hb_forward<Ts> (os)...); } propagate_error (std::forward<Ts> (os)...); }
/* To be called around main operation. */ /* To be called around main operation. */
template <typename Type> template <typename Type>
@ -358,6 +358,35 @@ struct hb_serialize_context_t
assert (packed.tail ()->head == tail); assert (packed.tail ()->head == tail);
} }
// Adds a virtual link from the current object to objidx. A virtual link is not associated with
// an actual offset field. They are solely used to enforce ordering constraints between objects.
// Adding a virtual link from object a to object b will ensure that object b is always packed after
// object a in the final serialized order.
//
// This is useful in certain situtations where there needs to be a specific ordering in the
// final serialization. Such as when platform bugs require certain orderings, or to provide
// guidance to the repacker for better offset overflow resolution.
void add_virtual_link (objidx_t objidx)
{
if (unlikely (in_error ())) return;
if (!objidx)
return;
assert (current);
auto& link = *current->links.push ();
if (current->links.in_error ())
err (HB_SERIALIZE_ERROR_OTHER);
link.width = 0;
link.objidx = objidx;
link.is_signed = 0;
link.whence = 0;
link.position = 0;
link.bias = 0;
}
template <typename T> template <typename T>
void add_link (T &ofs, objidx_t objidx, void add_link (T &ofs, objidx_t objidx,
whence_t whence = Head, whence_t whence = Head,
@ -376,11 +405,22 @@ struct hb_serialize_context_t
err (HB_SERIALIZE_ERROR_OTHER); err (HB_SERIALIZE_ERROR_OTHER);
link.width = sizeof (T); link.width = sizeof (T);
link.is_signed = hb_is_signed (hb_unwrap_type (T)); link.objidx = objidx;
if (unlikely (!sizeof (T)))
{
// This link is not associated with an actual offset and exists merely to enforce
// an ordering constraint.
link.is_signed = 0;
link.whence = 0;
link.position = 0;
link.bias = 0;
return;
}
link.is_signed = std::is_signed<hb_unwrap_type (T)>::value;
link.whence = (unsigned) whence; link.whence = (unsigned) whence;
link.position = (const char *) &ofs - current->head; link.position = (const char *) &ofs - current->head;
link.bias = bias; link.bias = bias;
link.objidx = objidx;
} }
unsigned to_bias (const void *base) const unsigned to_bias (const void *base) const
@ -402,6 +442,8 @@ struct hb_serialize_context_t
for (const object_t* parent : ++hb_iter (packed)) for (const object_t* parent : ++hb_iter (packed))
for (const object_t::link_t &link : parent->links) for (const object_t::link_t &link : parent->links)
{ {
if (unlikely (!link.width)) continue; // Don't need to resolve virtual offsets
const object_t* child = packed[link.objidx]; const object_t* child = packed[link.objidx];
if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; } if (unlikely (!child)) { err (HB_SERIALIZE_ERROR_OTHER); return; }
unsigned offset = 0; unsigned offset = 0;
@ -494,7 +536,7 @@ struct hb_serialize_context_t
template <typename Type, typename ...Ts> auto template <typename Type, typename ...Ts> auto
_copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN _copy (const Type &src, hb_priority<1>, Ts&&... ds) HB_RETURN
(Type *, src.copy (this, hb_forward<Ts> (ds)...)) (Type *, src.copy (this, std::forward<Ts> (ds)...))
template <typename Type> auto template <typename Type> auto
_copy (const Type &src, hb_priority<0>) -> decltype (&(hb_declval<Type> () = src)) _copy (const Type &src, hb_priority<0>) -> decltype (&(hb_declval<Type> () = src))
@ -509,16 +551,16 @@ struct hb_serialize_context_t
* instead of memcpy(). */ * instead of memcpy(). */
template <typename Type, typename ...Ts> template <typename Type, typename ...Ts>
Type *copy (const Type &src, Ts&&... ds) Type *copy (const Type &src, Ts&&... ds)
{ return _copy (src, hb_prioritize, hb_forward<Ts> (ds)...); } { return _copy (src, hb_prioritize, std::forward<Ts> (ds)...); }
template <typename Type, typename ...Ts> template <typename Type, typename ...Ts>
Type *copy (const Type *src, Ts&&... ds) Type *copy (const Type *src, Ts&&... ds)
{ return copy (*src, hb_forward<Ts> (ds)...); } { return copy (*src, std::forward<Ts> (ds)...); }
template<typename Iterator, template<typename Iterator,
hb_requires (hb_is_iterator (Iterator)), hb_requires (hb_is_iterator (Iterator)),
typename ...Ts> typename ...Ts>
void copy_all (Iterator it, Ts&&... ds) void copy_all (Iterator it, Ts&&... ds)
{ for (decltype (*it) _ : it) copy (_, hb_forward<Ts> (ds)...); } { for (decltype (*it) _ : it) copy (_, std::forward<Ts> (ds)...); }
template <typename Type> template <typename Type>
hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; } hb_serialize_context_t& operator << (const Type &obj) & { embed (obj); return *this; }
@ -546,10 +588,10 @@ struct hb_serialize_context_t
template <typename Type, typename ...Ts> template <typename Type, typename ...Ts>
Type *extend (Type *obj, Ts&&... ds) Type *extend (Type *obj, Ts&&... ds)
{ return extend_size (obj, obj->get_size (hb_forward<Ts> (ds)...)); } { return extend_size (obj, obj->get_size (std::forward<Ts> (ds)...)); }
template <typename Type, typename ...Ts> template <typename Type, typename ...Ts>
Type *extend (Type &obj, Ts&&... ds) Type *extend (Type &obj, Ts&&... ds)
{ return extend (hb_addressof (obj), hb_forward<Ts> (ds)...); } { return extend (hb_addressof (obj), std::forward<Ts> (ds)...); }
/* Output routines. */ /* Output routines. */
hb_bytes_t copy_bytes () const hb_bytes_t copy_bytes () const

View File

@ -168,15 +168,17 @@ struct hb_set_digest_combiner_t
* There is not much science to this: it's a result of intuition * There is not much science to this: it's a result of intuition
* and testing. * and testing.
*/ */
typedef hb_set_digest_combiner_t using hb_set_digest_t =
<
hb_set_digest_lowest_bits_t<unsigned long, 4>,
hb_set_digest_combiner_t hb_set_digest_combiner_t
< <
hb_set_digest_lowest_bits_t<unsigned long, 0>, hb_set_digest_lowest_bits_t<unsigned long, 4>,
hb_set_digest_lowest_bits_t<unsigned long, 9> hb_set_digest_combiner_t
<
hb_set_digest_lowest_bits_t<unsigned long, 0>,
hb_set_digest_lowest_bits_t<unsigned long, 9>
>
> >
> hb_set_digest_t; ;
#endif /* HB_SET_DIGEST_HH */ #endif /* HB_SET_DIGEST_HH */

View File

@ -42,9 +42,22 @@ struct hb_sparseset_t
~hb_sparseset_t () { fini (); } ~hb_sparseset_t () { fini (); }
hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); } hb_sparseset_t (const hb_sparseset_t& other) : hb_sparseset_t () { set (other); }
void operator= (const hb_sparseset_t& other) { set (other); } hb_sparseset_t (hb_sparseset_t&& other) : hb_sparseset_t () { s = std::move (other.s); }
// TODO Add move construtor/assign hb_sparseset_t& operator= (const hb_sparseset_t& other) { set (other); return *this; }
// TODO Add constructor for Iterator hb_sparseset_t& operator= (hb_sparseset_t&& other) { hb_swap (*this, other); return *this; }
friend void swap (hb_sparseset_t& a, hb_sparseset_t& b) { hb_swap (a.s, b.s); }
hb_sparseset_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t ()
{
for (auto&& item : lst)
add (item);
}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
hb_sparseset_t (const Iterable &o) : hb_sparseset_t ()
{
hb_copy (o, *this);
}
void init_shallow () { s.init (); } void init_shallow () { s.init (); }
void init () void init ()
@ -140,7 +153,18 @@ struct hb_sparseset_t
operator iter_t () const { return iter (); } operator iter_t () const { return iter (); }
}; };
struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t> {}; struct hb_set_t : hb_sparseset_t<hb_bit_set_invertible_t>
{
hb_set_t () = default;
~hb_set_t () = default;
hb_set_t (hb_set_t& o) = default;
hb_set_t& operator= (const hb_set_t& other) = default;
hb_set_t& operator= (hb_set_t&& other) = default;
hb_set_t (std::initializer_list<hb_codepoint_t> lst) : hb_sparseset_t<hb_bit_set_invertible_t> (lst) {}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
hb_set_t (const Iterable &o) : hb_sparseset_t<hb_bit_set_invertible_t> (o) {}
};
static_assert (hb_set_t::INVALID == HB_SET_VALUE_INVALID, ""); static_assert (hb_set_t::INVALID == HB_SET_VALUE_INVALID, "");

View File

@ -113,7 +113,9 @@ hb_style_get_value (hb_font_t *font, hb_style_tag_t style_tag)
case HB_STYLE_TAG_WIDTH: case HB_STYLE_TAG_WIDTH:
return face->table.OS2->has_data () return face->table.OS2->has_data ()
? face->table.OS2->get_width () ? face->table.OS2->get_width ()
: (face->table.head->is_condensed () ? 75 : 100); : (face->table.head->is_condensed () ? 75 :
face->table.head->is_expanded () ? 125 :
100);
case HB_STYLE_TAG_WEIGHT: case HB_STYLE_TAG_WEIGHT:
return face->table.OS2->has_data () return face->table.OS2->has_data ()
? face->table.OS2->usWeightClass ? face->table.OS2->usWeightClass

View File

@ -42,17 +42,19 @@ struct hb_subset_input_t
{ {
hb_object_header_t header; hb_object_header_t header;
struct sets_t {
hb_set_t *glyphs;
hb_set_t *unicodes;
hb_set_t *no_subset_tables;
hb_set_t *drop_tables;
hb_set_t *name_ids;
hb_set_t *name_languages;
hb_set_t *layout_features;
};
union { union {
struct { sets_t sets;
hb_set_t *glyphs; hb_set_t* set_ptrs[sizeof (sets_t) / sizeof (hb_set_t*)];
hb_set_t *unicodes;
hb_set_t *no_subset_tables;
hb_set_t *drop_tables;
hb_set_t *name_ids;
hb_set_t *name_languages;
hb_set_t *layout_features;
} sets;
hb_set_t* set_ptrs[sizeof (sets) / sizeof (hb_set_t*)];
}; };
unsigned flags; unsigned flags;

View File

@ -38,6 +38,7 @@
#include "hb-ot-color-colrv1-closure.hh" #include "hb-ot-color-colrv1-closure.hh"
#include "hb-ot-var-fvar-table.hh" #include "hb-ot-var-fvar-table.hh"
#include "hb-ot-stat-table.hh" #include "hb-ot-stat-table.hh"
#include "hb-ot-math-table.hh"
typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map; typedef hb_hashmap_t<unsigned, hb_set_t *, (unsigned)-1, nullptr> script_langsys_map;
@ -221,6 +222,50 @@ _cmap_closure (hb_face_t *face,
cmap.fini (); cmap.fini ();
} }
static void _colr_closure (hb_face_t *face,
hb_map_t *layers_map,
hb_map_t *palettes_map,
hb_set_t *glyphs_colred)
{
OT::COLR::accelerator_t colr;
colr.init (face);
if (!colr.is_valid ()) return;
unsigned iteration_count = 0;
hb_set_t palette_indices, layer_indices;
unsigned glyphs_num;
{
glyphs_num = glyphs_colred->get_population ();
// Collect all glyphs referenced by COLRv0
hb_set_t glyphset_colrv0;
for (hb_codepoint_t gid : glyphs_colred->iter ())
colr.closure_glyphs (gid, &glyphset_colrv0);
glyphs_colred->union_ (glyphset_colrv0);
//closure for COLRv1
colr.closure_forV1 (glyphs_colred, &layer_indices, &palette_indices);
} while (iteration_count++ <= HB_CLOSURE_MAX_STAGES &&
glyphs_num != glyphs_colred->get_population ());
colr.closure_V0palette_indices (glyphs_colred, &palette_indices);
_remap_indexes (&layer_indices, layers_map);
_remap_palette_indexes (&palette_indices, palettes_map);
colr.fini ();
}
static inline void
_math_closure (hb_face_t *face,
hb_set_t *glyphset)
{
hb_blob_ptr_t<OT::MATH> math = hb_sanitize_context_t ().reference_table<OT::MATH> (face);
if (math->has_data ())
math->closure_glyphs (glyphset);
math.destroy ();
}
static inline void static inline void
_remove_invalid_gids (hb_set_t *glyphs, _remove_invalid_gids (hb_set_t *glyphs,
unsigned int num_glyphs) unsigned int num_glyphs)
@ -301,12 +346,10 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
#ifndef HB_NO_SUBSET_CFF #ifndef HB_NO_SUBSET_CFF
OT::cff1::accelerator_t cff; OT::cff1::accelerator_t cff;
#endif #endif
OT::COLR::accelerator_t colr;
glyf.init (plan->source); glyf.init (plan->source);
#ifndef HB_NO_SUBSET_CFF #ifndef HB_NO_SUBSET_CFF
cff.init (plan->source); cff.init (plan->source);
#endif #endif
colr.init (plan->source);
plan->_glyphset_gsub->add (0); // Not-def plan->_glyphset_gsub->add (0); // Not-def
@ -334,30 +377,17 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
#endif #endif
_remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ()); _remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
// Collect all glyphs referenced by COLRv0 hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub);
hb_set_t* cur_glyphset = plan->_glyphset_gsub; _math_closure (plan->source, plan->_glyphset_mathed);
hb_set_t glyphset_colrv0; _remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ());
if (colr.is_valid ())
{
glyphset_colrv0.union_ (*cur_glyphset);
for (hb_codepoint_t gid : cur_glyphset->iter ())
colr.closure_glyphs (gid, &glyphset_colrv0);
cur_glyphset = &glyphset_colrv0;
}
hb_set_t palette_indices; hb_set_t cur_glyphset = *plan->_glyphset_mathed;
colr.closure_V0palette_indices (cur_glyphset, &palette_indices); _colr_closure (plan->source, plan->colrv1_layers, plan->colr_palettes, &cur_glyphset);
_remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ());
hb_set_t layer_indices;
colr.closure_forV1 (cur_glyphset, &layer_indices, &palette_indices);
_remap_indexes (&layer_indices, plan->colrv1_layers);
_remap_palette_indexes (&palette_indices, plan->colr_palettes);
colr.fini ();
_remove_invalid_gids (cur_glyphset, plan->source->get_num_glyphs ());
// Populate a full set of glyphs to retain by adding all referenced // Populate a full set of glyphs to retain by adding all referenced
// composite glyphs. // composite glyphs.
for (hb_codepoint_t gid : cur_glyphset->iter ()) for (hb_codepoint_t gid : cur_glyphset.iter ())
{ {
glyf.add_gid_and_children (gid, plan->_glyphset); glyf.add_gid_and_children (gid, plan->_glyphset);
#ifndef HB_NO_SUBSET_CFF #ifndef HB_NO_SUBSET_CFF
@ -468,6 +498,7 @@ hb_subset_plan_create (hb_face_t *face,
plan->_glyphset = hb_set_create (); plan->_glyphset = hb_set_create ();
plan->_glyphset_gsub = hb_set_create (); plan->_glyphset_gsub = hb_set_create ();
plan->_glyphset_mathed = hb_set_create ();
plan->codepoint_to_glyph = hb_map_create (); plan->codepoint_to_glyph = hb_map_create ();
plan->glyph_map = hb_map_create (); plan->glyph_map = hb_map_create ();
plan->reverse_glyph_map = hb_map_create (); plan->reverse_glyph_map = hb_map_create ();
@ -535,6 +566,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
hb_map_destroy (plan->reverse_glyph_map); hb_map_destroy (plan->reverse_glyph_map);
hb_set_destroy (plan->_glyphset); hb_set_destroy (plan->_glyphset);
hb_set_destroy (plan->_glyphset_gsub); hb_set_destroy (plan->_glyphset_gsub);
hb_set_destroy (plan->_glyphset_mathed);
hb_map_destroy (plan->gsub_lookups); hb_map_destroy (plan->gsub_lookups);
hb_map_destroy (plan->gpos_lookups); hb_map_destroy (plan->gpos_lookups);
hb_map_destroy (plan->gsub_features); hb_map_destroy (plan->gsub_features);

View File

@ -77,6 +77,7 @@ struct hb_subset_plan_t
unsigned int _num_output_glyphs; unsigned int _num_output_glyphs;
hb_set_t *_glyphset; hb_set_t *_glyphset;
hb_set_t *_glyphset_gsub; hb_set_t *_glyphset_gsub;
hb_set_t *_glyphset_mathed;
//active lookups we'd like to retain //active lookups we'd like to retain
hb_map_t *gsub_lookups; hb_map_t *gsub_lookups;

View File

@ -52,6 +52,7 @@
#include "hb-ot-layout-gpos-table.hh" #include "hb-ot-layout-gpos-table.hh"
#include "hb-ot-var-gvar-table.hh" #include "hb-ot-var-gvar-table.hh"
#include "hb-ot-var-hvar-table.hh" #include "hb-ot-var-hvar-table.hh"
#include "hb-ot-math-table.hh"
#include "hb-repacker.hh" #include "hb-repacker.hh"
/** /**
@ -109,7 +110,7 @@ _repack (hb_tag_t tag, const hb_serialize_context_t& c)
return nullptr; return nullptr;
hb_serialize_context_t repacked ((void *) buf, buf_size); hb_serialize_context_t repacked ((void *) buf, buf_size);
hb_resolve_overflows (c.object_graph (), &repacked); hb_resolve_overflows (c.object_graph (), tag, &repacked);
if (unlikely (repacked.in_error ())) if (unlikely (repacked.in_error ()))
// TODO(garretrieger): refactor so we can share the resize/retry logic with the subset // TODO(garretrieger): refactor so we can share the resize/retry logic with the subset
@ -305,6 +306,7 @@ _subset_table (hb_subset_plan_t *plan, hb_tag_t tag)
case HB_OT_TAG_CPAL: return _subset<const OT::CPAL> (plan); case HB_OT_TAG_CPAL: return _subset<const OT::CPAL> (plan);
case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan); case HB_OT_TAG_CBLC: return _subset<const OT::CBLC> (plan);
case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */ case HB_OT_TAG_CBDT: return true; /* skip CBDT, handled by CBLC */
case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan);
#ifndef HB_NO_SUBSET_CFF #ifndef HB_NO_SUBSET_CFF
case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan); case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan);

View File

@ -45,14 +45,14 @@ struct hb_subset_context_t :
private: private:
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
( obj.subset (this, hb_forward<Ts> (ds)...) ) ( obj.subset (this, std::forward<Ts> (ds)...) )
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
( obj.dispatch (this, hb_forward<Ts> (ds)...) ) ( obj.dispatch (this, std::forward<Ts> (ds)...) )
public: public:
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
( _dispatch (obj, hb_prioritize, hb_forward<Ts> (ds)...) ) ( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
hb_blob_t *source_blob; hb_blob_t *source_blob;
hb_subset_plan_t *plan; hb_subset_plan_t *plan;

View File

@ -121,7 +121,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
static hb_bool_t static hb_bool_t
is_variation_selector (hb_codepoint_t unicode) is_variation_selector (hb_codepoint_t unicode)
{ {
/* U+180B..180D MONGOLIAN FREE VARIATION SELECTORs are handled in the /* U+180B..180D, U+180F MONGOLIAN FREE VARIATION SELECTORs are handled in the
* Arabic shaper. No need to match them here. */ * Arabic shaper. No need to match them here. */
return unlikely (hb_in_ranges<hb_codepoint_t> (unicode, return unlikely (hb_in_ranges<hb_codepoint_t> (unicode,
0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */ 0xFE00u, 0xFE0Fu, /* VARIATION SELECTOR-1..16 */
@ -136,7 +136,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* As such, we make exceptions for those four. * As such, we make exceptions for those four.
* Also ignoring U+1BCA0..1BCA3. https://github.com/harfbuzz/harfbuzz/issues/503 * Also ignoring U+1BCA0..1BCA3. https://github.com/harfbuzz/harfbuzz/issues/503
* *
* Unicode 7.0: * Unicode 14.0:
* $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/' * $ grep '; Default_Ignorable_Code_Point ' DerivedCoreProperties.txt | sed 's/;.*#/#/'
* 00AD # Cf SOFT HYPHEN * 00AD # Cf SOFT HYPHEN
* 034F # Mn COMBINING GRAPHEME JOINER * 034F # Mn COMBINING GRAPHEME JOINER
@ -145,6 +145,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
* 17B4..17B5 # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA * 17B4..17B5 # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA
* 180B..180D # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE * 180B..180D # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE
* 180E # Cf MONGOLIAN VOWEL SEPARATOR * 180E # Cf MONGOLIAN VOWEL SEPARATOR
* 180F # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR
* 200B..200F # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK * 200B..200F # Cf [5] ZERO WIDTH SPACE..RIGHT-TO-LEFT MARK
* 202A..202E # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE * 202A..202E # Cf [5] LEFT-TO-RIGHT EMBEDDING..RIGHT-TO-LEFT OVERRIDE
* 2060..2064 # Cf [5] WORD JOINER..INVISIBLE PLUS * 2060..2064 # Cf [5] WORD JOINER..INVISIBLE PLUS

View File

@ -38,10 +38,23 @@ struct hb_vector_t
typedef Type item_t; typedef Type item_t;
static constexpr unsigned item_size = hb_static_size (Type); static constexpr unsigned item_size = hb_static_size (Type);
hb_vector_t () { init (); } hb_vector_t () = default;
hb_vector_t (const hb_vector_t &o) hb_vector_t (std::initializer_list<Type> lst) : hb_vector_t ()
{
alloc (lst.size ());
for (auto&& item : lst)
push (item);
}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
hb_vector_t (const Iterable &o) : hb_vector_t ()
{
if (hb_iter (o).is_random_access_iterator)
alloc (hb_len (hb_iter (o)));
hb_copy (o, *this);
}
hb_vector_t (const hb_vector_t &o) : hb_vector_t ()
{ {
init ();
alloc (o.length); alloc (o.length);
hb_copy (o, *this); hb_copy (o, *this);
} }
@ -55,11 +68,11 @@ struct hb_vector_t
~hb_vector_t () { fini (); } ~hb_vector_t () { fini (); }
private: private:
int allocated; /* == -1 means allocation failed. */ int allocated = 0; /* == -1 means allocation failed. */
public: public:
unsigned int length; unsigned int length = 0;
public: public:
Type *arrayZ; Type *arrayZ = nullptr;
void init () void init ()
{ {
@ -87,6 +100,13 @@ struct hb_vector_t
resize (0); resize (0);
} }
friend void swap (hb_vector_t& a, hb_vector_t& b)
{
hb_swap (a.allocated, b.allocated);
hb_swap (a.length, b.length);
hb_swap (a.arrayZ, b.arrayZ);
}
hb_vector_t& operator = (const hb_vector_t &o) hb_vector_t& operator = (const hb_vector_t &o)
{ {
reset (); reset ();
@ -96,11 +116,7 @@ struct hb_vector_t
} }
hb_vector_t& operator = (hb_vector_t &&o) hb_vector_t& operator = (hb_vector_t &&o)
{ {
fini (); hb_swap (*this, o);
allocated = o.allocated;
length = o.length;
arrayZ = o.arrayZ;
o.init ();
return *this; return *this;
} }
@ -134,7 +150,7 @@ struct hb_vector_t
/* Sink interface. */ /* Sink interface. */
template <typename T> template <typename T>
hb_vector_t& operator << (T&& v) { push (hb_forward<T> (v)); return *this; } hb_vector_t& operator << (T&& v) { push (std::forward<T> (v)); return *this; }
hb_array_t< Type> as_array () { return hb_array (arrayZ, length); } hb_array_t< Type> as_array () { return hb_array (arrayZ, length); }
hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); } hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); }
@ -182,7 +198,7 @@ struct hb_vector_t
// the created copy to leak memory since we won't have stored a // the created copy to leak memory since we won't have stored a
// reference to it. // reference to it.
return p; return p;
*p = hb_forward<T> (v); *p = std::forward<T> (v);
return p; return p;
} }
@ -239,7 +255,7 @@ struct hb_vector_t
Type pop () Type pop ()
{ {
if (!length) return Null (Type); if (!length) return Null (Type);
return hb_move (arrayZ[--length]); /* Does this move actually work? */ return std::move (arrayZ[--length]); /* Does this move actually work? */
} }
void remove (unsigned int i) void remove (unsigned int i)
@ -295,6 +311,19 @@ struct hb_vector_t
template <typename Type> template <typename Type>
struct hb_sorted_vector_t : hb_vector_t<Type> struct hb_sorted_vector_t : hb_vector_t<Type>
{ {
hb_sorted_vector_t () = default;
~hb_sorted_vector_t () = default;
hb_sorted_vector_t (hb_sorted_vector_t& o) = default;
hb_sorted_vector_t (hb_sorted_vector_t &&o) = default;
hb_sorted_vector_t (std::initializer_list<Type> lst) : hb_vector_t<Type> (lst) {}
template <typename Iterable,
hb_requires (hb_is_iterable (Iterable))>
hb_sorted_vector_t (const Iterable &o) : hb_vector_t<Type> (o) {}
hb_sorted_vector_t& operator = (const hb_sorted_vector_t &o) = default;
hb_sorted_vector_t& operator = (hb_sorted_vector_t &&o) = default;
friend void swap (hb_sorted_vector_t& a, hb_sorted_vector_t& b)
{ hb_swap ((hb_vector_t<Type>&) (a), (hb_vector_t<Type>&) (b)); }
hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->length); } hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->length); }
hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); } hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); }

View File

@ -47,20 +47,20 @@ HB_BEGIN_DECLS
* *
* The minor component of the library version available at compile-time. * The minor component of the library version available at compile-time.
*/ */
#define HB_VERSION_MINOR 0 #define HB_VERSION_MINOR 1
/** /**
* HB_VERSION_MICRO: * HB_VERSION_MICRO:
* *
* The micro component of the library version available at compile-time. * The micro component of the library version available at compile-time.
*/ */
#define HB_VERSION_MICRO 0 #define HB_VERSION_MICRO 1
/** /**
* HB_VERSION_STRING: * HB_VERSION_STRING:
* *
* A string literal containing the library version available at compile-time. * A string literal containing the library version available at compile-time.
*/ */
#define HB_VERSION_STRING "3.0.0" #define HB_VERSION_STRING "3.1.1"
/** /**
* HB_VERSION_ATLEAST: * HB_VERSION_ATLEAST:

View File

@ -62,6 +62,7 @@
/* Error. Should never happen. */ /* Error. Should never happen. */
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR #ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC_ERROR
#pragma GCC diagnostic error "-Wbitwise-instead-of-logical"
#pragma GCC diagnostic error "-Wcast-align" #pragma GCC diagnostic error "-Wcast-align"
#pragma GCC diagnostic error "-Wcast-function-type" #pragma GCC diagnostic error "-Wcast-function-type"
#pragma GCC diagnostic error "-Wdelete-non-virtual-dtor" #pragma GCC diagnostic error "-Wdelete-non-virtual-dtor"