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_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_metrics_for_context = pango_cairo_win32_font_create_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_metrics_for_context (PangoCairoFont *font,
108 PangoContext *context)
110 PangoFontMetrics *metrics;
111 PangoFontDescription *font_desc;
113 PangoRectangle extents;
114 PangoLanguage *language = pango_context_get_language (context);
115 const char *sample_str = pango_language_get_sample_string (language);
116 cairo_scaled_font_t *scaled_font;
117 cairo_font_extents_t font_extents;
120 metrics = pango_font_metrics_new ();
122 scaled_font = pango_cairo_font_get_scaled_font ((PangoFont *) font);
124 cairo_scaled_font_extents (scaled_font, &font_extents);
125 cairo_win32_scaled_font_done_font (scaled_font);
127 metrics->ascent = font_extents.ascent * PANGO_SCALE;
128 metrics->descent = font_extents.descent * PANGO_SCALE;
130 /* FIXME: Should get the real settings for these from the TrueType
133 height = metrics->ascent + metrics->descent;
134 metrics->underline_thickness = height / 14;
135 metrics->underline_position = - metrics->underline_thickness;
136 metrics->strikethrough_thickness = metrics->underline_thickness;
137 metrics->strikethrough_position = height / 4;
139 pango_quantize_line_geometry (&metrics->underline_thickness,
140 &metrics->underline_position);
141 pango_quantize_line_geometry (&metrics->strikethrough_thickness,
142 &metrics->strikethrough_position);
143 /* Quantizing may have pushed underline_position to 0. Not good */
144 if (metrics->underline_position == 0)
145 metrics->underline_position = - metrics->underline_thickness;
147 layout = pango_layout_new (context);
148 font_desc = pango_font_describe_with_absolute_size ((PangoFont *) font);
149 pango_layout_set_font_description (layout, font_desc);
150 pango_layout_set_text (layout, sample_str, -1);
151 pango_layout_get_extents (layout, NULL, &extents);
153 metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str);
155 pango_layout_set_text (layout, "0123456789", -1);
156 metrics->approximate_digit_width = max_glyph_width (layout);
158 pango_font_description_free (font_desc);
159 g_object_unref (layout);
165 pango_cairo_win32_font_finalize (GObject *object)
167 PangoCairoWin32Font *cwfont = (PangoCairoWin32Font *) object;
169 _pango_cairo_font_private_finalize (&cwfont->cf_priv);
171 G_OBJECT_CLASS (pango_cairo_win32_font_parent_class)->finalize (object);
175 pango_cairo_win32_font_get_glyph_extents (PangoFont *font,
177 PangoRectangle *ink_rect,
178 PangoRectangle *logical_rect)
180 PangoCairoWin32Font *cwfont = (PangoCairoWin32Font *) font;
182 _pango_cairo_font_private_get_glyph_extents (&cwfont->cf_priv,
189 pango_cairo_win32_font_select_font (PangoFont *font,
192 cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&PANGO_CAIRO_WIN32_FONT (font)->cf_priv);
194 return cairo_win32_scaled_font_select_font (scaled_font, hdc) == CAIRO_STATUS_SUCCESS;
198 pango_cairo_win32_font_done_font (PangoFont *font)
200 cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&PANGO_CAIRO_WIN32_FONT (font)->cf_priv);
202 cairo_win32_scaled_font_done_font (scaled_font);
206 pango_cairo_win32_font_get_metrics_factor (PangoFont *font)
208 PangoWin32Font *win32font = PANGO_WIN32_FONT (font);
209 cairo_scaled_font_t *scaled_font = _pango_cairo_font_private_get_scaled_font (&PANGO_CAIRO_WIN32_FONT (font)->cf_priv);
211 return cairo_win32_scaled_font_get_metrics_factor (scaled_font) * win32font->size;
215 pango_cairo_win32_font_class_init (PangoCairoWin32FontClass *class)
217 GObjectClass *object_class = G_OBJECT_CLASS (class);
218 PangoFontClass *font_class = PANGO_FONT_CLASS (class);
219 PangoWin32FontClass *win32_font_class = PANGO_WIN32_FONT_CLASS (class);
221 object_class->finalize = pango_cairo_win32_font_finalize;
223 font_class->get_glyph_extents = pango_cairo_win32_font_get_glyph_extents;
224 font_class->get_metrics = _pango_cairo_font_get_metrics;
226 win32_font_class->select_font = pango_cairo_win32_font_select_font;
227 win32_font_class->done_font = pango_cairo_win32_font_done_font;
228 win32_font_class->get_metrics_factor = pango_cairo_win32_font_get_metrics_factor;
232 pango_cairo_win32_font_init (PangoCairoWin32Font *cwfont G_GNUC_UNUSED)
236 /********************
238 ********************/
241 _pango_cairo_win32_font_new (PangoCairoWin32FontMap *cwfontmap,
242 PangoContext *context,
243 PangoWin32Face *face,
244 const PangoFontDescription *desc)
246 PangoCairoWin32Font *cwfont;
247 PangoWin32Font *win32font;
250 #define USE_FACE_CACHED_FONTS
251 #ifdef USE_FACE_CACHED_FONTS
252 PangoWin32FontMap *win32fontmap;
255 cairo_matrix_t font_matrix;
257 g_return_val_if_fail (PANGO_IS_CAIRO_WIN32_FONT_MAP (cwfontmap), NULL);
259 size = (double) pango_font_description_get_size (desc) / PANGO_SCALE;
263 dpi = pango_cairo_context_get_resolution (context);
266 dpi = cwfontmap->dpi;
269 dpi = cwfontmap->dpi;
271 if (!pango_font_description_get_size_is_absolute (desc))
274 #ifdef USE_FACE_CACHED_FONTS
275 win32fontmap = PANGO_WIN32_FONT_MAP (cwfontmap);
277 tmp_list = face->cached_fonts;
280 win32font = tmp_list->data;
281 if (ABS (win32font->size - size * PANGO_SCALE) < 2)
283 g_object_ref (win32font);
284 if (win32font->in_cache)
285 _pango_win32_fontmap_cache_remove (PANGO_FONT_MAP (win32fontmap), win32font);
287 return PANGO_FONT (win32font);
289 tmp_list = tmp_list->next;
292 cwfont = g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT, NULL);
293 win32font = PANGO_WIN32_FONT (cwfont);
295 g_assert (win32font->fontmap == NULL);
296 win32font->fontmap = (PangoFontMap *) cwfontmap;
297 g_object_add_weak_pointer (G_OBJECT (win32font->fontmap), (gpointer *) (gpointer) &win32font->fontmap);
299 win32font->win32face = face;
301 #ifdef USE_FACE_CACHED_FONTS
302 face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font);
305 /* FIXME: This is a pixel size, so not really what we want for describe(),
306 * but it's what we need when computing the scale factor.
308 win32font->size = size * PANGO_SCALE;
310 _pango_win32_make_matching_logfontw (win32font->fontmap,
313 &win32font->logfontw);
315 cairo_matrix_init_identity (&font_matrix);
317 cairo_matrix_scale (&font_matrix, size, size);
319 _pango_cairo_font_private_initialize (&cwfont->cf_priv,
320 (PangoCairoFont *) cwfont,
321 pango_font_description_get_gravity (desc),
322 _pango_cairo_context_get_merged_font_options (context),
323 pango_context_get_matrix (context),
326 return PANGO_FONT (cwfont);