merge mainline into bidi
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 9 Apr 2010 17:40:31 +0000 (19:40 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Fri, 9 Apr 2010 17:40:31 +0000 (19:40 +0200)
1  2 
font/font.c
util/grub-script-check.c

diff --cc font/font.c
@@@ -93,25 -91,24 +93,24 @@@ struct font_file_sectio
  };
  
  /* Replace unknown glyphs with a rounded question mark.  */
- static grub_uint8_t unknown_glyph_bitmap[] =
- {
+ static grub_uint8_t unknown_glyph_bitmap[] = {
 -  /*                               76543210 */
 +  /*       76543210 */
-   0x7C, /*  ooooo   */
-   0x82, /* o     o  */
-   0xBA, /* o ooo o  */
-   0xAA, /* o o o o  */
-   0xAA, /* o o o o  */
-   0x8A, /* o   o o  */
-   0x9A, /* o  oo o  */
-   0x92, /* o  o  o  */
-   0x92, /* o  o  o  */
-   0x92, /* o  o  o  */
-   0x92, /* o  o  o  */
-   0x82, /* o     o  */
-   0x92, /* o  o  o  */
-   0x82, /* o     o  */
-   0x7C, /*  ooooo   */
-   0x00  /*          */
+   0x7C,                               /*  ooooo   */
+   0x82,                               /* o     o  */
+   0xBA,                               /* o ooo o  */
+   0xAA,                               /* o o o o  */
+   0xAA,                               /* o o o o  */
+   0x8A,                               /* o   o o  */
+   0x9A,                               /* o  oo o  */
+   0x92,                               /* o  o  o  */
+   0x92,                               /* o  o  o  */
+   0x92,                               /* o  o  o  */
+   0x92,                               /* o  o  o  */
+   0x82,                               /* o     o  */
+   0x92,                               /* o  o  o  */
+   0x82,                               /* o     o  */
+   0x7C,                               /*  ooooo   */
+   0x00                                /*          */
  };
  
  /* The "unknown glyph" glyph, used as a last resort.  */
@@@ -142,19 -139,18 +141,19 @@@ ascii_glyph_lookup (grub_uint32_t code
      {
        int current;
        for (current = 0; current < 0x80; current++)
-         {
-         ascii_font_glyph[current] = grub_malloc(sizeof(struct grub_font_glyph)
-                               + ASCII_BITMAP_SIZE);
-           ascii_font_glyph[current]->width = 8;
-           ascii_font_glyph[current]->height = 16; 
-           ascii_font_glyph[current]->offset_x = 0; 
-           ascii_font_glyph[current]->offset_y = -2; 
+       {
+         ascii_font_glyph[current] =
+           grub_malloc (sizeof (struct grub_font_glyph) + ASCII_BITMAP_SIZE);
+         ascii_font_glyph[current]->width = 8;
+         ascii_font_glyph[current]->height = 16;
+         ascii_font_glyph[current]->offset_x = 0;
+         ascii_font_glyph[current]->offset_y = -2;
          ascii_font_glyph[current]->device_width = 8;
 +        ascii_font_glyph[current]->font = NULL;
  
          grub_memcpy (ascii_font_glyph[current]->bitmap,
 -                     &ascii_bitmaps[(0x7f - current) * ASCII_BITMAP_SIZE],
 +                     &ascii_bitmaps[current * ASCII_BITMAP_SIZE],
                       ASCII_BITMAP_SIZE);
        }
  
@@@ -1017,464 -1030,25 +1019,469 @@@ grub_font_get_glyph_with_fallback (grub
  
        glyph = grub_font_get_glyph_internal (curfont, code);
        if (glyph)
-         {
-           int d;
-           d = get_font_diversity (curfont, font);
-           if (d < best_diversity)
-             {
-               best_diversity = d;
-               best_glyph = glyph;
-             }
-         }
+       {
+         int d;
+         d = get_font_diversity (curfont, font);
+         if (d < best_diversity)
+           {
+             best_diversity = d;
+             best_glyph = glyph;
+           }
+       }
      }
  
 -  if (best_glyph)
 -    return best_glyph;
 +  return best_glyph;
 +}
 +
 +static struct grub_font_glyph *
 +grub_font_dup_glyph (struct grub_font_glyph *glyph)
 +{
 +  static struct grub_font_glyph *ret;
 +  ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8);
 +  if (!ret)
 +    return NULL;
 +  grub_memcpy (ret, glyph, sizeof (*ret)
 +             + (glyph->width * glyph->height + 7) / 8);
 +  return ret;
 +}
 +
 +/* FIXME: suboptimal.  */
 +static void
 +grub_font_blit_glyph (struct grub_font_glyph *target,
-                     struct grub_font_glyph *src,
-                     unsigned dx, unsigned dy)
++                    struct grub_font_glyph *src, unsigned dx, unsigned dy)
 +{
 +  unsigned src_bit, tgt_bit, src_byte, tgt_byte;
 +  unsigned i, j;
 +  for (i = 0; i < src->height; i++)
 +    {
 +      src_bit = (src->width * i) % 8;
 +      src_byte = (src->width * i) / 8;
 +      tgt_bit = (target->width * (dy + i) + dx) % 8;
 +      tgt_byte = (target->width * (dy + i) + dx) / 8;
 +      for (j = 0; j < src->width; j++)
 +      {
 +        target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit)
 +                                     & 0x80) >> tgt_bit;
 +        src_bit++;
 +        tgt_bit++;
 +        if (src_bit == 8)
 +          {
 +            src_byte++;
 +            src_bit = 0;
 +          }
 +        if (tgt_bit == 8)
 +          {
 +            tgt_byte++;
 +            tgt_bit = 0;
 +          }
 +      }
 +    }
 +}
 +
 +static void
 +grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
 +                           struct grub_font_glyph *src,
 +                           unsigned dx, unsigned dy)
 +{
 +  unsigned tgt_bit, src_byte, tgt_byte;
 +  signed src_bit;
 +  unsigned i, j;
 +  for (i = 0; i < src->height; i++)
 +    {
 +      src_bit = (src->width * i + src->width - 1) % 8;
 +      src_byte = (src->width * i + src->width - 1) / 8;
 +      tgt_bit = (target->width * (dy + i) + dx) % 8;
 +      tgt_byte = (target->width * (dy + i) + dx) / 8;
 +      for (j = 0; j < src->width; j++)
 +      {
 +        target->bitmap[tgt_byte] |= ((src->bitmap[src_byte] << src_bit)
 +                                     & 0x80) >> tgt_bit;
 +        src_bit--;
 +        tgt_bit++;
 +        if (src_bit == -1)
 +          {
 +            src_byte--;
 +            src_bit = 7;
 +          }
 +        if (tgt_bit == 8)
 +          {
 +            tgt_byte++;
 +            tgt_bit = 0;
 +          }
 +      }
 +    }
 +}
 +
 +static void
 +blit_comb (const struct grub_unicode_glyph *glyph_id,
 +         struct grub_font_glyph *glyph,
 +         struct grub_video_signed_rect *bounds_out,
 +         struct grub_font_glyph *main_glyph,
-          struct grub_font_glyph **combining_glyphs,
-          int *device_width)
++         struct grub_font_glyph **combining_glyphs, int *device_width)
 +{
 +  struct grub_video_signed_rect bounds;
 +  unsigned i;
 +  signed above_rightx, above_righty;
 +  signed above_leftx, above_lefty;
 +  signed below_rightx, below_righty;
 +  signed min_devwidth = 0;
 +  auto void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
 +                                    signed dx, signed dy);
 +  void NESTED_FUNC_ATTR do_blit (struct grub_font_glyph *src,
 +                               signed dx, signed dy)
 +  {
 +    if (glyph)
 +      grub_font_blit_glyph (glyph, src, dx - glyph->offset_x,
 +                          (glyph->height + glyph->offset_y) + dy);
 +    if (dx < bounds.x)
 +      {
 +      bounds.width += bounds.x - dx;
 +      bounds.x = dx;
 +      }
 +    if (bounds.y > -src->height - dy)
 +      {
 +      bounds.height += bounds.y - (-src->height - dy);
 +      bounds.y = (-src->height - dy);
 +      }
 +    if (dx + src->width - bounds.x >= (signed) bounds.width)
 +      bounds.width = dx + src->width - bounds.x + 1;
 +    if ((signed) bounds.height < src->height + (-src->height - dy) - bounds.y)
 +      bounds.height = src->height + (-src->height - dy) - bounds.y;
 +  }
 +
 +  auto void add_device_width (int val);
 +  void add_device_width (int val)
 +  {
 +    if (glyph)
 +      glyph->device_width += val;
 +    if (device_width)
 +      *device_width += val;
 +  }
 +
 +  if (glyph)
 +    glyph->device_width = main_glyph->device_width;
 +  if (device_width)
 +    *device_width = main_glyph->device_width;
 +
 +  bounds.x = main_glyph->offset_x;
 +  bounds.y = main_glyph->offset_y;
 +  bounds.width = main_glyph->width;
 +  bounds.height = main_glyph->height;
 +
 +  above_rightx = main_glyph->offset_x + main_glyph->width;
 +  above_righty = bounds.y + bounds.height;
 +
 +  above_leftx = main_glyph->offset_x;
 +  above_lefty = bounds.y + bounds.height;
 +
 +  below_rightx = bounds.x + bounds.width;
 +  below_righty = bounds.y;
 +
 +  for (i = 0; i < glyph_id->ncomb; i++)
 +    {
 +      grub_int16_t space = 0;
 +      /* Center by default.  */
 +      grub_int16_t targetx;
-       
++
 +      if (!combining_glyphs[i])
 +      continue;
-       targetx = (bounds.width - combining_glyphs[i]->width) / 2
-       + bounds.x;
++      targetx = (bounds.width - combining_glyphs[i]->width) / 2 + bounds.x;
 +      /* CGJ is to avoid diacritics reordering. */
-       if (glyph_id->combining[i].code == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
++      if (glyph_id->combining[i].code
++        == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER)
 +      continue;
 +      switch (glyph_id->combining[i].type)
 +      {
 +      case GRUB_UNICODE_COMB_OVERLAY:
 +        do_blit (combining_glyphs[i],
 +                 targetx,
 +                 (bounds.height - combining_glyphs[i]->height) / 2
-                  -(bounds.height + bounds.y));
++                 - (bounds.height + bounds.y));
 +        if (min_devwidth < combining_glyphs[i]->width)
 +          min_devwidth = combining_glyphs[i]->width;
 +        break;
 +
 +      case GRUB_UNICODE_COMB_ATTACHED_ABOVE_RIGHT:
 +        do_blit (combining_glyphs[i], above_rightx, -above_righty);
 +        above_rightx += combining_glyphs[i]->width;
 +        break;
 +
 +      case GRUB_UNICODE_COMB_ABOVE_RIGHT:
 +        do_blit (combining_glyphs[i], above_rightx,
 +                 -(above_righty + combining_glyphs[i]->height));
 +        above_rightx += combining_glyphs[i]->width;
 +        break;
 +
 +      case GRUB_UNICODE_COMB_ABOVE_LEFT:
 +        above_leftx -= combining_glyphs[i]->width;
 +        do_blit (combining_glyphs[i], above_leftx,
 +                 -(above_lefty + combining_glyphs[i]->height));
 +        break;
 +
 +      case GRUB_UNICODE_COMB_BELOW_RIGHT:
-         do_blit (combining_glyphs[i], below_rightx,
-                  below_righty);
++        do_blit (combining_glyphs[i], below_rightx, below_righty);
 +        below_rightx += combining_glyphs[i]->width;
 +        break;
 +
 +      case GRUB_UNICODE_COMB_HEBREW_HOLAM:
 +        if (glyph_id->base != GRUB_UNICODE_HEBREW_WAW)
-           targetx = main_glyph->offset_x - combining_glyphs[i]->width - (combining_glyphs[i]->width + 3) / 4;
++          targetx =
++            main_glyph->offset_x - combining_glyphs[i]->width -
++            (combining_glyphs[i]->width + 3) / 4;
 +        goto above_on_main;
 +
 +      case GRUB_UNICODE_COMB_HEBREW_SIN_DOT:
 +        targetx = main_glyph->offset_x + combining_glyphs[i]->width / 4;
 +        goto above_on_main;
 +
 +      case GRUB_UNICODE_COMB_HEBREW_SHIN_DOT:
-         targetx = main_glyph->width + main_glyph->offset_x - combining_glyphs[i]->width;
++        targetx =
++          main_glyph->width + main_glyph->offset_x -
++          combining_glyphs[i]->width;
 +      above_on_main:
 +        space = combining_glyphs[i]->offset_y
 +          - grub_font_get_xheight (combining_glyphs[i]->font) - 1;
 +        if (space <= 0)
 +          space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
 +        do_blit (combining_glyphs[i], targetx,
 +                 -(main_glyph->height + main_glyph->offset_y + space
 +                   + combining_glyphs[i]->height));
 +        if (min_devwidth < combining_glyphs[i]->width)
 +          min_devwidth = combining_glyphs[i]->width;
 +        break;
 +
 +        /* TODO: Put dammah, fathah and alif nearer to shadda.  */
 +      case GRUB_UNICODE_COMB_SYRIAC_SUPERSCRIPT_ALAPH:
 +      case GRUB_UNICODE_COMB_ARABIC_DAMMAH:
 +      case GRUB_UNICODE_COMB_ARABIC_DAMMATAN:
 +      case GRUB_UNICODE_COMB_ARABIC_FATHATAN:
 +      case GRUB_UNICODE_COMB_ARABIC_FATHAH:
 +      case GRUB_UNICODE_COMB_ARABIC_SUPERSCRIPT_ALIF:
 +      case GRUB_UNICODE_COMB_ARABIC_SUKUN:
 +      case GRUB_UNICODE_COMB_ARABIC_SHADDA:
 +      case GRUB_UNICODE_COMB_HEBREW_RAFE:
 +      case GRUB_UNICODE_STACK_ABOVE:
 +      stacked_above:
 +        space = combining_glyphs[i]->offset_y
 +          - grub_font_get_xheight (combining_glyphs[i]->font) - 1;
 +        if (space <= 0)
 +          space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
-           
-       case GRUB_UNICODE_STACK_ATTACHED_ABOVE:     
++
++      case GRUB_UNICODE_STACK_ATTACHED_ABOVE:
 +        do_blit (combining_glyphs[i], targetx,
 +                 -(bounds.height + bounds.y + space
 +                   + combining_glyphs[i]->height));
 +        if (min_devwidth < combining_glyphs[i]->width)
 +          min_devwidth = combining_glyphs[i]->width;
 +        break;
 +
 +      case GRUB_UNICODE_COMB_HEBREW_SHEVA:
 +      case GRUB_UNICODE_COMB_HEBREW_HIRIQ:
 +      case GRUB_UNICODE_COMB_HEBREW_QAMATS:
 +      case GRUB_UNICODE_COMB_HEBREW_TSERE:
 +      case GRUB_UNICODE_COMB_HEBREW_SEGOL:
 +        /* TODO: placement in final kaf and under reish.  */
 +
 +      case GRUB_UNICODE_COMB_HEBREW_HATAF_SEGOL:
 +      case GRUB_UNICODE_COMB_HEBREW_HATAF_PATAH:
 +      case GRUB_UNICODE_COMB_HEBREW_HATAF_QAMATS:
 +      case GRUB_UNICODE_COMB_HEBREW_PATAH:
 +      case GRUB_UNICODE_COMB_HEBREW_QUBUTS:
 +      case GRUB_UNICODE_COMB_HEBREW_METEG:
 +        /* TODO: Put kasra and kasratan under shadda.  */
 +      case GRUB_UNICODE_COMB_ARABIC_KASRA:
 +      case GRUB_UNICODE_COMB_ARABIC_KASRATAN:
 +        /* I don't know how ypogegrammeni differs from subscript. */
 +      case GRUB_UNICODE_COMB_YPOGEGRAMMENI:
 +      case GRUB_UNICODE_STACK_BELOW:
 +      stacked_below:
-         space = -(combining_glyphs[i]->offset_y 
++        space = -(combining_glyphs[i]->offset_y
 +                  + combining_glyphs[i]->height);
 +        if (space <= 0)
 +          space = 1 + (grub_font_get_xheight (main_glyph->font)) / 8;
-         
++
 +      case GRUB_UNICODE_STACK_ATTACHED_BELOW:
-         do_blit (combining_glyphs[i], targetx,
-                  -(bounds.y - space));
++        do_blit (combining_glyphs[i], targetx, -(bounds.y - space));
 +        if (min_devwidth < combining_glyphs[i]->width)
 +          min_devwidth = combining_glyphs[i]->width;
 +        break;
 +
 +      case GRUB_UNICODE_COMB_MN:
 +        switch (glyph_id->combining[i].code)
 +          {
 +          case GRUB_UNICODE_THAANA_ABAFILI:
 +          case GRUB_UNICODE_THAANA_AABAAFILI:
 +          case GRUB_UNICODE_THAANA_UBUFILI:
 +          case GRUB_UNICODE_THAANA_OOBOOFILI:
 +          case GRUB_UNICODE_THAANA_EBEFILI:
 +          case GRUB_UNICODE_THAANA_EYBEYFILI:
 +          case GRUB_UNICODE_THAANA_OBOFILI:
 +          case GRUB_UNICODE_THAANA_OABOAFILI:
 +          case GRUB_UNICODE_THAANA_SUKUN:
 +            goto stacked_above;
 +          case GRUB_UNICODE_THAANA_IBIFILI:
 +          case GRUB_UNICODE_THAANA_EEBEEFILI:
-             goto stacked_below;             
++            goto stacked_below;
 +          }
 +        /* Fall through.  */
 +      default:
 +        {
 +          /* Default handling. Just draw combining character on top
 +             of base character.
 +             FIXME: support more unicode types correctly.
-           */
++           */
 +          do_blit (combining_glyphs[i],
 +                   main_glyph->device_width
-                    + combining_glyphs[i]->offset_x,  
-                    - (combining_glyphs[i]->height 
-                       + combining_glyphs[i]->offset_y));
++                   + combining_glyphs[i]->offset_x,
++                   -(combining_glyphs[i]->height
++                     + combining_glyphs[i]->offset_y));
 +          add_device_width (combining_glyphs[i]->device_width);
 +        }
 +      }
 +    }
