[morx] Implement InsertionChain

pull/1197/head
Behdad Esfahbod 6 years ago
parent d8d1e7df00
commit 388ab91642
  1. 85
      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]);
const HBUINT32 &actionData = ligAction[action_idx];
if (unlikely (!actionData.sanitize (&c->sanitizer))) return false;
action = actionData;
uint32_t uoffset = action & LigActionOffset; if (!before)
if (uoffset & 0x20000000) buffer->copy_glyph ();
uoffset += 0xC0000000; /* TODO We ignore KashidaLike setting. */
int32_t offset = (int32_t) uoffset; for (unsigned int i = 0; i < count; i++)
unsigned int component_idx = buffer->cur().codepoint + offset; buffer->output_glyph (glyphs[i]);
if (!before)
buffer->skip_glyph ();
const HBUINT16 &componentData = component[component_idx]; buffer->move_to (end + count);
if (unlikely (!componentData.sanitize (&c->sanitizer))) return false; }
ligature_idx += componentData;
if (action & (LigActionStore | LigActionLast)) if (entry->data.currentInsertIndex != 0xFFFF)
{ {
const GlyphID &ligatureData = ligature[ligature_idx]; unsigned int count = (entry->flags & CurrentInsertCount) >> 5;
if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false; unsigned int start = entry->data.currentInsertIndex;
hb_codepoint_t lig = ligatureData; const GlyphID *glyphs = &insertionAction[start];
if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
match_positions[match_length++] = buffer->out_len; bool before = entry->flags & CurrentInsertBefore;
buffer->replace_glyph (lig);
//ligature_idx = 0; // XXX Yes or no? unsigned int end = buffer->out_len;
}
else 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 (); buffer->skip_glyph ();
end--;
}
/* 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