diff --git a/font/font.c b/font/font.c index d512ec98f..3aa415cdc 100644 --- a/font/font.c +++ b/font/font.c @@ -1248,6 +1248,13 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, min_devwidth = combining_glyphs[i]->width; break; + /* TODO: Put dammah and fathah nearer to shadda. */ + case GRUB_UNICODE_COMB_ARABIC_DAMMAH: + case GRUB_UNICODE_COMB_ARABIC_DAMMATAN: + case GRUB_UNICODE_COMB_ARABIC_FATHATAN: + case GRUB_UNICODE_COMB_ARABIC_FATHAH: + case GRUB_UNICODE_COMB_ARABIC_SUKUN: + case GRUB_UNICODE_COMB_ARABIC_SHADDA: case GRUB_UNICODE_COMB_HEBREW_RAFE: case GRUB_UNICODE_STACK_ABOVE: space = combining_glyphs[i]->offset_y @@ -1276,12 +1283,15 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, case GRUB_UNICODE_COMB_HEBREW_PATAH: case GRUB_UNICODE_COMB_HEBREW_QUBUTS: case GRUB_UNICODE_COMB_HEBREW_METEG: + /* TODO: Put kasra and kasratan under shadda. */ + case GRUB_UNICODE_COMB_ARABIC_KASRA: + case GRUB_UNICODE_COMB_ARABIC_KASRATAN: /* I don't know how ypogegrammeni differs from subscript. */ case GRUB_UNICODE_COMB_YPOGEGRAMMENI: case GRUB_UNICODE_STACK_BELOW: space = -(combining_glyphs[i]->offset_y + combining_glyphs[i]->height); - if (space < 0) + if (space <= 0) space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8; case GRUB_UNICODE_STACK_ATTACHED_BELOW: diff --git a/include/grub/unicode.h b/include/grub/unicode.h index a779e2c9c..19837d82e 100644 --- a/include/grub/unicode.h +++ b/include/grub/unicode.h @@ -106,6 +106,14 @@ enum grub_comb_type GRUB_UNICODE_COMB_HEBREW_SHIN_DOT = 24, GRUB_UNICODE_COMB_HEBREW_SIN_DOT = 25, GRUB_UNICODE_COMB_HEBREW_VARIKA = 26, + GRUB_UNICODE_COMB_ARABIC_FATHATAN = 27, + GRUB_UNICODE_COMB_ARABIC_DAMMATAN = 28, + GRUB_UNICODE_COMB_ARABIC_KASRATAN = 29, + GRUB_UNICODE_COMB_ARABIC_FATHAH = 30, + GRUB_UNICODE_COMB_ARABIC_DAMMAH = 31, + GRUB_UNICODE_COMB_ARABIC_KASRA = 32, + GRUB_UNICODE_COMB_ARABIC_SHADDA = 33, + GRUB_UNICODE_COMB_ARABIC_SUKUN = 34, GRUB_UNICODE_STACK_ATTACHED_BELOW = 202, GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214, GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT = 216, diff --git a/normal/charset.c b/normal/charset.c index 6f09fac90..6c68884ae 100644 --- a/normal/charset.c +++ b/normal/charset.c @@ -28,9 +28,8 @@ - Indic languages - non-Semitic shaping (rarely used) - Zl and Zp characters - - Combining characters of types 7, 8, 9, 21, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 84, 91, 103, 107, 118, 122, 129, 130, 132, - 218, 224, 226, 233, 234 + - Combining characters of types 7, 8, 9, 21, 35, 36, 84, 91, 103, 107, + 118, 122, 129, 130, 132, 218, 224, 226, 233, 234 - Private use characters (not really a problem) - Variations (no font support) - Vertical text @@ -40,7 +39,7 @@ - Justification data - Glyph posititioning - Baseline data - TODO: Use form characters of Unicode as last resort Arabic shaping. + Most underline diacritics aren't displayed in gfxterm */ /* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE @@ -550,6 +549,22 @@ grub_unicode_estimate_width (const struct grub_unicode_glyph *c) #endif +static inline int +is_type_after (enum grub_comb_type a, enum grub_comb_type b) +{ + /* Shadda is numerically higher than most of Arabic diacritics but has + to be rendered before them. */ + if (a == GRUB_UNICODE_COMB_ARABIC_SHADDA + && b <= GRUB_UNICODE_COMB_ARABIC_KASRA + && b >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) + return 0; + if (b == GRUB_UNICODE_COMB_ARABIC_SHADDA + && a <= GRUB_UNICODE_COMB_ARABIC_KASRA + && a >= GRUB_UNICODE_COMB_ARABIC_FATHATAN) + return 1; + return a > b; +} + grub_size_t grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, struct grub_unicode_glyph *out) @@ -605,7 +620,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, out->combining = n; for (j = last_comb_pointer; j < out->ncomb; j++) - if (out->combining[j].type > comb_type) + if (is_type_after (out->combining[j].type, comb_type)) break; grub_memmove (out->combining + j + 1, out->combining + j,