diff options
author | Behdad Esfahbod <behdad@gnome.org> | 2007-06-10 00:48:25 +0000 |
---|---|---|
committer | Behdad Esfahbod <behdad@src.gnome.org> | 2007-06-10 00:48:25 +0000 |
commit | 1bc615b0a5863c5680770171f014a1f99c975a9e (patch) | |
tree | e7956b3e611ec5867be06bf721b60333edac3798 /pango | |
parent | 672cd0f5671ba6f20c76a3b12cfbd4c77c57fb54 (diff) | |
download | pango-1bc615b0a5863c5680770171f014a1f99c975a9e.tar.gz |
Bug 337593 – move glyph extents code (and cache) from pangocairo-*font.c
2007-06-09 Behdad Esfahbod <behdad@gnome.org>
Bug 337593 – move glyph extents code (and cache) from
pangocairo-*font.c into pangocairo-font.c
* pango/pangocairo-fontmap.c:
* pango/pangocairo-fcfontmap.c:
Remove per-fontmap renderer. We've not been using it for a while
and there is no reason to use it.
* pango/pangocairo-font.c
* pango/pangocairo-fcfont.c:
Most most code (including glyph extents caching) from fcfont.c to
font.c. Simplifies individual backends a lot. ATSUI and Win32
cairo backends should adapt.
* pango/pangocairo-render.c
* pango/pangocairo-private.h:
Update to reflect above changes.
svn path=/trunk/; revision=2335
Diffstat (limited to 'pango')
-rw-r--r-- | pango/pangocairo-fcfont.c | 425 | ||||
-rw-r--r-- | pango/pangocairo-fcfontmap.c | 12 | ||||
-rw-r--r-- | pango/pangocairo-font.c | 506 | ||||
-rw-r--r-- | pango/pangocairo-fontmap.c | 16 | ||||
-rw-r--r-- | pango/pangocairo-private.h | 104 | ||||
-rw-r--r-- | pango/pangocairo-render.c | 8 |
6 files changed, 566 insertions, 505 deletions
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c index 8c44b2a0..b671ebea 100644 --- a/pango/pangocairo-fcfont.c +++ b/pango/pangocairo-fcfont.c @@ -21,9 +21,6 @@ #include <config.h> -#include <math.h> -#include <stdlib.h> - #include <cairo-ft.h> #include "pango-fontmap.h" @@ -41,36 +38,12 @@ typedef struct _PangoCairoFcFont PangoCairoFcFont; typedef struct _PangoCairoFcFontClass PangoCairoFcFontClass; -typedef struct _GlyphExtentsCacheEntry GlyphExtentsCacheEntry; - -#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 -> ink_rect 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 _GlyphExtentsCacheEntry -{ - PangoGlyph glyph; - int width; - PangoRectangle ink_rect; -}; - struct _PangoCairoFcFont { PangoFcFont font; + PangoCairoFontPrivate cf_priv; - cairo_font_face_t *font_face; - cairo_scaled_font_t *scaled_font; - cairo_matrix_t font_matrix; - cairo_matrix_t ctm; - cairo_font_options_t *options; PangoGravity gravity; - - PangoRectangle font_extents; - GlyphExtentsCacheEntry *glyph_extents_cache; }; struct _PangoCairoFcFontClass @@ -80,86 +53,33 @@ struct _PangoCairoFcFontClass GType pango_cairo_fc_font_get_type (void); -static cairo_font_face_t *pango_cairo_fc_font_get_font_face (PangoCairoFont *font); - -/******************************* - * Utility functions * - *******************************/ +/******************************** + * Method implementations * + ********************************/ static cairo_font_face_t * -pango_cairo_fc_font_get_font_face (PangoCairoFont *font) -{ - PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font); - PangoFcFont *fcfont = (PangoFcFont *) (cffont); - - if (!cffont->font_face) - { - cffont->font_face = cairo_ft_font_face_create_for_pattern (fcfont->font_pattern); - - /* Unable to create FT2 cairo scaled font. - * This means out of memory or a cairo/fontconfig/FreeType bug, - */ - if (!cffont->font_face) - return NULL; - } - - return cffont->font_face; -} - -static cairo_scaled_font_t * -pango_cairo_fc_font_get_scaled_font (PangoCairoFont *font) +pango_cairo_fc_font_create_font_face (PangoCairoFont *cfont) { - PangoCairoFcFont *cffont = (PangoCairoFcFont *)font; + PangoFcFont *fcfont = (PangoFcFont *) (cfont); - if (!cffont->scaled_font) - { - cairo_font_face_t *font_face; - - font_face = pango_cairo_fc_font_get_font_face (font); - - if (!font_face) - return NULL; - - cffont->scaled_font = cairo_scaled_font_create (font_face, - &cffont->font_matrix, - &cffont->ctm, - cffont->options); - - /* Unable to create FT2 cairo scaled font. - * This means out of memory or a cairo/fontconfig/FreeType bug, - * or a missing font... - */ - if (!cffont->scaled_font) - return NULL; - } - - return cffont->scaled_font; + return cairo_ft_font_face_create_for_pattern (fcfont->font_pattern); } -/******************************** - * Method implementations * - ********************************/ - -static gboolean -pango_cairo_fc_font_install (PangoCairoFont *font, - cairo_t *cr) +static PangoFontMetrics * +pango_cairo_fc_font_create_metrics_for_context (PangoCairoFont *cfont, + PangoContext *context) { - PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font); - - cairo_set_font_face (cr, - pango_cairo_fc_font_get_font_face (font)); - cairo_set_font_matrix (cr, &cffont->font_matrix); - cairo_set_font_options (cr, cffont->options); + PangoFcFont *fcfont = (PangoFcFont *) (cfont); - return TRUE; + return pango_fc_font_create_metrics_for_context (fcfont, context); } static void cairo_font_iface_init (PangoCairoFontIface *iface) { - iface->install = pango_cairo_fc_font_install; - iface->get_font_face = pango_cairo_fc_font_get_font_face; - iface->get_scaled_font = pango_cairo_fc_font_get_scaled_font; + iface->create_font_face = pango_cairo_fc_font_create_font_face; + iface->create_metrics_for_context = pango_cairo_fc_font_create_metrics_for_context; + iface->cf_priv_offset = G_STRUCT_OFFSET (PangoCairoFcFont, cf_priv); } G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFont, pango_cairo_fc_font, PANGO_TYPE_FC_FONT, @@ -170,105 +90,34 @@ pango_cairo_fc_font_finalize (GObject *object) { PangoCairoFcFont *cffont = (PangoCairoFcFont *) (object); - if (cffont->font_face) - cairo_font_face_destroy (cffont->font_face); - if (cffont->scaled_font) - cairo_scaled_font_destroy (cffont->scaled_font); - if (cffont->options) - cairo_font_options_destroy (cffont->options); - - - if (cffont->glyph_extents_cache) - { - g_free (cffont->glyph_extents_cache); - } + _pango_cairo_font_private_finalize (&cffont->cf_priv); G_OBJECT_CLASS (pango_cairo_fc_font_parent_class)->finalize (object); } -/* This function is cut-and-pasted from pangocairo-fcfont.c - it might be - * better to add a virtual fcfont->create_context (font). - */ -static PangoFontMetrics * -pango_cairo_fc_font_get_metrics (PangoFont *font, - PangoLanguage *language) +/* we want get_glyph_extents extremely fast, so we use a small wrapper here + * to avoid having to lookup the interface data like we do for get_metrics + * in _pango_cairo_font_get_metrics(). */ +static void +pango_cairo_fc_font_get_glyph_extents (PangoFont *font, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) { - PangoFcFont *fcfont = (PangoFcFont *) (font); PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font); - PangoFcMetricsInfo *info = NULL; /* Quiet gcc */ - GSList *tmp_list; - - const char *sample_str = pango_language_get_sample_string (language); - - tmp_list = fcfont->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) - { - PangoContext *context; - int height, shift; - - if (!fcfont->fontmap) - return pango_font_metrics_new (); - - info = g_slice_new0 (PangoFcMetricsInfo); - - fcfont->metrics_by_lang = g_slist_prepend (fcfont->metrics_by_lang, info); - - info->sample_str = sample_str; - - context = pango_fc_font_map_create_context (PANGO_FC_FONT_MAP (fcfont->fontmap)); - pango_context_set_language (context, language); - pango_cairo_context_set_font_options (context, cffont->options); - - info->metrics = pango_fc_font_create_metrics_for_context (fcfont, context); - /* We may actually reuse ascent/descent we got from cairo here. that's - * in cffont->font_extents. - */ - height = info->metrics->ascent + info->metrics->descent; - switch (cffont->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 (fcfont->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); - } - - return pango_font_metrics_ref (info->metrics); + _pango_cairo_font_private_get_glyph_extents (&cffont->cf_priv, + glyph, + ink_rect, + logical_rect); } static FT_Face pango_cairo_fc_font_lock_face (PangoFcFont *font) { - PangoCairoFont *cfont = (PangoCairoFont *)font; - cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); + PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font); + cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&cffont->cf_priv); + if (G_UNLIKELY (!scaled_font)) return NULL; @@ -278,8 +127,9 @@ pango_cairo_fc_font_lock_face (PangoFcFont *font) static void pango_cairo_fc_font_unlock_face (PangoFcFont *font) { - PangoCairoFont *cfont = (PangoCairoFont *)font; - cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); + PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font); + cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&cffont->cf_priv); + if (G_UNLIKELY (!scaled_font)) return; @@ -287,146 +137,11 @@ pango_cairo_fc_font_unlock_face (PangoFcFont *font) } static void -pango_cairo_fc_font_glyph_extents_cache_init (PangoCairoFcFont *cffont) -{ - PangoCairoFont *cfont = (PangoCairoFont *)cffont; - cairo_scaled_font_t *scaled_font = pango_cairo_fc_font_get_scaled_font (cfont); - cairo_font_extents_t font_extents; - - cairo_scaled_font_extents (scaled_font, &font_extents); - - cffont->font_extents.x = 0; - cffont->font_extents.width = 0; - cffont->font_extents.height = pango_units_from_double (font_extents.ascent + font_extents.descent); - switch (cffont->gravity) - { - default: - case PANGO_GRAVITY_AUTO: - case PANGO_GRAVITY_SOUTH: - cffont->font_extents.y = - pango_units_from_double (font_extents.ascent); - break; - case PANGO_GRAVITY_NORTH: - cffont->font_extents.y = - pango_units_from_double (font_extents.descent); - break; - case PANGO_GRAVITY_EAST: - case PANGO_GRAVITY_WEST: - { - PangoFcFont *fcfont = (PangoFcFont *) (cffont); - int ascent = pango_units_from_double (font_extents.ascent + font_extents.descent) / 2; - if (fcfont->is_hinted) - ascent = PANGO_UNITS_ROUND (ascent); - cffont->font_extents.y = - ascent; - } - } - - cffont->glyph_extents_cache = g_new0 (GlyphExtentsCacheEntry, GLYPH_CACHE_NUM_ENTRIES); - /* Make sure all cache entries are invalid initially */ - cffont->glyph_extents_cache[0].glyph = 1; /* glyph 1 cannot happen in bucket 0 */ -} - -/* Fills in the glyph extents cache entry - */ -static void -compute_glyph_extents (PangoCairoFcFont *cffont, - PangoGlyph glyph, - GlyphExtentsCacheEntry *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 (cffont->scaled_font, - &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 GlyphExtentsCacheEntry * -pango_cairo_fc_font_get_glyph_extents_cache_entry (PangoCairoFcFont *cffont, - PangoGlyph glyph) -{ - GlyphExtentsCacheEntry *entry; - guint idx; - - idx = glyph & GLYPH_CACHE_MASK; - entry = cffont->glyph_extents_cache + idx; - - if (entry->glyph != glyph) - { - compute_glyph_extents (cffont, glyph, entry); - } - - return entry; -} - -static void -pango_cairo_fc_font_get_glyph_extents (PangoFont *font, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect) -{ - PangoCairoFcFont *cffont = (PangoCairoFcFont *)font; - GlyphExtentsCacheEntry *entry; - - if (!pango_cairo_fc_font_get_scaled_font ((PangoCairoFont *)cffont)) - { - /* Get generic unknown-glyph extents. */ - pango_font_get_glyph_extents (NULL, glyph, ink_rect, logical_rect); - return; - } - - /* We need to initialize the cache here, since we use cffont->font_extents - */ - if (cffont->glyph_extents_cache == NULL) - pango_cairo_fc_font_glyph_extents_cache_init (cffont); - - 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 = cffont->font_extents; - return; - } - else if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - { - _pango_cairo_get_glyph_extents_missing((PangoCairoFont *)font, glyph, ink_rect, logical_rect); - return; - } - - entry = pango_cairo_fc_font_get_glyph_extents_cache_entry (cffont, glyph); - - if (ink_rect) - *ink_rect = entry->ink_rect; - if (logical_rect) - { - *logical_rect = cffont->font_extents; - logical_rect->width = entry->width; - } -} - -static void pango_cairo_fc_font_shutdown (PangoFcFont *fcfont) { PangoCairoFcFont *cffont = (PangoCairoFcFont *) (fcfont); - if (cffont->scaled_font) - { - cairo_scaled_font_destroy (cffont->scaled_font); - cffont->scaled_font = NULL; - } - if (cffont->font_face) - { - cairo_font_face_destroy (cffont->font_face); - cffont->font_face = NULL; - } + + _pango_cairo_font_private_finalize (&cffont->cf_priv); } static void @@ -439,7 +154,7 @@ pango_cairo_fc_font_class_init (PangoCairoFcFontClass *class) object_class->finalize = pango_cairo_fc_font_finalize; font_class->get_glyph_extents = pango_cairo_fc_font_get_glyph_extents; - font_class->get_metrics = pango_cairo_fc_font_get_metrics; + font_class->get_metrics = _pango_cairo_font_get_metrics; fc_font_class->lock_face = pango_cairo_fc_font_lock_face; fc_font_class->unlock_face = pango_cairo_fc_font_unlock_face; @@ -459,8 +174,7 @@ static double get_font_size (PangoCairoFcFontMap *cffontmap, PangoContext *context, const PangoFontDescription *desc, - FcPattern *pattern, - const PangoMatrix *matrix) + FcPattern *pattern) { double size; @@ -478,7 +192,7 @@ get_font_size (PangoCairoFcFontMap *cffontmap, */ if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch) - return size * PANGO_SCALE / pango_matrix_get_font_scale_factor (matrix); + return size * PANGO_SCALE / pango_matrix_get_font_scale_factor (pango_context_get_matrix (context)); /* Just in case FC_PIXEL_SIZE got unset between pango_fc_make_pattern() * and here. @@ -503,7 +217,7 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap, FcPattern *pattern) { PangoCairoFcFont *cffont; - const PangoMatrix *pango_ctm; + cairo_matrix_t font_matrix; FcMatrix *fc_matrix; double size; @@ -514,56 +228,29 @@ _pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap, "pattern", pattern, NULL); - cffont->gravity = pango_font_description_get_gravity (desc); - - /* first apply gravity rotation, then pattern 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(&cffont->font_matrix, - pango_gravity_to_rotation (cffont->gravity)); + size = get_font_size (cffontmap, context, desc, pattern); if (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch) - { - cairo_matrix_t matrix; - - cairo_matrix_init (&matrix, - fc_matrix->xx, - - fc_matrix->yx, - - fc_matrix->xy, - fc_matrix->yy, - 0., 0.); - - cairo_matrix_multiply (&cffont->font_matrix, - &matrix, - &cffont->font_matrix); - } - - pango_ctm = pango_context_get_matrix (context); - - size = get_font_size (cffontmap, context, desc, pattern, pango_ctm); - - cairo_matrix_scale (&cffont->font_matrix, - size / PANGO_SCALE, size / PANGO_SCALE); - - if (pango_ctm) - cairo_matrix_init (&cffont->ctm, - pango_ctm->xx, - pango_ctm->yx, - pango_ctm->xy, - pango_ctm->yy, + cairo_matrix_init (&font_matrix, + fc_matrix->xx, + - fc_matrix->yx, + - fc_matrix->xy, + fc_matrix->yy, 0., 0.); else - cairo_matrix_init_identity (&cffont->ctm); + cairo_matrix_init_identity (&font_matrix); + cairo_matrix_scale (&font_matrix, + size / PANGO_SCALE, size / PANGO_SCALE); - cffont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context)); + _pango_cairo_font_private_initialize (&cffont->cf_priv, + (PangoCairoFont *) cffont, + context, + desc, + &font_matrix); - /* fcfont's is_hinted controls metric hinting - */ - ((PangoFcFont *)(cffont))->is_hinted = - (cairo_font_options_get_hint_metrics(cffont->options) != CAIRO_HINT_METRICS_OFF); + ((PangoFcFont *)(cffont))->is_hinted = _pango_cairo_font_private_is_metrics_hinted (&cffont->cf_priv); - return (PangoFcFont *) (cffont); + return (PangoFcFont *) cffont; } diff --git a/pango/pangocairo-fcfontmap.c b/pango/pangocairo-fcfontmap.c index 5b5c9fb5..bcecb059 100644 --- a/pango/pangocairo-fcfontmap.c +++ b/pango/pangocairo-fcfontmap.c @@ -52,23 +52,11 @@ pango_cairo_fc_font_map_get_resolution_cairo (PangoCairoFontMap *cfontmap) return cffontmap->dpi; } -static PangoRenderer * -pango_cairo_fc_font_map_get_renderer (PangoCairoFontMap *cfontmap) -{ - PangoCairoFcFontMap *cffontmap = (PangoCairoFcFontMap *) (cfontmap); - - if (!cffontmap->renderer) - cffontmap->renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL); - - return cffontmap->renderer; -} - static void cairo_font_map_iface_init (PangoCairoFontMapIface *iface) { iface->set_resolution = pango_cairo_fc_font_map_set_resolution; iface->get_resolution = pango_cairo_fc_font_map_get_resolution_cairo; - iface->get_renderer = pango_cairo_fc_font_map_get_renderer; } G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFontMap, pango_cairo_fc_font_map, PANGO_TYPE_FC_FONT_MAP, diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c index 2595c0ef..5f439998 100644 --- a/pango/pangocairo-font.c +++ b/pango/pangocairo-font.c @@ -29,6 +29,12 @@ PangoCairoWarningHistory _pango_cairo_warning_history = { FALSE }; +#define PANGO_CAIRO_FONT_PRIVATE(font) \ + ((PangoCairoFontPrivate *) \ + (font == NULL ? NULL : \ + G_STRUCT_MEMBER_P (font, \ + PANGO_CAIRO_FONT_GET_IFACE(PANGO_CAIRO_FONT(font))->cf_priv_offset))) + GType pango_cairo_font_get_type (void) { @@ -60,45 +66,86 @@ pango_cairo_font_get_type (void) return cairo_font_type; } -/** - * _pango_cairo_font_install: - * @font: a #PangoCairoFont - * @cr: a #cairo_t - * - * Makes @font the current font for rendering in the specified - * Cairo context. - **/ -gboolean -_pango_cairo_font_install (PangoCairoFont *font, - cairo_t *cr) +static PangoCairoFontPrivateScaledFontData * +_pango_cairo_font_private_scaled_font_data_create (void) +{ + return g_slice_new (PangoCairoFontPrivateScaledFontData); +} + +static void +_pango_cairo_font_private_scaled_font_data_destroy (PangoCairoFontPrivateScaledFontData *data) { - if (G_UNLIKELY (!PANGO_IS_CAIRO_FONT (font))) + cairo_font_options_destroy (data->options); + g_slice_free (PangoCairoFontPrivateScaledFontData, data); +} + +cairo_scaled_font_t * +_pango_cairo_font_private_get_scaled_font (PangoCairoFontPrivate *cf_priv) +{ + cairo_font_face_t *font_face; + + if (G_LIKELY (cf_priv->scaled_font)) + return cf_priv->scaled_font; + + /* need to create it */ + + if (G_UNLIKELY (cf_priv->data == NULL)) + { + /* we have tried to create and failed before */ + return NULL; + } + + font_face = (* PANGO_CAIRO_FONT_GET_IFACE (cf_priv->cfont)->create_font_face) (cf_priv->cfont); + if (G_UNLIKELY (font_face == NULL)) + goto done; + + cf_priv->scaled_font = cairo_scaled_font_create (font_face, + &cf_priv->data->font_matrix, + &cf_priv->data->ctm, + cf_priv->data->options); + + cairo_font_face_destroy (font_face); + +done: + _pango_cairo_font_private_scaled_font_data_destroy (cf_priv->data); + cf_priv->data = NULL; + + if (G_UNLIKELY (cf_priv->scaled_font == NULL || cairo_scaled_font_status (cf_priv->scaled_font) != CAIRO_STATUS_SUCCESS)) { - if (!_pango_cairo_warning_history.font_install) + PangoFont *font = PANGO_FONT (cf_priv->cfont); + static GQuark warned_quark = 0; + if (!warned_quark) + warned_quark = g_quark_from_static_string ("pangocairo-scaledfont-warned"); + + if (!g_object_get_qdata (G_OBJECT (font), warned_quark)) { - _pango_cairo_warning_history.font_install = TRUE; - g_warning ("_pango_cairo_font_install called with bad font, expect ugly output"); - cairo_set_font_face (cr, NULL); + PangoFontDescription *desc; + char *s; + + desc = pango_font_describe (font); + s = pango_font_description_to_string (desc); + pango_font_description_free (desc); + + g_warning ("failed to create cairo %s, expect ugly output. the offending font is '%s'", + font_face ? "scaled font" : "font face", + s); + + g_free (s); + + g_object_set_qdata_full (G_OBJECT (font), warned_quark, + GINT_TO_POINTER (1), NULL); } - return FALSE; } - return (* PANGO_CAIRO_FONT_GET_IFACE (font)->install) (font, cr); + return cf_priv->scaled_font; } -cairo_font_face_t * -_pango_cairo_font_get_font_face (PangoCairoFont *font) +static cairo_scaled_font_t * +_pango_cairo_font_get_scaled_font (PangoFont *cfont) { - g_return_val_if_fail (PANGO_IS_CAIRO_FONT (font), NULL); - /* this function will be removed. don't bother with warning history here */ - - return (* PANGO_CAIRO_FONT_GET_IFACE (font)->get_font_face) (font); -} + PangoCairoFontPrivate *cf_priv; -cairo_scaled_font_t * -_pango_cairo_font_get_scaled_font (PangoCairoFont *font) -{ - if (G_UNLIKELY (!PANGO_IS_CAIRO_FONT (font))) + if (G_UNLIKELY (!PANGO_IS_CAIRO_FONT (cfont))) { if (!_pango_cairo_warning_history.font_get_scaled_font) { @@ -108,27 +155,126 @@ _pango_cairo_font_get_scaled_font (PangoCairoFont *font) return NULL; } - return (* PANGO_CAIRO_FONT_GET_IFACE (font)->get_scaled_font) (font); + cf_priv = PANGO_CAIRO_FONT_PRIVATE (cfont); + + return _pango_cairo_font_private_get_scaled_font (cf_priv); } -static void -_pango_cairo_hex_box_info_destroy (PangoCairoHexBoxInfo *hbi) +/** + * _pango_cairo_font_install: + * @font: a #PangoCairoFont + * @cr: a #cairo_t + * + * Makes @font the current font for rendering in the specified + * Cairo context. + * + * Return value: %TRUE if font was installed successfully, %FALSE otherwise. + **/ +gboolean +_pango_cairo_font_install (PangoFont *font, + cairo_t *cr) { - if (hbi) + cairo_scaled_font_t *scaled_font = _pango_cairo_font_get_scaled_font (font); + + if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)) + return FALSE; + + cairo_set_scaled_font (cr, scaled_font); + + return TRUE; +} + + +typedef struct _PangoCairoFontMetricsInfo +{ + const char *sample_str; + PangoFontMetrics *metrics; +} PangoCairoFontMetricsInfo; + +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) { - g_object_unref (hbi->font); - g_slice_free (PangoCairoHexBoxInfo, hbi); + info = tmp_list->data; + + if (info->sample_str == sample_str) /* We _don't_ need strcmp */ + break; + + tmp_list = tmp_list->next; } + + if (!tmp_list) + { + PangoContext *context; + cairo_font_options_t *font_options; + int height, shift; + + 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_cairo_font_map_create_context ((PangoCairoFontMap *) pango_font_get_font_map (font)); + 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); + } + + return pango_font_metrics_ref (info->metrics); } -PangoCairoHexBoxInfo * -_pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) +static PangoCairoFontHexBoxInfo * +_pango_cairo_font_private_get_hex_box_info (PangoCairoFontPrivate *cf_priv) { static const char hexdigits[] = "0123456789ABCDEF"; char c[2] = {0, 0}; PangoFont *mini_font; - PangoCairoFont *mini_cfont; - PangoCairoHexBoxInfo *hbi; + PangoCairoFontHexBoxInfo *hbi; /* for metrics hinting */ double scale_x = 1., scale_x_inv = 1., scale_y = 1., scale_y_inv = 1.; @@ -148,24 +294,20 @@ _pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) cairo_matrix_t cairo_ctm; PangoGravity gravity; - if (!cfont) + if (!cf_priv) return NULL; - hbi = (PangoCairoHexBoxInfo *) g_object_get_data (G_OBJECT (cfont), "hex_box_info"); - if (hbi) - return hbi; + if (cf_priv->hbi) + return cf_priv->hbi; - scaled_font = _pango_cairo_font_get_scaled_font (cfont); - if (!scaled_font) - { - g_object_set_data_full (G_OBJECT (cfont), "hex_box_info", NULL, NULL); - return NULL; - } + scaled_font = _pango_cairo_font_private_get_scaled_font (cf_priv); + if (G_UNLIKELY (scaled_font == NULL || cairo_scaled_font_status (scaled_font) != CAIRO_STATUS_SUCCESS)) + return NULL; + + is_hinted = cf_priv->is_hinted; font_options = cairo_font_options_create (); - cairo_scaled_font_get_font_options (scaled_font, font_options); - is_hinted = (cairo_font_options_get_hint_metrics(font_options) != CAIRO_HINT_METRICS_OFF); - desc = pango_font_describe_with_absolute_size ((PangoFont *)cfont); + desc = pango_font_describe_with_absolute_size ((PangoFont *)cf_priv->cfont); size = pango_font_description_get_size (desc) / (1.*PANGO_SCALE); gravity = pango_font_description_get_gravity (desc); @@ -208,7 +350,7 @@ _pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) PangoContext *context; PangoFontMap *fontmap; - fontmap = pango_font_get_font_map ((PangoFont *)cfont); + fontmap = pango_font_get_font_map ((PangoFont *)cf_priv->cfont); /* we inherit most font properties for the mini font. just * change family and size. means, you get bold hex digits @@ -233,8 +375,7 @@ _pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) } } - pango_font_description_set_absolute_size (desc, mini_size * PANGO_SCALE); - + pango_font_description_set_absolute_size (desc, pango_units_from_double (mini_size)); /* load mini_font */ @@ -251,8 +392,7 @@ _pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) cairo_font_options_destroy (font_options); - mini_cfont = (PangoCairoFont *) mini_font; - scaled_mini_font = _pango_cairo_font_get_scaled_font (mini_cfont); + scaled_mini_font = _pango_cairo_font_get_scaled_font (mini_font); for (i = 0 ; i < 16 ; i++) { @@ -274,8 +414,8 @@ _pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) pad = (font_extents.ascent + font_extents.descent) / 43; pad = MIN (pad, mini_size); - hbi = g_slice_new (PangoCairoHexBoxInfo); - hbi->font = mini_font; + hbi = g_slice_new (PangoCairoFontHexBoxInfo); + hbi->font = (PangoCairoFont *) mini_font; hbi->rows = rows; hbi->digit_width = width; @@ -314,21 +454,114 @@ _pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont) hbi->box_descent = HINT_Y (hbi->box_descent); } - g_object_set_data_full (G_OBJECT (cfont), "hex_box_info", hbi, (GDestroyNotify)_pango_cairo_hex_box_info_destroy); - 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 void +free_metrics_info (PangoCairoFontMetricsInfo *info) +{ + pango_font_metrics_unref (info->metrics); + g_slice_free (PangoCairoFontMetricsInfo, info); +} + void -_pango_cairo_get_glyph_extents_missing (PangoCairoFont *cfont, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect) +_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) { - PangoCairoHexBoxInfo *hbi; + PangoCairoFontHexBoxInfo *hbi; gint rows, cols; - hbi = _pango_cairo_font_get_hex_box_info (cfont); + hbi = _pango_cairo_font_private_get_hex_box_info (cf_priv); if (!hbi) { pango_font_get_glyph_extents (NULL, glyph, ink_rect, logical_rect); @@ -355,3 +588,142 @@ _pango_cairo_get_glyph_extents_missing (PangoCairoFont *cfont, } } +#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 void +compute_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; + } +} diff --git a/pango/pangocairo-fontmap.c b/pango/pangocairo-fontmap.c index 57540cd8..e16579e2 100644 --- a/pango/pangocairo-fontmap.c +++ b/pango/pangocairo-fontmap.c @@ -181,19 +181,3 @@ pango_cairo_font_map_create_context (PangoCairoFontMap *fontmap) return context; } - -/** - * _pango_cairo_font_map_get_renderer: - * @fontmap: a #PangoCairoFontmap - * - * Gets the singleton #PangoCairoRenderer for this fontmap. - * - * Return value: the singleton renderer - **/ -PangoRenderer * -_pango_cairo_font_map_get_renderer (PangoCairoFontMap *fontmap) -{ - g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), NULL); - - return (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->get_renderer) (fontmap); -} diff --git a/pango/pangocairo-private.h b/pango/pangocairo-private.h index d739abff..e5a7c382 100644 --- a/pango/pangocairo-private.h +++ b/pango/pangocairo-private.h @@ -27,6 +27,7 @@ G_BEGIN_DECLS + #define PANGO_CAIRO_FONT_MAP_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PANGO_TYPE_CAIRO_FONT_MAP, PangoCairoFontMapIface)) typedef struct _PangoCairoFontMapIface PangoCairoFontMapIface; @@ -38,10 +39,8 @@ struct _PangoCairoFontMapIface void (*set_resolution) (PangoCairoFontMap *fontmap, double dpi); double (*get_resolution) (PangoCairoFontMap *fontmap); - PangoRenderer *(*get_renderer) (PangoCairoFontMap *fontmap); }; -PangoRenderer *_pango_cairo_font_map_get_renderer (PangoCairoFontMap *cfontmap); #define PANGO_CAIRO_FONT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PANGO_TYPE_CAIRO_FONT, PangoCairoFontIface)) @@ -49,27 +48,82 @@ PangoRenderer *_pango_cairo_font_map_get_renderer (PangoCairoFontMap *cfontmap); #define PANGO_CAIRO_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FONT, PangoCairoFont)) #define PANGO_IS_CAIRO_FONT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_FONT)) -typedef struct _PangoCairoFont PangoCairoFont; -typedef struct _PangoCairoFontIface PangoCairoFontIface; +typedef struct _PangoCairoFont PangoCairoFont; +typedef struct _PangoCairoFontIface PangoCairoFontIface; +typedef struct _PangoCairoFontPrivate PangoCairoFontPrivate; +typedef struct _PangoCairoFontHexBoxInfo PangoCairoFontHexBoxInfo; +typedef struct _PangoCairoFontPrivateScaledFontData PangoCairoFontPrivateScaledFontData; +typedef struct _PangoCairoFontGlyphExtentsCacheEntry PangoCairoFontGlyphExtentsCacheEntry; + +struct _PangoCairoFontHexBoxInfo +{ + PangoCairoFont *font; + int rows; + double digit_width; + double digit_height; + double pad_x; + double pad_y; + double line_width; + double box_descent; + double box_height; +}; + +struct _PangoCairoFontPrivateScaledFontData +{ + cairo_matrix_t font_matrix; + cairo_matrix_t ctm; + cairo_font_options_t *options; +}; + +struct _PangoCairoFontPrivate +{ + PangoCairoFont *cfont; + + PangoCairoFontPrivateScaledFontData *data; + + cairo_scaled_font_t *scaled_font; + PangoCairoFontHexBoxInfo *hbi; + + gboolean is_hinted; + PangoGravity gravity; + + PangoRectangle font_extents; + PangoCairoFontGlyphExtentsCacheEntry *glyph_extents_cache; + + GSList *metrics_by_lang; +}; struct _PangoCairoFontIface { GTypeInterface g_iface; - gboolean (*install) (PangoCairoFont *font, - cairo_t *cr); + cairo_font_face_t *(*create_font_face) (PangoCairoFont *cfont); + PangoFontMetrics *(*create_metrics_for_context) (PangoCairoFont *cfont, + PangoContext *context); - cairo_font_face_t *(*get_font_face) (PangoCairoFont *font); - - cairo_scaled_font_t *(*get_scaled_font) (PangoCairoFont *font); + gssize cf_priv_offset; }; GType pango_cairo_font_get_type (void); -gboolean _pango_cairo_font_install (PangoCairoFont *font, - cairo_t *cr); -cairo_font_face_t *_pango_cairo_font_get_font_face (PangoCairoFont *font); -cairo_scaled_font_t *_pango_cairo_font_get_scaled_font (PangoCairoFont *font); +gboolean _pango_cairo_font_install (PangoFont *font, + cairo_t *cr); +PangoFontMetrics * _pango_cairo_font_get_metrics (PangoFont *font, + PangoLanguage *language); +PangoCairoFontHexBoxInfo *_pango_cairo_font_get_hex_box_info (PangoCairoFont *cfont); + +void _pango_cairo_font_private_initialize (PangoCairoFontPrivate *cf_priv, + PangoCairoFont *font, + PangoContext *context, + const PangoFontDescription *desc, + const cairo_matrix_t *font_matrix); +void _pango_cairo_font_private_finalize (PangoCairoFontPrivate *cf_priv); +cairo_scaled_font_t *_pango_cairo_font_private_get_scaled_font (PangoCairoFontPrivate *cf_priv); +gboolean _pango_cairo_font_private_is_metrics_hinted (PangoCairoFontPrivate *cf_priv); +void _pango_cairo_font_private_get_glyph_extents (PangoCairoFontPrivate *cf_priv, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect); #define PANGO_TYPE_CAIRO_RENDERER (pango_cairo_renderer_get_type()) #define PANGO_CAIRO_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_RENDERER, PangoCairoRenderer)) @@ -79,35 +133,13 @@ typedef struct _PangoCairoRenderer PangoCairoRenderer; GType pango_cairo_renderer_get_type (void); -const cairo_font_options_t *_pango_cairo_context_get_merged_font_options (PangoContext *context); - -typedef struct _PangoCairoHexBoxInfo PangoCairoHexBoxInfo; - -struct _PangoCairoHexBoxInfo -{ - PangoFont *font; - int rows; - double digit_width; - double digit_height; - double pad_x; - double pad_y; - double line_width; - double box_descent; - double box_height; -}; - -PangoCairoHexBoxInfo *_pango_cairo_font_get_hex_box_info (PangoCairoFont *font); +const cairo_font_options_t *_pango_cairo_context_get_merged_font_options (PangoContext *context); -void _pango_cairo_get_glyph_extents_missing (PangoCairoFont *cfont, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect); typedef struct _PangoCairoWarningHistory PangoCairoWarningHistory; struct _PangoCairoWarningHistory { - guint font_install : 1; guint font_get_scaled_font : 1; }; diff --git a/pango/pangocairo-render.c b/pango/pangocairo-render.c index 4c0baf29..d14d980d 100644 --- a/pango/pangocairo-render.c +++ b/pango/pangocairo-render.c @@ -128,7 +128,7 @@ _pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer, int rows, cols; char hexbox_string[2] = {0, 0}; double temp_x, temp_y; - PangoCairoHexBoxInfo *hbi; + PangoCairoFontHexBoxInfo *hbi; gunichar ch; cairo_save (crenderer->cr); @@ -136,7 +136,7 @@ _pango_cairo_renderer_draw_unknown_glyph (PangoCairoRenderer *crenderer, hbi = _pango_cairo_font_get_hex_box_info ((PangoCairoFont *)font); - if (!hbi || !_pango_cairo_font_install ((PangoCairoFont *) (hbi->font), crenderer->cr)) + if (!hbi || !_pango_cairo_font_install ((PangoFont *)(hbi->font), crenderer->cr)) { _pango_cairo_renderer_draw_box_glyph (crenderer, gi, cx, cy); goto done; @@ -204,7 +204,7 @@ pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer, if (!crenderer->do_path) set_color (crenderer, PANGO_RENDER_PART_FOREGROUND); - if (!_pango_cairo_font_install ((PangoCairoFont *) (font), crenderer->cr)) + if (!_pango_cairo_font_install (font, crenderer->cr)) { for (i = 0; i < glyphs->num_glyphs; i++) { @@ -455,8 +455,6 @@ acquire_renderer (gboolean *free_renderer) { PangoCairoRenderer *renderer; - /* renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap)); */ - if (G_LIKELY (G_TRYLOCK (cached_renderer))) { if (G_UNLIKELY (!cached_renderer)) |