-   add_device_width ((above_rightx > below_rightx ? above_rightx : below_rightx) 
-                   - (main_glyph->offset_x + main_glyph->width));
++  add_device_width ((above_rightx >
++                   below_rightx ? above_rightx : below_rightx) -
++                  (main_glyph->offset_x + main_glyph->width));
 +  add_device_width (above_leftx - main_glyph->offset_x);
 +  if (glyph && glyph->device_width < min_devwidth)
-       glyph->device_width = min_devwidth;
++    glyph->device_width = min_devwidth;
 +  if (device_width && *device_width < min_devwidth)
 +    *device_width = min_devwidth;
 +
 +  if (bounds_out)
 +    *bounds_out = bounds;
 +}
 +
 +static struct grub_font_glyph *
 +grub_font_construct_dry_run (grub_font_t hinted_font,
 +                           const struct grub_unicode_glyph *glyph_id,
 +                           struct grub_video_signed_rect *bounds,
 +                           struct grub_font_glyph ***combining_glyphs_out,
 +                           int *device_width)
 +{
 +  struct grub_font_glyph *main_glyph = NULL;
 +  struct grub_font_glyph **combining_glyphs;
 +  grub_uint32_t desired_attributes = 0;
 +
 +  if (combining_glyphs_out)
 +    *combining_glyphs_out = NULL;
 +
 +  if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_RIGHT_JOINED)
 +    desired_attributes |= GRUB_FONT_CODE_RIGHT_JOINED;
 +
 +  if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_LEFT_JOINED)
 +    desired_attributes |= GRUB_FONT_CODE_LEFT_JOINED;
 +
 +  main_glyph = grub_font_get_glyph_with_fallback (hinted_font, glyph_id->base
 +                                                | desired_attributes);
 +
 +  if (!main_glyph)
 +    main_glyph = grub_font_get_glyph_with_fallback (hinted_font,
 +                                                  glyph_id->base);
 +
 +  /* Glyph not available in any font.  Use ASCII fallback.  */
 +  if (!main_glyph)
 +    main_glyph = ascii_glyph_lookup (glyph_id->base);
 +
 +  /* Glyph not available in any font.  Return unknown glyph.  */
 +  if (!main_glyph)
 +    return NULL;
 +
 +  if (device_width)
 +    *device_width = main_glyph->device_width;
 +
 +  if (!glyph_id->ncomb && !glyph_id->attributes)
 +    return main_glyph;
 +
 +  combining_glyphs = grub_malloc (sizeof (combining_glyphs[0])
 +                                * glyph_id->ncomb);
 +  if (glyph_id->ncomb && !combining_glyphs)
 +    {
 +      grub_errno = GRUB_ERR_NONE;
 +      return main_glyph;
 +    }
