2 * pangocairowin32-font.c: Cairo font handling, Win32 backend
4 * Copyright (C) 2000-2005 Red Hat Software
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public
17 * License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
28 #include "pango-fontmap.h"
29 #include "pango-impl-utils.h"
30 #include "pangocairo-private.h"
31 #include "pangocairo-win32.h"
33 #include <cairo-win32.h>
35 #define PANGO_TYPE_CAIRO_WIN32_FONT (pango_cairo_win32_font_get_type ())
36 #define PANGO_CAIRO_WIN32_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_WIN32_FONT, PangoCairoWin32Font))
37 #define PANGO_CAIRO_WIN32_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_WIN32_FONT, PangoCairoWin32FontClass))
38 #define PANGO_CAIRO_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_WIN32_FONT))
39 #define PANGO_CAIRO_WIN32_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_WIN32_FONT, PangoCairoWin32FontClass))
41 typedef struct _PangoCairoWin32Font PangoCairoWin32Font;
42 typedef struct _PangoCairoWin32FontClass PangoCairoWin32FontClass;
44 struct _PangoCairoWin32Font
47 PangoCairoFontPrivate cf_priv;
50 struct _PangoCairoWin32FontClass
52 PangoWin32FontClass parent_class;
55 GType pango_cairo_win32_font_get_type (void);
57 static cairo_font_face_t *pango_cairo_win32_font_create_font_face (PangoCairoFont *font);
58 static PangoFontMetrics *pango_cairo_win32_font_create_base_metrics_for_context (PangoCairoFont *font,
59 PangoContext *context);
63 cairo_font_iface_init (PangoCairoFontIface *iface)
65 iface->create_font_face = pango_cairo_win32_font_create_font_face;
66 iface->create_base_metrics_for_context = pango_cairo_win32_font_create_base_metrics_for_context;
67 iface->cf_priv_offset = G_STRUCT_OFFSET (PangoCairoWin32Font, cf_priv);
70 G_DEFINE_TYPE_WITH_CODE (PangoCairoWin32Font, pango_cairo_win32_font, PANGO_TYPE_WIN32_FONT,
71 { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) });
73 static cairo_font_face_t *
74 pango_cairo_win32_font_create_font_face (PangoCairoFont *font)
76 PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
77 PangoWin32Font *win32font = &cwfont->font;
79 return cairo_win32_font_face_create_for_logfontw (&win32font->logfontw);
83 max_glyph_width (PangoLayout *layout)
88 for (l = pango_layout_get_lines_readonly (layout); l; l = l->next)
90 PangoLayoutLine *line = l->data;
92 for (r = line->runs; r; r = r->next)
94 PangoGlyphString *glyphs = ((PangoGlyphItem *)r->data)->glyphs;
97 for (i = 0; i < glyphs->num_glyphs; i++)
98 if (glyphs->glyphs[i].geometry.width > max_width)
99 max_width = glyphs->glyphs[i].geometry.width;
106 static PangoFontMetrics *
107 pango_cairo_win32_font_create_base_metrics_for_context (PangoCairoFont *font,
108 PangoContext *context)
110 PangoFontMetrics *metrics;
111 cairo_scaled_font_t *scaled_font;
112 cairo_font_extents_t font_extents;
115 metrics = pango_font_metrics_new ();
117 scaled_font = pango_cairo_font_get_scaled_font ((PangoFont *) font);
119 cairo_scaled_font_extents (scaled_font, &font_extents);
120 cairo_win32_scaled_font_done_font (scaled_font);
122 metrics->ascent = font_extents.ascent * PANGO_SCALE;
123 metrics->descent = font_extents.descent * PANGO_SCALE;
125 /* FIXME: Should get the real settings for these from the TrueType
128 height = metrics->ascent + metrics->descent;
129 metrics->underline_thickness = height / 14;
130 metrics->underline_position = - metrics->underline_thickness;
131 metrics->strikethrough_thickness = metrics->underline_thickness;
132 metrics->strikethrough_position = height / 4;
134 pango_quantize_line_geometry (&metrics->underline_thickness,
135 &metrics->underline_position);
136 pango_quantize_line_geometry (&metrics->strikethrough_thickness,
137 &metrics->strikethrough_position);
138 /* Quantizing may have pushed underline_position to 0. Not good */
139 if (metrics->underline_position == 0)
140 metrics->underline_position = - metrics->underline_thickness;
146 pango_cairo_win32_font_finalize (GObject *object)
148 PangoCairoWin32Font *cwfont = (PangoCairoWin32Font *) object;
150 _pango_cairo_font_private_finalize (&cwfont->cf_priv);
152 G_OBJECT_CLASS (pango_cairo_win32_font_parent_class)->finalize (object);
156 pango_cairo_win32_font_get_glyph_extents (PangoFont *font,
158 PangoRectangle *ink_rect,
159 PangoRectangle *logical_rect)
161 PangoCairoWin32Font *cwfont = (PangoCairoWin32Font *) font;
163 _pango_cairo_font_private_get_glyph_extents (&cwfont->cf_priv,
170 pango_cairo_win32_font_select_font (PangoFont *font,
173 cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&PANGO_CAIRO_WIN32_FONT (font)->cf_priv);
175 return cairo_win32_scaled_font_select_font (scaled_font, hdc) == CAIRO_STATUS_SUCCESS;
179 pango_cairo_win32_font_done_font (PangoFont *font)
181 cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&PANGO_CAIRO_WIN32_FONT (font)->cf_priv);
183 cairo_win32_scaled_font_done_font (scaled_font);
187 pango_cairo_win32_font_get_metrics_factor (PangoFont *font)
189 PangoWin32Font *win32font = PANGO_WIN32_FONT (font);
190 cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&PANGO_CAIRO_WIN32_FONT (font)->cf_priv);
192 return cairo_win32_scaled_font_get_metrics_factor (scaled_font) * win32font->size;
196 pango_cairo_win32_font_class_init (PangoCairoWin32FontClass *class)
198 GObjectClass *object_class = G_OBJECT_CLASS (class);
199 PangoFontClass *font_class = PANGO_FONT_CLASS (class);
200 PangoWin32FontClass *win32_font_class = PANGO_WIN32_FONT_CLASS (class);
202 object_class->finalize = pango_cairo_win32_font_finalize;
204 font_class->get_glyph_extents = pango_cairo_win32_font_get_glyph_extents;
205 font_class->get_metrics = _pango_cairo_font_get_metrics;
207 win32_font_class->select_font = pango_cairo_win32_font_select_font;
208 win32_font_class->done_font = pango_cairo_win32_font_done_font;
209 win32_font_class->get_metrics_factor = pango_cairo_win32_font_get_metrics_factor;
213 pango_cairo_win32_font_init (PangoCairoWin32Font *cwfont G_GNUC_UNUSED)
217 /********************
219 ********************/
222 _pango_cairo_win32_font_new (PangoCairoWin32FontMap *cwfontmap,
223 PangoContext *context,
224 PangoWin32Face *face,
225 const PangoFontDescription *desc)
227 PangoCairoWin32Font *cwfont;
228 PangoWin32Font *win32font;
231 #define USE_FACE_CACHED_FONTS
232 #ifdef USE_FACE_CACHED_FONTS
233 PangoWin32FontMap *win32fontmap;
236 cairo_matrix_t font_matrix;
238 g_return_val_if_fail (PANGO_IS_CAIRO_WIN32_FONT_MAP (cwfontmap), NULL);
240 size = (double) pango_font_description_get_size (desc) / PANGO_SCALE;
244 dpi = pango_cairo_context_get_resolution (context);
247 dpi = cwfontmap->dpi;
250 dpi = cwfontmap->dpi;
252 if (!pango_font_description_get_size_is_absolute (desc))
255 #ifdef USE_FACE_CACHED_FONTS
256 win32fontmap = PANGO_WIN32_FONT_MAP (cwfontmap);
258 tmp_list = face->cached_fonts;
261 win32font = tmp_list->data;
262 if (ABS (win32font->size - size * PANGO_SCALE) < 2)
264 g_object_ref (win32font);
265 if (win32font->in_cache)
266 _pango_win32_fontmap_cache_remove (PANGO_FONT_MAP (win32fontmap), win32font);
268 return PANGO_FONT (win32font);
270 tmp_list = tmp_list->next;
273 cwfont = g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT, NULL);
274 win32font = PANGO_WIN32_FONT (cwfont);
276 g_assert (win32font->fontmap == NULL);
277 win32font->fontmap = (PangoFontMap *) cwfontmap;
278 g_object_add_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap);
280 win32font->win32face = face;
282 #ifdef USE_FACE_CACHED_FONTS
283 face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font);
286 /* FIXME: This is a pixel size, so not really what we want for describe(),
287 * but it's what we need when computing the scale factor.
289 win32font->size = size * PANGO_SCALE;
291 _pango_win32_make_matching_logfontw (win32font->fontmap,
294 &win32font->logfontw);
296 cairo_matrix_init_identity (&font_matrix);
298 cairo_matrix_scale (&font_matrix, size, size);
300 _pango_cairo_font_private_initialize (&cwfont->cf_priv,
301 (PangoCairoFont *) cwfont,
302 pango_font_description_get_gravity (desc),
303 _pango_cairo_context_get_merged_font_options (context),
304 pango_context_get_matrix (context),
307 return PANGO_FONT (cwfont);