[morx] Add stub for InsertionChain
This commit is contained in:
parent
f8ccb545c4
commit
29c2bd1795
|
@ -50,7 +50,8 @@ struct RearrangementSubtable
|
||||||
struct driver_context_t
|
struct driver_context_t
|
||||||
{
|
{
|
||||||
static const bool in_place = true;
|
static const bool in_place = true;
|
||||||
enum Flags {
|
enum Flags
|
||||||
|
{
|
||||||
MarkFirst = 0x8000, /* If set, make the current glyph the first
|
MarkFirst = 0x8000, /* If set, make the current glyph the first
|
||||||
* glyph to be rearranged. */
|
* glyph to be rearranged. */
|
||||||
DontAdvance = 0x4000, /* If set, don't advance to the next glyph
|
DontAdvance = 0x4000, /* If set, don't advance to the next glyph
|
||||||
|
@ -196,7 +197,8 @@ struct ContextualSubtable
|
||||||
struct driver_context_t
|
struct driver_context_t
|
||||||
{
|
{
|
||||||
static const bool in_place = true;
|
static const bool in_place = true;
|
||||||
enum Flags {
|
enum Flags
|
||||||
|
{
|
||||||
SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */
|
SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */
|
||||||
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
|
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
|
||||||
* going to the new state. */
|
* going to the new state. */
|
||||||
|
@ -329,7 +331,8 @@ struct LigatureSubtable
|
||||||
struct driver_context_t
|
struct driver_context_t
|
||||||
{
|
{
|
||||||
static const bool in_place = false;
|
static const bool in_place = false;
|
||||||
enum Flags {
|
enum Flags
|
||||||
|
{
|
||||||
SetComponent = 0x8000, /* Push this glyph onto the component stack for
|
SetComponent = 0x8000, /* Push this glyph onto the component stack for
|
||||||
* eventual processing. */
|
* eventual processing. */
|
||||||
DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the
|
DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the
|
||||||
|
@ -338,7 +341,8 @@ struct LigatureSubtable
|
||||||
* group. */
|
* group. */
|
||||||
Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */
|
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
|
LigActionLast = 0x80000000, /* This is the last action in the list. This also
|
||||||
* implies storage. */
|
* implies storage. */
|
||||||
LigActionStore = 0x40000000, /* Store the ligature at the current cumulated index
|
LigActionStore = 0x40000000, /* Store the ligature at the current cumulated index
|
||||||
|
@ -517,19 +521,205 @@ struct NoncontextualSubtable
|
||||||
|
|
||||||
struct InsertionSubtable
|
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
|
inline bool apply (hb_aat_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
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
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
/* TODO */
|
/* The rest of array sanitizations are done at run-time. */
|
||||||
return_trace (true);
|
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_size (void) const { return length; }
|
||||||
inline unsigned int get_type (void) const { return coverage & 0xFF; }
|
inline unsigned int get_type (void) const { return coverage & 0xFF; }
|
||||||
|
|
||||||
enum Type {
|
enum Type
|
||||||
|
{
|
||||||
Rearrangement = 0,
|
Rearrangement = 0,
|
||||||
Contextual = 1,
|
Contextual = 1,
|
||||||
Ligature = 2,
|
Ligature = 2,
|
||||||
|
|
Loading…
Reference in New Issue