-   
++
 +  {
 +    unsigned i;
 +    for (i = 0; i < glyph_id->ncomb; i++)
 +      combining_glyphs[i]
 +      = grub_font_get_glyph_with_fallback (main_glyph->font,
 +                                           glyph_id->combining[i].code);
 +  }
 +
-   blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs, device_width);
++  blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs,
++           device_width);
 +  if (combining_glyphs_out)
 +    *combining_glyphs_out = combining_glyphs;
    else
 -    /* Glyph not available in any font.  Return ASCII failback.  */
 -    return ascii_glyph_lookup (code);
 +    grub_free (combining_glyphs);
 +
 +  return main_glyph;
  }
  
-                                       const struct grub_unicode_glyph *glyph_id)
 +int
 +grub_font_get_constructed_device_width (grub_font_t hinted_font,
-   
-   glyph = grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8);
++                                      const struct grub_unicode_glyph
++                                      *glyph_id)
 +{
 +  int ret;
 +  struct grub_font_glyph *main_glyph;
 +  main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id, NULL,
 +                                          NULL, &ret);
 +  if (!main_glyph)
 +    return unknown_glyph->device_width;
 +  return ret;
 +}
 +
 +struct grub_font_glyph *
 +grub_font_construct_glyph (grub_font_t hinted_font,
 +                         const struct grub_unicode_glyph *glyph_id)
 +{
 +  struct grub_font_glyph *main_glyph;
 +  struct grub_video_signed_rect bounds;
 +  struct grub_font_glyph *glyph;
 +  struct grub_font_glyph **combining_glyphs;
 +
 +  main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id,
 +                                          &bounds, &combining_glyphs, NULL);
 +
 +  if (!main_glyph)
 +    return grub_font_dup_glyph (unknown_glyph);
 +
 +  if (!combining_glyphs)
 +    return grub_font_dup_glyph (main_glyph);
