diff --git a/ChangeLog b/ChangeLog index e18206fd2..8cc8093e3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2013-08-21 Vladimir Serbinenko + + Move ascii.h and widthspec.h generation to a separate build-time-only + tool. + 2013-08-16 Grégoire Sutre * grub-core/loader/i386/bsd.c (grub_netbsd_add_boot_disk_and_wedge): diff --git a/Makefile.am b/Makefile.am index 9b42d5fa1..7343182cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -69,8 +69,11 @@ starfield_theme_files = $(srcdir)/themes/starfield/blob_w.png $(srcdir)/themes/s build-grub-mkfont: util/grub-mkfont.c grub-core/unidata.c grub-core/kern/emu/argp_common.c grub-core/kern/emu/misc.c util/misc.c grub-core/gnulib/progname.c $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) -I$(top_srcdir)/grub-core/gnulib -DGRUB_MKFONT=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) $(LIBINTL) -build-grub-bin2h: util/bin2h.c - $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $< +build-grub-gen-asciih: util/grub-gen-asciih.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) -I$(top_srcdir)/grub-core/gnulib -DGRUB_MKFONT=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) $(LIBINTL) -Wall -Werror + +build-grub-gen-widthspec: util/grub-gen-widthspec.c + $(BUILD_CC) -o $@ -I$(top_srcdir)/include $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) -I$(top_srcdir)/grub-core/gnulib -DGRUB_MKFONT=1 -DGRUB_UTIL=1 $^ $(build_freetype_cflags) $(build_freetype_libs) $(LIBINTL) -Wall -Werror if COND_STARFIELD starfield_DATA = dejavu_10.pf2 dejavu_12.pf2 dejavu_bold_14.pf2 dejavu_14.pf2 dejavu_16.pf2 $(starfield_theme_files) @@ -107,20 +110,12 @@ euro.pf2: $(FONT_SOURCE) build-grub-mkfont ./build-grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x4ff,0x1e00-0x1fff,$(UNICODE_ARROWS),$(UNICODE_LINES) CLEANFILES += euro.pf2 -ascii.bitmaps: $(FONT_SOURCE) build-grub-mkfont - ./build-grub-mkfont --ascii-bitmaps -o $@ $(FONT_SOURCE) -CLEANFILES += ascii.bitmaps +ascii.h: $(FONT_SOURCE) build-grub-gen-asciih + ./build-grub-gen-asciih $(FONT_SOURCE) $@ +CLEANFILES += ascii.h -ascii.h: ascii.bitmaps build-grub-bin2h - ./build-grub-bin2h ascii_bitmaps < $< > $@ -CLEANFILES += ascii.h $(top_builddir)/grub-core/include/ascii.h - -widthspec.bin: $(FONT_SOURCE) build-grub-mkfont - ./build-grub-mkfont --width-spec -o $@ $(FONT_SOURCE) -CLEANFILES += widthspec.bin - -widthspec.h: widthspec.bin build-grub-bin2h - ./build-grub-bin2h widthspec < $< > $@ +widthspec.h: $(FONT_SOURCE) build-grub-gen-asciih + ./build-grub-gen-widthspec $(FONT_SOURCE) $@ CLEANFILES += widthspec.h # Install config.h into platformdir diff --git a/util/grub-gen-asciih.c b/util/grub-gen-asciih.c new file mode 100644 index 000000000..2e3669918 --- /dev/null +++ b/util/grub-gen-asciih.c @@ -0,0 +1,253 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +#include + +#include +#include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H +#include FT_TRUETYPE_TABLES_H +#include + +#undef __FTERRORS_H__ +#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { +#define FT_ERRORDEF(e, v, s) [e] = s, +#define FT_ERROR_END_LIST }; +#include FT_ERRORS_H + +#define GRUB_FONT_DEFAULT_SIZE 16 + +#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) + +struct grub_glyph_info +{ + int width; + int height; + int x_ofs; + int y_ofs; + int device_width; + int bitmap_size; + unsigned char *bitmap; +}; + +static void +add_pixel (unsigned char **data, int *mask, int not_blank) +{ + if (*mask == 0) + { + (*data)++; + **data = 0; + *mask = 128; + } + + if (not_blank) + **data |= *mask; + + *mask >>= 1; +} + +static void +add_glyph (FT_UInt glyph_idx, FT_Face face, + unsigned int char_code, + struct grub_glyph_info *glyph_info) +{ + int width, height; + int cuttop, cutbottom, cutleft, cutright; + unsigned char *data; + int mask, i, j, bitmap_size; + FT_GlyphSlot glyph; + int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME; + FT_Error err; + + err = FT_Load_Glyph (face, glyph_idx, flag); + if (err) + { + printf ("Freetype Error %d loading glyph 0x%x for U+0x%x", + err, glyph_idx, char_code); + + if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) + printf (": %s\n", ft_errmsgs[err]); + else + printf ("\n"); + return; + } + + glyph = face->glyph; + + if (glyph->next) + printf ("%x\n", char_code); + + cuttop = cutbottom = cutleft = cutright = 0; + + width = glyph->bitmap.width; + height = glyph->bitmap.rows; + + bitmap_size = ((width * height + 7) / 8); + glyph_info->bitmap = malloc (bitmap_size); + if (!glyph_info->bitmap) + { + fprintf (stderr, "grub-gen-asciih: error: out of memory"); + exit (1); + } + glyph_info->bitmap_size = bitmap_size; + + glyph_info->width = width; + glyph_info->height = height; + glyph_info->x_ofs = glyph->bitmap_left; + glyph_info->y_ofs = glyph->bitmap_top - height; + glyph_info->device_width = glyph->metrics.horiAdvance / 64; + + mask = 0; + data = &glyph_info->bitmap[0] - 1; + for (j = cuttop; j < height + cuttop; j++) + for (i = cutleft; i < width + cutleft; i++) + add_pixel (&data, &mask, + glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] & + (1 << (7 - (i & 7)))); +} + +static void +write_font_ascii_bitmap (FILE *file, FT_Face face) +{ + struct grub_glyph_info glyph; + int char_code; + + fprintf (file, "/* THIS CHUNK OF BYTES IS AUTOMATICALLY GENERATED */\n"); + fprintf (file, "unsigned char ascii_bitmaps[] =\n"); + fprintf (file, "{\n"); + + for (char_code = 0; char_code <= 0x7f; char_code++) + { + FT_UInt glyph_idx; + + glyph_idx = FT_Get_Char_Index (face, char_code); + if (!glyph_idx) + return; + add_glyph (glyph_idx, face, char_code, &glyph); + + if (glyph.width == 8 && glyph.height == 16 + && glyph.x_ofs == 0 && glyph.y_ofs == 0) + { + int row; + for (row = 0; row < 16; row++) + fprintf (file, "0x%02x, ", glyph.bitmap[row]); + } + else + { + unsigned char glph[16]; + int p = 0, mask = 0x80; + int row, col; + int dy = 12 - glyph.height - glyph.y_ofs; + for (row = 0; row < 16; row++) + glph[row] = 0; + for (row = 0; row < glyph.height; row++) + for (col = 0; col < glyph.width; col++) + { + int val = glyph.bitmap[p] & mask; + mask >>= 1; + if (mask == 0) + { + mask = 0x80; + p++; + } + if (val && dy + row >= 0 + && dy + row < 16 + && glyph.x_ofs + col >= 0 + && glyph.x_ofs + col < 8) + glph[dy + row] |= 1 << (7 - (glyph.x_ofs + col)); + } + for (row = 0; row < 16; row++) + fprintf (file, "0x%02x, ", glph[row]); + } + fprintf (file, "\n"); + free (glyph.bitmap); + } + fprintf (file, "};\n"); +} + +int +main (int argc, char *argv[]) +{ + FT_Library ft_lib; + FT_Face ft_face; + FILE *file; + + if (argc != 3) + { + fprintf (stderr, "grub-gen-asciih: usage: INPUT OUTPUT"); + return 1; + } + + if (FT_Init_FreeType (&ft_lib)) + { + fprintf (stderr, "grub-gen-asciih: error: FT_Init_FreeType fails"); + return 1; + } + + { + int size; + FT_Error err; + + err = FT_New_Face (ft_lib, argv[1], 0, &ft_face); + if (err) + { + fprintf (stderr, "can't open file %s, index %d: error %d", + argv[1], 0, err); + if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) + fprintf (stderr, ": %s\n", ft_errmsgs[err]); + else + fprintf (stderr, "\n"); + + return 1; + } + + if ((ft_face->face_flags & FT_FACE_FLAG_SCALABLE) || + (! ft_face->num_fixed_sizes)) + size = GRUB_FONT_DEFAULT_SIZE; + else + size = ft_face->available_sizes[0].height; + + if (FT_Set_Pixel_Sizes (ft_face, size, size)) + { + fprintf (stderr, "grub-gen-asciih: error: can't set %dx%d font size", size, size); + return 1; + } + } + + file = fopen (argv[2], "w"); + if (! file) + { + fprintf (stderr, "grub-gen-asciih: error: cannot write to `%s': %s", argv[2], + strerror (errno)); + return 1; + } + + write_font_ascii_bitmap (file, ft_face); + + fclose (file); + + FT_Done_Face (ft_face); + + FT_Done_FreeType (ft_lib); + + return 0; +} diff --git a/util/grub-gen-widthspec.c b/util/grub-gen-widthspec.c new file mode 100644 index 000000000..ffd4f9866 --- /dev/null +++ b/util/grub-gen-widthspec.c @@ -0,0 +1,153 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2009,2010 Free Software Foundation, Inc. + * + * GRUB is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GRUB is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GRUB. If not, see . + */ + +#include +#include +#include + +#include + +#include +#include FT_FREETYPE_H +#include FT_TRUETYPE_TAGS_H +#include FT_TRUETYPE_TABLES_H +#include + +#undef __FTERRORS_H__ +#define FT_ERROR_START_LIST const char *ft_errmsgs[] = { +#define FT_ERRORDEF(e, v, s) [e] = s, +#define FT_ERROR_END_LIST }; +#include FT_ERRORS_H + +#define GRUB_FONT_DEFAULT_SIZE 16 + +#define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) + +#define MAX_CODE 65536 +static unsigned char result[MAX_CODE / 8]; + +static void +add_glyph (FT_Face face, + unsigned int char_code) +{ + int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME; + FT_Error err; + FT_UInt glyph_idx; + + glyph_idx = FT_Get_Char_Index (face, char_code); + if (!glyph_idx) + return; + + err = FT_Load_Glyph (face, glyph_idx, flag); + if (err) + { + printf ("Freetype Error %d loading glyph 0x%x for U+0x%x", + err, glyph_idx, char_code); + + if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) + printf (": %s\n", ft_errmsgs[err]); + else + printf ("\n"); + return; + } + + if (face->glyph->bitmap.width > 12 && char_code < MAX_CODE) + result[char_code >> 3] |= (1 << (char_code & 7)); +} + +int +main (int argc, char *argv[]) +{ + FT_Library ft_lib; + FILE *file; + int i; + + if (argc != 3) + { + fprintf (stderr, "grub-gen-widthspec: usage: INPUT OUTPUT"); + return 1; + } + + if (FT_Init_FreeType (&ft_lib)) + { + fprintf (stderr, "grub-gen-widthspec: error: FT_Init_FreeType fails"); + return 1; + } + + { + FT_Face ft_face; + int size; + FT_Error err; + unsigned int char_code, glyph_index; + + err = FT_New_Face (ft_lib, argv[1], 0, &ft_face); + if (err) + { + fprintf (stderr, "can't open file %s, index %d: error %d", + argv[1], 0, err); + if (err > 0 && err < (signed) ARRAY_SIZE (ft_errmsgs)) + fprintf (stderr, ": %s\n", ft_errmsgs[err]); + else + fprintf (stderr, "\n"); + + return 1; + } + + if ((ft_face->face_flags & FT_FACE_FLAG_SCALABLE) || + (! ft_face->num_fixed_sizes)) + size = GRUB_FONT_DEFAULT_SIZE; + else + size = ft_face->available_sizes[0].height; + + if (FT_Set_Pixel_Sizes (ft_face, size, size)) + { + fprintf (stderr, "grub-gen-widthspec: error: can't set %dx%d font size", size, size); + return 1; + } + + for (char_code = FT_Get_First_Char (face, &glyph_index); + glyph_index; + char_code = FT_Get_Next_Char (face, char_code, &glyph_index)) + add_glyph (face, char_code); + + FT_Done_Face (ft_face); + } + + FT_Done_FreeType (ft_lib); + + file = fopen (argv[2], "w"); + if (! file) + { + fprintf (stderr, "grub-gen-asciih: error: cannot write to `%s': %s", argv[2], + strerror (errno)); + return 1; + } + + fprintf (file, "/* THIS CHUNK OF BYTES IS AUTOMATICALLY GENERATED */\n"); + fprintf (file, "unsigned char widthspec[] =\n"); + fprintf (file, "{\n"); + + for (i = 0; i < MAX_CODE / 8; i++) + fprintf (file, "0x%02x,%c", result[i], ((i & 0xf) == 0xf) ? '\n' : ' '); + + fprintf (file, "};\n"); + + fclose (file); + + return 0; +} diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c index e7b8753ee..3ce820843 100644 --- a/util/grub-mkfont.c +++ b/util/grub-mkfont.c @@ -68,9 +68,7 @@ struct grub_glyph_info enum file_formats { - PF2, - ASCII_BITMAPS, - WIDTH_SPEC + PF2 }; enum @@ -772,79 +770,6 @@ print_glyphs (struct grub_font_info *font_info) } } -static void -write_font_ascii_bitmap (struct grub_font_info *font_info, char *output_file) -{ - FILE *file; - struct grub_glyph_info *glyph; - int num; - - file = fopen (output_file, "wb"); - if (! file) - grub_util_error (_("cannot write to `%s': %s"), output_file, - strerror (errno)); - - for (glyph = font_info->glyphs_sorted, num = 0; num < font_info->num_glyphs; - glyph++, num++) - { - if (glyph->width == 8 && glyph->height == 16 - && glyph->x_ofs == 0 && glyph->y_ofs == 0) - fwrite (glyph->bitmap, 16, 1, file); - else - { - grub_uint8_t glph[16]; - int p = 0, mask = 0x80; - int row, col; - int dy = 12 - glyph->height - glyph->y_ofs; - for (row = 0; row < 16; row++) - glph[row] = 0; - for (row = 0; row < glyph->height; row++) - for (col = 0; col < glyph->width; col++) - { - int val = glyph->bitmap[p] & mask; - mask >>= 1; - if (mask == 0) - { - mask = 0x80; - p++; - } - if (val && dy + row >= 0 - && dy + row < 16 - && glyph->x_ofs + col >= 0 - && glyph->x_ofs + col < 8) - glph[dy + row] |= 1 << (7 - (glyph->x_ofs + col)); - } - fwrite (glph, 16, 1, file); - } - } - fclose (file); -} - -static 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; - - out = xmalloc (8192); - memset (out, 0, 8192); - - file = fopen (output_file, "wb"); - if (! file) - grub_util_error (_("cannot write to `%s': %s"), output_file, - strerror (errno)); - - for (glyph = font_info->glyphs_sorted; - glyph < font_info->glyphs_sorted + font_info->num_glyphs; glyph++) - if (glyph->width > 12) - out[glyph->char_code >> 3] |= (1 << (glyph->char_code & 7)); - - fwrite (out, 8192, 1, file); - fclose (file); - free (out); -} - static void write_font_pf2 (struct grub_font_info *font_info, char *output_file) { @@ -997,7 +922,6 @@ write_font_pf2 (struct grub_font_info *font_info, char *output_file) static struct argp_option options[] = { {"output", 'o', N_("FILE"), 0, N_("save output in FILE [required]"), 0}, /* TRANSLATORS: bitmaps are images like e.g. in JPEG. */ - {"ascii-bitmaps", 0x102, 0, 0, N_("save only the ASCII bitmaps"), 0}, {"width-spec", 0x103, 0, 0, /* TRANSLATORS: this refers to creating a file containing the width of every glyph but not the glyphs themselves. */ @@ -1131,14 +1055,6 @@ argp_parser (int key, char *arg, struct argp_state *state) font_verbosity++; break; - case 0x102: - arguments->file_format = ASCII_BITMAPS; - break; - - case 0x103: - arguments->file_format = WIDTH_SPEC; - break; - case ARGP_KEY_ARG: assert (arguments->nfiles < arguments->files_max); arguments->files[arguments->nfiles++] = xstrdup(arg); @@ -1180,23 +1096,6 @@ main (int argc, char *argv[]) exit(1); } - if (arguments.file_format == ASCII_BITMAPS - && arguments.font_info.num_range > 0) - { - grub_util_error ("%s", _("Option --ascii-bitmaps doesn't accept ranges (it always uses ASCII).")); - return 1; - } - else if (arguments.file_format == ASCII_BITMAPS) - { - arguments.font_info.ranges = xrealloc (arguments.font_info.ranges, - GRUB_FONT_RANGE_BLOCK * - sizeof (grub_uint32_t) * 2); - - arguments.font_info.ranges[0] = (grub_uint32_t) 0x00; - arguments.font_info.ranges[1] = (grub_uint32_t) 0x7f; - arguments.font_info.num_range = 1; - } - if (! arguments.output_file) grub_util_error ("%s", _("output file must be specified")); @@ -1287,14 +1186,6 @@ main (int argc, char *argv[]) case PF2: write_font_pf2 (&arguments.font_info, arguments.output_file); break; - - case ASCII_BITMAPS: - write_font_ascii_bitmap (&arguments.font_info, arguments.output_file); - break; - - case WIDTH_SPEC: - write_font_width_spec (&arguments.font_info, arguments.output_file); - break; } if (font_verbosity > 1)