Improve bidi handling in entry editor.
This commit is contained in:
parent
4542e71b8b
commit
34f71cb866
8 changed files with 453 additions and 267 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2013-01-16 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Improve bidi handling in entry editor.
|
||||||
|
|
||||||
2013-01-16 Vladimir Serbinenko <phcoder@gmail.com>
|
2013-01-16 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/script/lexer.c (grub_script_lexer_init): Rename getline
|
* grub-core/script/lexer.c (grub_script_lexer_init): Rename getline
|
||||||
|
|
|
@ -52,7 +52,7 @@ grub_font_draw_string (const char *str, grub_font_t font,
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
||||||
visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual,
|
visual_len = grub_bidi_logical_to_visual (logical, logical_len, &visual,
|
||||||
0, 0, 0);
|
0, 0, 0, 0, 0, 0);
|
||||||
grub_free (logical);
|
grub_free (logical);
|
||||||
if (visual_len < 0)
|
if (visual_len < 0)
|
||||||
return grub_errno;
|
return grub_errno;
|
||||||
|
|
|
@ -513,7 +513,10 @@ 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, unsigned *levels,
|
||||||
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
|
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
|
||||||
grub_size_t maxwidth, grub_size_t startwidth)
|
grub_size_t maxwidth, grub_size_t startwidth,
|
||||||
|
grub_uint32_t contchar,
|
||||||
|
struct grub_term_pos *pos, int primitive_wrap,
|
||||||
|
grub_size_t log_end)
|
||||||
{
|
{
|
||||||
struct grub_unicode_glyph *outptr = visual_out;
|
struct grub_unicode_glyph *outptr = visual_out;
|
||||||
unsigned line_start = 0;
|
unsigned line_start = 0;
|
||||||
|
@ -521,17 +524,30 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
|
||||||
unsigned k;
|
unsigned k;
|
||||||
grub_ssize_t last_space = -1;
|
grub_ssize_t last_space = -1;
|
||||||
grub_ssize_t last_space_width = 0;
|
grub_ssize_t last_space_width = 0;
|
||||||
|
int lines = 0;
|
||||||
|
|
||||||
auto void revert (unsigned start, unsigned end);
|
auto void revert (unsigned start, unsigned end);
|
||||||
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, tl;
|
||||||
|
int a, b;
|
||||||
|
if (pos)
|
||||||
|
{
|
||||||
|
a = pos[visual[start].orig_pos].x;
|
||||||
|
b = pos[visual[end].orig_pos].x;
|
||||||
|
}
|
||||||
for (i = 0; i < (end - start) / 2 + 1; i++)
|
for (i = 0; i < (end - start) / 2 + 1; i++)
|
||||||
{
|
{
|
||||||
t = visual[start + i];
|
t = visual[start + i];
|
||||||
visual[start + i] = visual[end - i];
|
visual[start + i] = visual[end - i];
|
||||||
visual[end - i] = t;
|
visual[end - i] = t;
|
||||||
|
|
||||||
|
if (pos)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
tl = levels[start + i];
|
tl = levels[start + i];
|
||||||
levels[start + i] = levels[end - i];
|
levels[start + i] = levels[end - i];
|
||||||
levels[end - i] = tl;
|
levels[end - i] = tl;
|
||||||
|
@ -545,11 +561,27 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
|
||||||
{
|
{
|
||||||
grub_ssize_t last_width = 0;
|
grub_ssize_t last_width = 0;
|
||||||
|
|
||||||
|
|
||||||
|
if (pos && k != visual_len)
|
||||||
|
{
|
||||||
|
pos[visual[k].orig_pos].x = line_width;
|
||||||
|
pos[visual[k].orig_pos].y = lines;
|
||||||
|
pos[visual[k].orig_pos].valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (k == visual_len && pos)
|
||||||
|
{
|
||||||
|
pos[log_end].x = line_width;
|
||||||
|
pos[log_end].y = lines;
|
||||||
|
pos[log_end].valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
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'))
|
|| visual[k].base == '\t')
|
||||||
|
&& !primitive_wrap)
|
||||||
{
|
{
|
||||||
last_space = k;
|
last_space = k;
|
||||||
last_space_width = line_width;
|
last_space_width = line_width;
|
||||||
|
@ -561,9 +593,12 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
|
||||||
unsigned min_odd_level = 0xffffffff;
|
unsigned min_odd_level = 0xffffffff;
|
||||||
unsigned max_level = 0;
|
unsigned max_level = 0;
|
||||||
|
|
||||||
|
lines++;
|
||||||
|
|
||||||
if (k != visual_len && last_space > (signed) line_start)
|
if (k != visual_len && last_space > (signed) line_start)
|
||||||
k = last_space;
|
k = last_space;
|
||||||
else if (k != visual_len && line_start == 0 && startwidth != 0)
|
else if (k != visual_len && line_start == 0 && startwidth != 0
|
||||||
|
&& !primitive_wrap)
|
||||||
{
|
{
|
||||||
k = 0;
|
k = 0;
|
||||||
last_space_width = startwidth;
|
last_space_width = startwidth;
|
||||||
|
@ -685,6 +720,12 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
|
||||||
outptr += k - line_start;
|
outptr += k - line_start;
|
||||||
if (k != visual_len)
|
if (k != visual_len)
|
||||||
{
|
{
|
||||||
|
if (contchar)
|
||||||
|
{
|
||||||
|
grub_memset (outptr, 0, sizeof (visual[0]));
|
||||||
|
outptr->base = contchar;
|
||||||
|
outptr++;
|
||||||
|
}
|
||||||
grub_memset (outptr, 0, sizeof (visual[0]));
|
grub_memset (outptr, 0, sizeof (visual[0]));
|
||||||
outptr->base = '\n';
|
outptr->base = '\n';
|
||||||
outptr++;
|
outptr++;
|
||||||
|
@ -695,6 +736,11 @@ bidi_line_wrap (struct grub_unicode_glyph *visual_out,
|
||||||
|
|
||||||
line_start = k;
|
line_start = k;
|
||||||
line_width -= last_space_width;
|
line_width -= last_space_width;
|
||||||
|
if (pos && k != visual_len)
|
||||||
|
{
|
||||||
|
pos[visual[k].orig_pos].x = 0;
|
||||||
|
pos[visual[k].orig_pos].y = lines;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -707,7 +753,11 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
|
||||||
grub_size_t logical_len,
|
grub_size_t logical_len,
|
||||||
struct grub_unicode_glyph *visual_out,
|
struct grub_unicode_glyph *visual_out,
|
||||||
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
|
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
|
||||||
grub_size_t maxwidth, grub_size_t startwidth)
|
grub_size_t maxwidth, grub_size_t startwidth,
|
||||||
|
grub_uint32_t contchar,
|
||||||
|
struct grub_term_pos *pos,
|
||||||
|
int primitive_wrap,
|
||||||
|
grub_size_t log_end)
|
||||||
{
|
{
|
||||||
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};
|
||||||
|
@ -832,7 +882,7 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
|
||||||
|
|
||||||
p = grub_unicode_aglomerate_comb (lptr, logical + logical_len - lptr,
|
p = grub_unicode_aglomerate_comb (lptr, logical + logical_len - lptr,
|
||||||
&visual[visual_len]);
|
&visual[visual_len]);
|
||||||
|
visual[visual_len].orig_pos = lptr - logical;
|
||||||
type = get_bidi_type (visual[visual_len].base);
|
type = get_bidi_type (visual[visual_len].base);
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
|
@ -1066,7 +1116,8 @@ grub_bidi_line_logical_to_visual (const grub_uint32_t *logical,
|
||||||
{
|
{
|
||||||
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, levels,
|
||||||
getcharwidth, maxwidth, startwidth);
|
getcharwidth, maxwidth, startwidth, contchar,
|
||||||
|
pos, primitive_wrap, log_end);
|
||||||
grub_free (levels);
|
grub_free (levels);
|
||||||
grub_free (visual);
|
grub_free (visual);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1078,11 +1129,12 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical,
|
||||||
grub_size_t logical_len,
|
grub_size_t logical_len,
|
||||||
struct grub_unicode_glyph **visual_out,
|
struct grub_unicode_glyph **visual_out,
|
||||||
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
|
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
|
||||||
grub_size_t max_length, grub_size_t startwidth)
|
grub_size_t max_length, grub_size_t startwidth,
|
||||||
|
grub_uint32_t contchar, struct grub_term_pos *pos, int primitive_wrap)
|
||||||
{
|
{
|
||||||
const grub_uint32_t *line_start = logical, *ptr;
|
const grub_uint32_t *line_start = logical, *ptr;
|
||||||
struct grub_unicode_glyph *visual_ptr;
|
struct grub_unicode_glyph *visual_ptr;
|
||||||
*visual_out = visual_ptr = grub_malloc (2 * sizeof (visual_ptr[0])
|
*visual_out = visual_ptr = grub_malloc (3 * sizeof (visual_ptr[0])
|
||||||
* logical_len);
|
* logical_len);
|
||||||
if (!visual_ptr)
|
if (!visual_ptr)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1096,7 +1148,11 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical,
|
||||||
visual_ptr,
|
visual_ptr,
|
||||||
getcharwidth,
|
getcharwidth,
|
||||||
max_length,
|
max_length,
|
||||||
startwidth);
|
startwidth,
|
||||||
|
contchar,
|
||||||
|
pos,
|
||||||
|
primitive_wrap,
|
||||||
|
logical_len);
|
||||||
startwidth = 0;
|
startwidth = 0;
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -1188,3 +1244,27 @@ grub_unicode_get_comb_start (const grub_uint32_t *str,
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const grub_uint32_t *
|
||||||
|
grub_unicode_get_comb_end (const grub_uint32_t *end,
|
||||||
|
const grub_uint32_t *cur)
|
||||||
|
{
|
||||||
|
const grub_uint32_t *ptr;
|
||||||
|
for (ptr = cur; ptr < end; 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 end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,15 +43,12 @@ struct line
|
||||||
int len;
|
int len;
|
||||||
/* The maximum length of the line. */
|
/* The maximum length of the line. */
|
||||||
int max_len;
|
int max_len;
|
||||||
|
struct grub_term_pos **pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct per_term_screen
|
struct per_term_screen
|
||||||
{
|
{
|
||||||
struct grub_term_output *term;
|
struct grub_term_output *term;
|
||||||
/* The X coordinate. */
|
|
||||||
int x;
|
|
||||||
/* The Y coordinate. */
|
|
||||||
int y;
|
|
||||||
int y_line_start;
|
int y_line_start;
|
||||||
/* Number of entries. */
|
/* Number of entries. */
|
||||||
int num_entries;
|
int num_entries;
|
||||||
|
@ -90,13 +87,18 @@ static int completion_type;
|
||||||
|
|
||||||
/* Initialize a line. */
|
/* Initialize a line. */
|
||||||
static int
|
static int
|
||||||
init_line (struct line *linep)
|
init_line (struct screen *screen, struct line *linep)
|
||||||
{
|
{
|
||||||
linep->len = 0;
|
linep->len = 0;
|
||||||
linep->max_len = 80;
|
linep->max_len = 80;
|
||||||
linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0]));
|
linep->buf = grub_malloc ((linep->max_len + 1) * sizeof (linep->buf[0]));
|
||||||
if (! linep->buf)
|
linep->pos = grub_zalloc (screen->nterms * sizeof (linep->pos[0]));
|
||||||
return 0;
|
if (! linep->buf || !linep->pos)
|
||||||
|
{
|
||||||
|
grub_free (linep->buf);
|
||||||
|
grub_free (linep->pos);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -125,94 +127,17 @@ get_logical_num_lines (struct line *linep, struct per_term_screen *term_screen)
|
||||||
/ grub_term_entry_width (term_screen->term)) + 1;
|
/ 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
|
static void
|
||||||
advance_to (struct screen *screen, int c)
|
advance_to (struct screen *screen, int c)
|
||||||
{
|
{
|
||||||
if (c > screen->lines[screen->line].len)
|
if (c > screen->lines[screen->line].len)
|
||||||
c = screen->lines[screen->line].len;
|
c = screen->lines[screen->line].len;
|
||||||
|
|
||||||
while (screen->column < c)
|
screen->column = grub_unicode_get_comb_end (screen->lines[screen->line].buf
|
||||||
advance (screen);
|
+ screen->lines[screen->line].len,
|
||||||
}
|
screen->lines[screen->line].buf
|
||||||
|
+ c)
|
||||||
/* Print a line. */
|
- screen->lines[screen->line].buf;
|
||||||
static int
|
|
||||||
print_line (struct line *linep, int offset, int y,
|
|
||||||
struct per_term_screen *term_screen, int dry_run)
|
|
||||||
{
|
|
||||||
int x;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
grub_term_gotoxy (term_screen->term,
|
|
||||||
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
|
|
||||||
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;
|
|
||||||
|
|
||||||
delta = grub_unicode_aglomerate_comb (linep->buf + offset + i,
|
|
||||||
linep->len - offset - i,
|
|
||||||
&glyph);
|
|
||||||
width = grub_term_getcharwidth (term_screen->term, &glyph);
|
|
||||||
grub_free (glyph.combining);
|
|
||||||
|
|
||||||
if (x + width > grub_term_entry_width (term_screen->term) && x != 0)
|
|
||||||
break;
|
|
||||||
x += width;
|
|
||||||
i += delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dry_run)
|
|
||||||
return i;
|
|
||||||
|
|
||||||
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. */
|
||||||
|
@ -225,7 +150,7 @@ print_empty_line (int y, struct per_term_screen *term_screen)
|
||||||
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
|
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
|
||||||
y + GRUB_TERM_FIRST_ENTRY_Y);
|
y + GRUB_TERM_FIRST_ENTRY_Y);
|
||||||
|
|
||||||
for (i = 0; i < grub_term_entry_width (term_screen->term) + 1; i++)
|
for (i = 0; i < grub_term_entry_width (term_screen->term); i++)
|
||||||
grub_putcode (' ', term_screen->term);
|
grub_putcode (' ', term_screen->term);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,7 +186,7 @@ print_down (int flag, struct per_term_screen *term_screen)
|
||||||
/* Draw the lines of the screen SCREEN. */
|
/* Draw the lines of the screen SCREEN. */
|
||||||
static void
|
static void
|
||||||
update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
int region_start, int region_column,
|
int region_start, int region_column __attribute__ ((unused)),
|
||||||
int up, int down, enum update_mode mode)
|
int up, int down, enum update_mode mode)
|
||||||
{
|
{
|
||||||
int up_flag = 0;
|
int up_flag = 0;
|
||||||
|
@ -270,19 +195,26 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
int i;
|
int i;
|
||||||
struct line *linep;
|
struct line *linep;
|
||||||
|
|
||||||
|
y = term_screen->y_line_start;
|
||||||
|
linep = screen->lines;
|
||||||
|
|
||||||
|
for (i = 0; i < screen->line; i++, linep++)
|
||||||
|
y += get_logical_num_lines (linep, term_screen);
|
||||||
|
linep = screen->lines + screen->line;
|
||||||
|
y += grub_getstringwidth (linep->buf, linep->buf + screen->column,
|
||||||
|
term_screen->term) / grub_term_entry_width (term_screen->term);
|
||||||
|
|
||||||
/* Check if scrolling is necessary. */
|
/* Check if scrolling is necessary. */
|
||||||
if (term_screen->y < 0 || term_screen->y >= term_screen->num_entries)
|
if (y < 0 || y >= term_screen->num_entries)
|
||||||
{
|
{
|
||||||
int delta;
|
int delta;
|
||||||
if (term_screen->y < 0)
|
if (y < 0)
|
||||||
delta = -term_screen->y;
|
delta = -y;
|
||||||
else
|
else
|
||||||
delta = term_screen->num_entries - 1 - term_screen->y;
|
delta = term_screen->num_entries - 1 - y;
|
||||||
term_screen->y += delta;
|
|
||||||
term_screen->y_line_start += delta;
|
term_screen->y_line_start += delta;
|
||||||
|
|
||||||
region_start = 0;
|
region_start = 0;
|
||||||
region_column = 0;
|
|
||||||
up = 1;
|
up = 1;
|
||||||
down = 1;
|
down = 1;
|
||||||
mode = ALL_LINES;
|
mode = ALL_LINES;
|
||||||
|
@ -293,58 +225,81 @@ 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_line_start;
|
y = term_screen->y_line_start;
|
||||||
i = screen->line;
|
i = 0;
|
||||||
linep = screen->lines + i;
|
linep = screen->lines;
|
||||||
while (y > 0)
|
while (1)
|
||||||
{
|
{
|
||||||
i--;
|
int add;
|
||||||
linep--;
|
add = get_logical_num_lines (linep, term_screen);
|
||||||
y -= get_logical_num_lines (linep, term_screen);
|
if (y + add > 0)
|
||||||
}
|
break;
|
||||||
|
i++;
|
||||||
|
linep++;
|
||||||
|
y += add;
|
||||||
|
}
|
||||||
|
|
||||||
if (y < 0 || i > 0)
|
if (y < 0 || i > 0)
|
||||||
up_flag = 1;
|
up_flag = 1;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
int column;
|
|
||||||
int off = 0;
|
int off = 0;
|
||||||
int full_len;
|
struct grub_term_pos **pos;
|
||||||
|
|
||||||
if (linep >= screen->lines + screen->num_lines)
|
if (linep >= screen->lines + screen->num_lines)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
full_len = grub_getstringwidth (linep->buf, linep->buf + linep->len,
|
pos = linep->pos + (term_screen - screen->terms);
|
||||||
term_screen->term);
|
|
||||||
|
|
||||||
for (column = 0;
|
if (!*pos)
|
||||||
column <= full_len
|
*pos = grub_zalloc ((linep->len + 1) * sizeof (**pos));
|
||||||
&& y < term_screen->num_entries;
|
|
||||||
column += grub_term_entry_width (term_screen->term), y++)
|
if (i == region_start || linep == screen->lines + screen->line)
|
||||||
{
|
{
|
||||||
if (y < 0)
|
int sp;
|
||||||
{
|
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
|
||||||
off += print_line (linep, off, y, term_screen, 1);
|
+ GRUB_TERM_MARGIN + 1, (y < 0 ? 0 : y)
|
||||||
continue;
|
+ GRUB_TERM_FIRST_ENTRY_Y);
|
||||||
}
|
grub_print_ucs4_menu (linep->buf,
|
||||||
|
linep->buf + linep->len,
|
||||||
if (i == region_start)
|
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN
|
||||||
{
|
+ 1,
|
||||||
if (region_column >= column
|
GRUB_TERM_MARGIN
|
||||||
&& region_column
|
+ GRUB_TERM_SCROLL_WIDTH + 2,
|
||||||
< (column
|
term_screen->term,
|
||||||
+ grub_term_entry_width (term_screen->term)))
|
(y < 0) ? -y : 0,
|
||||||
off += print_line (linep, off, y, term_screen, 0);
|
term_screen->num_entries
|
||||||
else if (region_column < column)
|
- ((y > 0) ? y : 0), '\\',
|
||||||
off += print_line (linep, off, y, term_screen, 0);
|
*pos);
|
||||||
else
|
sp = grub_term_entry_width (term_screen->term)
|
||||||
off += print_line (linep, off, y, term_screen, 1);
|
- (*pos)[linep->len].x;
|
||||||
}
|
if (sp > 0)
|
||||||
else if (i > region_start && mode == ALL_LINES)
|
grub_print_spaces (term_screen->term, sp);
|
||||||
off += print_line (linep, off, y, term_screen, 0);
|
}
|
||||||
|
else if (i > region_start && mode == ALL_LINES)
|
||||||
|
{
|
||||||
|
int sp;
|
||||||
|
grub_term_gotoxy (term_screen->term, GRUB_TERM_LEFT_BORDER_X
|
||||||
|
+ GRUB_TERM_MARGIN + 1, (y < 0 ? 0 : y)
|
||||||
|
+ GRUB_TERM_FIRST_ENTRY_Y);
|
||||||
|
grub_print_ucs4_menu (linep->buf,
|
||||||
|
linep->buf + linep->len,
|
||||||
|
GRUB_TERM_LEFT_BORDER_X
|
||||||
|
+ GRUB_TERM_MARGIN + 1,
|
||||||
|
GRUB_TERM_MARGIN
|
||||||
|
+ GRUB_TERM_SCROLL_WIDTH + 2,
|
||||||
|
term_screen->term,
|
||||||
|
(y < 0) ? -y : 0,
|
||||||
|
term_screen->num_entries
|
||||||
|
- ((y > 0) ? y : 0), '\\',
|
||||||
|
*pos);
|
||||||
|
sp = grub_term_entry_width (term_screen->term)
|
||||||
|
- (*pos)[linep->len].x;
|
||||||
|
if (sp > 0)
|
||||||
|
grub_print_spaces (term_screen->term, sp);
|
||||||
}
|
}
|
||||||
|
y += get_logical_num_lines (linep, term_screen);
|
||||||
if (y == term_screen->num_entries)
|
if (y >= term_screen->num_entries)
|
||||||
{
|
{
|
||||||
if (off <= linep->len || i + 1 < screen->num_lines)
|
if (off <= linep->len || i + 1 < screen->num_lines)
|
||||||
down_flag = 1;
|
down_flag = 1;
|
||||||
|
@ -367,10 +322,30 @@ update_screen (struct screen *screen, struct per_term_screen *term_screen,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Place the cursor. */
|
/* Place the cursor. */
|
||||||
grub_term_gotoxy (term_screen->term,
|
if (screen->lines[screen->line].pos[term_screen - screen->terms])
|
||||||
GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1
|
{
|
||||||
+ term_screen->x,
|
const struct grub_term_pos *cpos;
|
||||||
GRUB_TERM_FIRST_ENTRY_Y + term_screen->y);
|
for (cpos = &(screen->lines[screen->line].pos[term_screen - screen->terms])[screen->column];
|
||||||
|
cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0];
|
||||||
|
cpos--)
|
||||||
|
if (cpos->valid)
|
||||||
|
break;
|
||||||
|
y = term_screen->y_line_start;
|
||||||
|
for (i = 0; i < screen->line; i++)
|
||||||
|
y += get_logical_num_lines (screen->lines + i, term_screen);
|
||||||
|
if (cpos >= &(screen->lines[screen->line].pos[term_screen - screen->terms])[0])
|
||||||
|
grub_term_gotoxy (term_screen->term,
|
||||||
|
cpos->x + GRUB_TERM_LEFT_BORDER_X
|
||||||
|
+ GRUB_TERM_MARGIN + 1,
|
||||||
|
cpos->y + y
|
||||||
|
+ GRUB_TERM_FIRST_ENTRY_Y);
|
||||||
|
else
|
||||||
|
grub_term_gotoxy (term_screen->term,
|
||||||
|
GRUB_TERM_LEFT_BORDER_X
|
||||||
|
+ GRUB_TERM_MARGIN + 1,
|
||||||
|
y + GRUB_TERM_FIRST_ENTRY_Y);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
grub_term_refresh (term_screen->term);
|
grub_term_refresh (term_screen->term);
|
||||||
}
|
}
|
||||||
|
@ -424,7 +399,7 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
((screen->num_lines - screen->line - 2)
|
((screen->num_lines - screen->line - 2)
|
||||||
* sizeof (struct line)));
|
* sizeof (struct line)));
|
||||||
|
|
||||||
if (! init_line (screen->lines + screen->line + 1))
|
if (! init_line (screen, screen->lines + screen->line + 1))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Fold the line. */
|
/* Fold the line. */
|
||||||
|
@ -439,6 +414,11 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
current_linep->buf + screen->column,
|
current_linep->buf + screen->column,
|
||||||
size * sizeof (next_linep->buf[0]));
|
size * sizeof (next_linep->buf[0]));
|
||||||
current_linep->len = screen->column;
|
current_linep->len = screen->column;
|
||||||
|
for (i = 0; i < screen->nterms; i++)
|
||||||
|
{
|
||||||
|
grub_free (current_linep->pos[i]);
|
||||||
|
current_linep->pos[i] = 0;
|
||||||
|
}
|
||||||
next_linep->len = size;
|
next_linep->len = size;
|
||||||
|
|
||||||
/* Update a dirty region. */
|
/* Update a dirty region. */
|
||||||
|
@ -457,12 +437,6 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
/* Move the cursor. */
|
/* Move the cursor. */
|
||||||
screen->column = screen->real_column = 0;
|
screen->column = screen->real_column = 0;
|
||||||
screen->line++;
|
screen->line++;
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].x = 0;
|
|
||||||
screen->terms[i].y++;
|
|
||||||
screen->terms[i].y_line_start = screen->terms[i].y;
|
|
||||||
}
|
|
||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -501,6 +475,12 @@ insert_string (struct screen *screen, const char *s, int update)
|
||||||
size * sizeof (current_linep->buf[0]));
|
size * sizeof (current_linep->buf[0]));
|
||||||
grub_free (unicode_msg);
|
grub_free (unicode_msg);
|
||||||
|
|
||||||
|
for (i = 0; i < screen->nterms; i++)
|
||||||
|
{
|
||||||
|
grub_free (current_linep->pos[i]);
|
||||||
|
current_linep->pos[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
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]);
|
||||||
|
@ -582,7 +562,7 @@ make_screen (grub_menu_entry_t entry)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* Initialize the first line which must be always present. */
|
/* Initialize the first line which must be always present. */
|
||||||
if (! init_line (screen->lines))
|
if (! init_line (screen, screen->lines))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
insert_string (screen, (char *) entry->sourcecode, 0);
|
insert_string (screen, (char *) entry->sourcecode, 0);
|
||||||
|
@ -593,9 +573,7 @@ make_screen (grub_menu_entry_t entry)
|
||||||
screen->line = 0;
|
screen->line = 0;
|
||||||
for (i = 0; i < screen->nterms; i++)
|
for (i = 0; i < screen->nterms; i++)
|
||||||
{
|
{
|
||||||
screen->terms[i].x = 0;
|
screen->terms[i].y_line_start = 0;
|
||||||
screen->terms[i].y = 0;
|
|
||||||
screen->terms[i].y_line_start = screen->terms[i].y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return screen;
|
return screen;
|
||||||
|
@ -609,21 +587,20 @@ static int
|
||||||
forward_char (struct screen *screen, int update)
|
forward_char (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
struct line *linep;
|
struct line *linep;
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
linep = screen->lines + screen->line;
|
linep = screen->lines + screen->line;
|
||||||
if (screen->column < linep->len)
|
if (screen->column < linep->len)
|
||||||
advance (screen);
|
{
|
||||||
|
screen->column = grub_unicode_get_comb_end (screen->lines[screen->line].buf
|
||||||
|
+ screen->lines[screen->line].len,
|
||||||
|
screen->lines[screen->line].buf
|
||||||
|
+ screen->column + 1)
|
||||||
|
- screen->lines[screen->line].buf;
|
||||||
|
}
|
||||||
else if (screen->num_lines > screen->line + 1)
|
else if (screen->num_lines > screen->line + 1)
|
||||||
{
|
{
|
||||||
screen->column = 0;
|
screen->column = 0;
|
||||||
screen->line++;
|
screen->line++;
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].x = 0;
|
|
||||||
screen->terms[i].y++;
|
|
||||||
screen->terms[i].y_line_start = screen->terms[i].y;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->real_column = screen->column;
|
screen->real_column = screen->column;
|
||||||
|
@ -636,8 +613,6 @@ forward_char (struct screen *screen, int update)
|
||||||
static int
|
static int
|
||||||
backward_char (struct screen *screen, int update)
|
backward_char (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
if (screen->column > 0)
|
if (screen->column > 0)
|
||||||
{
|
{
|
||||||
struct grub_unicode_glyph glyph;
|
struct grub_unicode_glyph glyph;
|
||||||
|
@ -653,36 +628,16 @@ backward_char (struct screen *screen, int update)
|
||||||
grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column,
|
grub_unicode_aglomerate_comb (screen->lines[screen->line].buf + screen->column,
|
||||||
screen->lines[screen->line].len - screen->column,
|
screen->lines[screen->line].len - screen->column,
|
||||||
&glyph);
|
&glyph);
|
||||||
|
screen->column = grub_unicode_get_comb_start (linep->buf,
|
||||||
|
linep->buf + screen->column)
|
||||||
|
- linep->buf;
|
||||||
|
|
||||||
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 < 0)
|
|
||||||
{
|
|
||||||
screen->terms[i].x
|
|
||||||
= grub_term_entry_width (screen->terms[i].term) - 1;
|
|
||||||
screen->terms[i].y--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
grub_free (glyph.combining);
|
grub_free (glyph.combining);
|
||||||
}
|
}
|
||||||
else if (screen->line > 0)
|
else if (screen->line > 0)
|
||||||
{
|
{
|
||||||
struct line *linep;
|
|
||||||
|
|
||||||
screen->column = 0;
|
|
||||||
screen->line--;
|
screen->line--;
|
||||||
linep = screen->lines + screen->line;
|
screen->column = screen->lines[screen->line].len;
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].y_line_start -= get_logical_num_lines (linep, &screen->terms[i]);
|
|
||||||
screen->terms[i].y = screen->terms[i].y_line_start;
|
|
||||||
screen->terms[i].x = 0;
|
|
||||||
}
|
|
||||||
advance_to (screen, screen->lines[screen->line].len);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
screen->real_column = screen->column;
|
screen->real_column = screen->column;
|
||||||
|
@ -696,8 +651,6 @@ backward_char (struct screen *screen, int update)
|
||||||
static int
|
static int
|
||||||
previous_line (struct screen *screen, int update)
|
previous_line (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
if (screen->line > 0)
|
if (screen->line > 0)
|
||||||
{
|
{
|
||||||
struct line *linep;
|
struct line *linep;
|
||||||
|
@ -712,22 +665,10 @@ previous_line (struct screen *screen, int update)
|
||||||
col = screen->real_column;
|
col = screen->real_column;
|
||||||
|
|
||||||
screen->column = 0;
|
screen->column = 0;
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].y_line_start -= get_logical_num_lines (linep, &screen->terms[i]);
|
|
||||||
screen->terms[i].y = screen->terms[i].y_line_start;
|
|
||||||
screen->terms[i].x = 0;
|
|
||||||
}
|
|
||||||
advance_to (screen, col);
|
advance_to (screen, col);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].y = screen->terms[i].y_line_start;
|
|
||||||
screen->terms[i].x = 0;
|
|
||||||
}
|
|
||||||
screen->column = 0;
|
screen->column = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,8 +681,6 @@ previous_line (struct screen *screen, int update)
|
||||||
static int
|
static int
|
||||||
next_line (struct screen *screen, int update)
|
next_line (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
if (screen->line < screen->num_lines - 1)
|
if (screen->line < screen->num_lines - 1)
|
||||||
{
|
{
|
||||||
struct line *linep;
|
struct line *linep;
|
||||||
|
@ -758,12 +697,6 @@ next_line (struct screen *screen, int update)
|
||||||
c = screen->real_column;
|
c = screen->real_column;
|
||||||
screen->column = 0;
|
screen->column = 0;
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].y_line_start += get_logical_num_lines (linep, &screen->terms[i]);
|
|
||||||
screen->terms[i].x = 0;
|
|
||||||
screen->terms[i].y = screen->terms[i].y_line_start;
|
|
||||||
}
|
|
||||||
advance_to (screen, c);
|
advance_to (screen, c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -778,14 +711,7 @@ next_line (struct screen *screen, int update)
|
||||||
static int
|
static int
|
||||||
beginning_of_line (struct screen *screen, int update)
|
beginning_of_line (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
screen->column = screen->real_column = 0;
|
screen->column = screen->real_column = 0;
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
{
|
|
||||||
screen->terms[i].x = 0;
|
|
||||||
screen->terms[i].y = screen->terms[i].y_line_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
||||||
|
@ -826,6 +752,11 @@ delete_char (struct screen *screen, int update)
|
||||||
* sizeof (linep->buf[0]));
|
* sizeof (linep->buf[0]));
|
||||||
linep->len--;
|
linep->len--;
|
||||||
|
|
||||||
|
for (i = 0; i < screen->nterms; i++)
|
||||||
|
{
|
||||||
|
grub_free (linep->pos[i]);
|
||||||
|
linep->pos[i] = 0;
|
||||||
|
}
|
||||||
start = screen->line;
|
start = screen->line;
|
||||||
column = screen->column;
|
column = screen->column;
|
||||||
|
|
||||||
|
@ -848,6 +779,7 @@ delete_char (struct screen *screen, int update)
|
||||||
else if (screen->num_lines > screen->line + 1)
|
else if (screen->num_lines > screen->line + 1)
|
||||||
{
|
{
|
||||||
struct line *next_linep;
|
struct line *next_linep;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
next_linep = linep + 1;
|
next_linep = linep + 1;
|
||||||
if (! ensure_space (linep, next_linep->len))
|
if (! ensure_space (linep, next_linep->len))
|
||||||
|
@ -856,6 +788,11 @@ delete_char (struct screen *screen, int update)
|
||||||
grub_memmove (linep->buf + linep->len, next_linep->buf,
|
grub_memmove (linep->buf + linep->len, next_linep->buf,
|
||||||
next_linep->len * sizeof (linep->buf[0]));
|
next_linep->len * sizeof (linep->buf[0]));
|
||||||
linep->len += next_linep->len;
|
linep->len += next_linep->len;
|
||||||
|
for (i = 0; i < screen->nterms; i++)
|
||||||
|
{
|
||||||
|
grub_free (linep->pos[i]);
|
||||||
|
linep->pos[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
grub_free (next_linep->buf);
|
grub_free (next_linep->buf);
|
||||||
grub_memmove (next_linep,
|
grub_memmove (next_linep,
|
||||||
|
@ -975,24 +912,12 @@ yank (struct screen *screen, int update)
|
||||||
static int
|
static int
|
||||||
open_line (struct screen *screen, int update)
|
open_line (struct screen *screen, int update)
|
||||||
{
|
{
|
||||||
int saved_y[screen->nterms];
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; i++)
|
|
||||||
saved_y[i] = screen->terms[i].y;
|
|
||||||
|
|
||||||
if (! insert_string (screen, "\n", 0))
|
if (! insert_string (screen, "\n", 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (! backward_char (screen, 0))
|
if (! backward_char (screen, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (i = 0; i < screen->nterms; 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);
|
||||||
|
|
||||||
|
@ -1303,7 +1228,20 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||||
screen->nterms = 0;
|
screen->nterms = 0;
|
||||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
screen->nterms++;
|
screen->nterms++;
|
||||||
screen->terms = grub_malloc (screen->nterms * sizeof (screen->terms[0]));
|
|
||||||
|
for (i = 0; i < (unsigned) screen->num_lines; i++)
|
||||||
|
{
|
||||||
|
grub_free (screen->lines[i].pos);
|
||||||
|
screen->lines[i].pos = grub_zalloc (screen->nterms * sizeof (screen->lines[i].pos[0]));
|
||||||
|
if (! screen->lines[i].pos)
|
||||||
|
{
|
||||||
|
grub_print_error ();
|
||||||
|
grub_errno = GRUB_ERR_NONE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
screen->terms = grub_zalloc (screen->nterms * sizeof (screen->terms[0]));
|
||||||
if (!screen->terms)
|
if (!screen->terms)
|
||||||
{
|
{
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
|
@ -1314,9 +1252,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
{
|
{
|
||||||
screen->terms[i].term = term;
|
screen->terms[i].term = term;
|
||||||
screen->terms[i].x = 0;
|
screen->terms[i].y_line_start = 0;
|
||||||
screen->terms[i].y = 0;
|
|
||||||
screen->terms[i].y_line_start = screen->terms[i].y;
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
/* Draw the screen. */
|
/* Draw the screen. */
|
||||||
|
|
|
@ -34,6 +34,10 @@ struct term_state
|
||||||
int backlog_fixed_tab;
|
int backlog_fixed_tab;
|
||||||
grub_size_t backlog_len;
|
grub_size_t backlog_len;
|
||||||
|
|
||||||
|
int bidi_stack_depth;
|
||||||
|
grub_uint8_t bidi_stack[GRUB_BIDI_MAX_EXPLICIT_LEVEL];
|
||||||
|
int invalid_pushes;
|
||||||
|
|
||||||
void *free;
|
void *free;
|
||||||
int num_lines;
|
int num_lines;
|
||||||
char *term_name;
|
char *term_name;
|
||||||
|
@ -44,7 +48,9 @@ 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 fixed_tab);
|
int dry_run, int fixed_tab, unsigned skip_lines,
|
||||||
|
unsigned max_lines,
|
||||||
|
grub_uint32_t contchar, struct grub_term_pos *pos);
|
||||||
|
|
||||||
static struct term_state *term_states = NULL;
|
static struct term_state *term_states = NULL;
|
||||||
|
|
||||||
|
@ -243,7 +249,8 @@ grub_puts_terminal (const char *str, struct grub_term_output *term)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_ucs4_real (unicode_str, unicode_last_position, 0, 0, term, 0, 0, 0);
|
print_ucs4_real (unicode_str, unicode_last_position, 0, 0, term,
|
||||||
|
0, 0, 0, 0, -1, 0, 0);
|
||||||
grub_free (unicode_str);
|
grub_free (unicode_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,13 +548,25 @@ get_startwidth (struct grub_term_output *term,
|
||||||
return ((term->getxy (term) >> 8) & 0xff) - margin_left;
|
return ((term->getxy (term) >> 8) & 0xff) - margin_left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
fill_margin (struct grub_term_output *term, int r)
|
||||||
|
{
|
||||||
|
int sp = (term->getwh (term) >> 8)
|
||||||
|
- (term->getxy (term) >> 8) - r;
|
||||||
|
if (sp > 0)
|
||||||
|
grub_print_spaces (term, sp);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
print_ucs4_terminal (const grub_uint32_t * str,
|
print_ucs4_terminal (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,
|
struct grub_term_output *term,
|
||||||
struct term_state *state,
|
struct term_state *state,
|
||||||
int dry_run, int fixed_tab)
|
int dry_run, int fixed_tab, unsigned skip_lines,
|
||||||
|
unsigned max_lines,
|
||||||
|
grub_uint32_t contchar,
|
||||||
|
int primitive_wrap, struct grub_term_pos *pos)
|
||||||
{
|
{
|
||||||
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);
|
||||||
|
@ -556,10 +575,40 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right);
|
grub_ssize_t max_width = get_maxwidth (term, margin_left, margin_right);
|
||||||
const grub_uint32_t *line_start = str, *last_space = str - 1;
|
const grub_uint32_t *line_start = str, *last_space = str - 1;
|
||||||
int lines = 0;
|
int lines = 0;
|
||||||
|
int i;
|
||||||
|
struct term_state local_state;
|
||||||
|
|
||||||
|
if (!state)
|
||||||
|
{
|
||||||
|
grub_memset (&local_state, 0, sizeof (local_state));
|
||||||
|
state = &local_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < state->bidi_stack_depth; i++)
|
||||||
|
putcode_real (state->bidi_stack[i] | (GRUB_UNICODE_LRE & ~0xff),
|
||||||
|
term, fixed_tab);
|
||||||
|
|
||||||
for (ptr = str; ptr < last_position; ptr++)
|
for (ptr = str; ptr < last_position; ptr++)
|
||||||
{
|
{
|
||||||
grub_ssize_t last_width = 0;
|
grub_ssize_t last_width = 0;
|
||||||
|
switch (*ptr)
|
||||||
|
{
|
||||||
|
case GRUB_UNICODE_LRE:
|
||||||
|
case GRUB_UNICODE_RLE:
|
||||||
|
case GRUB_UNICODE_LRO:
|
||||||
|
case GRUB_UNICODE_RLO:
|
||||||
|
if (state->bidi_stack_depth >= (int) ARRAY_SIZE (state->bidi_stack))
|
||||||
|
state->invalid_pushes++;
|
||||||
|
else
|
||||||
|
state->bidi_stack[state->bidi_stack_depth++] = *ptr;
|
||||||
|
break;
|
||||||
|
case GRUB_UNICODE_PDF:
|
||||||
|
if (state->invalid_pushes)
|
||||||
|
state->invalid_pushes--;
|
||||||
|
else if (state->bidi_stack_depth)
|
||||||
|
state->bidi_stack_depth--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE)
|
if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE)
|
||||||
{
|
{
|
||||||
struct grub_unicode_glyph c = {
|
struct grub_unicode_glyph c = {
|
||||||
|
@ -569,10 +618,16 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
.combining = 0
|
.combining = 0
|
||||||
};
|
};
|
||||||
c.base = *ptr;
|
c.base = *ptr;
|
||||||
|
if (pos)
|
||||||
|
{
|
||||||
|
pos[ptr - str].x = line_width;
|
||||||
|
pos[ptr - str].y = lines;
|
||||||
|
pos[ptr - str].valid = 1;
|
||||||
|
}
|
||||||
line_width += last_width = grub_term_getcharwidth (term, &c);
|
line_width += last_width = grub_term_getcharwidth (term, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*ptr == ' ')
|
if (*ptr == ' ' && !primitive_wrap)
|
||||||
{
|
{
|
||||||
lastspacewidth = line_width;
|
lastspacewidth = line_width;
|
||||||
last_space = ptr;
|
last_space = ptr;
|
||||||
|
@ -581,6 +636,13 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
if (line_width > max_width || *ptr == '\n')
|
if (line_width > max_width || *ptr == '\n')
|
||||||
{
|
{
|
||||||
const grub_uint32_t *ptr2;
|
const grub_uint32_t *ptr2;
|
||||||
|
int wasn = (*ptr == '\n');
|
||||||
|
|
||||||
|
if (wasn)
|
||||||
|
{
|
||||||
|
state->bidi_stack_depth = 0;
|
||||||
|
state->invalid_pushes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (line_width > max_width && last_space > line_start)
|
if (line_width > max_width && last_space > line_start)
|
||||||
ptr = last_space;
|
ptr = last_space;
|
||||||
|
@ -595,7 +657,7 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
|
|
||||||
lines++;
|
lines++;
|
||||||
|
|
||||||
if (!dry_run)
|
if (!skip_lines && !dry_run)
|
||||||
{
|
{
|
||||||
for (ptr2 = line_start; ptr2 < ptr; ptr2++)
|
for (ptr2 = line_start; ptr2 < ptr; ptr2++)
|
||||||
{
|
{
|
||||||
|
@ -608,9 +670,12 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
putcode_real (*ptr2, term, fixed_tab);
|
putcode_real (*ptr2, term, fixed_tab);
|
||||||
}
|
}
|
||||||
|
|
||||||
grub_print_spaces (term, margin_right);
|
if (!wasn && contchar)
|
||||||
|
putcode_real (contchar, term, fixed_tab);
|
||||||
|
fill_margin (term, contchar ? margin_right : 1);
|
||||||
|
|
||||||
grub_putcode ('\n', term);
|
grub_putcode ('\n', term);
|
||||||
if (state && ++state->num_lines
|
if (state != &local_state && ++state->num_lines
|
||||||
>= (grub_ssize_t) grub_term_height (term) - 2)
|
>= (grub_ssize_t) grub_term_height (term) - 2)
|
||||||
{
|
{
|
||||||
state->backlog_ucs4 = (ptr == last_space || *ptr == '\n')
|
state->backlog_ucs4 = (ptr == last_space || *ptr == '\n')
|
||||||
|
@ -622,17 +687,42 @@ print_ucs4_terminal (const grub_uint32_t * str,
|
||||||
}
|
}
|
||||||
|
|
||||||
line_width -= lastspacewidth;
|
line_width -= lastspacewidth;
|
||||||
if (!dry_run)
|
|
||||||
grub_print_spaces (term, margin_left);
|
|
||||||
if (ptr == last_space || *ptr == '\n')
|
if (ptr == last_space || *ptr == '\n')
|
||||||
ptr++;
|
ptr++;
|
||||||
line_start = ptr;
|
line_start = ptr;
|
||||||
|
|
||||||
|
if (skip_lines)
|
||||||
|
skip_lines--;
|
||||||
|
else if (max_lines != (unsigned) -1)
|
||||||
|
{
|
||||||
|
max_lines--;
|
||||||
|
if (!max_lines)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!skip_lines && !dry_run)
|
||||||
|
{
|
||||||
|
if (!contchar)
|
||||||
|
grub_print_spaces (term, margin_left);
|
||||||
|
else
|
||||||
|
grub_term_gotoxy (term, margin_left,
|
||||||
|
grub_term_getxy (term) & 0xff);
|
||||||
|
for (i = 0; i < state->bidi_stack_depth; i++)
|
||||||
|
putcode_real (state->bidi_stack[i] | (GRUB_UNICODE_LRE & ~0xff),
|
||||||
|
term, fixed_tab);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pos)
|
||||||
|
{
|
||||||
|
pos[ptr - str].x = line_width;
|
||||||
|
pos[ptr - str].y = lines;
|
||||||
|
pos[ptr - str].valid = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (line_start < last_position)
|
if (line_start < last_position)
|
||||||
lines++;
|
lines++;
|
||||||
if (!dry_run)
|
if (!dry_run && !skip_lines && max_lines)
|
||||||
{
|
{
|
||||||
const grub_uint32_t *ptr2;
|
const grub_uint32_t *ptr2;
|
||||||
for (ptr2 = line_start; ptr2 < last_position; ptr2++)
|
for (ptr2 = line_start; ptr2 < last_position; ptr2++)
|
||||||
|
@ -717,7 +807,8 @@ print_backlog (struct grub_term_output *term,
|
||||||
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);
|
state->backlog_fixed_tab, 0, -1, 0, 0,
|
||||||
|
0);
|
||||||
if (!ret)
|
if (!ret)
|
||||||
{
|
{
|
||||||
grub_free (state->free);
|
grub_free (state->free);
|
||||||
|
@ -753,17 +844,28 @@ 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 fixed_tab)
|
int dry_run, int fixed_tab, unsigned skip_lines,
|
||||||
|
unsigned max_lines,
|
||||||
|
grub_uint32_t contchar, struct grub_term_pos *pos)
|
||||||
{
|
{
|
||||||
struct term_state *state = NULL;
|
struct term_state *state = NULL;
|
||||||
|
|
||||||
if (!dry_run)
|
if (!dry_run)
|
||||||
{
|
{
|
||||||
|
int xy;
|
||||||
if (backlog)
|
if (backlog)
|
||||||
state = find_term_state (term);
|
state = find_term_state (term);
|
||||||
|
|
||||||
if (((term->getxy (term) >> 8) & 0xff) < margin_left)
|
xy = term->getxy (term);
|
||||||
grub_print_spaces (term, margin_left - ((term->getxy (term) >> 8) & 0xff));
|
|
||||||
|
if (((xy >> 8) & 0xff) < margin_left)
|
||||||
|
{
|
||||||
|
if (!contchar)
|
||||||
|
grub_print_spaces (term, margin_left - ((xy >> 8) & 0xff));
|
||||||
|
else
|
||||||
|
grub_term_gotoxy (term, margin_left,
|
||||||
|
xy & 0xff);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
@ -773,7 +875,10 @@ print_ucs4_real (const grub_uint32_t * str,
|
||||||
{
|
{
|
||||||
grub_ssize_t visual_len;
|
grub_ssize_t visual_len;
|
||||||
struct grub_unicode_glyph *visual;
|
struct grub_unicode_glyph *visual;
|
||||||
|
grub_ssize_t visual_len_show;
|
||||||
|
struct grub_unicode_glyph *visual_show;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct grub_unicode_glyph *vptr;
|
||||||
|
|
||||||
auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c);
|
auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c);
|
||||||
grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c)
|
grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c)
|
||||||
|
@ -787,27 +892,45 @@ print_ucs4_real (const grub_uint32_t * str,
|
||||||
margin_left,
|
margin_left,
|
||||||
margin_right),
|
margin_right),
|
||||||
get_startwidth (term,
|
get_startwidth (term,
|
||||||
margin_left));
|
margin_left),
|
||||||
|
contchar, pos, !!contchar);
|
||||||
if (visual_len < 0)
|
if (visual_len < 0)
|
||||||
{
|
{
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
visual_show = visual;
|
||||||
|
for (; skip_lines && visual_show < visual + visual_len; visual_show++)
|
||||||
|
if (visual_show->base == '\n')
|
||||||
|
skip_lines--;
|
||||||
|
if (max_lines != (unsigned) -1)
|
||||||
|
{
|
||||||
|
for (vptr = visual_show;
|
||||||
|
max_lines && vptr < visual + visual_len; vptr++)
|
||||||
|
if (visual_show->base == '\n')
|
||||||
|
max_lines--;
|
||||||
|
|
||||||
|
visual_len_show = vptr - visual_show;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
visual_len_show = visual + visual_len - visual_show;
|
||||||
|
|
||||||
if (dry_run)
|
if (dry_run)
|
||||||
{
|
{
|
||||||
struct grub_unicode_glyph *vptr;
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
for (vptr = visual; vptr < visual + visual_len; vptr++)
|
for (vptr = visual_show; vptr < visual_show + visual_len_show; vptr++)
|
||||||
if (vptr->base == '\n')
|
if (vptr->base == '\n')
|
||||||
ret++;
|
ret++;
|
||||||
if (visual_len && visual[visual_len - 1].base != '\n')
|
if (visual_len_show && visual[visual_len_show - 1].base != '\n')
|
||||||
ret++;
|
ret++;
|
||||||
grub_free (visual);
|
grub_free (visual);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = put_glyphs_terminal (visual, visual_len, margin_left,
|
ret = put_glyphs_terminal (visual_show, visual_len_show, margin_left,
|
||||||
margin_right, term, state, fixed_tab);
|
contchar ? margin_right : 1,
|
||||||
|
term, state, fixed_tab);
|
||||||
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
grub_free (visual);
|
grub_free (visual);
|
||||||
else
|
else
|
||||||
|
@ -816,7 +939,22 @@ 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, fixed_tab);
|
term, state, dry_run, fixed_tab, skip_lines,
|
||||||
|
max_lines, contchar, !!contchar, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_print_ucs4_menu (const grub_uint32_t * str,
|
||||||
|
const grub_uint32_t * last_position,
|
||||||
|
int margin_left, int margin_right,
|
||||||
|
struct grub_term_output *term,
|
||||||
|
int skip_lines, int max_lines,
|
||||||
|
grub_uint32_t contchar,
|
||||||
|
struct grub_term_pos *pos)
|
||||||
|
{
|
||||||
|
print_ucs4_real (str, last_position, margin_left, margin_right,
|
||||||
|
term, 0, 0, 1, skip_lines, max_lines,
|
||||||
|
contchar, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -826,7 +964,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, 1);
|
term, 0, 0, 1, 0, -1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -836,7 +974,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, 1);
|
term, 0, 1, 1, 0, -1, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -886,7 +1024,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, 0);
|
term, grub_more, 0, 0, 0, -1, 0, 0);
|
||||||
if (cur)
|
if (cur)
|
||||||
backlog = 1;
|
backlog = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -77,6 +77,14 @@ grub_print_ucs4 (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);
|
struct grub_term_output *term);
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_print_ucs4_menu (const grub_uint32_t * str,
|
||||||
|
const grub_uint32_t * last_position,
|
||||||
|
int margin_left, int margin_right,
|
||||||
|
struct grub_term_output *term,
|
||||||
|
int skip_lines, int max_lines, grub_uint32_t contchar,
|
||||||
|
struct grub_term_pos *pos);
|
||||||
int
|
int
|
||||||
grub_ucs4_count_lines (const grub_uint32_t * str,
|
grub_ucs4_count_lines (const grub_uint32_t * str,
|
||||||
const grub_uint32_t * last_position,
|
const grub_uint32_t * last_position,
|
||||||
|
|
|
@ -104,7 +104,7 @@ grub_term_color_state;
|
||||||
#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT)
|
#define GRUB_TERM_CODE_TYPE_CP437 (1 << GRUB_TERM_CODE_TYPE_SHIFT)
|
||||||
/* UTF-8 stream in logical order. Usually used for terminals
|
/* UTF-8 stream in logical order. Usually used for terminals
|
||||||
which just forward the stream to another computer. */
|
which just forward the stream to another computer. */
|
||||||
#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT)
|
#define GRUB_TERM_CODE_TYPE_UTF8_LOGICAL (2 << GRUB_TERM_CODE_TYPE_SHIFT)
|
||||||
/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */
|
/* UTF-8 in visual order. Like UTF-8 logical but for buggy endpoints. */
|
||||||
#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT)
|
#define GRUB_TERM_CODE_TYPE_UTF8_VISUAL (3 << GRUB_TERM_CODE_TYPE_SHIFT)
|
||||||
/* Glyph description in visual order. */
|
/* Glyph description in visual order. */
|
||||||
|
@ -344,7 +344,7 @@ static inline unsigned grub_term_height (struct grub_term_output *term)
|
||||||
static inline unsigned
|
static inline unsigned
|
||||||
grub_term_border_width (struct grub_term_output *term)
|
grub_term_border_width (struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
return grub_term_width (term) - GRUB_TERM_MARGIN * 3 - GRUB_TERM_SCROLL_WIDTH;
|
return grub_term_width (term) - GRUB_TERM_MARGIN * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The max column number of an entry. The last "-1" is for a
|
/* The max column number of an entry. The last "-1" is for a
|
||||||
|
@ -352,7 +352,7 @@ grub_term_border_width (struct grub_term_output *term)
|
||||||
static inline int
|
static inline int
|
||||||
grub_term_entry_width (struct grub_term_output *term)
|
grub_term_entry_width (struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
return grub_term_border_width (term) - 2 - GRUB_TERM_MARGIN * 2 - 1;
|
return grub_term_border_width (term) - GRUB_TERM_MARGIN * 2 - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline grub_uint16_t
|
static inline grub_uint16_t
|
||||||
|
|
|
@ -139,6 +139,7 @@ struct grub_unicode_glyph
|
||||||
grub_uint16_t variant:9;
|
grub_uint16_t variant:9;
|
||||||
grub_uint8_t attributes:5;
|
grub_uint8_t attributes:5;
|
||||||
grub_size_t ncomb;
|
grub_size_t ncomb;
|
||||||
|
grub_size_t orig_pos;
|
||||||
struct grub_unicode_combining {
|
struct grub_unicode_combining {
|
||||||
grub_uint32_t code;
|
grub_uint32_t code;
|
||||||
enum grub_comb_type type;
|
enum grub_comb_type type;
|
||||||
|
@ -186,6 +187,13 @@ enum
|
||||||
GRUB_UNICODE_THAANA_SUKUN = 0x07b0,
|
GRUB_UNICODE_THAANA_SUKUN = 0x07b0,
|
||||||
GRUB_UNICODE_ZWNJ = 0x200c,
|
GRUB_UNICODE_ZWNJ = 0x200c,
|
||||||
GRUB_UNICODE_ZWJ = 0x200d,
|
GRUB_UNICODE_ZWJ = 0x200d,
|
||||||
|
GRUB_UNICODE_LRM = 0x200e,
|
||||||
|
GRUB_UNICODE_RLM = 0x200f,
|
||||||
|
GRUB_UNICODE_LRE = 0x202a,
|
||||||
|
GRUB_UNICODE_RLE = 0x202b,
|
||||||
|
GRUB_UNICODE_PDF = 0x202c,
|
||||||
|
GRUB_UNICODE_LRO = 0x202d,
|
||||||
|
GRUB_UNICODE_RLO = 0x202e,
|
||||||
GRUB_UNICODE_LEFTARROW = 0x2190,
|
GRUB_UNICODE_LEFTARROW = 0x2190,
|
||||||
GRUB_UNICODE_UPARROW = 0x2191,
|
GRUB_UNICODE_UPARROW = 0x2191,
|
||||||
GRUB_UNICODE_RIGHTARROW = 0x2192,
|
GRUB_UNICODE_RIGHTARROW = 0x2192,
|
||||||
|
@ -222,13 +230,21 @@ extern struct grub_unicode_bidi_pair grub_unicode_bidi_pairs[];
|
||||||
/* Unicode mandates an arbitrary limit. */
|
/* Unicode mandates an arbitrary limit. */
|
||||||
#define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61
|
#define GRUB_BIDI_MAX_EXPLICIT_LEVEL 61
|
||||||
|
|
||||||
|
struct grub_term_pos
|
||||||
|
{
|
||||||
|
unsigned valid:1;
|
||||||
|
unsigned x:15, y:16;
|
||||||
|
};
|
||||||
|
|
||||||
grub_ssize_t
|
grub_ssize_t
|
||||||
grub_bidi_logical_to_visual (const grub_uint32_t *logical,
|
grub_bidi_logical_to_visual (const grub_uint32_t *logical,
|
||||||
grub_size_t logical_len,
|
grub_size_t logical_len,
|
||||||
struct grub_unicode_glyph **visual_out,
|
struct grub_unicode_glyph **visual_out,
|
||||||
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
|
grub_ssize_t (*getcharwidth) (const struct grub_unicode_glyph *visual),
|
||||||
grub_size_t max_width,
|
grub_size_t max_width,
|
||||||
grub_size_t start_width);
|
grub_size_t start_width, grub_uint32_t codechar,
|
||||||
|
struct grub_term_pos *pos,
|
||||||
|
int primitive_wrap);
|
||||||
|
|
||||||
enum grub_comb_type
|
enum grub_comb_type
|
||||||
grub_unicode_get_comb_type (grub_uint32_t c);
|
grub_unicode_get_comb_type (grub_uint32_t c);
|
||||||
|
@ -275,4 +291,8 @@ grub_unicode_mirror_code (grub_uint32_t in);
|
||||||
grub_uint32_t
|
grub_uint32_t
|
||||||
grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr);
|
grub_unicode_shape_code (grub_uint32_t in, grub_uint8_t attr);
|
||||||
|
|
||||||
|
const grub_uint32_t *
|
||||||
|
grub_unicode_get_comb_end (const grub_uint32_t *end,
|
||||||
|
const grub_uint32_t *cur);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue