Support for 3 more combining marks types

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2010-01-08 00:46:42 +01:00
parent 97ea65d432
commit 82c5d8dcfc
3 changed files with 149 additions and 104 deletions

View file

@ -63,3 +63,4 @@ stamp-h1
stamp-h.in stamp-h.in
symlist.c symlist.c
update-grub_lib update-grub_lib
unidata.c

View file

@ -1163,6 +1163,21 @@ grub_font_construct_glyph (grub_font_t hinted_font,
combtype = get_comb_type (glyph_id->combining[i]); combtype = get_comb_type (glyph_id->combining[i]);
switch (combtype) switch (combtype)
{ {
case GRUB_UNICODE_COMB_OVERLAY:
if (height < combining_glyphs[i]->height)
{
offset_y -= (combining_glyphs[i]->height - height) / 2;
height = combining_glyphs[i]->height;
}
if (width < combining_glyphs[i]->width)
{
offset_x -= (combining_glyphs[i]->width - width) / 2;
width = combining_glyphs[i]->width;
}
if (device_width < combining_glyphs[i]->width)
device_width = combining_glyphs[i]->width;
break;
case GRUB_UNICODE_STACK_ABOVE: case GRUB_UNICODE_STACK_ABOVE:
{ {
grub_int16_t space; grub_int16_t space;
@ -1261,40 +1276,45 @@ grub_font_construct_glyph (grub_font_t hinted_font,
for (i = 0; i < glyph_id->ncomb; i++) for (i = 0; i < glyph_id->ncomb; i++)
{ {
enum grub_comb_type combtype; enum grub_comb_type combtype;
grub_int16_t space = 0;
if (!combining_glyphs[i]) if (!combining_glyphs[i])
continue; continue;
combtype = get_comb_type (glyph_id->combining[i]); combtype = get_comb_type (glyph_id->combining[i]);
switch (combtype) switch (combtype)
{ {
case GRUB_UNICODE_STACK_ABOVE: case GRUB_UNICODE_COMB_OVERLAY:
{ grub_font_blit_glyph (glyph, combining_glyphs[i],
grub_int16_t space; (width - combining_glyphs[i]->width) / 2,
space = combining_glyphs[i]->offset_y (height - combining_glyphs[i]->height) / 2);
- grub_font_get_xheight (combining_glyphs[i]->font); break;
if (space < 0)
space = 1;
curtop += combining_glyphs[i]->height + space; case GRUB_UNICODE_STACK_ABOVE:
grub_font_blit_glyph (glyph, combining_glyphs[i], space = combining_glyphs[i]->offset_y
(width - combining_glyphs[i]->width) / 2, - grub_font_get_xheight (combining_glyphs[i]->font);
(height + offset_y) - curtop); if (space < 0)
} space = 1;
case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
curtop += combining_glyphs[i]->height + space;
grub_font_blit_glyph (glyph, combining_glyphs[i],
(width - combining_glyphs[i]->width) / 2,
(height + offset_y) - curtop);
break; break;
case GRUB_UNICODE_STACK_BELOW: case GRUB_UNICODE_STACK_BELOW:
{ space = -(combining_glyphs[i]->offset_y
grub_int16_t space; + combining_glyphs[i]->height);
space = -(combining_glyphs[i]->offset_y if (space < 0)
+ combining_glyphs[i]->height); space = 1;
if (space < 0)
space = 1;
curbottom -= space; case GRUB_UNICODE_STACK_ATTACHED_BELOW:
grub_font_blit_glyph (glyph, combining_glyphs[i], curbottom -= space;
(width - combining_glyphs[i]->width) / 2, grub_font_blit_glyph (glyph, combining_glyphs[i],
(height + offset_y) - curbottom); (width - combining_glyphs[i]->width) / 2,
curbottom -= combining_glyphs[i]->height; (height + offset_y) - curbottom);
} curbottom -= combining_glyphs[i]->height;
break; break;
default: default:
@ -1525,87 +1545,107 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical,
cur_level = base_level; cur_level = base_level;
cur_override = OVERRIDE_NEUTRAL; cur_override = OVERRIDE_NEUTRAL;
for (i = 0; i < logical_len; i++) {
{ unsigned last_comb_pointer = 0;
/* Variation selectors >= 17 are outside of BMP and SMP. for (i = 0; i < logical_len; i++)
Handle variation selectors first to avoid potentially costly lookups. {
*/ /* Variation selectors >= 17 are outside of BMP and SMP.
if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_1 Handle variation selectors first to avoid potentially costly lookups.
&& logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_16) */
{ if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_1
if (!visual_len) && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_16)
continue;
visual[visual_len - 1].variant
= logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1;
}
if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_17
&& logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_256)
{
if (!visual_len)
continue;
visual[visual_len - 1].variant
= logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17;
continue;
}
type = get_bidi_type (logical[i]);
switch (type)
{
case GRUB_BIDI_TYPE_RLE:
push_stack (cur_override, (cur_level | 1) + 1);
break;
case GRUB_BIDI_TYPE_RLO:
push_stack (OVERRIDE_R, (cur_level | 1) + 1);
break;
case GRUB_BIDI_TYPE_LRE:
push_stack (cur_override, (cur_level & ~1) + 2);
break;
case GRUB_BIDI_TYPE_LRO:
push_stack (OVERRIDE_L, (cur_level & ~1) + 2);
break;
case GRUB_BIDI_TYPE_PDF:
pop_stack ();
break;
case GRUB_BIDI_TYPE_BN:
break;
default:
{ {
enum grub_comb_type comb_type; if (!visual_len)
comb_type = get_comb_type (logical[i]); continue;
if (comb_type) visual[visual_len - 1].variant
{ = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1;
grub_uint32_t *n;
if (!visual_len)
break;
n = grub_realloc (visual[visual_len - 1].combining,
sizeof (grub_uint32_t)
* (visual[visual_len - 1].ncomb + 1));
if (!n)
{
grub_errno = GRUB_ERR_NONE;
break;
}
visual[visual_len - 1].combining = n;
visual[visual_len - 1].combining[visual[visual_len - 1].ncomb]
= logical[i];
visual[visual_len - 1].ncomb++;
break;
}
levels[visual_len] = cur_level;
if (cur_override != OVERRIDE_NEUTRAL)
resolved_types[visual_len] =
(cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L : GRUB_BIDI_TYPE_R;
else
resolved_types[visual_len] = type;
visual[visual_len].base = logical[i];
visual[visual_len].variant = 0;
visual[visual_len].attributes = 0;
visual[visual_len].ncomb = 0;
visual[visual_len].combining = NULL;
visual_len++;
} }
} if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_17
} && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_256)
{
if (!visual_len)
continue;
visual[visual_len - 1].variant
= logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17;
continue;
}
type = get_bidi_type (logical[i]);
switch (type)
{
case GRUB_BIDI_TYPE_RLE:
push_stack (cur_override, (cur_level | 1) + 1);
break;
case GRUB_BIDI_TYPE_RLO:
push_stack (OVERRIDE_R, (cur_level | 1) + 1);
break;
case GRUB_BIDI_TYPE_LRE:
push_stack (cur_override, (cur_level & ~1) + 2);
break;
case GRUB_BIDI_TYPE_LRO:
push_stack (OVERRIDE_L, (cur_level & ~1) + 2);
break;
case GRUB_BIDI_TYPE_PDF:
pop_stack ();
break;
case GRUB_BIDI_TYPE_BN:
break;
default:
{
enum grub_comb_type comb_type;
comb_type = get_comb_type (logical[i]);
if (comb_type)
{
grub_uint32_t *n;
unsigned j;
if (!visual_len)
break;
if (comb_type == GRUB_UNICODE_COMB_MC
|| comb_type == GRUB_UNICODE_COMB_ME
|| comb_type == GRUB_UNICODE_COMB_MN)
last_comb_pointer = visual[visual_len - 1].ncomb;
n = grub_realloc (visual[visual_len - 1].combining,
sizeof (grub_uint32_t)
* (visual[visual_len - 1].ncomb + 1));
if (!n)
{
grub_errno = GRUB_ERR_NONE;
break;
}
for (j = last_comb_pointer;
j < visual[visual_len - 1].ncomb; j++)
if (get_comb_type (visual[visual_len - 1].combining[j])
> comb_type)
break;
grub_memmove (visual[visual_len - 1].combining + j + 1,
visual[visual_len - 1].combining + j,
(visual[visual_len - 1].ncomb - j)
* sizeof (visual[visual_len - 1].combining[0]));
visual[visual_len - 1].combining = n;
visual[visual_len - 1].combining[j] = logical[i];
visual[visual_len - 1].ncomb++;
break;
}
last_comb_pointer = 0;
levels[visual_len] = cur_level;
if (cur_override != OVERRIDE_NEUTRAL)
resolved_types[visual_len] =
(cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L
: GRUB_BIDI_TYPE_R;
else
resolved_types[visual_len] = type;
visual[visual_len].base = logical[i];
visual[visual_len].variant = 0;
visual[visual_len].attributes = 0;
visual[visual_len].ncomb = 0;
visual[visual_len].combining = NULL;
visual_len++;
}
}
}
}
for (run_start = 0; run_start < visual_len; run_start = run_end) for (run_start = 0; run_start < visual_len; run_start = run_end)
{ {
@ -1781,6 +1821,7 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical,
if (levels[i] < min_odd_level && (levels[i] & 1)) if (levels[i] < min_odd_level && (levels[i] & 1))
min_odd_level = levels[i]; min_odd_level = levels[i];
} }
/* FIXME: can be optimized. */
for (j = max_level; j >= min_odd_level; j--) for (j = max_level; j >= min_odd_level; j--)
{ {
unsigned in = 0; unsigned in = 0;

View file

@ -55,6 +55,9 @@ enum grub_bidi_type
enum grub_comb_type enum grub_comb_type
{ {
GRUB_UNICODE_COMB_OVERLAY = 1,
GRUB_UNICODE_STACK_ATTACHED_BELOW = 202,
GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214,
GRUB_UNICODE_STACK_BELOW = 220, GRUB_UNICODE_STACK_BELOW = 220,
GRUB_UNICODE_STACK_ABOVE = 230, GRUB_UNICODE_STACK_ABOVE = 230,
/* If combining nature is indicated only by class and /* If combining nature is indicated only by class and