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.

--- 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;
--- 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);
 
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to