2010-01-10 Carles Pina i Estany <carles@pina.cat>

* font/font.c: Include `ascii.h'.
	(ASCII_BITMAP_SIZE): New macro.
	(ascii_font_glyph): Define.
	(ascii_glyph_lookup): New function.
	(grub_font_get_string_width): Change comment. If glyph not found, use
	ascii_glyph_lookup.
	(grub_font_get_glyph_with_fallback): If glyph not available returns
	ascii_glyph_lookup.
	* util/grub-mkfont.c (file_formats): New enum.
	(options): Add `ascii-bitmaps' new option.
	(usage): Add `asii-bitmaps' new option.
	(write_font_ascii_bitmap): New function.
	(write_font): Rename to ...
	(write_font_p2): ... this. Remove print_glyphs call.
	(main): Use file_format. Implement code for ranges if ascii-bitmaps is
	used. Call print_glyphs.
	* Makefile.in (pkgdata_DATA): Add `font/ascii.h'.
This commit is contained in:
carles 2010-01-10 23:33:57 +00:00
parent f40f890a12
commit 26ba5c2262
4 changed files with 154 additions and 12 deletions

View File

@ -1,3 +1,23 @@
2010-01-10 Carles Pina i Estany <carles@pina.cat>
* font/font.c: Include `ascii.h'.
(ASCII_BITMAP_SIZE): New macro.
(ascii_font_glyph): Define.
(ascii_glyph_lookup): New function.
(grub_font_get_string_width): Change comment. If glyph not found, use
ascii_glyph_lookup.
(grub_font_get_glyph_with_fallback): If glyph not available returns
ascii_glyph_lookup.
* util/grub-mkfont.c (file_formats): New enum.
(options): Add `ascii-bitmaps' new option.
(usage): Add `asii-bitmaps' new option.
(write_font_ascii_bitmap): New function.
(write_font): Rename to ...
(write_font_p2): ... this. Remove print_glyphs call.
(main): Use file_format. Implement code for ranges if ascii-bitmaps is
used. Call print_glyphs.
* Makefile.in (pkgdata_DATA): Add `font/ascii.h'.
2010-01-10 Robert Millan <rmh.grub@aybabtu.com>
* conf/common.rmk (bin_UTILITIES): Add `grub-bin2h'.

View File

@ -234,7 +234,7 @@ else
ifeq ($(enable_grub_mkfont),yes)
pkgdata_DATA += unicode.pf2 ascii.pf2
pkgdata_DATA += unicode.pf2 ascii.pf2 font/ascii.h
# Arrows and lines are needed to draw the menu, so we always include them
UNICODE_ARROWS=0x2190-0x2193
@ -245,6 +245,12 @@ unicode.pf2: $(FONT_SOURCE) grub-mkfont
ascii.pf2: $(FONT_SOURCE) grub-mkfont
$(builddir)/grub-mkfont -o $@ $(FONT_SOURCE) -r 0x0-0x7f,$(UNICODE_ARROWS),$(UNICODE_LINES)
font/ascii.bitmaps: $(FONT_SOURCE) grub-mkfont
$(builddir)/grub-mkfont --ascii-bitmaps -o $@ $(FONT_SOURCE)
font/ascii.h: font/ascii.bitmaps grub-bin2h
$(builddir)/grub-bin2h ascii_bitmaps 2048 < font/ascii.bitmaps > font/ascii.h
endif
endif

View File

@ -17,6 +17,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
#define GENERATE_ASCII
#include <grub/bufio.h>
#include <grub/dl.h>
#include <grub/file.h>
@ -27,6 +29,10 @@
#include <grub/video.h>
#include <grub/bitmap.h>
#ifdef GENERATE_ASCII
#include "ascii.h"
#endif
#ifndef FONT_DEBUG
#define FONT_DEBUG 0
#endif
@ -43,6 +49,7 @@ struct char_index_entry
#define FONT_WEIGHT_NORMAL 100
#define FONT_WEIGHT_BOLD 200
#define ASCII_BITMAP_SIZE 16
struct grub_font
{
@ -129,6 +136,48 @@ static struct grub_font null_font;
/* Flag to ensure module is initialized only once. */
static grub_uint8_t font_loader_initialized;
#ifdef GENERATE_ASCII
static struct grub_font_glyph *ascii_font_glyph[0x80];
#endif
static struct grub_font_glyph *
ascii_glyph_lookup (grub_uint32_t code)
{
#ifdef GENERATE_ASCII
static int ascii_failback_initialized = 0;
if (code >= 0x80)
return unknown_glyph;
if (ascii_failback_initialized == 0)
{
int current;
for (current = 0; current < 0x80; current++)
{
ascii_font_glyph[current] = grub_malloc(sizeof(struct grub_font_glyph)
+ ASCII_BITMAP_SIZE);
ascii_font_glyph[current]->width = 8;
ascii_font_glyph[current]->height = 16;
ascii_font_glyph[current]->offset_x = 0;
ascii_font_glyph[current]->offset_y = -2;
ascii_font_glyph[current]->device_width = 8;
grub_memcpy (ascii_font_glyph[current]->bitmap,
&ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE],
ASCII_BITMAP_SIZE);
}
ascii_failback_initialized = 1;
}
return ascii_font_glyph[code];
#else
(void) code;
return unknown_glyph;
#endif
}
void
grub_font_loader_init (void)
{
@ -865,15 +914,17 @@ grub_font_get_string_width (grub_font_t font, const char *str)
}
/* Get the glyph for FONT corresponding to the Unicode code point CODE.
Returns a pointer to an glyph indicating there is no glyph available
if CODE does not exist in the font. The glyphs are cached once loaded. */
Returns the ASCII glyph for the code if no other fonts are available.
The glyphs are cached once loaded. */
struct grub_font_glyph *
grub_font_get_glyph (grub_font_t font, grub_uint32_t code)
{
struct grub_font_glyph *glyph;
glyph = grub_font_get_glyph_internal (font, code);
if (glyph == 0)
glyph = unknown_glyph;
{
glyph = ascii_glyph_lookup (code);
}
return glyph;
}
@ -968,8 +1019,8 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
if (best_glyph)
return best_glyph;
else
/* Glyph not available in any font. Return unknown glyph. */
return unknown_glyph;
/* Glyph not available in any font. Return ASCII failback. */
return ascii_glyph_lookup (code);
}

View File

@ -49,6 +49,12 @@ struct grub_glyph_info
grub_uint8_t bitmap[0];
};
enum file_formats
{
PF2,
ASCII_BITMAPS
};
#define GRUB_FONT_FLAG_BOLD 1
#define GRUB_FONT_FLAG_NOBITMAP 2
#define GRUB_FONT_FLAG_NOHINTING 4
@ -87,6 +93,7 @@ static struct option options[] =
{"help", no_argument, 0, 'h'},
{"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
{"ascii-bitmaps", no_argument, 0, 0x102},
{0, 0, 0, 0}
};
@ -102,6 +109,7 @@ usage (int status)
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\
-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\
@ -337,7 +345,39 @@ print_glyphs (struct grub_font_info *font_info)
}
void
write_font (struct grub_font_info *font_info, char *output_file)
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 ("Can\'t write to file %s.", output_file);
int correct_size;
for (glyph = font_info->glyph, num = 0; glyph; glyph = glyph->next, num++)
{
correct_size = 1;
if (glyph->width != 8 || glyph->height != 16)
{
// printf ("Width or height from glyph U+%04x not supported, skipping.\n", glyph->char_code);
correct_size = 0;
}
int row;
for (row = 0; row < glyph->height; row++)
{
if (correct_size)
fwrite (&glyph->bitmap[row], sizeof(glyph->bitmap[row]), 1, file);
else
fwrite (&correct_size, 1, 1, file);
}
}
fclose (file);
}
void
write_font_pf2 (struct grub_font_info *font_info, char *output_file)
{
FILE *file;
grub_uint32_t leng, data;
@ -473,9 +513,6 @@ write_font (struct grub_font_info *font_info, char *output_file)
grub_util_write_image ((char *) &cur->bitmap[0], cur->bitmap_size, file);
}
if (font_verbosity > 1)
print_glyphs (font_info);
fclose (file);
}
@ -487,6 +524,7 @@ main (int argc, char *argv[])
int font_index = 0;
int font_size = 0;
char *output_file = NULL;
enum file_formats file_format = PF2;
memset (&font_info, 0, sizeof (font_info));
@ -552,7 +590,7 @@ main (int argc, char *argv[])
font_info.ranges = xrealloc (font_info.ranges,
(font_info.num_range +
GRUB_FONT_RANGE_BLOCK) *
sizeof (int) * 2);
sizeof (grub_uint32_t) * 2);
font_info.ranges[font_info.num_range * 2] = a;
font_info.ranges[font_info.num_range * 2 + 1] = b;
@ -591,12 +629,33 @@ main (int argc, char *argv[])
font_verbosity++;
break;
case 0x102:
file_format = ASCII_BITMAPS;
break;
default:
usage (1);
break;
}
}
if (file_format == ASCII_BITMAPS && font_info.num_range > 0)
{
grub_util_error ("Option --ascii-bitmaps doesn't accept ranges (use ASCII).");
return 1;
}
else if (file_format == ASCII_BITMAPS)
{
font_info.ranges = xrealloc (font_info.ranges,
GRUB_FONT_RANGE_BLOCK *
sizeof (grub_uint32_t) * 2);
font_info.ranges[0] = (grub_uint32_t) 0x00;
font_info.ranges[1] = (grub_uint32_t) 0x7f;
font_info.num_range = 1;
}
if (! output_file)
grub_util_error ("No output file is specified.");
@ -638,7 +697,13 @@ main (int argc, char *argv[])
FT_Done_FreeType (ft_lib);
write_font (&font_info, output_file);
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);
if (font_verbosity > 1)
print_glyphs (&font_info);
return 0;
}