staticconst hb_ot_map_feature_t
khmer_features[] =
{ /* * Basic features. * These features are applied all at once, before reordering, constrained * to the syllable.
*/
{HB_TAG('p','r','e','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
{HB_TAG('b','l','w','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
{HB_TAG('a','b','v','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
{HB_TAG('p','s','t','f'), F_MANUAL_JOINERS | F_PER_SYLLABLE},
{HB_TAG('c','f','a','r'), F_MANUAL_JOINERS | F_PER_SYLLABLE}, /* * Other features. * These features are applied all at once after clearing syllables.
*/
{HB_TAG('p','r','e','s'), F_GLOBAL_MANUAL_JOINERS},
{HB_TAG('a','b','v','s'), F_GLOBAL_MANUAL_JOINERS},
{HB_TAG('b','l','w','s'), F_GLOBAL_MANUAL_JOINERS},
{HB_TAG('p','s','t','s'), F_GLOBAL_MANUAL_JOINERS},
};
/* * Must be in the same order as the khmer_features array.
*/ enum {
KHMER_PREF,
KHMER_BLWF,
KHMER_ABVF,
KHMER_PSTF,
KHMER_CFAR,
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables_khmer);
map->add_gsub_pause (reorder_khmer);
/* Testing suggests that Uniscribe does NOT pause between basic * features. Test with KhmerUI.ttf and the following three * sequences: * * U+1789,U+17BC * U+1789,U+17D2,U+1789 * U+1789,U+17D2,U+1789,U+17BC * * https://github.com/harfbuzz/harfbuzz/issues/974
*/
map->enable_feature (HB_TAG('l','o','c','l'), F_PER_SYLLABLE);
map->enable_feature (HB_TAG('c','c','m','p'), F_PER_SYLLABLE);
unsignedint i = 0; for (; i < KHMER_BASIC_FEATURES; i++)
map->add_feature (khmer_features[i]);
/* Khmer spec has 'clig' as part of required shaping features: * "Apply feature 'clig' to form ligatures that are desired for
* typographical correctness.", hence in overrides... */
map->enable_feature (HB_TAG('c','l','i','g'));
/* Uniscribe does not apply 'kern' in Khmer. */ if (hb_options ().uniscribe_bug_compatible)
{
map->disable_feature (HB_TAG('k','e','r','n'));
}
unsignedint num_coengs = 0; for (unsignedint i = start + 1; i < end; i++)
{ /* """ * When a COENG + (Cons | IndV) combination are found (and subscript count * is less than two) the character combination is handled according to the * subscript type of the character following the COENG. * * ... * * Subscript Type 2 - The COENG + RO characters are reordered to immediately * before the base glyph. Then the COENG + RO characters are assigned to have * the 'pref' OpenType feature applied to them. * """
*/ if (info[i].khmer_category() == K_Cat(H) && num_coengs <= 2 && i + 1 < end)
{
num_coengs++;
/* Move the Coeng,Ro sequence to the start. */
buffer->merge_clusters (start, i + 2);
hb_glyph_info_t t0 = info[i];
hb_glyph_info_t t1 = info[i + 1];
memmove (&info[start + 2], &info[start], (i - start) * sizeof (info[0]));
info[start] = t0;
info[start + 1] = t1;
/* Mark the subsequent stuff with 'cfar'. Used in Khmer. * Read the feature spec. * This allows distinguishing the following cases with MS Khmer fonts: * U+1784,U+17D2,U+179A,U+17D2,U+1782 * U+1784,U+17D2,U+1782,U+17D2,U+179A
*/ if (khmer_plan->mask_array[KHMER_CFAR]) for (unsignedint j = i + 2; j < end; j++)
info[j].mask |= khmer_plan->mask_array[KHMER_CFAR];
num_coengs = 2; /* Done. */
}
}
/* Reorder left matra piece. */ elseif (info[i].khmer_category() == K_Cat(VPre))
{ /* Move to the start. */
buffer->merge_clusters (start, i + 1);
hb_glyph_info_t t = info[i];
memmove (&info[start + 1], &info[start], (i - start) * sizeof (info[0]));
info[start] = t;
}
}
}
staticvoid
reorder_syllable_khmer (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer, unsignedint start, unsignedint end)
{
khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (buffer->info[start].syllable() & 0x0F); switch (syllable_type)
{ case khmer_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */ case khmer_consonant_syllable:
reorder_consonant_syllable (plan, face, buffer, start, end); break;
case khmer_non_khmer_cluster: break;
}
}
staticbool
reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{ bool ret = false; if (buffer->message (font, "start reordering khmer"))
{ if (hb_syllabic_insert_dotted_circles (font, buffer,
khmer_broken_cluster,
K_Cat(DOTTEDCIRCLE),
(unsigned) -1))
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.