Port Arabic fallback ligating to share code with GSUB
This will eventually allow us to skip marks, as well as (fallback) attach marks to ligature components of fallback-shaped Arabic. That would be pretty cool. I kludged GDEF props in, so mark-skipping works, but the produced ligature id/components will be cleared later by substitute_start() et al. Perhaps using a synthetic table for Arabic fallback shaping was a better idea. The current approach has way too many layering violations...
This commit is contained in:
parent
5e399a8a45
commit
2fcbbdb41a
@ -134,6 +134,10 @@ struct hb_apply_context_t
|
||||
has_glyph_classes (gdef.has_glyph_classes ()),
|
||||
digest (*digest_) {}
|
||||
|
||||
void set_lookup_props (unsigned int lookup_props_) {
|
||||
lookup_props = lookup_props_;
|
||||
}
|
||||
|
||||
void set_lookup (const Lookup &l) {
|
||||
lookup_props = l.get_props ();
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#include "hb-ot-shape-complex-private.hh"
|
||||
#include "hb-ot-shape-private.hh"
|
||||
|
||||
#include "hb-ot-layout-gsubgpos-private.hh"
|
||||
|
||||
|
||||
/* buffer var allocations */
|
||||
@ -88,17 +88,6 @@ static hb_codepoint_t get_arabic_shape (hb_codepoint_t u, unsigned int shape)
|
||||
return u;
|
||||
}
|
||||
|
||||
static uint16_t get_ligature (hb_codepoint_t first, hb_codepoint_t second)
|
||||
{
|
||||
if (unlikely (!second)) return 0;
|
||||
for (unsigned i = 0; i < ARRAY_LENGTH (ligature_table); i++)
|
||||
if (ligature_table[i].first == first)
|
||||
for (unsigned j = 0; j < ARRAY_LENGTH (ligature_table[i].ligatures); j++)
|
||||
if (ligature_table[i].ligatures[j].second == second)
|
||||
return ligature_table[i].ligatures[j].ligature;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const hb_tag_t arabic_features[] =
|
||||
{
|
||||
HB_TAG('i','n','i','t'),
|
||||
@ -257,20 +246,57 @@ arabic_fallback_shape (hb_font_t *font, hb_buffer_t *buffer)
|
||||
buffer->info[i].codepoint = shaped;
|
||||
}
|
||||
|
||||
OT::hb_apply_context_t c (font, buffer, 1/*global mask*/, NULL);
|
||||
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
||||
|
||||
/* Mandatory ligatures */
|
||||
buffer->clear_output ();
|
||||
for (buffer->idx = 0; buffer->idx + 1 < count;) {
|
||||
hb_codepoint_t ligature = get_ligature (buffer->cur().codepoint,
|
||||
buffer->cur(+1).codepoint);
|
||||
if (likely (!ligature) || !(font->get_glyph (ligature, 0, &glyph))) {
|
||||
buffer->next_glyph ();
|
||||
continue;
|
||||
for (buffer->idx = 0; buffer->idx + 1 < count;)
|
||||
{
|
||||
const unsigned int count = 2;
|
||||
unsigned int end_offset;
|
||||
bool is_mark_ligature;
|
||||
unsigned int total_component_count;
|
||||
|
||||
bool matched = false;
|
||||
for (unsigned i = 0; i < ARRAY_LENGTH (ligature_table); i++)
|
||||
{
|
||||
if (ligature_table[i].first != buffer->cur().codepoint)
|
||||
continue;
|
||||
for (unsigned j = 0; j < ARRAY_LENGTH (ligature_table[i].ligatures); j++)
|
||||
{
|
||||
OT::USHORT component;
|
||||
component.set (ligature_table[i].ligatures[j].second);
|
||||
hb_codepoint_t ligature = ligature_table[i].ligatures[j].ligature;
|
||||
if (likely (!OT::match_input (&c, count,
|
||||
&component,
|
||||
OT::match_glyph,
|
||||
NULL,
|
||||
&end_offset,
|
||||
&is_mark_ligature,
|
||||
&total_component_count) ||
|
||||
!(font->get_glyph (ligature, 0, &glyph))))
|
||||
continue;
|
||||
|
||||
/* Deal, we are forming the ligature. */
|
||||
buffer->merge_clusters (buffer->idx, buffer->idx + end_offset);
|
||||
|
||||
OT::ligate_input (&c,
|
||||
count,
|
||||
&component,
|
||||
ligature,
|
||||
OT::match_glyph,
|
||||
NULL,
|
||||
is_mark_ligature,
|
||||
total_component_count);
|
||||
matched = true;
|
||||
break;
|
||||
}
|
||||
if (matched)
|
||||
break;
|
||||
}
|
||||
|
||||
buffer->replace_glyphs (2, 1, &ligature);
|
||||
|
||||
/* Technically speaking we can skip marks and stuff, like the GSUB path does.
|
||||
* But who cares, we're in fallback! */
|
||||
if (!matched)
|
||||
buffer->next_glyph ();
|
||||
}
|
||||
for (; buffer->idx < count;)
|
||||
buffer->next_glyph ();
|
||||
|
@ -319,8 +319,10 @@ hb_ot_map_glyphs_fast (hb_buffer_t *buffer)
|
||||
static inline void
|
||||
hb_ot_substitute_default (hb_ot_shape_context_t *c)
|
||||
{
|
||||
if (c->plan->shaper->preprocess_text)
|
||||
if (c->plan->shaper->preprocess_text) {
|
||||
hb_synthesize_glyph_classes (c); /* XXX This is a hack for now. */
|
||||
c->plan->shaper->preprocess_text (c->plan, c->buffer, c->font);
|
||||
}
|
||||
|
||||
hb_ot_mirror_chars (c);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user