]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Index of BMP for faster font lookup
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 29 Nov 2009 13:26:07 +0000 (14:26 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Sun, 29 Nov 2009 13:26:07 +0000 (14:26 +0100)
font/font.c

index a81291916310ef997a3bd3931ff95decd98c56fc..82e0d88e74a459d8387c31593058d62655b64338 100644 (file)
@@ -58,6 +58,7 @@ struct grub_font
   short leading;
   grub_uint32_t num_chars;
   struct char_index_entry *char_index;
+  grub_uint16_t *bmp_idx;
 };
 
 /* Definition of font registry.  */
@@ -180,6 +181,7 @@ font_init (grub_font_t font)
   font->descent = 0;
   font->num_chars = 0;
   font->char_index = 0;
+  font->bmp_idx = 0;
 }
 
 /* Open the next section in the file.
@@ -273,6 +275,14 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
                                   * sizeof (struct char_index_entry));
   if (! font->char_index)
     return 1;
+  font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t));
+  if (! font->bmp_idx)
+    {
+      grub_free (font->char_index);
+      return 1;
+    }
+  grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t));
+
 
 #if FONT_DEBUG >= 2
   grub_printf("num_chars=%d)\n", font->num_chars);
@@ -299,6 +309,9 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct
           return 1;
         }
 
+      if (entry->code < 0x10000)
+       font->bmp_idx[entry->code] = i;
+
       last_code = entry->code;
 
       /* Read storage flags byte.  */
@@ -594,7 +607,7 @@ read_be_int16 (grub_file_t file, grub_int16_t * value)
 
 /* Return a pointer to the character index entry for the glyph corresponding to
    the codepoint CODE in the font FONT.  If not found, return zero.  */
-static struct char_index_entry *
+static inline struct char_index_entry *
 find_glyph (const grub_font_t font, grub_uint32_t code)
 {
   struct char_index_entry *table;
@@ -602,8 +615,17 @@ find_glyph (const grub_font_t font, grub_uint32_t code)
   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;
+
+  /* Use BMP index if possible.  */
+  if (code < 0x10000)
+    {
+      if (font->bmp_idx[code] == 0xffff)
+       return 0;
+      return &table[font->bmp_idx[code]];
+    }
+
+  /* Do a binary search in `char_index', which is ordered by code point.  */
   lo = 0;
   hi = font->num_chars - 1;