-                                - (main_glyph->height + main_glyph->offset_y));
++
++  glyph =
++    grub_zalloc (sizeof (*glyph) + (bounds.width * bounds.height + 7) / 8);
 +  if (!glyph)
 +    {
 +      grub_errno = GRUB_ERR_NONE;
 +      return grub_font_dup_glyph (main_glyph);
 +    }
 +
 +  glyph->font = main_glyph->font;
 +  glyph->width = bounds.width;
 +  glyph->height = bounds.height;
 +  glyph->offset_x = bounds.x;
 +  glyph->offset_y = bounds.y;
 +
 +  if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR)
 +    grub_font_blit_glyph_mirror (glyph, main_glyph,
 +                               main_glyph->offset_x - glyph->offset_x,
 +                               (glyph->height + glyph->offset_y)
++                               - (main_glyph->height +
++                                  main_glyph->offset_y));
 +  else
 +    grub_font_blit_glyph (glyph, main_glyph,
 +                        main_glyph->offset_x - glyph->offset_x,
 +                        (glyph->height + glyph->offset_y)
 +                        - (main_glyph->height + main_glyph->offset_y));
 +
 +  blit_comb (glyph_id, glyph, NULL, main_glyph, combining_glyphs, NULL);
 +
 +  return glyph;
 +}
  
  /* Draw the specified glyph at (x, y).  The y coordinate designates the
     baseline of the character, while the x coordinate designates the left
@@@ -1492,9 -1065,8 +1498,8 @@@ grub_font_draw_glyph (struct grub_font_
  
    glyph_bitmap.mode_info.width = glyph->width;
    glyph_bitmap.mode_info.height = glyph->height;
--  glyph_bitmap.mode_info.mode_type =
-     (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS)
-     | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
 -    (1 << GRUB_VIDEO_MODE_TYPE_DEPTH_POS) | GRUB_VIDEO_MODE_TYPE_1BIT_BITMAP;
++  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;
  
    int bitmap_top = bitmap_bottom - glyph->height;
  
    return grub_video_blit_bitmap (&glyph_bitmap, GRUB_VIDEO_BLIT_BLEND,
-                                  bitmap_left, bitmap_top,
-                                  0, 0,
-                                  glyph->width, glyph->height);
+                                bitmap_left, bitmap_top,
+                                0, 0, glyph->width, glyph->height);
  }
 -
 -/* Draw a UTF-8 string of text on the current video render target.
 -   The x coordinate specifies the starting x position for the first character,
 -   while the y coordinate specifies the baseline position.
 -   If the string contains a character that FONT does not contain, then
 -   a glyph from another loaded font may be used instead.  */
 -grub_err_t
 -grub_font_draw_string (const char *str, grub_font_t font,
 -                     grub_video_color_t color, int left_x, int baseline_y)
 -{
 -  int x;
 -  struct grub_font_glyph *glyph;
 -  grub_uint32_t code;
 -  const grub_uint8_t *ptr;
 -
 -  for (ptr = (const grub_uint8_t *) str, x = left_x;
 -       grub_utf8_to_ucs4 (&code, 1, ptr, -1, &ptr) > 0;)
 -    {
 -      glyph = grub_font_get_glyph_with_fallback (font, code);
 -      if (grub_font_draw_glyph (glyph, color, x, baseline_y) != GRUB_ERR_NONE)
 -      return grub_errno;
 -      x += glyph->device_width;
 -    }
--
 -  return GRUB_ERR_NONE;
 -}
Simple merge