inline hb_mask_t get_global_mask (void) const { return global_mask; }
- inline hb_mask_t get_mask (hb_tag_t tag, unsigned int *shift = NULL) const {
- const feature_map_t *map = features.bsearch (&tag);
+ inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = NULL) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
if (shift) *shift = map ? map->shift : 0;
return map ? map->mask : 0;
}
- inline hb_mask_t get_1_mask (hb_tag_t tag) const {
- const feature_map_t *map = features.bsearch (&tag);
+ inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
return map ? map->_1_mask : 0;
}
+ inline hb_mask_t get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
+ const feature_map_t *map = features.bsearch (&feature_tag);
+ return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
+ }
+
inline hb_tag_t get_chosen_script (unsigned int table_index) const
{ return chosen_script[table_index]; }
return a < b ? -1 : a == b ? 0 : +1;
}
-static indic_position_t
-consonant_position (hb_codepoint_t u)
+static bool
+would_substitute (hb_codepoint_t *glyphs, unsigned int glyphs_count,
+ hb_tag_t feature_tag, hb_ot_map_t *map, hb_face_t *face)
{
- consonant_position_t *record;
-
- /* Khmer does not have pre-base half forms. */
- if (0x1780 <= u && u <= 0x17FF)
- return POS_BELOW_C;
-
- record = (consonant_position_t *) bsearch (&u, consonant_positions,
- ARRAY_LENGTH (consonant_positions),
- sizeof (consonant_positions[0]),
- compare_codepoint);
+ unsigned int lookup_indices[32];
+ unsigned int offset, len;
+
+ offset = 0;
+ do {
+ len = ARRAY_LENGTH (lookup_indices);
+ hb_ot_layout_feature_get_lookup_indexes (face, HB_OT_TAG_GSUB,
+ map->get_feature_index (0/*GSUB*/, feature_tag),
+ offset,
+ &len,
+ lookup_indices);
+
+ for (unsigned int i = 0; i < len; i++)
+ if (hb_ot_layout_would_substitute_lookup (face, glyphs, glyphs_count, lookup_indices[i]))
+ return true;
+
+ offset += len;
+ } while (len == ARRAY_LENGTH (lookup_indices));
+
+ return false;
+}
- return record ? record->position : POS_BASE_C;
+static indic_position_t
+consonant_position (hb_codepoint_t u, hb_ot_map_t *map, hb_font_t *font)
+{
+ hb_codepoint_t virama = (u & ~0x007F) | 0x004D;
+ if ((u & ~0x007F) == 0x0D80) virama = 0x0DCA; /* Sinahla */
+ if ((u & ~0x007F) == 0x1780) virama = 0x17D2; /* Khmer */
+ hb_codepoint_t glyphs[2];
+
+ hb_font_get_glyph (font, virama, 0, &glyphs[0]);
+ hb_font_get_glyph (font, u, 0, &glyphs[1]);
+
+ hb_face_t *face = hb_font_get_face (font);
+ if (would_substitute (glyphs, ARRAY_LENGTH (glyphs), HB_TAG('p','r','e','f'), map, face)) return POS_BELOW_C;
+ if (would_substitute (glyphs, ARRAY_LENGTH (glyphs), HB_TAG('b','l','w','f'), map, face)) return POS_BELOW_C;
+ if (would_substitute (glyphs, ARRAY_LENGTH (glyphs), HB_TAG('p','s','t','f'), map, face)) return POS_POST_C;
+ return POS_BASE_C;
}
#define MATRA_POS_LEFT(u) POS_PRE_M
}
static inline void
-set_indic_properties (hb_glyph_info_t &info)
+set_indic_properties (hb_glyph_info_t &info, hb_ot_map_t *map, hb_font_t *font)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = get_indic_categories (u);
if ((FLAG (cat) & CONSONANT_FLAGS))
{
- pos = consonant_position (u);
+ pos = consonant_position (u, map, font);
if (is_ra (u))
cat = OT_Ra;
}
void
-_hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map HB_UNUSED,
+_hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map,
hb_buffer_t *buffer,
- hb_font_t *font HB_UNUSED)
+ hb_font_t *font)
{
HB_BUFFER_ALLOCATE_VAR (buffer, indic_category);
HB_BUFFER_ALLOCATE_VAR (buffer, indic_position);
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
- set_indic_properties (buffer->info[i]);
+ set_indic_properties (buffer->info[i], map, font);
}
static int