Agglomerate more mallocs to speed-up gfxterm.

This commit is contained in:
Vladimir 'phcoder' Serbinenko 2013-05-04 22:23:23 +02:00
parent 22b06e9685
commit 85002bf34a
15 changed files with 254 additions and 187 deletions

View file

@ -1,3 +1,7 @@
2013-05-04 Vladimir Serbinenko <phcoder@gmail.com>
Agglomerate more mallocs to speed-up gfxterm.
2013-05-04 Vladimir Serbinenko <phcoder@gmail.com> 2013-05-04 Vladimir Serbinenko <phcoder@gmail.com>
Speed-up gfxterm by slightly agglomerating mallocs. Speed-up gfxterm by slightly agglomerating mallocs.

View file

@ -1064,6 +1064,7 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
return best_glyph; return best_glyph;
} }
#if 0
static struct grub_font_glyph * static struct grub_font_glyph *
grub_font_dup_glyph (struct grub_font_glyph *glyph) grub_font_dup_glyph (struct grub_font_glyph *glyph)
{ {
@ -1075,6 +1076,7 @@ grub_font_dup_glyph (struct grub_font_glyph *glyph)
+ (glyph->width * glyph->height + 7) / 8); + (glyph->width * glyph->height + 7) / 8);
return ret; return ret;
} }
#endif
/* FIXME: suboptimal. */ /* FIXME: suboptimal. */
static void static void
@ -1202,6 +1204,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
signed above_leftx, above_lefty; signed above_leftx, above_lefty;
signed below_rightx, below_righty; signed below_rightx, below_righty;
signed min_devwidth = 0; signed min_devwidth = 0;
const struct grub_unicode_combining *comb;
if (glyph) if (glyph)
glyph->device_width = main_glyph->device_width; glyph->device_width = main_glyph->device_width;
@ -1222,6 +1225,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
below_rightx = ctx.bounds.x + ctx.bounds.width; below_rightx = ctx.bounds.x + ctx.bounds.width;
below_righty = ctx.bounds.y; below_righty = ctx.bounds.y;
comb = grub_unicode_get_comb (glyph_id);
for (i = 0; i < glyph_id->ncomb; i++) for (i = 0; i < glyph_id->ncomb; i++)
{ {
grub_int16_t space = 0; grub_int16_t space = 0;
@ -1232,10 +1237,10 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
continue; continue;
targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x;
/* CGJ is to avoid diacritics reordering. */ /* CGJ is to avoid diacritics reordering. */
if (glyph_id->combining[i].code if (comb[i].code
== GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
continue; continue;
switch (glyph_id->combining[i].type) switch (comb[i].type)
{ {
case GRUB_UNICODE_COMB_OVERLAY: case GRUB_UNICODE_COMB_OVERLAY:
do_blit (combining_glyphs[i], do_blit (combining_glyphs[i],
@ -1361,7 +1366,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id,
break; break;
case GRUB_UNICODE_COMB_MN: case GRUB_UNICODE_COMB_MN:
switch (glyph_id->combining[i].code) switch (comb[i].code)
{ {
case GRUB_UNICODE_THAANA_ABAFILI: case GRUB_UNICODE_THAANA_ABAFILI:
case GRUB_UNICODE_THAANA_AABAAFILI: case GRUB_UNICODE_THAANA_AABAAFILI:
@ -1410,17 +1415,14 @@ static struct grub_font_glyph *
grub_font_construct_dry_run (grub_font_t hinted_font, grub_font_construct_dry_run (grub_font_t hinted_font,
const struct grub_unicode_glyph *glyph_id, const struct grub_unicode_glyph *glyph_id,
struct grub_video_signed_rect *bounds, struct grub_video_signed_rect *bounds,
struct grub_font_glyph ***combining_glyphs_out, struct grub_font_glyph **combining_glyphs,
int *device_width) int *device_width)
{ {
struct grub_font_glyph *main_glyph = NULL; struct grub_font_glyph *main_glyph = NULL;
struct grub_font_glyph **combining_glyphs;
grub_uint32_t desired_attributes = 0; grub_uint32_t desired_attributes = 0;
unsigned i; unsigned i;
grub_uint32_t base = glyph_id->base; grub_uint32_t base = glyph_id->base;
const struct grub_unicode_combining *comb;
if (combining_glyphs_out)
*combining_glyphs_out = NULL;
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED) if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED)
desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED; desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED;
@ -1428,11 +1430,12 @@ grub_font_construct_dry_run (grub_font_t hinted_font,
if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED) if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)
desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED; desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED;
comb = grub_unicode_get_comb (glyph_id);
if (base == 'i' || base == 'j') if (base == 'i' || base == 'j')
{ {
for (i = 0; i < glyph_id->ncomb; i++) for (i = 0; i < glyph_id->ncomb; i++)
if (glyph_id->combining[i].type == GRUB_UNICODE_STACK_ABOVE) if (comb[i].type == GRUB_UNICODE_STACK_ABOVE)
break; break;
if (i < glyph_id->ncomb && base == 'i') if (i < glyph_id->ncomb && base == 'i')
base = GRUB_UNICODE_DOTLESS_LOWERCASE_I; base = GRUB_UNICODE_DOTLESS_LOWERCASE_I;
@ -1461,8 +1464,6 @@ grub_font_construct_dry_run (grub_font_t hinted_font,
if (!glyph_id->ncomb && !glyph_id->attributes) if (!glyph_id->ncomb && !glyph_id->attributes)
return main_glyph; return main_glyph;
combining_glyphs = grub_malloc (sizeof (combining_glyphs[0])
* glyph_id->ncomb);
if (glyph_id->ncomb && !combining_glyphs) if (glyph_id->ncomb && !combining_glyphs)
{ {
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
@ -1472,18 +1473,33 @@ grub_font_construct_dry_run (grub_font_t hinted_font,
for (i = 0; i < glyph_id->ncomb; i++) for (i = 0; i < glyph_id->ncomb; i++)
combining_glyphs[i] combining_glyphs[i]
= grub_font_get_glyph_with_fallback (main_glyph->font, = grub_font_get_glyph_with_fallback (main_glyph->font,
glyph_id->combining[i].code); comb[i].code);
blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs, blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs,
device_width); device_width);
if (combining_glyphs_out)
*combining_glyphs_out = combining_glyphs;
else
grub_free (combining_glyphs);
return main_glyph; return main_glyph;
} }
static struct grub_font_glyph **render_combining_glyphs = 0;
static grub_size_t render_max_comb_glyphs = 0;
static void
ensure_comb_space (const struct grub_unicode_glyph *glyph_id)
{
if (glyph_id->ncomb <= render_max_comb_glyphs)
return;
render_max_comb_glyphs = 2 * glyph_id->ncomb;
if (render_max_comb_glyphs < 8)
render_max_comb_glyphs = 8;
grub_free (render_combining_glyphs);
render_combining_glyphs = grub_malloc (render_max_comb_glyphs
* sizeof (render_combining_glyphs[0]));
if (!render_combining_glyphs)
grub_errno = 0;
}
int int
grub_font_get_constructed_device_width (grub_font_t hinted_font, grub_font_get_constructed_device_width (grub_font_t hinted_font,
const struct grub_unicode_glyph const struct grub_unicode_glyph
@ -1491,8 +1507,11 @@ grub_font_get_constructed_device_width (grub_font_t hinted_font,
{ {
int ret; int ret;
struct grub_font_glyph *main_glyph; struct grub_font_glyph *main_glyph;
ensure_comb_space (glyph_id);
main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL, main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL,
NULL, &ret); render_combining_glyphs, &ret);
if (!main_glyph) if (!main_glyph)
return unknown_glyph->device_width; return unknown_glyph->device_width;
return ret; return ret;
@ -1504,26 +1523,42 @@ grub_font_construct_glyph (grub_font_t hinted_font,
{ {
struct grub_font_glyph *main_glyph; struct grub_font_glyph *main_glyph;
struct grub_video_signed_rect bounds; struct grub_video_signed_rect bounds;
struct grub_font_glyph *glyph; static struct grub_font_glyph *glyph = 0;
struct grub_font_glyph **combining_glyphs; static grub_size_t max_glyph_size = 0;
ensure_comb_space (glyph_id);
main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id,
&bounds, &combining_glyphs, NULL); &bounds, render_combining_glyphs,
NULL);
if (!main_glyph) if (!main_glyph)
return grub_font_dup_glyph (unknown_glyph); return unknown_glyph;
if (!combining_glyphs) if (!render_combining_glyphs && glyph_id->ncomb)
return grub_font_dup_glyph (main_glyph); return main_glyph;
glyph = if (!glyph_id->ncomb && !glyph_id->attributes)
grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8); return main_glyph;
if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT)
{
grub_free (glyph);
max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2;
if (max_glyph_size < 8)
max_glyph_size = 8;
glyph = grub_malloc (max_glyph_size);
}
if (!glyph) if (!glyph)
{ {
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
return grub_font_dup_glyph (main_glyph); return main_glyph;
} }
grub_memset (glyph, 0, sizeof (*glyph)
+ (bounds.width * bounds.height
+ GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT);
glyph->font = main_glyph->font; glyph->font = main_glyph->font;
glyph->width = bounds.width; glyph->width = bounds.width;
glyph->height = bounds.height; glyph->height = bounds.height;
@ -1542,9 +1577,7 @@ grub_font_construct_glyph (grub_font_t hinted_font,
(glyph->height + glyph->offset_y) (glyph->height + glyph->offset_y)
- (main_glyph->height + main_glyph->offset_y)); - (main_glyph->height + main_glyph->offset_y));
blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs, NULL); blit_comb (glyph_id, glyph, NULL, main_glyph, render_combining_glyphs, NULL);
grub_free (combining_glyphs);
return glyph; return glyph;
} }

View file

@ -42,7 +42,6 @@ grub_font_draw_string (const char *str, grub_font_t font,
int left_x, int baseline_y) int left_x, int baseline_y)
{ {
int x; int x;
struct grub_font_glyph *glyph;
grub_uint32_t *logical; grub_uint32_t *logical;
grub_ssize_t logical_len, visual_len; grub_ssize_t logical_len, visual_len;
struct grub_unicode_glyph *visual, *ptr; struct grub_unicode_glyph *visual, *ptr;
@ -60,18 +59,18 @@ grub_font_draw_string (const char *str, grub_font_t font,
for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++) for (ptr = visual, x = left_x; ptr < visual + visual_len; ptr++)
{ {
grub_err_t err; grub_err_t err;
struct grub_font_glyph *glyph;
glyph = grub_font_construct_glyph (font, ptr); glyph = grub_font_construct_glyph (font, ptr);
if (!glyph) if (!glyph)
return grub_errno; return grub_errno;
err = grub_font_draw_glyph (glyph, color, x, baseline_y); err = grub_font_draw_glyph (glyph, color, x, baseline_y);
x += glyph->device_width; x += glyph->device_width;
grub_free (glyph);
if (err) if (err)
return err; return err;
} }
for (ptr = visual; ptr < visual + visual_len; ptr++) for (ptr = visual; ptr < visual + visual_len; ptr++)
grub_free (ptr->combining); grub_unicode_destroy_glyph (ptr);
grub_free (visual); grub_free (visual);
return GRUB_ERR_NONE; return GRUB_ERR_NONE;
@ -104,7 +103,7 @@ grub_font_get_string_width (grub_font_t font, const char *str)
&glyph); &glyph);
width += grub_font_get_constructed_device_width (font, &glyph); width += grub_font_get_constructed_device_width (font, &glyph);
grub_free (glyph.combining); grub_unicode_destroy_glyph (&glyph);
} }
grub_free (logical); grub_free (logical);

View file

@ -87,6 +87,7 @@ list_destroy (void *vself)
self->scrollbar_thumb->destroy (self->scrollbar_thumb); self->scrollbar_thumb->destroy (self->scrollbar_thumb);
if (self->scrollbar_frame) if (self->scrollbar_frame)
self->scrollbar_frame->destroy (self->scrollbar_frame); self->scrollbar_frame->destroy (self->scrollbar_frame);
grub_free (self->scrollbar_thumb_pattern);
grub_free (self); grub_free (self);
} }

View file

@ -59,6 +59,9 @@ static void
progress_bar_destroy (void *vself) progress_bar_destroy (void *vself)
{ {
grub_gui_progress_bar_t self = vself; grub_gui_progress_bar_t self = vself;
grub_free (self->theme_dir);
grub_free (self->template);
grub_free (self->id);
grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self); grub_gfxmenu_timeout_unregister ((grub_gui_component_t) self);
grub_free (self); grub_free (self);
} }

View file

@ -46,7 +46,6 @@ grub_putcode_dumb (grub_uint32_t code,
.variant = 0, .variant = 0,
.attributes = 0, .attributes = 0,
.ncomb = 0, .ncomb = 0,
.combining = 0,
.estimated_width = 1 .estimated_width = 1
}; };

View file

@ -435,7 +435,6 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
out->attributes = 0; out->attributes = 0;
out->ncomb = 0; out->ncomb = 0;
out->estimated_width = 1; out->estimated_width = 1;
out->combining = NULL;
return 1; return 1;
} }
@ -473,25 +472,42 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|| comb_type == GRUB_UNICODE_COMB_ME || comb_type == GRUB_UNICODE_COMB_ME
|| comb_type == GRUB_UNICODE_COMB_MN) || comb_type == GRUB_UNICODE_COMB_MN)
last_comb_pointer = out->ncomb; last_comb_pointer = out->ncomb;
n = grub_realloc (out->combining,
sizeof (n[0]) * (out->ncomb + 1)); if (out->ncomb + 1 <= (int) ARRAY_SIZE (out->combining_inline))
if (!n) n = out->combining_inline;
else if (out->ncomb > (int) ARRAY_SIZE (out->combining_inline))
{ {
grub_errno = GRUB_ERR_NONE; n = grub_realloc (out->combining_ptr,
continue; sizeof (n[0]) * (out->ncomb + 1));
if (!n)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
out->combining_ptr = n;
}
else
{
n = grub_malloc (sizeof (n[0]) * (out->ncomb + 1));
if (!n)
{
grub_errno = GRUB_ERR_NONE;
continue;
}
grub_memcpy (n, out->combining_inline,
sizeof (out->combining_inline));
out->combining_ptr = n;
} }
out->combining = n;
for (j = last_comb_pointer; j < out->ncomb; j++) for (j = last_comb_pointer; j < out->ncomb; j++)
if (is_type_after (out->combining[j].type, comb_type)) if (is_type_after (n[j].type, comb_type))
break; break;
grub_memmove (out->combining + j + 1, grub_memmove (n + j + 1,
out->combining + j, n + j,
(out->ncomb - j) (out->ncomb - j)
* sizeof (out->combining[0])); * sizeof (n[0]));
out->combining = n; n[j].code = *ptr;
out->combining[j].code = *ptr; n[j].type = comb_type;
out->combining[j].type = comb_type;
out->ncomb++; out->ncomb++;
continue; continue;
} }
@ -503,7 +519,6 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
out->attributes = 0; out->attributes = 0;
out->ncomb = 0; out->ncomb = 0;
out->estimated_width = 1; out->estimated_width = 1;
out->combining = NULL;
} }
return ptr - in; return ptr - in;
} }
@ -511,7 +526,7 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
static grub_ssize_t static grub_ssize_t
bidi_line_wrap (struct grub_unicode_glyph *visual_out, bidi_line_wrap (struct grub_unicode_glyph *visual_out,
struct grub_unicode_glyph *visual, struct grub_unicode_glyph *visual,
grub_size_t visual_len, unsigned *levels, grub_size_t visual_len,
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg), grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual, void *getcharwidth_arg),
void *getcharwidth_arg, void *getcharwidth_arg,
grub_size_t maxwidth, grub_size_t startwidth, grub_size_t maxwidth, grub_size_t startwidth,
@ -531,7 +546,7 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
void revert (unsigned start, unsigned end) void revert (unsigned start, unsigned end)
{ {
struct grub_unicode_glyph t; struct grub_unicode_glyph t;
unsigned i, tl; unsigned i;
int a, b; int a, b;
if (pos) if (pos)
{ {
@ -549,9 +564,6 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
pos[visual[start + i].orig_pos].x = a + b - pos[visual[start + i].orig_pos].x; pos[visual[start + i].orig_pos].x = a + b - pos[visual[start + i].orig_pos].x;
pos[visual[end - i].orig_pos].x = a + b - pos[visual[end - i].orig_pos].x; pos[visual[end - i].orig_pos].x = a + b - pos[visual[end - i].orig_pos].x;
} }
tl = levels[start + i];
levels[start + i] = levels[end - i];
levels[end - i] = tl;
} }
} }
@ -611,10 +623,10 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
unsigned i; unsigned i;
for (i = line_start; i < k; i++) for (i = line_start; i < k; i++)
{ {
if (levels[i] > max_level) if (visual[i].bidi_level > max_level)
max_level = levels[i]; max_level = visual[i].bidi_level;
if (levels[i] < min_odd_level && (levels[i] & 1)) if (visual[i].bidi_level < min_odd_level && (visual[i].bidi_level & 1))
min_odd_level = levels[i]; min_odd_level = visual[i].bidi_level;
} }
} }
@ -627,9 +639,11 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
unsigned i; unsigned i;
for (i = line_start; i < k; i++) for (i = line_start; i < k; i++)
{ {
if (i != line_start && levels[i] >= j && levels[i-1] < j) if (i != line_start && visual[i].bidi_level >= j
&& visual[i-1].bidi_level < j)
in = i; in = i;
if (levels[i] >= j && (i + 1 == k || levels[i+1] < j)) if (visual[i].bidi_level >= j && (i + 1 == k
|| visual[i+1].bidi_level < j))
revert (in, i); revert (in, i);
} }
} }
@ -639,10 +653,10 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
unsigned i; unsigned i;
for (i = line_start; i < k; i++) for (i = line_start; i < k; i++)
{ {
if (is_mirrored (visual[i].base) && levels[i]) if (is_mirrored (visual[i].base) && visual[i].bidi_level)
visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR; visual[i].attributes |= GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR;
if ((visual[i].attributes & GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN) if ((visual[i].attributes & GRUB_UNICODE_GLYPH_ATTRIBUTES_JOIN)
&& levels[i]) && visual[i].bidi_level)
{ {
int left, right; int left, right;
left = visual[i].attributes left = visual[i].attributes
@ -763,8 +777,6 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
{ {
enum grub_bidi_type type = GRUB_BIDI_TYPE_L; enum grub_bidi_type type = GRUB_BIDI_TYPE_L;
enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L}; enum override_status {OVERRIDE_NEUTRAL = 0, OVERRIDE_R, OVERRIDE_L};
unsigned *levels;
enum grub_bidi_type *resolved_types;
unsigned base_level; unsigned base_level;
enum override_status cur_override; enum override_status cur_override;
unsigned i; unsigned i;
@ -808,24 +820,9 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
cur_override = stack_override[stack_depth]; cur_override = stack_override[stack_depth];
} }
levels = grub_malloc (sizeof (levels[0]) * logical_len);
if (!levels)
return -1;
resolved_types = grub_malloc (sizeof (resolved_types[0]) * logical_len);
if (!resolved_types)
{
grub_free (levels);
return -1;
}
visual = grub_malloc (sizeof (visual[0]) * logical_len); visual = grub_malloc (sizeof (visual[0]) * logical_len);
if (!visual) if (!visual)
{ return -1;
grub_free (resolved_types);
grub_free (levels);
return -1;
}
for (i = 0; i < logical_len; i++) for (i = 0; i < logical_len; i++)
{ {
@ -930,13 +927,13 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
join_state = JOIN_DEFAULT; join_state = JOIN_DEFAULT;
zwj_propagate_to_previous = 1; zwj_propagate_to_previous = 1;
levels[visual_len] = cur_level; visual[visual_len].bidi_level = cur_level;
if (cur_override != OVERRIDE_NEUTRAL) if (cur_override != OVERRIDE_NEUTRAL)
resolved_types[visual_len] = visual[visual_len].bidi_type =
(cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L
: GRUB_BIDI_TYPE_R; : GRUB_BIDI_TYPE_R;
else else
resolved_types[visual_len] = type; visual[visual_len].bidi_type = type;
visual_len++; visual_len++;
} }
} }
@ -951,16 +948,16 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
unsigned prev_level, next_level, cur_run_level; unsigned prev_level, next_level, cur_run_level;
unsigned last_type, last_strong_type; unsigned last_type, last_strong_type;
for (run_end = run_start; run_end < visual_len && for (run_end = run_start; run_end < visual_len &&
levels[run_end] == levels[run_start]; run_end++); visual[run_end].bidi_level == visual[run_start].bidi_level; run_end++);
if (run_start == 0) if (run_start == 0)
prev_level = base_level; prev_level = base_level;
else else
prev_level = levels[run_start - 1]; prev_level = visual[run_start - 1].bidi_level;
if (run_end == visual_len) if (run_end == visual_len)
next_level = base_level; next_level = base_level;
else else
next_level = levels[run_end]; next_level = visual[run_end].bidi_level;
cur_run_level = levels[run_start]; cur_run_level = visual[run_start].bidi_level;
if (prev_level & 1) if (prev_level & 1)
last_type = GRUB_BIDI_TYPE_R; last_type = GRUB_BIDI_TYPE_R;
else else
@ -968,48 +965,48 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
last_strong_type = last_type; last_strong_type = last_type;
for (i = run_start; i < run_end; i++) for (i = run_start; i < run_end; i++)
{ {
switch (resolved_types[i]) switch (visual[i].bidi_type)
{ {
case GRUB_BIDI_TYPE_NSM: case GRUB_BIDI_TYPE_NSM:
resolved_types[i] = last_type; visual[i].bidi_type = last_type;
break; break;
case GRUB_BIDI_TYPE_EN: case GRUB_BIDI_TYPE_EN:
if (last_strong_type == GRUB_BIDI_TYPE_AL) if (last_strong_type == GRUB_BIDI_TYPE_AL)
resolved_types[i] = GRUB_BIDI_TYPE_AN; visual[i].bidi_type = GRUB_BIDI_TYPE_AN;
break; break;
case GRUB_BIDI_TYPE_L: case GRUB_BIDI_TYPE_L:
case GRUB_BIDI_TYPE_R: case GRUB_BIDI_TYPE_R:
last_strong_type = resolved_types[i]; last_strong_type = visual[i].bidi_type;
break; break;
case GRUB_BIDI_TYPE_ES: case GRUB_BIDI_TYPE_ES:
if (last_type == GRUB_BIDI_TYPE_EN if (last_type == GRUB_BIDI_TYPE_EN
&& i + 1 < run_end && i + 1 < run_end
&& resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN)
resolved_types[i] = GRUB_BIDI_TYPE_EN; visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
else else
resolved_types[i] = GRUB_BIDI_TYPE_ON; visual[i].bidi_type = GRUB_BIDI_TYPE_ON;
break; break;
case GRUB_BIDI_TYPE_ET: case GRUB_BIDI_TYPE_ET:
{ {
unsigned j; unsigned j;
if (last_type == GRUB_BIDI_TYPE_EN) if (last_type == GRUB_BIDI_TYPE_EN)
{ {
resolved_types[i] = GRUB_BIDI_TYPE_EN; visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
break; break;
} }
for (j = i; j < run_end for (j = i; j < run_end
&& resolved_types[j] == GRUB_BIDI_TYPE_ET; j++); && visual[j].bidi_type == GRUB_BIDI_TYPE_ET; j++);
if (j != run_end && resolved_types[j] == GRUB_BIDI_TYPE_EN) if (j != run_end && visual[j].bidi_type == GRUB_BIDI_TYPE_EN)
{ {
for (; i < run_end for (; i < run_end
&& resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++)
resolved_types[i] = GRUB_BIDI_TYPE_EN; visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
i--; i--;
break; break;
} }
for (; i < run_end for (; i < run_end
&& resolved_types[i] == GRUB_BIDI_TYPE_ET; i++) && visual[i].bidi_type == GRUB_BIDI_TYPE_ET; i++)
resolved_types[i] = GRUB_BIDI_TYPE_ON; visual[i].bidi_type = GRUB_BIDI_TYPE_ON;
i--; i--;
break; break;
} }
@ -1017,33 +1014,33 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
case GRUB_BIDI_TYPE_CS: case GRUB_BIDI_TYPE_CS:
if (last_type == GRUB_BIDI_TYPE_EN if (last_type == GRUB_BIDI_TYPE_EN
&& i + 1 < run_end && i + 1 < run_end
&& resolved_types[i + 1] == GRUB_BIDI_TYPE_EN) && visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN)
{ {
resolved_types[i] = GRUB_BIDI_TYPE_EN; visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
break; break;
} }
if (last_type == GRUB_BIDI_TYPE_AN if (last_type == GRUB_BIDI_TYPE_AN
&& i + 1 < run_end && i + 1 < run_end
&& (resolved_types[i + 1] == GRUB_BIDI_TYPE_AN && (visual[i + 1].bidi_type == GRUB_BIDI_TYPE_AN
|| (resolved_types[i + 1] == GRUB_BIDI_TYPE_EN || (visual[i + 1].bidi_type == GRUB_BIDI_TYPE_EN
&& last_strong_type == GRUB_BIDI_TYPE_AL))) && last_strong_type == GRUB_BIDI_TYPE_AL)))
{ {
resolved_types[i] = GRUB_BIDI_TYPE_EN; visual[i].bidi_type = GRUB_BIDI_TYPE_EN;
break; break;
} }
resolved_types[i] = GRUB_BIDI_TYPE_ON; visual[i].bidi_type = GRUB_BIDI_TYPE_ON;
break; break;
case GRUB_BIDI_TYPE_AL: case GRUB_BIDI_TYPE_AL:
last_strong_type = resolved_types[i]; last_strong_type = visual[i].bidi_type;
resolved_types[i] = GRUB_BIDI_TYPE_R; visual[i].bidi_type = GRUB_BIDI_TYPE_R;
break; break;
default: /* Make GCC happy. */ default: /* Make GCC happy. */
break; break;
} }
last_type = resolved_types[i]; last_type = visual[i].bidi_type;
if (resolved_types[i] == GRUB_BIDI_TYPE_EN if (visual[i].bidi_type == GRUB_BIDI_TYPE_EN
&& last_strong_type == GRUB_BIDI_TYPE_L) && last_strong_type == GRUB_BIDI_TYPE_L)
resolved_types[i] = GRUB_BIDI_TYPE_L; visual[i].bidi_type = GRUB_BIDI_TYPE_L;
} }
if (prev_level & 1) if (prev_level & 1)
last_type = GRUB_BIDI_TYPE_R; last_type = GRUB_BIDI_TYPE_R;
@ -1054,13 +1051,13 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
unsigned j; unsigned j;
unsigned next_type; unsigned next_type;
for (j = i; j < run_end && for (j = i; j < run_end &&
(resolved_types[j] == GRUB_BIDI_TYPE_B (visual[j].bidi_type == GRUB_BIDI_TYPE_B
|| resolved_types[j] == GRUB_BIDI_TYPE_S || visual[j].bidi_type == GRUB_BIDI_TYPE_S
|| resolved_types[j] == GRUB_BIDI_TYPE_WS || visual[j].bidi_type == GRUB_BIDI_TYPE_WS
|| resolved_types[j] == GRUB_BIDI_TYPE_ON); j++); || visual[j].bidi_type == GRUB_BIDI_TYPE_ON); j++);
if (j == i) if (j == i)
{ {
if (resolved_types[i] == GRUB_BIDI_TYPE_L) if (visual[i].bidi_type == GRUB_BIDI_TYPE_L)
last_type = GRUB_BIDI_TYPE_L; last_type = GRUB_BIDI_TYPE_L;
else else
last_type = GRUB_BIDI_TYPE_R; last_type = GRUB_BIDI_TYPE_R;
@ -1071,39 +1068,39 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L; next_type = (next_level & 1) ? GRUB_BIDI_TYPE_R : GRUB_BIDI_TYPE_L;
else else
{ {
if (resolved_types[j] == GRUB_BIDI_TYPE_L) if (visual[j].bidi_type == GRUB_BIDI_TYPE_L)
next_type = GRUB_BIDI_TYPE_L; next_type = GRUB_BIDI_TYPE_L;
else else
next_type = GRUB_BIDI_TYPE_R; next_type = GRUB_BIDI_TYPE_R;
} }
if (next_type == last_type) if (next_type == last_type)
for (; i < j; i++) for (; i < j; i++)
resolved_types[i] = last_type; visual[i].bidi_type = last_type;
else else
for (; i < j; i++) for (; i < j; i++)
resolved_types[i] = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R visual[i].bidi_type = (cur_run_level & 1) ? GRUB_BIDI_TYPE_R
: GRUB_BIDI_TYPE_L; : GRUB_BIDI_TYPE_L;
} }
} }
for (i = 0; i < visual_len; i++) for (i = 0; i < visual_len; i++)
{ {
if (!(levels[i] & 1) && resolved_types[i] == GRUB_BIDI_TYPE_R) if (!(visual[i].bidi_level & 1) && visual[i].bidi_type == GRUB_BIDI_TYPE_R)
{ {
levels[i]++; visual[i].bidi_level++;
continue; continue;
} }
if (!(levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_AN if (!(visual[i].bidi_level & 1) && (visual[i].bidi_type == GRUB_BIDI_TYPE_AN
|| resolved_types[i] == GRUB_BIDI_TYPE_EN)) || visual[i].bidi_type == GRUB_BIDI_TYPE_EN))
{ {
levels[i] += 2; visual[i].bidi_level += 2;
continue; continue;
} }
if ((levels[i] & 1) && (resolved_types[i] == GRUB_BIDI_TYPE_L if ((visual[i].bidi_level & 1) && (visual[i].bidi_type == GRUB_BIDI_TYPE_L
|| resolved_types[i] == GRUB_BIDI_TYPE_AN || visual[i].bidi_type == GRUB_BIDI_TYPE_AN
|| resolved_types[i] == GRUB_BIDI_TYPE_EN)) || visual[i].bidi_type == GRUB_BIDI_TYPE_EN))
{ {
levels[i]++; visual[i].bidi_level++;
continue; continue;
} }
} }
@ -1111,16 +1108,14 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
else else
{ {
for (i = 0; i < visual_len; i++) for (i = 0; i < visual_len; i++)
levels[i] = 0; visual[i].bidi_level = 0;
} }
grub_free (resolved_types);
{ {
grub_ssize_t ret; grub_ssize_t ret;
ret = bidi_line_wrap (visual_out, visual, visual_len, levels, ret = bidi_line_wrap (visual_out, visual, visual_len,
getcharwidth, getcharwidth_arg, maxwidth, startwidth, contchar, getcharwidth, getcharwidth_arg, maxwidth, startwidth, contchar,
pos, primitive_wrap, log_end); pos, primitive_wrap, log_end);
grub_free (levels);
grub_free (visual); grub_free (visual);
return ret; return ret;
} }

View file

@ -624,7 +624,7 @@ backward_char (struct screen *screen, int update)
linep->buf + screen->column) linep->buf + screen->column)
- linep->buf; - linep->buf;
grub_free (glyph.combining); grub_unicode_destroy_glyph (&glyph);
} }
else if (screen->line > 0) else if (screen->line > 0)
{ {

View file

@ -56,10 +56,10 @@ grub_getstringwidth (grub_uint32_t * str, const grub_uint32_t * last_position,
while (str < last_position) while (str < last_position)
{ {
struct grub_unicode_glyph glyph; struct grub_unicode_glyph glyph;
glyph.combining = 0; glyph.ncomb = 0;
str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph); str += grub_unicode_aglomerate_comb (str, last_position - str, &glyph);
width += grub_term_getcharwidth (term, &glyph); width += grub_term_getcharwidth (term, &glyph);
grub_free (glyph.combining); grub_unicode_destroy_glyph (&glyph);
} }
return width; return width;
} }
@ -259,7 +259,8 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
len - i, &glyph); len - i, &glyph);
width = grub_term_getcharwidth (term, &glyph); width = grub_term_getcharwidth (term, &glyph);
grub_free (glyph.combining);
grub_unicode_destroy_glyph (&glyph);
if (x + width <= (int) (GRUB_TERM_LEFT_BORDER_X if (x + width <= (int) (GRUB_TERM_LEFT_BORDER_X
+ grub_term_border_width (term) + grub_term_border_width (term)
@ -284,7 +285,6 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
.variant = 0, .variant = 0,
.attributes = 0, .attributes = 0,
.ncomb = 0, .ncomb = 0,
.combining = 0,
.estimated_width = 1 .estimated_width = 1
}; };
x += grub_term_getcharwidth (term, &pseudo_glyph); x += grub_term_getcharwidth (term, &pseudo_glyph);

View file

@ -29,7 +29,7 @@
struct term_state struct term_state
{ {
struct term_state *next; struct term_state *next;
const struct grub_unicode_glyph *backlog_glyphs; struct grub_unicode_glyph *backlog_glyphs;
const grub_uint32_t *backlog_ucs4; const grub_uint32_t *backlog_ucs4;
int backlog_fixed_tab; int backlog_fixed_tab;
grub_size_t backlog_len; grub_size_t backlog_len;
@ -228,7 +228,6 @@ grub_puts_terminal (const char *str, struct grub_term_output *term)
.variant = 0, .variant = 0,
.attributes = 0, .attributes = 0,
.ncomb = 0, .ncomb = 0,
.combining = 0,
.estimated_width = 1, .estimated_width = 1,
.base = *str .base = *str
}; };
@ -422,7 +421,6 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term,
.variant = 0, .variant = 0,
.attributes = 0, .attributes = 0,
.ncomb = 0, .ncomb = 0,
.combining = 0,
.estimated_width = 1 .estimated_width = 1
}; };
@ -475,7 +473,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term,
} }
} }
else else
code = c->combining[i].code; code = grub_unicode_get_comb (c) [i].code;
grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8)); grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8));
@ -506,7 +504,6 @@ putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab)
.variant = 0, .variant = 0,
.attributes = 0, .attributes = 0,
.ncomb = 0, .ncomb = 0,
.combining = 0,
.estimated_width = 1 .estimated_width = 1
}; };
@ -534,7 +531,6 @@ get_maxwidth (struct grub_term_output *term,
.variant = 0, .variant = 0,
.attributes = 0, .attributes = 0,
.ncomb = 0, .ncomb = 0,
.combining = 0
}; };
return (grub_term_width (term) return (grub_term_width (term)
- grub_term_getcharwidth (term, &space_glyph) - grub_term_getcharwidth (term, &space_glyph)
@ -615,7 +611,6 @@ print_ucs4_terminal (const grub_uint32_t * str,
.variant = 0, .variant = 0,
.attributes = 0, .attributes = 0,
.ncomb = 0, .ncomb = 0,
.combining = 0
}; };
c.base = *ptr; c.base = *ptr;
if (pos) if (pos)
@ -779,14 +774,14 @@ find_term_state (struct grub_term_output *term)
} }
static int static int
put_glyphs_terminal (const struct grub_unicode_glyph *visual, put_glyphs_terminal (struct grub_unicode_glyph *visual,
grub_ssize_t visual_len, grub_ssize_t visual_len,
int margin_left, int margin_right, int margin_left, int margin_right,
struct grub_term_output *term, struct grub_term_output *term,
struct term_state *state, int fixed_tab, struct term_state *state, int fixed_tab,
grub_uint32_t contchar) grub_uint32_t contchar)
{ {
const struct grub_unicode_glyph *visual_ptr; struct grub_unicode_glyph *visual_ptr;
int since_last_nl = 1; int since_last_nl = 1;
for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++) for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++)
{ {
@ -813,7 +808,7 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual,
grub_term_gotoxy (term, margin_left, grub_term_gotoxy (term, margin_left,
grub_term_getxy (term) & 0xff); grub_term_getxy (term) & 0xff);
} }
grub_free (visual_ptr->combining); grub_unicode_destroy_glyph (visual_ptr);
} }
if (contchar && since_last_nl) if (contchar && since_last_nl)
fill_margin (term, margin_right); fill_margin (term, margin_right);
@ -953,7 +948,7 @@ print_ucs4_real (const grub_uint32_t * str,
if (visual_len_show && visual[visual_len_show - 1].base != '\n') if (visual_len_show && visual[visual_len_show - 1].base != '\n')
ret++; ret++;
for (vptr = visual; vptr < visual + visual_len; vptr++) for (vptr = visual; vptr < visual + visual_len; vptr++)
grub_free (vptr->combining); grub_unicode_destroy_glyph (vptr);
grub_free (visual); grub_free (visual);
} }
else else
@ -1030,7 +1025,6 @@ grub_xnputs (const char *str, grub_size_t msg_len)
.variant = 0, .variant = 0,
.attributes = 0, .attributes = 0,
.ncomb = 0, .ncomb = 0,
.combining = 0,
.estimated_width = 1, .estimated_width = 1,
.base = *str .base = *str
}; };

