[HarfBuzz] harfbuzz: Branch 'master' - 3 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Sat Sep 15 17:14:12 UTC 2018
src/hb-aat-layout-morx-table.hh | 257 +++++++++++++++++++++++++++++++++++-----
1 file changed, 230 insertions(+), 27 deletions(-)
New commits:
commit 9ff76c6025b55d184c96b193f23aa935ab32f1fc
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Sep 15 18:31:14 2018 +0200
[morx] Respect default feature settings
Does NOT apply user-selected features. But at least now enables
correct subtables.
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 52de7bcd..c544cb37 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -760,11 +760,6 @@ struct ChainSubtable
Insertion = 5
};
- inline void apply (hb_aat_apply_context_t *c) const
- {
- dispatch (c);
- }
-
template <typename context_t>
inline typename context_t::return_t dispatch (context_t *c) const
{
@@ -810,21 +805,38 @@ struct Chain
{
inline void apply (hb_aat_apply_context_t *c) const
{
+ uint32_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++)
+ {
+ const Feature &feature = featureZ[i];
+ if (false) /* XXX Check if feature enabled... */
+ {
+ flags &= feature.disableFlags;
+ flags |= feature.enableFlags;
+ }
+ }
+ }
+
const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount);
unsigned int count = subtableCount;
for (unsigned int i = 0; i < count; i++)
{
+ if (!(subtable->subFeatureFlags & flags))
+ goto skip;
+
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
- {
- c->set_lookup_index (c->lookup_index + 1);
- continue;
- }
+ goto skip;
- subtable->apply (c);
- subtable = &StructAfter<ChainSubtable> (*subtable);
+ subtable->dispatch (c);
(void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index);
+ skip:
+ subtable = &StructAfter<ChainSubtable> (*subtable);
c->set_lookup_index (c->lookup_index + 1);
}
}
commit 2f97da6e2d6629e112789d399765d90f96952c0a
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Sep 15 14:51:50 2018 +0200
[aat] Change version field
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index 82e1d13f..52de7bcd 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -831,7 +831,7 @@ struct Chain
inline unsigned int get_size (void) const { return length; }
- inline bool sanitize (hb_sanitize_context_t *c, unsigned int major) const
+ inline bool sanitize (hb_sanitize_context_t *c, unsigned int version) const
{
TRACE_SANITIZE (this);
if (!length.sanitize (c) ||
@@ -862,7 +862,7 @@ struct Chain
UnsizedArrayOf<Feature> featureZ; /* Features. */
/*ChainSubtable firstSubtable;*//* Subtables. */
-/*subtableGlyphCoverageArray*/ /* Only if major == 3. */
+/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */
public:
DEFINE_SIZE_MIN (16);
@@ -892,8 +892,7 @@ struct morx
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- if (!version.sanitize (c) ||
- (version.major >> (sizeof (HBUINT32) == 4 ? 1 : 0)) != 1 ||
+ if (!version.sanitize (c) || version < 2 ||
!chainCount.sanitize (c))
return_trace (false);
@@ -901,7 +900,7 @@ struct morx
unsigned int count = chainCount;
for (unsigned int i = 0; i < count; i++)
{
- if (!chain->sanitize (c, version.major))
+ if (!chain->sanitize (c, version))
return_trace (false);
chain = &StructAfter<Chain> (*chain);
}
@@ -910,8 +909,9 @@ struct morx
}
protected:
- FixedVersion<>version; /* Version number of the glyph metamorphosis table.
- * 1 for mort, 2 or 3 for morx. */
+ HBUINT16 version; /* Version number of the glyph metamorphosis table.
+ * 2 or 3. */
+ HBUINT16 unused; /* Set to 0. */
HBUINT32 chainCount; /* Number of metamorphosis chains contained in this
* table. */
Chain firstChain; /* Chains. */
commit 29c2bd1795b933a611512af50a14f25e25d43159
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Sep 15 14:47:18 2018 +0200
[morx] Add stub for InsertionChain
diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh
index e4774c4c..82e1d13f 100644
--- a/src/hb-aat-layout-morx-table.hh
+++ b/src/hb-aat-layout-morx-table.hh
@@ -50,7 +50,8 @@ struct RearrangementSubtable
struct driver_context_t
{
static const bool in_place = true;
- enum Flags {
+ enum Flags
+ {
MarkFirst = 0x8000, /* If set, make the current glyph the first
* glyph to be rearranged. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph
@@ -196,7 +197,8 @@ struct ContextualSubtable
struct driver_context_t
{
static const bool in_place = true;
- enum Flags {
+ enum Flags
+ {
SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. */
@@ -329,7 +331,8 @@ struct LigatureSubtable
struct driver_context_t
{
static const bool in_place = false;
- enum Flags {
+ enum Flags
+ {
SetComponent = 0x8000, /* Push this glyph onto the component stack for
* eventual processing. */
DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the
@@ -338,7 +341,8 @@ struct LigatureSubtable
* group. */
Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */
};
- enum LigActionFlags {
+ enum LigActionFlags
+ {
LigActionLast = 0x80000000, /* This is the last action in the list. This also
* implies storage. */
LigActionStore = 0x40000000, /* Store the ligature at the current cumulated index
@@ -517,19 +521,205 @@ struct NoncontextualSubtable
struct InsertionSubtable
{
+ struct EntryData
+ {
+ HBUINT16 currentInsertIndex; /* Zero-based index into the insertion glyph table.
+ * The number of glyphs to be inserted is contained
+ * in the currentInsertCount field in the flags.
+ * A value of 0xFFFF indicates no insertion is to
+ * be done. */
+ HBUINT16 markedInsertIndex; /* Zero-based index into the insertion glyph table.
+ * The number of glyphs to be inserted is contained
+ * in the markedInsertCount field in the flags.
+ * A value of 0xFFFF indicates no insertion is to
+ * be done. */
+ public:
+ DEFINE_SIZE_STATIC (4);
+ };
+
+ struct driver_context_t
+ {
+ static const bool in_place = false;
+ enum Flags
+ {
+ SetMark = 0x8000, /* If set, mark the current glyph. */
+ DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
+ * going to the new state. This does not mean
+ * that the glyph pointed to is the same one as
+ * before. If you've made insertions immediately
+ * downstream of the current glyph, the next glyph
+ * processed would in fact be the first one
+ * inserted. */
+ CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero,
+ * then the specified glyph list will be inserted
+ * as a kashida-like insertion, either before or
+ * after the current glyph (depending on the state
+ * of the currentInsertBefore flag). If clear, and
+ * the currentInsertList is nonzero, then the
+ * specified glyph list will be inserted as a
+ * split-vowel-like insertion, either before or
+ * after the current glyph (depending on the state
+ * of the currentInsertBefore flag). */
+ MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero,
+ * then the specified glyph list will be inserted
+ * as a kashida-like insertion, either before or
+ * after the marked glyph (depending on the state
+ * of the markedInsertBefore flag). If clear, and
+ * the markedInsertList is nonzero, then the
+ * specified glyph list will be inserted as a
+ * split-vowel-like insertion, either before or
+ * after the marked glyph (depending on the state
+ * of the markedInsertBefore flag). */
+ CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made
+ * to the left of the current glyph. If clear,
+ * they're made to the right of the current glyph. */
+ MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be
+ * made to the left of the marked glyph. If clear,
+ * they're made to the right of the marked glyph. */
+ CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the
+ * number of glyphs to insert at the current
+ * position. Since zero means no insertions, the
+ * largest number of insertions at any given
+ * current location is 31 glyphs. */
+ MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the
+ * number of glyphs to insert at the marked
+ * position. Since zero means no insertions, the
+ * largest number of insertions at any given
+ * marked location is 31 glyphs. */
+ };
+
+ inline driver_context_t (const InsertionSubtable *table,
+ hb_aat_apply_context_t *c_) :
+ ret (false),
+ c (c_),
+ mark_set (false),
+ mark (0),
+ insertionAction (table+table->insertionAction) {}
+
+ inline bool is_actionable (StateTableDriver<EntryData> *driver,
+ const Entry<EntryData> *entry)
+ {
+ return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) &&
+ (entry->data.currentInsertIndex != 0xFFFF ||entry->data.markedInsertIndex != 0xFFFF);
+ }
+ inline bool transition (StateTableDriver<EntryData> *driver,
+ const Entry<EntryData> *entry)
+ {
+ hb_buffer_t *buffer = driver->buffer;
+ unsigned int flags = entry->flags;
+
+#if 0
+ if (flags & SetComponent)
+ {
+ if (unlikely (match_length >= ARRAY_LENGTH (match_positions)))
+ return false;
+
+ /* Never mark same index twice, in case DontAdvance was used... */
+ if (match_length && match_positions[match_length - 1] == buffer->out_len)
+ match_length--;
+
+ match_positions[match_length++] = buffer->out_len;
+ }
+
+ if (flags & PerformAction)
+ {
+ unsigned int end = buffer->out_len;
+ unsigned int action_idx = entry->data.ligActionIndex;
+ unsigned int action;
+ unsigned int ligature_idx = 0;
+ do
+ {
+ if (unlikely (!match_length))
+ return false;
+
+ buffer->move_to (match_positions[--match_length]);
+
+ const HBUINT32 &actionData = ligAction[action_idx];
+ if (unlikely (!actionData.sanitize (&c->sanitizer))) return false;
+ action = actionData;
+
+ uint32_t uoffset = action & LigActionOffset;
+ if (uoffset & 0x20000000)
+ uoffset += 0xC0000000;
+ int32_t offset = (int32_t) uoffset;
+ unsigned int component_idx = buffer->cur().codepoint + offset;
+
+ const HBUINT16 &componentData = component[component_idx];
+ if (unlikely (!componentData.sanitize (&c->sanitizer))) return false;
+ ligature_idx += componentData;
+
+ if (action & (LigActionStore | LigActionLast))
+ {
+ const GlyphID &ligatureData = ligature[ligature_idx];
+ if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false;
+ hb_codepoint_t lig = ligatureData;
+
+ match_positions[match_length++] = buffer->out_len;
+ buffer->replace_glyph (lig);
+
+ //ligature_idx = 0; // XXX Yes or no?
+ }
+ else
+ {
+ buffer->skip_glyph ();
+ end--;
+ }
+ /* TODO merge_clusters / unsafe_to_break */
+
+ action_idx++;
+ }
+ while (!(action & LigActionLast));
+ buffer->move_to (end);
+ }
+#endif
+
+ if (flags & SetMark)
+ {
+ mark_set = true;
+ mark = buffer->idx;
+ }
+
+
+ return true;
+ }
+
+ public:
+ bool ret;
+ private:
+ hb_aat_apply_context_t *c;
+ bool mark_set;
+ unsigned int mark;
+ const UnsizedArrayOf<GlyphID> &insertionAction;
+ };
+
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
- /* TODO */
- return_trace (false);
+
+ driver_context_t dc (this, c);
+
+ StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
+ driver.drive (&dc);
+
+ return_trace (dc.ret);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- /* TODO */
- return_trace (true);
+ /* The rest of array sanitizations are done at run-time. */
+ return_trace (c->check_struct (this) && machine.sanitize (c) &&
+ insertionAction);
}
+
+ protected:
+ StateTable<EntryData>
+ machine;
+ LOffsetTo<UnsizedArrayOf<GlyphID> >
+ insertionAction; /* Byte offset from stateHeader to the start of
+ * the insertion glyph table. */
+ public:
+ DEFINE_SIZE_STATIC (20);
};
@@ -561,7 +751,8 @@ struct ChainSubtable
inline unsigned int get_size (void) const { return length; }
inline unsigned int get_type (void) const { return coverage & 0xFF; }
- enum Type {
+ enum Type
+ {
Rearrangement = 0,
Contextual = 1,
Ligature = 2,
More information about the HarfBuzz
mailing list