From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1NYHyg-0005CC-42 for mharc-grub-devel@gnu.org; Fri, 22 Jan 2010 06:47:02 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NYHye-0005Bs-0J for grub-devel@gnu.org; Fri, 22 Jan 2010 06:47:00 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NYHyd-0005Bf-7D for grub-devel@gnu.org; Fri, 22 Jan 2010 06:46:59 -0500 Received: from [199.232.76.173] (port=39308 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NYHyd-0005Bc-1B for grub-devel@gnu.org; Fri, 22 Jan 2010 06:46:59 -0500 Received: from fg-out-1718.google.com ([72.14.220.158]:34192) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NYHyc-0002BT-9b for grub-devel@gnu.org; Fri, 22 Jan 2010 06:46:58 -0500 Received: by fg-out-1718.google.com with SMTP id 22so1007061fge.12 for ; Fri, 22 Jan 2010 03:46:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:subject:from:to:in-reply-to :references:content-type:date:message-id:mime-version:x-mailer; bh=ylcZkY06oCjp/p4Z1u4qkBk8/MKVGSDRw55H/BCysmk=; b=Mq5F7L/2zxHTu8YY4s0GpU2fvSwFY30l703+9UO3pBk2r1U9j/CCzJVr864XyG8fEp etGFAWM9YZWYeGueUabPA6LQRV0t08aimnY4V/B2LD0QaeyJzkdm4+rcCbrDqisdLsV1 dc5Qg9fGRCmRxPq4GstdsU4PJTLAtzEBED4To= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=subject:from:to:in-reply-to:references:content-type:date:message-id :mime-version:x-mailer; b=kyoa82+uDVHQDM4E0KrE003hjj2eOoNi56fz/lGwBZJG8oseur/hPu9av7lg5VX1xU kPZsha0rLzJbHKEgv/txHYOoCzY8+juQEP2bEM7K57douxwBfOyk/aBEbNw3HYqhT588 boV8CWvhbHz5wKVG/UVGiAKQHiFGwiQW1hvIQ= Received: by 10.87.76.30 with SMTP id d30mr4606168fgl.6.1264160817138; Fri, 22 Jan 2010 03:46:57 -0800 (PST) Received: from ?78.140.16.69? ([78.140.16.69]) by mx.google.com with ESMTPS id l12sm7140713fgb.10.2010.01.22.03.46.55 (version=SSLv3 cipher=RC4-MD5); Fri, 22 Jan 2010 03:46:56 -0800 (PST) From: Evgeny Kolesnikov To: The development of GNU GRUB In-Reply-To: <4B585690.8090602@gmail.com> References: <4B585690.8090602@gmail.com> Content-Type: multipart/mixed; boundary="=-/cSWPN2smOx7JiL9F0sT" Date: Fri, 22 Jan 2010 17:46:55 +0600 Message-ID: <1264160815.29881.61.camel@EK> Mime-Version: 1.0 X-Mailer: Evolution 2.28.1 X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: Antialiased fonts patch. X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Jan 2010 11:47:00 -0000 --=-/cSWPN2smOx7JiL9F0sT Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit 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. --=-/cSWPN2smOx7JiL9F0sT Content-Disposition: attachment; filename="font.c.diff" Content-Type: text/x-patch; name="font.c.diff"; charset="UTF-8" Content-Transfer-Encoding: 7bit --- 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; --=-/cSWPN2smOx7JiL9F0sT Content-Disposition: attachment; filename="grub-mkfont.c.diff" Content-Type: text/x-patch; name="grub-mkfont.c.diff"; charset="UTF-8" Content-Transfer-Encoding: 7bit --- 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); --=-/cSWPN2smOx7JiL9F0sT--