[morx] Add stub for InsertionChain
This commit is contained in:
parent
f8ccb545c4
commit
29c2bd1795
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user