Fix doublewidth character handling
This commit is contained in:
parent
2b5af23fa5
commit
6c363dfd54
6 changed files with 121 additions and 17 deletions
|
@ -259,7 +259,13 @@ ascii.bitmaps: $(FONT_SOURCE) grub-mkfont
|
||||||
ascii.h: ascii.bitmaps grub-bin2h
|
ascii.h: ascii.bitmaps grub-bin2h
|
||||||
$(builddir)/grub-bin2h ascii_bitmaps < $< > $@
|
$(builddir)/grub-bin2h ascii_bitmaps < $< > $@
|
||||||
|
|
||||||
TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1
|
widthspec.bin: $(FONT_SOURCE) grub-mkfont
|
||||||
|
$(builddir)/grub-mkfont --width-spec -o $@ $(FONT_SOURCE)
|
||||||
|
|
||||||
|
widthspec.h: widthspec.bin grub-bin2h
|
||||||
|
$(builddir)/grub-bin2h widthspec < $< > $@
|
||||||
|
|
||||||
|
TARGET_CFLAGS += -DUSE_ASCII_FAILBACK=1 -DHAVE_UNIFONT_WIDTHSPEC=1
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
|
@ -640,6 +640,10 @@ normal_mod_SOURCES = normal/main.c normal/cmdline.c normal/dyncmd.c \
|
||||||
normal/menu_entry.c normal/menu_text.c normal/charset.c \
|
normal/menu_entry.c normal/menu_text.c normal/charset.c \
|
||||||
normal/misc.c normal/crypto.c normal/term.c normal/context.c \
|
normal/misc.c normal/crypto.c normal/term.c normal/context.c \
|
||||||
unidata.c
|
unidata.c
|
||||||
|
ifneq (, $(FONT_SOURCE))
|
||||||
|
normal/charset.c_SOURCES += widthspec.h
|
||||||
|
endif
|
||||||
|
|
||||||
normal_mod_CFLAGS = $(COMMON_CFLAGS)
|
normal_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||||
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
normal_mod_LDFLAGS = $(COMMON_LDFLAGS)
|
||||||
|
|
||||||
|
|
|
@ -380,12 +380,36 @@ grub_term_cls (struct grub_term_output *term)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_UNIFONT_WIDTHSPEC
|
||||||
|
|
||||||
|
grub_ssize_t
|
||||||
|
grub_unicode_estimate_width (const struct grub_unicode_glyph *c);
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline grub_ssize_t
|
||||||
|
grub_unicode_estimate_width (const struct grub_unicode_glyph *c __attribute__ ((unused)))
|
||||||
|
{
|
||||||
|
if (grub_unicode_get_comb_type (c->base))
|
||||||
|
return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
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 (term->getcharwidth)
|
if (term->getcharwidth)
|
||||||
return term->getcharwidth (c);
|
return term->getcharwidth (c);
|
||||||
|
else 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)
|
||||||
|
|| ((term->flags & GRUB_TERM_CODE_TYPE_MASK)
|
||||||
|
== GRUB_TERM_CODE_TYPE_VISUAL_GLYPHS))
|
||||||
|
return grub_unicode_estimate_width (c);
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,6 +30,10 @@
|
||||||
#include <grub/term.h>
|
#include <grub/term.h>
|
||||||
#include <grub/normal.h>
|
#include <grub/normal.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_UNIFONT_WIDTHSPEC
|
||||||
|
#include "widthspec.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
grub_ssize_t
|
grub_ssize_t
|
||||||
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
|
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
|
||||||
const grub_uint8_t *src, grub_size_t srcsize,
|
const grub_uint8_t *src, grub_size_t srcsize,
|
||||||
|
@ -465,6 +469,21 @@ grub_unicode_get_comb_type (grub_uint32_t c)
|
||||||
return GRUB_UNICODE_COMB_NONE;
|
return GRUB_UNICODE_COMB_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_UNIFONT_WIDTHSPEC
|
||||||
|
|
||||||
|
grub_ssize_t
|
||||||
|
grub_unicode_estimate_width (const struct grub_unicode_glyph *c)
|
||||||
|
{
|
||||||
|
if (grub_unicode_get_comb_type (c->base))
|
||||||
|
return 0;
|
||||||
|
if (widthspec[c->base >> 3] & (1 << (c->base & 7)))
|
||||||
|
return 2;
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
grub_size_t
|
grub_size_t
|
||||||
grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
||||||
struct grub_unicode_glyph *out)
|
struct grub_unicode_glyph *out)
|
||||||
|
@ -1098,7 +1117,7 @@ putglyph (const struct grub_unicode_glyph *c, struct grub_term_output *term)
|
||||||
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
|
== GRUB_TERM_CODE_TYPE_UTF8_VISUAL)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
c2.estimated_width = 1;
|
c2.estimated_width = grub_term_getcharwidth (term, c);
|
||||||
for (i = -1; i < (int) c->ncomb; i++)
|
for (i = -1; i < (int) c->ncomb; i++)
|
||||||
{
|
{
|
||||||
grub_uint8_t u8[20], *ptr;
|
grub_uint8_t u8[20], *ptr;
|
||||||
|
@ -1192,8 +1211,15 @@ grub_print_ucs4 (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;
|
||||||
struct grub_unicode_glyph *visual_ptr;
|
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_len = grub_bidi_logical_to_visual (str, last_position - str,
|
||||||
&visual, term->getcharwidth,
|
&visual, getcharwidth,
|
||||||
max_width, startwidth);
|
max_width, startwidth);
|
||||||
if (visual_len < 0)
|
if (visual_len < 0)
|
||||||
{
|
{
|
||||||
|
@ -1231,7 +1257,7 @@ grub_print_ucs4 (const grub_uint32_t * str,
|
||||||
.combining = 0
|
.combining = 0
|
||||||
};
|
};
|
||||||
c.base = *ptr;
|
c.base = *ptr;
|
||||||
line_width += last_width = term->getcharwidth (&c);
|
line_width += last_width = grub_term_getcharwidth (term, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*ptr == ' ')
|
if (*ptr == ' ')
|
||||||
|
@ -1279,7 +1305,15 @@ grub_print_ucs4 (const grub_uint32_t * str,
|
||||||
{
|
{
|
||||||
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++)
|
||||||
grub_putcode (*ptr2, term);
|
{
|
||||||
|
/* 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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -364,12 +364,6 @@ grub_serial_putchar (const struct grub_unicode_glyph *c)
|
||||||
serial_hw_put (c->base);
|
serial_hw_put (c->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static grub_ssize_t
|
|
||||||
grub_serial_getcharwidth (const struct grub_unicode_glyph *c __attribute__ ((unused)))
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static grub_uint16_t
|
static grub_uint16_t
|
||||||
grub_serial_getwh (void)
|
grub_serial_getwh (void)
|
||||||
{
|
{
|
||||||
|
@ -449,7 +443,6 @@ static struct grub_term_output grub_serial_term_output =
|
||||||
{
|
{
|
||||||
.name = "serial",
|
.name = "serial",
|
||||||
.putchar = grub_serial_putchar,
|
.putchar = grub_serial_putchar,
|
||||||
.getcharwidth = grub_serial_getcharwidth,
|
|
||||||
.getwh = grub_serial_getwh,
|
.getwh = grub_serial_getwh,
|
||||||
.getxy = grub_serial_getxy,
|
.getxy = grub_serial_getxy,
|
||||||
.gotoxy = grub_serial_gotoxy,
|
.gotoxy = grub_serial_gotoxy,
|
||||||
|
|
|
@ -53,7 +53,8 @@ struct grub_glyph_info
|
||||||
enum file_formats
|
enum file_formats
|
||||||
{
|
{
|
||||||
PF2,
|
PF2,
|
||||||
ASCII_BITMAPS
|
ASCII_BITMAPS,
|
||||||
|
WIDTH_SPEC
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GRUB_FONT_FLAG_BOLD 1
|
#define GRUB_FONT_FLAG_BOLD 1
|
||||||
|
@ -95,6 +96,7 @@ static struct option options[] =
|
||||||
{"version", no_argument, 0, 'V'},
|
{"version", no_argument, 0, 'V'},
|
||||||
{"verbose", no_argument, 0, 'v'},
|
{"verbose", no_argument, 0, 'v'},
|
||||||
{"ascii-bitmaps", no_argument, 0, 0x102},
|
{"ascii-bitmaps", no_argument, 0, 0x102},
|
||||||
|
{"width-spec", no_argument, 0, 0x103},
|
||||||
{0, 0, 0, 0}
|
{0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,6 +113,7 @@ Usage: %s [OPTIONS] FONT_FILES\n\
|
||||||
\nOptions:\n\
|
\nOptions:\n\
|
||||||
-o, --output=FILE_NAME set output file name\n\
|
-o, --output=FILE_NAME set output file name\n\
|
||||||
--ascii-bitmaps save only the ASCII bitmaps\n\
|
--ascii-bitmaps save only the ASCII bitmaps\n\
|
||||||
|
--width-spec create width summary file\n\
|
||||||
-i, --index=N set face index\n\
|
-i, --index=N set face index\n\
|
||||||
-r, --range=A-B[,C-D] set font range\n\
|
-r, --range=A-B[,C-D] set font range\n\
|
||||||
-n, --name=S set font family name\n\
|
-n, --name=S set font family name\n\
|
||||||
|
@ -380,6 +383,32 @@ write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file)
|
||||||
fclose (file);
|
fclose (file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
write_font_width_spec (struct grub_font_info *font_info, char *output_file)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
struct grub_glyph_info *glyph;
|
||||||
|
grub_uint8_t *out;
|
||||||
|
grub_uint8_t *rle;
|
||||||
|
int rle_size;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
out = xmalloc (8192);
|
||||||
|
memset (out, 0, 8192);
|
||||||
|
|
||||||
|
file = fopen (output_file, "wb");
|
||||||
|
if (! file)
|
||||||
|
grub_util_error ("Can\'t write to file %s.", output_file);
|
||||||
|
|
||||||
|
for (glyph = font_info->glyph; glyph; glyph = glyph->next)
|
||||||
|
if (glyph->width > 12)
|
||||||
|
out[glyph->char_code >> 3] |= (1 << (glyph->char_code & 7));
|
||||||
|
|
||||||
|
fwrite (out, 8192, 1, file);
|
||||||
|
fclose (file);
|
||||||
|
free (out);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
write_font_pf2 (struct grub_font_info *font_info, char *output_file)
|
write_font_pf2 (struct grub_font_info *font_info, char *output_file)
|
||||||
{
|
{
|
||||||
|
@ -648,6 +677,10 @@ main (int argc, char *argv[])
|
||||||
file_format = ASCII_BITMAPS;
|
file_format = ASCII_BITMAPS;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x103:
|
||||||
|
file_format = WIDTH_SPEC;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
usage (1);
|
usage (1);
|
||||||
break;
|
break;
|
||||||
|
@ -712,10 +745,20 @@ main (int argc, char *argv[])
|
||||||
|
|
||||||
FT_Done_FreeType (ft_lib);
|
FT_Done_FreeType (ft_lib);
|
||||||
|
|
||||||
if (file_format == PF2)
|
switch (file_format)
|
||||||
|
{
|
||||||
|
case PF2:
|
||||||
write_font_pf2 (&font_info, output_file);
|
write_font_pf2 (&font_info, output_file);
|
||||||
else if (file_format == ASCII_BITMAPS)
|
break;
|
||||||
|
|
||||||
|
case ASCII_BITMAPS:
|
||||||
write_font_ascii_bitmap (&font_info, output_file);
|
write_font_ascii_bitmap (&font_info, output_file);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WIDTH_SPEC:
|
||||||
|
write_font_width_spec (&font_info, output_file);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (font_verbosity > 1)
|
if (font_verbosity > 1)
|
||||||
print_glyphs (&font_info);
|
print_glyphs (&font_info);
|
||||||
|
|
Loading…
Reference in a new issue