From: Evgeny Kolesnikov <evgenyz@gmail.com>
To: The development of GNU GRUB <grub-devel@gnu.org>
Subject: Antialiased fonts patch.
Date: Fri, 22 Jan 2010 17:46:55 +0600 [thread overview]
Message-ID: <1264160815.29881.61.camel@EK> (raw)
In-Reply-To: <4B585690.8090602@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1104 bytes --]
Here is the path for anti-aliased fonts.
Everything my path does is:
1) Enriches grub-mkfont with ability to write (and debug with -vv)
pff3 (as I call it now) font format. There are 2 differences between
pff2 and pff3 formats: FILE magic (PFF2 becomes PFF3) and DATA block
entires size multiples by 8 (1bit -> 8bit). In other words PFF3 stores
8-bit alpha channel instead of 1-bit.
And grub-mkfont will still be able to generate pff2, of course.
2) Adds pff3 format parsing and drawing ability to font.c.
And of course pff2 still there; actually as you can understand 95% of
code is reused because of such a little differences in formats.
Drawing itself implemented pretty straightforward: on each glyph
drawing A channel (from glyph) and foreground color are converted to
RGBA buffer and then blended in RGBA_8888 mode.
As far as I understand writing custom blitter for now will not worth it
in terms of efficiency.
When I test it I was unable to see performance difference between 1-bit
fonts and my version. They both flickers a little.
Files affected: /font/font.c and /util/grub-mkfont.c.
[-- Attachment #2: font.c.diff --]
[-- Type: text/x-patch, Size: 5512 bytes --]
--- font.c 2010-01-22 16:52:54.980914210 +0600
+++ font.bak.c 2010-01-22 00:38:28.000000000 +0600
@@ -51,7 +51,6 @@
struct grub_font
{
- grub_uint8_t version;
char *name;
grub_file_t file;
char *family;
@@ -65,7 +64,6 @@
grub_uint32_t num_chars;
struct char_index_entry *char_index;
grub_uint16_t *bmp_idx;
- grub_uint8_t *glyph_bitmap_buffer;
};
/* Definition of font registry. */
@@ -93,7 +91,6 @@
/* Font file format constants. */
static const char pff2_magic[4] = { 'P', 'F', 'F', '2' };
-static const char pff3_magic[4] = { 'P', 'F', 'F', '3' };
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' };
@@ -216,8 +213,6 @@
static void
font_init (grub_font_t font)
{
- font->version = 2;
-
font->name = 0;
font->file = 0;
font->family = 0;
@@ -445,7 +440,6 @@
struct font_file_section section;
char magic[4];
grub_font_t font = 0;
- grub_uint8_t pff3 = 0;
#if FONT_DEBUG >= 1
grub_printf("add_font(%s)\n", filename);
@@ -495,15 +489,12 @@
grub_printf("read magic ok\n");
#endif
- if (grub_memcmp (magic, pff2_magic, 4) != 0 && grub_memcmp (magic, pff3_magic, 4) != 0)
+ 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;
}
- else
- if (grub_memcmp (magic, pff3_magic, 4) == 0)
- pff3 = 1;
#if FONT_DEBUG >= 3
grub_printf("compare magic ok\n");
@@ -517,9 +508,6 @@
font_init (font);
font->file = file;
- if (pff3 != 0)
- font->version = 3;
-
#if FONT_DEBUG >= 3
grub_printf("allocate font ok; loading font info\n");
#endif
@@ -621,9 +609,6 @@
font->max_char_width, font->max_char_height,
font->num_chars);
#endif
-
- /* Font loaded. Create glyph to bitmap conversion buffer */
- font->glyph_bitmap_buffer = grub_malloc (font->max_char_width * font->max_char_height * 4);
if (font->max_char_width == 0
|| font->max_char_height == 0
@@ -752,10 +737,7 @@
return 0;
}
- if (font->version == 3)
- len = width * height;
- else
- len = (width * height + 7) / 8;
+ len = (width * height + 7) / 8;
glyph = grub_malloc (sizeof (struct grub_font_glyph) + len);
if (! glyph)
{
@@ -806,7 +788,6 @@
grub_free (font->name);
grub_free (font->family);
grub_free (font->char_index);
- grub_free (font->glyph_bitmap_buffer);
grub_free (font);
}
}
@@ -1079,59 +1060,29 @@
glyph_bitmap.mode_info.width = glyph->width;
glyph_bitmap.mode_info.height = glyph->height;
-
- if (glyph->font->version == 3)
- {
- glyph_bitmap.mode_info.mode_type =
- (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
- | GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_ALPHA;
- glyph_bitmap.mode_info.blit_format = GRUB_VIDEO_BLIT_FORMAT_RGBA_8888;
- glyph_bitmap.mode_info.bpp = 32;
- glyph_bitmap.mode_info.bytes_per_pixel = 4;
- glyph_bitmap.mode_info.pitch = glyph->width * 4;
- }
- else
- {
- 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;
- }
-
+ 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);
-
- if (glyph->font->version == 3)
- {
- int i;
- grub_uint8_t *pixel = glyph->font->glyph_bitmap_buffer;
- for (i = 0; i < glyph->width * glyph->height; i++)
- {
- *pixel = glyph_bitmap.mode_info.fg_red; pixel++;
- *pixel = glyph_bitmap.mode_info.fg_green; pixel++;
- *pixel = glyph_bitmap.mode_info.fg_blue; pixel++;
- *pixel = glyph->bitmap[i]; pixel++;
- }
- glyph_bitmap.data = glyph->font->glyph_bitmap_buffer;
- }
- else
- glyph_bitmap.data = glyph->bitmap;
+ glyph_bitmap.data = glyph->bitmap;
int bitmap_left = left_x + glyph->offset_x;
int bitmap_bottom = baseline_y - glyph->offset_y;
[-- Attachment #3: grub-mkfont.c.diff --]
[-- Type: text/x-patch, Size: 8437 bytes --]
--- grub-mkfont.c 2010-01-22 15:01:47.664910782 +0600
+++ grub-mkfont.bak.c 2010-01-22 00:38:28.000000000 +0600
@@ -51,7 +51,7 @@
enum file_formats
{
- PFN,
+ PF2,
ASCII_BITMAPS
};
@@ -59,7 +59,6 @@
#define GRUB_FONT_FLAG_NOBITMAP 2
#define GRUB_FONT_FLAG_NOHINTING 4
#define GRUB_FONT_FLAG_FORCEHINT 8
-#define GRUB_FONT_FLAG_8BIT_AA 4096
struct grub_font_info
{
@@ -95,7 +94,6 @@
{"version", no_argument, 0, 'V'},
{"verbose", no_argument, 0, 'v'},
{"ascii-bitmaps", no_argument, 0, 0x102},
- {"pff3", no_argument, 0, '3'},
{0, 0, 0, 0}
};
@@ -111,7 +109,6 @@
Usage: %s [OPTIONS] FONT_FILES\n\
\nOptions:\n\
-o, --output=FILE_NAME set output file name\n\
- -3, --pff3 save in pff3 format (antialiased)\n\
--ascii-bitmaps save only the ASCII bitmaps\n\
-i, --index=N set face index\n\
-r, --range=A-B[,C-D] set font range\n\
@@ -157,12 +154,7 @@
grub_uint8_t *data;
int mask, i, j, bitmap_size;
FT_GlyphSlot glyph;
- int flag = FT_LOAD_RENDER;
-
- if (font_info->flags & GRUB_FONT_FLAG_8BIT_AA)
- flag |= FT_LOAD_TARGET_NORMAL;
- else
- flag |= FT_LOAD_MONOCHROME;
+ int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME;
if (font_info->flags & GRUB_FONT_FLAG_NOBITMAP)
flag |= FT_LOAD_NO_BITMAP;
@@ -193,11 +185,7 @@
width = glyph->bitmap.width;
height = glyph->bitmap.rows;
- if (font_info->flags & GRUB_FONT_FLAG_8BIT_AA)
- bitmap_size = width * height;
- else
- bitmap_size = ((width * height + 7) / 8);
-
+ bitmap_size = ((width * height + 7) / 8);
glyph_info = xmalloc (sizeof (struct grub_glyph_info) + bitmap_size);
glyph_info->bitmap_size = bitmap_size;
@@ -223,18 +211,13 @@
if (glyph_info->y_ofs + height > font_info->max_y)
font_info->max_y = glyph_info->y_ofs + height;
- if (font_info->flags & GRUB_FONT_FLAG_8BIT_AA)
- memcpy (glyph_info->bitmap, glyph->bitmap.buffer, bitmap_size);
- else
- {
- mask = 0;
- data = &glyph_info->bitmap[0] - 1;
- for (j = 0; j < height; j++)
- for (i = 0; i < width; i++)
- add_pixel (&data, &mask,
- glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] &
- (1 << (7 - (i & 7))));
- }
+ mask = 0;
+ data = &glyph_info->bitmap[0] - 1;
+ for (j = 0; j < height; j++)
+ for (i = 0; i < width; i++)
+ add_pixel (&data, &mask,
+ glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] &
+ (1 << (7 - (i & 7))));
}
void
@@ -246,17 +229,18 @@
grub_uint32_t j;
for (i = 0; i < font_info->num_range; i++)
- for (j = font_info->ranges[i * 2]; j <= font_info->ranges[i * 2 + 1]; j++)
- add_char (font_info, face, j);
+ for (j = font_info->ranges[i * 2]; j <= font_info->ranges[i * 2 + 1];
+ j++)
+ add_char (font_info, face, j);
}
else
{
grub_uint32_t char_code, glyph_index;
for (char_code = FT_Get_First_Char (face, &glyph_index);
- glyph_index;
- char_code = FT_Get_Next_Char (face, char_code, &glyph_index))
- add_char (font_info, face, char_code);
+ glyph_index;
+ char_code = FT_Get_Next_Char (face, char_code, &glyph_index))
+ add_char (font_info, face, char_code);
}
}
@@ -308,74 +292,56 @@
xmax = glyph->x_ofs + glyph->width;
if (xmax < glyph->device_width)
- xmax = glyph->device_width;
+ xmax = glyph->device_width;
xmin = glyph->x_ofs;
if (xmin > 0)
- xmin = 0;
+ xmin = 0;
ymax = glyph->y_ofs + glyph->height;
if (ymax < font_info->asce)
- ymax = font_info->asce;
+ ymax = font_info->asce;
ymin = glyph->y_ofs;
if (ymin > - font_info->desc)
- ymin = - font_info->desc;
+ ymin = - font_info->desc;
bitmap = glyph->bitmap;
mask = 0x80;
for (y = ymax - 1; y >= ymin; y--)
- {
- int line_pos;
+ {
+ int line_pos;
- line_pos = 0;
- for (x = xmin; x < xmax; x++)
- {
- if ((x >= glyph->x_ofs) &&
- (x < glyph->x_ofs + glyph->width) &&
- (y >= glyph->y_ofs) &&
- (y < glyph->y_ofs + glyph->height))
- {
- if (font_info->flags & GRUB_FONT_FLAG_8BIT_AA)
- {
- if (*bitmap > 127)
- line[line_pos++] = '#';
- else if (*bitmap > 64)
- line[line_pos++] = '8';
- else if (*bitmap > 8)
- line[line_pos++] = 'o';
- else if (*bitmap > 1)
- line[line_pos++] = '-';
- else
- line[line_pos++] = '_';
-
- bitmap++;
- }
- else
- {
- line[line_pos++] = (*bitmap & mask) ? '#' : '_';
- mask >>= 1;
- if (mask == 0)
- {
- mask = 0x80;
- bitmap++;
- }
- }
- }
- else if ((x >= 0) &&
- (x < glyph->device_width) &&
- (y >= - font_info->desc) &&
- (y < font_info->asce))
- {
- line[line_pos++] = ((x == 0) || (y == 0)) ? '+' : '.';
- }
- else
- line[line_pos++] = '*';
- }
- line[line_pos] = 0;
- printf ("%s\n", line);
- }
- }
+ line_pos = 0;
+ for (x = xmin; x < xmax; x++)
+ {
+ if ((x >= glyph->x_ofs) &&
+ (x < glyph->x_ofs + glyph->width) &&
+ (y >= glyph->y_ofs) &&
+ (y < glyph->y_ofs + glyph->height))
+ {
+ line[line_pos++] = (*bitmap & mask) ? '#' : '_';
+ mask >>= 1;
+ if (mask == 0)
+ {
+ mask = 0x80;
+ bitmap++;
+ }
+ }
+ else if ((x >= 0) &&
+ (x < glyph->device_width) &&
+ (y >= - font_info->desc) &&
+ (y < font_info->asce))
+ {
+ line[line_pos++] = ((x == 0) || (y == 0)) ? '+' : '.';
+ }
+ else
+ line[line_pos++] = '*';
+ }
+ line[line_pos] = 0;
+ printf ("%s\n", line);
+ }
+ }
}
void
@@ -396,22 +362,22 @@
if (glyph->width != 8 || glyph->height != 16)
{
/* printf ("Width or height from glyph U+%04x not supported, skipping.\n", glyph->char_code); */
- correct_size = 0;
+ correct_size = 0;
}
int row;
for (row = 0; row < glyph->height; row++)
{
- if (correct_size)
- fwrite (&glyph->bitmap[row], sizeof(glyph->bitmap[row]), 1, file);
- else
- fwrite (&correct_size, 1, 1, file);
+ if (correct_size)
+ fwrite (&glyph->bitmap[row], sizeof(glyph->bitmap[row]), 1, file);
+ else
+ fwrite (&correct_size, 1, 1, file);
}
}
- fclose (file);
+ fclose (file);
}
void
-write_font_pfN (struct grub_font_info *font_info, char *output_file)
+write_font_pf2 (struct grub_font_info *font_info, char *output_file)
{
FILE *file;
grub_uint32_t leng, data;
@@ -428,11 +394,7 @@
leng = grub_cpu_to_be32 (4);
grub_util_write_image ("FILE", 4, file);
grub_util_write_image ((char *) &leng, 4, file);
- if (font_info->flags & GRUB_FONT_FLAG_8BIT_AA)
- grub_util_write_image ("PFF3", 4, file);
- else
- grub_util_write_image ("PFF2", 4, file);
-
+ grub_util_write_image ("PFF2", 4, file);
offset += 12;
if (! font_info->name)
@@ -562,7 +524,7 @@
int font_index = 0;
int font_size = 0;
char *output_file = NULL;
- enum file_formats file_format = PFN;
+ enum file_formats file_format = PF2;
memset (&font_info, 0, sizeof (font_info));
@@ -573,7 +535,7 @@
/* Check for options. */
while (1)
{
- int c = getopt_long (argc, argv, "bao:n:i:s:d:r:hVv3", options, 0);
+ int c = getopt_long (argc, argv, "bao:n:i:s:d:r:hVv", options, 0);
if (c == -1)
break;
@@ -670,10 +632,6 @@
case 0x102:
file_format = ASCII_BITMAPS;
break;
-
- case '3':
- font_info.flags |= GRUB_FONT_FLAG_8BIT_AA;
- break;
default:
usage (1);
@@ -739,8 +697,8 @@
FT_Done_FreeType (ft_lib);
- if (file_format == PFN)
- write_font_pfN (&font_info, output_file);
+ if (file_format == PF2)
+ write_font_pf2 (&font_info, output_file);
else if (file_format == ASCII_BITMAPS)
write_font_ascii_bitmap (&font_info, output_file);
next prev parent reply other threads:[~2010-01-22 11:47 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-21 13:19 grub-mkfont and DejaVu font problems Evgeny K
2010-01-21 13:28 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-22 11:46 ` Evgeny Kolesnikov [this message]
2010-01-22 12:53 ` Antialiased fonts patch BVK Chaitanya
2010-01-22 13:22 ` Evgeny Kolesnikov
2010-01-26 9:11 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-26 10:04 ` Evgeny Kolesnikov
2010-01-26 11:59 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-01-26 19:44 ` Carles Pina i Estany
2010-02-11 2:58 ` Vladimir 'φ-coder/phcoder' Serbinenko
[not found] ` <1265957146.2292.11.camel@EK>
2010-02-12 9:50 ` Vladimir 'φ-coder/phcoder' Serbinenko
2010-02-11 13:30 ` Michal Suchanek
2010-02-12 6:21 ` richardvoigt
2010-02-12 6:48 ` Evgeny Kolesnikov
2010-02-12 7:08 ` Evgeny Kolesnikov
2010-02-12 7:20 ` Bruce Dubbs
2010-02-12 7:52 ` Evgeny Kolesnikov
2010-02-12 9:15 ` Michal Suchanek
2010-02-12 9:55 ` Vladimir 'φ-coder/phcoder' Serbinenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1264160815.29881.61.camel@EK \
--to=evgenyz@gmail.com \
--cc=grub-devel@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.