[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[1936] 2009-01-02 Colin D Bennett <address@hidden>
From: |
Vesa Jääskeläinen |
Subject: |
[1936] 2009-01-02 Colin D Bennett <address@hidden> |
Date: |
Fri, 02 Jan 2009 15:26:08 +0000 |
Revision: 1936
http://svn.sv.gnu.org/viewvc/?view=rev&root=grub&revision=1936
Author: chaac
Date: 2009-01-02 15:26:06 +0000 (Fri, 02 Jan 2009)
Log Message:
-----------
2009-01-02 Colin D Bennett <address@hidden>
New font engine.
Additional changes by Vesa J?\195?\164?\195?\164skel?\195?\164inen
<address@hidden> to adapt to
build system and fixed gfxterm.c to work with different sized fonts.
* configure.ac: Changed UNIFONT_HEX to UNIFONT_BDF.
* configure: Re-generated.
* DISTLIST: Removed font/manager.c.
Added font/font.c.
Added font/font_cmd.c.
* Makefile.in: Changed UNIFONT_HEX to UNIFONT_BDF. Added Font tool
compilation.
* include/grub/misc.h (grub_utf8_to_ucs4): Changed prototype. Changed
users.
* kern/misc.c (grub_utf8_to_ucs4): Changed prototype.
* kern/term.c: Changed users of grub_utf8_to_ucs4.
* normal/menu.c: Likewise.
* conf/common.rmk (font_mod_SOURCES): Removed font/manager.c.
(font_mod_SOURCES): Added font/font_cmd.c, font/font.c.
* include/grub/font.h: Replaced with new file.
* include/grub/video.h (GRUB_VIDEO_MODE_TYPE_ALPHA): Changed value.
(GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED): Likewise.
(GRUB_VIDEO_MODE_TYPE_COLOR_MASK): Likewise.
(GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP): Added.
(grub_video_blit_format): Added GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED.
(grub_video_mode_info): Added bg_red, bg_green, bg_blue, bg_alpha,
fg_red, fg_green, fg_blue, fg_alpha.
(grub_video_adapter): Removed blit_glyph.
(grub_video_blit_glyph): Removed.
* font/manager.c: Removed file.
* font/font.c: New file.
* font/font_cmd.c: Likewise.
* video/video.c (grub_video_blit_glyph): Removed.
* video/i386/pc/vbe.c (grub_video_vbe_map_rgb): Added 1-bit support.
(grub_video_vbe_map_rgba): Likewise.
(grub_video_vbe_unmap_color_int): Likewise.
(grub_video_vbe_blit_glyph): Removed.
(grub_video_vbe_adapter): Removed blit_glyph.
* video/i386/pc/vbeutil.c (get_data_ptr): Added 1-bit support.
(get_pixel): Likewise.
(set_pixel): Likewise.
* commands/videotest.c (grub_cmd_videotest): Added more tests for fonts.
* term/gfxterm.c: Adapted to new font engine.
* term/i386/pc/vesafb.c: Marked as deprecated. Made it compile.
* term/i386/pc/vga.c: Likewise.
* util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java: New file.
* util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java: Likewise.
* util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise.
* util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise.
* util/fonttool/src/org/gnu/grub/fonttool/Converter.java: Likewise.
* util/fonttool/src/org/gnu/grub/fonttool/Font.java: Likewise.
* util/fonttool/src/org/gnu/grub/fonttool/Glyph.java: Likewise.
* util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java: Likewise.
* util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java: Likewise.
* util/grub.d/00_header.in: Changed to use new loadfont command.
* util/grub-mkconfig_lib.in: Changed font extension.
Modified Paths:
--------------
trunk/grub2/ChangeLog
trunk/grub2/DISTLIST
trunk/grub2/Makefile.in
trunk/grub2/commands/videotest.c
trunk/grub2/conf/common.mk
trunk/grub2/conf/common.rmk
trunk/grub2/configure
trunk/grub2/configure.ac
trunk/grub2/include/grub/font.h
trunk/grub2/include/grub/misc.h
trunk/grub2/include/grub/video.h
trunk/grub2/kern/misc.c
trunk/grub2/kern/term.c
trunk/grub2/normal/menu.c
trunk/grub2/term/gfxterm.c
trunk/grub2/term/i386/pc/vesafb.c
trunk/grub2/term/i386/pc/vga.c
trunk/grub2/util/grub-mkconfig_lib.in
trunk/grub2/util/grub.d/00_header.in
trunk/grub2/video/i386/pc/vbe.c
trunk/grub2/video/i386/pc/vbeutil.c
trunk/grub2/video/video.c
Added Paths:
-----------
trunk/grub2/font/font.c
trunk/grub2/font/font_cmd.c
trunk/grub2/util/fonttool/
trunk/grub2/util/fonttool/src/
trunk/grub2/util/fonttool/src/org/
trunk/grub2/util/fonttool/src/org/gnu/
trunk/grub2/util/fonttool/src/org/gnu/grub/
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharStorageInfo.java
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Converter.java
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Font.java
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Glyph.java
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java
Removed Paths:
-------------
trunk/grub2/font/manager.c
Modified: trunk/grub2/ChangeLog
===================================================================
--- trunk/grub2/ChangeLog 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/ChangeLog 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,3 +1,92 @@
+2009-01-02 Colin D Bennett <address@hidden>
+
+ New font engine.
+
+ Additional changes by Vesa Jääskeläinen <address@hidden> to adapt to
+ build system and fixed gfxterm.c to work with different sized fonts.
+
+ * configure.ac: Changed UNIFONT_HEX to UNIFONT_BDF.
+
+ * configure: Re-generated.
+
+ * DISTLIST: Removed font/manager.c.
+ Added font/font.c.
+ Added font/font_cmd.c.
+
+ * Makefile.in: Changed UNIFONT_HEX to UNIFONT_BDF. Added Font tool
+ compilation.
+
+ * include/grub/misc.h (grub_utf8_to_ucs4): Changed prototype. Changed
users.
+
+ * kern/misc.c (grub_utf8_to_ucs4): Changed prototype.
+
+ * kern/term.c: Changed users of grub_utf8_to_ucs4.
+
+ * normal/menu.c: Likewise.
+
+ * conf/common.rmk (font_mod_SOURCES): Removed font/manager.c.
+ (font_mod_SOURCES): Added font/font_cmd.c, font/font.c.
+
+ * include/grub/font.h: Replaced with new file.
+
+ * include/grub/video.h (GRUB_VIDEO_MODE_TYPE_ALPHA): Changed value.
+ (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED): Likewise.
+ (GRUB_VIDEO_MODE_TYPE_COLOR_MASK): Likewise.
+ (GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP): Added.
+ (grub_video_blit_format): Added GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED.
+ (grub_video_mode_info): Added bg_red, bg_green, bg_blue, bg_alpha,
+ fg_red, fg_green, fg_blue, fg_alpha.
+ (grub_video_adapter): Removed blit_glyph.
+ (grub_video_blit_glyph): Removed.
+
+ * font/manager.c: Removed file.
+
+ * font/font.c: New file.
+
+ * font/font_cmd.c: Likewise.
+
+ * video/video.c (grub_video_blit_glyph): Removed.
+
+ * video/i386/pc/vbe.c (grub_video_vbe_map_rgb): Added 1-bit support.
+ (grub_video_vbe_map_rgba): Likewise.
+ (grub_video_vbe_unmap_color_int): Likewise.
+ (grub_video_vbe_blit_glyph): Removed.
+ (grub_video_vbe_adapter): Removed blit_glyph.
+
+ * video/i386/pc/vbeutil.c (get_data_ptr): Added 1-bit support.
+ (get_pixel): Likewise.
+ (set_pixel): Likewise.
+
+ * commands/videotest.c (grub_cmd_videotest): Added more tests for fonts.
+
+ * term/gfxterm.c: Adapted to new font engine.
+
+ * term/i386/pc/vesafb.c: Marked as deprecated. Made it compile.
+
+ * term/i386/pc/vga.c: Likewise.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java: New file.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java: Likewise.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java: Likewise.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/Converter.java: Likewise.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/Font.java: Likewise.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/Glyph.java: Likewise.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java: Likewise.
+
+ * util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java: Likewise.
+
+ * util/grub.d/00_header.in: Changed to use new loadfont command.
+
+ * util/grub-mkconfig_lib.in: Changed font extension.
+
2008-12-28 Felix Zielcke <address@hidden>
* util/getroot.c (grub_util_get_grub_dev): Add support for
Modified: trunk/grub2/DISTLIST
===================================================================
--- trunk/grub2/DISTLIST 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/DISTLIST 2009-01-02 15:26:06 UTC (rev 1936)
@@ -103,7 +103,8 @@
docs/grub.cfg
docs/grub.texi
docs/texinfo.tex
-font/manager.c
+font/font.c
+font/font_cmd.c
fs/affs.c
fs/afs.c
fs/cpio.c
Modified: trunk/grub2/Makefile.in
===================================================================
--- trunk/grub2/Makefile.in 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/Makefile.in 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
# -*- makefile -*-
#
-# Copyright (C)
1994,1995,1996,1997,1998,1999,2000,2001,2002,2004,2005,2006,2007 Free Software
Foundation, Inc.
+# Copyright (C)
1994,1995,1996,1997,1998,1999,2000,2001,2002,2004,2005,2006,2007,2008,2009 Free
Software Foundation, Inc.
#
# This Makefile.in is free software; the author
# gives unlimited permission to copy and/or distribute it,
@@ -88,7 +88,7 @@
LIBCURSES = @LIBCURSES@
LIBLZO = @LIBLZO@
YACC = @YACC@
-UNIFONT_HEX = @UNIFONT_HEX@
+UNIFONT_BDF = @UNIFONT_BDF@
# Options.
enable_grub_emu = @enable_grub_emu@
@@ -148,19 +148,26 @@
partmap.lst: $(PARTMAPFILES)
cat $^ /dev/null | sort > $@
-ifeq (, $(UNIFONT_HEX))
+ifeq (, $(UNIFONT_BDF))
else
-pkgdata_DATA += unicode.pff ascii.pff
+pkgdata_DATA += unicode.pf2 ascii.pf2
# Arrows and lines are needed to draw the menu, so we always include them
UNICODE_ARROWS=0x2190-0x2193
UNICODE_LINES=0x2501-0x251B
-unicode.pff: $(UNIFONT_HEX)
- ruby $(srcdir)/util/unifont2pff.rb $(UNIFONT_HEX) > $@
+# Note: fonttool should be replaced with C only implementation
-ascii.pff: $(UNIFONT_HEX)
- ruby $(srcdir)/util/unifont2pff.rb 0x0-0x7f $(UNICODE_ARROWS)
$(UNICODE_LINES) $(UNIFONT_HEX) > $@
+$(builddir)/fonttool/fonttool.jar:
+ mkdir -p "$(builddir)/fonttool/src"
+ javac -source 1.5 -target 1.5 -g -deprecation -encoding UTF-8 -d
"$(builddir)/fonttool/src" `find "$(srcdir)/util/fonttool/src/" -name '*.java'`
+ jar cf $(builddir)/fonttool/fonttool.jar -C $(builddir)/fonttool/src .
+
+unicode.pf2: $(UNIFONT_BDF) $(builddir)/fonttool/fonttool.jar
+ java -cp $(builddir)/fonttool/fonttool.jar
org.gnu.grub.fonttool.Converter --in=$(UNIFONT_BDF) --out=$@
+
+ascii.pf2: $(UNIFONT_BDF) $(builddir)/fonttool/fonttool.jar
+ java -cp $(builddir)/fonttool/fonttool.jar
org.gnu.grub.fonttool.Converter --in=$(UNIFONT_BDF) --out=$@ 0x0-0x7f
$(UNICODE_ARROWS) $(UNICODE_LINES)
endif
# Used for building modules externally
Modified: trunk/grub2/commands/videotest.c
===================================================================
--- trunk/grub2/commands/videotest.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/commands/videotest.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2009 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
@@ -36,17 +36,21 @@
GRUB_VIDEO_MODE_TYPE_INDEX_COLOR) != GRUB_ERR_NONE)
return grub_errno;
- grub_getkey ();
-
grub_video_color_t color;
unsigned int x;
unsigned int y;
unsigned int width;
unsigned int height;
int i;
- struct grub_font_glyph glyph;
+ grub_font_t sansbig;
+ grub_font_t sans;
+ grub_font_t sanssmall;
+ grub_font_t fixed;
+ struct grub_font_glyph *glyph;
struct grub_video_render_target *text_layer;
grub_video_color_t palette[16];
+ const char *str;
+ int texty;
grub_video_get_viewport (&x, &y, &width, &height);
@@ -65,9 +69,16 @@
color = grub_video_map_rgb (0, 255, 255);
grub_video_fill_rect (color, 100, 100, 100, 100);
- grub_font_get_glyph ('*', &glyph);
- grub_video_blit_glyph (&glyph, color, 200 ,0);
+ sansbig = grub_font_get ("Helvetica Bold 24");
+ sans = grub_font_get ("Helvetica Bold 14");
+ sanssmall = grub_font_get ("Helvetica 8");
+ fixed = grub_font_get ("Fixed 20");
+ if (! sansbig || ! sans || ! sanssmall || ! fixed)
+ return grub_error (GRUB_ERR_BAD_FONT, "No font loaded.");
+ glyph = grub_font_get_glyph (fixed, '*');
+ grub_font_draw_glyph (glyph, color, 200 ,0);
+
grub_video_set_viewport (x + 150, y + 150,
width - 150 * 2, height - 150 * 2);
color = grub_video_map_rgb (77, 33, 77);
@@ -77,18 +88,69 @@
color = grub_video_map_rgb (255, 255, 255);
- grub_font_get_glyph ('A', &glyph);
- grub_video_blit_glyph (&glyph, color, 16, 16);
- grub_font_get_glyph ('B', &glyph);
- grub_video_blit_glyph (&glyph, color, 16 * 2, 16);
+ texty = 32;
+ grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
+ sans, color, 16, texty);
+ texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
- grub_font_get_glyph ('*', &glyph);
+ texty += grub_font_get_ascent (fixed);
+ grub_font_draw_string ("The quick brown fox jumped over the lazy dog.",
+ fixed, color, 16, texty);
+ texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
+ /* To convert Unicode characters into UTF-8 for this test, the following
+ command is useful:
+ echo -ne '\x00\x00\x26\x3A' | iconv -f UTF-32BE -t UTF-8 | od -t x1
+ This converts the Unicode character U+263A to UTF-8. */
+
+ /* Characters used:
+ Code point Description UTF-8 encoding
+ ----------- ------------------------------ --------------
+ U+263A unfilled smiley face E2 98 BA
+ U+00A1 inverted exclamation point C2 A1
+ U+00A3 British pound currency symbol C2 A3
+ U+03C4 Greek tau CF 84
+ U+00E4 lowercase letter a with umlaut C3 A4
+ U+2124 set 'Z' symbol (integers) E2 84 A4
+ U+2287 subset symbol E2 8A 87
+ U+211D set 'R' symbol (real numbers) E2 84 9D */
+
+ str =
+ "Unicode test: happy\xE2\x98\xBA \xC2\xA3 5.00"
+ " \xC2\xA1\xCF\x84\xC3\xA4u! "
+ " \xE2\x84\xA4\xE2\x8A\x87\xE2\x84\x9D";
+ color = grub_video_map_rgb (128, 128, 255);
+
+ /* All characters in the string exist in the 'Fixed 20' (10x20) font. */
+ texty += grub_font_get_ascent(fixed);
+ grub_font_draw_string (str, fixed, color, 16, texty);
+ texty += grub_font_get_descent (fixed) + grub_font_get_leading (fixed);
+
+ /* Some character don't exist in the Helvetica font, so the font engine
+ will fall back to using glyphs from another font that does contain them.
+ TODO The font engine should be smart about selecting a replacement font
+ and prioritize fonts with similar sizes. */
+
+ texty += grub_font_get_ascent(sansbig);
+ grub_font_draw_string (str, sansbig, color, 16, texty);
+ texty += grub_font_get_descent (sansbig) + grub_font_get_leading (sansbig);
+
+ texty += grub_font_get_ascent(sans);
+ grub_font_draw_string (str, sans, color, 16, texty);
+ texty += grub_font_get_descent (sans) + grub_font_get_leading (sans);
+
+ texty += grub_font_get_ascent(sanssmall);
+ grub_font_draw_string (str, sanssmall, color, 16, texty);
+ texty += (grub_font_get_descent (sanssmall)
+ + grub_font_get_leading (sanssmall));
+
+ glyph = grub_font_get_glyph (fixed, '*');
+
for (i = 0; i < 16; i++)
{
color = grub_video_map_color (i);
palette[i] = color;
- grub_video_blit_glyph (&glyph, color, 16 + i * 16, 32);
+ grub_font_draw_glyph (glyph, color, 16 + i * 16, 220);
}
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
Modified: trunk/grub2/conf/common.mk
===================================================================
--- trunk/grub2/conf/common.mk 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/conf/common.mk 2009-01-02 15:26:06 UTC (rev 1936)
@@ -2803,13 +2803,13 @@
help_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For font.mod.
-font_mod_SOURCES = font/manager.c
-CLEANFILES += font.mod mod-font.o mod-font.c pre-font.o
font_mod-font_manager.o und-font.lst
+font_mod_SOURCES = font/font_cmd.c font/font.c
+CLEANFILES += font.mod mod-font.o mod-font.c pre-font.o
font_mod-font_font_cmd.o font_mod-font_font.o und-font.lst
ifneq ($(font_mod_EXPORTS),no)
CLEANFILES += def-font.lst
DEFSYMFILES += def-font.lst
endif
-MOSTLYCLEANFILES += font_mod-font_manager.d
+MOSTLYCLEANFILES += font_mod-font_font_cmd.d font_mod-font_font.d
UNDSYMFILES += und-font.lst
font.mod: pre-font.o mod-font.o $(TARGET_OBJ2ELF)
@@ -2818,9 +2818,9 @@
if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f
$@; exit 1); fi
$(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K
_grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
-pre-font.o: $(font_mod_DEPENDENCIES) font_mod-font_manager.o
+pre-font.o: $(font_mod_DEPENDENCIES) font_mod-font_font_cmd.o
font_mod-font_font.o
-rm -f $@
- $(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
font_mod-font_manager.o
+ $(TARGET_CC) $(font_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@
font_mod-font_font_cmd.o font_mod-font_font.o
mod-font.o: mod-font.c
$(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -c
-o $@ $<
@@ -2837,25 +2837,44 @@
echo 'font' > $@
$(NM) -u -P -p $< | cut -f1 -d' ' >> $@
-font_mod-font_manager.o: font/manager.c $(font/manager.c_DEPENDENCIES)
+font_mod-font_font_cmd.o: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES)
$(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(font_mod_CFLAGS) -MD -c -o $@ $<
--include font_mod-font_manager.d
+-include font_mod-font_font_cmd.d
-CLEANFILES += cmd-font_mod-font_manager.lst fs-font_mod-font_manager.lst
partmap-font_mod-font_manager.lst
-COMMANDFILES += cmd-font_mod-font_manager.lst
-FSFILES += fs-font_mod-font_manager.lst
-PARTMAPFILES += partmap-font_mod-font_manager.lst
+CLEANFILES += cmd-font_mod-font_font_cmd.lst fs-font_mod-font_font_cmd.lst
partmap-font_mod-font_font_cmd.lst
+COMMANDFILES += cmd-font_mod-font_font_cmd.lst
+FSFILES += fs-font_mod-font_font_cmd.lst
+PARTMAPFILES += partmap-font_mod-font_font_cmd.lst
-cmd-font_mod-font_manager.lst: font/manager.c $(font/manager.c_DEPENDENCIES)
gencmdlist.sh
+cmd-font_mod-font_font_cmd.lst: font/font_cmd.c
$(font/font_cmd.c_DEPENDENCIES) gencmdlist.sh
set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh font > $@ || (rm -f $@; exit 1)
-fs-font_mod-font_manager.lst: font/manager.c $(font/manager.c_DEPENDENCIES)
genfslist.sh
+fs-font_mod-font_font_cmd.lst: font/font_cmd.c $(font/font_cmd.c_DEPENDENCIES)
genfslist.sh
set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh font > $@ || (rm -f $@; exit 1)
-partmap-font_mod-font_manager.lst: font/manager.c
$(font/manager.c_DEPENDENCIES) genpartmaplist.sh
+partmap-font_mod-font_font_cmd.lst: font/font_cmd.c
$(font/font_cmd.c_DEPENDENCIES) genpartmaplist.sh
set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh font > $@ || (rm -f $@; exit 1)
+font_mod-font_font.o: font/font.c $(font/font.c_DEPENDENCIES)
+ $(TARGET_CC) -Ifont -I$(srcdir)/font $(TARGET_CPPFLAGS)
$(TARGET_CFLAGS) $(font_mod_CFLAGS) -MD -c -o $@ $<
+-include font_mod-font_font.d
+
+CLEANFILES += cmd-font_mod-font_font.lst fs-font_mod-font_font.lst
partmap-font_mod-font_font.lst
+COMMANDFILES += cmd-font_mod-font_font.lst
+FSFILES += fs-font_mod-font_font.lst
+PARTMAPFILES += partmap-font_mod-font_font.lst
+
+cmd-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES)
gencmdlist.sh
+ set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh
$(srcdir)/gencmdlist.sh font > $@ || (rm -f $@; exit 1)
+
+fs-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES) genfslist.sh
+ set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh
$(srcdir)/genfslist.sh font > $@ || (rm -f $@; exit 1)
+
+partmap-font_mod-font_font.lst: font/font.c $(font/font.c_DEPENDENCIES)
genpartmaplist.sh
+ set -e; $(TARGET_CC) -Ifont -I$(srcdir)/font
$(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(font_mod_CFLAGS) -E $< | sh
$(srcdir)/genpartmaplist.sh font > $@ || (rm -f $@; exit 1)
+
+
font_mod_CFLAGS = $(COMMON_CFLAGS)
font_mod_LDFLAGS = $(COMMON_LDFLAGS)
Modified: trunk/grub2/conf/common.rmk
===================================================================
--- trunk/grub2/conf/common.rmk 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/conf/common.rmk 2009-01-02 15:26:06 UTC (rev 1936)
@@ -364,7 +364,7 @@
help_mod_LDFLAGS = $(COMMON_LDFLAGS)
# For font.mod.
-font_mod_SOURCES = font/manager.c
+font_mod_SOURCES = font/font_cmd.c font/font.c
font_mod_CFLAGS = $(COMMON_CFLAGS)
font_mod_LDFLAGS = $(COMMON_LDFLAGS)
Modified: trunk/grub2/configure
===================================================================
--- trunk/grub2/configure 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/configure 2009-01-02 15:26:06 UTC (rev 1936)
@@ -667,7 +667,7 @@
platform
CMP
YACC
-UNIFONT_HEX
+UNIFONT_BDF
INSTALL_PROGRAM
INSTALL_SCRIPT
INSTALL_DATA
@@ -2107,9 +2107,9 @@
{ (exit 1); exit 1; }; }
fi
-for file in /usr/share/unifont/unifont.hex ; do
+for file in /usr/src/unifont.bdf ; do
if test -e $file ; then
- UNIFONT_HEX=$file
+ UNIFONT_BDF=$file
break
fi
@@ -9110,7 +9110,7 @@
platform!$platform$ac_delim
CMP!$CMP$ac_delim
YACC!$YACC$ac_delim
-UNIFONT_HEX!$UNIFONT_HEX$ac_delim
+UNIFONT_BDF!$UNIFONT_BDF$ac_delim
INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim
INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim
INSTALL_DATA!$INSTALL_DATA$ac_delim
Modified: trunk/grub2/configure.ac
===================================================================
--- trunk/grub2/configure.ac 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/configure.ac 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
# Process this file with autoconf to produce a configure script.
-# Copyright (C) 2002,2003,2004,2005,2006,2007,2008 Free Software Foundation,
Inc.
+# Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009 Free Software
Foundation, Inc.
#
# This configure.ac is free software; the author
# gives unlimited permission to copy and/or distribute it,
@@ -127,9 +127,9 @@
AC_MSG_ERROR([bison is not found])
fi
-for file in /usr/share/unifont/unifont.hex ; do
+for file in /usr/src/unifont.bdf ; do
if test -e $file ; then
- AC_SUBST([UNIFONT_HEX], [$file])
+ AC_SUBST([UNIFONT_BDF], [$file])
break
fi
done
Added: trunk/grub2/font/font.c
===================================================================
--- trunk/grub2/font/font.c (rev 0)
+++ trunk/grub2/font/font.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,1026 @@
+/* font.c - Font API and font file loader. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2005,2006,2007,2008,2009 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 <grub/bufio.h>
+#include <grub/dl.h>
+#include <grub/file.h>
+#include <grub/font.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+#include <grub/video.h>
+#include <grub/bitmap.h>
+
+#ifndef FONT_DEBUG
+#define FONT_DEBUG 0
+#endif
+
+struct char_index_entry
+{
+ grub_uint32_t code;
+ grub_uint8_t storage_flags;
+ grub_uint32_t offset;
+
+ /* Glyph if loaded, or NULL otherwise. */
+ struct grub_font_glyph *glyph;
+};
+
+#define FONT_WEIGHT_NORMAL 100
+#define FONT_WEIGHT_BOLD 200
+
+struct grub_font
+{
+ char *name;
+ grub_file_t file;
+ char *family;
+ short point_size;
+ short weight;
+ short max_char_width;
+ short max_char_height;
+ short ascent;
+ short descent;
+ short leading;
+ grub_uint32_t num_chars;
+ struct char_index_entry *char_index;
+};
+
+/* Definition of font registry. */
+struct grub_font_node *grub_font_list;
+
+static int register_font (grub_font_t font);
+static void font_init (grub_font_t font);
+static void free_font (grub_font_t font);
+static void remove_font (grub_font_t font);
+
+struct font_file_section
+{
+ /* The file this section is in. */
+ grub_file_t file;
+
+ /* FOURCC name of the section. */
+ char name[4];
+
+ /* Length of the section contents. */
+ grub_uint32_t length;
+
+ /* Set by open_section() on EOF. */
+ int eof;
+};
+
+/* Font file format constants. */
+static const char pff2_magic[4] = { 'P', 'F', 'F', '2' };
+static const char section_names_file[4] = { 'F', 'I', 'L', 'E' };
+static const char section_names_font_name[4] = { 'N', 'A', 'M', 'E' };
+static const char section_names_point_size[4] = { 'P', 'T', 'S', 'Z' };
+static const char section_names_weight[4] = { 'W', 'E', 'I', 'G' };
+static const char section_names_max_char_width[4] = { 'M', 'A', 'X', 'W' };
+static const char section_names_max_char_height[4] = { 'M', 'A', 'X', 'H' };
+static const char section_names_ascent[4] = { 'A', 'S', 'C', 'E' };
+static const char section_names_descent[4] = { 'D', 'E', 'S', 'C' };
+static const char section_names_char_index[4] = { 'C', 'H', 'I', 'X' };
+static const char section_names_data[4] = { 'D', 'A', 'T', 'A' };
+
+/* Replace unknown glyphs with a rounded question mark. */
+static grub_uint8_t unknown_glyph_bitmap[] =
+{
+ /* 76543210 */
+ 0x7C, /* ooooo */
+ 0x82, /* o o */
+ 0xBA, /* o ooo o */
+ 0xAA, /* o o o o */
+ 0xAA, /* o o o o */
+ 0x8A, /* o o o */
+ 0x9A, /* o oo o */
+ 0x92, /* o o o */
+ 0x92, /* o o o */
+ 0x92, /* o o o */
+ 0x92, /* o o o */
+ 0x82, /* o o */
+ 0x92, /* o o o */
+ 0x82, /* o o */
+ 0x7C, /* ooooo */
+ 0x00 /* */
+};
+
+/* The "unknown glyph" glyph, used as a last resort. */
+static struct grub_font_glyph *unknown_glyph;
+
+/* The font structure used when no other font is loaded. This functions
+ as a "Null Object" pattern, so that code everywhere does not have to
+ check for a NULL grub_font_t to avoid dereferencing a null pointer. */
+static struct grub_font null_font;
+
+/* Flag to ensure module is initialized only once. */
+static grub_uint8_t font_loader_initialized;
+
+void
+grub_font_loader_init (void)
+{
+ /* Only initialize font loader once. */
+ if (font_loader_initialized)
+ return;
+
+ /* Make glyph for unknown glyph. */
+ unknown_glyph = grub_malloc(sizeof(struct grub_font_glyph)
+ + sizeof(unknown_glyph_bitmap));
+ if (! unknown_glyph)
+ return;
+
+ unknown_glyph->width = 8;
+ unknown_glyph->height = 16;
+ unknown_glyph->offset_x = 0;
+ unknown_glyph->offset_y = 0;
+ unknown_glyph->device_width = 8;
+ grub_memcpy(unknown_glyph->bitmap,
+ unknown_glyph_bitmap, sizeof(unknown_glyph_bitmap));
+
+ /* Initialize the null font. */
+ font_init (&null_font);
+ null_font.name = "<No Font>";
+ null_font.ascent = unknown_glyph->height;
+ null_font.descent = 1;
+ null_font.max_char_width = unknown_glyph->width;
+ null_font.max_char_height = unknown_glyph->height;
+
+ font_loader_initialized = 1;
+}
+
+/* Initialize the font object with initial default values. */
+static void
+font_init (grub_font_t font)
+{
+ font->name = 0;
+ font->file = 0;
+ font->family = 0;
+ font->point_size = 0;
+ font->weight = 0;
+
+ /* Default leading value, not in font file yet. */
+ font->leading = 1;
+
+ font->max_char_width = 0;
+ font->max_char_height = 0;
+ font->ascent = 0;
+ font->descent = 0;
+ font->num_chars = 0;
+ font->char_index = 0;
+}
+
+/* Open the next section in the file.
+
+ On success, the section name is stored in section->name and the length in
+ section->length, and 0 is returned. On failure, 1 is returned and
+ grub_errno is set approriately with an error message.
+
+ If 1 is returned due to being at the end of the file, then section->eof is
+ set to 1; otherwise, section->eof is set to 0. */
+static int
+open_section (grub_file_t file, struct font_file_section *section)
+{
+ grub_ssize_t retval;
+ grub_uint32_t raw_length;
+
+ section->file = file;
+ section->eof = 0;
+
+ /* Read the FOURCC section name. */
+ retval = grub_file_read (file, section->name, 4);
+ if (retval >= 0 && retval < 4)
+ {
+ /* EOF encountered. */
+ section->eof = 1;
+ return 1;
+ }
+ else if (retval < 0)
+ {
+ grub_error (GRUB_ERR_BAD_FONT,
+ "Font format error: can't read section name");
+ return 1;
+ }
+
+ /* Read the big-endian 32-bit section length. */
+ retval = grub_file_read (file, (char *) &raw_length, 4);
+ if (retval >= 0 && retval < 4)
+ {
+ /* EOF encountered. */
+ section->eof = 1;
+ return 1;
+ }
+ else if (retval < 0)
+ {
+ grub_error (GRUB_ERR_BAD_FONT,
+ "Font format error: can't read section length");
+ return 1;
+ }
+
+ /* Convert byte-order and store in *length. */
+ section->length = grub_be_to_cpu32 (raw_length);
+
+ return 0;
+}
+
+/* Size in bytes of each character index (CHIX section)
+ entry in the font file. */
+#define FONT_CHAR_INDEX_ENTRY_SIZE (4 + 1 + 4)
+
+/* Load the character index (CHIX) section contents from the font file. This
+ presumes that the position of FILE is positioned immediately after the
+ section length for the CHIX section (i.e., at the start of the section
+ contents). Returns 0 upon success, nonzero for failure (in which case
+ grub_errno is set appropriately). */
+static int
+load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
+ grub_font *font)
+{
+ unsigned i;
+
+#if FONT_DEBUG >= 2
+ grub_printf("load_font_index(sect_length=%d)\n", sect_length);
+#endif
+
+ /* Sanity check: ensure section length is divisible by the entry size. */
+ if ((sect_length % FONT_CHAR_INDEX_ENTRY_SIZE) != 0)
+ {
+ grub_error (GRUB_ERR_BAD_FONT,
+ "Font file format error: character index length %d "
+ "is not a multiple of the entry size %d",
+ sect_length, FONT_CHAR_INDEX_ENTRY_SIZE);
+ return 1;
+ }
+
+ /* Calculate the number of characters. */
+ font->num_chars = sect_length / FONT_CHAR_INDEX_ENTRY_SIZE;
+
+ /* Allocate the character index array. */
+ font->char_index = grub_malloc (font->num_chars
+ * sizeof (struct char_index_entry));
+ if (! font->char_index)
+ return 1;
+
+#if FONT_DEBUG >= 2
+ grub_printf("num_chars=%d)\n", font->num_chars);
+#endif
+
+ /* Load the character index data from the file. */
+ for (i = 0; i < font->num_chars; i++)
+ {
+ struct char_index_entry *entry = &font->char_index[i];
+
+ /* Read code point value; convert to native byte order. */
+ if (grub_file_read (file, (char *) &entry->code, 4) != 4)
+ return 1;
+ entry->code = grub_be_to_cpu32 (entry->code);
+
+ /* Read storage flags byte. */
+ if (grub_file_read (file, (char *) &entry->storage_flags, 1) != 1)
+ return 1;
+
+ /* Read glyph data offset; convert to native byte order. */
+ if (grub_file_read (file, (char *) &entry->offset, 4) != 4)
+ return 1;
+ entry->offset = grub_be_to_cpu32 (entry->offset);
+
+ /* No glyph loaded. Will be loaded on demand and cached thereafter. */
+ entry->glyph = 0;
+
+#if FONT_DEBUG >= 5
+ /* Print the 1st 10 characters. */
+ if (i < 10)
+ grub_printf("c=%d o=%d\n", entry->code, entry->offset);
+#endif
+ }
+
+ return 0;
+}
+
+/* Read the contents of the specified section as a string, which is
+ allocated on the heap. Returns 0 if there is an error. */
+static char *
+read_section_as_string (struct font_file_section *section)
+{
+ char *str;
+ grub_ssize_t ret;
+
+ str = grub_malloc (section->length + 1);
+ if (! str)
+ return 0;
+
+ ret = grub_file_read (section->file, str, section->length);
+ if (ret < 0 || ret != (grub_ssize_t) section->length)
+ {
+ grub_free (str);
+ return 0;
+ }
+
+ str[section->length] = '\0';
+ return str;
+}
+
+/* Read the contents of the current section as a 16-bit integer value,
+ which is stored into *VALUE.
+ Returns 0 upon success, nonzero upon failure. */
+static int
+read_section_as_short (struct font_file_section *section, grub_int16_t *value)
+{
+ grub_uint16_t raw_value;
+
+ if (section->length != 2)
+ {
+ grub_error (GRUB_ERR_BAD_FONT,
+ "Font file format error: section %c%c%c%c length "
+ "is %d but should be 2",
+ section->name[0], section->name[1],
+ section->name[2], section->name[3],
+ section->length);
+ return 1;
+ }
+ if (grub_file_read (section->file, (char *) &raw_value, 2) != 2)
+ return 1;
+
+ *value = grub_be_to_cpu16 (raw_value);
+ return 0;
+}
+
+/* Load a font and add it to the beginning of the global font list.
+ Returns 0 upon success, nonzero upon failure. */
+int
+grub_font_load (const char *filename)
+{
+ grub_file_t file = 0;
+ struct font_file_section section;
+ char magic[4];
+ grub_font_t font = 0;
+
+#if FONT_DEBUG >= 1
+ grub_printf("add_font(%s)\n", filename);
+#endif
+
+ file = grub_buffile_open (filename, 1024);
+ if (!file)
+ goto fail;
+
+#if FONT_DEBUG >= 3
+ grub_printf("file opened\n");
+#endif
+
+ /* Read the FILE section. It indicates the file format. */
+ if (open_section (file, §ion) != 0)
+ goto fail;
+
+#if FONT_DEBUG >= 3
+ grub_printf("opened FILE section\n");
+#endif
+ if (grub_memcmp (section.name, section_names_file, 4) != 0)
+ {
+ grub_error (GRUB_ERR_BAD_FONT,
+ "Font file format error: 1st section must be FILE");
+ goto fail;
+ }
+
+#if FONT_DEBUG >= 3
+ grub_printf("section name ok\n");
+#endif
+ if (section.length != 4)
+ {
+ grub_error (GRUB_ERR_BAD_FONT,
+ "Font file format error (file type ID length is %d "
+ "but should be 4)", section.length);
+ goto fail;
+ }
+
+#if FONT_DEBUG >= 3
+ grub_printf("section length ok\n");
+#endif
+ /* Check the file format type code. */
+ if (grub_file_read (file, magic, 4) != 4)
+ goto fail;
+
+#if FONT_DEBUG >= 3
+ grub_printf("read magic ok\n");
+#endif
+
+ if (grub_memcmp (magic, pff2_magic, 4) != 0)
+ {
+ grub_error (GRUB_ERR_BAD_FONT, "Invalid font magic %x %x %x %x",
+ magic[0], magic[1], magic[2], magic[3]);
+ goto fail;
+ }
+
+#if FONT_DEBUG >= 3
+ grub_printf("compare magic ok\n");
+#endif
+
+ /* Allocate the font object. */
+ font = (grub_font_t) grub_malloc (sizeof (struct grub_font));
+ if (! font)
+ goto fail;
+
+ font_init (font);
+ font->file = file;
+
+#if FONT_DEBUG >= 3
+ grub_printf("allocate font ok; loading font info\n");
+#endif
+
+ /* Load the font information. */
+ while (1)
+ {
+ if (open_section (file, §ion) != 0)
+ {
+ if (section.eof)
+ break; /* Done reading the font file. */
+ else
+ goto fail;
+ }
+
+#if FONT_DEBUG >= 2
+ grub_printf("opened section %c%c%c%c ok\n",
+ section.name[0], section.name[1],
+ section.name[2], section.name[3]);
+#endif
+
+ if (grub_memcmp (section.name, section_names_font_name, 4) == 0)
+ {
+ font->name = read_section_as_string (§ion);
+ if (!font->name)
+ goto fail;
+ }
+ else if (grub_memcmp (section.name, section_names_point_size, 4) == 0)
+ {
+ if (read_section_as_short (§ion, &font->point_size) != 0)
+ goto fail;
+ }
+ else if (grub_memcmp (section.name, section_names_weight, 4) == 0)
+ {
+ char *wt;
+ wt = read_section_as_string (§ion);
+ if (!wt)
+ continue;
+ /* Convert the weight string 'normal' or 'bold' into a number. */
+ if (grub_strcmp (wt, "normal") == 0)
+ font->weight = FONT_WEIGHT_NORMAL;
+ else if (grub_strcmp (wt, "bold") == 0)
+ font->weight = FONT_WEIGHT_BOLD;
+ grub_free (wt);
+ }
+ else if (grub_memcmp (section.name, section_names_max_char_width, 4) ==
0)
+ {
+ if (read_section_as_short (§ion, &font->max_char_width) != 0)
+ goto fail;
+ }
+ else if (grub_memcmp (section.name, section_names_max_char_height, 4) ==
0)
+ {
+ if (read_section_as_short (§ion, &font->max_char_height) != 0)
+ goto fail;
+ }
+ else if (grub_memcmp (section.name, section_names_ascent, 4) == 0)
+ {
+ if (read_section_as_short (§ion, &font->ascent) != 0)
+ goto fail;
+ }
+ else if (grub_memcmp (section.name, section_names_descent, 4) == 0)
+ {
+ if (read_section_as_short (§ion, &font->descent) != 0)
+ goto fail;
+ }
+ else if (grub_memcmp (section.name, section_names_char_index, 4) == 0)
+ {
+ if (load_font_index (file, section.length, font) != 0)
+ goto fail;
+ }
+ else if (grub_memcmp (section.name, section_names_data, 4) == 0)
+ {
+ /* When the DATA section marker is reached, we stop reading. */
+ break;
+ }
+ else
+ {
+ /* Unhandled section type, simply skip past it. */
+#if FONT_DEBUG >= 3
+ grub_printf("Unhandled section type, skipping.\n");
+#endif
+ grub_off_t section_end = grub_file_tell (file) + section.length;
+ if ((int) grub_file_seek (file, section_end) == -1)
+ goto fail;
+ }
+ }
+
+ if (! font->name)
+ {
+ grub_printf ("Note: Font has no name.\n");
+ font->name = grub_strdup ("Unknown");
+ }
+
+#if FONT_DEBUG >= 1
+ grub_printf ("Loaded font `%s'.\n"
+ "Ascent=%d Descent=%d MaxW=%d MaxH=%d Number of
characters=%d.\n",
+ font->name,
+ font->ascent, font->descent,
+ font->max_char_width, font->max_char_height,
+ font->num_chars);
+#endif
+
+ if (font->max_char_width == 0
+ || font->max_char_height == 0
+ || font->num_chars == 0
+ || font->char_index == 0
+ || font->ascent == 0
+ || font->descent == 0)
+ {
+ grub_error (GRUB_ERR_BAD_FONT,
+ "Invalid font file: missing some required data.");
+ goto fail;
+ }
+
+ /* Add the font to the global font registry. */
+ if (register_font (font) != 0)
+ goto fail;
+
+ return 0;
+
+fail:
+ free_font (font);
+ return 1;
+}
+
+/* Read a 16-bit big-endian integer from FILE, convert it to native byte
+ order, and store it in *VALUE.
+ Returns 0 on success, 1 on failure. */
+static int
+read_be_uint16 (grub_file_t file, grub_uint16_t * value)
+{
+ if (grub_file_read (file, (char *) value, 2) != 2)
+ return 1;
+ *value = grub_be_to_cpu16 (*value);
+ return 0;
+}
+
+static int
+read_be_int16 (grub_file_t file, grub_int16_t * value)
+{
+ /* For the signed integer version, use the same code as for unsigned. */
+ return read_be_uint16 (file, (grub_uint16_t *) value);
+}
+
+/* Return a pointer to the character index entry for the glyph corresponding to
+ the codepoint CODE in the font FONT. If not found, return zero. */
+static struct char_index_entry *
+find_glyph (const grub_font_t font, grub_uint32_t code)
+{
+ grub_uint32_t i;
+ grub_uint32_t len = font->num_chars;
+ struct char_index_entry *table = font->char_index;
+
+ /* Do a linear search. */
+ for (i = 0; i < len; i++)
+ {
+ if (table[i].code == code)
+ return &table[i];
+ }
+
+ return 0;
+}
+
+/* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded
+ from the font file if has not been loaded yet.
+ Returns a pointer to the glyph if found, or 0 if it is not found. */
+static struct grub_font_glyph *
+grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code)
+{
+ struct char_index_entry *index_entry;
+
+ index_entry = find_glyph (font, code);
+ if (index_entry)
+ {
+ struct grub_font_glyph *glyph = 0;
+ grub_uint16_t width;
+ grub_uint16_t height;
+ grub_int16_t xoff;
+ grub_int16_t yoff;
+ grub_int16_t dwidth;
+ int len;
+
+ if (index_entry->glyph)
+ /* Return cached glyph. */
+ return index_entry->glyph;
+
+ if (! font->file)
+ /* No open file, can't load any glyphs. */
+ return 0;
+
+ /* Make sure we can find glyphs for error messages. Push active
+ error message to error stack and reset error message. */
+ grub_error_push ();
+
+ grub_file_seek (font->file, index_entry->offset);
+
+ /* Read the glyph width, height, and baseline. */
+ if (read_be_uint16(font->file, &width) != 0
+ || read_be_uint16(font->file, &height) != 0
+ || read_be_int16(font->file, &xoff) != 0
+ || read_be_int16(font->file, &yoff) != 0
+ || read_be_int16(font->file, &dwidth) != 0)
+ {
+ remove_font (font);
+ return 0;
+ }
+
+ len = (width * height + 7) / 8;
+ glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
+ if (! glyph)
+ {
+ remove_font (font);
+ return 0;
+ }
+
+ glyph->font = font;
+ glyph->width = width;
+ glyph->height = height;
+ glyph->offset_x = xoff;
+ glyph->offset_y = yoff;
+ glyph->device_width = dwidth;
+
+ /* Don't try to read empty bitmaps (e.g., space characters). */
+ if (len != 0)
+ {
+ if (grub_file_read (font->file, (char *) glyph->bitmap, len) != len)
+ {
+ remove_font (font);
+ return 0;
+ }
+ }
+
+ /* Restore old error message. */
+ grub_error_pop ();
+
+ /* Cache the glyph. */
+ index_entry->glyph = glyph;
+
+ return glyph;
+ }
+
+ return 0;
+}
+
+/* Free the memory used by FONT.
+ This should not be called if the font has been made available to
+ users (once it is added to the global font list), since there would
+ be the possibility of a dangling pointer. */
+static void
+free_font (grub_font_t font)
+{
+ if (font)
+ {
+ if (font->file)
+ grub_file_close (font->file);
+ grub_free (font->name);
+ grub_free (font->family);
+ grub_free (font->char_index);
+ grub_free (font);
+ }
+}
+
+/* Add FONT to the global font registry.
+ Returns 0 upon success, nonzero on failure
+ (the font was not registered). */
+static int
+register_font (grub_font_t font)
+{
+ struct grub_font_node *node = 0;
+
+ node = grub_malloc (sizeof (struct grub_font_node));
+ if (! node)
+ return 1;
+
+ node->value = font;
+ node->next = grub_font_list;
+ grub_font_list = node;
+
+ return 0;
+}
+
+/* Remove the font from the global font list. We don't actually free the
+ font's memory since users could be holding references to the font. */
+static void
+remove_font (grub_font_t font)
+{
+ struct grub_font_node **nextp, *cur;
+
+ for (nextp = &grub_font_list, cur = *nextp;
+ cur;
+ nextp = &cur->next, cur = cur->next)
+ {
+ if (cur->value == font)
+ {
+ *nextp = cur->next;
+
+ /* Free the node, but not the font itself. */
+ grub_free (cur);
+
+ return;
+ }
+ }
+}
+
+/* Get a font from the list of loaded fonts. This function will return
+ another font if the requested font is not available. If no fonts are
+ loaded, then a special 'null font' is returned, which contains no glyphs,
+ but is not a null pointer so the caller may omit checks for NULL. */
+grub_font_t
+grub_font_get (const char *font_name)
+{
+ struct grub_font_node *node;
+
+ for (node = grub_font_list; node; node = node->next)
+ {
+ grub_font_t font = node->value;
+ if (grub_strcmp (font->name, font_name) == 0)
+ return font;
+ }
+
+ /* If no font by that name is found, return the first font in the list
+ as a fallback. */
+ if (grub_font_list && grub_font_list->value)
+ return grub_font_list->value;
+ else
+ /* The null_font is a last resort. */
+ return &null_font;
+}
+
+/* Get the full name of the font. For instance, "Helvetica Bold 12". */
+const char *
+grub_font_get_name (grub_font_t font)
+{
+ return font->name;
+}
+
+/* Get the maximum width of any character in the font in pixels. */
+int
+grub_font_get_max_char_width (grub_font_t font)
+{
+ return font->max_char_width;
+}
+
+/* Get the maximum height of any character in the font in pixels. */
+int
+grub_font_get_max_char_height (grub_font_t font)
+{
+ return font->max_char_height;
+}
+
+/* Get the distance in pixels from the top of characters to the baseline. */
+int
+grub_font_get_ascent (grub_font_t font)
+{
+ return font->ascent;
+}
+
+/* Get the distance in pixels from the baseline to the lowest descenders
+ (for instance, in a lowercase 'y', 'g', etc.). */
+int
+grub_font_get_descent (grub_font_t font)
+{
+ return font->descent;
+}
+
+/* Get the *standard leading* of the font in pixel, which is the spacing
+ between two lines of text. Specifically, it is the space between the
+ descent of one line and the ascent of the next line. This is included
+ in the *height* metric. */
+int
+grub_font_get_leading (grub_font_t font)
+{
+ return font->leading;
+}
+
+/* Get the distance in pixels between baselines of adjacent lines of text. */
+int
+grub_font_get_height (grub_font_t font)
+{
+ return font->ascent + font->descent + font->leading;
+}
+
+/* Get the width in pixels of the specified UTF-8 string, when rendered in
+ in the specified font (but falling back on other fonts for glyphs that
+ are missing). */
+int
+grub_font_get_string_width (grub_font_t font, const char *str)
+{
+ int width;
+ struct grub_font_glyph *glyph;
+ grub_uint32_t code;
+ const grub_uint8_t *ptr;
+
+ for (ptr = (const grub_uint8_t *) str, width = 0;
+ grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; )
+ {
+ glyph = grub_font_get_glyph_with_fallback (font, code);
+ width += glyph->device_width;
+ }
+
+ return width;
+}
+
+/* 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. */
+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;
+ return glyph;
+}
+
+
+/* Calculate a subject value representing "how similar" two fonts are.
+ This is used to prioritize the order that fonts are scanned for missing
+ glyphs. The object is to select glyphs from the most similar font
+ possible, for the best appearance.
+ The heuristic is crude, but it helps greatly when fonts of similar
+ sizes are used so that tiny 8 point glyphs are not mixed into a string
+ of 24 point text unless there is no other choice. */
+static int
+get_font_diversity(grub_font_t a, grub_font_t b)
+{
+ int d;
+
+ d = 0;
+
+ if (a->ascent && b->ascent)
+ d += grub_abs (a->ascent - b->ascent) * 8;
+ else
+ /* Penalty for missing attributes. */
+ d += 50;
+
+ if (a->max_char_height && b->max_char_height)
+ d += grub_abs (a->max_char_height - b->max_char_height) * 8;
+ else
+ /* Penalty for missing attributes. */
+ d += 50;
+
+ /* Weight is a minor factor. */
+ d += (a->weight != b->weight) ? 5 : 0;
+
+ return d;
+}
+
+/* Get a glyph corresponding to the codepoint CODE. If FONT contains the
+ specified glyph, then it is returned. Otherwise, all other loaded fonts
+ are searched until one is found that contains a glyph for CODE.
+ If no glyph is available for CODE in the loaded fonts, then a glyph
+ representing an unknown character is returned.
+ This function never returns NULL.
+ The returned glyph is owned by the font manager and should not be freed
+ by the caller. The glyphs are cached. */
+struct grub_font_glyph *
+grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code)
+{
+ struct grub_font_glyph *glyph;
+ struct grub_font_node *node;
+ /* Keep track of next node, in case there's an I/O error in
+ grub_font_get_glyph_internal() and the font is removed from the list. */
+ struct grub_font_node *next;
+ /* Information on the best glyph found so far, to help find the glyph in
+ the best matching to the requested one. */
+ int best_diversity;
+ struct grub_font_glyph *best_glyph;
+
+ if (font)
+ {
+ /* First try to get the glyph from the specified font. */
+ glyph = grub_font_get_glyph_internal (font, code);
+ if (glyph)
+ return glyph;
+ }
+
+ /* Otherwise, search all loaded fonts for the glyph and use the one from
+ the font that best matches the requested font. */
+ best_diversity = 10000;
+ best_glyph = 0;
+
+ for (node = grub_font_list; node; node = next)
+ {
+ grub_font_t curfont;
+
+ curfont = node->value;
+ next = node->next;
+
+ glyph = grub_font_get_glyph_internal (curfont, code);
+ if (glyph)
+ {
+ int d;
+
+ d = get_font_diversity (curfont, font);
+ if (d < best_diversity)
+ {
+ best_diversity = d;
+ best_glyph = glyph;
+ }
+ }
+ }
+
+ if (best_glyph)
+ return best_glyph;
+ else
+ /* Glyph not available in any font. Return unknown glyph. */
+ return unknown_glyph;
+}
+
+
+/* Draw the specified glyph at (x, y). The y coordinate designates the
+ baseline of the character, while the x coordinate designates the left
+ side location of the character. */
+grub_err_t
+grub_font_draw_glyph (struct grub_font_glyph *glyph,
+ grub_video_color_t color,
+ int left_x, int baseline_y)
+{
+ struct grub_video_bitmap glyph_bitmap;
+
+ /* Don't try to draw empty glyphs (U+0020, etc.). */
+ if (glyph->width == 0 || glyph->height == 0)
+ return GRUB_ERR_NONE;
+
+ glyph_bitmap.mode_info.width = glyph->width;
+ glyph_bitmap.mode_info.height = glyph->height;
+ glyph_bitmap.mode_info.mode_type =
+ (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
+ | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
+ glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED;
+ glyph_bitmap.mode_info.bpp = 1;
+
+ /* Really 1 bit per pixel. */
+ glyph_bitmap.mode_info.bytes_per_pixel = 0;
+
+ /* Packed densely as bits. */
+ glyph_bitmap.mode_info.pitch = glyph->width;
+
+ glyph_bitmap.mode_info.number_of_colors = 2;
+ glyph_bitmap.mode_info.bg_red = 0;
+ glyph_bitmap.mode_info.bg_green = 0;
+ glyph_bitmap.mode_info.bg_blue = 0;
+ glyph_bitmap.mode_info.bg_alpha = 0;
+ grub_video_unmap_color(color,
+ &glyph_bitmap.mode_info.fg_red,
+ &glyph_bitmap.mode_info.fg_green,
+ &glyph_bitmap.mode_info.fg_blue,
+ &glyph_bitmap.mode_info.fg_alpha);
+ glyph_bitmap.data = glyph->bitmap;
+
+ int bitmap_left = left_x + glyph->offset_x;
+ int bitmap_bottom = baseline_y - glyph->offset_y;
+ int bitmap_top = bitmap_bottom - glyph->height;
+
+ return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND,
+ bitmap_left, bitmap_top,
+ 0, 0,
+ glyph->width, glyph->height);
+}
+
+/* Draw a UTF-8 string of text on the current video render target.
+ The x coordinate specifies the starting x position for the first character,
+ while the y coordinate specifies the baseline position.
+ If the string contains a character that FONT does not contain, then
+ a glyph from another loaded font may be used instead. */
+grub_err_t
+grub_font_draw_string (const char *str, grub_font_t font,
+ grub_video_color_t color,
+ int left_x, int baseline_y)
+{
+ int x;
+ struct grub_font_glyph *glyph;
+ grub_uint32_t code;
+ const grub_uint8_t *ptr;
+
+ for (ptr = (const grub_uint8_t *) str, x = left_x;
+ grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0; )
+ {
+ glyph = grub_font_get_glyph_with_fallback (font, code);
+ if (grub_font_draw_glyph (glyph, color, x, baseline_y)
+ != GRUB_ERR_NONE)
+ return grub_errno;
+ x += glyph->device_width;
+ }
+
+ return GRUB_ERR_NONE;
+}
+
Property changes on: trunk/grub2/font/font.c
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/font/font_cmd.c
===================================================================
--- trunk/grub2/font/font_cmd.c (rev 0)
+++ trunk/grub2/font/font_cmd.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,77 @@
+/* font_cmd.c - Font command definition. */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2003,2005,2006,2007,2008,2009 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 <grub/font.h>
+#include <grub/dl.h>
+#include <grub/normal.h>
+#include <grub/misc.h>
+
+static grub_err_t
+loadfont_command (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc,
+ char **args)
+{
+ if (argc == 0)
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified");
+
+ while (argc--)
+ if (grub_font_load (*args++) != 0)
+ return GRUB_ERR_BAD_FONT;
+
+ return GRUB_ERR_NONE;
+}
+
+static grub_err_t
+lsfonts_command (struct grub_arg_list *state __attribute__ ((unused)),
+ int argc __attribute__ ((unused)),
+ char **args __attribute__ ((unused)))
+{
+ struct grub_font_node *node;
+
+ grub_printf ("Loaded fonts:\n");
+ for (node = grub_font_list; node; node = node->next)
+ {
+ grub_font_t font = node->value;
+ grub_printf ("%s\n", grub_font_get_name (font));
+ }
+
+ return GRUB_ERR_NONE;
+}
+
+GRUB_MOD_INIT(font_manager)
+{
+ grub_font_loader_init ();
+
+ grub_register_command ("loadfont", loadfont_command, GRUB_COMMAND_FLAG_BOTH,
+ "loadfont FILE...",
+ "Specify one or more font files to load.", 0);
+
+ grub_register_command ("lsfonts", lsfonts_command, GRUB_COMMAND_FLAG_BOTH,
+ "lsfonts",
+ "List the loaded fonts.", 0);
+}
+
+GRUB_MOD_FINI(font_manager)
+{
+ /* TODO: Determine way to free allocated resources.
+ Warning: possible pointer references could be in use. */
+
+ grub_unregister_command ("loadfont");
+}
+
Property changes on: trunk/grub2/font/font_cmd.c
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Deleted: trunk/grub2/font/manager.c
===================================================================
--- trunk/grub2/font/manager.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/font/manager.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,283 +0,0 @@
-/*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2003,2005,2006,2007 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 <grub/file.h>
-#include <grub/misc.h>
-#include <grub/dl.h>
-#include <grub/normal.h>
-#include <grub/types.h>
-#include <grub/mm.h>
-#include <grub/font.h>
-#include <grub/bufio.h>
-
-struct entry
-{
- grub_uint32_t code;
- grub_uint32_t offset;
-};
-
-struct font
-{
- struct font *next;
- grub_file_t file;
- grub_uint32_t num;
- struct entry table[0];
-};
-
-static struct font *font_list;
-
-/* Fill unknown glyph's with rounded question mark. */
-static grub_uint8_t unknown_glyph[16] =
-{ /* 76543210 */
- 0x7C, /* ooooo */
- 0x82, /* o o */
- 0xBA, /* o ooo o */
- 0xAA, /* o o o o */
- 0xAA, /* o o o o */
- 0x8A, /* o o o */
- 0x9A, /* o oo o */
- 0x92, /* o o o */
- 0x92, /* o o o */
- 0x92, /* o o o */
- 0x92, /* o o o */
- 0x82, /* o o */
- 0x92, /* o o o */
- 0x82, /* o o */
- 0x7C, /* ooooo */
- 0x00 /* */
-};
-
-static int
-add_font (const char *filename)
-{
- grub_file_t file = 0;
- char magic[4];
- grub_uint32_t num, i;
- struct font *font = 0;
-
- file = grub_buffile_open (filename, 0);
- if (! file)
- goto fail;
-
- if (grub_file_read (file, magic, 4) != 4)
- goto fail;
-
- if (grub_memcmp (magic, GRUB_FONT_MAGIC, 4) != 0)
- {
- grub_error (GRUB_ERR_BAD_FONT, "invalid font magic");
- goto fail;
- }
-
- if (grub_file_read (file, (char *) &num, 4) != 4)
- goto fail;
-
- num = grub_le_to_cpu32 (num);
- font = (struct font *) grub_malloc (sizeof (struct font)
- + sizeof (struct entry) * num);
- if (! font)
- goto fail;
-
- font->file = file;
- font->num = num;
-
- for (i = 0; i < num; i++)
- {
- grub_uint32_t code, offset;
-
- if (grub_file_read (file, (char *) &code, 4) != 4)
- goto fail;
-
- if (grub_file_read (file, (char *) &offset, 4) != 4)
- goto fail;
-
- font->table[i].code = grub_le_to_cpu32 (code);
- font->table[i].offset = grub_le_to_cpu32 (offset);
- }
-
- font->next = font_list;
- font_list = font;
-
- return 1;
-
- fail:
- if (font)
- grub_free (font);
-
- if (file)
- grub_file_close (file);
-
- return 0;
-}
-
-static void
-remove_font (struct font *font)
-{
- struct font **p, *q;
-
- for (p = &font_list, q = *p; q; p = &(q->next), q = q->next)
- if (q == font)
- {
- *p = q->next;
-
- grub_file_close (font->file);
- grub_free (font);
-
- break;
- }
-}
-
-/* Return the offset of the glyph corresponding to the codepoint CODE
- in the font FONT. If no found, return zero. */
-static grub_uint32_t
-find_glyph (const struct font *font, grub_uint32_t code)
-{
- grub_uint32_t start = 0;
- grub_uint32_t end = font->num - 1;
- const struct entry *table = font->table;
-
- /* This shouldn't happen. */
- if (font->num == 0)
- return 0;
-
- /* Do a binary search. */
- while (start <= end)
- {
- grub_uint32_t i = (start + end) / 2;
-
- if (table[i].code < code)
- start = i + 1;
- else if (table[i].code > code)
- end = i - 1;
- else
- return table[i].offset;
- }
-
- return 0;
-}
-
-/* Set the glyph to something stupid. */
-static void
-fill_with_default_glyph (grub_font_glyph_t glyph)
-{
- unsigned i;
-
- /* Use pre-defined pattern to fill unknown glyphs. */
- for (i = 0; i < 16; i++)
- glyph->bitmap[i] = unknown_glyph[i];
-
- glyph->char_width = 1;
- glyph->width = glyph->char_width * 8;
- glyph->height = 16;
- glyph->baseline = (16 * 3) / 4;
-}
-
-/* Get a glyph corresponding to the codepoint CODE. Always fill glyph
- information with something, even if no glyph is found. */
-int
-grub_font_get_glyph (grub_uint32_t code,
- grub_font_glyph_t glyph)
-{
- struct font *font;
- grub_uint8_t bitmap[32];
-
- /* FIXME: It is necessary to cache glyphs! */
-
- restart:
- for (font = font_list; font; font = font->next)
- {
- grub_uint32_t offset;
-
- offset = find_glyph (font, code);
- if (offset)
- {
- grub_uint32_t w;
- int len;
-
- /* Make sure we can find glyphs for error messages. Push active
- error message to error stack and reset error message. */
- grub_error_push ();
-
- grub_file_seek (font->file, offset);
- if ((len = grub_file_read (font->file, (char *) &w, sizeof (w)))
- != sizeof (w))
- {
- remove_font (font);
- goto restart;
- }
-
- w = grub_le_to_cpu32 (w);
- if (w != 1 && w != 2)
- {
- /* grub_error (GRUB_ERR_BAD_FONT, "invalid width"); */
- remove_font (font);
- goto restart;
- }
-
- if (grub_file_read (font->file, (char *) bitmap, w * 16)
- != (grub_ssize_t) w * 16)
- {
- remove_font (font);
- goto restart;
- }
-
- /* Fill glyph with information. */
- grub_memcpy (glyph->bitmap, bitmap, w * 16);
-
- glyph->char_width = w;
- glyph->width = glyph->char_width * 8;
- glyph->height = 16;
- glyph->baseline = (16 * 3) / 4;
-
- /* Restore old error message. */
- grub_error_pop ();
-
- return 1;
- }
- }
-
- /* Uggh... No font was found. */
- fill_with_default_glyph (glyph);
- return 0;
-}
-
-static grub_err_t
-font_command (struct grub_arg_list *state __attribute__ ((unused)),
- int argc __attribute__ ((unused)),
- char **args __attribute__ ((unused)))
-{
- if (argc == 0)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "no font specified");
-
- while (argc--)
- if (! add_font (*args++))
- return 1;
-
- return 0;
-}
-
-GRUB_MOD_INIT(font_manager)
-{
- grub_register_command ("font", font_command, GRUB_COMMAND_FLAG_BOTH,
- "font FILE...",
- "Specify one or more font files to display.", 0);
-}
-
-GRUB_MOD_FINI(font_manager)
-{
- grub_unregister_command ("font");
-}
Modified: trunk/grub2/include/grub/font.h
===================================================================
--- trunk/grub2/include/grub/font.h 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/include/grub/font.h 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2003,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2003,2007,2008,2009 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
@@ -20,34 +20,96 @@
#define GRUB_FONT_HEADER 1
#include <grub/types.h>
+#include <grub/video.h>
-#define GRUB_FONT_MAGIC "PPF\x7f"
+/* Forward declaration of opaque structure grub_font.
+ Users only pass struct grub_font pointers to the font module functions,
+ and do not have knowledge of the structure contents. */
+struct grub_font;
+/* Font type used to access font functions. */
+typedef struct grub_font *grub_font_t;
+
+struct grub_font_node
+{
+ struct grub_font_node *next;
+ grub_font_t value;
+};
+
+/* Global font registry. */
+extern struct grub_font_node *grub_font_list;
+
struct grub_font_glyph
{
- /* Glyph width in pixels. */
- grub_uint8_t width;
-
- /* Glyph height in pixels. */
- grub_uint8_t height;
-
- /* Glyph width in characters. */
- grub_uint8_t char_width;
-
- /* Glyph baseline position in pixels (from up). */
- grub_uint8_t baseline;
-
- /* Glyph bitmap data array of bytes in ((width + 7) / 8) * height.
- Bitmap is formulated by height scanlines, each scanline having
- width number of pixels. Pixels are coded as bits, value 1 meaning
- of opaque pixel and 0 is transparent. If width does not fit byte
- boundary, it will be padded with 0 to make it fit. */
- grub_uint8_t bitmap[32];
+ /* Reference to the font this glyph belongs to. */
+ grub_font_t font;
+
+ /* Glyph bitmap width in pixels. */
+ grub_uint16_t width;
+
+ /* Glyph bitmap height in pixels. */
+ grub_uint16_t height;
+
+ /* Glyph bitmap x offset in pixels. Add to screen coordinate. */
+ grub_int16_t offset_x;
+
+ /* Glyph bitmap y offset in pixels. Subtract from screen coordinate. */
+ grub_int16_t offset_y;
+
+ /* Number of pixels to advance to start the next character. */
+ grub_uint16_t device_width;
+
+ /* Row-major order, packed bits (no padding; rows can break within a byte).
+ The length of the array is (width * height + 7) / 8. Within a
+ byte, the most significant bit is the first (leftmost/uppermost) pixel.
+ Pixels are coded as bits, value 1 meaning of opaque pixel and 0 is
+ transparent. If the length of the array does not fit byte boundary, it
+ will be padded with 0 bits to make it fit. */
+ grub_uint8_t bitmap[0];
};
-typedef struct grub_font_glyph *grub_font_glyph_t;
+/* Initialize the font loader.
+ Must be called before any fonts are loaded or used. */
+void grub_font_loader_init (void);
-int grub_font_get_glyph (grub_uint32_t code,
- grub_font_glyph_t glyph);
+/* Load a font and add it to the beginning of the global font list.
+ Returns: 0 upon success; nonzero upon failure. */
+int grub_font_load (const char *filename);
+/* Get the font that has the specified name. Font names are in the form
+ "Family Name Bold Italic 14", where Bold and Italic are optional.
+ If no font matches the name specified, the most recently loaded font
+ is returned as a fallback. */
+grub_font_t grub_font_get (const char *font_name);
+
+const char *grub_font_get_name (grub_font_t font);
+
+int grub_font_get_max_char_width (grub_font_t font);
+
+int grub_font_get_max_char_height (grub_font_t font);
+
+int grub_font_get_ascent (grub_font_t font);
+
+int grub_font_get_descent (grub_font_t font);
+
+int grub_font_get_leading (grub_font_t font);
+
+int grub_font_get_height (grub_font_t font);
+
+int grub_font_get_string_width (grub_font_t font, const char *str);
+
+struct grub_font_glyph *grub_font_get_glyph (grub_font_t font,
+ grub_uint32_t code);
+
+struct grub_font_glyph *grub_font_get_glyph_with_fallback (grub_font_t font,
+ grub_uint32_t code);
+
+grub_err_t grub_font_draw_glyph (struct grub_font_glyph *glyph,
+ grub_video_color_t color,
+ int left_x, int baseline_y);
+
+grub_err_t grub_font_draw_string (const char *str, grub_font_t font,
+ grub_video_color_t color,
+ int left_x, int baseline_y);
+
#endif /* ! GRUB_FONT_HEADER */
Modified: trunk/grub2/include/grub/misc.h
===================================================================
--- trunk/grub2/include/grub/misc.h 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/include/grub/misc.h 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,7 +1,7 @@
/* misc.h - prototypes for misc functions */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002,2003,2005,2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2003,2005,2006,2007,2008,2009 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
@@ -77,8 +77,10 @@
grub_uint16_t *src,
grub_size_t size);
grub_ssize_t EXPORT_FUNC(grub_utf8_to_ucs4) (grub_uint32_t *dest,
+ grub_size_t destsize,
const grub_uint8_t *src,
- grub_size_t size);
+ grub_size_t srcsize,
+ const grub_uint8_t **srcend);
grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n,
grub_uint32_t d, grub_uint32_t *r);
Modified: trunk/grub2/include/grub/video.h
===================================================================
--- trunk/grub2/include/grub/video.h 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/include/grub/video.h 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2008,2009 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
@@ -31,17 +31,17 @@
struct grub_video_render_target;
/* Forward declarations for used data structures. */
-struct grub_font_glyph;
struct grub_video_bitmap;
/* Defines used to describe video mode or rendering target. */
-#define GRUB_VIDEO_MODE_TYPE_ALPHA 0x00000008
-#define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000004
+#define GRUB_VIDEO_MODE_TYPE_ALPHA 0x00000020
+#define GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED 0x00000010
+#define GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP 0x00000004
#define GRUB_VIDEO_MODE_TYPE_INDEX_COLOR 0x00000002
#define GRUB_VIDEO_MODE_TYPE_RGB 0x00000001
/* Defines used to mask flags. */
-#define GRUB_VIDEO_MODE_TYPE_COLOR_MASK 0x00000003
+#define GRUB_VIDEO_MODE_TYPE_COLOR_MASK 0x0000000F
/* Defines used to specify requested bit depth. */
#define GRUB_VIDEO_MODE_TYPE_DEPTH_MASK 0x0000ff00
@@ -72,7 +72,10 @@
GRUB_VIDEO_BLIT_FORMAT_BGR_565,
/* When needed, decode color or just use value as is. */
- GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR
+ GRUB_VIDEO_BLIT_FORMAT_INDEXCOLOR,
+
+ /* Two color bitmap; bits packed: rows are not padded to byte boundary. */
+ GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED
};
/* Define blitting operators. */
@@ -135,6 +138,18 @@
/* What is location of reserved color bits. In Index Color mode,
this is 0. */
unsigned int reserved_field_pos;
+
+ /* For 1-bit bitmaps, the background color. Used for bits = 0. */
+ grub_uint8_t bg_red;
+ grub_uint8_t bg_green;
+ grub_uint8_t bg_blue;
+ grub_uint8_t bg_alpha;
+
+ /* For 1-bit bitmaps, the foreground color. Used for bits = 1. */
+ grub_uint8_t fg_red;
+ grub_uint8_t fg_green;
+ grub_uint8_t fg_blue;
+ grub_uint8_t fg_alpha;
};
struct grub_video_palette_data
@@ -188,9 +203,6 @@
grub_err_t (*fill_rect) (grub_video_color_t color, int x, int y,
unsigned int width, unsigned int height);
- grub_err_t (*blit_glyph) (struct grub_font_glyph *glyph,
- grub_video_color_t color, int x, int y);
-
grub_err_t (*blit_bitmap) (struct grub_video_bitmap *bitmap,
enum grub_video_blit_operators oper,
int x, int y, int offset_x, int offset_y,
@@ -260,9 +272,6 @@
grub_err_t grub_video_fill_rect (grub_video_color_t color, int x, int y,
unsigned int width, unsigned int height);
-grub_err_t grub_video_blit_glyph (struct grub_font_glyph *glyph,
- grub_video_color_t color, int x, int y);
-
grub_err_t grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
enum grub_video_blit_operators oper,
int x, int y, int offset_x, int offset_y,
Modified: trunk/grub2/kern/misc.c
===================================================================
--- trunk/grub2/kern/misc.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/kern/misc.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,7 +1,7 @@
/* misc.c - definitions of misc functions */
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008 Free
Software Foundation, Inc.
+ * Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009 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
@@ -951,22 +951,29 @@
return dest;
}
-/* Convert an UTF-8 string to an UCS-4 string. Return the number of
- characters converted. DEST must be able to hold at least SIZE
- characters (when the input is unknown). If an invalid sequence is found,
- return -1. */
+/* Convert a (possibly null-terminated) UTF-8 string of at most SRCSIZE
+ bytes (if SRCSIZE is -1, it is ignored) in length to a UCS-4 string.
+ Return the number of characters converted. DEST must be able to hold
+ at least DESTSIZE characters. If an invalid sequence is found, return -1.
+ If SRCEND is not NULL, then *SRCEND is set to the next byte after the
+ last byte used in SRC. */
grub_ssize_t
-grub_utf8_to_ucs4 (grub_uint32_t *dest, const grub_uint8_t *src,
- grub_size_t size)
+grub_utf8_to_ucs4 (grub_uint32_t *dest, grub_size_t destsize,
+ const grub_uint8_t *src, grub_size_t srcsize,
+ const grub_uint8_t **srcend)
{
grub_uint32_t *p = dest;
int count = 0;
grub_uint32_t code = 0;
- while (size--)
+ if (srcend)
+ *srcend = src;
+
+ while (srcsize && destsize)
{
grub_uint32_t c = *src++;
-
+ if (srcsize != (grub_size_t)-1)
+ srcsize--;
if (count)
{
if ((c & 0xc0) != 0x80)
@@ -983,6 +990,9 @@
}
else
{
+ if (c == 0)
+ break;
+
if ((c & 0x80) == 0x00)
code = c;
else if ((c & 0xe0) == 0xc0)
@@ -1011,14 +1021,18 @@
code = c & 0x01;
}
else
- /* invalid */
return -1;
}
if (count == 0)
- *p++ = code;
+ {
+ *p++ = code;
+ destsize--;
+ }
}
+ if (srcend)
+ *srcend = src;
return p - dest;
}
Modified: trunk/grub2/kern/term.c
===================================================================
--- trunk/grub2/kern/term.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/kern/term.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2002,2003,2005,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2002,2003,2005,2007,2008,2009 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
@@ -208,7 +208,7 @@
grub_ssize_t ret;
buf[size++] = c;
- ret = grub_utf8_to_ucs4 (&code, buf, size);
+ ret = grub_utf8_to_ucs4 (&code, 1, buf, size, 0);
if (ret > 0)
{
Modified: trunk/grub2/normal/menu.c
===================================================================
--- trunk/grub2/normal/menu.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/normal/menu.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2003,2004,2005,2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2003,2004,2005,2006,2007,2008,2009 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
@@ -116,19 +116,21 @@
{
int x;
const char *title;
+ grub_size_t title_len;
grub_ssize_t len;
grub_uint32_t *unicode_title;
grub_ssize_t i;
grub_uint8_t old_color_normal, old_color_highlight;
title = entry ? entry->title : "";
- unicode_title = grub_malloc (grub_strlen (title) * sizeof (*unicode_title));
+ title_len = grub_strlen (title);
+ unicode_title = grub_malloc (title_len * sizeof (*unicode_title));
if (! unicode_title)
/* XXX How to show this error? */
return;
- len = grub_utf8_to_ucs4 (unicode_title, (grub_uint8_t *) title,
- grub_strlen (title));
+ len = grub_utf8_to_ucs4 (unicode_title, title_len,
+ (grub_uint8_t *) title, -1, 0);
if (len < 0)
{
/* It is an invalid sequence. */
Modified: trunk/grub2/term/gfxterm.c
===================================================================
--- trunk/grub2/term/gfxterm.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/term/gfxterm.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2008,2009 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
@@ -34,9 +34,6 @@
#define DEFAULT_VIDEO_HEIGHT 480
#define DEFAULT_VIDEO_FLAGS 0
-#define DEFAULT_CHAR_WIDTH 8
-#define DEFAULT_CHAR_HEIGHT 16
-
#define DEFAULT_BORDER_WIDTH 10
#define DEFAULT_STANDARD_COLOR 0x07
@@ -69,27 +66,32 @@
struct grub_virtual_screen
{
- /* Dimensions of the virtual screen. */
+ /* Dimensions of the virtual screen in pixels. */
unsigned int width;
unsigned int height;
- /* Offset in the display. */
+ /* Offset in the display in pixels. */
unsigned int offset_x;
unsigned int offset_y;
- /* TTY Character sizes. */
- unsigned int char_width;
- unsigned int char_height;
+ /* TTY Character sizes in pixes. */
+ unsigned int normal_char_width;
+ unsigned int normal_char_height;
- /* Virtual screen TTY size. */
+ /* Virtual screen TTY size in characters. */
unsigned int columns;
unsigned int rows;
- /* Current cursor details. */
+ /* Current cursor location in characters. */
unsigned int cursor_x;
unsigned int cursor_y;
+
+ /* Current cursor state. */
int cursor_state;
+ /* Font settings. */
+ grub_font_t font;
+
/* Terminal color settings. */
grub_uint8_t standard_color_setting;
grub_uint8_t normal_color_setting;
@@ -125,6 +127,10 @@
static void dirty_region_add (int x, int y,
unsigned int width, unsigned int height);
+static unsigned int calculate_normal_character_width (grub_font_t font);
+
+static unsigned char calculate_character_width (struct grub_font_glyph *glyph);
+
static void
set_term_color (grub_uint8_t term_color)
{
@@ -168,25 +174,32 @@
static grub_err_t
grub_virtual_screen_setup (unsigned int x, unsigned int y,
- unsigned int width, unsigned int height)
+ unsigned int width, unsigned int height,
+ const char *font_name)
{
/* Free old virtual screen. */
grub_virtual_screen_free ();
/* Initialize with default data. */
+ virtual_screen.font = grub_font_get (font_name);
+ if (!virtual_screen.font)
+ return grub_error (GRUB_ERR_BAD_FONT,
+ "No font loaded.");
virtual_screen.width = width;
virtual_screen.height = height;
virtual_screen.offset_x = x;
virtual_screen.offset_y = y;
- virtual_screen.char_width = DEFAULT_CHAR_WIDTH;
- virtual_screen.char_height = DEFAULT_CHAR_HEIGHT;
+ virtual_screen.normal_char_width =
+ calculate_normal_character_width (virtual_screen.font);
+ virtual_screen.normal_char_height =
+ grub_font_get_max_char_height (virtual_screen.font);
virtual_screen.cursor_x = 0;
virtual_screen.cursor_y = 0;
virtual_screen.cursor_state = 1;
/* Calculate size of text buffer. */
- virtual_screen.columns = virtual_screen.width / virtual_screen.char_width;
- virtual_screen.rows = virtual_screen.height / virtual_screen.char_height;
+ virtual_screen.columns = virtual_screen.width /
virtual_screen.normal_char_width;
+ virtual_screen.rows = virtual_screen.height /
virtual_screen.normal_char_height;
/* Allocate memory for text buffer. */
virtual_screen.text_buffer =
@@ -225,6 +238,7 @@
static grub_err_t
grub_gfxterm_init (void)
{
+ char *font_name;
char *modevar;
int width = DEFAULT_VIDEO_WIDTH;
int height = DEFAULT_VIDEO_HEIGHT;
@@ -232,6 +246,11 @@
int flags = DEFAULT_VIDEO_FLAGS;
grub_video_color_t color;
+ /* Select the font to use. */
+ font_name = grub_env_get ("gfxterm_font");
+ if (! font_name)
+ font_name = ""; /* Allow fallback to any font. */
+
/* Parse gfxmode environment variable if set. */
modevar = grub_env_get ("gfxmode");
if (modevar)
@@ -471,7 +490,7 @@
/* Create virtual screen. */
if (grub_virtual_screen_setup (DEFAULT_BORDER_WIDTH, DEFAULT_BORDER_WIDTH,
- width, height) != GRUB_ERR_NONE)
+ width, height, font_name) != GRUB_ERR_NONE)
{
grub_video_restore ();
return grub_errno;
@@ -657,11 +676,12 @@
write_char (void)
{
struct grub_colored_char *p;
- struct grub_font_glyph glyph;
+ struct grub_font_glyph *glyph;
grub_video_color_t color;
grub_video_color_t bgcolor;
unsigned int x;
unsigned int y;
+ int ascent;
/* Find out active character. */
p = (virtual_screen.text_buffer
@@ -671,27 +691,28 @@
p -= p->index;
/* Get glyph for character. */
- grub_font_get_glyph (p->code, &glyph);
+ glyph = grub_font_get_glyph (virtual_screen.font, p->code);
+ ascent = grub_font_get_ascent (virtual_screen.font);
color = p->fg_color;
bgcolor = p->bg_color;
- x = virtual_screen.cursor_x * virtual_screen.char_width;
- y = virtual_screen.cursor_y * virtual_screen.char_height;
+ x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
+ y = virtual_screen.cursor_y * virtual_screen.normal_char_height;
/* Render glyph to text layer. */
grub_video_set_active_render_target (text_layer);
- grub_video_fill_rect (bgcolor, x, y, glyph.width, glyph.height);
- grub_video_blit_glyph (&glyph, color, x, y);
+ grub_video_fill_rect (bgcolor, x, y, glyph->width, glyph->height);
+ grub_font_draw_glyph (glyph, color, x, y + ascent);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
/* Mark character to be drawn. */
dirty_region_add (virtual_screen.offset_x + x, virtual_screen.offset_y + y,
- glyph.width, glyph.height);
+ glyph->width, glyph->height);
}
static void
-write_cursor (void)
+draw_cursor (int show)
{
unsigned int x;
unsigned int y;
@@ -700,12 +721,22 @@
grub_video_color_t color;
/* Determine cursor properties and position on text layer. */
- x = virtual_screen.cursor_x * virtual_screen.char_width;
- y = ((virtual_screen.cursor_y + 1) * virtual_screen.char_height) - 3;
- width = virtual_screen.char_width;
+ x = virtual_screen.cursor_x * virtual_screen.normal_char_width;
+ y = (virtual_screen.cursor_y * virtual_screen.normal_char_height
+ + grub_font_get_ascent (virtual_screen.font));
+ width = virtual_screen.normal_char_width;
height = 2;
- color = virtual_screen.fg_color;
+ if (show)
+ {
+ color = virtual_screen.fg_color;
+ }
+ else
+ {
+ color = virtual_screen.bg_color;
+ y = virtual_screen.cursor_y * virtual_screen.normal_char_height;
+ height = virtual_screen.normal_char_height;
+ }
/* Render cursor to text layer. */
grub_video_set_active_render_target (text_layer);
@@ -727,7 +758,7 @@
if (!bitmap)
{
/* Remove cursor. */
- write_char ();
+ draw_cursor (0);
/* Redraw only changed regions. */
dirty_region_redraw ();
@@ -755,7 +786,7 @@
/* Scroll physical screen. */
grub_video_set_active_render_target (text_layer);
color = virtual_screen.bg_color;
- grub_video_scroll (color, 0, -virtual_screen.char_height);
+ grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
grub_video_set_active_render_target (GRUB_VIDEO_RENDER_TARGET_DISPLAY);
/* If we have bitmap, re-draw screen, otherwise scroll physical screen too.
*/
@@ -767,16 +798,16 @@
else
{
/* Clear new border area. */
- grub_video_fill_rect (color,
- virtual_screen.offset_x, virtual_screen.offset_y,
- virtual_screen.width, virtual_screen.char_height);
-
+ grub_video_fill_rect (color,
+ virtual_screen.offset_x, virtual_screen.offset_y,
+ virtual_screen.width,
virtual_screen.normal_char_height);
+
/* Scroll physical screen. */
- grub_video_scroll (color, 0, -virtual_screen.char_height);
+ grub_video_scroll (color, 0, -virtual_screen.normal_char_height);
/* Draw cursor if visible. */
if (virtual_screen.cursor_state)
- write_cursor ();
+ draw_cursor (1);
}
}
@@ -791,7 +822,7 @@
{
/* Erase current cursor, if any. */
if (virtual_screen.cursor_state)
- write_char ();
+ draw_cursor (0);
switch (c)
{
@@ -814,18 +845,27 @@
/* Redraw cursor if visible. */
if (virtual_screen.cursor_state)
- write_cursor ();
+ draw_cursor (1);
}
else
{
- struct grub_font_glyph glyph;
+ struct grub_font_glyph *glyph;
struct grub_colored_char *p;
+ unsigned char char_width;
- /* Get properties of the character. */
- grub_font_get_glyph (c, &glyph);
+ /* Erase current cursor, if any. */
+ if (virtual_screen.cursor_state)
+ draw_cursor (0);
+ /* Get properties of the character. */
+ glyph = grub_font_get_glyph (virtual_screen.font, c);
+
+ /* Calculate actual character width for glyph. This is number of
+ times of normal_font_width. */
+ char_width = calculate_character_width(glyph);
+
/* If we are about to exceed line length, wrap to next line. */
- if (virtual_screen.cursor_x + glyph.char_width > virtual_screen.columns)
+ if (virtual_screen.cursor_x + char_width > virtual_screen.columns)
grub_putchar ('\n');
/* Find position on virtual screen, and fill information. */
@@ -835,18 +875,18 @@
p->code = c;
p->fg_color = virtual_screen.fg_color;
p->bg_color = virtual_screen.bg_color;
- p->width = glyph.char_width - 1;
+ p->width = char_width - 1;
p->index = 0;
/* If we have large glyph, add fixup info. */
- if (glyph.char_width > 1)
+ if (char_width > 1)
{
unsigned i;
- for (i = 1; i < glyph.char_width; i++)
+ for (i = 1; i < char_width; i++)
{
p[i].code = ' ';
- p[i].width = glyph.char_width - 1;
+ p[i].width = char_width - 1;
p[i].index = i;
}
}
@@ -855,7 +895,7 @@
write_char ();
/* Make sure we scroll screen when needed and wrap line correctly. */
- virtual_screen.cursor_x += glyph.char_width;
+ virtual_screen.cursor_x += char_width;
if (virtual_screen.cursor_x >= virtual_screen.columns)
{
virtual_screen.cursor_x = 0;
@@ -868,18 +908,58 @@
/* Draw cursor if visible. */
if (virtual_screen.cursor_state)
- write_cursor ();
+ draw_cursor (1);
}
}
+/* Use ASCII characters to determine normal character width. */
+static unsigned int
+calculate_normal_character_width (grub_font_t font)
+{
+ struct grub_font_glyph *glyph;
+ unsigned int width = 0;
+ unsigned int i;
+
+ /* Get properties of every printable ASCII character. */
+ for (i = 32; i < 127; i++)
+ {
+ glyph = grub_font_get_glyph (font, i);
+
+ /* Skip unknown characters. Should never happen on normal conditions.
*/
+ if (! glyph)
+ continue;
+
+ if (glyph->device_width > width)
+ width = glyph->device_width;
+ }
+
+ return width;
+}
+
+static unsigned char
+calculate_character_width (struct grub_font_glyph *glyph)
+{
+ if (! glyph || glyph->device_width == 0)
+ return 1;
+
+ return (glyph->device_width
+ + (virtual_screen.normal_char_width - 1))
+ / virtual_screen.normal_char_width;
+}
+
static grub_ssize_t
grub_gfxterm_getcharwidth (grub_uint32_t c)
{
- struct grub_font_glyph glyph;
+ struct grub_font_glyph *glyph;
+ unsigned char char_width;
- grub_font_get_glyph (c, &glyph);
+ /* Get properties of the character. */
+ glyph = grub_font_get_glyph (virtual_screen.font, c);
- return glyph.char_width;
+ /* Calculate actual character width for glyph. */
+ char_width = calculate_character_width (glyph);
+
+ return char_width;
}
static grub_uint16_t
@@ -903,14 +983,16 @@
if (y >= virtual_screen.rows)
y = virtual_screen.rows - 1;
+ /* Erase current cursor, if any. */
if (virtual_screen.cursor_state)
- write_char ();
+ draw_cursor (0);
virtual_screen.cursor_x = x;
virtual_screen.cursor_y = y;
+ /* Draw cursor if visible. */
if (virtual_screen.cursor_state)
- write_cursor ();
+ draw_cursor (1);
}
static void
@@ -995,9 +1077,9 @@
if (virtual_screen.cursor_state != on)
{
if (virtual_screen.cursor_state)
- write_char ();
+ draw_cursor (0);
else
- write_cursor ();
+ draw_cursor (1);
virtual_screen.cursor_state = on;
}
Modified: trunk/grub2/term/i386/pc/vesafb.c
===================================================================
--- trunk/grub2/term/i386/pc/vesafb.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/term/i386/pc/vesafb.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2007,2009 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
@@ -16,6 +16,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+// TODO: Deprecated and broken. Scheduled for removal as there is VBE driver
in Video subsystem.
+
#include <grub/machine/memory.h>
#include <grub/machine/vga.h>
#include <grub/machine/vbe.h>
@@ -250,10 +252,11 @@
break;
default:
- return grub_font_get_glyph (code, bitmap, width);
+ return grub_font_get_glyph_any (code, bitmap, width);
}
}
+ /* TODO This is wrong for the new font module. Should it be fixed? */
if (bitmap)
grub_memcpy (bitmap,
vga_font + code * virtual_screen.char_height,
Modified: trunk/grub2/term/i386/pc/vga.c
===================================================================
--- trunk/grub2/term/i386/pc/vga.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/term/i386/pc/vga.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008 Free Software
Foundation, Inc.
+ * Copyright (C) 2000,2001,2002,2003,2004,2005,2007,2008,2009 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
@@ -16,6 +16,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+// TODO: Deprecated and broken. Needs to be converted to Video Driver!
+
#include <grub/machine/vga.h>
#include <grub/machine/console.h>
#include <grub/cpu/io.h>
@@ -65,6 +67,7 @@
static struct colored_char text_buf[TEXT_WIDTH * TEXT_HEIGHT];
static unsigned char saved_map_mask;
static int page = 0;
+static grub_font_t font = 0;
#define SEQUENCER_ADDR_PORT 0x3C4
#define SEQUENCER_DATA_PORT 0x3C5
@@ -161,6 +164,9 @@
saved_map_mask = get_map_mask ();
set_map_mask (0x0f);
set_start_address (PAGE_OFFSET (page));
+ font = grub_font_get (""); /* Choose any font, for now. */
+ if (!font)
+ return grub_error (GRUB_ERR_BAD_FONT, "No font loaded.");
return GRUB_ERR_NONE;
}
@@ -185,7 +191,7 @@
write_char (void)
{
struct colored_char *p = text_buf + xpos + ypos * TEXT_WIDTH;
- struct grub_font_glyph glyph;
+ struct grub_font_glyph *glyph;
unsigned char *mem_base;
unsigned plane;
@@ -194,7 +200,7 @@
p -= p->index;
/* Get glyph for character. */
- grub_font_get_glyph (p->code, &glyph);
+ glyph = grub_font_get_glyph (font, p->code);
for (plane = 0x01; plane <= 0x08; plane <<= 1)
{
@@ -208,19 +214,23 @@
y < CHAR_HEIGHT;
y++, mem += TEXT_WIDTH)
{
+ /* TODO Re-implement glyph drawing for vga module. */
+#if 0
unsigned i;
- for (i = 0; i < glyph.char_width && offset < 32; i++)
+ unsigned char_width = 1; /* TODO Figure out wide characters. */
+ for (i = 0; i < char_width && offset < 32; i++)
{
unsigned char fg_mask, bg_mask;
- fg_mask = (p->fg_color & plane) ? glyph.bitmap[offset] : 0;
- bg_mask = (p->bg_color & plane) ? ~(glyph.bitmap[offset]) : 0;
+ fg_mask = (p->fg_color & plane) ? glyph->bitmap[offset] : 0;
+ bg_mask = (p->bg_color & plane) ? ~(glyph->bitmap[offset]) : 0;
offset++;
if (check_vga_mem (mem + i))
mem[i] = (fg_mask | bg_mask);
}
+#endif /* 0 */
}
}
@@ -320,36 +330,37 @@
}
else
{
- struct grub_font_glyph glyph;
+ struct grub_font_glyph *glyph;
struct colored_char *p;
+ unsigned char_width = 1;
- grub_font_get_glyph(c, &glyph);
+ glyph = grub_font_get_glyph(font, c);
- if (xpos + glyph.char_width > TEXT_WIDTH)
+ if (xpos + char_width > TEXT_WIDTH)
grub_putchar ('\n');
p = text_buf + xpos + ypos * TEXT_WIDTH;
p->code = c;
p->fg_color = fg_color;
p->bg_color = bg_color;
- p->width = glyph.char_width - 1;
+ p->width = char_width - 1;
p->index = 0;
- if (glyph.char_width > 1)
+ if (char_width > 1)
{
unsigned i;
- for (i = 1; i < glyph.char_width; i++)
+ for (i = 1; i < char_width; i++)
{
p[i].code = ' ';
- p[i].width = glyph.char_width - 1;
+ p[i].width = char_width - 1;
p[i].index = i;
}
}
write_char ();
- xpos += glyph.char_width;
+ xpos += char_width;
if (xpos >= TEXT_WIDTH)
{
xpos = 0;
@@ -381,11 +392,16 @@
static grub_ssize_t
grub_vga_getcharwidth (grub_uint32_t c)
{
+#if 0
struct grub_font_glyph glyph;
- grub_font_get_glyph (c, &glyph);
+ glyph = grub_font_get_glyph (c);
return glyph.char_width;
+#else
+ (void) c; /* Prevent warning. */
+ return 1; /* TODO Fix wide characters? */
+#endif
}
static grub_uint16_t
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,271 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+import java.io.*;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class BDFLoader {
+ private final BufferedReader in;
+ private final Font font;
+ private int maxCharWidth;
+ private int maxCharHeight;
+
+ BDFLoader(BufferedReader in) {
+ this.in = in;
+ this.font = new Font();
+ this.maxCharWidth = 0;
+ this.maxCharHeight = 0;
+ }
+
+ public static boolean isBDFFile(String filename) {
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(new FileInputStream(filename));
+ final String signature = "STARTFONT ";
+ byte[] b = new byte[signature.length()];
+ in.readFully(b);
+ in.close();
+
+ String s = new String(b, "US-ASCII");
+ return signature.equals(s);
+ } catch (IOException e) {
+ if (in != null) {
+ try {
+ in.close();
+ } catch (IOException e1) {
+ // Ignore.
+ }
+ }
+ return false;
+ }
+ }
+
+ public static Font loadFontResource(String resourceName) throws
IOException {
+ InputStream in =
BDFLoader.class.getClassLoader().getResourceAsStream(resourceName);
+ if (in == null)
+ throw new FileNotFoundException("Font resource " + resourceName +
" not found");
+ return loadFontFromStream(in);
+ }
+
+ public static Font loadFontFile(String filename) throws IOException {
+ InputStream in = new FileInputStream(filename);
+ return loadFontFromStream(in);
+ }
+
+ private static Font loadFontFromStream(InputStream inStream) throws
IOException {
+ BufferedReader in;
+ try {
+ in = new BufferedReader(new InputStreamReader(inStream,
"ISO-8859-1"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException("Encoding not supported: " +
e.getMessage(), e);
+ }
+ return new BDFLoader(in).loadFont();
+ }
+
+ private Font loadFont() throws IOException {
+ loadFontInfo();
+ while (loadChar()) {
+ /* Loop. */
+ }
+
+ font.setMaxCharWidth(maxCharWidth);
+ font.setMaxCharHeight(maxCharHeight);
+ return font;
+ }
+
+ private void loadFontInfo() throws IOException {
+ final Pattern stringSettingPattern =
Pattern.compile("^(\\w+)\\s+\"([^\"]+)\"$");
+ String line;
+ // Load the global font information that appears before CHARS.
+ final int UNSET = Integer.MIN_VALUE;
+ font.setAscent(UNSET);
+ font.setDescent(UNSET);
+ font.setFamily("Unknown");
+ font.setBold(false);
+ font.setItalic(false);
+ font.setPointSize(Font.UNKNOWN_POINT_SIZE);
+ do {
+ line = in.readLine();
+ if (line == null)
+ throw new IOException("BDF format error: end of file while " +
+ "reading global font information");
+
+ StringTokenizer st = new StringTokenizer(line);
+ if (st.hasMoreTokens()) {
+ String name = st.nextToken();
+ if (name.equals("FONT_ASCENT")) {
+ if (!st.hasMoreTokens())
+ throw new IOException("BDF format error: " +
+ "no tokens after " + name);
+ font.setAscent(Integer.parseInt(st.nextToken()));
+ } else if (name.equals("FONT_DESCENT")) {
+ if (!st.hasMoreTokens())
+ throw new IOException("BDF format error: " +
+ "no tokens after " + name);
+ font.setDescent(Integer.parseInt(st.nextToken()));
+ } else if (name.equals("POINT_SIZE")) {
+ if (!st.hasMoreTokens())
+ throw new IOException("BDF format error: " +
+ "no tokens after " + name);
+ // Divide by 10, since it is stored X10.
+ font.setPointSize(Integer.parseInt(st.nextToken()) / 10);
+ } else if (name.equals("FAMILY_NAME")) {
+ Matcher matcher = stringSettingPattern.matcher(line);
+ if (!matcher.matches())
+ throw new IOException("BDF format error: " +
+ "line doesn't match string " +
+ "setting pattern: " + line);
+ font.setFamily(matcher.group(2));
+ } else if (name.equals("WEIGHT_NAME")) {
+ Matcher matcher = stringSettingPattern.matcher(line);
+ if (!matcher.matches())
+ throw new IOException("BDF format error: " +
+ "line doesn't match string " +
+ "setting pattern: " + line);
+ String weightName = matcher.group(2);
+ font.setBold("bold".equalsIgnoreCase(weightName));
+ } else if (name.equals("SLANT")) {
+ Matcher matcher = stringSettingPattern.matcher(line);
+ if (!matcher.matches())
+ throw new IOException("BDF format error: " +
+ "line doesn't match string " +
+ "setting pattern: " + line);
+ String slantType = matcher.group(2);
+ font.setItalic(!"R".equalsIgnoreCase(slantType));
+ } else if (name.equals("CHARS")) {
+ // This is the end of the global font information and
+ // the beginning of the character definitions.
+ break;
+ } else {
+ // Skip other fields.
+ }
+ }
+ } while (true);
+
+ if (font.getAscent() == UNSET)
+ throw new IOException("BDF format error: no FONT_ASCENT property");
+ if (font.getDescent() == UNSET)
+ throw new IOException("BDF format error: no FONT_DESCENT
property");
+ }
+
+ private boolean loadChar() throws IOException {
+ String line;
+ // Find start of character
+ do {
+ line = in.readLine();
+ if (line == null)
+ return false;
+ StringTokenizer st = new StringTokenizer(line);
+ if (st.hasMoreTokens() && st.nextToken().equals("STARTCHAR")) {
+ if (!st.hasMoreTokens())
+ throw new IOException("BDF format error: no character name
after STARTCHAR");
+ break;
+ }
+ } while (true);
+
+ // Find properties
+ final int UNSET = Integer.MIN_VALUE;
+ int codePoint = UNSET;
+ int bbx = UNSET;
+ int bby = UNSET;
+ int bbox = UNSET;
+ int bboy = UNSET;
+ int dwidth = UNSET;
+ do {
+ line = in.readLine();
+ if (line == null)
+ return false;
+ StringTokenizer st = new StringTokenizer(line);
+ if (st.hasMoreTokens()) {
+ String field = st.nextToken();
+ if (field.equals("ENCODING")) {
+ if (!st.hasMoreTokens())
+ throw new IOException("BDF format error: no encoding #
after ENCODING");
+ String codePointStr = st.nextToken();
+ codePoint = Integer.parseInt(codePointStr);
+ } else if (field.equals("BBX")) {
+ if (!st.hasMoreTokens())
+ throw new IOException("BDF format error: no tokens
after BBX");
+ bbx = Integer.parseInt(st.nextToken());
+ bby = Integer.parseInt(st.nextToken());
+ bbox = Integer.parseInt(st.nextToken());
+ bboy = Integer.parseInt(st.nextToken());
+ } else if (field.equals("DWIDTH")) {
+ if (!st.hasMoreTokens())
+ throw new IOException("BDF format error: no tokens
after DWIDTH");
+ dwidth = Integer.parseInt(st.nextToken());
+ int dwidthY = Integer.parseInt(st.nextToken());
+ // The DWIDTH Y value should be zero for any normal font.
+ if (dwidthY != 0) {
+ throw new IOException("BDF format error: dwidth Y
value" +
+ "is nonzero (" + dwidthY + ") " +
+ "for char " + codePoint + ".");
+ }
+ } else if (field.equals("BITMAP")) {
+ break; // now read the bitmap
+ }
+ }
+ } while (true);
+
+ if (codePoint == UNSET)
+ throw new IOException("BDF format error: " +
+ "no code point set");
+ if (bbx == UNSET || bby == UNSET)
+ throw new IOException("BDF format error: " +
+ "bbx/bby missing: " + bbx + ", " + bby +
+ " for char " + codePoint);
+
+ if (bbox == UNSET || bboy == UNSET)
+ throw new IOException("BDF format error: " +
+ "bbox/bboy missing: " + bbox + ", " + bboy +
+ " for char " + codePoint);
+
+ if (dwidth == UNSET)
+ throw new IOException("BDF format error: " +
+ "dwidth missing for char " + codePoint);
+
+ final int glyphWidth = bbx;
+ final int glyphHeight = bby;
+ if (glyphWidth > maxCharWidth)
+ maxCharWidth = glyphWidth;
+ if (glyphHeight > maxCharHeight)
+ maxCharHeight = glyphHeight;
+
+ // Read the bitmap
+ Glyph glyph = new Glyph(codePoint, glyphWidth, glyphHeight, bbox,
bboy, dwidth);
+ for (int y = 0; y < glyphHeight; y++) {
+ line = in.readLine();
+ if (line == null)
+ return false;
+ for (int b = 0; b < line.length(); b++) {
+ int v = Integer.parseInt(Character.toString(line.charAt(b)),
16);
+ for (int x = b * 4, i = 0; i < 4 && x < glyphWidth; x++, i++) {
+ boolean set = (v & 0x8) != 0;
+ v <<= 1;
+ glyph.setPixel(x, y, set);
+ }
+ }
+ }
+
+ font.putGlyph(codePoint, glyph);
+ return true;
+ }
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/BDFLoader.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,181 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.TreeMap;
+
+class CharDefs {
+ private boolean debug = "1".equals(System.getProperty("fonttool.debug"));
+ private TreeMap<Integer, Glyph> glyphs;
+ private ByteArrayOutputStream charDefsData;
+ private int maxCharWidth;
+ private int maxCharHeight;
+ private HashMap<Integer, CharStorageInfo> charIndex;
+
+ public CharDefs(Font font) {
+ this.glyphs = font.getGlyphs();
+ this.charIndex = null;
+ this.charDefsData = null;
+
+ calculateMaxSizes();
+ }
+
+ private void calculateMaxSizes() {
+ maxCharWidth = 0;
+ maxCharHeight = 0;
+ for (Glyph glyph : glyphs.values()) {
+ final int w = glyph.getWidth();
+ final int h = glyph.getHeight();
+ if (w > maxCharWidth)
+ maxCharWidth = w;
+ if (h > maxCharHeight)
+ maxCharHeight = h;
+ }
+ }
+
+ void buildDefinitions(List<CharacterRange> rangeList) {
+ charIndex = new HashMap<Integer, CharStorageInfo>();
+ HashMap<CharDef, Long> charDefIndex = new HashMap<CharDef, Long>();
+ charDefsData = new ByteArrayOutputStream();
+ DataOutputStream charDefs = new DataOutputStream(charDefsData);
+ try {
+ // Loop through all the glyphs, writing the glyph data to the
+ // in-memory byte stream, collapsing duplicate glyphs, and
+ // constructing index information.
+ for (Glyph glyph : glyphs.values()) {
+ // Determine if glyph should be included in written file
+ if (rangeList.size() > 0) {
+ boolean skip = true;
+
+ for (Iterator<CharacterRange> iter =
rangeList.iterator(); iter
+ .hasNext();) {
+ CharacterRange item =
iter.next();
+
+ if
(item.isWithinRange(glyph.getCodePoint())) {
+ skip = false;
+ break;
+ }
+ }
+
+ if (skip) {
+ continue;
+ }
+ }
+
+ CharDef charDef = new CharDef(glyph.getWidth(),
+ glyph.getHeight(),
+ glyph.getBitmap());
+
+ if (charDefIndex.containsKey(charDef)) {
+ // Use already-written glyph.
+ if (debug)
+ System.out.printf("Duplicate glyph for character
U+%04X%n",
+ glyph.getCodePoint());
+ final int charOffset =
charDefIndex.get(charDef).intValue();
+ final CharStorageInfo info =
+ new CharStorageInfo(glyph.getCodePoint(),
charOffset);
+ charIndex.put(glyph.getCodePoint(), info);
+ } else {
+ // Write glyph data.
+ final int charOffset = charDefs.size();
+ final CharStorageInfo info =
+ new CharStorageInfo(glyph.getCodePoint(),
charOffset);
+ charIndex.put(glyph.getCodePoint(), info);
+
+ charDefIndex.put(charDef, (long) charOffset);
+
+ charDefs.writeShort(glyph.getWidth());
+ charDefs.writeShort(glyph.getHeight());
+ charDefs.writeShort(glyph.getBbox());
+ charDefs.writeShort(glyph.getBboy());
+ charDefs.writeShort(glyph.getDeviceWidth());
+ charDefs.write(glyph.getBitmap());
+ }
+ }
+ } catch (IOException e) {
+ throw new RuntimeException("Error writing to in-memory byte
stream", e);
+ }
+ }
+
+ public int getMaxCharWidth() {
+ return maxCharWidth;
+ }
+
+ public int getMaxCharHeight() {
+ return maxCharHeight;
+ }
+
+ public HashMap<Integer, CharStorageInfo> getCharIndex() {
+ if (charIndex == null) throw new IllegalStateException();
+ return charIndex;
+ }
+
+ public byte[] getDefinitionData() {
+ if (charDefsData == null) throw new IllegalStateException();
+ return charDefsData.toByteArray();
+ }
+
+
+ private static class CharDef {
+ private final int width;
+ private final int height;
+ private final byte[] data;
+
+ public CharDef(int width, int height, byte[] data) {
+ this.width = width;
+ this.height = height;
+ this.data = data;
+ }
+
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+
+ CharDef charDef = (CharDef) o;
+
+ if (height != charDef.height) return false;
+ if (width != charDef.width) return false;
+ if (!Arrays.equals(data, charDef.data)) return false;
+
+ return true;
+ }
+
+ public int hashCode() {
+ int result;
+ result = width;
+ result = 31 * result + height;
+ result = 31 * result + Arrays.hashCode(data);
+ return result;
+ }
+ }
+
+
+ public int getIndexSize() {
+ if (charIndex == null)
+ return 0;
+
+ return charIndex.size();
+ }
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharDefs.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharStorageInfo.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharStorageInfo.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharStorageInfo.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,36 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+class CharStorageInfo {
+ private final int codePoint;
+ private final int fileOffset;
+
+ public CharStorageInfo(int codePoint, int fileOffset) {
+ this.codePoint = codePoint;
+ this.fileOffset = fileOffset;
+ }
+
+ public int getCodePoint() {
+ return codePoint;
+ }
+
+ public int getFileOffset() {
+ return fileOffset;
+ }
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharStorageInfo.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,75 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+/**
+ * @author chaac
+ *
+ */
+public class CharacterRange {
+ private int start;
+ private int end;
+
+ public CharacterRange(int start, int end) {
+ this.start = start;
+ this.end = end;
+ }
+
+ public int getStart() {
+ return start;
+ }
+
+ public int getEnd() {
+ return end;
+ }
+
+ protected boolean isCombinable(CharacterRange range) {
+ if (getStart() <= range.getStart() && range.getStart() <=
getEnd())
+ return true;
+
+ if (range.getStart() <= getStart() && getStart() <=
range.getEnd())
+ return true;
+
+ return false;
+ }
+
+ public boolean isWithinRange(int value) {
+ if (value >= start && value <= end)
+ return true;
+
+ return false;
+ }
+
+ public boolean combine(CharacterRange range) {
+ int start;
+ int end;
+
+ if (! isCombinable(range))
+ return false;
+
+ start = getStart();
+ if (range.getStart() < start)
+ start = range.getStart();
+
+ end = getEnd();
+ if (range.getEnd() > end)
+ end = range.getEnd();
+
+ return true;
+ }
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/CharacterRange.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Converter.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Converter.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Converter.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,168 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Program to convert BDF fonts into PFF2 fonts for use with GRUB.
+ */
+public class Converter {
+ public static void main(String[] args) {
+ if (args.length < 1) {
+ printUsageAndExit();
+ }
+
+ String in = null;
+ String out = null;
+ List <CharacterRange> rangeList = new ArrayList<CharacterRange>();
+
+ try {
+ for (String arg : args) {
+ if (arg.startsWith("--")) {
+ String option;
+ String value;
+ int equalsPos = arg.indexOf('=');
+ if (equalsPos < 0) {
+ option = arg.substring(2);
+ value = null;
+ } else {
+ option = arg.substring(2,
equalsPos);
+ value = arg.substring(equalsPos
+ 1);
+ }
+
+ if ("in".equals(option)) {
+ if (value == null)
+ throw new
CommandLineException(option
+ + "
option requires a value.");
+ in = value;
+ } else if ("out".equals(option)) {
+ if (value == null)
+ throw new
CommandLineException(option
+ + "
option requires a value.");
+ out = value;
+ }
+ } else if (arg.startsWith("0x")) {
+ // Range specifier
+ String strRange[] = arg.split("-");
+
+ if (strRange.length > 0) {
+ boolean validRange = true;
+ int start;
+ int end;
+
+ if (strRange.length > 2) {
+ validRange = false;
+ } else if (strRange.length == 2
+ &&
!strRange[1].startsWith("0x")) {
+ validRange = false;
+ } else
+ {
+ try {
+ start =
Integer.parseInt(strRange[0]
+
.substring(2), 16);
+ end = start;
+
+ if
(strRange.length == 2) {
+ end =
Integer.parseInt(strRange[1]
+
.substring(2), 16);
+ }
+
+ CharacterRange
range = new CharacterRange(
+
start, end);
+ boolean add =
true;
+
+ // First, try
to combine range to existing ranges
+ for
(Iterator<CharacterRange> iter = rangeList.iterator(); iter.hasNext(); )
+ {
+
CharacterRange item = iter.next();
+
+ if
(range.equals(item))
+ {
+
add = false;
+
continue;
+ }
+
+ if
(item.combine(range))
+ {
+
// Start from beginning of list using combined range
+
range = item;
+
iter = rangeList.iterator();
+
add = false;
+ }
+ }
+
+ // If range
could not be combined or no matching range, add it to the list
+ if (add)
+ {
+
rangeList.add(range);
+ }
+
+ } catch
(NumberFormatException e) {
+ validRange =
false;
+ }
+
+ }
+
+ if (!validRange) {
+ throw new
CommandLineException("Invalid range `"
+ + arg +
"'.");
+ }
+ }
+ } else {
+ throw new CommandLineException("Non-option argument `" +
arg + "'.");
+ }
+ }
+ if (in == null || out == null) {
+ throw new CommandLineException("Both --in=X and --out=Y must
be specified.");
+ }
+ } catch (CommandLineException e) {
+ System.err.println("Error: " + e.getMessage());
+ System.exit(1);
+ }
+
+ try {
+ // Read BDF.
+ Font font = BDFLoader.loadFontFile(in);
+
+ // Write PFF2.
+ new PFF2Writer(out).writeFont(font, rangeList);
+ } catch (IOException e) {
+ System.err.println("I/O error converting font: " + e);
+ e.printStackTrace();
+ System.exit(1);
+ }
+ }
+
+ private static class CommandLineException extends Exception {
+ public CommandLineException(String message) {
+ super(message);
+ }
+ }
+
+ private static void printUsageAndExit() {
+ System.err.println("GNU GRUB Font Conversion Tool");
+ System.err.println();
+ System.err.println("Usage: Converter --in=IN.bdf --out=OUT.pf2");
+ System.err.println();
+ System.exit(1);
+ }
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Converter.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Font.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Font.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Font.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,123 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+import java.util.TreeMap;
+
+public class Font {
+ public static final int UNKNOWN_POINT_SIZE = -1;
+
+ private TreeMap<Integer, Glyph> glyphs;
+ private String family;
+ private boolean bold;
+ private boolean italic;
+ private int pointSize;
+ private int maxCharWidth;
+ private int maxCharHeight;
+ private int ascent;
+ private int descent;
+
+ public Font() {
+ glyphs = new TreeMap<Integer, Glyph>();
+ }
+
+ public String getFamily() {
+ return family;
+ }
+
+ public void setFamily(String family) {
+ this.family = family;
+ }
+
+ public boolean isBold() {
+ return bold;
+ }
+
+ public void setBold(boolean bold) {
+ this.bold = bold;
+ }
+
+ public boolean isItalic() {
+ return italic;
+ }
+
+ public void setItalic(boolean italic) {
+ this.italic = italic;
+ }
+
+ public int getPointSize() {
+ return pointSize;
+ }
+
+ public void setPointSize(int pointSize) {
+ this.pointSize = pointSize;
+ }
+
+ public int getMaxCharWidth() {
+ return maxCharWidth;
+ }
+
+ public void setMaxCharWidth(int maxCharWidth) {
+ this.maxCharWidth = maxCharWidth;
+ }
+
+ public int getMaxCharHeight() {
+ return maxCharHeight;
+ }
+
+ public void setMaxCharHeight(int maxCharHeight) {
+ this.maxCharHeight = maxCharHeight;
+ }
+
+ public int getAscent() {
+ return ascent;
+ }
+
+ public void setAscent(int ascent) {
+ this.ascent = ascent;
+ }
+
+ public int getDescent() {
+ return descent;
+ }
+
+ public void setDescent(int descent) {
+ this.descent = descent;
+ }
+
+ public void putGlyph(int codePoint, Glyph glyph) {
+ glyphs.put(codePoint, glyph);
+ }
+
+ public TreeMap<Integer, Glyph> getGlyphs() {
+ return glyphs;
+ }
+
+ public Glyph getGlyph(int codePoint) {
+ return glyphs.get(codePoint);
+ }
+
+ public String getStandardName() {
+ StringBuilder name = new StringBuilder(getFamily());
+ if (isBold()) name.append(" Bold");
+ if (isItalic()) name.append(" Italic");
+ name.append(' ');
+ name.append(getPointSize());
+ return name.toString();
+ }
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Font.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Glyph.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Glyph.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Glyph.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,100 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+public class Glyph {
+ private final int codePoint;
+ private final int width;
+ private final int height;
+
+ // These define the amounts to shift the character bitmap by
+ // before drawing it. See
+ // http://www.adobe.com/devnet/font/pdfs/5005.BDF_Spec.pdf
+ // and
+ // http://www.linuxbabble.com/documentation/x/bdf/
+ // for explanatory figures.
+ private final int bbox;
+ private final int bboy;
+
+ // Number of pixels to advance horizontally from this character's origin
+ // to the origin of the next character.
+ private final int deviceWidth;
+
+ // Row-major order, no padding. Rows can break within a byte.
+ // MSb is first (leftmost/uppermost) pixel.
+ private final byte[] bitmap;
+
+ public Glyph(int codePoint, int width, int height, int bbox, int bboy, int
deviceWidth) {
+ this(codePoint, width, height, bbox, bboy, deviceWidth,
+ new byte[(width * height + 7) / 8]);
+ }
+
+ public Glyph(int codePoint, int width, int height,
+ int bbox, int bboy, int deviceWidth,
+ byte[] bitmap) {
+ this.codePoint = codePoint;
+ this.width = width;
+ this.height = height;
+ this.bboy = bboy;
+ this.bbox = bbox;
+ this.deviceWidth = deviceWidth;
+ this.bitmap = bitmap;
+ }
+
+ public void setPixel(int x, int y, boolean value) {
+ if (x < 0 || y < 0 || x >= width || y >= height)
+ throw new IllegalArgumentException(
+ "Invalid pixel location (" + x + ", " + y + ") for "
+ + width + "x" + height + " glyph");
+
+ int bitIndex = y * width + x;
+ int byteIndex = bitIndex / 8;
+ int bitPos = bitIndex % 8;
+ int v = value ? 0x80 >>> bitPos : 0;
+ int mask = ~(0x80 >>> bitPos);
+ bitmap[byteIndex] = (byte) ((bitmap[byteIndex] & mask) | v);
+ }
+
+ public int getCodePoint() {
+ return codePoint;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getBbox() {
+ return bbox;
+ }
+
+ public int getBboy() {
+ return bboy;
+ }
+
+ public int getDeviceWidth() {
+ return deviceWidth;
+ }
+
+ public byte[] getBitmap() {
+ return bitmap;
+ }
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/Glyph.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,36 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+/**
+ * Section name constants for the PFF2 file format.
+ */
+public class PFF2Sections {
+ static final String FILE = "FILE";
+ static final String FONT_NAME = "NAME";
+ static final String FONT_FAMILY = "FAMI";
+ static final String FONT_WEIGHT = "WEIG";
+ static final String FONT_SLANT = "SLAN";
+ static final String FONT_POINT_SIZE = "PTSZ";
+ static final String MAX_CHAR_WIDTH = "MAXW";
+ static final String MAX_CHAR_HEIGHT = "MAXH";
+ static final String FONT_ASCENT = "ASCE";
+ static final String FONT_DESCENT = "DESC";
+ static final String CHAR_INDEX = "CHIX";
+ static final String REMAINDER_IS_DATA = "DATA";
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Sections.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java
===================================================================
--- trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java
(rev 0)
+++ trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java
2009-01-02 15:26:06 UTC (rev 1936)
@@ -0,0 +1,154 @@
+/**
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2009 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/>.
+ */
+package org.gnu.grub.fonttool;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.List;
+
+// TODO Add DEFLATE compressed blocks of characters.
+public class PFF2Writer {
+ private RandomAccessFile f;
+ private String currentSection;
+ private long currentSectionStart;
+
+ public PFF2Writer(String filename) throws FileNotFoundException {
+ this.f = new RandomAccessFile(filename, "rw");
+ this.currentSection = null;
+ this.currentSectionStart = -1;
+ }
+
+ public void writeFont(Font font, List<CharacterRange> rangeList) throws
IOException {
+ // Clear existing file.
+ f.setLength(0);
+
+ // Write file type ID header.
+ writeSection(PFF2Sections.FILE, "PFF2");
+
+ writeSection(PFF2Sections.FONT_NAME, font.getStandardName());
+ writeSection(PFF2Sections.FONT_FAMILY, font.getFamily());
+ writeSection(PFF2Sections.FONT_WEIGHT, font.isBold() ? "bold" :
"normal");
+ writeSection(PFF2Sections.FONT_SLANT, font.isItalic() ? "italic" :
"normal");
+ if (font.getPointSize() != Font.UNKNOWN_POINT_SIZE)
+ writeShortSection(PFF2Sections.FONT_POINT_SIZE,
font.getPointSize());
+
+ // Construct character definitions.
+ CharDefs charDefs = new CharDefs(font);
+ charDefs.buildDefinitions(rangeList);
+
+ // Write max character width and height metrics.
+ writeShortSection(PFF2Sections.MAX_CHAR_WIDTH,
charDefs.getMaxCharWidth());
+ writeShortSection(PFF2Sections.MAX_CHAR_HEIGHT,
charDefs.getMaxCharHeight());
+ writeShortSection(PFF2Sections.FONT_ASCENT, font.getAscent());
+ writeShortSection(PFF2Sections.FONT_DESCENT, font.getDescent());
+
+ // Write character index with pointers to the character definitions.
+ beginSection(PFF2Sections.CHAR_INDEX);
+
+ // Determine the size of the index, so we can properly refer to the
+ // character definition offset in the index. The actual number of
+ // bytes written is compared to the calculated value to ensure we
+ // are correct.
+ final int indexStart = (int) f.getFilePointer();
+ final int calculatedIndexLength =
+ charDefs.getIndexSize() * (4 + 1 + 4);
+ final int charDefStart = indexStart + calculatedIndexLength + 8;
+
+ for (CharStorageInfo storageInfo : charDefs.getCharIndex().values()) {
+ f.writeInt(storageInfo.getCodePoint());
+ f.writeByte(0); // Storage flags: bits 1..0 = 00b : uncompressed.
+ f.writeInt(charDefStart + storageInfo.getFileOffset());
+ }
+
+ final int indexEnd = (int) f.getFilePointer();
+ if (indexEnd - indexStart != calculatedIndexLength) {
+ throw new RuntimeException("Incorrect index length calculated,
calc="
+ + calculatedIndexLength
+ + " actual=" + (indexEnd - indexStart));
+ }
+ endSection(PFF2Sections.CHAR_INDEX);
+
+ f.writeBytes(PFF2Sections.REMAINDER_IS_DATA);
+ f.writeInt(-1); // Data takes up the rest of the file.
+ f.write(charDefs.getDefinitionData());
+
+ f.close();
+ }
+
+ private void beginSection(String sectionName) throws IOException {
+ verifyOkToBeginSection(sectionName);
+
+ f.writeBytes(sectionName);
+ f.writeInt(-1); // Placeholder for the section length.
+ currentSection = sectionName;
+ currentSectionStart = f.getFilePointer();
+ }
+
+ private void endSection(String sectionName) throws IOException {
+ verifyOkToEndSection(sectionName);
+
+ long sectionEnd = f.getFilePointer();
+ long sectionLength = sectionEnd - currentSectionStart;
+ f.seek(currentSectionStart - 4);
+ f.writeInt((int) sectionLength);
+ f.seek(sectionEnd);
+ currentSection = null;
+ currentSectionStart = -1;
+ }
+
+ private void verifyOkToBeginSection(String sectionName) {
+ if (sectionName.length() != 4)
+ throw new IllegalArgumentException(
+ "Section names must be 4 characters: `" + sectionName +
"'.");
+ if (currentSection != null)
+ throw new IllegalStateException(
+ "Attempt to start `" + sectionName
+ + "' section before ending the previous section `"
+ + currentSection + "'.");
+ }
+
+ private void verifyOkToEndSection(String sectionName) {
+ if (sectionName.length() != 4)
+ throw new IllegalStateException("Invalid section name '" +
sectionName
+ + "'; must be 4 characters.");
+ if (currentSection == null)
+ throw new IllegalStateException(
+ "Attempt to end section `" + sectionName
+ + "' when no section active.");
+ if (!sectionName.equals(currentSection))
+ throw new IllegalStateException(
+ "Attempt to end `" + sectionName
+ + "' section during active section `"
+ + currentSection + "'.");
+ }
+
+ private void writeSection(String sectionName, String contents) throws
IOException {
+ verifyOkToBeginSection(sectionName);
+ f.writeBytes(sectionName);
+ f.writeInt(contents.length());
+ f.writeBytes(contents);
+ }
+
+ private void writeShortSection(String sectionName, int value) throws
IOException {
+ verifyOkToBeginSection(sectionName);
+ f.writeBytes(sectionName);
+ f.writeInt(2);
+ f.writeShort(value);
+ }
+}
Property changes on:
trunk/grub2/util/fonttool/src/org/gnu/grub/fonttool/PFF2Writer.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/grub2/util/grub-mkconfig_lib.in
===================================================================
--- trunk/grub2/util/grub-mkconfig_lib.in 2008-12-28 16:20:30 UTC (rev
1935)
+++ trunk/grub2/util/grub-mkconfig_lib.in 2009-01-02 15:26:06 UTC (rev
1936)
@@ -1,5 +1,5 @@
# Helper library for grub-mkconfig
-# Copyright (C) 2007,2008 Free Software Foundation, Inc.
+# Copyright (C) 2007,2008,2009 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
@@ -154,7 +154,7 @@
# FIXME: We prefer ascii because loading complete fonts is too slow (and
# we don't yet provide the gettext magic that would make unicode useful).
for basename in ascii unicode unifont ; do
- path="${dir}/${basename}.pff"
+ path="${dir}/${basename}.pf2"
if is_path_readable_by_grub ${path} > /dev/null ; then
echo "${path}"
return 0
Modified: trunk/grub2/util/grub.d/00_header.in
===================================================================
--- trunk/grub2/util/grub.d/00_header.in 2008-12-28 16:20:30 UTC (rev
1935)
+++ trunk/grub2/util/grub.d/00_header.in 2009-01-02 15:26:06 UTC (rev
1936)
@@ -1,7 +1,7 @@
#! /bin/sh -e
# update-grub helper script.
-# Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
+# Copyright (C) 2006,2007,2008,2009 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
@@ -87,7 +87,7 @@
fi
cat << EOF
-if font `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then
+if loadfont `make_system_path_relative_to_its_root ${GRUB_FONT_PATH}` ; then
set gfxmode=${GRUB_GFXMODE}
insmod gfxterm
insmod ${video_backend}
Modified: trunk/grub2/video/i386/pc/vbe.c
===================================================================
--- trunk/grub2/video/i386/pc/vbe.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/video/i386/pc/vbe.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2005,2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2005,2006,2007,2008,2009 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
@@ -26,7 +26,6 @@
#include <grub/types.h>
#include <grub/dl.h>
#include <grub/misc.h>
-#include <grub/font.h>
#include <grub/mm.h>
#include <grub/video.h>
#include <grub/bitmap.h>
@@ -710,6 +709,16 @@
return minindex;
}
+ else if ((render_target->mode_info.mode_type
+ & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+ {
+ if (red == render_target->mode_info.fg_red
+ && green == render_target->mode_info.fg_green
+ && blue == render_target->mode_info.fg_blue)
+ return 1;
+ else
+ return 0;
+ }
else
{
grub_uint32_t value;
@@ -740,6 +749,17 @@
/* No alpha available in index color modes, just use
same value as in only RGB modes. */
return grub_video_vbe_map_rgb (red, green, blue);
+ else if ((render_target->mode_info.mode_type
+ & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+ {
+ if (red == render_target->mode_info.fg_red
+ && green == render_target->mode_info.fg_green
+ && blue == render_target->mode_info.fg_blue
+ && alpha == render_target->mode_info.fg_alpha)
+ return 1;
+ else
+ return 0;
+ }
else
{
grub_uint32_t value;
@@ -802,6 +822,24 @@
*alpha = framebuffer.palette[color].a;
return;
}
+ else if ((mode_info->mode_type
+ & GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP) != 0)
+ {
+ if (color & 1)
+ {
+ *red = mode_info->fg_red;
+ *green = mode_info->fg_green;
+ *blue = mode_info->fg_blue;
+ *alpha = mode_info->fg_alpha;
+ }
+ else
+ {
+ *red = mode_info->bg_red;
+ *green = mode_info->bg_green;
+ *blue = mode_info->bg_blue;
+ *alpha = mode_info->bg_alpha;
+ }
+ }
else
{
grub_uint32_t tmp;
@@ -925,76 +963,6 @@
return GRUB_ERR_NONE;
}
-// TODO: Remove this method and replace with bitmap based glyphs
-static grub_err_t
-grub_video_vbe_blit_glyph (struct grub_font_glyph * glyph,
- grub_video_color_t color, int x, int y)
-{
- struct grub_video_i386_vbeblit_info target;
- unsigned int width;
- unsigned int charwidth;
- unsigned int height;
- unsigned int i;
- unsigned int j;
- unsigned int x_offset = 0;
- unsigned int y_offset = 0;
-
- /* Make sure there is something to do. */
- if (x >= (int)render_target->viewport.width)
- return GRUB_ERR_NONE;
-
- if (y >= (int)render_target->viewport.height)
- return GRUB_ERR_NONE;
-
- /* Calculate glyph dimensions. */
- width = ((glyph->width + 7) / 8) * 8;
- charwidth = width;
- height = glyph->height;
-
- if (x + (int)width < 0)
- return GRUB_ERR_NONE;
-
- if (y + (int)height < 0)
- return GRUB_ERR_NONE;
-
- /* Do not allow drawing out of viewport. */
- if (x < 0)
- {
- width += x;
- x_offset = (unsigned int)-x;
- x = 0;
- }
- if (y < 0)
- {
- height += y;
- y_offset = (unsigned int)-y;
- y = 0;
- }
-
- if ((x + width) > render_target->viewport.width)
- width = render_target->viewport.width - x;
- if ((y + height) > render_target->viewport.height)
- height = render_target->viewport.height - y;
-
- /* Add viewport offset. */
- x += render_target->viewport.x;
- y += render_target->viewport.y;
-
- /* Use vbeblit_info to encapsulate rendering. */
- target.mode_info = &render_target->mode_info;
- target.data = render_target->data;
-
- /* Draw glyph. */
- for (j = 0; j < height; j++)
- for (i = 0; i < width; i++)
- if ((glyph->bitmap[((i + x_offset) / 8)
- + (j + y_offset) * (charwidth / 8)]
- & (1 << ((charwidth - (i + x_offset) - 1) % 8))))
- set_pixel (&target, x+i, y+j, color);
-
- return GRUB_ERR_NONE;
-}
-
/* NOTE: This function assumes that given coordinates are within bounds of
handled data. */
static void
@@ -1619,7 +1587,6 @@
.map_rgba = grub_video_vbe_map_rgba,
.unmap_color = grub_video_vbe_unmap_color,
.fill_rect = grub_video_vbe_fill_rect,
- .blit_glyph = grub_video_vbe_blit_glyph,
.blit_bitmap = grub_video_vbe_blit_bitmap,
.blit_render_target = grub_video_vbe_blit_render_target,
.scroll = grub_video_vbe_scroll,
Modified: trunk/grub2/video/i386/pc/vbeutil.c
===================================================================
--- trunk/grub2/video/i386/pc/vbeutil.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/video/i386/pc/vbeutil.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2009 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
@@ -52,6 +52,12 @@
+ y * source->mode_info->pitch
+ x;
break;
+
+ case 1:
+ /* For 1-bit bitmaps, addressing needs to be done at the bit level
+ and it doesn't make sense, in general, to ask for a pointer
+ to a particular pixel's data. */
+ break;
}
return ptr;
@@ -86,6 +92,17 @@
color = *(grub_uint8_t *)get_data_ptr (source, x, y);
break;
+ case 1:
+ if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+ {
+ int bit_index = y * source->mode_info->width + x;
+ grub_uint8_t *ptr = (grub_uint8_t *)source->data
+ + bit_index / 8;
+ int bit_pos = 7 - bit_index % 8;
+ color = (*ptr >> bit_pos) & 0x01;
+ }
+ break;
+
default:
break;
}
@@ -143,6 +160,17 @@
}
break;
+ case 1:
+ if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED)
+ {
+ int bit_index = y * source->mode_info->width + x;
+ grub_uint8_t *ptr = (grub_uint8_t *)source->data
+ + bit_index / 8;
+ int bit_pos = 7 - bit_index % 8;
+ *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos);
+ }
+ break;
+
default:
break;
}
Modified: trunk/grub2/video/video.c
===================================================================
--- trunk/grub2/video/video.c 2008-12-28 16:20:30 UTC (rev 1935)
+++ trunk/grub2/video/video.c 2009-01-02 15:26:06 UTC (rev 1936)
@@ -1,6 +1,6 @@
/*
* GRUB -- GRand Unified Bootloader
- * Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
+ * Copyright (C) 2006,2007,2008,2009 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
@@ -336,17 +336,6 @@
return grub_video_adapter_active->fill_rect (color, x, y, width, height);
}
-/* Blit glyph to screen using specified color. */
-grub_err_t
-grub_video_blit_glyph (struct grub_font_glyph *glyph,
- grub_video_color_t color, int x, int y)
-{
- if (! grub_video_adapter_active)
- return grub_error (GRUB_ERR_BAD_DEVICE, "No video mode activated");
-
- return grub_video_adapter_active->blit_glyph (glyph, color, x, y);
-}
-
/* Blit bitmap to screen. */
grub_err_t
grub_video_blit_bitmap (struct grub_video_bitmap *bitmap,
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [1936] 2009-01-02 Colin D Bennett <address@hidden>,
Vesa Jääskeläinen <=