View file

@ -175,7 +175,7 @@ set_term_color (grub_uint8_t term_color)
static void static void
clear_char (struct grub_colored_char *c) clear_char (struct grub_colored_char *c)
{ {
grub_free (c->code.combining); grub_unicode_destroy_glyph (&c->code);
grub_unicode_set_glyph_from_code (&c->code, ' '); grub_unicode_set_glyph_from_code (&c->code, ' ');
c->fg_color = virtual_screen.fg_color; c->fg_color = virtual_screen.fg_color;
c->bg_color = virtual_screen.bg_color; c->bg_color = virtual_screen.bg_color;
@ -191,7 +191,7 @@ grub_virtual_screen_free (void)
for (i = 0; for (i = 0;
i < virtual_screen.columns * virtual_screen.rows; i < virtual_screen.columns * virtual_screen.rows;
i++) i++)
grub_free (virtual_screen.text_buffer[i].code.combining); grub_unicode_destroy_glyph (&virtual_screen.text_buffer[i].code);
grub_free (virtual_screen.text_buffer); grub_free (virtual_screen.text_buffer);
} }
@ -267,7 +267,7 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
/* Clear out text buffer. */ /* Clear out text buffer. */
for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
{ {
virtual_screen.text_buffer[i].code.combining = 0; virtual_screen.text_buffer[i].code.ncomb = 0;
clear_char (&(virtual_screen.text_buffer[i])); clear_char (&(virtual_screen.text_buffer[i]));
} }
@ -408,8 +408,8 @@ grub_gfxterm_term_fini (struct grub_term_output *term __attribute__ ((unused)))
for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++) for (i = 0; i < virtual_screen.columns * virtual_screen.rows; i++)
{ {
grub_free (virtual_screen.text_buffer[i].code.combining); grub_unicode_destroy_glyph (&virtual_screen.text_buffer[i].code);
virtual_screen.text_buffer[i].code.combining = 0; virtual_screen.text_buffer[i].code.ncomb = 0;
virtual_screen.text_buffer[i].code.base = 0; virtual_screen.text_buffer[i].code.base = 0;
} }
@ -651,7 +651,6 @@ paint_char (unsigned cx, unsigned cy)
/* Mark character to be drawn. */ /* Mark character to be drawn. */
dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y, dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y,
width, height); width, height);
grub_free (glyph);
} }
static inline void static inline void
@ -804,7 +803,7 @@ scroll_up (void)
/* Clear first line in text buffer. */ /* Clear first line in text buffer. */
for (i = 0; i < virtual_screen.columns; i++) for (i = 0; i < virtual_screen.columns; i++)
grub_free (virtual_screen.text_buffer[i].code.combining); grub_unicode_destroy_glyph (&virtual_screen.text_buffer[i].code);
/* Scroll text buffer with one line to up. */ /* Scroll text buffer with one line to up. */
grub_memmove (virtual_screen.text_buffer, grub_memmove (virtual_screen.text_buffer,
@ -877,7 +876,7 @@ grub_gfxterm_putchar (struct grub_term_output *term,
p = (virtual_screen.text_buffer + p = (virtual_screen.text_buffer +
virtual_screen.cursor_x + virtual_screen.cursor_x +
virtual_screen.cursor_y * virtual_screen.columns); virtual_screen.cursor_y * virtual_screen.columns);
grub_free (p->code.combining); grub_unicode_destroy_glyph (&p->code);
grub_unicode_set_glyph (&p->code, c); grub_unicode_set_glyph (&p->code, c);
grub_errno = GRUB_ERR_NONE; grub_errno = GRUB_ERR_NONE;
p->fg_color = virtual_screen.fg_color; p->fg_color = virtual_screen.fg_color;
@ -892,7 +891,7 @@ grub_gfxterm_putchar (struct grub_term_output *term,
virtual_screen.text_buffer + virtual_screen.columns virtual_screen.text_buffer + virtual_screen.columns
* virtual_screen.rows; i++) * virtual_screen.rows; i++)
{ {
grub_free (p[i].code.combining); grub_unicode_destroy_glyph (&p[i].code);
p[i].code.base = 0; p[i].code.base = 0;
} }
} }

