[Indic] Reorder matras

Number of failing shape-complex tests goes from 125 down to 94.

Next: Add Ra handling and it's fair to say we kinda support Indic :).
This commit is contained in:
Behdad Esfahbod 2011-07-30 14:44:30 -04:00
parent 911bf32aca
commit 45d6f29f15
3 changed files with 67 additions and 24 deletions

View File

@ -63,8 +63,6 @@ enum indic_position_t {
POS_ABOVE,
POS_BELOW,
POS_POST,
POS_INHERIT /* For Halant, Nukta, ZWJ, ZWNJ */
};
/* Categories used in IndicSyllabicCategory.txt from UCD */
@ -365,6 +363,14 @@ _hb_ot_shape_complex_setup_masks_indic (hb_ot_map_t *map, hb_buffer_t *buffer)
}
}
static int
compare_indic_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
{
int a = pa->indic_position();
int b = pb->indic_position();
return a < b ? -1 : a == b ? 0 : +1;
}
static void
found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t *mask_array,
@ -454,6 +460,25 @@ found_consonant_syllable (const hb_ot_map_t *map, hb_buffer_t *buffer, hb_mask_t
*/
/* Reorder characters */
for (i = start; i < base; i++)
buffer->info[i].indic_position() = POS_PRE;
buffer->info[base].indic_position() = POS_BASE;
/* Attach ZWJ, ZWNJ, nukta, and halant to previous char to move with them. */
for (i = start + 1; i < end; i++)
if ((FLAG (buffer->info[i].indic_category()) &
(FLAG (OT_ZWNJ) | FLAG (OT_ZWJ) | FLAG (OT_N) | FLAG (OT_H))))
buffer->info[i].indic_position() = buffer->info[i - 1].indic_position();
/* We do bubble-sort, skip malicious clusters attempts */
if (end - start > 20)
return;
/* Sit tight, rock 'n roll! */
hb_bubble_sort (buffer->info + start, end - start, compare_indic_order);
/* Setup masks now */
/* Pre-base */

View File

@ -147,6 +147,15 @@ decompose_multi_char_cluster (hb_ot_shape_context_t *c,
decompose_current_glyph (c, FALSE);
}
static int
compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
{
unsigned int a = pa->combining_class();
unsigned int b = pb->combining_class();
return a < b ? -1 : a == b ? 0 : +1;
}
void
_hb_ot_shape_normalize (hb_ot_shape_context_t *c)
{
@ -216,22 +225,7 @@ _hb_ot_shape_normalize (hb_ot_shape_context_t *c)
continue;
}
unsigned int k = end - i - 1;
do {
hb_glyph_info_t *pinfo = buffer->info + i;
unsigned int new_k = 0;
for (unsigned int j = 0; j < k; j++)
if (pinfo[j].combining_class() > pinfo[j+1].combining_class()) {
hb_glyph_info_t t;
t = pinfo[j];
pinfo[j] = pinfo[j + 1];
pinfo[j + 1] = t;
new_k = j;
}
k = new_k;
} while (k);
hb_bubble_sort (buffer->info + i, end - i, compare_combining_class);
i = end;
}

View File

@ -568,12 +568,9 @@ struct hb_auto_trace_t<0> {
const char *message) {}
};
HB_BEGIN_DECLS
/* Misc */
HB_END_DECLS
/* Pre-mature optimization:
* Checks for lo <= u <= hi but with an optimization if lo and hi
@ -590,13 +587,40 @@ hb_in_range (T u, T lo, T hi)
return lo <= u && u <= hi;
}
HB_BEGIN_DECLS
/* Useful for set-operations on small enums */
/* Useful for set-operations on small enums.
* For example, for testing "x ∈ {x1, x2, x3}" use:
* (FLAG(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3)))
*/
#define FLAG(x) (1<<(x))
template <typename T> inline void
hb_bubble_sort (T *array, unsigned int len, int(*compar)(const T *, const T *))
{
if (unlikely (!len))
return;
unsigned int k = len - 1;
do {
unsigned int new_k = 0;
for (unsigned int j = 0; j < k; j++)
if (compar (&array[j], &array[j+1]) > 0) {
T t;
t = array[j];
array[j] = array[j + 1];
array[j + 1] = t;
new_k = j;
}
k = new_k;
} while (k);
}
HB_BEGIN_DECLS
HB_END_DECLS
#endif /* HB_PRIVATE_HH */