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); }
/** * pango_cairo_font_get_scaled_font: * @font: a #PangoFont from a #PangoCairoFontMap * * Gets the #cairo_scaled_font_t used by @font. * The scaled font can be referenced and kept using * cairo_scaled_font_reference(). * * Return value: the #cairo_scaled_font_t used by @font, * or %NULL if @font is %NULL. * * Since: 1.18 **/ cairo_scaled_font_t * pango_cairo_font_get_scaled_font (PangoCairoFont *cfont) { PangoCairoFontPrivate *cf_priv; if (G_UNLIKELY (!cfont)) return NULL; cf_priv = PANGO_CAIRO_FONT_PRIVATE (cfont); return _pango_cairo_font_private_get_scaled_font (cf_priv); }
PangoFontMetrics * _pango_cairo_font_get_metrics (PangoFont *font, PangoLanguage *language) { PangoCairoFont *cfont = (PangoCairoFont *) font; PangoCairoFontPrivate *cf_priv = PANGO_CAIRO_FONT_PRIVATE (font); PangoCairoFontMetricsInfo *info = NULL; /* Quiet gcc */ GSList *tmp_list; const char *sample_str = pango_language_get_sample_string (language); tmp_list = cf_priv->metrics_by_lang; while (tmp_list) { info = tmp_list->data; if (info->sample_str == sample_str) /* We _don't_ need strcmp */ break; tmp_list = tmp_list->next; } if (!tmp_list) { PangoFontMap *fontmap; PangoContext *context; cairo_font_options_t *font_options; int height, shift; /* XXX this is racy. need a ref'ing getter... */ fontmap = pango_font_get_font_map (font); if (!fontmap) return pango_font_metrics_new (); fontmap = g_object_ref (fontmap); info = g_slice_new0 (PangoCairoFontMetricsInfo); cf_priv->metrics_by_lang = g_slist_prepend (cf_priv->metrics_by_lang, info); info->sample_str = sample_str; context = pango_font_map_create_context (fontmap); pango_context_set_language (context, language); font_options = cairo_font_options_create (); cairo_scaled_font_get_font_options (_pango_cairo_font_private_get_scaled_font (cf_priv), font_options); pango_cairo_context_set_font_options (context, font_options); cairo_font_options_destroy (font_options); info->metrics = (* PANGO_CAIRO_FONT_GET_IFACE (font)->create_metrics_for_context) (cfont, context); /* We may actually reuse ascent/descent we got from cairo here. that's * in cf_priv->font_extents. */ height = info->metrics->ascent + info->metrics->descent; switch (cf_priv->gravity) { default: case PANGO_GRAVITY_AUTO: case PANGO_GRAVITY_SOUTH: break; case PANGO_GRAVITY_NORTH: info->metrics->ascent = info->metrics->descent; break; case PANGO_GRAVITY_EAST: case PANGO_GRAVITY_WEST: { int ascent = height / 2; if (cf_priv->is_hinted) ascent = PANGO_UNITS_ROUND (ascent); info->metrics->ascent = ascent; } } shift = (height - info->metrics->ascent) - info->metrics->descent; info->metrics->descent += shift; info->metrics->underline_position -= shift; info->metrics->strikethrough_position -= shift; info->metrics->ascent = height - info->metrics->descent; g_object_unref (context); g_object_unref (fontmap); } return pango_font_metrics_ref (info->metrics); }
PangoFontMetrics * _pango_cairo_font_get_metrics (PangoFont *font, PangoLanguage *language) { PangoCairoFont *cfont = (PangoCairoFont *) font; PangoCairoFontPrivate *cf_priv = PANGO_CAIRO_FONT_PRIVATE (font); PangoCairoFontMetricsInfo *info = NULL; /* Quiet gcc */ GSList *tmp_list; const char *sample_str = pango_language_get_sample_string (language); tmp_list = cf_priv->metrics_by_lang; while (tmp_list) { info = tmp_list->data; if (info->sample_str == sample_str) /* We _don't_ need strcmp */ break; tmp_list = tmp_list->next; } if (!tmp_list) { PangoFontMap *fontmap; PangoContext *context; cairo_font_options_t *font_options; PangoLayout *layout; PangoRectangle extents; PangoFontDescription *desc; cairo_scaled_font_t *scaled_font; cairo_matrix_t cairo_matrix; PangoMatrix pango_matrix; PangoMatrix identity = PANGO_MATRIX_INIT; int height, shift; /* XXX this is racy. need a ref'ing getter... */ fontmap = pango_font_get_font_map (font); if (!fontmap) return pango_font_metrics_new (); fontmap = g_object_ref (fontmap); info = g_slice_new0 (PangoCairoFontMetricsInfo); cf_priv->metrics_by_lang = g_slist_prepend (cf_priv->metrics_by_lang, info); info->sample_str = sample_str; scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv); context = pango_font_map_create_context (fontmap); pango_context_set_language (context, language); font_options = cairo_font_options_create (); cairo_scaled_font_get_font_options (scaled_font, font_options); pango_cairo_context_set_font_options (context, font_options); cairo_font_options_destroy (font_options); info->metrics = (* PANGO_CAIRO_FONT_GET_IFACE (font)->create_base_metrics_for_context) (cfont, context); /* We now need to adjust the base metrics for ctm */ cairo_scaled_font_get_ctm (scaled_font, &cairo_matrix); pango_matrix.xx = cairo_matrix.xx; pango_matrix.yx = cairo_matrix.yx; pango_matrix.xy = cairo_matrix.xy; pango_matrix.yy = cairo_matrix.yy; pango_matrix.x0 = 0; pango_matrix.y0 = 0; if (G_UNLIKELY (0 != memcmp (&identity, &pango_matrix, 4 * sizeof (double)))) { double xscale = pango_matrix_get_font_scale_factor (&pango_matrix); if (xscale) xscale = 1 / xscale; info->metrics->ascent *= xscale; info->metrics->descent *= xscale; info->metrics->underline_position *= xscale; info->metrics->underline_thickness *= xscale; info->metrics->strikethrough_position *= xscale; info->metrics->strikethrough_thickness *= xscale; } /* Set the matrix on the context so we don't have to adjust the derived * metrics. */ pango_context_set_matrix (context, &pango_matrix); /* Update approximate_*_width now */ layout = pango_layout_new (context); desc = pango_font_describe_with_absolute_size (font); pango_layout_set_font_description (layout, desc); pango_font_description_free (desc); pango_layout_set_text (layout, sample_str, -1); pango_layout_get_extents (layout, NULL, &extents); info->metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str); pango_layout_set_text (layout, "0123456789", -1); info->metrics->approximate_digit_width = max_glyph_width (layout); g_object_unref (layout); /* We may actually reuse ascent/descent we got from cairo here. that's * in cf_priv->font_extents. */ height = info->metrics->ascent + info->metrics->descent; switch (cf_priv->gravity) { default: case PANGO_GRAVITY_AUTO: case PANGO_GRAVITY_SOUTH: break; case PANGO_GRAVITY_NORTH: info->metrics->ascent = info->metrics->descent; break; case PANGO_GRAVITY_EAST: case PANGO_GRAVITY_WEST: { int ascent = height / 2; if (cf_priv->is_hinted) ascent = PANGO_UNITS_ROUND (ascent); info->metrics->ascent = ascent; } } shift = (height - info->metrics->ascent) - info->metrics->descent; info->metrics->descent += shift; info->metrics->underline_position -= shift; info->metrics->strikethrough_position -= shift; info->metrics->ascent = height - info->metrics->descent; g_object_unref (context); g_object_unref (fontmap); } return pango_font_metrics_ref (info->metrics); }