Move terminal-related function from normal/charset.c to normal/term.c
This commit is contained in:
parent
abe8f24a47
commit
09f9aa3b2e
3 changed files with 324 additions and 321 deletions
|
@ -156,4 +156,7 @@ grub_unicode_glyph_from_code (grub_uint32_t code)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grub_uint32_t
|
||||||
|
grub_unicode_mirror_code (grub_uint32_t in);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
323
normal/charset.c
323
normal/charset.c
|
@ -1022,75 +1022,8 @@ grub_bidi_logical_to_visual (const grub_uint32_t *logical,
|
||||||
return visual_ptr - *visual_out;
|
return visual_ptr - *visual_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_uint32_t
|
grub_uint32_t
|
||||||
map_code (grub_uint32_t in, struct grub_term_output *term)
|
grub_unicode_mirror_code (grub_uint32_t in)
|
||||||
{
|
|
||||||
if (in <= 0x7f)
|
|
||||||
return in;
|
|
||||||
|
|
||||||
switch (term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
|
||||||
{
|
|
||||||
case GRUB_TERM_CODE_TYPE_VGA:
|
|
||||||
switch (in)
|
|
||||||
{
|
|
||||||
case GRUB_TERM_DISP_LEFT:
|
|
||||||
return 0x1b;
|
|
||||||
case GRUB_TERM_DISP_UP:
|
|
||||||
return 0x18;
|
|
||||||
case GRUB_TERM_DISP_RIGHT:
|
|
||||||
return 0x1a;
|
|
||||||
case GRUB_TERM_DISP_DOWN:
|
|
||||||
return 0x19;
|
|
||||||
case GRUB_TERM_DISP_HLINE:
|
|
||||||
return 0xc4;
|
|
||||||
case GRUB_TERM_DISP_VLINE:
|
|
||||||
return 0xb3;
|
|
||||||
case GRUB_TERM_DISP_UL:
|
|
||||||
return 0xda;
|
|
||||||
case GRUB_TERM_DISP_UR:
|
|
||||||
return 0xbf;
|
|
||||||
case GRUB_TERM_DISP_LL:
|
|
||||||
return 0xc0;
|
|
||||||
case GRUB_TERM_DISP_LR:
|
|
||||||
return 0xd9;
|
|
||||||
}
|
|
||||||
return '?';
|
|
||||||
case GRUB_TERM_CODE_TYPE_ASCII:
|
|
||||||
/* Better than nothing. */
|
|
||||||
switch (in)
|
|
||||||
{
|
|
||||||
case GRUB_TERM_DISP_LEFT:
|
|
||||||
return '<';
|
|
||||||
|
|
||||||
case GRUB_TERM_DISP_UP:
|
|
||||||
return '^';
|
|
||||||
|
|
||||||
case GRUB_TERM_DISP_RIGHT:
|
|
||||||
return '>';
|
|
||||||
|
|
||||||
case GRUB_TERM_DISP_DOWN:
|
|
||||||
return 'v';
|
|
||||||
|
|
||||||
case GRUB_TERM_DISP_HLINE:
|
|
||||||
return '-';
|
|
||||||
|
|
||||||
case GRUB_TERM_DISP_VLINE:
|
|
||||||
return '|';
|
|
||||||
|
|
||||||
case GRUB_TERM_DISP_UL:
|
|
||||||
case GRUB_TERM_DISP_UR:
|
|
||||||
case GRUB_TERM_DISP_LL:
|
|
||||||
case GRUB_TERM_DISP_LR:
|
|
||||||
return '+';
|
|
||||||
|
|
||||||
}
|
|
||||||
return '?';
|
|
||||||
}
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_uint32_t
|
|
||||||
mirror_code (grub_uint32_t in)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; grub_unicode_bidi_pairs[i].key; i++)
|
for (i = 0; grub_unicode_bidi_pairs[i].key; i++)
|
||||||
|
@ -1098,255 +1031,3 @@ mirror_code (grub_uint32_t in)
|
||||||
return grub_unicode_bidi_pairs[i].replace;
|
return grub_unicode_bidi_pairs[i].replace;
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
|
|
||||||
{
|
|
||||||
struct grub_unicode_glyph c2 =
|
|
||||||
{
|
|
||||||
.variant = 0,
|
|
||||||
.attributes = 0,
|
|
||||||
.ncomb = 0,
|
|
||||||
.combining = 0,
|
|
||||||
.estimated_width = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
if (c->base == '\t' && term->getxy)
|
|
||||||
{
|
|
||||||
int n;
|
|
||||||
|
|
||||||
n = 8 - ((term->getxy () >> 8) & 7);
|
|
||||||
c2.base = ' ';
|
|
||||||
while (n--)
|
|
||||||
(term->putchar) (&c2);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
|
||||||
== GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
|
|
||||||
|| (term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
|
||||||
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
c2.estimated_width = grub_term_getcharwidth (term, c);
|
|
||||||
for (i = -1; i < (int) c->ncomb; i++)
|
|
||||||
{
|
|
||||||
grub_uint8_t u8[20], *ptr;
|
|
||||||
grub_uint32_t code;
|
|
||||||
|
|
||||||
if (i == -1)
|
|
||||||
{
|
|
||||||
code = c->base;
|
|
||||||
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
|
||||||
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL
|
|
||||||
&& (c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR))
|
|
||||||
code = mirror_code (code);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
code = c->combining[i].code;
|
|
||||||
|
|
||||||
grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8));
|
|
||||||
|
|
||||||
for (ptr = u8; *ptr; ptr++)
|
|
||||||
{
|
|
||||||
c2.base = *ptr;
|
|
||||||
(term->putchar) (&c2);
|
|
||||||
c2.estimated_width = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c2.estimated_width = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
(term->putchar) (c);
|
|
||||||
|
|
||||||
if (c->base == '\n')
|
|
||||||
{
|
|
||||||
c2.base = '\r';
|
|
||||||
(term->putchar) (&c2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
putcode_real (grub_uint32_t code, struct grub_term_output *term)
|
|
||||||
{
|
|
||||||
struct grub_unicode_glyph c =
|
|
||||||
{
|
|
||||||
.variant = 0,
|
|
||||||
.attributes = 0,
|
|
||||||
.ncomb = 0,
|
|
||||||
.combining = 0,
|
|
||||||
.estimated_width = 1
|
|
||||||
};
|
|
||||||
|
|
||||||
c.base = map_code (code, term);
|
|
||||||
putglyph (&c, term);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Put a Unicode character. */
|
|
||||||
void
|
|
||||||
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
|
|
||||||
{
|
|
||||||
/* Combining character by itself? */
|
|
||||||
if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
putcode_real (code, term);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
grub_print_ucs4 (const grub_uint32_t * str,
|
|
||||||
const grub_uint32_t * last_position,
|
|
||||||
int margin_left, int margin_right,
|
|
||||||
struct grub_term_output *term)
|
|
||||||
{
|
|
||||||
grub_ssize_t max_width;
|
|
||||||
grub_ssize_t startwidth;
|
|
||||||
|
|
||||||
{
|
|
||||||
struct grub_unicode_glyph space_glyph = {
|
|
||||||
.base = ' ',
|
|
||||||
.variant = 0,
|
|
||||||
.attributes = 0,
|
|
||||||
.ncomb = 0,
|
|
||||||
.combining = 0
|
|
||||||
};
|
|
||||||
max_width = grub_term_width (term)
|
|
||||||
- grub_term_getcharwidth (term, &space_glyph)
|
|
||||||
* (margin_left + margin_right) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((term->getxy () >> 8) & 0xff) < margin_left)
|
|
||||||
grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff));
|
|
||||||
|
|
||||||
startwidth = ((term->getxy () >> 8) & 0xff) - margin_left;
|
|
||||||
|
|
||||||
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
|
||||||
== GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
|
|
||||||
|| (term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
|
||||||
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
|
|
||||||
{
|
|
||||||
grub_ssize_t visual_len;
|
|
||||||
struct grub_unicode_glyph *visual;
|
|
||||||
struct grub_unicode_glyph *visual_ptr;
|
|
||||||
|
|
||||||
auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c);
|
|
||||||
grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c)
|
|
||||||
{
|
|
||||||
return grub_term_getcharwidth (term, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
visual_len = grub_bidi_logical_to_visual (str, last_position - str,
|
|
||||||
&visual, getcharwidth,
|
|
||||||
max_width, startwidth);
|
|
||||||
if (visual_len < 0)
|
|
||||||
{
|
|
||||||
grub_print_error ();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++)
|
|
||||||
{
|
|
||||||
if (visual_ptr->base == '\n')
|
|
||||||
grub_print_spaces (term, margin_right);
|
|
||||||
putglyph (visual_ptr, term);
|
|
||||||
if (visual_ptr->base == '\n')
|
|
||||||
grub_print_spaces (term, margin_left);
|
|
||||||
grub_free (visual_ptr->combining);
|
|
||||||
}
|
|
||||||
grub_free (visual);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const grub_uint32_t *ptr;
|
|
||||||
grub_ssize_t line_width = startwidth;
|
|
||||||
grub_ssize_t lastspacewidth = 0;
|
|
||||||
const grub_uint32_t *line_start = str, *last_space = str - 1;
|
|
||||||
|
|
||||||
for (ptr = str; ptr < last_position; ptr++)
|
|
||||||
{
|
|
||||||
grub_ssize_t last_width = 0;
|
|
||||||
if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE)
|
|
||||||
{
|
|
||||||
struct grub_unicode_glyph c = {
|
|
||||||
.variant = 0,
|
|
||||||
.attributes = 0,
|
|
||||||
.ncomb = 0,
|
|
||||||
.combining = 0
|
|
||||||
};
|
|
||||||
c.base = *ptr;
|
|
||||||
line_width += last_width = grub_term_getcharwidth (term, &c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*ptr == ' ')
|
|
||||||
{
|
|
||||||
lastspacewidth = line_width;
|
|
||||||
last_space = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (line_width > max_width || *ptr == '\n')
|
|
||||||
{
|
|
||||||
const grub_uint32_t *ptr2;
|
|
||||||
|
|
||||||
if (line_width > max_width && last_space > line_start)
|
|
||||||
ptr = last_space;
|
|
||||||
else if (line_width > max_width
|
|
||||||
&& line_start == str && startwidth != 0)
|
|
||||||
{
|
|
||||||
ptr = str;
|
|
||||||
lastspacewidth = startwidth;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
lastspacewidth = line_width - last_width;
|
|
||||||
|
|
||||||
for (ptr2 = line_start; ptr2 < ptr; ptr2++)
|
|
||||||
{
|
|
||||||
/* Skip combining characters on non-UTF8 terminals. */
|
|
||||||
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
|
||||||
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
|
|
||||||
&& grub_unicode_get_comb_type (*ptr2)
|
|
||||||
!= GRUB_UNICODE_COMB_NONE)
|
|
||||||
continue;
|
|
||||||
putcode_real (*ptr2, term);
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_print_spaces (term, margin_right);
|
|
||||||
grub_putcode ('\n', term);
|
|
||||||
line_width -= lastspacewidth;
|
|
||||||
grub_print_spaces (term, margin_left);
|
|
||||||
if (ptr == last_space || *ptr == '\n')
|
|
||||||
ptr++;
|
|
||||||
line_start = ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const grub_uint32_t *ptr2;
|
|
||||||
for (ptr2 = line_start; ptr2 < last_position; ptr2++)
|
|
||||||
{
|
|
||||||
/* Skip combining characters on non-UTF8 terminals. */
|
|
||||||
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
|
||||||
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
|
|
||||||
&& grub_unicode_get_comb_type (*ptr2)
|
|
||||||
!= GRUB_UNICODE_COMB_NONE)
|
|
||||||
continue;
|
|
||||||
putcode_real (*ptr2, term);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
grub_xputs_normal (const char *str)
|
|
||||||
{
|
|
||||||
grub_term_output_t term;
|
|
||||||
|
|
||||||
FOR_ACTIVE_TERM_OUTPUTS(term)
|
|
||||||
{
|
|
||||||
grub_uint32_t *unicode_str, *unicode_last_position;
|
|
||||||
grub_utf8_to_ucs4_alloc (str, &unicode_str,
|
|
||||||
&unicode_last_position);
|
|
||||||
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
|
|
||||||
grub_free (unicode_str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
319
normal/term.c
319
normal/term.c
|
@ -95,6 +95,73 @@ grub_install_newline_hook (void)
|
||||||
grub_newline_hook = process_newline;
|
grub_newline_hook = process_newline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static grub_uint32_t
|
||||||
|
map_code (grub_uint32_t in, struct grub_term_output *term)
|
||||||
|
{
|
||||||
|
if (in <= 0x7f)
|
||||||
|
return in;
|
||||||
|
|
||||||
|
switch (term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
{
|
||||||
|
case GRUB_TERM_CODE_TYPE_VGA:
|
||||||
|
switch (in)
|
||||||
|
{
|
||||||
|
case GRUB_TERM_DISP_LEFT:
|
||||||
|
return 0x1b;
|
||||||
|
case GRUB_TERM_DISP_UP:
|
||||||
|
return 0x18;
|
||||||
|
case GRUB_TERM_DISP_RIGHT:
|
||||||
|
return 0x1a;
|
||||||
|
case GRUB_TERM_DISP_DOWN:
|
||||||
|
return 0x19;
|
||||||
|
case GRUB_TERM_DISP_HLINE:
|
||||||
|
return 0xc4;
|
||||||
|
case GRUB_TERM_DISP_VLINE:
|
||||||
|
return 0xb3;
|
||||||
|
case GRUB_TERM_DISP_UL:
|
||||||
|
return 0xda;
|
||||||
|
case GRUB_TERM_DISP_UR:
|
||||||
|
return 0xbf;
|
||||||
|
case GRUB_TERM_DISP_LL:
|
||||||
|
return 0xc0;
|
||||||
|
case GRUB_TERM_DISP_LR:
|
||||||
|
return 0xd9;
|
||||||
|
}
|
||||||
|
return '?';
|
||||||
|
case GRUB_TERM_CODE_TYPE_ASCII:
|
||||||
|
/* Better than nothing. */
|
||||||
|
switch (in)
|
||||||
|
{
|
||||||
|
case GRUB_TERM_DISP_LEFT:
|
||||||
|
return '<';
|
||||||
|
|
||||||
|
case GRUB_TERM_DISP_UP:
|
||||||
|
return '^';
|
||||||
|
|
||||||
|
case GRUB_TERM_DISP_RIGHT:
|
||||||
|
return '>';
|
||||||
|
|
||||||
|
case GRUB_TERM_DISP_DOWN:
|
||||||
|
return 'v';
|
||||||
|
|
||||||
|
case GRUB_TERM_DISP_HLINE:
|
||||||
|
return '-';
|
||||||
|
|
||||||
|
case GRUB_TERM_DISP_VLINE:
|
||||||
|
return '|';
|
||||||
|
|
||||||
|
case GRUB_TERM_DISP_UL:
|
||||||
|
case GRUB_TERM_DISP_UR:
|
||||||
|
case GRUB_TERM_DISP_LL:
|
||||||
|
case GRUB_TERM_DISP_LR:
|
||||||
|
return '+';
|
||||||
|
|
||||||
|
}
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
return in;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_puts_terminal (const char *str, struct grub_term_output *term)
|
grub_puts_terminal (const char *str, struct grub_term_output *term)
|
||||||
{
|
{
|
||||||
|
@ -265,3 +332,255 @@ read_terminal_list (void)
|
||||||
|
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_errno = GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
|
||||||
|
{
|
||||||
|
struct grub_unicode_glyph c2 =
|
||||||
|
{
|
||||||
|
.variant = 0,
|
||||||
|
.attributes = 0,
|
||||||
|
.ncomb = 0,
|
||||||
|
.combining = 0,
|
||||||
|
.estimated_width = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
if (c->base == '\t' && term->getxy)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = 8 - ((term->getxy () >> 8) & 7);
|
||||||
|
c2.base = ' ';
|
||||||
|
while (n--)
|
||||||
|
(term->putchar) (&c2);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
== GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
|
||||||
|
|| (term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
c2.estimated_width = grub_term_getcharwidth (term, c);
|
||||||
|
for (i = -1; i < (int) c->ncomb; i++)
|
||||||
|
{
|
||||||
|
grub_uint8_t u8[20], *ptr;
|
||||||
|
grub_uint32_t code;
|
||||||
|
|
||||||
|
if (i == -1)
|
||||||
|
{
|
||||||
|
code = c->base;
|
||||||
|
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL
|
||||||
|
&& (c->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR))
|
||||||
|
code = grub_unicode_mirror_code (code);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
code = c->combining[i].code;
|
||||||
|
|
||||||
|
grub_ucs4_to_utf8 (&code, 1, u8, sizeof (u8));
|
||||||
|
|
||||||
|
for (ptr = u8; *ptr; ptr++)
|
||||||
|
{
|
||||||
|
c2.base = *ptr;
|
||||||
|
(term->putchar) (&c2);
|
||||||
|
c2.estimated_width = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c2.estimated_width = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(term->putchar) (c);
|
||||||
|
|
||||||
|
if (c->base == '\n')
|
||||||
|
{
|
||||||
|
c2.base = '\r';
|
||||||
|
(term->putchar) (&c2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
putcode_real (grub_uint32_t code, struct grub_term_output *term)
|
||||||
|
{
|
||||||
|
struct grub_unicode_glyph c =
|
||||||
|
{
|
||||||
|
.variant = 0,
|
||||||
|
.attributes = 0,
|
||||||
|
.ncomb = 0,
|
||||||
|
.combining = 0,
|
||||||
|
.estimated_width = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
c.base = map_code (code, term);
|
||||||
|
putglyph (&c, term);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Put a Unicode character. */
|
||||||
|
void
|
||||||
|
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
|
||||||
|
{
|
||||||
|
/* Combining character by itself? */
|
||||||
|
if (grub_unicode_get_comb_type (code) != GRUB_UNICODE_COMB_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
putcode_real (code, term);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_print_ucs4 (const grub_uint32_t * str,
|
||||||
|
const grub_uint32_t * last_position,
|
||||||
|
int margin_left, int margin_right,
|
||||||
|
struct grub_term_output *term)
|
||||||
|
{
|
||||||
|
grub_ssize_t max_width;
|
||||||
|
grub_ssize_t startwidth;
|
||||||
|
|
||||||
|
{
|
||||||
|
struct grub_unicode_glyph space_glyph = {
|
||||||
|
.base = ' ',
|
||||||
|
.variant = 0,
|
||||||
|
.attributes = 0,
|
||||||
|
.ncomb = 0,
|
||||||
|
.combining = 0
|
||||||
|
};
|
||||||
|
max_width = grub_term_width (term)
|
||||||
|
- grub_term_getcharwidth (term, &space_glyph)
|
||||||
|
* (margin_left + margin_right) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (((term->getxy () >> 8) & 0xff) < margin_left)
|
||||||
|
grub_print_spaces (term, margin_left - ((term->getxy () >> 8) & 0xff));
|
||||||
|
|
||||||
|
startwidth = ((term->getxy () >> 8) & 0xff) - margin_left;
|
||||||
|
|
||||||
|
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
== GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS
|
||||||
|
|| (term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
|
||||||
|
{
|
||||||
|
grub_ssize_t visual_len;
|
||||||
|
struct grub_unicode_glyph *visual;
|
||||||
|
struct grub_unicode_glyph *visual_ptr;
|
||||||
|
|
||||||
|
auto grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c);
|
||||||
|
grub_ssize_t getcharwidth (const struct grub_unicode_glyph *c)
|
||||||
|
{
|
||||||
|
return grub_term_getcharwidth (term, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
visual_len = grub_bidi_logical_to_visual (str, last_position - str,
|
||||||
|
&visual, getcharwidth,
|
||||||
|
max_width, startwidth);
|
||||||
|
if (visual_len < 0)
|
||||||
|
{
|
||||||
|
grub_print_error ();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (visual_ptr = visual; visual_ptr < visual + visual_len; visual_ptr++)
|
||||||
|
{
|
||||||
|
if (visual_ptr->base == '\n')
|
||||||
|
grub_print_spaces (term, margin_right);
|
||||||
|
putglyph (visual_ptr, term);
|
||||||
|
if (visual_ptr->base == '\n')
|
||||||
|
grub_print_spaces (term, margin_left);
|
||||||
|
grub_free (visual_ptr->combining);
|
||||||
|
}
|
||||||
|
grub_free (visual);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const grub_uint32_t *ptr;
|
||||||
|
grub_ssize_t line_width = startwidth;
|
||||||
|
grub_ssize_t lastspacewidth = 0;
|
||||||
|
const grub_uint32_t *line_start = str, *last_space = str - 1;
|
||||||
|
|
||||||
|
for (ptr = str; ptr < last_position; ptr++)
|
||||||
|
{
|
||||||
|
grub_ssize_t last_width = 0;
|
||||||
|
if (grub_unicode_get_comb_type (*ptr) == GRUB_UNICODE_COMB_NONE)
|
||||||
|
{
|
||||||
|
struct grub_unicode_glyph c = {
|
||||||
|
.variant = 0,
|
||||||
|
.attributes = 0,
|
||||||
|
.ncomb = 0,
|
||||||
|
.combining = 0
|
||||||
|
};
|
||||||
|
c.base = *ptr;
|
||||||
|
line_width += last_width = grub_term_getcharwidth (term, &c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*ptr == ' ')
|
||||||
|
{
|
||||||
|
lastspacewidth = line_width;
|
||||||
|
last_space = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line_width > max_width || *ptr == '\n')
|
||||||
|
{
|
||||||
|
const grub_uint32_t *ptr2;
|
||||||
|
|
||||||
|
if (line_width > max_width && last_space > line_start)
|
||||||
|
ptr = last_space;
|
||||||
|
else if (line_width > max_width
|
||||||
|
&& line_start == str && startwidth != 0)
|
||||||
|
{
|
||||||
|
ptr = str;
|
||||||
|
lastspacewidth = startwidth;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lastspacewidth = line_width - last_width;
|
||||||
|
|
||||||
|
for (ptr2 = line_start; ptr2 < ptr; ptr2++)
|
||||||
|
{
|
||||||
|
/* Skip combining characters on non-UTF8 terminals. */
|
||||||
|
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
|
||||||
|
&& grub_unicode_get_comb_type (*ptr2)
|
||||||
|
!= GRUB_UNICODE_COMB_NONE)
|
||||||
|
continue;
|
||||||
|
putcode_real (*ptr2, term);
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_print_spaces (term, margin_right);
|
||||||
|
grub_putcode ('\n', term);
|
||||||
|
line_width -= lastspacewidth;
|
||||||
|
grub_print_spaces (term, margin_left);
|
||||||
|
if (ptr == last_space || *ptr == '\n')
|
||||||
|
ptr++;
|
||||||
|
line_start = ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const grub_uint32_t *ptr2;
|
||||||
|
for (ptr2 = line_start; ptr2 < last_position; ptr2++)
|
||||||
|
{
|
||||||
|
/* Skip combining characters on non-UTF8 terminals. */
|
||||||
|
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
!= GRUB_TERM_CODE_TYPE_UTF8_LOGICAL
|
||||||
|
&& grub_unicode_get_comb_type (*ptr2)
|
||||||
|
!= GRUB_UNICODE_COMB_NONE)
|
||||||
|
continue;
|
||||||
|
putcode_real (*ptr2, term);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
grub_xputs_normal (const char *str)
|
||||||
|
{
|
||||||
|
grub_term_output_t term;
|
||||||
|
|
||||||
|
FOR_ACTIVE_TERM_OUTPUTS(term)
|
||||||
|
{
|
||||||
|
grub_uint32_t *unicode_str, *unicode_last_position;
|
||||||
|
grub_utf8_to_ucs4_alloc (str, &unicode_str,
|
||||||
|
&unicode_last_position);
|
||||||
|
grub_print_ucs4 (unicode_str, unicode_last_position, 0, 0, term);
|
||||||
|
grub_free (unicode_str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue