Fix tab and wide character handling in editor and menu.
* grub-core/normal/charset.c (grub_unicode_aglomerate_comb): Don't agglomerate control characters with combining marks. (bidi_line_wrap): Allow break on tab. (grub_unicode_get_comb_start): New function. * grub-core/normal/menu_entry.c: Restructure to handle wide characters and tab correctly. * grub-core/normal/menu_text.c (print_entry): Replace \n, \r, \b and \e with a space. * grub-core/normal/term.c (print_ucs4_terminal): New argument fixed_tab_size. All users updated. * include/grub/term.h (GRUB_TERM_TAB_WIDTH): New const. (grub_term_getcharwidth): Handle \t. * include/grub/unicode.h (grub_unicode_glyph_dup): Fix allocation and copy.
This commit is contained in:
parent
22e6a774f9
commit
e1bd676b4e
9 changed files with 320 additions and 189 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
2012-03-27 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Fix tab and wide character handling in editor and menu.
|
||||||
|
|
||||||
|
* grub-core/normal/charset.c (grub_unicode_aglomerate_comb): Don't
|
||||||
|
agglomerate control characters with combining marks.
|
||||||
|
(bidi_line_wrap): Allow break on tab.
|
||||||
|
(grub_unicode_get_comb_start): New function.
|
||||||
|
* grub-core/normal/menu_entry.c: Restructure to handle wide characters
|
||||||
|
and tab correctly.
|
||||||
|
* grub-core/normal/menu_text.c (print_entry): Replace \n, \r, \b and \e
|
||||||
|
with a space.
|
||||||
|
* grub-core/normal/term.c (print_ucs4_terminal): New argument
|
||||||
|
fixed_tab_size. All users updated.
|
||||||
|
* include/grub/term.h (GRUB_TERM_TAB_WIDTH): New const.
|
||||||
|
(grub_term_getcharwidth): Handle \t.
|
||||||
|
* include/grub/unicode.h (grub_unicode_glyph_dup): Fix allocation
|
||||||
|
and copy.
|
||||||
|
|
||||||
2012-03-26 Vladimir Serbinenko <phcoder@gmail.com>
|
2012-03-26 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
Handle big-endian mdraid.
|
Handle big-endian mdraid.
|
||||||
|
|
|
@ -50,7 +50,8 @@ grub_putcode_dumb (grub_uint32_t code,
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = 8 - ((term->getxy (term) >> 8) & 7);
|
n = GRUB_TERM_TAB_WIDTH - ((term->getxy (term) >> 8)
|
||||||
|
% GRUB_TERM_TAB_WIDTH);
|
||||||
while (n--)
|
while (n--)
|
||||||
grub_putcode_dumb (' ', term);
|
grub_putcode_dumb (' ', term);
|
||||||
|
|
||||||
|
|
|
@ -418,6 +418,17 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
||||||
|
|
||||||
grub_memset (out, 0, sizeof (*out));
|
grub_memset (out, 0, sizeof (*out));
|
||||||
|
|
||||||
|
if (inlen && grub_iscntrl (*in))
|
||||||
|
{
|
||||||
|
out->base = *in;
|
||||||
|
out->variant = 0;
|
||||||
|
out->attributes = 0;
|
||||||
|
out->ncomb = 0;
|
||||||
|
out->estimated_width = 1;
|
||||||
|
out->combining = NULL;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
for (ptr = in; ptr < in + inlen; ptr++)
|
for (ptr = in; ptr < in + inlen; ptr++)
|
||||||
{
|
{
|
||||||
/* Variation selectors >= 17 are outside of BMP and SMP.
|
/* Variation selectors >= 17 are outside of BMP and SMP.
|
||||||
|
@ -429,7 +440,6 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
||||||
if (haveout)
|
if (haveout)
|
||||||
out->variant = *ptr - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1;
|
out->variant = *ptr - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17
|
if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17
|
||||||
&& *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256)
|
&& *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256)
|
||||||
|
@ -528,7 +538,8 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
|
||||||
if (getcharwidth && k != visual_len)
|
if (getcharwidth && k != visual_len)
|
||||||
line_width += last_width = getcharwidth (&visual[k]);
|
line_width += last_width = getcharwidth (&visual[k]);
|
||||||
|
|
||||||
if (k != visual_len && visual[k].base == ' ')
|
if (k != visual_len && (visual[k].base == ' '
|
||||||
|
|| visual[k].base == '\t'))
|
||||||
{
|
{
|
||||||
last_space = k;
|
last_space = k;
|
||||||
last_space_width = line_width;
|
last_space_width = line_width;
|
||||||
|
@ -1142,3 +1153,28 @@ grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr)
|
||||||
|
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const grub_uint32_t *
|
||||||
|
grub_unicode_get_comb_start (const grub_uint32_t *str,
|
||||||
|
const grub_uint32_t *cur)
|
||||||
|
{
|
||||||
|
const grub_uint32_t *ptr;
|
||||||
|
for (ptr = cur; ptr >= str; ptr--)
|
||||||
|
{
|
||||||
|
if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_1
|
||||||
|
&& *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_16)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (*ptr >= GRUB_UNICODE_VARIATION_SELECTOR_17
|
||||||
|
&& *ptr <= GRUB_UNICODE_VARIATION_SELECTOR_256)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
enum grub_comb_type comb_type;
|
||||||
|
comb_type = grub_unicode_get_comb_type (*ptr);
|
||||||
|
if (comb_type)
|
||||||
|
continue;
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ enum update_mode
|
||||||
struct line
|
struct line
|
||||||
{
|
{
|
||||||
/* The line buffer. */
|
/* The line buffer. */
|
||||||
char *buf;
|
grub_uint32_t *buf;
|
||||||
/* The length of the line. */
|
/* The length of the line. */
|
||||||
int len;
|
int len;
|
||||||
/* The maximum length of the line. */
|
/* The maximum length of the line. */
|
||||||
|
@ -52,6 +52,7 @@ struct per_term_screen
|
||||||
int x;
|
int x;
|
||||||
/* The Y coordinate. */
|
/* The Y coordinate. */
|
||||||
int y;
|
int y;
|
||||||
|
int y_line_start;
|
||||||
/* Number of entries. */
|
/* Number of entries. */
|
||||||
int num_entries;
|
int num_entries;
|
||||||
};
|
};
|
||||||
|
@ -80,7 +81,11 @@ struct screen
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used for storing completion items temporarily. */
|
/* Used for storing completion items temporarily. */
|
||||||
static struct line completion_buffer;
|
static struct {
|
||||||
|
char *buf;
|
||||||
|
grub_size_t len;
|
||||||
|
grub_size_t max_len;
|
||||||
|
} completion_buffer;
|
||||||
static int completion_type;
|
static int completion_type;
|
||||||
|
|
||||||
/* Initialize a line. */
|
/* Initialize a line. */
|
||||||
|
@ -88,8 +93,8 @@ static int
|
||||||
init_line (struct line *linep)
|
init_line (struct line *linep)
|
||||||
{
|
{
|
||||||
linep->len = 0;
|
linep->len = 0;
|
||||||
linep->max_len = 80; /* XXX */
|
linep->max_len = 80;
|
||||||
linep->buf = grub_malloc (linep->max_len + 1);
|
linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0]));
|
||||||
if (! linep->buf)
|
if (! linep->buf)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -102,8 +107,8 @@ ensure_space (struct line *linep, int extra)
|
||||||
{
|
{
|
||||||
if (linep->max_len < linep->len + extra)
|
if (linep->max_len < linep->len + extra)
|
||||||
{
|
{
|
||||||
linep->max_len = linep->len + extra + 80; /* XXX */
|
linep->max_len = 2 * (linep->len + extra);
|
||||||
linep->buf = grub_realloc (linep->buf, linep->max_len + 1);
|
linep->buf = grub_realloc (linep->buf, (linep->max_len + 1) * sizeof (linep->buf[0]));
|
||||||
if (! linep->buf)
|
if (! linep->buf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -115,44 +120,99 @@ ensure_space (struct line *linep, int extra)
|
||||||
static int
|
static int
|
||||||
get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
|
get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
|
||||||
{
|
{
|
||||||
return (linep->len / grub_term_entry_width (term_screen->term)) + 1;
|
return (grub_getstringwidth (linep->buf, linep->buf + linep->len,
|
||||||
|
term_screen->term)
|
||||||
|
/ grub_term_entry_width (term_screen->term)) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
advance (struct screen *screen)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
struct grub_unicode_glyph glyph;
|
||||||
|
|
||||||
|
screen->column += grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column,
|
||||||
|
screen->lines[screen->line].len - screen->column,
|
||||||
|
&glyph);
|
||||||
|
|
||||||
|
for (i = 0; i < screen->nterms; i++)
|
||||||
|
{
|
||||||
|
grub_ssize_t width;
|
||||||
|
width = grub_term_getcharwidth (screen->terms[i].term, &glyph);
|
||||||
|
screen->terms[i].x += width;
|
||||||
|
if (screen->terms[i].x
|
||||||
|
== grub_term_entry_width (screen->terms[i].term))
|
||||||
|
{
|
||||||
|
screen->terms[i].x = 0;
|
||||||
|
screen->terms[i].y++;
|
||||||
|
}
|
||||||
|
if (screen->terms[i].x
|
||||||
|
> grub_term_entry_width (screen->terms[i].term))
|
||||||
|
{
|
||||||
|
screen->terms[i].x = width;
|
||||||
|
screen->terms[i].y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
grub_free (glyph.combining);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
advance_to (struct screen *screen, int c)
|
||||||
|
{
|
||||||
|
if (c > screen->lines[screen->line].len)
|
||||||
|
c = screen->lines[screen->line].len;
|
||||||
|
|
||||||
|
while (screen->column < c)
|
||||||
|
advance (screen);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print a line. */
|
/* Print a line. */
|
||||||
static void
|
static int
|
||||||
print_line (struct line *linep, int offset, int start, int y,
|
print_line (struct line *linep, int offset, int y,
|
||||||
struct per_term_screen *term_screen)
|
struct per_term_screen *term_screen, int dry_run)
|
||||||
{
|
{
|
||||||
|
int x;
|
||||||
|
int i;
|
||||||
|
|
||||||
grub_term_gotoxy (term_screen->term,
|
grub_term_gotoxy (term_screen->term,
|
||||||
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
|
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
|
||||||
y + GRUB_TERM_FIRST_ENTRY_Y);
|
y + GRUB_TERM_FIRST_ENTRY_Y);
|
||||||
|
|
||||||
|
x = 0;
|
||||||
|
for (i = 0; i + offset < (int) linep->len;)
|
||||||
|
{
|
||||||
|
grub_ssize_t width;
|
||||||
|
grub_size_t delta = 0;
|
||||||
|
struct grub_unicode_glyph glyph;
|
||||||
|
|
||||||
if (linep->len >= offset + grub_term_entry_width (term_screen->term))
|
delta = grub_unicode_aglomerate_comb (linep->buf + offset + i,
|
||||||
{
|
linep->len - offset - i,
|
||||||
char *p, c;
|
&glyph);
|
||||||
p = linep->buf + offset + grub_term_entry_width (term_screen->term);
|
width = grub_term_getcharwidth (term_screen->term, &glyph);
|
||||||
c = *p;
|
grub_free (glyph.combining);
|
||||||
*p = 0;
|
|
||||||
grub_puts_terminal (linep->buf + offset + start, term_screen->term);
|
|
||||||
*p = c;
|
|
||||||
grub_putcode ('\\', term_screen->term);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
char *p, c;
|
|
||||||
|
|
||||||
p = linep->buf + linep->len;
|
if (x + width > grub_term_entry_width (term_screen->term) && x != 0)
|
||||||
c = *p;
|
break;
|
||||||
*p = 0;
|
x += width;
|
||||||
grub_puts_terminal (linep->buf + offset + start, term_screen->term);
|
i += delta;
|
||||||
*p = c;
|
}
|
||||||
|
|
||||||
for (i = 0;
|
if (dry_run)
|
||||||
i <= grub_term_entry_width (term_screen->term) - linep->len + offset;
|
return i;
|
||||||
i++)
|
|
||||||
grub_putcode (' ', term_screen->term);
|
grub_print_ucs4 (linep->buf + offset,
|
||||||
}
|
linep->buf + offset + i, 0, 0, term_screen->term);
|
||||||
|
|
||||||
|
if (i + offset != linep->len)
|
||||||
|
grub_putcode ('\\', term_screen->term);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (;
|
||||||
|
x < (int) grub_term_entry_width (term_screen->term);
|
||||||
|
x++)
|
||||||
|
grub_putcode (' ', term_screen->term);
|
||||||
|
}
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print an empty line. */
|
/* Print an empty line. */
|
||||||
|
@ -213,10 +273,13 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
/* Check if scrolling is necessary. */
|
/* Check if scrolling is necessary. */
|
||||||
if (term_screen->y < 0 || term_screen->y >= term_screen->num_entries)
|
if (term_screen->y < 0 || term_screen->y >= term_screen->num_entries)
|
||||||
{
|
{
|
||||||
|
int delta;
|
||||||
if (term_screen->y < 0)
|
if (term_screen->y < 0)
|
||||||
term_screen->y = 0;
|
delta = -term_screen->y;
|
||||||
else
|
else
|
||||||
term_screen->y = term_screen->num_entries - 1;
|
delta = term_screen->num_entries - 1 - term_screen->y;
|
||||||
|
term_screen->y += delta;
|
||||||
|
term_screen->y_line_start += delta;
|
||||||
|
|
||||||
region_start = 0;
|
region_start = 0;
|
||||||
region_column = 0;
|
region_column = 0;
|
||||||
|
@ -229,8 +292,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
{
|
{
|
||||||
/* Draw lines. This code is tricky, because this must calculate logical
|
/* Draw lines. This code is tricky, because this must calculate logical
|
||||||
positions. */
|
positions. */
|
||||||
y = term_screen->y - screen->column
|
y = term_screen->y_line_start;
|
||||||
/ grub_term_entry_width (term_screen->term);
|
|
||||||
i = screen->line;
|
i = screen->line;
|
||||||
linep = screen->lines + i;
|
linep = screen->lines + i;
|
||||||
while (y > 0)
|
while (y > 0)
|
||||||
|
@ -246,6 +308,7 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int column;
|
int column;
|
||||||
|
int off = 0;
|
||||||
|
|
||||||
if (linep >= screen->lines + screen->num_lines)
|
if (linep >= screen->lines + screen->num_lines)
|
||||||
break;
|
break;
|
||||||
|
@ -256,7 +319,10 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
column += grub_term_entry_width (term_screen->term), y++)
|
column += grub_term_entry_width (term_screen->term), y++)
|
||||||
{
|
{
|
||||||
if (y < 0)
|
if (y < 0)
|
||||||
continue;
|
{
|
||||||
|
off += print_line (linep, off, y, term_screen, 1);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (i == region_start)
|
if (i == region_start)
|
||||||
{
|
{
|
||||||
|
@ -264,18 +330,19 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
&& region_column
|
&& region_column
|
||||||
< (column
|
< (column
|
||||||
+ grub_term_entry_width (term_screen->term)))
|
+ grub_term_entry_width (term_screen->term)))
|
||||||
print_line (linep, column, region_column - column, y,
|
off += print_line (linep, off, y, term_screen, 0);
|
||||||
term_screen);
|
|
||||||
else if (region_column < column)
|
else if (region_column < column)
|
||||||
print_line (linep, column, 0, y, term_screen);
|
off += print_line (linep, off, y, term_screen, 0);
|
||||||
|
else
|
||||||
|
off += print_line (linep, off, y, term_screen, 1);
|
||||||
}
|
}
|
||||||
else if (i > region_start && mode == ALL_LINES)
|
else if (i > region_start && mode == ALL_LINES)
|
||||||
print_line (linep, column, 0, y, term_screen);
|
off += print_line (linep, off, y, term_screen, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (y == term_screen->num_entries)
|
if (y == term_screen->num_entries)
|
||||||
{
|
{
|
||||||
if (column <= linep->len || i + 1 < screen->num_lines)
|
if (off <= linep->len || i + 1 < screen->num_lines)
|
||||||
down_flag = 1;
|
down_flag = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,7 +352,6 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
if (mode == ALL_LINES && i == screen->num_lines)
|
if (mode == ALL_LINES && i == screen->num_lines)
|
||||||
for (; y < term_screen->num_entries; y++)
|
for (; y < term_screen->num_entries; y++)
|
||||||
print_empty_line (y, term_screen);
|
print_empty_line (y, term_screen);
|
||||||
|
|
||||||
}
|
}
|
||||||
while (y < term_screen->num_entries);
|
while (y < term_screen->num_entries);
|
||||||
|
|
||||||
|
@ -367,7 +433,7 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
|
|
||||||
grub_memmove (next_linep->buf,
|
grub_memmove (next_linep->buf,
|
||||||
current_linep->buf + screen->column,
|
current_linep->buf + screen->column,
|
||||||
size);
|
size * sizeof (next_linep->buf[0]));
|
||||||
current_linep->len = screen->column;
|
current_linep->len = screen->column;
|
||||||
next_linep->len = size;
|
next_linep->len = size;
|
||||||
|
|
||||||
|
@ -391,6 +457,7 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
{
|
{
|
||||||
screen->terms[i].x = 0;
|
screen->terms[i].x = 0;
|
||||||
screen->terms[i].y++;
|
screen->terms[i].y++;
|
||||||
|
screen->terms[i].y_line_start = screen->terms[i].y;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
@ -401,6 +468,7 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
struct line *current_linep;
|
struct line *current_linep;
|
||||||
int size;
|
int size;
|
||||||
int orig_num[screen->nterms], new_num[screen->nterms];
|
int orig_num[screen->nterms], new_num[screen->nterms];
|
||||||
|
grub_uint32_t *unicode_msg;
|
||||||
|
|
||||||
/* Find a string delimited by LF. */
|
/* Find a string delimited by LF. */
|
||||||
p = grub_strchr (s, '\n');
|
p = grub_strchr (s, '\n');
|
||||||
|
@ -409,16 +477,26 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
|
|
||||||
/* Insert the string. */
|
/* Insert the string. */
|
||||||
current_linep = screen->lines + screen->line;
|
current_linep = screen->lines + screen->line;
|
||||||
size = p - s;
|
unicode_msg = grub_malloc ((p - s) * sizeof (grub_uint32_t));
|
||||||
|
|
||||||
|
if (!unicode_msg)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
size = grub_utf8_to_ucs4 (unicode_msg, (p - s),
|
||||||
|
(grub_uint8_t *) s, (p - s), 0);
|
||||||
|
|
||||||
if (! ensure_space (current_linep, size))
|
if (! ensure_space (current_linep, size))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
grub_memmove (current_linep->buf + screen->column + size,
|
grub_memmove (current_linep->buf + screen->column + size,
|
||||||
current_linep->buf + screen->column,
|
current_linep->buf + screen->column,
|
||||||
current_linep->len - screen->column);
|
(current_linep->len - screen->column)
|
||||||
|
* sizeof (current_linep->buf[0]));
|
||||||
grub_memmove (current_linep->buf + screen->column,
|
grub_memmove (current_linep->buf + screen->column,
|
||||||
s,
|
unicode_msg,
|
||||||
size);
|
size * sizeof (current_linep->buf[0]));
|
||||||
|
grub_free (unicode_msg);
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
orig_num[i] = get_logical_num_lines (current_linep,
|
orig_num[i] = get_logical_num_lines (current_linep,
|
||||||
&screen->terms[i]);
|
&screen->terms[i]);
|
||||||
|
@ -444,16 +522,9 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
mode[i] = SINGLE_LINE;
|
mode[i] = SINGLE_LINE;
|
||||||
|
|
||||||
/* Move the cursor. */
|
/* Move the cursor. */
|
||||||
screen->column += size;
|
advance_to (screen, screen->column + size);
|
||||||
|
|
||||||
screen->real_column = screen->column;
|
screen->real_column = screen->column;
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].x += size;
|
|
||||||
screen->terms[i].y += screen->terms[i].x
|
|
||||||
/ grub_term_entry_width (screen->terms[i].term);
|
|
||||||
screen->terms[i].x
|
|
||||||
%= grub_term_entry_width (screen->terms[i].term);
|
|
||||||
}
|
|
||||||
s = p;
|
s = p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -520,6 +591,7 @@ make_screen (grub_menu_entry_t entry)
|
||||||
{
|
{
|
||||||
screen->terms[i].x = 0;
|
screen->terms[i].x = 0;
|
||||||
screen->terms[i].y = 0;
|
screen->terms[i].y = 0;
|
||||||
|
screen->terms[i].y_line_start = screen->terms[i].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
return screen;
|
return screen;
|
||||||
|
@ -537,19 +609,7 @@ forward_char (struct screen *screen, int update)
|
||||||
|
|
||||||
linep = screen->lines + screen->line;
|
linep = screen->lines + screen->line;
|
||||||
if (screen->column < linep->len)
|
if (screen->column < linep->len)
|
||||||
{
|
advance (screen);
|
||||||
screen->column++;
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].x++;
|
|
||||||
if (screen->terms[i].x
|
|
||||||
== grub_term_entry_width (screen->terms[i].term))
|
|
||||||
{
|
|
||||||
screen->terms[i].x = 0;
|
|
||||||
screen->terms[i].y++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (screen->num_lines > screen->line + 1)
|
else if (screen->num_lines > screen->line + 1)
|
||||||
{
|
{
|
||||||
screen->column = 0;
|
screen->column = 0;
|
||||||
|
@ -558,6 +618,7 @@ forward_char (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
screen->terms[i].x = 0;
|
screen->terms[i].x = 0;
|
||||||
screen->terms[i].y++;
|
screen->terms[i].y++;
|
||||||
|
screen->terms[i].y_line_start = screen->terms[i].y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,31 +636,49 @@ backward_char (struct screen *screen, int update)
|
||||||
|
|
||||||
if (screen->column > 0)
|
if (screen->column > 0)
|
||||||
{
|
{
|
||||||
|
struct grub_unicode_glyph glyph;
|
||||||
|
struct line *linep;
|
||||||
|
|
||||||
|
linep = screen->lines + screen->line;
|
||||||
|
|
||||||
screen->column--;
|
screen->column--;
|
||||||
|
screen->column = grub_unicode_get_comb_start (linep->buf,
|
||||||
|
linep->buf + screen->column)
|
||||||
|
- linep->buf;
|
||||||
|
|
||||||
|
grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column,
|
||||||
|
screen->lines[screen->line].len - screen->column,
|
||||||
|
&glyph);
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
{
|
{
|
||||||
screen->terms[i].x--;
|
grub_ssize_t width;
|
||||||
if (screen->terms[i].x == -1)
|
width = grub_term_getcharwidth (screen->terms[i].term, &glyph);
|
||||||
|
screen->terms[i].x -= width;
|
||||||
|
if (screen->terms[i].x < 0)
|
||||||
{
|
{
|
||||||
screen->terms[i].x
|
screen->terms[i].x
|
||||||
= grub_term_entry_width (screen->terms[i].term) - 1;
|
= grub_term_entry_width (screen->terms[i].term) - 1;
|
||||||
screen->terms[i].y--;
|
screen->terms[i].y--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
grub_free (glyph.combining);
|
||||||
}
|
}
|
||||||
else if (screen->line > 0)
|
else if (screen->line > 0)
|
||||||
{
|
{
|
||||||
struct line *linep;
|
struct line *linep;
|
||||||
|
|
||||||
screen->line--;
|
|
||||||
linep = screen->lines + screen->line;
|
linep = screen->lines + screen->line;
|
||||||
screen->column = linep->len;
|
screen->column = 0;
|
||||||
|
screen->line--;
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
{
|
{
|
||||||
screen->terms[i].x = screen->column
|
screen->terms[i].y_line_start -= get_logical_num_lines (linep, &screen->terms[i]);
|
||||||
% grub_term_entry_width (screen->terms[i].term);
|
screen->terms[i].y = screen->terms[i].y_line_start;
|
||||||
screen->terms[i].y--;
|
screen->terms[i].x = 0;
|
||||||
}
|
}
|
||||||
|
advance_to (screen, screen->lines[screen->line].len);
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->real_column = screen->column;
|
screen->real_column = screen->column;
|
||||||
|
@ -620,40 +699,29 @@ previous_line (struct screen *screen, int update)
|
||||||
struct line *linep;
|
struct line *linep;
|
||||||
int col;
|
int col;
|
||||||
|
|
||||||
/* How many physical lines from the current position
|
|
||||||
to the first physical line? */
|
|
||||||
col = screen->column;
|
|
||||||
|
|
||||||
screen->line--;
|
screen->line--;
|
||||||
|
|
||||||
linep = screen->lines + screen->line;
|
linep = screen->lines + screen->line;
|
||||||
if (linep->len < screen->real_column)
|
if (linep->len < screen->real_column)
|
||||||
screen->column = linep->len;
|
col = linep->len;
|
||||||
else
|
else
|
||||||
screen->column = screen->real_column;
|
col = screen->real_column;
|
||||||
|
|
||||||
|
screen->column = 0;
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
{
|
{
|
||||||
int dy;
|
screen->terms[i].y_line_start -= get_logical_num_lines (linep, &screen->terms[i]);
|
||||||
dy = col / grub_term_entry_width (screen->terms[i].term);
|
screen->terms[i].y = screen->terms[i].y_line_start;
|
||||||
|
screen->terms[i].x = 0;
|
||||||
/* How many physical lines from the current position
|
}
|
||||||
to the last physical line? */
|
advance_to (screen, col);
|
||||||
dy += (linep->len / grub_term_entry_width (screen->terms[i].term)
|
|
||||||
- screen->column
|
|
||||||
/ grub_term_entry_width (screen->terms[i].term));
|
|
||||||
|
|
||||||
screen->terms[i].y -= dy + 1;
|
|
||||||
screen->terms[i].x
|
|
||||||
= screen->column % grub_term_entry_width (screen->terms[i].term);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
{
|
{
|
||||||
screen->terms[i].y
|
screen->terms[i].y = screen->terms[i].y_line_start;
|
||||||
-= screen->column / grub_term_entry_width (screen->terms[i].term);
|
|
||||||
screen->terms[i].x = 0;
|
screen->terms[i].x = 0;
|
||||||
}
|
}
|
||||||
screen->column = 0;
|
screen->column = 0;
|
||||||
|
@ -673,53 +741,29 @@ next_line (struct screen *screen, int update)
|
||||||
if (screen->line < screen->num_lines - 1)
|
if (screen->line < screen->num_lines - 1)
|
||||||
{
|
{
|
||||||
struct line *linep;
|
struct line *linep;
|
||||||
int l1, c1;
|
int c;
|
||||||
|
|
||||||
/* How many physical lines from the current position
|
/* How many physical lines from the current position
|
||||||
to the last physical line? */
|
to the last physical line? */
|
||||||
linep = screen->lines + screen->line;
|
linep = screen->lines + screen->line;
|
||||||
l1 = linep->len;
|
|
||||||
c1 = screen->column;
|
|
||||||
|
|
||||||
screen->line++;
|
screen->line++;
|
||||||
|
if ((linep + 1)->len < screen->real_column)
|
||||||
linep++;
|
c = (linep + 1)->len;
|
||||||
if (linep->len < screen->real_column)
|
|
||||||
screen->column = linep->len;
|
|
||||||
else
|
else
|
||||||
screen->column = screen->real_column;
|
c = screen->real_column;
|
||||||
|
screen->column = 0;
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
{
|
{
|
||||||
int dy;
|
screen->terms[i].y_line_start += get_logical_num_lines (linep, &screen->terms[i]);
|
||||||
dy = l1 / grub_term_entry_width (screen->terms[i].term)
|
screen->terms[i].x = 0;
|
||||||
- c1 / grub_term_entry_width (screen->terms[i].term);
|
screen->terms[i].y = screen->terms[i].y_line_start;
|
||||||
/* How many physical lines from the current position
|
|
||||||
to the first physical line? */
|
|
||||||
dy += screen->column / grub_term_entry_width (screen->terms[i].term);
|
|
||||||
screen->terms[i].y += dy + 1;
|
|
||||||
screen->terms[i].x = screen->column
|
|
||||||
% grub_term_entry_width (screen->terms[i].term);
|
|
||||||
}
|
}
|
||||||
|
advance_to (screen, c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
advance_to (screen, screen->lines[screen->line].len);
|
||||||
struct line *linep;
|
|
||||||
int l, s;
|
|
||||||
|
|
||||||
linep = screen->lines + screen->line;
|
|
||||||
l = linep->len;
|
|
||||||
s = screen->column;
|
|
||||||
screen->column = linep->len;
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].y
|
|
||||||
+= (l / grub_term_entry_width (screen->terms[i].term)
|
|
||||||
- s / grub_term_entry_width (screen->terms[i].term));
|
|
||||||
screen->terms[i].x
|
|
||||||
= screen->column % grub_term_entry_width (screen->terms[i].term);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
|
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
|
||||||
|
@ -731,14 +775,12 @@ static int
|
||||||
beginning_of_line (struct screen *screen, int update)
|
beginning_of_line (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
unsigned i;
|
unsigned i;
|
||||||
int col;
|
|
||||||
|
|
||||||
col = screen->column;
|
|
||||||
screen->column = screen->real_column = 0;
|
screen->column = screen->real_column = 0;
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
{
|
{
|
||||||
screen->terms[i].x = 0;
|
screen->terms[i].x = 0;
|
||||||
screen->terms[i].y -= col / grub_term_entry_width (screen->terms[i].term);
|
screen->terms[i].y = screen->terms[i].y_line_start;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
|
@ -750,21 +792,7 @@ beginning_of_line (struct screen *screen, int update)
|
||||||
static int
|
static int
|
||||||
end_of_line (struct screen *screen, int update)
|
end_of_line (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
struct line *linep;
|
advance_to (screen, screen->lines[screen->line].len);
|
||||||
unsigned i;
|
|
||||||
int col;
|
|
||||||
|
|
||||||
linep = screen->lines + screen->line;
|
|
||||||
col = screen->column;
|
|
||||||
screen->column = screen->real_column = linep->len;
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].y
|
|
||||||
+= (linep->len / grub_term_entry_width (screen->terms->term)
|
|
||||||
- col / grub_term_entry_width (screen->terms->term));
|
|
||||||
screen->terms[i].x
|
|
||||||
= screen->column % grub_term_entry_width (screen->terms->term);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
|
update_screen_all (screen, screen->num_lines, 0, 0, 0, NO_LINE);
|
||||||
|
@ -790,7 +818,8 @@ delete_char (struct screen *screen, int update)
|
||||||
|
|
||||||
grub_memmove (linep->buf + screen->column,
|
grub_memmove (linep->buf + screen->column,
|
||||||
linep->buf + screen->column + 1,
|
linep->buf + screen->column + 1,
|
||||||
linep->len - screen->column - 1);
|
(linep->len - screen->column - 1)
|
||||||
|
* sizeof (linep->buf[0]));
|
||||||
linep->len--;
|
linep->len--;
|
||||||
|
|
||||||
start = screen->line;
|
start = screen->line;
|
||||||
|
@ -820,7 +849,8 @@ delete_char (struct screen *screen, int update)
|
||||||
if (! ensure_space (linep, next_linep->len))
|
if (! ensure_space (linep, next_linep->len))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
grub_memmove (linep->buf + linep->len, next_linep->buf, next_linep->len);
|
grub_memmove (linep->buf + linep->len, next_linep->buf,
|
||||||
|
next_linep->len * sizeof (linep->buf[0]));
|
||||||
linep->len += next_linep->len;
|
linep->len += next_linep->len;
|
||||||
|
|
||||||
grub_free (next_linep->buf);
|
grub_free (next_linep->buf);
|
||||||
|
@ -954,7 +984,10 @@ open_line (struct screen *screen, int update)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
screen->terms[i].y = saved_y[i];
|
{
|
||||||
|
screen->terms[i].y = saved_y[i];
|
||||||
|
screen->terms[i].y_line_start = screen->terms[i].y;
|
||||||
|
}
|
||||||
|
|
||||||
if (update)
|
if (update)
|
||||||
update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);
|
update_screen_all (screen, screen->line, screen->column, 0, 1, ALL_LINES);
|
||||||
|
@ -1003,7 +1036,6 @@ store_completion (const char *item, grub_completion_type_t type,
|
||||||
static int
|
static int
|
||||||
complete (struct screen *screen, int continuous, int update)
|
complete (struct screen *screen, int continuous, int update)
|
||||||
{
|
{
|
||||||
char saved_char;
|
|
||||||
struct line *linep;
|
struct line *linep;
|
||||||
int restore;
|
int restore;
|
||||||
char *insert;
|
char *insert;
|
||||||
|
@ -1012,6 +1044,7 @@ complete (struct screen *screen, int continuous, int update)
|
||||||
grub_uint32_t *ucs4;
|
grub_uint32_t *ucs4;
|
||||||
grub_size_t buflen;
|
grub_size_t buflen;
|
||||||
grub_ssize_t ucs4len;
|
grub_ssize_t ucs4len;
|
||||||
|
char *u8;
|
||||||
|
|
||||||
if (continuous)
|
if (continuous)
|
||||||
count++;
|
count++;
|
||||||
|
@ -1023,12 +1056,11 @@ complete (struct screen *screen, int continuous, int update)
|
||||||
completion_buffer.max_len = 0;
|
completion_buffer.max_len = 0;
|
||||||
|
|
||||||
linep = screen->lines + screen->line;
|
linep = screen->lines + screen->line;
|
||||||
saved_char = linep->buf[screen->column];
|
u8 = grub_ucs4_to_utf8_alloc (linep->buf, screen->column);
|
||||||
linep->buf[screen->column] = '\0';
|
if (!u8)
|
||||||
|
return 1;
|
||||||
|
|
||||||
insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
|
insert = grub_normal_do_completion (u8, &restore, store_completion);
|
||||||
|
|
||||||
linep->buf[screen->column] = saved_char;
|
|
||||||
|
|
||||||
if (completion_buffer.buf)
|
if (completion_buffer.buf)
|
||||||
{
|
{
|
||||||
|
@ -1287,6 +1319,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||||
screen->terms[i].term = term;
|
screen->terms[i].term = term;
|
||||||
screen->terms[i].x = 0;
|
screen->terms[i].x = 0;
|
||||||
screen->terms[i].y = 0;
|
screen->terms[i].y = 0;
|
||||||
|
screen->terms[i].y_line_start = screen->terms[i].y;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
/* Draw the screen. */
|
/* Draw the screen. */
|
||||||
|
|
|
@ -234,6 +234,12 @@ print_entry (int y, int highlight, grub_menu_entry_t entry,
|
||||||
grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
|
grub_term_gotoxy (term, GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN, y);
|
||||||
|
|
||||||
int last_printed = 0;
|
int last_printed = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
if (unicode_title[i] == '\n' || unicode_title[i] == '\b'
|
||||||
|
|| unicode_title[i] == '\r' || unicode_title[i] == '\e')
|
||||||
|
unicode_title[i] = ' ';
|
||||||
|
|
||||||
for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0;
|
for (x = GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1, i = 0;
|
||||||
x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
|
x < (int) (GRUB_TERM_LEFT_BORDER_X + grub_term_border_width (term)
|
||||||
- GRUB_TERM_MARGIN);)
|
- GRUB_TERM_MARGIN);)
|
||||||
|
|
|
@ -31,6 +31,7 @@ struct term_state
|
||||||
struct term_state *next;
|
struct term_state *next;
|
||||||
const struct grub_unicode_glyph *backlog_glyphs;
|
const struct grub_unicode_glyph *backlog_glyphs;
|
||||||
const grub_uint32_t *backlog_ucs4;
|
const grub_uint32_t *backlog_ucs4;
|
||||||
|
int backlog_fixed_tab;
|
||||||
grub_size_t backlog_len;
|
grub_size_t backlog_len;
|
||||||
|
|
||||||
void *free;
|
void *free;
|
||||||
|
@ -38,13 +39,20 @@ struct term_state
|
||||||
char *term_name;
|
char *term_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
print_ucs4_real (const grub_uint32_t * str,
|
||||||
|
const grub_uint32_t * last_position,
|
||||||
|
int margin_left, int margin_right,
|
||||||
|
struct grub_term_output *term, int backlog,
|
||||||
|
int dry_run, int fixed_tab);
|
||||||
|
|
||||||
static struct term_state *term_states = NULL;
|
static struct term_state *term_states = NULL;
|
||||||
|
|
||||||
/* If the more pager is active. */
|
/* If the more pager is active. */
|
||||||
static int grub_more;
|
static int grub_more;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
putcode_real (grub_uint32_t code, struct grub_term_output *term);
|
putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab);
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_normal_reset_more (void)
|
grub_normal_reset_more (void)
|
||||||
|
@ -235,7 +243,7 @@ grub_puts_terminal (const char *str, struct grub_term_output *term)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
|
print_ucs4_real (unicode_str, unicode_last_position, 0, 0, term, 0, 0, 0);
|
||||||
grub_free (unicode_str);
|
grub_free (unicode_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +406,8 @@ read_terminal_list (const char *prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
|
putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term,
|
||||||
|
int fixed_tab)
|
||||||
{
|
{
|
||||||
struct grub_unicode_glyph c2 =
|
struct grub_unicode_glyph c2 =
|
||||||
{
|
{
|
||||||
|
@ -409,11 +418,24 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
|
||||||
.estimated_width = 1
|
.estimated_width = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (c->base == '\t' && fixed_tab)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = GRUB_TERM_TAB_WIDTH;
|
||||||
|
c2.base = ' ';
|
||||||
|
while (n--)
|
||||||
|
(term->putchar) (term, &c2);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (c->base == '\t' && term->getxy)
|
if (c->base == '\t' && term->getxy)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
n = 8 - ((term->getxy (term) >> 8) & 7);
|
n = GRUB_TERM_TAB_WIDTH - ((term->getxy (term) >> 8)
|
||||||
|
% GRUB_TERM_TAB_WIDTH);
|
||||||
c2.base = ' ';
|
c2.base = ' ';
|
||||||
while (n--)
|
while (n--)
|
||||||
(term->putchar) (term, &c2);
|
(term->putchar) (term, &c2);
|
||||||
|
@ -469,7 +491,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
putcode_real (grub_uint32_t code, struct grub_term_output *term)
|
putcode_real (grub_uint32_t code, struct grub_term_output *term, int fixed_tab)
|
||||||
{
|
{
|
||||||
struct grub_unicode_glyph c =
|
struct grub_unicode_glyph c =
|
||||||
{
|
{
|
||||||
|
@ -481,7 +503,7 @@ putcode_real (grub_uint32_t code, struct grub_term_output *term)
|
||||||
};
|
};
|
||||||
|
|
||||||
c.base = map_code (code, term);
|
c.base = map_code (code, term);
|
||||||
putglyph (&c, term);
|
putglyph (&c, term, fixed_tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put a Unicode character. */
|
/* Put a Unicode character. */
|
||||||
|
@ -492,7 +514,7 @@ grub_putcode (grub_uint32_t code, struct grub_term_output *term)
|
||||||
if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE)
|
if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
putcode_real (code, term);
|
putcode_real (code, term, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_ssize_t
|
static grub_ssize_t
|
||||||
|
@ -524,7 +546,7 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
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,
|
struct term_state *state,
|
||||||
int dry_run)
|
int dry_run, int fixed_tab)
|
||||||
{
|
{
|
||||||
const grub_uint32_t *ptr;
|
const grub_uint32_t *ptr;
|
||||||
grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left);
|
grub_ssize_t startwidth = dry_run ? 0 : get_startwidth (term, margin_left);
|
||||||
|
@ -582,7 +604,7 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
&& grub_unicode_get_comb_type (*ptr2)
|
&& grub_unicode_get_comb_type (*ptr2)
|
||||||
!= GRUB_UNICODE_COMB_NONE)
|
!= GRUB_UNICODE_COMB_NONE)
|
||||||
continue;
|
continue;
|
||||||
putcode_real (*ptr2, term);
|
putcode_real (*ptr2, term, fixed_tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_print_spaces (term, margin_right);
|
grub_print_spaces (term, margin_right);
|
||||||
|
@ -593,6 +615,7 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
state->backlog_ucs4 = (ptr == last_space || *ptr == '\n')
|
state->backlog_ucs4 = (ptr == last_space || *ptr == '\n')
|
||||||
? ptr + 1 : ptr;
|
? ptr + 1 : ptr;
|
||||||
state->backlog_len = last_position - state->backlog_ucs4;
|
state->backlog_len = last_position - state->backlog_ucs4;
|
||||||
|
state->backlog_fixed_tab = fixed_tab;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -619,7 +642,7 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
&& grub_unicode_get_comb_type (*ptr2)
|
&& grub_unicode_get_comb_type (*ptr2)
|
||||||
!= GRUB_UNICODE_COMB_NONE)
|
!= GRUB_UNICODE_COMB_NONE)
|
||||||
continue;
|
continue;
|
||||||
putcode_real (*ptr2, term);
|
putcode_real (*ptr2, term, fixed_tab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return dry_run ? lines : 0;
|
return dry_run ? lines : 0;
|
||||||
|
@ -652,14 +675,14 @@ put_glyphs_terminal (const 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)
|
struct term_state *state, int fixed_tab)
|
||||||
{
|
{
|
||||||
const struct grub_unicode_glyph *visual_ptr;
|
const struct grub_unicode_glyph *visual_ptr;
|
||||||
for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++)
|
for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++)
|
||||||
{
|
{
|
||||||
if (visual_ptr->base == '\n')
|
if (visual_ptr->base == '\n')
|
||||||
grub_print_spaces (term, margin_right);
|
grub_print_spaces (term, margin_right);
|
||||||
putglyph (visual_ptr, term);
|
putglyph (visual_ptr, term, fixed_tab);
|
||||||
if (visual_ptr->base == '\n')
|
if (visual_ptr->base == '\n')
|
||||||
{
|
{
|
||||||
if (state && ++state->num_lines
|
if (state && ++state->num_lines
|
||||||
|
@ -667,6 +690,7 @@ put_glyphs_terminal (const struct grub_unicode_glyph *visual,
|
||||||
{
|
{
|
||||||
state->backlog_glyphs = visual_ptr + 1;
|
state->backlog_glyphs = visual_ptr + 1;
|
||||||
state->backlog_len = visual_len - (visual_ptr - visual) - 1;
|
state->backlog_len = visual_len - (visual_ptr - visual) - 1;
|
||||||
|
state->backlog_fixed_tab = fixed_tab;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,7 +715,8 @@ print_backlog (struct grub_term_output *term,
|
||||||
int ret;
|
int ret;
|
||||||
ret = print_ucs4_terminal (state->backlog_ucs4,
|
ret = print_ucs4_terminal (state->backlog_ucs4,
|
||||||
state->backlog_ucs4 + state->backlog_len,
|
state->backlog_ucs4 + state->backlog_len,
|
||||||
margin_left, margin_right, term, state, 0);
|
margin_left, margin_right, term, state, 0,
|
||||||
|
state->backlog_fixed_tab);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
grub_free (state->free);
|
grub_free (state->free);
|
||||||
|
@ -707,7 +732,8 @@ print_backlog (struct grub_term_output *term,
|
||||||
int ret;
|
int ret;
|
||||||
ret = put_glyphs_terminal (state->backlog_glyphs,
|
ret = put_glyphs_terminal (state->backlog_glyphs,
|
||||||
state->backlog_len,
|
state->backlog_len,
|
||||||
margin_left, margin_right, term, state);
|
margin_left, margin_right, term, state,
|
||||||
|
state->backlog_fixed_tab);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
grub_free (state->free);
|
grub_free (state->free);
|
||||||
|
@ -726,7 +752,7 @@ print_ucs4_real (const grub_uint32_t * str,
|
||||||
const grub_uint32_t * last_position,
|
const grub_uint32_t * last_position,
|
||||||
int margin_left, int margin_right,
|
int margin_left, int margin_right,
|
||||||
struct grub_term_output *term, int backlog,
|
struct grub_term_output *term, int backlog,
|
||||||
int dry_run)
|
int dry_run, int fixed_tab)
|
||||||
{
|
{
|
||||||
struct term_state *state = NULL;
|
struct term_state *state = NULL;
|
||||||
|
|
||||||
|
@ -780,7 +806,7 @@ print_ucs4_real (const grub_uint32_t * str,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = put_glyphs_terminal (visual, visual_len, margin_left,
|
ret = put_glyphs_terminal (visual, visual_len, margin_left,
|
||||||
margin_right, term, state);
|
margin_right, term, state, fixed_tab);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
grub_free (visual);
|
grub_free (visual);
|
||||||
else
|
else
|
||||||
|
@ -789,7 +815,7 @@ print_ucs4_real (const grub_uint32_t * str,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
return print_ucs4_terminal (str, last_position, margin_left, margin_right,
|
return print_ucs4_terminal (str, last_position, margin_left, margin_right,
|
||||||
term, state, dry_run);
|
term, state, dry_run, fixed_tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -799,7 +825,7 @@ grub_print_ucs4 (const grub_uint32_t * str,
|
||||||
struct grub_term_output *term)
|
struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
print_ucs4_real (str, last_position, margin_left, margin_right,
|
print_ucs4_real (str, last_position, margin_left, margin_right,
|
||||||
term, 0, 0);
|
term, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -809,7 +835,7 @@ grub_ucs4_count_lines (const grub_uint32_t * str,
|
||||||
struct grub_term_output *term)
|
struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
return print_ucs4_real (str, last_position, margin_left, margin_right,
|
return print_ucs4_real (str, last_position, margin_left, margin_right,
|
||||||
term, 0, 1);
|
term, 0, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -859,7 +885,7 @@ grub_xputs_normal (const char *str)
|
||||||
{
|
{
|
||||||
int cur;
|
int cur;
|
||||||
cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0,
|
cur = print_ucs4_real (unicode_str, unicode_last_position, 0, 0,
|
||||||
term, grub_more, 0);
|
term, grub_more, 0, 0);
|
||||||
if (cur)
|
if (cur)
|
||||||
backlog = 1;
|
backlog = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -293,4 +293,8 @@ grub_ssize_t
|
||||||
grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend,
|
grub_encode_utf8_character (grub_uint8_t *dest, grub_uint8_t *destend,
|
||||||
grub_uint32_t code);
|
grub_uint32_t code);
|
||||||
|
|
||||||
|
const grub_uint32_t *
|
||||||
|
grub_unicode_get_comb_start (const grub_uint32_t *str,
|
||||||
|
const grub_uint32_t *cur);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -435,10 +435,15 @@ grub_unicode_estimate_width (const struct grub_unicode_glyph *c __attribute__ ((
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define GRUB_TERM_TAB_WIDTH 8
|
||||||
|
|
||||||
static inline grub_ssize_t
|
static inline grub_ssize_t
|
||||||
grub_term_getcharwidth (struct grub_term_output *term,
|
grub_term_getcharwidth (struct grub_term_output *term,
|
||||||
const struct grub_unicode_glyph *c)
|
const struct grub_unicode_glyph *c)
|
||||||
{
|
{
|
||||||
|
if (c->base == '\t')
|
||||||
|
return GRUB_TERM_TAB_WIDTH;
|
||||||
|
|
||||||
if (term->getcharwidth)
|
if (term->getcharwidth)
|
||||||
return term->getcharwidth (term, c);
|
return term->getcharwidth (term, c);
|
||||||
else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
else if (((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
|
|
@ -243,13 +243,14 @@ grub_unicode_glyph_dup (const struct grub_unicode_glyph *in)
|
||||||
grub_memcpy (out, in, sizeof (*in));
|
grub_memcpy (out, in, sizeof (*in));
|
||||||
if (in->combining)
|
if (in->combining)
|
||||||
{
|
{
|
||||||
out->combining = grub_malloc (in->ncomb * sizeof (*in));
|
out->combining = grub_malloc (in->ncomb * sizeof (out->combining[0]));
|
||||||
if (!out->combining)
|
if (!out->combining)
|
||||||
{
|
{
|
||||||
grub_free (out);
|
grub_free (out);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
grub_memcpy (out->combining, in->combining, in->ncomb * sizeof (*in));
|
grub_memcpy (out->combining, in->combining,
|
||||||
|
in->ncomb * sizeof (out->combining[0]));
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue