From: Colin D Bennett <colin@gibibit.com>
To: grub-devel@gnu.org
Subject: [PATCH] Faster text rendering by optimizing font glyph lookup
Date: Sun, 8 Feb 2009 13:49:53 -0800 [thread overview]
Message-ID: <20090208134953.00aef328@gibibit.com> (raw)
[-- Attachment #1.1: Type: text/plain, Size: 860 bytes --]
This patch greatly—*tremendously*, even, if higher-numbered Unicode
characters are used—speeds up retrieving a glyph for a particular
Unicode character. This makes text rendering in general much faster.
My text benchmark shows the new text rendering speed is somewhere from
2.6x to 31x of the previous speed. Basically, PFF2 font files are now
required to have the character index ordered in ascending order of code
point.
Fonts created by 'grub-mkfont' already satisfy this requirement. Fonts
created by my old Java 'fonttool' do not, and cannot be used any longer.
The font loader verifies that fonts fulfill the character ordering
requirement, refusing to load invalid fonts, but the primary change is
in the 'find_glyph()' function, which now uses a binary search rather
than a linear search to find the glyph.
Regards,
Colin
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: font-optimization.patch --]
[-- Type: text/x-patch, Size: 2668 bytes --]
=== modified file 'ChangeLog'
--- ChangeLog 2009-02-04 10:52:25 +0000
+++ ChangeLog 2009-02-08 21:46:42 +0000
@@ -1,3 +1,14 @@
+2009-02-08 Colin D Bennett <colin@gibibit.com>
+
+ Optimized font character lookup using binary search instead of linear
+ search. Fonts now are required to have the character index ordered by
+ code point.
+
+ * font/font.c (load_font_index): Verify that fonts have ordered
+ character indices.
+ (find_glyph): Use binary search instead of linear search to find a
+ character in a font.
+
2009-02-04 Felix Zielcke <fzielcke@z-51.de>
util/getroot.c (grub_util_get_grub_dev): Add support for /dev/mdNpN and
=== modified file 'font/font.c'
--- font/font.c 2009-01-19 17:09:53 +0000
+++ font/font.c 2009-02-08 19:50:58 +0000
@@ -249,6 +249,7 @@
grub_font *font)
{
unsigned i;
+ grub_uint32_t last_code;
#if FONT_DEBUG >= 2
grub_printf("load_font_index(sect_length=%d)\n", sect_length);
@@ -277,6 +278,8 @@
grub_printf("num_chars=%d)\n", font->num_chars);
#endif
+ last_code = 0;
+
/* Load the character index data from the file. */
for (i = 0; i < font->num_chars; i++)
{
@@ -287,6 +290,17 @@
return 1;
entry->code = grub_be_to_cpu32 (entry->code);
+ /* Verify that characters are in ascending order. */
+ if (i != 0 && entry->code <= last_code)
+ {
+ grub_error (GRUB_ERR_BAD_FONT,
+ "Font characters not in ascending order: %u <= %u",
+ entry->code, last_code);
+ return 1;
+ }
+
+ last_code = entry->code;
+
/* Read storage flags byte. */
if (grub_file_read (file, (char *) &entry->storage_flags, 1) != 1)
return 1;
@@ -583,15 +597,25 @@
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++)
+ struct char_index_entry *table;
+ grub_size_t lo;
+ grub_size_t hi;
+ grub_size_t mid;
+
+ /* Do a binary search in `char_index', which is ordered by code point. */
+ table = font->char_index;
+ lo = 0;
+ hi = font->num_chars - 1;
+
+ while (lo <= hi)
{
- if (table[i].code == code)
- return &table[i];
+ mid = lo + (hi - lo) / 2;
+ if (code < table[mid].code)
+ hi = mid - 1;
+ else if (code > table[mid].code)
+ lo = mid + 1;
+ else
+ return &table[mid];
}
return 0;
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
next reply other threads:[~2009-02-08 21:50 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-08 21:49 Colin D Bennett [this message]
2009-02-09 14:11 ` [PATCH] Faster text rendering by optimizing font glyph lookup Robert Millan
2009-02-09 16:24 ` Colin D Bennett
2009-06-11 10:28 ` Felix Zielcke
2009-06-11 21:31 ` Vladimir 'phcoder' Serbinenko
2009-07-24 21:17 ` Felix Zielcke
2009-07-25 16:04 ` Robert Millan
2009-07-25 16:22 ` Felix Zielcke
2009-07-26 8:38 ` Michal Suchanek
2009-07-26 8:56 ` Felix Zielcke
2009-07-26 9:13 ` Felix Zielcke
2009-04-10 23:39 ` phcoder
2009-04-13 13:57 ` Robert Millan
2009-04-13 14:17 ` Felix Zielcke
2009-05-31 9:41 ` Vladimir '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=20090208134953.00aef328@gibibit.com \
--to=colin@gibibit.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.