[HarfBuzz] harfbuzz: Branch 'master' - 11 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Wed Oct 31 06:56:00 UTC 2018
src/hb-aat-layout-common.hh | 105 +++++++++++++----
src/hb-aat-layout-kerx-table.hh | 17 +-
src/hb-aat-layout-morx-table.hh | 243 +++++++++++++++++++++++++---------------
src/hb-aat-layout.cc | 49 +++++++-
src/hb-open-type.hh | 7 +
src/hb-ot-face.hh | 1
src/hb-ot-maxp-table.hh | 2
7 files changed, 296 insertions(+), 128 deletions(-)
New commits:
commit 28b68cffe4e5ebf82217ebf439f428431d672af3
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 23:33:30 2018 -0700
[mort] Implement / adjust Contextual substitution
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index dba352f9..c3a74835 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -213,10 +213,13 @@ struct ContextualSubtable
Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */
};
- inline driver_context_t (const ContextualSubtable *table) :
+ inline driver_context_t (const ContextualSubtable *table_,
+ hb_aat_apply_context_t *c_) :
ret (false),
+ c (c_),
mark_set (false),
mark (0),
+ table (table_),
subs (table+table->substitutionTables) {}
inline bool is_actionable (StateTableDriver<Types, EntryData> *driver,
@@ -239,30 +242,57 @@ struct ContextualSubtable
if (buffer->idx == buffer->len && !mark_set)
return true;
- if (entry->data.markIndex != 0xFFFF)
+ const GlyphID *replacement;
+
+ replacement = nullptr;
+ if (Types::extended)
{
- const Lookup<GlyphID> &lookup = subs[entry->data.markIndex];
- hb_glyph_info_t *info = buffer->info;
- const GlyphID *replacement = lookup.get_value (info[mark].codepoint, driver->num_glyphs);
- if (replacement)
+ if (entry->data.markIndex != 0xFFFF)
{
- buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len));
- info[mark].codepoint = *replacement;
- ret = true;
+ const Lookup<GlyphID> &lookup = subs[entry->data.markIndex];
+ replacement = lookup.get_value (buffer->info[mark].codepoint, driver->num_glyphs);
}
}
- if (entry->data.currentIndex != 0xFFFF)
+ else
+ {
+ unsigned int offset = 2 * (entry->data.markIndex + buffer->info[mark].codepoint);
+ replacement = &StructAtOffset<GlyphID> (table, offset);
+ if ((const void *) replacement < (const void *) subs ||
+ !replacement->sanitize (&c->sanitizer) ||
+ !*replacement)
+ replacement = nullptr;
+ }
+ if (replacement)
+ {
+ buffer->unsafe_to_break (mark, MIN (buffer->idx + 1, buffer->len));
+ buffer->info[mark].codepoint = *replacement;
+ ret = true;
+ }
+
+ replacement = nullptr;
+ unsigned int idx = MIN (buffer->idx, buffer->len - 1);
+ if (Types::extended)
{
- unsigned int idx = MIN (buffer->idx, buffer->len - 1);
- const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex];
- hb_glyph_info_t *info = buffer->info;
- const GlyphID *replacement = lookup.get_value (info[idx].codepoint, driver->num_glyphs);
- if (replacement)
+ if (entry->data.currentIndex != 0xFFFF)
{
- info[idx].codepoint = *replacement;
- ret = true;
+ const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex];
+ replacement = lookup.get_value (buffer->info[idx].codepoint, driver->num_glyphs);
}
}
+ else
+ {
+ unsigned int offset = 2 * (entry->data.currentIndex + buffer->info[idx].codepoint);
+ replacement = &StructAtOffset<GlyphID> (table, offset);
+ if ((const void *) replacement < (const void *) subs ||
+ !replacement->sanitize (&c->sanitizer) ||
+ !*replacement)
+ replacement = nullptr;
+ }
+ if (replacement)
+ {
+ buffer->info[idx].codepoint = *replacement;
+ ret = true;
+ }
if (entry->flags & SetMark)
{
@@ -276,8 +306,10 @@ struct ContextualSubtable
public:
bool ret;
private:
+ hb_aat_apply_context_t *c;
bool mark_set;
unsigned int mark;
+ const ContextualSubtable *table;
const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false> &subs;
};
@@ -285,7 +317,7 @@ struct ContextualSubtable
{
TRACE_APPLY (this);
- driver_context_t dc (this);
+ driver_context_t dc (this, c);
StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
@@ -300,6 +332,8 @@ struct ContextualSubtable
unsigned int num_entries = 0;
if (unlikely (!machine.sanitize (c, &num_entries))) return_trace (false);
+ if (!Types::extended) return_trace (true);
+
unsigned int num_lookups = 0;
const Entry<EntryData> *entries = machine.get_entries ();
diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh
index e9f99b10..00bd134d 100644
--- a/src/hb-open-type.hh
+++ b/src/hb-open-type.hh
@@ -340,6 +340,9 @@ struct UnsizedArrayOf
inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
+ template <typename T> inline operator T * (void) { return arrayZ; }
+ template <typename T> inline operator const T * (void) const { return arrayZ; }
+
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{
TRACE_SANITIZE (this);
@@ -450,6 +453,10 @@ struct ArrayOf
if (unlikely (i >= len)) return Crap(Type);
return arrayZ[i];
}
+
+ template <typename T> inline operator T * (void) { return arrayZ; }
+ template <typename T> inline operator const T * (void) const { return arrayZ; }
+
inline unsigned int get_size (void) const
{ return len.static_size + len * Type::static_size; }
commit 11dbf0f12926b80d0c308c70a218342280045c23
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 21:49:59 2018 -0700
[mort] More fixes]
diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index 65e7fd93..33d9e556 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -430,9 +430,8 @@ struct StateTable
CLASS_END_OF_LINE = 3,
};
- inline unsigned int row_stride (void) const { return nClasses * sizeof (HBUSHORT); }
inline unsigned int new_state (unsigned int newState) const
- { return newState / (Types::extended ? 1 : row_stride ()); }
+ { return Types::extended ? newState : (newState - stateArrayTable) / nClasses; }
inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
@@ -524,7 +523,7 @@ struct StateTable
entryTable; /* Offset to the entry array. */
public:
- DEFINE_SIZE_STATIC (16);
+ DEFINE_SIZE_STATIC (4 * sizeof (HBUINT));
};
struct ClassTable
commit e1552af95b6c17571f7ee58ebac92f48d93c8f98
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 21:09:05 2018 -0700
[maxp] Minor
diff --git a/src/hb-ot-maxp-table.hh b/src/hb-ot-maxp-table.hh
index 648f232d..198dd251 100644
--- a/src/hb-ot-maxp-table.hh
+++ b/src/hb-ot-maxp-table.hh
@@ -92,7 +92,7 @@ struct maxp
if (version.major == 1)
{
const maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*this);
- return v1.sanitize (c);
+ return_trace (v1.sanitize (c));
}
return_trace (likely (version.major == 0 && version.minor == 0x5000u));
}
commit 0cf282a32e5b0fe1fec454ff293ffe04b33f1112
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 20:51:44 2018 -0700
[mort] Grind some more
diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index c9d5cfe9..65e7fd93 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -430,6 +430,10 @@ struct StateTable
CLASS_END_OF_LINE = 3,
};
+ inline unsigned int row_stride (void) const { return nClasses * sizeof (HBUSHORT); }
+ inline unsigned int new_state (unsigned int newState) const
+ { return newState / (Types::extended ? 1 : row_stride ()); }
+
inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
@@ -495,7 +499,10 @@ struct StateTable
{ /* Sweep new entries. */
const Entry<Extra> *stop = &entries[num_entries];
for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
- num_states = MAX<unsigned int> (num_states, p->newState + 1);
+ {
+ unsigned int newState = new_state (p->newState);
+ num_states = MAX<unsigned int> (num_states, newState + 1);
+ }
entry = num_entries;
}
}
@@ -620,17 +627,17 @@ struct StateTableDriver
}
if (unlikely (!c->transition (this, entry)))
- break;
+ break;
last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops-- > 0;
- state = entry->newState;
+ state = machine.new_state (entry->newState);
if (buffer->idx == buffer->len)
- break;
+ break;
if (!last_was_dont_advance)
- buffer->next_glyph ();
+ buffer->next_glyph ();
}
if (!c->in_place)
commit 90667b31bc3e61e68e27966e4781aba456c6b93b
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 20:15:28 2018 -0700
[mort] Hook up more
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index 2b4f5783..b6bdb0be 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -207,7 +207,19 @@ void
hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_aat_map_t *map)
{
- _get_morx (mapper->face).compile_flags (mapper, map);
+ const AAT::morx& morx = _get_morx (mapper->face, nullptr);
+ if (morx.has_data ())
+ {
+ morx.compile_flags (mapper, map);
+ return;
+ }
+
+ const AAT::mort& mort = _get_mort (mapper->face, nullptr);
+ if (mort.has_data ())
+ {
+ mort.compile_flags (mapper, map);
+ return;
+ }
}
commit 9346b1f158dfd7d25ed0057b40aaa6980a85ea17
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 20:04:13 2018 -0700
[morx] Remove stale comment
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 6d6ef708..dba352f9 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -865,8 +865,6 @@ struct Chain
{
hb_mask_t flags = defaultFlags;
{
- /* Compute applicable flags. TODO Should move this to planning
- * stage and take user-requested features into account. */
unsigned int count = featureCount;
for (unsigned i = 0; i < count; i++)
{
commit f864ef215e1354a1e5a3c8796afafba761404e08
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 19:42:21 2018 -0700
[mort] More massaging towards mort
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index a2dd45a0..6d6ef708 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -782,28 +782,29 @@ struct Feature
template <typename Types>
struct ChainSubtable
{
+ typedef typename Types::HBUINT HBUINT;
+
template <typename T>
friend struct Chain;
inline unsigned int get_size (void) const { return length; }
- inline unsigned int get_type (void) const { return coverage & SubtableType; }
+ inline unsigned int get_type (void) const { return coverage & 0xFF; }
+ inline unsigned int get_coverage (void) const { return coverage >> (sizeof (HBUINT) * 8 - 8); }
enum Coverage
{
- Vertical = 0x80000000, /* If set, this subtable will only be applied
- * to vertical text. If clear, this subtable
- * will only be applied to horizontal text. */
- Backwards = 0x40000000, /* If set, this subtable will process glyphs
- * in descending order. If clear, it will
- * process the glyphs in ascending order. */
- AllDirections = 0x20000000, /* If set, this subtable will be applied to
- * both horizontal and vertical text (i.e.
- * the state of bit 0x80000000 is ignored). */
- Logical = 0x10000000, /* If set, this subtable will process glyphs
- * in logical order (or reverse logical order,
- * depending on the value of bit 0x80000000). */
- Reserved = 0x0FFFFF00, /* Reserved, set to zero. */
- SubtableType = 0x000000FF, /* Subtable type; see following table. */
+ Vertical = 0x80, /* If set, this subtable will only be applied
+ * to vertical text. If clear, this subtable
+ * will only be applied to horizontal text. */
+ Backwards = 0x40, /* If set, this subtable will process glyphs
+ * in descending order. If clear, it will
+ * process the glyphs in ascending order. */
+ AllDirections = 0x20, /* If set, this subtable will be applied to
+ * both horizontal and vertical text (i.e.
+ * the state of bit 0x80000000 is ignored). */
+ Logical = 0x10, /* If set, this subtable will process glyphs
+ * in logical order (or reverse logical order,
+ * depending on the value of bit 0x80000000). */
};
enum Type
{
@@ -841,8 +842,8 @@ struct ChainSubtable
}
protected:
- HBUINT32 length; /* Total subtable length, including this header. */
- HBUINT32 coverage; /* Coverage flags and subtable type. */
+ HBUINT length; /* Total subtable length, including this header. */
+ HBUINT coverage; /* Coverage flags and subtable type. */
HBUINT32 subFeatureFlags;/* The 32-bit mask identifying which subtable this is. */
union {
RearrangementSubtable<Types> rearrangement;
@@ -852,7 +853,7 @@ struct ChainSubtable
InsertionSubtable<Types> insertion;
} u;
public:
- DEFINE_SIZE_MIN (2 * sizeof (HBUINT32) + 4);
+ DEFINE_SIZE_MIN (2 * sizeof (HBUINT) + 4);
};
template <typename Types>
@@ -895,9 +896,9 @@ struct Chain
if (!(subtable->subFeatureFlags & flags))
goto skip;
- if (!(subtable->coverage & ChainSubtable<Types>::AllDirections) &&
+ if (!(subtable->get_coverage() & ChainSubtable<Types>::AllDirections) &&
HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
- bool (subtable->coverage & ChainSubtable<Types>::Vertical))
+ bool (subtable->get_coverage() & ChainSubtable<Types>::Vertical))
goto skip;
/* Buffer contents is always in logical direction. Determine if
@@ -927,9 +928,9 @@ struct Chain
(the order opposite that of the characters, which
may be right-to-left or left-to-right).
*/
- reverse = subtable->coverage & ChainSubtable<Types>::Logical ?
- bool (subtable->coverage & ChainSubtable<Types>::Backwards) :
- bool (subtable->coverage & ChainSubtable<Types>::Backwards) !=
+ reverse = subtable->get_coverage () & ChainSubtable<Types>::Logical ?
+ bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) :
+ bool (subtable->get_coverage () & ChainSubtable<Types>::Backwards) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
@@ -981,8 +982,8 @@ struct Chain
}
protected:
- HBUINT defaultFlags; /* The default specification for subtables. */
- HBUINT length; /* Total byte count, including this header. */
+ HBUINT32 defaultFlags; /* The default specification for subtables. */
+ HBUINT32 length; /* Total byte count, including this header. */
HBUINT featureCount; /* Number of feature subtable entries. */
HBUINT subtableCount; /* The number of subtables in the chain. */
@@ -991,7 +992,7 @@ struct Chain
/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */
public:
- DEFINE_SIZE_MIN (2 * sizeof (HBUINT) + 4);
+ DEFINE_SIZE_MIN (8 + 2 * sizeof (HBUINT));
};
commit 2d9467340b1498ccc0cd47bf915b84ab12dfa025
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 19:33:31 2018 -0700
[mort] Fix version check in sanitize
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index e619d9e9..a2dd45a0 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -1052,8 +1052,7 @@ struct mortmorx
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- if (!version.sanitize (c) || version < 2 ||
- !chainCount.sanitize (c))
+ if (!version.sanitize (c) || !version || !chainCount.sanitize (c))
return_trace (false);
const Chain<Types> *chain = &firstChain;
@@ -1070,7 +1069,7 @@ struct mortmorx
protected:
HBUINT16 version; /* Version number of the glyph metamorphosis table.
- * 2 or 3. */
+ * 1, 2, or 3. */
HBUINT16 unused; /* Set to 0. */
HBUINT32 chainCount; /* Number of metamorphosis chains contained in this
* table. */
commit c2527a1bc2b493473f06ea6ae79f0a87b722c4d3
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 19:26:16 2018 -0700
[mort] Make it compile / hook it up
Untested.
diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index 7327cc5b..c9d5cfe9 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -433,8 +433,7 @@ struct StateTable
inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
if (unlikely (glyph_id == DELETED_GLYPH)) return CLASS_DELETED_GLYPH;
- const HBUINT16 *v = (this+classTable).get_value (glyph_id, num_glyphs);
- return v ? (unsigned) *v : (unsigned) CLASS_OUT_OF_BOUNDS;
+ return (this+classTable).get_class (glyph_id, num_glyphs);
}
inline const Entry<Extra> *get_entries () const
@@ -446,7 +445,7 @@ struct StateTable
{
if (unlikely (klass >= nClasses)) return nullptr;
- const HBUINT16 *states = (this+stateArrayTable).arrayZ;
+ const HBUSHORT *states = (this+stateArrayTable).arrayZ;
const Entry<Extra> *entries = (this+entryTable).arrayZ;
unsigned int entry = states[state * nClasses + klass];
@@ -461,7 +460,7 @@ struct StateTable
if (unlikely (!(c->check_struct (this) &&
classTable.sanitize (c, this)))) return_trace (false);
- const HBUINT16 *states = (this+stateArrayTable).arrayZ;
+ const HBUSHORT *states = (this+stateArrayTable).arrayZ;
const Entry<Extra> *entries = (this+entryTable).arrayZ;
unsigned int num_classes = nClasses;
@@ -483,8 +482,8 @@ struct StateTable
if ((c->max_ops -= num_states - state) < 0)
return_trace (false);
{ /* Sweep new states. */
- const HBUINT16 *stop = &states[num_states * num_classes];
- for (const HBUINT16 *p = &states[state * num_classes]; p < stop; p++)
+ const HBUSHORT *stop = &states[num_states * num_classes];
+ for (const HBUSHORT *p = &states[state * num_classes]; p < stop; p++)
num_entries = MAX<unsigned int> (num_entries, *p + 1);
state = num_states;
}
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 99627d3a..e619d9e9 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -278,7 +278,7 @@ struct ContextualSubtable
private:
bool mark_set;
unsigned int mark;
- const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32, false> &subs;
+ const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false> &subs;
};
inline bool apply (hb_aat_apply_context_t *c) const
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index 59157c21..2b4f5783 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -133,20 +133,20 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag)
* mort/morx/kerx/trak
*/
-// static inline const AAT::mort&
-// _get_mort (hb_face_t *face, hb_blob_t **blob = nullptr)
-// {
-// if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
-// {
-// if (blob)
-// *blob = hb_blob_get_empty ();
-// return Null(AAT::mort);
-// }
-// const AAT::morx& mort = *(hb_ot_face_data (face)->mort.get ());
-// if (blob)
-// *blob = hb_ot_face_data (face)->mort.get_blob ();
-// return mort;
-// }
+static inline const AAT::mort&
+_get_mort (hb_face_t *face, hb_blob_t **blob = nullptr)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
+ {
+ if (blob)
+ *blob = hb_blob_get_empty ();
+ return Null(AAT::mort);
+ }
+ const AAT::mort& mort = *(hb_ot_face_data (face)->mort.get ());
+ if (blob)
+ *blob = hb_ot_face_data (face)->mort.get_blob ();
+ return mort;
+}
static inline const AAT::morx&
_get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
{
@@ -214,7 +214,8 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_bool_t
hb_aat_layout_has_substitution (hb_face_t *face)
{
- return _get_morx (face).has_data ();
+ return _get_morx (face).has_data () ||
+ _get_mort (face).has_data ();
}
void
@@ -223,10 +224,22 @@ hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer)
{
hb_blob_t *blob;
+
const AAT::morx& morx = _get_morx (font->face, &blob);
+ if (morx.has_data ())
+ {
+ AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+ morx.apply (&c);
+ return;
+ }
- AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
- morx.apply (&c);
+ const AAT::mort& mort = _get_mort (font->face, &blob);
+ if (mort.has_data ())
+ {
+ AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+ mort.apply (&c);
+ return;
+ }
}
commit 933babdc075c27fbcc1b726c3c9b2aa67338c6ad
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Tue Oct 30 19:22:43 2018 -0700
[mort] Fixup on previous commit
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 336d0e35..99627d3a 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -73,12 +73,12 @@ struct RearrangementSubtable
ret (false),
start (0), end (0) {}
- inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
+ inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry)
{
return (entry->flags & Verb) && start < end;
}
- inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
+ inline bool transition (StateTableDriver<Types, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -169,7 +169,7 @@ struct RearrangementSubtable
driver_context_t dc (this);
- StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->face);
+ StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
@@ -219,7 +219,7 @@ struct ContextualSubtable
mark (0),
subs (table+table->substitutionTables) {}
- inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver,
+ inline bool is_actionable (StateTableDriver<Types, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -229,7 +229,7 @@ struct ContextualSubtable
return entry->data.markIndex != 0xFFFF || entry->data.currentIndex != 0xFFFF;
}
- inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
+ inline bool transition (StateTableDriver<Types, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -287,7 +287,7 @@ struct ContextualSubtable
driver_context_t dc (this);
- StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->face);
+ StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
@@ -373,12 +373,12 @@ struct LigatureSubtable
ligature (table+table->ligature),
match_length (0) {}
- inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
+ inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry)
{
return entry->flags & PerformAction;
}
- inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
+ inline bool transition (StateTableDriver<Types, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -492,7 +492,7 @@ struct LigatureSubtable
driver_context_t dc (this, c);
- StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->face);
+ StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
@@ -636,13 +636,13 @@ struct InsertionSubtable
mark (0),
insertionAction (table+table->insertionAction) {}
- inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
+ inline bool is_actionable (StateTableDriver<Types, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry)
{
return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) &&
(entry->data.currentInsertIndex != 0xFFFF ||entry->data.markedInsertIndex != 0xFFFF);
}
- inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
+ inline bool transition (StateTableDriver<Types, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -734,7 +734,7 @@ struct InsertionSubtable
driver_context_t dc (this, c);
- StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->face);
+ StateTableDriver<Types, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
commit b053cabacd99ff69144a1459fe02ffd574c2416c
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Tue Oct 30 18:41:34 2018 +0330
[mort] Bring back mort generalizations
Started by reverting https://github.com/harfbuzz/harfbuzz/commit/1f1c85a5
Just a starting point, if we agree even mort can come back.
diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index ce40abd5..7327cc5b 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -410,9 +410,13 @@ struct Entry<void>
DEFINE_SIZE_STATIC (4);
};
-template <typename Extra>
+template <typename Types, typename Extra>
struct StateTable
{
+ typedef typename Types::HBUINT HBUINT;
+ typedef typename Types::HBUSHORT HBUSHORT;
+ typedef typename Types::ClassType ClassType;
+
enum State
{
STATE_START_OF_TEXT = 0,
@@ -504,23 +508,73 @@ struct StateTable
}
protected:
- HBUINT32 nClasses; /* Number of classes, which is the number of indices
+ HBUINT nClasses; /* Number of classes, which is the number of indices
* in a single line in the state array. */
- LOffsetTo<Lookup<HBUINT16>, false>
+ OffsetTo<ClassType, HBUINT, false>
classTable; /* Offset to the class table. */
- LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
+ OffsetTo<UnsizedArrayOf<HBUSHORT>, HBUINT, false>
stateArrayTable;/* Offset to the state array. */
- LOffsetTo<UnsizedArrayOf<Entry<Extra> >, false>
+ OffsetTo<UnsizedArrayOf<Entry<Extra> >, HBUINT, false>
entryTable; /* Offset to the entry array. */
public:
DEFINE_SIZE_STATIC (16);
};
-template <typename EntryData>
+struct ClassTable
+{
+ inline unsigned int get_class (hb_codepoint_t glyph_id) const
+ {
+ return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? classArrayZ[glyph_id - firstGlyph] : 1;
+ }
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && classArrayZ.sanitize (c, glyphCount));
+ }
+ protected:
+ GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
+ HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
+ * glyph minus the value of firstGlyph plus 1). */
+ UnsizedArrayOf<HBUINT8>
+ classArrayZ; /* The class codes (indexed by glyph index minus
+ * firstGlyph). */
+ public:
+ DEFINE_SIZE_ARRAY (4, classArrayZ);
+};
+
+struct MortTypes
+{
+ static const bool extended = false;
+ typedef HBUINT16 HBUINT;
+ typedef HBUINT8 HBUSHORT;
+ struct ClassType : ClassTable
+ {
+ inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs HB_UNUSED) const
+ {
+ return ClassTable::get_class (glyph_id);
+ }
+ };
+};
+struct MorxTypes
+{
+ static const bool extended = true;
+ typedef HBUINT32 HBUINT;
+ typedef HBUINT16 HBUSHORT;
+ struct ClassType : Lookup<HBUINT16>
+ {
+ inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
+ {
+ const HBUINT16 *v = get_value (glyph_id, num_glyphs);
+ return v ? *v : 1;
+ }
+ };
+};
+
+template <typename Types, typename EntryData>
struct StateTableDriver
{
- inline StateTableDriver (const StateTable<EntryData> &machine_,
+ inline StateTableDriver (const StateTable<Types, EntryData> &machine_,
hb_buffer_t *buffer_,
hb_face_t *face_) :
machine (machine_),
@@ -533,13 +587,13 @@ struct StateTableDriver
if (!c->in_place)
buffer->clear_output ();
- unsigned int state = StateTable<EntryData>::STATE_START_OF_TEXT;
+ unsigned int state = StateTable<Types, EntryData>::STATE_START_OF_TEXT;
bool last_was_dont_advance = false;
for (buffer->idx = 0; buffer->successful;)
{
unsigned int klass = buffer->idx < buffer->len ?
machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) :
- (unsigned) StateTable<EntryData>::CLASS_END_OF_TEXT;
+ (unsigned) StateTable<Types, EntryData>::CLASS_END_OF_TEXT;
const Entry<EntryData> *entry = machine.get_entryZ (state, klass);
if (unlikely (!entry))
break;
@@ -553,7 +607,7 @@ struct StateTableDriver
/* If there's no action and we're just epsilon-transitioning to state 0,
* safe to break. */
if (c->is_actionable (this, entry) ||
- !(entry->newState == StateTable<EntryData>::STATE_START_OF_TEXT &&
+ !(entry->newState == StateTable<Types, EntryData>::STATE_START_OF_TEXT &&
entry->flags == context_t::DontAdvance))
buffer->unsafe_to_break_from_outbuffer (buffer->backtrack_len () - 1, buffer->idx + 1);
}
@@ -590,7 +644,7 @@ struct StateTableDriver
}
public:
- const StateTable<EntryData> &machine;
+ const StateTable<Types, EntryData> &machine;
hb_buffer_t *buffer;
unsigned int num_glyphs;
};
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index a8831250..94e0a9b6 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -163,12 +163,12 @@ struct KerxSubTableFormat1
kernAction (&table->machine + table->kernAction),
depth (0) {}
- inline bool is_actionable (StateTableDriver<EntryData> *driver HB_UNUSED,
+ inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry)
{
return entry->data.kernActionIndex != 0xFFFF;
}
- inline bool transition (StateTableDriver<EntryData> *driver,
+ inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -239,7 +239,7 @@ struct KerxSubTableFormat1
driver_context_t dc (this, c);
- StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
+ StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->font->face);
driver.drive (&dc);
return_trace (true);
@@ -255,7 +255,7 @@ struct KerxSubTableFormat1
protected:
KerxSubTableHeader header;
- StateTable<EntryData> machine;
+ StateTable<MorxTypes, EntryData> machine;
LOffsetTo<UnsizedArrayOf<FWORD>, false> kernAction;
public:
DEFINE_SIZE_STATIC (32);
@@ -365,12 +365,12 @@ struct KerxSubTableFormat4
mark_set (false),
mark (0) {}
- inline bool is_actionable (StateTableDriver<EntryData> *driver HB_UNUSED,
+ inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry)
{
return entry->data.ankrActionIndex != 0xFFFF;
}
- inline bool transition (StateTableDriver<EntryData> *driver,
+ inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -473,7 +473,7 @@ struct KerxSubTableFormat4
driver_context_t dc (this, c);
- StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
+ StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->font->face);
driver.drive (&dc);
return_trace (true);
@@ -489,7 +489,8 @@ struct KerxSubTableFormat4
protected:
KerxSubTableHeader header;
- StateTable<EntryData> machine;
+ StateTable<MorxTypes, EntryData>
+ machine;
HBUINT32 flags;
public:
DEFINE_SIZE_STATIC (32);
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index a5620910..336d0e35 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -35,17 +35,21 @@
/*
* morx -- Extended Glyph Metamorphosis
* https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6mort.html
*/
#define HB_AAT_TAG_morx HB_TAG('m','o','r','x')
+#define HB_AAT_TAG_mort HB_TAG('m','o','r','t')
namespace AAT {
using namespace OT;
-
+template <typename Types>
struct RearrangementSubtable
{
+ typedef typename Types::HBUINT HBUINT;
+
typedef void EntryData;
struct driver_context_t
@@ -69,12 +73,12 @@ struct RearrangementSubtable
ret (false),
start (0), end (0) {}
- inline bool is_actionable (StateTableDriver<EntryData> *driver HB_UNUSED,
+ inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry)
{
return (entry->flags & Verb) && start < end;
}
- inline bool transition (StateTableDriver<EntryData> *driver,
+ inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -165,7 +169,7 @@ struct RearrangementSubtable
driver_context_t dc (this);
- StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
+ StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
@@ -178,13 +182,16 @@ struct RearrangementSubtable
}
protected:
- StateTable<EntryData> machine;
+ StateTable<Types, EntryData> machine;
public:
DEFINE_SIZE_STATIC (16);
};
+template <typename Types>
struct ContextualSubtable
{
+ typedef typename Types::HBUINT HBUINT;
+
struct EntryData
{
HBUINT16 markIndex; /* Index of the substitution table for the
@@ -212,7 +219,7 @@ struct ContextualSubtable
mark (0),
subs (table+table->substitutionTables) {}
- inline bool is_actionable (StateTableDriver<EntryData> *driver,
+ inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -222,7 +229,7 @@ struct ContextualSubtable
return entry->data.markIndex != 0xFFFF || entry->data.currentIndex != 0xFFFF;
}
- inline bool transition (StateTableDriver<EntryData> *driver,
+ inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -280,7 +287,7 @@ struct ContextualSubtable
driver_context_t dc (this);
- StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
+ StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
@@ -310,16 +317,19 @@ struct ContextualSubtable
}
protected:
- StateTable<EntryData>
+ StateTable<Types, EntryData>
machine;
- LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32, false>, false>
+ OffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT, false>, HBUINT, false>
substitutionTables;
public:
DEFINE_SIZE_STATIC (20);
};
+template <typename Types>
struct LigatureSubtable
{
+ typedef typename Types::HBUINT HBUINT;
+
struct EntryData
{
HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry
@@ -363,12 +373,12 @@ struct LigatureSubtable
ligature (table+table->ligature),
match_length (0) {}
- inline bool is_actionable (StateTableDriver<EntryData> *driver HB_UNUSED,
+ inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry)
{
return entry->flags & PerformAction;
}
- inline bool transition (StateTableDriver<EntryData> *driver,
+ inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -482,7 +492,7 @@ struct LigatureSubtable
driver_context_t dc (this, c);
- StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
+ StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
@@ -497,18 +507,19 @@ struct LigatureSubtable
}
protected:
- StateTable<EntryData>
+ StateTable<Types, EntryData>
machine;
- LOffsetTo<UnsizedArrayOf<HBUINT32>, false>
+ OffsetTo<UnsizedArrayOf<HBUINT32>, HBUINT, false>
ligAction; /* Offset to the ligature action table. */
- LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
+ OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT, false>
component; /* Offset to the component table. */
- LOffsetTo<UnsizedArrayOf<GlyphID>, false>
+ OffsetTo<UnsizedArrayOf<GlyphID>, HBUINT, false>
ligature; /* Offset to the actual ligature lists. */
public:
DEFINE_SIZE_STATIC (28);
};
+template <typename Types>
struct NoncontextualSubtable
{
inline bool apply (hb_aat_apply_context_t *c) const
@@ -545,8 +556,11 @@ struct NoncontextualSubtable
DEFINE_SIZE_MIN (2);
};
+template <typename Types>
struct InsertionSubtable
{
+ typedef typename Types::HBUINT HBUINT;
+
struct EntryData
{
HBUINT16 currentInsertIndex; /* Zero-based index into the insertion glyph table.
@@ -622,13 +636,13 @@ struct InsertionSubtable
mark (0),
insertionAction (table+table->insertionAction) {}
- inline bool is_actionable (StateTableDriver<EntryData> *driver HB_UNUSED,
+ inline bool is_actionable (StateTableDriver<MorxTypes, EntryData> *driver HB_UNUSED,
const Entry<EntryData> *entry)
{
return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) &&
(entry->data.currentInsertIndex != 0xFFFF ||entry->data.markedInsertIndex != 0xFFFF);
}
- inline bool transition (StateTableDriver<EntryData> *driver,
+ inline bool transition (StateTableDriver<MorxTypes, EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
@@ -720,7 +734,7 @@ struct InsertionSubtable
driver_context_t dc (this, c);
- StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
+ StateTableDriver<MorxTypes, EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
@@ -735,9 +749,9 @@ struct InsertionSubtable
}
protected:
- StateTable<EntryData>
+ StateTable<Types, EntryData>
machine;
- LOffsetTo<UnsizedArrayOf<GlyphID>, false>
+ OffsetTo<UnsizedArrayOf<GlyphID>, HBUINT, false>
insertionAction; /* Byte offset from stateHeader to the start of
* the insertion glyph table. */
public:
@@ -765,9 +779,10 @@ struct Feature
DEFINE_SIZE_STATIC (12);
};
-
+template <typename Types>
struct ChainSubtable
{
+ template <typename T>
friend struct Chain;
inline unsigned int get_size (void) const { return length; }
@@ -830,18 +845,21 @@ struct ChainSubtable
HBUINT32 coverage; /* Coverage flags and subtable type. */
HBUINT32 subFeatureFlags;/* The 32-bit mask identifying which subtable this is. */
union {
- RearrangementSubtable rearrangement;
- ContextualSubtable contextual;
- LigatureSubtable ligature;
- NoncontextualSubtable noncontextual;
- InsertionSubtable insertion;
+ RearrangementSubtable<Types> rearrangement;
+ ContextualSubtable<Types> contextual;
+ LigatureSubtable<Types> ligature;
+ NoncontextualSubtable<Types> noncontextual;
+ InsertionSubtable<Types> insertion;
} u;
public:
- DEFINE_SIZE_MIN (12);
+ DEFINE_SIZE_MIN (2 * sizeof (HBUINT32) + 4);
};
+template <typename Types>
struct Chain
{
+ typedef typename Types::HBUINT HBUINT;
+
inline hb_mask_t compile_flags (const hb_aat_map_builder_t *map) const
{
hb_mask_t flags = defaultFlags;
@@ -868,7 +886,7 @@ struct Chain
inline void apply (hb_aat_apply_context_t *c,
hb_mask_t flags) const
{
- const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount);
+ const ChainSubtable<Types> *subtable = &StructAtOffset<ChainSubtable<Types> > (&featureZ, featureZ[0].static_size * featureCount);
unsigned int count = subtableCount;
for (unsigned int i = 0; i < count; i++)
{
@@ -877,9 +895,9 @@ struct Chain
if (!(subtable->subFeatureFlags & flags))
goto skip;
- if (!(subtable->coverage & ChainSubtable::AllDirections) &&
+ if (!(subtable->coverage & ChainSubtable<Types>::AllDirections) &&
HB_DIRECTION_IS_VERTICAL (c->buffer->props.direction) !=
- bool (subtable->coverage & ChainSubtable::Vertical))
+ bool (subtable->coverage & ChainSubtable<Types>::Vertical))
goto skip;
/* Buffer contents is always in logical direction. Determine if
@@ -909,9 +927,9 @@ struct Chain
(the order opposite that of the characters, which
may be right-to-left or left-to-right).
*/
- reverse = subtable->coverage & ChainSubtable::Logical ?
- bool (subtable->coverage & ChainSubtable::Backwards) :
- bool (subtable->coverage & ChainSubtable::Backwards) !=
+ reverse = subtable->coverage & ChainSubtable<Types>::Logical ?
+ bool (subtable->coverage & ChainSubtable<Types>::Backwards) :
+ bool (subtable->coverage & ChainSubtable<Types>::Backwards) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
@@ -932,7 +950,7 @@ struct Chain
if (unlikely (!c->buffer->successful)) return;
skip:
- subtable = &StructAfter<ChainSubtable> (*subtable);
+ subtable = &StructAfter<ChainSubtable<Types> > (*subtable);
c->set_lookup_index (c->lookup_index + 1);
}
}
@@ -950,38 +968,39 @@ struct Chain
if (!c->check_array (featureZ.arrayZ, featureCount))
return_trace (false);
- const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount);
+ const ChainSubtable<Types> *subtable = &StructAtOffset<ChainSubtable<Types> > (&featureZ, featureZ[0].static_size * featureCount);
unsigned int count = subtableCount;
for (unsigned int i = 0; i < count; i++)
{
if (!subtable->sanitize (c))
return_trace (false);
- subtable = &StructAfter<ChainSubtable> (*subtable);
+ subtable = &StructAfter<ChainSubtable<Types> > (*subtable);
}
return_trace (true);
}
protected:
- HBUINT32 defaultFlags; /* The default specification for subtables. */
- HBUINT32 length; /* Total byte count, including this header. */
- HBUINT32 featureCount; /* Number of feature subtable entries. */
- HBUINT32 subtableCount; /* The number of subtables in the chain. */
+ HBUINT defaultFlags; /* The default specification for subtables. */
+ HBUINT length; /* Total byte count, including this header. */
+ HBUINT featureCount; /* Number of feature subtable entries. */
+ HBUINT subtableCount; /* The number of subtables in the chain. */
UnsizedArrayOf<Feature> featureZ; /* Features. */
/*ChainSubtable firstSubtable;*//* Subtables. */
/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */
public:
- DEFINE_SIZE_MIN (16);
+ DEFINE_SIZE_MIN (2 * sizeof (HBUINT) + 4);
};
/*
- * The 'morx' Table
+ * The 'mort'/'morx' Table
*/
-struct morx
+template <typename Types>
+struct mortmorx
{
static const hb_tag_t tableTag = HB_AAT_TAG_morx;
@@ -990,12 +1009,12 @@ struct morx
inline void compile_flags (const hb_aat_map_builder_t *mapper,
hb_aat_map_t *map) const
{
- const Chain *chain = &firstChain;
+ const Chain<Types> *chain = &firstChain;
unsigned int count = chainCount;
for (unsigned int i = 0; i < count; i++)
{
map->chain_flags.push (chain->compile_flags (mapper));
- chain = &StructAfter<Chain> (*chain);
+ chain = &StructAfter<Chain<Types> > (*chain);
}
}
@@ -1019,13 +1038,13 @@ struct morx
{
if (unlikely (!c->buffer->successful)) return;
c->set_lookup_index (0);
- const Chain *chain = &firstChain;
+ const Chain<Types> *chain = &firstChain;
unsigned int count = chainCount;
for (unsigned int i = 0; i < count; i++)
{
chain->apply (c, c->plan->aat_map.chain_flags[i]);
if (unlikely (!c->buffer->successful)) return;
- chain = &StructAfter<Chain> (*chain);
+ chain = &StructAfter<Chain<Types> > (*chain);
}
remove_deleted_glyphs (c->buffer);
}
@@ -1037,13 +1056,13 @@ struct morx
!chainCount.sanitize (c))
return_trace (false);
- const Chain *chain = &firstChain;
+ const Chain<Types> *chain = &firstChain;
unsigned int count = chainCount;
for (unsigned int i = 0; i < count; i++)
{
if (!chain->sanitize (c, version))
return_trace (false);
- chain = &StructAfter<Chain> (*chain);
+ chain = &StructAfter<Chain<Types> > (*chain);
}
return_trace (true);
@@ -1055,12 +1074,22 @@ struct morx
HBUINT16 unused; /* Set to 0. */
HBUINT32 chainCount; /* Number of metamorphosis chains contained in this
* table. */
- Chain firstChain; /* Chains. */
+ Chain<Types> firstChain; /* Chains. */
public:
DEFINE_SIZE_MIN (8);
};
+struct morx : mortmorx<MorxTypes>
+{
+ static const hb_tag_t tableTag = HB_AAT_TAG_morx;
+};
+struct mort : mortmorx<MortTypes>
+{
+ static const hb_tag_t tableTag = HB_AAT_TAG_mort;
+};
+
+
} /* namespace AAT */
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index ec053938..59157c21 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -130,9 +130,23 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag)
/*
- * morx/kerx/trak
+ * mort/morx/kerx/trak
*/
+// static inline const AAT::mort&
+// _get_mort (hb_face_t *face, hb_blob_t **blob = nullptr)
+// {
+// if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
+// {
+// if (blob)
+// *blob = hb_blob_get_empty ();
+// return Null(AAT::mort);
+// }
+// const AAT::morx& mort = *(hb_ot_face_data (face)->mort.get ());
+// if (blob)
+// *blob = hb_ot_face_data (face)->mort.get_blob ();
+// return mort;
+// }
static inline const AAT::morx&
_get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
{
diff --git a/src/hb-ot-face.hh b/src/hb-ot-face.hh
index f3b7945b..6e629eb4 100644
--- a/src/hb-ot-face.hh
+++ b/src/hb-ot-face.hh
@@ -52,6 +52,7 @@
HB_OT_TABLE(OT, BASE) \
/* AAT shaping. */ \
HB_OT_TABLE(AAT, morx) \
+ HB_OT_TABLE(AAT, mort) \
HB_OT_TABLE(AAT, kerx) \
HB_OT_TABLE(AAT, ankr) \
HB_OT_TABLE(AAT, trak) \
More information about the HarfBuzz
mailing list