"SfR Fresh" - the SfR Freeware/Shareware Archive 
Member "pango-1.20.5/pango/pangocairo-context.c" of archive pango-1.20.5.tar.gz:
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /* Pango
2 * pangocairo-fontmap.c: Cairo font handling
3 *
4 * Copyright (C) 2000-2005 Red Hat Software
5 *
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.
10 *
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.
15 *
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.
20 */
21
22 #include <config.h>
23
24 #include "pangocairo.h"
25 #include "pangocairo-private.h"
26 #include "pango-impl-utils.h"
27
28 #include <string.h>
29
30 typedef struct _PangoCairoContextInfo PangoCairoContextInfo;
31
32 struct _PangoCairoContextInfo
33 {
34 double dpi;
35
36 cairo_font_options_t *set_options;
37 cairo_font_options_t *surface_options;
38 cairo_font_options_t *merged_options;
39
40 PangoCairoShapeRendererFunc shape_renderer_func;
41 gpointer shape_renderer_data;
42 GDestroyNotify shape_renderer_notify;
43 };
44
45 static void
46 free_context_info (PangoCairoContextInfo *info)
47 {
48 if (info->set_options)
49 cairo_font_options_destroy (info->set_options);
50 if (info->surface_options)
51 cairo_font_options_destroy (info->surface_options);
52 if (info->merged_options)
53 cairo_font_options_destroy (info->merged_options);
54
55 if (info->shape_renderer_notify)
56 info->shape_renderer_notify (info->shape_renderer_data);
57
58 g_slice_free (PangoCairoContextInfo, info);
59 }
60
61 static PangoCairoContextInfo *
62 get_context_info (PangoContext *context,
63 gboolean create)
64 {
65 static GQuark context_info_quark;
66 PangoCairoContextInfo *info;
67
68 if (G_UNLIKELY (!context_info_quark))
69 context_info_quark = g_quark_from_static_string ("pango-cairo-context-info");
70
71 info = g_object_get_qdata (G_OBJECT (context), context_info_quark);
72
73 if (G_UNLIKELY (!info) && create)
74 {
75 info = g_slice_new0 (PangoCairoContextInfo);
76 info->dpi = -1.0;
77
78 g_object_set_qdata_full (G_OBJECT (context), context_info_quark,
79 info, (GDestroyNotify)free_context_info);
80 }
81
82 return info;
83 }
84
85 static gboolean
86 _pango_cairo_update_context (cairo_t *cr,
87 PangoContext *context)
88 {
89 PangoCairoContextInfo *info;
90 cairo_matrix_t cairo_matrix;
91 cairo_surface_t *target;
92 PangoMatrix pango_matrix;
93 const PangoMatrix *current_matrix, identity_matrix = PANGO_MATRIX_INIT;
94 const cairo_font_options_t *merged_options;
95 gboolean changed = FALSE;
96
97 info = get_context_info (context, TRUE);
98
99
100 target = cairo_get_target (cr);
101
102 if (!info->surface_options) {
103 info->surface_options = cairo_font_options_create ();
104 changed = TRUE;
105 cairo_surface_get_font_options (target, info->surface_options);
106 } else {
107 cairo_font_options_t *surface_options = cairo_font_options_create ();
108 cairo_surface_get_font_options (target, surface_options);
109 if (!cairo_font_options_equal (surface_options, info->surface_options))
110 {
111 cairo_surface_get_font_options (target, info->surface_options);
112 changed = TRUE;
113 }
114 cairo_font_options_destroy (surface_options);
115 }
116
117 if (info->merged_options)
118 {
119 cairo_font_options_destroy (info->merged_options);
120 info->merged_options = NULL;
121 }
122
123 merged_options = _pango_cairo_context_get_merged_font_options (context);
124
125
126 cairo_get_matrix (cr, &cairo_matrix);
127 pango_matrix.xx = cairo_matrix.xx;
128 pango_matrix.yx = cairo_matrix.yx;
129 pango_matrix.xy = cairo_matrix.xy;
130 pango_matrix.yy = cairo_matrix.yy;
131 pango_matrix.x0 = cairo_matrix.x0;
132 pango_matrix.y0 = cairo_matrix.y0;
133
134 current_matrix = pango_context_get_matrix (context);
135 if (!current_matrix)
136 current_matrix = &identity_matrix;
137
138 /* layout is matrix-independent if metrics-hinting is off.
139 * also ignore matrix translation offsets */
140 if ((cairo_font_options_get_hint_metrics (merged_options) != CAIRO_HINT_METRICS_OFF) &&
141 (0 != memcmp (&pango_matrix, current_matrix, 4 * sizeof (double))))
142 changed = TRUE;
143
144 pango_context_set_matrix (context, &pango_matrix);
145
146
147 return changed;
148 }
149
150 /**
151 * pango_cairo_update_context:
152 * @cr: a Cairo context
153 * @context: a #PangoContext, from pango_cairo_font_map_create_context()
154 *
155 * Updates a #PangoContext previously created for use with Cairo to
156 * match the current transformation and target surface of a Cairo
157 * context. If any layouts have been created for the context,
158 * it's necessary to call pango_layout_context_changed() on those
159 * layouts.
160 *
161 * Since: 1.10
162 **/
163 void
164 pango_cairo_update_context (cairo_t *cr,
165 PangoContext *context)
166 {
167 g_return_if_fail (cr != NULL);
168 g_return_if_fail (PANGO_IS_CONTEXT (context));
169
170 (void) _pango_cairo_update_context (cr, context);
171 }
172
173 /**
174 * pango_cairo_context_set_resolution:
175 * @context: a #PangoContext, from pango_cairo_font_map_create_context()
176 * @dpi: the resolution in "dots per inch". (Physical inches aren't actually
177 * involved; the terminology is conventional.) A 0 or negative value
178 * means to use the resolution from the font map.
179 *
180 * Sets the resolution for the context. This is a scale factor between
181 * points specified in a #PangoFontDescription and Cairo units. The
182 * default value is 96, meaning that a 10 point font will be 13
183 * units high. (10 * 96. / 72. = 13.3).
184 *
185 * Since: 1.10
186 **/
187 void
188 pango_cairo_context_set_resolution (PangoContext *context,
189 double dpi)
190 {
191 PangoCairoContextInfo *info = get_context_info (context, TRUE);
192 info->dpi = dpi;
193 }
194
195 /**
196 * pango_cairo_context_get_resolution:
197 * @context: a #PangoContext, from pango_cairo_font_map_create_context()
198 *
199 * Gets the resolution for the context. See pango_cairo_context_set_resolution()
200 *
201 * Return value: the resolution in "dots per inch". A negative value will
202 * be returned if no resolution has previously been set.
203 *
204 * Since: 1.10
205 **/
206 double
207 pango_cairo_context_get_resolution (PangoContext *context)
208 {
209 PangoCairoContextInfo *info = get_context_info (context, FALSE);
210
211 if (info)
212 return info->dpi;
213 else
214 return -1.0;
215 }
216
217 /**
218 * pango_cairo_context_set_font_options:
219 * @context: a #PangoContext, from pango_cairo_font_map_create_context()
220 * @options: a #cairo_font_options_t, or %NULL to unset any previously set
221 * options. A copy is made.
222 *
223 * Sets the font options used when rendering text with this context.
224 * These options override any options that pango_cairo_update_context()
225 * derives from the target surface.
226 *
227 * Since: 1.10
228 */
229 void
230 pango_cairo_context_set_font_options (PangoContext *context,
231 const cairo_font_options_t *options)
232 {
233 PangoCairoContextInfo *info;
234
235 g_return_if_fail (PANGO_IS_CONTEXT (context));
236
237 info = get_context_info (context, TRUE);
238
239 if (info->set_options)
240 cairo_font_options_destroy (info->set_options);
241
242 if (options)
243 info->set_options = cairo_font_options_copy (options);
244 else
245 info->set_options = NULL;
246
247 if (info->merged_options)
248 {
249 cairo_font_options_destroy (info->merged_options);
250 info->merged_options = NULL;
251 }
252 }
253
254 /**
255 * pango_cairo_context_get_font_options:
256 * @context: a #PangoContext, from pango_cairo_font_map_create_context()
257 *
258 * Retrieves any font rendering options previously set with
259 * pango_cairo_font_map_set_font_options(). This functions not report options
260 * that are derived from the target surface by pango_cairo_update_context()
261 *
262 * Return value: the font options previously set on the context, or %NULL
263 * if no options have been set. This value is owned by the context
264 * and must not be modified or freed.
265 *
266 * Since: 1.10
267 **/
268 G_CONST_RETURN cairo_font_options_t *
269 pango_cairo_context_get_font_options (PangoContext *context)
270 {
271 PangoCairoContextInfo *info;
272
273 g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
274
275 info = get_context_info (context, FALSE);
276
277 if (info)
278 return info->set_options;
279 else
280 return NULL;
281 }
282
283 /**
284 * _pango_cairo_context_merge_font_options:
285 * @context: a #PangoContext
286 * @options: a #cairo_font_options_t
287 *
288 * Merge together options from the target surface and explicitly set
289 * on the context.
290 *
291 * Return value: the combined set of font options. This value is owned
292 * by the context and must not be modified or freed.
293 **/
294 G_CONST_RETURN cairo_font_options_t *
295 _pango_cairo_context_get_merged_font_options (PangoContext *context)
296 {
297 PangoCairoContextInfo *info = get_context_info (context, TRUE);
298
299 if (!info->merged_options)
300 {
301 info->merged_options = cairo_font_options_create ();
302
303 if (info->surface_options)
304 cairo_font_options_merge (info->merged_options, info->surface_options);
305 if (info->set_options)
306 cairo_font_options_merge (info->merged_options, info->set_options);
307 }
308
309 return info->merged_options;
310 }
311
312 /**
313 * pango_cairo_context_set_shape_renderer:
314 * @context: a #PangoContext, from pango_cairo_font_map_create_context()
315 * @func: Callback function for rendering attributes of type
316 * %PANGO_ATTR_SHAPE, or %NULL to disable shape rendering.
317 * @data: User data that will be passed to @func.
318 * @dnotify: Callback that will be called when the
319 * context is freed to release @data, or %NULL.
320 *
321 * Sets callback function for context to use for rendering attributes
322 * of type %PANGO_ATTR_SHAPE. See #PangoCairoShapeRendererFunc for
323 * details.
324 *
325 * Since: 1.18
326 */
327 void
328 pango_cairo_context_set_shape_renderer (PangoContext *context,
329 PangoCairoShapeRendererFunc func,
330 gpointer data,
331 GDestroyNotify dnotify)
332 {
333 PangoCairoContextInfo *info;
334
335 g_return_if_fail (PANGO_IS_CONTEXT (context));
336
337 info = get_context_info (context, TRUE);
338
339 if (info->shape_renderer_notify)
340 info->shape_renderer_notify (info->shape_renderer_data);
341
342 info->shape_renderer_func = func;
343 info->shape_renderer_data = data;
344 info->shape_renderer_notify = dnotify;
345 }
346
347 /**
348 * pango_cairo_context_get_shape_renderer:
349 * @context: a #PangoContext, from pango_cairo_font_map_create_context()
350 * @data: Pointer to #gpointer to return user data
351 *
352 * Sets callback function for context to use for rendering attributes
353 * of type %PANGO_ATTR_SHAPE. See #PangoCairoShapeRendererFunc for
354 * details.
355 *
356 * Retrieves callback function and associated user data for rendering
357 * attributes of type %PANGO_ATTR_SHAPE as set by
358 * pango_cairo_context_set_shape_renderer(), if any.
359 *
360 * Return value: the shape rendering callback previously set on the context, or %NULL
361 * if no shape rendering callback have been set.
362 *
363 * Since: 1.18
364 */
365 PangoCairoShapeRendererFunc
366 pango_cairo_context_get_shape_renderer (PangoContext *context,
367 gpointer *data)
368 {
369 PangoCairoContextInfo *info;
370
371 g_return_val_if_fail (PANGO_IS_CONTEXT (context), NULL);
372
373 info = get_context_info (context, FALSE);
374
375 if (info)
376 {
377 if (data)
378 *data = info->shape_renderer_data;
379 return info->shape_renderer_func;
380 }
381 else
382 {
383 if (data)
384 *data = NULL;
385 return NULL;
386 }
387 }
388
389 /**
390 * pango_cairo_create_layout:
391 * @cr: a Cairo context
392 *
393 * Creates a layout object set up to match the current transformation
394 * and target surface of the Cairo context. This layout can then be
395 * used for text measurement with functions like
396 * pango_layout_get_size() or drawing with functions like
397 * pango_cairo_show_layout(). If you change the transformation
398 * or target surface for @cr, you need to call pango_cairo_update_layout()
399 *
400 * This function is the most convenient way to use Cairo with Pango,
401 * however it is slightly inefficient since it creates a separate
402 * #PangoContext object for each layout. This might matter in an
403 * application that was laying out large amounts of text.
404 *
405 * Return value: the newly created #PangoLayout. Free with
406 * g_object_unref().
407 *
408 * Since: 1.10
409 **/
410 PangoLayout *
411 pango_cairo_create_layout (cairo_t *cr)
412 {
413 PangoFontMap *fontmap;
414 PangoContext *context;
415 PangoLayout *layout;
416
417 g_return_val_if_fail (cr != NULL, NULL);
418
419 fontmap = pango_cairo_font_map_get_default ();
420 context = pango_cairo_font_map_create_context ((PangoCairoFontMap *) (fontmap));
421 layout = pango_layout_new (context);
422
423 pango_cairo_update_context (cr, context);
424 g_object_unref (context);
425
426 return layout;
427 }
428
429 /**
430 * pango_cairo_update_layout:
431 * @cr: a Cairo context
432 * @layout: a #PangoLayout, from pango_cairo_create_layout()
433 *
434 * Updates the private #PangoContext of a #PangoLayout created with
435 * pango_cairo_create_layout() to match the current transformation
436 * and target surface of a Cairo context.
437 *
438 * Since: 1.10
439 **/
440 void
441 pango_cairo_update_layout (cairo_t *cr,
442 PangoLayout *layout)
443 {
444 g_return_if_fail (cr != NULL);
445 g_return_if_fail (PANGO_IS_LAYOUT (layout));
446
447 if (_pango_cairo_update_context (cr, pango_layout_get_context (layout)))
448 pango_layout_context_changed (layout);
449 }
450