diff options
Diffstat (limited to 'pango/pangocairo-atsuifont.c')
-rw-r--r-- | pango/pangocairo-atsuifont.c | 282 |
1 files changed, 52 insertions, 230 deletions
diff --git a/pango/pangocairo-atsuifont.c b/pango/pangocairo-atsuifont.c index a5501439..e477a036 100644 --- a/pango/pangocairo-atsuifont.c +++ b/pango/pangocairo-atsuifont.c @@ -33,18 +33,12 @@ struct _PangoCairoATSUIFont { PangoATSUIFont font; + PangoCairoFontPrivate cf_priv; ATSUFontID font_id; - 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; double size; int absolute_size; - - GSList *metrics_by_lang; }; struct _PangoCairoATSUIFontClass @@ -54,7 +48,10 @@ struct _PangoCairoATSUIFontClass -static cairo_font_face_t *pango_cairo_atsui_font_get_font_face (PangoCairoFont *font); +static cairo_font_face_t *pango_cairo_atsui_font_create_font_face (PangoCairoFont *font); +static PangoFontMetrics *pango_cairo_atsui_font_create_metrics_for_context (PangoCairoFont *font, + PangoContext *context); + /** * pango_cairo_atsui_font_get_atsu_font_id: @@ -72,137 +69,40 @@ pango_cairo_atsui_font_get_atsu_font_id (PangoCairoATSUIFont *cafont) return cafont->font_id; } -static gboolean -pango_cairo_atsui_font_install (PangoCairoFont *font, - cairo_t *cr) -{ - PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font); - - cairo_set_font_face (cr, - pango_cairo_atsui_font_get_font_face (font)); - - cairo_set_font_matrix (cr, &cafont->font_matrix); - cairo_set_font_options (cr, cafont->options); - - return TRUE; -} - -static cairo_font_face_t * -pango_cairo_atsui_font_get_font_face (PangoCairoFont *font) -{ - PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font); - - if (!cafont->font_face) - { - cafont->font_face = cairo_atsui_font_face_create_for_atsu_font_id (cafont->font_id); - - /* Failure of the above should only occur for out of memory, - * we can't proceed at that point - */ - if (!cafont->font_face) - g_error ("Unable to create ATSUI cairo font face.\nThis means out of memory or a cairo/fontconfig/FreeType bug"); - } - - return cafont->font_face; -} - -static cairo_scaled_font_t * -pango_cairo_atsui_font_get_scaled_font (PangoCairoFont *font) -{ - PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font); - - if (!cafont->scaled_font) - { - cairo_font_face_t *font_face; - - font_face = pango_cairo_atsui_font_get_font_face (font); - cafont->scaled_font = cairo_scaled_font_create (font_face, - &cafont->font_matrix, - &cafont->ctm, - cafont->options); - - /* Failure of the above should only occur for out of memory, - * we can't proceed at that point - */ - if (!cafont->scaled_font) - g_error ("Unable to create ATSUI cairo scaled font.\nThis means out of memory or a cairo/fontconfig/FreeType bug"); - } - - return cafont->scaled_font; -} - static void cairo_font_iface_init (PangoCairoFontIface *iface) { - iface->install = pango_cairo_atsui_font_install; - iface->get_font_face = pango_cairo_atsui_font_get_font_face; - iface->get_scaled_font = pango_cairo_atsui_font_get_scaled_font; + iface->create_font_face = pango_cairo_atsui_font_create_font_face; + iface->create_metrics_for_context = pango_cairo_atsui_font_create_metrics_for_context; + iface->cf_priv_offset = G_STRUCT_OFFSET (PangoCairoATSUIFont, cf_priv); } G_DEFINE_TYPE_WITH_CODE (PangoCairoATSUIFont, pango_cairo_atsui_font, PANGO_TYPE_ATSUI_FONT, { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) }); +/* 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_atsui_font_get_glyph_extents (PangoFont *font, - PangoGlyph glyph, - PangoRectangle *ink_rect, - PangoRectangle *logical_rect) +pango_cairo_atsui_font_get_glyph_extents (PangoFont *font, + PangoGlyph glyph, + PangoRectangle *ink_rect, + PangoRectangle *logical_rect) { - PangoCairoFont *cfont = (PangoCairoFont *)font; - cairo_scaled_font_t *scaled_font; - cairo_font_extents_t font_extents; - cairo_text_extents_t extents; - cairo_glyph_t cairo_glyph; - - scaled_font = pango_cairo_atsui_font_get_scaled_font (PANGO_CAIRO_FONT (font)); - - if (logical_rect) - cairo_scaled_font_extents (scaled_font, &font_extents); - - cairo_glyph.index = glyph; - cairo_glyph.x = 0; - cairo_glyph.y = 0; + PangoCairoATSUIFont *cafont = (PangoCairoATSUIFont *) (font); - 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->x = 0; - logical_rect->y = - font_extents.ascent * PANGO_SCALE; - logical_rect->width = 0; - logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE; - } - } - else if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - { - /* space for the hex box */ - _pango_cairo_get_glyph_extents_missing(cfont, glyph, ink_rect, logical_rect); - } - else - { - cairo_scaled_font_glyph_extents (scaled_font, - &cairo_glyph, 1, &extents); + _pango_cairo_font_private_get_glyph_extents (&cafont->cf_priv, + glyph, + ink_rect, + logical_rect); +} - if (ink_rect) - { - ink_rect->x = extents.x_bearing * PANGO_SCALE; - ink_rect->y = extents.y_bearing * PANGO_SCALE; - ink_rect->width = extents.width * PANGO_SCALE; - ink_rect->height = extents.height * PANGO_SCALE; - } +static cairo_font_face_t * +pango_cairo_atsui_font_create_font_face (PangoCairoFont *font) +{ + PangoCairoATSUIFont *cafont = (PangoCairoATSUIFont *) (font); - if (logical_rect) - { - logical_rect->x = 0; - logical_rect->y = - font_extents.ascent * PANGO_SCALE; - logical_rect->width = extents.x_advance * PANGO_SCALE; - logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE; - } - } + return cairo_atsui_font_face_create_for_atsu_font_id (cafont->font_id); } static int @@ -230,10 +130,10 @@ max_glyph_width (PangoLayout *layout) } static PangoFontMetrics * -create_metrics_for_context (PangoFont *font, - PangoContext *context) +pango_cairo_atsui_font_create_metrics_for_context (PangoCairoFont *font, + PangoContext *context) { - PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font); + PangoCairoATSUIFont *cafont = (PangoCairoATSUIFont *) font; ATSFontRef ats_font; ATSFontMetrics ats_metrics; PangoFontMetrics *metrics; @@ -259,7 +159,7 @@ create_metrics_for_context (PangoFont *font, metrics->strikethrough_thickness = ats_metrics.underlineThickness * cafont->size * PANGO_SCALE; layout = pango_layout_new (context); - font_desc = pango_font_describe_with_absolute_size (font); + font_desc = pango_font_describe_with_absolute_size ((PangoFont *) font); pango_layout_set_font_description (layout, font_desc); pango_layout_set_text (layout, sample_str, -1); pango_layout_get_extents (layout, NULL, &extents); @@ -275,65 +175,12 @@ create_metrics_for_context (PangoFont *font, return metrics; } -typedef struct -{ - const char *sample_str; - PangoFontMetrics *metrics; -} PangoATSUIMetricsInfo; - -static PangoFontMetrics * -pango_cairo_atsui_font_get_metrics (PangoFont *font, - PangoLanguage *language) -{ - PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font); - PangoATSUIMetricsInfo *info; - GSList *tmp_list; - const char *sample_str = pango_language_get_sample_string (language); - - tmp_list = cafont->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; - - if (!pango_font_get_font_map (font)) - return pango_font_metrics_new (); - - info = g_slice_new0 (PangoATSUIMetricsInfo); - - cafont->metrics_by_lang = g_slist_prepend (cafont->metrics_by_lang, - info); - - info->sample_str = sample_str; - - context = pango_context_new (); - pango_context_set_font_map (context, pango_font_get_font_map (font)); - pango_context_set_language (context, language); - pango_cairo_context_set_font_options (context, cafont->options); - - info->metrics = create_metrics_for_context (font, context); - - g_object_unref (context); - } - - return pango_font_metrics_ref (info->metrics); -} - static PangoFontDescription * pango_cairo_atsui_font_describe_absolute (PangoFont *font) { PangoFontDescription *desc; - PangoATSUIFont *afont = PANGO_ATSUI_FONT (font); - PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (font); + PangoATSUIFont *afont = (PangoATSUIFont *) font; + PangoCairoATSUIFont *cafont = (PangoCairoATSUIFont *) font; desc = pango_font_description_copy (afont->desc); pango_font_description_set_absolute_size (desc, cafont->absolute_size); @@ -342,24 +189,8 @@ pango_cairo_atsui_font_describe_absolute (PangoFont *font) } static void -free_metrics_info (PangoATSUIMetricsInfo *info) -{ - pango_font_metrics_unref (info->metrics); - g_slice_free (PangoATSUIMetricsInfo, info); -} - -static void pango_cairo_atsui_font_finalize (GObject *object) { - PangoCairoATSUIFont *cafont = PANGO_CAIRO_ATSUI_FONT (object); - - g_slist_foreach (cafont->metrics_by_lang, (GFunc)free_metrics_info, NULL); - g_slist_free (cafont->metrics_by_lang); - - cairo_font_face_destroy (cafont->font_face); - cairo_scaled_font_destroy (cafont->scaled_font); - cairo_font_options_destroy (cafont->options); - G_OBJECT_CLASS (pango_cairo_atsui_font_parent_class)->finalize (object); } @@ -371,8 +202,8 @@ pango_cairo_atsui_font_class_init (PangoCairoATSUIFontClass *class) object_class->finalize = pango_cairo_atsui_font_finalize; - font_class->get_metrics = pango_cairo_atsui_font_get_metrics; font_class->get_glyph_extents = pango_cairo_atsui_font_get_glyph_extents; + font_class->get_metrics = _pango_cairo_font_get_metrics; font_class->describe_absolute = pango_cairo_atsui_font_describe_absolute; } @@ -393,9 +224,10 @@ _pango_cairo_atsui_font_new (PangoCairoATSUIFontMap *cafontmap, PangoATSUIFont *afont; CFStringRef cfstr; ATSFontRef font_ref; - const PangoMatrix *pango_ctm; ATSUFontID font_id; + double size; double dpi; + cairo_matrix_t font_matrix; postscript_name = _pango_atsui_face_get_postscript_name (face); @@ -415,7 +247,6 @@ _pango_cairo_atsui_font_new (PangoCairoATSUIFontMap *cafontmap, NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSString *nsname; NSFont *nsfont, *converted_font; - gdouble size; size = (double) pango_font_description_get_size (desc) / PANGO_SCALE; @@ -447,7 +278,7 @@ _pango_cairo_atsui_font_new (PangoCairoATSUIFontMap *cafontmap, afont->desc = pango_font_description_copy (desc); afont->face = face; - cafont->size = (double) pango_font_description_get_size (desc) / PANGO_SCALE; + size = (double) pango_font_description_get_size (desc) / PANGO_SCALE; cafont->font_id = font_id; if (context) @@ -463,35 +294,26 @@ _pango_cairo_atsui_font_new (PangoCairoATSUIFontMap *cafontmap, cafont->absolute_size = pango_font_description_get_size (desc); if (!pango_font_description_get_size_is_absolute (desc)) - cafont->size *= dpi / 72.; - - cairo_matrix_init_scale (&cafont->font_matrix, cafont->size, cafont->size); - pango_ctm = pango_context_get_matrix (context); - if (pango_ctm) - cairo_matrix_init (&cafont->ctm, - pango_ctm->xx, - pango_ctm->yx, - pango_ctm->xy, - pango_ctm->yy, - 0., 0.); - else - cairo_matrix_init_identity (&cafont->ctm); + size *= dpi / 72.; - if (synthesize_italic) - { - cairo_matrix_t shear, result; + cafont->size = size; - /* Apply a shear matrix, matching what Cocoa does. */ - cairo_matrix_init (&shear, - 1, 0, - 0.25, 1, - 0, 0); + /* If necessary, apply a shear matrix, matching what Cocoa does. */ + if (synthesize_italic) + cairo_matrix_init (&font_matrix, + 1, 0, + 0.25, 1, + 0, 0); + else + cairo_matrix_init_identity (&font_matrix); - cairo_matrix_multiply (&result, &shear, &cafont->font_matrix); - cafont->font_matrix = result; - } + cairo_matrix_scale (&font_matrix, size, size); - cafont->options = cairo_font_options_copy (_pango_cairo_context_get_merged_font_options (context)); + _pango_cairo_font_private_initialize (&cafont->cf_priv, + (PangoCairoFont *) cafont, + context, + desc, + &font_matrix); return afont; } |