123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- /*
- * 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 <http://www.gnu.org/licenses/>.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <errno.h>
- #include <ft2build.h>
- #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]))
- 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)
- {
- fprintf (stderr, "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))
- fprintf (stderr, ": %s\n", ft_errmsgs[err]);
- else
- fprintf (stderr, "\n");
- exit (1);
- }
- 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)
- {
- 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;
- struct grub_glyph_info glyph;
- glyph_idx = FT_Get_Char_Index (face, char_code);
- if (!glyph_idx)
- return;
- memset (&glyph, 0, sizeof(glyph));
- 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;
- }
|