2009-06-05 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.
This commit is contained in:
parent
408305be7a
commit
c8048e32d6
2 changed files with 42 additions and 7 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2009-06-05 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-06-05 Michael Scherer <misc@mandriva.org>
|
||||
|
||||
* fs/hfsplus.c (grub_hfsplus_mount): Determine if the filesystem
|
||||
|
|
38
font/font.c
38
font/font.c
|
@ -249,6 +249,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
|||
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 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
|||
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 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
|
|||
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 @@ read_be_int16 (grub_file_t file, grub_int16_t * value)
|
|||
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;
|
||||
struct char_index_entry *table;
|
||||
grub_size_t lo;
|
||||
grub_size_t hi;
|
||||
grub_size_t mid;
|
||||
|
||||
/* Do a linear search. */
|
||||
for (i = 0; i < len; i++)
|
||||
/* 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;
|
||||
|
|
Loading…
Reference in a new issue