Implement Arabic fallback shaping mandatory ligatures
This commit is contained in:
parent
b7d04eb606
commit
939c010211
|
@ -133,11 +133,7 @@ def print_shaping_table(f):
|
||||||
print "#define SHAPING_TABLE_LAST 0x%04X" % max_u
|
print "#define SHAPING_TABLE_LAST 0x%04X" % max_u
|
||||||
print
|
print
|
||||||
|
|
||||||
print
|
ligas = {}
|
||||||
print "static const uint16_t ligature_table[][3] ="
|
|
||||||
print "{"
|
|
||||||
|
|
||||||
ligas = []
|
|
||||||
for pair in ligatures.keys ():
|
for pair in ligatures.keys ():
|
||||||
for shape in ligatures[pair]:
|
for shape in ligatures[pair]:
|
||||||
c = ligatures[pair][shape]
|
c = ligatures[pair][shape]
|
||||||
|
@ -147,11 +143,27 @@ def print_shaping_table(f):
|
||||||
liga = (shapes[pair[0]]['medial'], shapes[pair[1]]['final'])
|
liga = (shapes[pair[0]]['medial'], shapes[pair[1]]['final'])
|
||||||
else:
|
else:
|
||||||
raise Exception ("Unexpected shape", shape)
|
raise Exception ("Unexpected shape", shape)
|
||||||
ligas.append (liga + (c,))
|
if liga[0] not in ligas:
|
||||||
ligas.sort ()
|
ligas[liga[0]] = []
|
||||||
for liga in ligas:
|
ligas[liga[0]].append ((liga[1], c))
|
||||||
value = ', '.join ("0x%04X" % c for c in liga)
|
max_i = max (len (ligas[l]) for l in ligas)
|
||||||
print " {%s}, /* U+%04X %s */" % (value, liga[2], names[liga[2]])
|
print
|
||||||
|
print "static const struct {"
|
||||||
|
print " uint16_t first;"
|
||||||
|
print " struct {"
|
||||||
|
print " uint16_t second;"
|
||||||
|
print " uint16_t ligature;"
|
||||||
|
print " } ligatures[%d];" % max_i
|
||||||
|
print "} ligature_table[] ="
|
||||||
|
print "{"
|
||||||
|
keys = ligas.keys ()
|
||||||
|
keys.sort ()
|
||||||
|
for first in keys:
|
||||||
|
|
||||||
|
print " { 0x%04X, {" % (first)
|
||||||
|
for liga in ligas[first]:
|
||||||
|
print " { 0x%04X, 0x%04X }, /* %s */" % (liga[0], liga[1], names[liga[1]])
|
||||||
|
print " }},"
|
||||||
|
|
||||||
print "};"
|
print "};"
|
||||||
print
|
print
|
||||||
|
|
|
@ -914,16 +914,26 @@ static const uint16_t shaping_table[][4] =
|
||||||
#define SHAPING_TABLE_LAST 0x06D3
|
#define SHAPING_TABLE_LAST 0x06D3
|
||||||
|
|
||||||
|
|
||||||
static const uint16_t ligature_table[][3] =
|
static const struct {
|
||||||
|
uint16_t first;
|
||||||
|
struct {
|
||||||
|
uint16_t second;
|
||||||
|
uint16_t ligature;
|
||||||
|
} ligatures[4];
|
||||||
|
} ligature_table[] =
|
||||||
{
|
{
|
||||||
{0xFEDF, 0xFE82, 0xFEF5}, /* U+FEF5 ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
|
{ 0xFEDF, {
|
||||||
{0xFEDF, 0xFE84, 0xFEF7}, /* U+FEF7 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
|
{ 0xFE88, 0xFEF9 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
|
||||||
{0xFEDF, 0xFE88, 0xFEF9}, /* U+FEF9 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM */
|
{ 0xFE82, 0xFEF5 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM */
|
||||||
{0xFEDF, 0xFE8E, 0xFEFB}, /* U+FEFB ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
|
{ 0xFE8E, 0xFEFB }, /* ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM */
|
||||||
{0xFEE0, 0xFE82, 0xFEF6}, /* U+FEF6 ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
|
{ 0xFE84, 0xFEF7 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM */
|
||||||
{0xFEE0, 0xFE84, 0xFEF8}, /* U+FEF8 ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
|
}},
|
||||||
{0xFEE0, 0xFE88, 0xFEFA}, /* U+FEFA ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
|
{ 0xFEE0, {
|
||||||
{0xFEE0, 0xFE8E, 0xFEFC}, /* U+FEFC ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
|
{ 0xFE88, 0xFEFA }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM */
|
||||||
|
{ 0xFE82, 0xFEF6 }, /* ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM */
|
||||||
|
{ 0xFE8E, 0xFEFC }, /* ARABIC LIGATURE LAM WITH ALEF FINAL FORM */
|
||||||
|
{ 0xFE84, 0xFEF8 }, /* ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM */
|
||||||
|
}},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,16 @@ static hb_codepoint_t get_arabic_shape (hb_codepoint_t u, unsigned int shape)
|
||||||
return u;
|
return u;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t get_ligature (hb_codepoint_t first, hb_codepoint_t second)
|
||||||
|
{
|
||||||
|
if (unlikely (!second)) return 0;
|
||||||
|
for (unsigned i = 0; i < ARRAY_LENGTH (ligature_table); i++)
|
||||||
|
if (ligature_table[i].first == first)
|
||||||
|
for (unsigned j = 0; j < ARRAY_LENGTH (ligature_table[i].ligatures); j++)
|
||||||
|
if (ligature_table[i].ligatures[j].second == second)
|
||||||
|
return ligature_table[i].ligatures[j].ligature;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static const hb_tag_t arabic_syriac_features[] =
|
static const hb_tag_t arabic_syriac_features[] =
|
||||||
{
|
{
|
||||||
|
@ -198,8 +208,29 @@ static void
|
||||||
arabic_fallback_shape (hb_buffer_t *buffer)
|
arabic_fallback_shape (hb_buffer_t *buffer)
|
||||||
{
|
{
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
|
|
||||||
|
/* Shape to presentation forms */
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
buffer->info[i].codepoint = get_arabic_shape (buffer->info[i].codepoint, buffer->info[i].arabic_shaping_action());
|
buffer->info[i].codepoint = get_arabic_shape (buffer->info[i].codepoint, buffer->info[i].arabic_shaping_action());
|
||||||
|
|
||||||
|
/* Mandatory ligatures */
|
||||||
|
buffer->clear_output ();
|
||||||
|
for (buffer->idx = 0; buffer->idx + 1 < count;) {
|
||||||
|
uint16_t ligature = get_ligature (buffer->info[buffer->idx].codepoint,
|
||||||
|
buffer->info[buffer->idx + 1].codepoint);
|
||||||
|
if (likely (!ligature)) {
|
||||||
|
buffer->next_glyph ();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer->replace_glyphs (2, 1, &ligature);
|
||||||
|
|
||||||
|
/* Technically speaking we can skip marks and stuff, like the GSUB path does.
|
||||||
|
* But who cares, we're in fallback! */
|
||||||
|
}
|
||||||
|
for (; buffer->idx < count;)
|
||||||
|
buffer->next_glyph ();
|
||||||
|
buffer->swap_buffers ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -132,7 +132,7 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map, hb_buffer_t *buffer)
|
||||||
unsigned int count = buffer->len;
|
unsigned int count = buffer->len;
|
||||||
for (buffer->idx = 0; buffer->idx < count;)
|
for (buffer->idx = 0; buffer->idx < count;)
|
||||||
{
|
{
|
||||||
if (!IS_SARA_AM (buffer->info[buffer->idx].codepoint)) {
|
if (likely (!IS_SARA_AM (buffer->info[buffer->idx].codepoint))) {
|
||||||
buffer->next_glyph ();
|
buffer->next_glyph ();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ _hb_ot_shape_complex_setup_masks_thai (hb_ot_map_t *map, hb_buffer_t *buffer)
|
||||||
uint16_t decomposed[2] = {NIKHAHIT_FROM_SARA_AM (buffer->info[buffer->idx].codepoint),
|
uint16_t decomposed[2] = {NIKHAHIT_FROM_SARA_AM (buffer->info[buffer->idx].codepoint),
|
||||||
SARA_AA_FROM_SARA_AM (buffer->info[buffer->idx].codepoint)};
|
SARA_AA_FROM_SARA_AM (buffer->info[buffer->idx].codepoint)};
|
||||||
buffer->replace_glyphs (1, 2, decomposed);
|
buffer->replace_glyphs (1, 2, decomposed);
|
||||||
if (buffer->in_error)
|
if (unlikely (buffer->in_error))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Ok, let's see... */
|
/* Ok, let's see... */
|
||||||
|
|
Loading…
Reference in New Issue