Example #1
0
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);

  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;
}
Example #2
0
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;
  static struct grub_font_glyph *glyph = 0;
  static grub_size_t max_glyph_size = 0;

  ensure_comb_space (glyph_id);

  main_glyph = grub_font_construct_dry_run (hinted_font, glyph_id,
					    &bounds, render_combining_glyphs,
					    NULL);

  if (!main_glyph)
    return unknown_glyph;

  if (!render_combining_glyphs && glyph_id->ncomb)
    return main_glyph;

  if (!glyph_id->ncomb && !glyph_id->attributes)
    return main_glyph;

  if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT)
    {
      grub_free (glyph);
      max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2;
      if (max_glyph_size < 8)
	max_glyph_size = 8;
      glyph = grub_malloc (max_glyph_size);
    }
  if (!glyph)
    {
      grub_errno = GRUB_ERR_NONE;
      return main_glyph;
    }

  grub_memset (glyph, 0, sizeof (*glyph)
	       + (bounds.width * bounds.height
		  + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT);

  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, render_combining_glyphs, NULL);

  return glyph;
}
Example #3
0
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,
			     int *device_width)
{
  struct grub_font_glyph *main_glyph = NULL;
  grub_uint32_t desired_attributes = 0;
  unsigned i;
  grub_uint32_t base = glyph_id->base;
  const struct grub_unicode_combining *comb;

  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;

  comb = grub_unicode_get_comb (glyph_id);

  if (base == 'i' || base == 'j')
    {
      for (i = 0; i < glyph_id->ncomb; i++)
	if (comb[i].type == GRUB_UNICODE_STACK_ABOVE)
	  break;
      if (i < glyph_id->ncomb && base == 'i')
	base = GRUB_UNICODE_DOTLESS_LOWERCASE_I;
      if (i < glyph_id->ncomb && base == 'j')
	base = GRUB_UNICODE_DOTLESS_LOWERCASE_J;
    }

  main_glyph = grub_font_get_glyph_with_fallback (hinted_font, base
						  | desired_attributes);

  if (!main_glyph)
    main_glyph = grub_font_get_glyph_with_fallback (hinted_font,
						    base);

  /* Glyph not available in any font.  Use ASCII fallback.  */
  if (!main_glyph)
    main_glyph = ascii_glyph_lookup (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;

  if (glyph_id->ncomb && !combining_glyphs)
    {
      grub_errno = GRUB_ERR_NONE;
      return main_glyph;
    }

  for (i = 0; i < glyph_id->ncomb; i++)
    combining_glyphs[i]
      = grub_font_get_glyph_with_fallback (main_glyph->font,
					   comb[i].code);

  blit_comb (glyph_id, NULL, bounds, main_glyph, combining_glyphs,
	     device_width);

  return main_glyph;
}