]> git.proxmox.com Git - grub2.git/commitdiff
Support for 3 more combining marks types
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 7 Jan 2010 23:46:42 +0000 (00:46 +0100)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Thu, 7 Jan 2010 23:46:42 +0000 (00:46 +0100)
.bzrignore
font/font.c
include/grub/unicode.h

index 8cdc9d12d01b98be6f5d1f7eba66b195b4b15164..d313d0358e382383bd45e58c790f3d6c54ea71c4 100644 (file)
@@ -63,3 +63,4 @@ stamp-h1
 stamp-h.in
 symlist.c
 update-grub_lib
+unidata.c
index 6655a29ae2c8e4e013a6ef8832bab0ac8cf27ee2..172653c923f3c0b6246394b89c970fbee5879cdd 100644 (file)
@@ -1163,6 +1163,21 @@ grub_font_construct_glyph (grub_font_t hinted_font,
       combtype = get_comb_type (glyph_id->combining[i]);
       switch (combtype)
        {
+       case GRUB_UNICODE_COMB_OVERLAY:
+         if (height < combining_glyphs[i]->height)
+           {
+             offset_y -= (combining_glyphs[i]->height - height) / 2;
+             height = combining_glyphs[i]->height;
+           }
+         if (width < combining_glyphs[i]->width)
+           {
+             offset_x -= (combining_glyphs[i]->width - width) / 2;
+             width = combining_glyphs[i]->width;
+           }
+         if (device_width < combining_glyphs[i]->width)
+           device_width = combining_glyphs[i]->width;
+         break;
+
        case GRUB_UNICODE_STACK_ABOVE:
          {
            grub_int16_t space;
@@ -1261,40 +1276,45 @@ grub_font_construct_glyph (grub_font_t hinted_font,
   for (i = 0; i < glyph_id->ncomb; i++)
     {
       enum grub_comb_type combtype;
+      grub_int16_t space = 0;
+
       if (!combining_glyphs[i])
        continue;
       combtype = get_comb_type (glyph_id->combining[i]);
       switch (combtype)
        {
-       case GRUB_UNICODE_STACK_ABOVE:
-         {
-           grub_int16_t space;
-           space = combining_glyphs[i]->offset_y
-             - grub_font_get_xheight (combining_glyphs[i]->font);
-           if (space < 0)
-             space = 1;
+       case GRUB_UNICODE_COMB_OVERLAY:
+         grub_font_blit_glyph (glyph, combining_glyphs[i],
+                               (width - combining_glyphs[i]->width) / 2,
+                               (height - combining_glyphs[i]->height) / 2);
+         break;
 
-           curtop += combining_glyphs[i]->height + space;
-           grub_font_blit_glyph (glyph, combining_glyphs[i],
-                                 (width - combining_glyphs[i]->width) / 2,
-                                 (height + offset_y) - curtop);
-         }
+       case GRUB_UNICODE_STACK_ABOVE:
+         space = combining_glyphs[i]->offset_y
+           - grub_font_get_xheight (combining_glyphs[i]->font);
+         if (space < 0)
+           space = 1;
+
+       case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
+           
+         curtop += combining_glyphs[i]->height + space;
+         grub_font_blit_glyph (glyph, combining_glyphs[i],
+                               (width - combining_glyphs[i]->width) / 2,
+                               (height + offset_y) - curtop);
          break;
 
        case GRUB_UNICODE_STACK_BELOW:
-         {
-           grub_int16_t space;
-           space = -(combining_glyphs[i]->offset_y 
-                     + combining_glyphs[i]->height);
-           if (space < 0)
-             space = 1;
-
-           curbottom -= space;
-           grub_font_blit_glyph (glyph, combining_glyphs[i],
-                                 (width - combining_glyphs[i]->width) / 2,
-                                 (height + offset_y) - curbottom);
-           curbottom -= combining_glyphs[i]->height;
-         }
+         space = -(combining_glyphs[i]->offset_y 
+                   + combining_glyphs[i]->height);
+         if (space < 0)
+           space = 1;
+         
+       case GRUB_UNICODE_STACK_ATTACHED_BELOW:
+         curbottom -= space;
+         grub_font_blit_glyph (glyph, combining_glyphs[i],
+                               (width - combining_glyphs[i]->width) / 2,
+                               (height + offset_y) - curbottom);
+         curbottom -= combining_glyphs[i]->height;
          break;
 
        default:
@@ -1525,87 +1545,107 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical,
   
   cur_level = base_level;
   cur_override = OVERRIDE_NEUTRAL;
-  for (i = 0; i < logical_len; i++)
-    {
-      /* Variation selectors >= 17 are outside of BMP and SMP. 
-        Handle variation selectors first to avoid potentially costly lookups.
-       */
-      if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_1
-         && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_16)
-       {
-         if (!visual_len)
-           continue;
-         visual[visual_len - 1].variant
-           = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1;
-       }
-      if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_17
-         && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_256)
-       {
-         if (!visual_len)
+  {
+    unsigned last_comb_pointer = 0;
+    for (i = 0; i < logical_len; i++)
+      {
+       /* Variation selectors >= 17 are outside of BMP and SMP. 
+          Handle variation selectors first to avoid potentially costly lookups.
+       */
+       if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_1
+           && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_16)
+         {
+           if (!visual_len)
+             continue;
+           visual[visual_len - 1].variant
+             = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_1 + 1;
+         }
+       if (logical[i] >= GRUB_UNICODE_VARIATION_SELECTOR_17
+           && logical[i] <= GRUB_UNICODE_VARIATION_SELECTOR_256)
+         {
+           if (!visual_len)
+             continue;
+           visual[visual_len - 1].variant
+             = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17;
            continue;
-         visual[visual_len - 1].variant
-           = logical[i] - GRUB_UNICODE_VARIATION_SELECTOR_17 + 17;
-         continue;
-       }
-
-      type = get_bidi_type (logical[i]);
-      switch (type)
-       {
-       case GRUB_BIDI_TYPE_RLE:
-         push_stack (cur_override, (cur_level | 1) + 1);
-         break;
-       case GRUB_BIDI_TYPE_RLO:
-         push_stack (OVERRIDE_R, (cur_level | 1) + 1);
-         break;
-       case GRUB_BIDI_TYPE_LRE:
-         push_stack (cur_override, (cur_level & ~1) + 2);
-         break;
-       case GRUB_BIDI_TYPE_LRO:
-         push_stack (OVERRIDE_L, (cur_level & ~1) + 2);
-         break;
-       case GRUB_BIDI_TYPE_PDF:
-         pop_stack ();
-         break;
-       case GRUB_BIDI_TYPE_BN:
-         break;
-       default:
+         }
+       
+       type = get_bidi_type (logical[i]);
+       switch (type)
          {
-           enum grub_comb_type comb_type;
-           comb_type = get_comb_type (logical[i]);
-           if (comb_type)
-             {
-               grub_uint32_t *n;
-               if (!visual_len)
-                 break;
-               n = grub_realloc (visual[visual_len - 1].combining, 
-                                 sizeof (grub_uint32_t)
-                                 * (visual[visual_len - 1].ncomb + 1));
-               if (!n)
-                 {
-                   grub_errno = GRUB_ERR_NONE;
+         case GRUB_BIDI_TYPE_RLE:
+           push_stack (cur_override, (cur_level | 1) + 1);
+           break;
+         case GRUB_BIDI_TYPE_RLO:
+           push_stack (OVERRIDE_R, (cur_level | 1) + 1);
+           break;
+         case GRUB_BIDI_TYPE_LRE:
+           push_stack (cur_override, (cur_level & ~1) + 2);
+           break;
+         case GRUB_BIDI_TYPE_LRO:
+           push_stack (OVERRIDE_L, (cur_level & ~1) + 2);
+           break;
+         case GRUB_BIDI_TYPE_PDF:
+           pop_stack ();
+           break;
+         case GRUB_BIDI_TYPE_BN:
+           break;
+         default:
+           {
+             enum grub_comb_type comb_type;
+             comb_type = get_comb_type (logical[i]);
+             if (comb_type)
+               {
+                 grub_uint32_t *n;
+                 unsigned j;
+
+                 if (!visual_len)
                    break;
-                 }
-               visual[visual_len - 1].combining = n;
-               visual[visual_len - 1].combining[visual[visual_len - 1].ncomb]
-                 = logical[i];
-               visual[visual_len - 1].ncomb++;
-               break;
-             }
-           levels[visual_len] = cur_level;
-           if (cur_override != OVERRIDE_NEUTRAL)
-             resolved_types[visual_len] = 
-               (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L : GRUB_BIDI_TYPE_R;
-           else
-             resolved_types[visual_len] = type;
-           visual[visual_len].base = logical[i];
-           visual[visual_len].variant = 0;
-           visual[visual_len].attributes = 0;
-           visual[visual_len].ncomb = 0;
-           visual[visual_len].combining = NULL;
-           visual_len++;
+                 if (comb_type == GRUB_UNICODE_COMB_MC
+                     || comb_type == GRUB_UNICODE_COMB_ME
+                     || comb_type == GRUB_UNICODE_COMB_MN)
+                   last_comb_pointer = visual[visual_len - 1].ncomb;
+                 n = grub_realloc (visual[visual_len - 1].combining, 
+                                   sizeof (grub_uint32_t)
+                                   * (visual[visual_len - 1].ncomb + 1));
+                 if (!n)
+                   {
+                     grub_errno = GRUB_ERR_NONE;
+                     break;
+                   }
+
+                 for (j = last_comb_pointer;
+                      j < visual[visual_len - 1].ncomb; j++)
+                   if (get_comb_type (visual[visual_len - 1].combining[j])
+                       > comb_type)
+                     break;
+                 grub_memmove (visual[visual_len - 1].combining + j + 1,
+                               visual[visual_len - 1].combining + j,
+                               (visual[visual_len - 1].ncomb - j)
+                               * sizeof (visual[visual_len - 1].combining[0]));
+                 visual[visual_len - 1].combining = n;
+                 visual[visual_len - 1].combining[j] = logical[i];
+                 visual[visual_len - 1].ncomb++;
+                 break;
+               }
+             last_comb_pointer = 0;
+             levels[visual_len] = cur_level;
+             if (cur_override != OVERRIDE_NEUTRAL)
+               resolved_types[visual_len] = 
+                 (cur_override == OVERRIDE_L) ? GRUB_BIDI_TYPE_L
+                 : GRUB_BIDI_TYPE_R;
+             else
+               resolved_types[visual_len] = type;
+             visual[visual_len].base = logical[i];
+             visual[visual_len].variant = 0;
+             visual[visual_len].attributes = 0;
+             visual[visual_len].ncomb = 0;
+             visual[visual_len].combining = NULL;
+             visual_len++;
+           }
          }
-       }
-    }
+      }
+  }
 
   for (run_start = 0; run_start < visual_len; run_start = run_end)
     {
@@ -1781,6 +1821,7 @@ grub_err_bidi_logical_to_visual (grub_uint32_t *logical,
        if (levels[i] < min_odd_level && (levels[i] & 1))
          min_odd_level = levels[i];
       }
+    /* FIXME: can be optimized.  */
     for (j = max_level; j >= min_odd_level; j--)
       {
        unsigned in = 0;
index 20c7c41677f279bbfd959f575366a86cad32ad51..17932a4b1bfefdbcb741941799f4b153878213c0 100644 (file)
@@ -55,6 +55,9 @@ enum grub_bidi_type
 
 enum grub_comb_type
   {
+    GRUB_UNICODE_COMB_OVERLAY = 1,
+    GRUB_UNICODE_STACK_ATTACHED_BELOW = 202,
+    GRUB_UNICODE_STACK_ATTACHED_ABOVE = 214,
     GRUB_UNICODE_STACK_BELOW = 220,
     GRUB_UNICODE_STACK_ABOVE = 230,
     /* If combining nature is indicated only by class and