/* Pango * pangocairo-coretextfont.c * * Copyright (C) 2000-2005 Red Hat Software * Copyright (C) 2005-2007 Imendio AB * Copyright (C) 2010 Kristian Rietveld * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ #include "config.h" #include #include "pango-impl-utils.h" #include "pangocoretext-private.h" #include "pangocairo.h" #include "pangocairo-private.h" #include "pangocairo-coretext.h" #include "pangocairo-coretextfont.h" struct _PangoCairoCoreTextFont { PangoCoreTextFont font; PangoCairoFontPrivate cf_priv; int abs_size; }; struct _PangoCairoCoreTextFontClass { PangoCoreTextFontClass parent_class; }; static cairo_font_face_t *pango_cairo_core_text_font_create_font_face (PangoCairoFont *font); static PangoFontMetrics *pango_cairo_core_text_font_create_base_metrics_for_context (PangoCairoFont *font, PangoContext *context); static void cairo_font_iface_init (PangoCairoFontIface *iface) { iface->create_font_face = pango_cairo_core_text_font_create_font_face; iface->create_base_metrics_for_context = pango_cairo_core_text_font_create_base_metrics_for_context; iface->cf_priv_offset = G_STRUCT_OFFSET (PangoCairoCoreTextFont, cf_priv); } G_DEFINE_TYPE_WITH_CODE (PangoCairoCoreTextFont, pango_cairo_core_text_font, PANGO_TYPE_CORE_TEXT_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_core_text_font_get_glyph_extents (PangoFont *font, PangoGlyph glyph, PangoRectangle *ink_rect, PangoRectangle *logical_rect) { PangoCairoCoreTextFont *cafont = (PangoCairoCoreTextFont *) (font); _pango_cairo_font_private_get_glyph_extents (&cafont->cf_priv, glyph, ink_rect, logical_rect); } static cairo_font_face_t * pango_cairo_core_text_font_create_font_face (PangoCairoFont *font) { PangoCoreTextFont *ctfont = (PangoCoreTextFont *) (font); CTFontRef font_id; CGFontRef cgfont; cairo_font_face_t *cairo_face; font_id = pango_core_text_font_get_ctfont (ctfont); cgfont = CTFontCopyGraphicsFont (font_id, NULL); cairo_face = cairo_quartz_font_face_create_for_cgfont (cgfont); CFRelease (cgfont); return cairo_face; } static PangoFontMetrics * pango_cairo_core_text_font_create_base_metrics_for_context (PangoCairoFont *font, PangoContext *context) { PangoCoreTextFont *cfont = (PangoCoreTextFont *) font; PangoFontMetrics *metrics; CTFontRef ctfont; metrics = pango_font_metrics_new (); ctfont = pango_core_text_font_get_ctfont (cfont); metrics->ascent = CTFontGetAscent (ctfont) * PANGO_SCALE; metrics->descent = CTFontGetDescent (ctfont) * PANGO_SCALE; metrics->height = (CTFontGetAscent (ctfont) + CTFontGetDescent (ctfont) + CTFontGetLeading (ctfont)) * PANGO_SCALE; metrics->underline_position = CTFontGetUnderlinePosition (ctfont) * PANGO_SCALE; metrics->underline_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE; metrics->strikethrough_position = metrics->ascent / 3; metrics->strikethrough_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE; return metrics; } static PangoFontDescription * pango_cairo_core_text_font_describe_absolute (PangoFont *font) { PangoCairoCoreTextFont *cafont = (PangoCairoCoreTextFont *)font; PangoFontDescription *desc = pango_font_describe (font); pango_font_description_set_absolute_size (desc, cafont->abs_size); return desc; } static void pango_cairo_core_text_font_finalize (GObject *object) { PangoCairoCoreTextFont *cafont = (PangoCairoCoreTextFont *) object; _pango_cairo_font_private_finalize (&cafont->cf_priv); G_OBJECT_CLASS (pango_cairo_core_text_font_parent_class)->finalize (object); } static void pango_cairo_core_text_font_class_init (PangoCairoCoreTextFontClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); PangoFontClass *font_class = PANGO_FONT_CLASS (class); object_class->finalize = pango_cairo_core_text_font_finalize; /* font_class->describe defined by parent class PangoCoreTextFont. */ font_class->get_glyph_extents = pango_cairo_core_text_font_get_glyph_extents; font_class->get_metrics = _pango_cairo_font_get_metrics; font_class->describe_absolute = pango_cairo_core_text_font_describe_absolute; } static void pango_cairo_core_text_font_init (PangoCairoCoreTextFont *cafont G_GNUC_UNUSED) { } PangoCoreTextFont * _pango_cairo_core_text_font_new (PangoCairoCoreTextFontMap *cafontmap, PangoCoreTextFontKey *key) { gboolean synthesize_italic = FALSE; PangoCairoCoreTextFont *cafont; PangoCoreTextFont *cfont; CTFontRef font_ref; CTFontDescriptorRef ctdescriptor; CGFontRef font_id; double size; cairo_matrix_t font_matrix; size = pango_units_to_double (pango_core_text_font_key_get_size (key)); size /= pango_matrix_get_font_scale_factor (pango_core_text_font_key_get_matrix (key)); ctdescriptor = pango_core_text_font_key_get_ctfontdescriptor (key); font_ref = CTFontCreateWithFontDescriptor (ctdescriptor, size, NULL); if (pango_core_text_font_key_get_synthetic_italic (key)) synthesize_italic = TRUE; font_id = CTFontCopyGraphicsFont (font_ref, NULL); if (!font_id) return NULL; cafont = g_object_new (PANGO_TYPE_CAIRO_CORE_TEXT_FONT, NULL); cfont = PANGO_CORE_TEXT_FONT (cafont); cafont->abs_size = pango_core_text_font_key_get_size (key); _pango_core_text_font_set_ctfont (cfont, font_ref); if (synthesize_italic) cairo_matrix_init (&font_matrix, 1, 0, -0.25, 1, 0, 0); else cairo_matrix_init_identity (&font_matrix); cairo_matrix_scale (&font_matrix, size, size); _pango_cairo_font_private_initialize (&cafont->cf_priv, (PangoCairoFont *) cafont, pango_core_text_font_key_get_gravity (key), pango_core_text_font_key_get_context_key (key), pango_core_text_font_key_get_matrix (key), &font_matrix); return cfont; }