staticconst hb_tag_t
use_basic_features[] =
{ /* * Basic features. * These features are applied all at once, before reordering, constrained * to the syllable.
*/
HB_TAG('r','k','r','f'),
HB_TAG('a','b','v','f'),
HB_TAG('b','l','w','f'),
HB_TAG('h','a','l','f'),
HB_TAG('p','s','t','f'),
HB_TAG('v','a','t','u'),
HB_TAG('c','j','c','t'),
}; staticconst hb_tag_t
use_topographical_features[] =
{
HB_TAG('i','s','o','l'),
HB_TAG('i','n','i','t'),
HB_TAG('m','e','d','i'),
HB_TAG('f','i','n','a'),
}; /* Same order as use_topographical_features. */ enum joining_form_t {
JOINING_FORM_ISOL,
JOINING_FORM_INIT,
JOINING_FORM_MEDI,
JOINING_FORM_FINA,
_JOINING_FORM_NONE
}; staticconst hb_tag_t
use_other_features[] =
{ /* * Other features. * These features are applied all at once, after reordering and * clearing syllables.
*/
HB_TAG('a','b','v','s'),
HB_TAG('b','l','w','s'),
HB_TAG('h','a','l','n'),
HB_TAG('p','r','e','s'),
HB_TAG('p','s','t','s'),
};
/* Do this before allocating use_category(). */ if (use_plan->arabic_plan)
{
setup_masks_arabic_plan (use_plan->arabic_plan, buffer, plan->props.script);
}
HB_BUFFER_ALLOCATE_VAR (buffer, use_category);
/* We cannot setup masks here. We save information about characters
* and setup masks later on in a pause-callback. */
unsignedint count = buffer->len;
hb_glyph_info_t *info = buffer->info; for (unsignedint i = 0; i < count; i++)
info[i].use_category() = hb_use_get_category (info[i].codepoint);
}
case use_virama_terminated_cluster: case use_sakot_terminated_cluster: case use_standard_cluster: case use_number_joiner_terminated_cluster: case use_numeral_cluster: case use_symbol_cluster: case use_broken_cluster:
if (join)
{ /* Fixup previous syllable's form. */
last_form = last_form == JOINING_FORM_FINA ? JOINING_FORM_MEDI : JOINING_FORM_INIT; for (unsignedint i = last_start; i < start; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
}
/* Form for this syllable. */
last_form = join ? JOINING_FORM_FINA : JOINING_FORM_ISOL; for (unsignedint i = start; i < end; i++)
info[i].mask = (info[i].mask & other_masks) | masks[last_form];
foreach_syllable (buffer, start, end)
{ /* Mark a substituted repha as USE(R). */ for (unsignedint i = start; i < end && (info[i].mask & mask); i++) if (_hb_glyph_info_substituted (&info[i]))
{
info[i].use_category() = USE(R); break;
}
} returnfalse;
}
foreach_syllable (buffer, start, end)
{ /* Mark a substituted pref as VPre, as they behave the same way. */ for (unsignedint i = start; i < end; i++) if (_hb_glyph_info_substituted (&info[i]))
{
info[i].use_category() = USE(VPre); break;
}
} returnfalse;
}
/* Move things forward. */ if (info[start].use_category() == USE(R) && end - start > 1)
{ /* Got a repha. Reorder it towards the end, but before the first post-base
* glyph. */ for (unsignedint i = start + 1; i < end; i++)
{ bool is_post_base_glyph = (FLAG64_UNSAFE (info[i].use_category()) & POST_BASE_FLAGS64) ||
is_halant_use (info[i]); if (is_post_base_glyph || i == end - 1)
{ /* If we hit a post-base glyph, move before it; otherwise move to the
* end. Shift things in between backward. */
if (is_post_base_glyph)
i--;
buffer->merge_clusters (start, i + 1);
hb_glyph_info_t t = info[start];
memmove (&info[start], &info[start + 1], (i - start) * sizeof (info[0]));
info[i] = t;
break;
}
}
}
/* Move things back. */ unsignedint j = start; for (unsignedint i = start; i < end; i++)
{
uint32_t flag = FLAG_UNSAFE (info[i].use_category()); if (is_halant_use (info[i]))
{ /* If we hit a halant, move after it; otherwise move to the beginning, and
* shift things in between forward. */
j = i + 1;
} elseif (((flag) & (FLAG (USE(VPre)) | FLAG (USE(VMPre)))) && /* Only move the first component of a MultipleSubst. */
0 == _hb_glyph_info_get_lig_comp (&info[i]) &&
j < i)
{
buffer->merge_clusters (j, i + 1);
hb_glyph_info_t t = info[i];
memmove (&info[j + 1], &info[j], (i - j) * sizeof (info[0]));
info[j] = t;
}
}
}
staticbool
reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{ bool ret = false; if (buffer->message (font, "start reordering USE"))
{ if (hb_syllabic_insert_dotted_circles (font, buffer,
use_broken_cluster,
USE(B),
USE(R)))
ret = true;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.