/* * 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 FT_SYNTHESIS_H #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 (ft_face, &glyph_index); glyph_index; char_code = FT_Get_Next_Char (ft_face, char_code, &glyph_index)) add_glyph (ft_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; }