Preliminary support for UTF-8 console
This commit is contained in:
parent
9a3355cfde
commit
f10331edf2
3 changed files with 69 additions and 39 deletions
|
@ -117,7 +117,9 @@ grub_is_valid_utf8 (const grub_uint8_t *src, grub_size_t srcsize);
|
||||||
|
|
||||||
int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
|
int grub_utf8_to_ucs4_alloc (const char *msg, grub_uint32_t **unicode_msg,
|
||||||
grub_uint32_t **last_position);
|
grub_uint32_t **last_position);
|
||||||
|
void
|
||||||
|
grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
|
||||||
|
grub_uint8_t *dest, grub_size_t destsize);
|
||||||
grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
|
grub_size_t grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
|
||||||
const grub_uint8_t *src, grub_size_t srcsize,
|
const grub_uint8_t *src, grub_size_t srcsize,
|
||||||
const grub_uint8_t **srcend);
|
const grub_uint8_t **srcend);
|
||||||
|
|
102
normal/charset.c
102
normal/charset.c
|
@ -120,6 +120,45 @@ grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
|
||||||
return p - dest;
|
return p - dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert UCS-4 to UTF-8. */
|
||||||
|
void
|
||||||
|
grub_ucs4_to_utf8 (grub_uint32_t *src, grub_size_t size,
|
||||||
|
grub_uint8_t *dest, grub_size_t destsize)
|
||||||
|
{
|
||||||
|
/* Keep last char for \0. */
|
||||||
|
grub_uint8_t *destend = dest + destsize - 1;
|
||||||
|
|
||||||
|
while (size-- && dest < destend)
|
||||||
|
{
|
||||||
|
grub_uint32_t code = *src++;
|
||||||
|
|
||||||
|
if (code <= 0x007F)
|
||||||
|
*dest++ = code;
|
||||||
|
else if (code <= 0x07FF)
|
||||||
|
{
|
||||||
|
if (dest + 1 >= destend)
|
||||||
|
break;
|
||||||
|
*dest++ = (code >> 6) | 0xC0;
|
||||||
|
*dest++ = (code & 0x3F) | 0x80;
|
||||||
|
}
|
||||||
|
else if ((code >= 0xDC00 && code <= 0xDFFF)
|
||||||
|
|| (code >= 0xD800 && code <= 0xDBFF))
|
||||||
|
{
|
||||||
|
/* No surrogates in UCS-4... */
|
||||||
|
*dest++ = '?';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (dest + 2 >= destend)
|
||||||
|
break;
|
||||||
|
*dest++ = (code >> 12) | 0xE0;
|
||||||
|
*dest++ = ((code >> 6) & 0x3F) | 0x80;
|
||||||
|
*dest++ = (code & 0x3F) | 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*dest = 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* Convert UCS-4 to UTF-8. */
|
/* Convert UCS-4 to UTF-8. */
|
||||||
char *
|
char *
|
||||||
grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
|
grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
|
||||||
|
@ -127,7 +166,7 @@ grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
|
||||||
grub_size_t remaining;
|
grub_size_t remaining;
|
||||||
grub_uint32_t *ptr;
|
grub_uint32_t *ptr;
|
||||||
grub_size_t cnt = 0;
|
grub_size_t cnt = 0;
|
||||||
grub_uint8_t *ret, *dest;
|
grub_uint8_t *ret;
|
||||||
|
|
||||||
remaining = size;
|
remaining = size;
|
||||||
ptr = src;
|
ptr = src;
|
||||||
|
@ -152,34 +191,7 @@ grub_ucs4_to_utf8_alloc (grub_uint32_t *src, grub_size_t size)
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dest = ret;
|
grub_ucs4_to_utf8 (src, size, ret, cnt);
|
||||||
remaining = size;
|
|
||||||
ptr = src;
|
|
||||||
while (remaining--)
|
|
||||||
{
|
|
||||||
grub_uint32_t code = *ptr++;
|
|
||||||
|
|
||||||
if (code <= 0x007F)
|
|
||||||
*dest++ = code;
|
|
||||||
else if (code <= 0x07FF)
|
|
||||||
{
|
|
||||||
*dest++ = (code >> 6) | 0xC0;
|
|
||||||
*dest++ = (code & 0x3F) | 0x80;
|
|
||||||
}
|
|
||||||
else if ((code >= 0xDC00 && code <= 0xDFFF)
|
|
||||||
|| (code >= 0xD800 && code <= 0xDBFF))
|
|
||||||
{
|
|
||||||
/* No surrogates in UCS-4... */
|
|
||||||
*dest++ = '?';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*dest++ = (code >> 12) | 0xE0;
|
|
||||||
*dest++ = ((code >> 6) & 0x3F) | 0x80;
|
|
||||||
*dest++ = (code & 0x3F) | 0x80;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*dest = 0;
|
|
||||||
|
|
||||||
return (char *) ret;
|
return (char *) ret;
|
||||||
}
|
}
|
||||||
|
@ -953,8 +965,9 @@ map_code (grub_uint32_t in, struct grub_term_output *term)
|
||||||
if (in <= 0x7f)
|
if (in <= 0x7f)
|
||||||
return in;
|
return in;
|
||||||
|
|
||||||
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK) == GRUB_TERM_CODE_TYPE_VGA)
|
switch (term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
{
|
{
|
||||||
|
case GRUB_TERM_CODE_TYPE_VGA:
|
||||||
switch (in)
|
switch (in)
|
||||||
{
|
{
|
||||||
case GRUB_TERM_DISP_LEFT:
|
case GRUB_TERM_DISP_LEFT:
|
||||||
|
@ -979,9 +992,7 @@ map_code (grub_uint32_t in, struct grub_term_output *term)
|
||||||
return 0xd9;
|
return 0xd9;
|
||||||
}
|
}
|
||||||
return '?';
|
return '?';
|
||||||
}
|
case GRUB_TERM_CODE_TYPE_ASCII:
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Better than nothing. */
|
/* Better than nothing. */
|
||||||
switch (in)
|
switch (in)
|
||||||
{
|
{
|
||||||
|
@ -990,7 +1001,7 @@ map_code (grub_uint32_t in, struct grub_term_output *term)
|
||||||
|
|
||||||
case GRUB_TERM_DISP_UP:
|
case GRUB_TERM_DISP_UP:
|
||||||
return '^';
|
return '^';
|
||||||
|
|
||||||
case GRUB_TERM_DISP_RIGHT:
|
case GRUB_TERM_DISP_RIGHT:
|
||||||
return '>';
|
return '>';
|
||||||
|
|
||||||
|
@ -1017,8 +1028,7 @@ map_code (grub_uint32_t in, struct grub_term_output *term)
|
||||||
|
|
||||||
/* Put a Unicode character. */
|
/* Put a Unicode character. */
|
||||||
void
|
void
|
||||||
grub_putcode (grub_uint32_t code,
|
grub_putcode (grub_uint32_t code, struct grub_term_output *term)
|
||||||
struct grub_term_output *term)
|
|
||||||
{
|
{
|
||||||
struct grub_unicode_glyph c =
|
struct grub_unicode_glyph c =
|
||||||
{
|
{
|
||||||
|
@ -1042,9 +1052,25 @@ grub_putcode (grub_uint32_t code,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.base = map_code (code, term);
|
if ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
== GRUB_TERM_CODE_TYPE_UTF8_LOGICAL)
|
||||||
|
{
|
||||||
|
grub_uint8_t str[20], *ptr;
|
||||||
|
|
||||||
|
grub_ucs4_to_utf8 (&code, 1, str, sizeof (str));
|
||||||
|
|
||||||
|
for (ptr = str; *ptr; ptr++)
|
||||||
|
{
|
||||||
|
c.base = *ptr;
|
||||||
|
(term->putchar) (&c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c.base = map_code (code, term);
|
||||||
|
(term->putchar) (&c);
|
||||||
|
}
|
||||||
|
|
||||||
(term->putchar) (&c);
|
|
||||||
if (code == '\n')
|
if (code == '\n')
|
||||||
grub_putcode ('\r', term);
|
grub_putcode ('\r', term);
|
||||||
}
|
}
|
||||||
|
|
|
@ -343,6 +343,8 @@ grub_serial_putchar (const struct grub_unicode_glyph *c)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
if ((c->base & 0xC0) == 0xC0)
|
||||||
|
break;
|
||||||
if (xpos >= TEXT_WIDTH)
|
if (xpos >= TEXT_WIDTH)
|
||||||
{
|
{
|
||||||
xpos = 0;
|
xpos = 0;
|
||||||
|
|
Loading…
Reference in a new issue