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
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)
}
}
+#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;
}
#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,
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)
== 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;
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)
{
.combining = 0
};
c.base = *ptr;
- line_width += last_width = term->getcharwidth (&c);
+ line_width += last_width = grub_term_getcharwidth (term, &c);
}
if (*ptr == ' ')
{
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);
+ }
}
}
}
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)
{
{
.name = "serial",
.putchar = grub_serial_putchar,
- .getcharwidth = grub_serial_getcharwidth,
.getwh = grub_serial_getwh,
.getxy = grub_serial_getxy,
.gotoxy = grub_serial_gotoxy,
enum file_formats
{
PF2,
- ASCII_BITMAPS
+ ASCII_BITMAPS,
+ WIDTH_SPEC
};
#define GRUB_FONT_FLAG_BOLD 1
{"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}
};
\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\
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)
{
file_format = ASCII_BITMAPS;
break;
+ case 0x103:
+ file_format = WIDTH_SPEC;
+ break;
+
default:
usage (1);
break;
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);