[amalgam] Fix most duplicate-id instances in Indic-like shapers

Part of https://github.com/harfbuzz/harfbuzz/issues/1809
This commit is contained in:
Behdad Esfahbod 2019-07-02 14:42:45 -07:00
parent c073233f45
commit d115a9e022
14 changed files with 231 additions and 303 deletions

View File

@ -168,6 +168,17 @@ _hb_next_syllable (hb_buffer_t *buffer, unsigned int start)
return start;
}
static inline void
_hb_clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
/* unicode_props */
@ -551,6 +562,17 @@ _hb_glyph_info_clear_substituted (hb_glyph_info_t *info)
info->glyph_props() &= ~(HB_OT_LAYOUT_GLYPH_PROPS_SUBSTITUTED);
}
static inline void
_hb_clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
_hb_glyph_info_clear_substituted (&info[i]);
}
/* Allocation / deallocation. */

View File

@ -395,13 +395,13 @@ static const int indic_syllable_machine_en_main = 39;
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_indic (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;
@ -569,4 +569,6 @@ _again:
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */

View File

@ -96,13 +96,13 @@ main := |*
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | indic_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_indic (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;
@ -121,4 +121,6 @@ find_syllables (hb_buffer_t *buffer)
}%%
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_MACHINE_HH */

View File

@ -172,21 +172,17 @@ enum {
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
setup_syllables_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
final_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
collect_features_indic (hb_ot_shape_planner_t *plan)
@ -194,7 +190,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_gsub_pause (setup_syllables_indic);
map->enable_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
@ -203,14 +199,14 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
map->add_gsub_pause (initial_reordering_indic);
for (; i < INDIC_BASIC_FEATURES; i++) {
map->add_feature (indic_features[i]);
map->add_gsub_pause (nullptr);
}
map->add_gsub_pause (final_reordering);
map->add_gsub_pause (final_reordering_indic);
for (; i < INDIC_NUM_FEATURES; i++)
map->add_feature (indic_features[i]);
@ -218,7 +214,7 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
map->enable_feature (HB_TAG('c','a','l','t'));
map->enable_feature (HB_TAG('c','l','i','g'));
map->add_gsub_pause (clear_syllables);
map->add_gsub_pause (_hb_clear_syllables);
}
static void
@ -228,32 +224,6 @@ override_features_indic (hb_ot_shape_planner_t *plan)
}
struct would_substitute_feature_t
{
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
struct indic_shape_plan_t
{
bool load_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
@ -285,10 +255,10 @@ struct indic_shape_plan_t
#endif
mutable hb_atomic_int_t virama_glyph;
would_substitute_feature_t rphf;
would_substitute_feature_t pref;
would_substitute_feature_t blwf;
would_substitute_feature_t pstf;
hb_indic_would_substitute_feature_t rphf;
hb_indic_would_substitute_feature_t pref;
hb_indic_would_substitute_feature_t blwf;
hb_indic_would_substitute_feature_t pstf;
hb_mask_t mask_array[INDIC_NUM_FEATURES];
};
@ -371,13 +341,13 @@ consonant_position_from_face (const indic_shape_plan_t *indic_plan,
}
enum syllable_type_t {
consonant_syllable,
vowel_syllable,
standalone_cluster,
symbol_cluster,
broken_cluster,
non_indic_cluster,
enum indic_syllable_type_t {
indic_consonant_syllable,
indic_vowel_syllable,
indic_standalone_cluster,
indic_symbol_cluster,
indic_broken_cluster,
indic_non_indic_cluster,
};
#include "hb-ot-shape-complex-indic-machine.hh"
@ -401,11 +371,11 @@ setup_masks_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
setup_syllables_indic (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
find_syllables_indic (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
}
@ -950,21 +920,21 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
indic_syllable_type_t syllable_type = (indic_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type)
{
case vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */
case consonant_syllable:
case indic_vowel_syllable: /* We made the vowels look like consonants. So let's call the consonant logic! */
case indic_consonant_syllable:
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
break;
case broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
case standalone_cluster:
case indic_broken_cluster: /* We already inserted dotted-circles, so just call the standalone_cluster. */
case indic_standalone_cluster:
initial_reordering_standalone_cluster (plan, face, buffer, start, end);
break;
case symbol_cluster:
case non_indic_cluster:
case indic_symbol_cluster:
case indic_non_indic_cluster:
break;
}
}
@ -983,7 +953,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
if ((info[i].syllable() & 0x0F) == indic_broken_cluster)
{
has_broken_syllables = true;
break;
@ -1008,8 +978,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
indic_syllable_type_t syllable_type = (indic_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == indic_broken_cluster))
{
last_syllable = syllable;
@ -1033,9 +1003,9 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
initial_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
update_consonant_positions (plan, font, buffer);
insert_dotted_circles (plan, font, buffer);
@ -1508,9 +1478,9 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
final_reordering_indic (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
if (unlikely (!count)) return;
@ -1523,18 +1493,6 @@ final_reordering (const hb_ot_shape_plan_t *plan,
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
static void
preprocess_text_indic (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,

View File

@ -398,5 +398,31 @@ set_indic_properties (hb_glyph_info_t &info)
info.indic_position() = pos;
}
struct hb_indic_would_substitute_feature_t
{
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
#endif /* HB_OT_SHAPE_COMPLEX_INDIC_HH */

View File

@ -226,13 +226,13 @@ static const int khmer_syllable_machine_en_main = 20;
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_khmer (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
@ -367,4 +367,6 @@ _again:
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */

View File

@ -83,13 +83,13 @@ main := |*
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | khmer_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_khmer (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
@ -108,4 +108,6 @@ find_syllables (hb_buffer_t *buffer)
}%%
}
#undef found_syllable
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */

View File

@ -89,17 +89,13 @@ enum {
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
setup_syllables_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
collect_features_khmer (hb_ot_shape_planner_t *plan)
@ -107,8 +103,8 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_gsub_pause (reorder);
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
@ -127,7 +123,7 @@ collect_features_khmer (hb_ot_shape_planner_t *plan)
for (; i < KHMER_BASIC_FEATURES; i++)
map->add_feature (khmer_features[i]);
map->add_gsub_pause (clear_syllables);
map->add_gsub_pause (_hb_clear_syllables);
for (; i < KHMER_NUM_FEATURES; i++)
map->add_feature (khmer_features[i]);
@ -153,32 +149,6 @@ override_features_khmer (hb_ot_shape_planner_t *plan)
}
struct would_substitute_feature_t
{
void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
struct khmer_shape_plan_t
{
bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
@ -202,7 +172,7 @@ struct khmer_shape_plan_t
mutable hb_codepoint_t virama_glyph;
would_substitute_feature_t pref;
hb_indic_would_substitute_feature_t pref;
hb_mask_t mask_array[KHMER_NUM_FEATURES];
};
@ -232,10 +202,10 @@ data_destroy_khmer (void *data)
}
enum syllable_type_t {
consonant_syllable,
broken_cluster,
non_khmer_cluster,
enum khmer_syllable_type_t {
khmer_consonant_syllable,
khmer_broken_cluster,
khmer_non_khmer_cluster,
};
#include "hb-ot-shape-complex-khmer-machine.hh"
@ -257,11 +227,11 @@ setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
setup_syllables_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
find_syllables_khmer (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
}
@ -351,15 +321,15 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type)
{
case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
case consonant_syllable:
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 non_khmer_cluster:
case khmer_non_khmer_cluster:
break;
}
}
@ -378,7 +348,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
if ((info[i].syllable() & 0x0F) == khmer_broken_cluster)
{
has_broken_syllables = true;
break;
@ -403,8 +373,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
khmer_syllable_type_t syllable_type = (khmer_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == khmer_broken_cluster))
{
last_syllable = syllable;
@ -428,9 +398,9 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
reorder_khmer (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles (plan, font, buffer);
@ -440,17 +410,6 @@ reorder (const hb_ot_shape_plan_t *plan,
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
static bool
decompose_khmer (const hb_ot_shape_normalize_context_t *c,

View File

@ -304,13 +304,13 @@ static const int myanmar_syllable_machine_en_main = 0;
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_myanmar (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;

View File

@ -97,13 +97,13 @@ main := |*
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | myanmar_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_myanmar (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;

View File

@ -80,15 +80,11 @@ positioning_features[] =
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
reorder_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
@ -98,7 +94,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_gsub_pause (setup_syllables_myanmar);
map->enable_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
@ -106,7 +102,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
map->enable_feature (HB_TAG('c','c','m','p'));
map->add_gsub_pause (reorder);
map->add_gsub_pause (reorder_myanmar);
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
{
@ -114,7 +110,7 @@ collect_features_myanmar (hb_ot_shape_planner_t *plan)
map->add_gsub_pause (nullptr);
}
map->add_gsub_pause (clear_syllables);
map->add_gsub_pause (_hb_clear_syllables);
for (unsigned int i = 0; i < ARRAY_LENGTH (other_features); i++)
map->enable_feature (other_features[i], F_MANUAL_ZWJ);
@ -130,11 +126,11 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
}
enum syllable_type_t {
consonant_syllable,
punctuation_cluster,
broken_cluster,
non_myanmar_cluster,
enum myanmar_syllable_type_t {
myanmar_consonant_syllable,
myanmar_punctuation_cluster,
myanmar_broken_cluster,
myanmar_non_myanmar_cluster,
};
#include "hb-ot-shape-complex-myanmar-machine.hh"
@ -158,11 +154,11 @@ setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
setup_syllables_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
find_syllables_myanmar (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
}
@ -283,16 +279,16 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type) {
case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
case consonant_syllable:
case myanmar_broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
case myanmar_consonant_syllable:
initial_reordering_consonant_syllable (buffer, start, end);
break;
case punctuation_cluster:
case non_myanmar_cluster:
case myanmar_punctuation_cluster:
case myanmar_non_myanmar_cluster:
break;
}
}
@ -311,7 +307,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
if ((info[i].syllable() & 0x0F) == myanmar_broken_cluster)
{
has_broken_syllables = true;
break;
@ -336,8 +332,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
myanmar_syllable_type_t syllable_type = (myanmar_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == myanmar_broken_cluster))
{
last_syllable = syllable;
@ -355,9 +351,9 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
reorder_myanmar (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles (plan, font, buffer);
@ -368,17 +364,6 @@ reorder (const hb_ot_shape_plan_t *plan,
HB_BUFFER_DEALLOCATE_VAR (buffer, myanmar_position);
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
{

View File

@ -380,13 +380,13 @@ static const int use_syllable_machine_en_main = 5;
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_use (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;

View File

@ -165,13 +165,13 @@ main := |*
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
info[i].syllable() = (syllable_serial << 4) | use_##syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
find_syllables_use (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act;
int cs;

View File

@ -106,29 +106,21 @@ positioning_features[] =
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
setup_syllables_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
record_rphf_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_substitution_flags (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
record_rphf (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
record_pref (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
record_pref_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
collect_features_use (hb_ot_shape_planner_t *plan)
@ -136,7 +128,7 @@ collect_features_use (hb_ot_shape_planner_t *plan)
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_gsub_pause (setup_syllables_use);
/* "Default glyph pre-processing group" */
map->enable_feature (HB_TAG('l','o','c','l'));
@ -145,19 +137,19 @@ collect_features_use (hb_ot_shape_planner_t *plan)
map->enable_feature (HB_TAG('a','k','h','n'), F_MANUAL_ZWJ);
/* "Reordering group" */
map->add_gsub_pause (clear_substitution_flags);
map->add_gsub_pause (_hb_clear_substitution_flags);
map->add_feature (HB_TAG('r','p','h','f'), F_MANUAL_ZWJ);
map->add_gsub_pause (record_rphf);
map->add_gsub_pause (clear_substitution_flags);
map->add_gsub_pause (record_rphf_use);
map->add_gsub_pause (_hb_clear_substitution_flags);
map->enable_feature (HB_TAG('p','r','e','f'), F_MANUAL_ZWJ);
map->add_gsub_pause (record_pref);
map->add_gsub_pause (record_pref_use);
/* "Orthographic unit shaping group" */
for (unsigned int i = 0; i < ARRAY_LENGTH (basic_features); i++)
map->enable_feature (basic_features[i], F_MANUAL_ZWJ);
map->add_gsub_pause (reorder);
map->add_gsub_pause (clear_syllables);
map->add_gsub_pause (reorder_use);
map->add_gsub_pause (_hb_clear_syllables);
/* "Topographical features" */
for (unsigned int i = 0; i < ARRAY_LENGTH (arabic_features); i++)
@ -247,16 +239,16 @@ data_destroy_use (void *data)
free (data);
}
enum syllable_type_t {
independent_cluster,
virama_terminated_cluster,
sakot_terminated_cluster,
standard_cluster,
number_joiner_terminated_cluster,
numeral_cluster,
symbol_cluster,
broken_cluster,
non_cluster,
enum use_syllable_type_t {
use_independent_cluster,
use_virama_terminated_cluster,
use_sakot_terminated_cluster,
use_standard_cluster,
use_number_joiner_terminated_cluster,
use_numeral_cluster,
use_symbol_cluster,
use_broken_cluster,
use_non_cluster,
};
#include "hb-ot-shape-complex-use-machine.hh"
@ -331,22 +323,22 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
hb_glyph_info_t *info = buffer->info;
foreach_syllable (buffer, start, end)
{
syllable_type_t syllable_type = (syllable_type_t) (info[start].syllable() & 0x0F);
use_syllable_type_t syllable_type = (use_syllable_type_t) (info[start].syllable() & 0x0F);
switch (syllable_type)
{
case independent_cluster:
case symbol_cluster:
case non_cluster:
case use_independent_cluster:
case use_symbol_cluster:
case use_non_cluster:
/* These don't join. Nothing to do. */
last_form = _NONE;
break;
case virama_terminated_cluster:
case sakot_terminated_cluster:
case standard_cluster:
case number_joiner_terminated_cluster:
case numeral_cluster:
case broken_cluster:
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_broken_cluster:
bool join = last_form == FINA || last_form == ISOL;
@ -371,11 +363,11 @@ setup_topographical_masks (const hb_ot_shape_plan_t *plan,
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
setup_syllables_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
find_syllables_use (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
setup_rphf_mask (plan, buffer);
@ -383,20 +375,9 @@ setup_syllables (const hb_ot_shape_plan_t *plan,
}
static void
clear_substitution_flags (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
_hb_glyph_info_clear_substituted (&info[i]);
}
static void
record_rphf (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
record_rphf_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
const use_shape_plan_t *use_plan = (const use_shape_plan_t *) plan->data;
@ -417,9 +398,9 @@ record_rphf (const hb_ot_shape_plan_t *plan,
}
static void
record_pref (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
record_pref_use (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
@ -443,15 +424,15 @@ is_halant (const hb_glyph_info_t &info)
}
static void
reorder_syllable (hb_buffer_t *buffer, unsigned int start, unsigned int end)
reorder_syllable_use (hb_buffer_t *buffer, unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
use_syllable_type_t syllable_type = (use_syllable_type_t) (buffer->info[start].syllable() & 0x0F);
/* Only a few syllable types need reordering. */
if (unlikely (!(FLAG_UNSAFE (syllable_type) &
(FLAG (virama_terminated_cluster) |
FLAG (sakot_terminated_cluster) |
FLAG (standard_cluster) |
FLAG (broken_cluster) |
(FLAG (use_virama_terminated_cluster) |
FLAG (use_sakot_terminated_cluster) |
FLAG (use_standard_cluster) |
FLAG (use_broken_cluster) |
0))))
return;
@ -539,7 +520,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
if ((info[i].syllable() & 0x0F) == use_broken_cluster)
{
has_broken_syllables = true;
break;
@ -559,8 +540,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
while (buffer->idx < buffer->len && buffer->successful)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
use_syllable_type_t syllable_type = (use_syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == use_broken_cluster))
{
last_syllable = syllable;
@ -584,29 +565,18 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
}
static void
reorder (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
reorder_use (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles (plan, font, buffer);
foreach_syllable (buffer, start, end)
reorder_syllable (buffer, start, end);
reorder_syllable_use (buffer, start, end);
HB_BUFFER_DEALLOCATE_VAR (buffer, use_category);
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
static void
preprocess_text_use (const hb_ot_shape_plan_t *plan,