View file

@ -478,6 +478,11 @@ int genfd = -1;
#include <grub/time.h> #include <grub/time.h>
#if defined (GRUB_MACHINE_EMU) && defined (COLLECT_TIME_STATISTICS)
#include <sys/times.h>
#include <unistd.h>
#endif
static void static void
write_time (void) write_time (void)
{ {
@ -486,9 +491,12 @@ write_time (void)
static grub_uint64_t prev; static grub_uint64_t prev;
grub_uint64_t cur; grub_uint64_t cur;
static int tmrfd = -1; static int tmrfd = -1;
struct tms tm;
if (tmrfd < 0) if (tmrfd < 0)
tmrfd = open ("time.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); tmrfd = open ("time.txt", O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
cur = grub_get_time_ms ();
times (&tm);
cur = (tm.tms_utime * 1000ULL) / sysconf(_SC_CLK_TCK);
grub_snprintf (buf, sizeof (buf), "%s_%dx%dx%s:%d: %" PRIuGRUB_UINT64_T " ms\n", grub_snprintf (buf, sizeof (buf), "%s_%dx%dx%s:%d: %" PRIuGRUB_UINT64_T " ms\n",
basename, basename,
capt_mode_info.width, capt_mode_info.width,

View file

@ -1085,15 +1085,9 @@ grub_video_fbblit_replace_index_RGBX8888 (struct grub_video_fbblit_info *dst,
{ {
color = *srcptr++; color = *srcptr++;
#ifdef GRUB_CPU_WORDS_BIGENDIAN
sb = (color >> 0) & 0xFF;
sg = (color >> 8) & 0xFF;
sr = (color >> 16) & 0xFF;
#else
sr = (color >> 0) & 0xFF; sr = (color >> 0) & 0xFF;
sg = (color >> 8) & 0xFF; sg = (color >> 8) & 0xFF;
sb = (color >> 16) & 0xFF; sb = (color >> 16) & 0xFF;
#endif
color = grub_video_fb_map_rgb(sr, sg, sb); color = grub_video_fb_map_rgb(sr, sg, sb);
*dstptr++ = color & 0xFF; *dstptr++ = color & 0xFF;

View file

@ -5,3 +5,5 @@ void EXPORT_FUNC (write) (void);
void EXPORT_FUNC (ioctl) (void); void EXPORT_FUNC (ioctl) (void);
void EXPORT_FUNC (__errno_location) (void); void EXPORT_FUNC (__errno_location) (void);
void EXPORT_FUNC (strerror) (void); void EXPORT_FUNC (strerror) (void);
void EXPORT_FUNC (sysconf) (void);
void EXPORT_FUNC (times) (void);

View file

@ -132,21 +132,33 @@ enum grub_comb_type
GRUB_UNICODE_COMB_MN = 255, GRUB_UNICODE_COMB_MN = 255,
}; };
struct grub_unicode_combining
{
grub_uint32_t code:21;
enum grub_comb_type type:8;
};
/* This structure describes a glyph as opposed to character. */ /* This structure describes a glyph as opposed to character. */
struct grub_unicode_glyph struct grub_unicode_glyph
{ {
grub_uint32_t base; grub_uint32_t base:23; /* minimum: 21 */
grub_uint16_t variant:9; grub_uint16_t variant:9; /* minimum: 9 */
grub_uint8_t attributes:5;
grub_size_t ncomb; grub_uint8_t attributes:5; /* minimum: 5 */
grub_size_t orig_pos; grub_uint8_t bidi_level:6; /* minimum: 6 */
struct grub_unicode_combining { enum grub_bidi_type bidi_type:5; /* minimum: :5 */
grub_uint32_t code;
enum grub_comb_type type; unsigned ncomb:8;
} *combining;
/* Hint by unicode subsystem how wide this character usually is. /* Hint by unicode subsystem how wide this character usually is.
Real width is determined by font. Set only in UTF-8 stream. */ Real width is determined by font. Set only in UTF-8 stream. */
int estimated_width; int estimated_width:8;
grub_size_t orig_pos;
union
{
struct grub_unicode_combining combining_inline[sizeof (void *)
/ sizeof (struct grub_unicode_combining)];
struct grub_unicode_combining *combining_ptr;
};
}; };
#define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1 #define GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR 0x1
@ -253,6 +265,24 @@ grub_size_t
grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
struct grub_unicode_glyph *out); struct grub_unicode_glyph *out);
static inline const struct grub_unicode_combining *
grub_unicode_get_comb (const struct grub_unicode_glyph *in)
{
if (in->ncomb == 0)
return NULL;
if (in->ncomb > ARRAY_SIZE (in->combining_inline))
return in->combining_ptr;
return in->combining_inline;
}
static inline void
grub_unicode_destroy_glyph (struct grub_unicode_glyph *glyph)
{
if (glyph->ncomb > ARRAY_SIZE (glyph->combining_inline))
grub_free (glyph->combining_ptr);
glyph->ncomb = 0;
}
static inline struct grub_unicode_glyph * static inline struct grub_unicode_glyph *
grub_unicode_glyph_dup (const struct grub_unicode_glyph *in) grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
{ {
@ -260,17 +290,20 @@ grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
if (!out) if (!out)
return NULL; return NULL;
grub_memcpy (out, in, sizeof (*in)); grub_memcpy (out, in, sizeof (*in));
if (in->combining) if (in->ncomb > ARRAY_SIZE (out->combining_inline))
{ {
out->combining = grub_malloc (in->ncomb * sizeof (out->combining[0])); out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0]));
if (!out->combining) if (!out->combining_ptr)
{ {
grub_free (out); grub_free (out);
return NULL; return NULL;
} }
grub_memcpy (out->combining, in->combining, grub_memcpy (out->combining_ptr, in->combining_ptr,
in->ncomb * sizeof (out->combining[0])); in->ncomb * sizeof (out->combining_ptr[0]));
} }
else
grub_memcpy (&out->combining_inline, &in->combining_inline,
sizeof (out->combining_inline));
return out; return out;
} }
@ -279,14 +312,17 @@ grub_unicode_set_glyph (struct grub_unicode_glyph *out,
const struct grub_unicode_glyph *in) const struct grub_unicode_glyph *in)
{ {
grub_memcpy (out, in, sizeof (*in)); grub_memcpy (out, in, sizeof (*in));
if (in->combining) if (in->ncomb > ARRAY_SIZE (out->combining_inline))
{ {
out->combining = grub_malloc (in->ncomb * sizeof (out->combining[0])); out->combining_ptr = grub_malloc (in->ncomb * sizeof (out->combining_ptr[0]));
if (!out->combining) if (!out->combining_ptr)
return; return;
grub_memcpy (out->combining, in->combining, grub_memcpy (out->combining_ptr, in->combining_ptr,
in->ncomb * sizeof (out->combining[0])); in->ncomb * sizeof (out->combining_ptr[0]));
} }
else
grub_memcpy (&out->combining_inline, &in->combining_inline,
sizeof (out->combining_inline));
} }
static inline struct grub_unicode_glyph * static inline struct grub_unicode_glyph *