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
|
||||
$(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
|
||||
|
||||
|
|
|
@ -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/misc.c normal/crypto.c normal/term.c normal/context.c \
|
||||
unidata.c
|
||||
ifneq (, $(FONT_SOURCE))
|
||||
normal/charset.c_SOURCES += widthspec.h
|
||||
endif
|
||||
|
||||
normal_mod_CFLAGS = $(COMMON_CFLAGS)
|
||||
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
|
||||
grub_term_getcharwidth (struct grub_term_output *term,
|
||||
const struct grub_unicode_glyph *c)
|
||||
{
|
||||
if (term->getcharwidth)
|
||||
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
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,10 @@
|
|||
#include <grub/term.h>
|
||||
#include <grub/normal.h>
|
||||
|
||||
#ifdef HAVE_UNIFONT_WIDTHSPEC
|
||||
#include "widthspec.h"
|
||||
#endif
|
||||
|
||||
grub_ssize_t
|
||||
grub_utf8_to_utf16 (grub_uint16_t *dest, grub_size_t destsize,
|
||||
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;
|
||||
}
|
||||
|
||||
#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_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen,
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
c2.estimated_width = 1;
|
||||
c2.estimated_width = grub_term_getcharwidth (term, c);
|
||||
for (i = -1; i < (int) c->ncomb; i++)
|
||||
{
|
||||
grub_uint8_t u8[20], *ptr;
|
||||
|
@ -1192,8 +1211,15 @@ grub_print_ucs4 (const grub_uint32_t * str,
|
|||
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, term->getcharwidth,
|
||||
&visual, getcharwidth,
|
||||
max_width, startwidth);
|
||||
if (visual_len < 0)
|
||||
{
|
||||
|
@ -1231,7 +1257,7 @@ grub_print_ucs4 (const grub_uint32_t * str,
|
|||
.combining = 0
|
||||
};
|
||||
c.base = *ptr;
|
||||
line_width += last_width = term->getcharwidth (&c);
|
||||
line_width += last_width = grub_term_getcharwidth (term, &c);
|
||||
}
|
||||
|
||||
if (*ptr == ' ')
|
||||
|
@ -1279,7 +1305,15 @@ grub_print_ucs4 (const grub_uint32_t * str,
|
|||
{
|
||||
const grub_uint32_t *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);
|
||||
}
|
||||
|
||||
static grub_ssize_t
|
||||
grub_serial_getcharwidth (const struct grub_unicode_glyph *c __attribute__ ((unused)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static grub_uint16_t
|
||||
grub_serial_getwh (void)
|
||||
{
|
||||
|
@ -449,7 +443,6 @@ static struct grub_term_output grub_serial_term_output =
|
|||
{
|
||||
.name = "serial",
|
||||
.putchar = grub_serial_putchar,
|
||||
.getcharwidth = grub_serial_getcharwidth,
|
||||
.getwh = grub_serial_getwh,
|
||||
.getxy = grub_serial_getxy,
|
||||
.gotoxy = grub_serial_gotoxy,
|
||||
|
|
|
@ -53,7 +53,8 @@ struct grub_glyph_info
|
|||
enum file_formats
|
||||
{
|
||||
PF2,
|
||||
ASCII_BITMAPS
|
||||
ASCII_BITMAPS,
|
||||
WIDTH_SPEC
|
||||
};
|
||||
|
||||
#define GRUB_FONT_FLAG_BOLD 1
|
||||
|
@ -95,6 +96,7 @@ static struct option options[] =
|
|||
{"version", no_argument, 0, 'V'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{"ascii-bitmaps", no_argument, 0, 0x102},
|
||||
{"width-spec", no_argument, 0, 0x103},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -111,6 +113,7 @@ Usage: %s [OPTIONS] FONT_FILES\n\
|
|||
\nOptions:\n\
|
||||
-o, --output=FILE_NAME set output file name\n\
|
||||
--ascii-bitmaps save only the ASCII bitmaps\n\
|
||||
--width-spec create width summary file\n\
|
||||
-i, --index=N set face index\n\
|
||||
-r, --range=A-B[,C-D] set font range\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);
|
||||
}
|
||||
|
||||
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
|
||||
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;
|
||||
break;
|
||||
|
||||
case 0x103:
|
||||
file_format = WIDTH_SPEC;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage (1);
|
||||
break;
|
||||
|
@ -712,10 +745,20 @@ main (int argc, char *argv[])
|
|||
|
||||
FT_Done_FreeType (ft_lib);
|
||||
|
||||
if (file_format == PF2)
|
||||
write_font_pf2 (&font_info, output_file);
|
||||
else if (file_format == ASCII_BITMAPS)
|
||||
write_font_ascii_bitmap (&font_info, output_file);
|
||||
switch (file_format)
|
||||
{
|
||||
case PF2:
|
||||
write_font_pf2 (&font_info, output_file);
|
||||
break;
|
||||
|
||||
case ASCII_BITMAPS:
|
||||
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)
|
||||
print_glyphs (&font_info);
|
||||
|
|
Loading…
Reference in a new issue