[morx] Implement InsertionChain

pull/1197/head
Behdad Esfahbod 6 years ago
parent d8d1e7df00
commit 388ab91642
  1. 87
      src/hb-aat-layout-morx-table.hh

@ -608,80 +608,59 @@ struct InsertionSubtable
hb_buffer_t *buffer = driver->buffer; hb_buffer_t *buffer = driver->buffer;
unsigned int flags = entry->flags; unsigned int flags = entry->flags;
if (0) if (entry->data.markedInsertIndex != 0xFFFF)
c->sanitizer.check_range (nullptr, 0);
#if 0
if (flags & SetComponent)
{ {
if (unlikely (match_length >= ARRAY_LENGTH (match_positions))) unsigned int count = (entry->flags & MarkedInsertCount);
return false; unsigned int start = entry->data.markedInsertIndex;
const GlyphID *glyphs = &insertionAction[start];
if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
/* Never mark same index twice, in case DontAdvance was used... */ bool before = entry->flags & MarkedInsertBefore;
if (match_length && match_positions[match_length - 1] == buffer->out_len)
match_length--;
match_positions[match_length++] = buffer->out_len; if (unlikely (!mark_set)) return false;
}
if (flags & PerformAction)
{
unsigned int end = buffer->out_len; unsigned int end = buffer->out_len;
unsigned int action_idx = entry->data.ligActionIndex; buffer->move_to (mark);
unsigned int action;
unsigned int ligature_idx = 0;
do
{
if (unlikely (!match_length))
return false;
buffer->move_to (match_positions[--match_length]); if (!before)
buffer->copy_glyph ();
/* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++)
buffer->output_glyph (glyphs[i]);
if (!before)
buffer->skip_glyph ();
const HBUINT32 &actionData = ligAction[action_idx]; buffer->move_to (end + count);
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 (entry->data.currentInsertIndex != 0xFFFF)
if (unlikely (!componentData.sanitize (&c->sanitizer))) return false; {
ligature_idx += componentData; unsigned int count = (entry->flags & CurrentInsertCount) >> 5;
unsigned int start = entry->data.currentInsertIndex;
const GlyphID *glyphs = &insertionAction[start];
if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
if (action & (LigActionStore | LigActionLast)) bool before = entry->flags & CurrentInsertBefore;
{
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; unsigned int end = buffer->out_len;
buffer->replace_glyph (lig);
//ligature_idx = 0; // XXX Yes or no? if (!before)
} buffer->copy_glyph ();
else /* TODO We ignore KashidaLike setting. */
{ for (unsigned int i = 0; i < count; i++)
buffer->skip_glyph (); buffer->output_glyph (glyphs[i]);
end--; if (!before)
} buffer->skip_glyph ();
/* TODO merge_clusters / unsafe_to_break */
action_idx++;
}
while (!(action & LigActionLast));
buffer->move_to (end); buffer->move_to (end);
} }
#endif
if (flags & SetMark) if (flags & SetMark)
{ {
mark_set = true; mark_set = true;
mark = buffer->idx; mark = buffer->out_len;
} }
return true; return true;
} }

Loading…
Cancel
Save