⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pangocairo-font.c

📁 Pango is a library for layout and rendering of text, with an emphasis on internationalization. Pang
💻 C
📖 第 1 页 / 共 2 页
字号:
    mini_size = size / 2.4;    if (is_hinted)      {	mini_size = HINT_Y (mini_size);	if (mini_size < 5.0)	  {	    rows = 1;	    mini_size = MIN (MAX (size - 1, 0), 5.0);	  }      }    pango_font_description_set_absolute_size (desc, pango_units_from_double (mini_size));    /* load mini_font */    context = pango_cairo_font_map_create_context ((PangoCairoFontMap *) (fontmap));    pango_context_set_matrix (context, &pango_ctm);    pango_context_set_language (context, pango_script_get_sample_language (PANGO_SCRIPT_LATIN));    pango_cairo_context_set_font_options (context, font_options);    mini_font = pango_font_map_load_font (fontmap, context, desc);    g_object_unref (context);  }  pango_font_description_free (desc);  cairo_font_options_destroy (font_options);  scaled_mini_font = pango_cairo_font_get_scaled_font ((PangoCairoFont *) mini_font);  for (i = 0 ; i < 16 ; i++)    {      cairo_text_extents_t extents;      c[0] = hexdigits[i];      cairo_scaled_font_text_extents (scaled_mini_font, c, &extents);      width = MAX (width, extents.width);      height = MAX (height, extents.height);    }  cairo_scaled_font_extents (scaled_font, &font_extents);  if (font_extents.ascent + font_extents.descent <= 0)    {      font_extents.ascent = PANGO_UNKNOWN_GLYPH_HEIGHT;      font_extents.descent = 0;    }  pad = (font_extents.ascent + font_extents.descent) / 43;  pad = MIN (pad, mini_size);  hbi = g_slice_new (PangoCairoFontHexBoxInfo);  hbi->font = (PangoCairoFont *) mini_font;  hbi->rows = rows;  hbi->digit_width  = width;  hbi->digit_height = height;  hbi->pad_x = pad;  hbi->pad_y = pad;  if (is_hinted)    {      hbi->digit_width  = HINT_X (hbi->digit_width);      hbi->digit_height = HINT_Y (hbi->digit_height);      hbi->pad_x = HINT_X (hbi->pad_x);      hbi->pad_y = HINT_Y (hbi->pad_y);    }  hbi->line_width = MIN (hbi->pad_x, hbi->pad_y);  hbi->box_height = 3 * hbi->pad_y + rows * (hbi->pad_y + hbi->digit_height);  if (rows == 1 || hbi->box_height <= font_extents.ascent)    {      hbi->box_descent = 2 * hbi->pad_y;    }  else if (hbi->box_height <= font_extents.ascent + font_extents.descent - 2 * hbi->pad_y)    {      hbi->box_descent = 2 * hbi->pad_y + hbi->box_height - font_extents.ascent;    }  else    {      hbi->box_descent = font_extents.descent * hbi->box_height /			 (font_extents.ascent + font_extents.descent);    }  if (is_hinted)    {       hbi->box_descent = HINT_Y (hbi->box_descent);    }  cf_priv->hbi = hbi;  return hbi;}static void_pango_cairo_font_hex_box_info_destroy (PangoCairoFontHexBoxInfo *hbi){  if (hbi)    {      g_object_unref (hbi->font);      g_slice_free (PangoCairoFontHexBoxInfo, hbi);    }}PangoCairoFontHexBoxInfo *_pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont){  PangoCairoFontPrivate *cf_priv = PANGO_CAIRO_FONT_PRIVATE (cfont);  return _pango_cairo_font_private_get_hex_box_info (cf_priv);}void_pango_cairo_font_private_initialize (PangoCairoFontPrivate      *cf_priv,				      PangoCairoFont             *cfont,				      PangoContext               *context,				      const PangoFontDescription *desc,				      const cairo_matrix_t       *font_matrix){  const cairo_font_options_t *font_options;  cairo_matrix_t gravity_matrix;  const PangoMatrix *pango_ctm;  cf_priv->cfont = cfont;  cf_priv->gravity = pango_font_description_get_gravity (desc);  cf_priv->data = _pango_cairo_font_private_scaled_font_data_create ();   /* first apply gravity rotation, then font_matrix, such that   * vertical italic text comes out "correct".  we don't do anything   * like baseline adjustment etc though.  should be specially   * handled when we support italic correction. */  cairo_matrix_init_rotate(&gravity_matrix,			   pango_gravity_to_rotation (cf_priv->gravity));  cairo_matrix_multiply (&cf_priv->data->font_matrix,			 font_matrix,			 &gravity_matrix);  pango_ctm = pango_context_get_matrix (context);  if (pango_ctm)    cairo_matrix_init (&cf_priv->data->ctm,		       pango_ctm->xx,		       pango_ctm->yx,		       pango_ctm->xy,		       pango_ctm->yy,		       0., 0.);  else    cairo_matrix_init_identity (&cf_priv->data->ctm);  font_options = _pango_cairo_context_get_merged_font_options (context);  cf_priv->data->options = cairo_font_options_copy (font_options);  cf_priv->is_hinted = cairo_font_options_get_hint_metrics (font_options) != CAIRO_HINT_METRICS_OFF;  cf_priv->scaled_font = NULL;  cf_priv->hbi = NULL;  cf_priv->glyph_extents_cache = NULL;  cf_priv->metrics_by_lang = NULL;}static voidfree_metrics_info (PangoCairoFontMetricsInfo *info){  pango_font_metrics_unref (info->metrics);  g_slice_free (PangoCairoFontMetricsInfo, info);}void_pango_cairo_font_private_finalize (PangoCairoFontPrivate *cf_priv){  _pango_cairo_font_private_scaled_font_data_destroy (cf_priv->data);  if (cf_priv->scaled_font)    cairo_scaled_font_destroy (cf_priv->scaled_font);  _pango_cairo_font_hex_box_info_destroy (cf_priv->hbi);  if (cf_priv->glyph_extents_cache)    g_free (cf_priv->glyph_extents_cache);  g_slist_foreach (cf_priv->metrics_by_lang, (GFunc)free_metrics_info, NULL);  g_slist_free (cf_priv->metrics_by_lang);}gboolean_pango_cairo_font_private_is_metrics_hinted (PangoCairoFontPrivate *cf_priv){  return cf_priv->is_hinted;}static void_pango_cairo_font_private_get_glyph_extents_missing (PangoCairoFontPrivate *cf_priv,						     PangoGlyph             glyph,						     PangoRectangle        *ink_rect,						     PangoRectangle        *logical_rect){  PangoCairoFontHexBoxInfo *hbi;  gunichar ch;  gint rows, cols;  hbi = _pango_cairo_font_private_get_hex_box_info (cf_priv);  if (!hbi)    {      pango_font_get_glyph_extents (NULL, glyph, ink_rect, logical_rect);      return;    }  ch = glyph & ~PANGO_GLYPH_UNKNOWN_FLAG;  rows = hbi->rows;  if (G_UNLIKELY (glyph == PANGO_GLYPH_INVALID_INPUT || ch > 0x10FFFF))    cols = 1;  else    cols = ((glyph & ~PANGO_GLYPH_UNKNOWN_FLAG) > 0xffff ? 6 : 4) / rows;  if (ink_rect)    {      ink_rect->x = PANGO_SCALE * hbi->pad_x;      ink_rect->y = PANGO_SCALE * (hbi->box_descent - hbi->box_height);      ink_rect->width = PANGO_SCALE * (3 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));      ink_rect->height = PANGO_SCALE * hbi->box_height;    }  if (logical_rect)    {      logical_rect->x = 0;      logical_rect->y = PANGO_SCALE * (hbi->box_descent - (hbi->box_height + hbi->pad_y));      logical_rect->width = PANGO_SCALE * (5 * hbi->pad_x + cols * (hbi->digit_width + hbi->pad_x));      logical_rect->height = PANGO_SCALE * (hbi->box_height + 2 * hbi->pad_y);    }}#define GLYPH_CACHE_NUM_ENTRIES 256 /* should be power of two */#define GLYPH_CACHE_MASK (GLYPH_CACHE_NUM_ENTRIES - 1)/* An entry in the fixed-size cache for the glyph->extents mapping. * The cache is indexed by the lower N bits of the glyph (see * GLYPH_CACHE_NUM_ENTRIES).  For scripts with few glyphs, * this should provide pretty much instant lookups. */struct _PangoCairoFontGlyphExtentsCacheEntry{  PangoGlyph     glyph;  int            width;  PangoRectangle ink_rect;};static gboolean_pango_cairo_font_private_glyph_extents_cache_init (PangoCairoFontPrivate *cf_priv){  cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv);  cairo_font_extents_t font_extents;  if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS))    return FALSE;  cairo_scaled_font_extents (scaled_font, &font_extents);  cf_priv->font_extents.x = 0;  cf_priv->font_extents.width = 0;  cf_priv->font_extents.height = pango_units_from_double (font_extents.ascent + font_extents.descent);  switch (cf_priv->gravity)    {      default:      case PANGO_GRAVITY_AUTO:      case PANGO_GRAVITY_SOUTH:	cf_priv->font_extents.y = - pango_units_from_double (font_extents.ascent);	break;      case PANGO_GRAVITY_NORTH:	cf_priv->font_extents.y = - pango_units_from_double (font_extents.descent);	break;      case PANGO_GRAVITY_EAST:      case PANGO_GRAVITY_WEST:	{	  int ascent = pango_units_from_double (font_extents.ascent + font_extents.descent) / 2;	  if (cf_priv->is_hinted)	    ascent = PANGO_UNITS_ROUND (ascent);	  cf_priv->font_extents.y = - ascent;	}    }  cf_priv->glyph_extents_cache = g_new0 (PangoCairoFontGlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES);  /* Make sure all cache entries are invalid initially */  cf_priv->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */  return TRUE;}/* Fills in the glyph extents cache entry */static voidcompute_glyph_extents (PangoCairoFontPrivate  *cf_priv,		       PangoGlyph              glyph,		       PangoCairoFontGlyphExtentsCacheEntry *entry){  cairo_text_extents_t extents;  cairo_glyph_t cairo_glyph;  cairo_glyph.index = glyph;  cairo_glyph.x = 0;  cairo_glyph.y = 0;  cairo_scaled_font_glyph_extents (_pango_cairo_font_private_get_scaled_font (cf_priv),				   &cairo_glyph, 1, &extents);  entry->glyph = glyph;  entry->width = pango_units_from_double (extents.x_advance);  entry->ink_rect.x = pango_units_from_double (extents.x_bearing);  entry->ink_rect.y = pango_units_from_double (extents.y_bearing);  entry->ink_rect.width = pango_units_from_double (extents.width);  entry->ink_rect.height = pango_units_from_double (extents.height);}static PangoCairoFontGlyphExtentsCacheEntry *_pango_cairo_font_private_get_glyph_extents_cache_entry (PangoCairoFontPrivate  *cf_priv,							 PangoGlyph              glyph){  PangoCairoFontGlyphExtentsCacheEntry *entry;  guint idx;  idx = glyph & GLYPH_CACHE_MASK;  entry = cf_priv->glyph_extents_cache + idx;  if (entry->glyph != glyph)    {      compute_glyph_extents (cf_priv, glyph, entry);    }  return entry;}void_pango_cairo_font_private_get_glyph_extents (PangoCairoFontPrivate *cf_priv,					     PangoGlyph             glyph,					     PangoRectangle        *ink_rect,					     PangoRectangle        *logical_rect){  PangoCairoFontGlyphExtentsCacheEntry *entry;  if (!cf_priv ||      (cf_priv->glyph_extents_cache == NULL &&       !_pango_cairo_font_private_glyph_extents_cache_init (cf_priv)))    {      /* Get generic unknown-glyph extents. */      pango_font_get_glyph_extents (NULL, glyph, ink_rect, logical_rect);      return;    }  if (glyph == PANGO_GLYPH_EMPTY)    {      if (ink_rect)	ink_rect->x = ink_rect->y = ink_rect->width = ink_rect->height = 0;      if (logical_rect)	*logical_rect = cf_priv->font_extents;      return;    }  else if (glyph & PANGO_GLYPH_UNKNOWN_FLAG)    {      _pango_cairo_font_private_get_glyph_extents_missing(cf_priv, glyph, ink_rect, logical_rect);      return;    }  entry = _pango_cairo_font_private_get_glyph_extents_cache_entry (cf_priv, glyph);  if (ink_rect)    *ink_rect = entry->ink_rect;  if (logical_rect)    {      *logical_rect = cf_priv->font_extents;      logical_rect->width = entry->width;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -