1 /* cairo - a vector graphics library with display and print output
3 * Copyright © 2006, 2008 Red Hat, Inc
5 * This library is free software; you can redistribute it and/or
6 * modify it either under the terms of the GNU Lesser General Public
7 * License version 2.1 as published by the Free Software Foundation
8 * (the "LGPL") or, at your option, under the terms of the Mozilla
9 * Public License Version 1.1 (the "MPL"). If you do not alter this
10 * notice, a recipient may use your version of this file under either
11 * the MPL or the LGPL.
13 * You should have received a copy of the LGPL along with this library
14 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 * You should have received a copy of the MPL along with this library
17 * in the file COPYING-MPL-1.1
19 * The contents of this file are subject to the Mozilla Public License
20 * Version 1.1 (the "License"); you may not use this file except in
21 * compliance with the License. You may obtain a copy of the License at
22 * http://www.mozilla.org/MPL/
24 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
25 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
26 * the specific language governing rights and limitations.
28 * The Original Code is the cairo graphics library.
30 * The Initial Developer of the Original Code is Red Hat, Inc.
33 * Kristian Høgsberg <krh@redhat.com>
34 * Behdad Esfahbod <behdad@behdad.org>
38 #include "cairo-user-font-private.h"
39 #include "cairo-meta-surface-private.h"
40 #include "cairo-analysis-surface-private.h"
42 typedef struct _cairo_user_scaled_font_methods
{
43 cairo_user_scaled_font_init_func_t init
;
44 cairo_user_scaled_font_render_glyph_func_t render_glyph
;
45 cairo_user_scaled_font_unicode_to_glyph_func_t unicode_to_glyph
;
46 cairo_user_scaled_font_text_to_glyphs_func_t text_to_glyphs
;
47 } cairo_user_scaled_font_methods_t
;
49 typedef struct _cairo_user_font_face
{
50 cairo_font_face_t base
;
52 /* Set to true after first scaled font is created. At that point,
53 * the scaled_font_methods cannot change anymore. */
54 cairo_bool_t immutable
;
56 cairo_user_scaled_font_methods_t scaled_font_methods
;
57 } cairo_user_font_face_t
;
59 typedef struct _cairo_user_scaled_font
{
60 cairo_scaled_font_t base
;
62 cairo_text_extents_t default_glyph_extents
;
64 /* space to compute extents in, and factors to convert back to user space */
65 cairo_matrix_t extent_scale
;
66 double extent_x_scale
;
67 double extent_y_scale
;
69 /* multiplier for metrics hinting */
73 } cairo_user_scaled_font_t
;
75 /* #cairo_user_scaled_font_t */
78 _cairo_user_scaled_font_create_meta_context (cairo_user_scaled_font_t
*scaled_font
)
80 cairo_content_t content
;
81 cairo_surface_t
*meta_surface
;
84 content
= scaled_font
->base
.options
.antialias
== CAIRO_ANTIALIAS_SUBPIXEL
?
85 CAIRO_CONTENT_COLOR_ALPHA
:
88 meta_surface
= _cairo_meta_surface_create (content
, -1, -1);
89 cr
= cairo_create (meta_surface
);
90 cairo_surface_destroy (meta_surface
);
92 cairo_set_matrix (cr
, &scaled_font
->base
.scale
);
93 cairo_set_font_size (cr
, 1.0);
94 cairo_set_font_options (cr
, &scaled_font
->base
.options
);
95 cairo_set_source_rgb (cr
, 1., 1., 1.);
100 static cairo_int_status_t
101 _cairo_user_scaled_glyph_init (void *abstract_font
,
102 cairo_scaled_glyph_t
*scaled_glyph
,
103 cairo_scaled_glyph_info_t info
)
105 cairo_int_status_t status
= CAIRO_STATUS_SUCCESS
;
106 cairo_user_scaled_font_t
*scaled_font
= abstract_font
;
107 cairo_surface_t
*meta_surface
= scaled_glyph
->meta_surface
;
109 if (!scaled_glyph
->meta_surface
) {
110 cairo_user_font_face_t
*face
=
111 (cairo_user_font_face_t
*) scaled_font
->base
.font_face
;
112 cairo_text_extents_t extents
= scaled_font
->default_glyph_extents
;
115 cr
= _cairo_user_scaled_font_create_meta_context (scaled_font
);
117 if (face
->scaled_font_methods
.render_glyph
)
118 status
= face
->scaled_font_methods
.render_glyph ((cairo_scaled_font_t
*)scaled_font
,
119 _cairo_scaled_glyph_index(scaled_glyph
),
122 status
= CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED
;
124 if (status
== CAIRO_STATUS_SUCCESS
)
125 status
= cairo_status (cr
);
127 meta_surface
= cairo_surface_reference (cairo_get_target (cr
));
131 if (unlikely (status
)) {
132 cairo_surface_destroy (meta_surface
);
136 _cairo_scaled_glyph_set_meta_surface (scaled_glyph
,
143 if (extents
.width
== 0.) {
144 /* Compute extents.x/y/width/height from meta_surface, in font space */
147 double x1
, y1
, x2
, y2
;
148 double x_scale
, y_scale
;
149 cairo_surface_t
*null_surface
;
150 cairo_surface_t
*analysis_surface
;
152 null_surface
= _cairo_null_surface_create (cairo_surface_get_content (meta_surface
));
153 analysis_surface
= _cairo_analysis_surface_create (null_surface
, -1, -1);
154 cairo_surface_destroy (null_surface
);
155 status
= analysis_surface
->status
;
156 if (unlikely (status
))
159 _cairo_analysis_surface_set_ctm (analysis_surface
,
160 &scaled_font
->extent_scale
);
161 status
= _cairo_meta_surface_replay (meta_surface
,
163 _cairo_analysis_surface_get_bounding_box (analysis_surface
, &bbox
);
164 cairo_surface_destroy (analysis_surface
);
166 if (unlikely (status
))
169 _cairo_box_to_doubles (&bbox
, &x1
, &y1
, &x2
, &y2
);
171 x_scale
= scaled_font
->extent_x_scale
;
172 y_scale
= scaled_font
->extent_y_scale
;
173 extents
.x_bearing
= x1
* x_scale
;
174 extents
.y_bearing
= y1
* y_scale
;
175 extents
.width
= (x2
- x1
) * x_scale
;
176 extents
.height
= (y2
- y1
) * y_scale
;
179 if (scaled_font
->base
.options
.hint_metrics
!= CAIRO_HINT_METRICS_OFF
) {
180 extents
.x_advance
= _cairo_lround (extents
.x_advance
/ scaled_font
->snap_x_scale
) * scaled_font
->snap_x_scale
;
181 extents
.y_advance
= _cairo_lround (extents
.y_advance
/ scaled_font
->snap_y_scale
) * scaled_font
->snap_y_scale
;
184 _cairo_scaled_glyph_set_metrics (scaled_glyph
,
189 if (info
& CAIRO_SCALED_GLYPH_INFO_SURFACE
) {
190 cairo_surface_t
*surface
;
191 cairo_format_t format
;
195 * extend the glyph cache to support argb glyphs.
196 * need to figure out the semantics and interaction with subpixel
200 width
= _cairo_fixed_integer_ceil (scaled_glyph
->bbox
.p2
.x
) -
201 _cairo_fixed_integer_floor (scaled_glyph
->bbox
.p1
.x
);
202 height
= _cairo_fixed_integer_ceil (scaled_glyph
->bbox
.p2
.y
) -
203 _cairo_fixed_integer_floor (scaled_glyph
->bbox
.p1
.y
);
205 switch (scaled_font
->base
.options
.antialias
) {
207 case CAIRO_ANTIALIAS_DEFAULT
:
208 case CAIRO_ANTIALIAS_GRAY
: format
= CAIRO_FORMAT_A8
; break;
209 case CAIRO_ANTIALIAS_NONE
: format
= CAIRO_FORMAT_A1
; break;
210 case CAIRO_ANTIALIAS_SUBPIXEL
: format
= CAIRO_FORMAT_ARGB32
; break;
212 surface
= cairo_image_surface_create (format
, width
, height
);
214 cairo_surface_set_device_offset (surface
,
215 - _cairo_fixed_integer_floor (scaled_glyph
->bbox
.p1
.x
),
216 - _cairo_fixed_integer_floor (scaled_glyph
->bbox
.p1
.y
));
217 status
= _cairo_meta_surface_replay (meta_surface
, surface
);
219 if (unlikely (status
)) {
220 cairo_surface_destroy(surface
);
224 _cairo_scaled_glyph_set_surface (scaled_glyph
,
226 (cairo_image_surface_t
*) surface
);
229 if (info
& CAIRO_SCALED_GLYPH_INFO_PATH
) {
230 cairo_path_fixed_t
*path
= _cairo_path_fixed_create ();
232 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
234 status
= _cairo_meta_surface_get_path (meta_surface
, path
);
236 if (unlikely (status
)) {
237 _cairo_path_fixed_destroy (path
);
241 _cairo_scaled_glyph_set_path (scaled_glyph
,
250 _cairo_user_ucs4_to_index (void *abstract_font
,
253 cairo_user_scaled_font_t
*scaled_font
= abstract_font
;
254 cairo_user_font_face_t
*face
=
255 (cairo_user_font_face_t
*) scaled_font
->base
.font_face
;
256 unsigned long glyph
= 0;
258 if (face
->scaled_font_methods
.unicode_to_glyph
) {
259 cairo_status_t status
;
261 status
= face
->scaled_font_methods
.unicode_to_glyph (&scaled_font
->base
,
264 if (status
== CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED
)
265 goto not_implemented
;
267 if (status
!= CAIRO_STATUS_SUCCESS
) {
268 status
= _cairo_scaled_font_set_error (&scaled_font
->base
, status
);
280 static cairo_int_status_t
281 _cairo_user_text_to_glyphs (void *abstract_font
,
286 cairo_glyph_t
**glyphs
,
288 cairo_text_cluster_t
**clusters
,
290 cairo_text_cluster_flags_t
*cluster_flags
)
292 cairo_int_status_t status
= CAIRO_INT_STATUS_UNSUPPORTED
;
294 cairo_user_scaled_font_t
*scaled_font
= abstract_font
;
295 cairo_user_font_face_t
*face
=
296 (cairo_user_font_face_t
*) scaled_font
->base
.font_face
;
298 if (face
->scaled_font_methods
.text_to_glyphs
) {
300 cairo_glyph_t
*orig_glyphs
= *glyphs
;
301 int orig_num_glyphs
= *num_glyphs
;
303 status
= face
->scaled_font_methods
.text_to_glyphs (&scaled_font
->base
,
306 clusters
, num_clusters
, cluster_flags
);
308 if (status
!= CAIRO_STATUS_SUCCESS
&&
309 status
!= CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED
)
312 if (status
== CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED
|| *num_glyphs
< 0) {
313 if (orig_glyphs
!= *glyphs
) {
314 cairo_glyph_free (*glyphs
);
315 *glyphs
= orig_glyphs
;
317 *num_glyphs
= orig_num_glyphs
;
318 return CAIRO_INT_STATUS_UNSUPPORTED
;
321 /* Convert from font space to user space and add x,y */
322 for (i
= 0; i
< *num_glyphs
; i
++) {
323 double gx
= (*glyphs
)[i
].x
;
324 double gy
= (*glyphs
)[i
].y
;
326 cairo_matrix_transform_point (&scaled_font
->base
.font_matrix
,
329 (*glyphs
)[i
].x
= gx
+ x
;
330 (*glyphs
)[i
].y
= gy
+ y
;
337 static cairo_status_t
338 _cairo_user_font_face_scaled_font_create (void *abstract_face
,
339 const cairo_matrix_t
*font_matrix
,
340 const cairo_matrix_t
*ctm
,
341 const cairo_font_options_t
*options
,
342 cairo_scaled_font_t
**scaled_font
);
344 static cairo_status_t
345 _cairo_user_font_face_create_for_toy (cairo_toy_font_face_t
*toy_face
,
346 cairo_font_face_t
**font_face
)
348 return _cairo_font_face_twin_create_for_toy (toy_face
, font_face
);
351 static const cairo_scaled_font_backend_t _cairo_user_scaled_font_backend
= {
352 CAIRO_FONT_TYPE_USER
,
353 NULL
, /* scaled_font_fini */
354 _cairo_user_scaled_glyph_init
,
355 _cairo_user_text_to_glyphs
,
356 _cairo_user_ucs4_to_index
,
357 NULL
, /* show_glyphs */
358 NULL
, /* load_truetype_table */
359 NULL
/* index_to_ucs4 */
362 /* #cairo_user_font_face_t */
364 static cairo_status_t
365 _cairo_user_font_face_scaled_font_create (void *abstract_face
,
366 const cairo_matrix_t
*font_matrix
,
367 const cairo_matrix_t
*ctm
,
368 const cairo_font_options_t
*options
,
369 cairo_scaled_font_t
**scaled_font
)
371 cairo_status_t status
= CAIRO_STATUS_SUCCESS
;
372 cairo_user_font_face_t
*font_face
= abstract_face
;
373 cairo_user_scaled_font_t
*user_scaled_font
= NULL
;
374 cairo_font_extents_t font_extents
= {1., 0., 1., 1., 0.};
376 font_face
->immutable
= TRUE
;
378 user_scaled_font
= malloc (sizeof (cairo_user_scaled_font_t
));
379 if (unlikely (user_scaled_font
== NULL
))
380 return _cairo_error (CAIRO_STATUS_NO_MEMORY
);
382 status
= _cairo_scaled_font_init (&user_scaled_font
->base
,
384 font_matrix
, ctm
, options
,
385 &_cairo_user_scaled_font_backend
);
387 if (unlikely (status
)) {
388 free (user_scaled_font
);
392 /* XXX metrics hinting? */
394 /* compute a normalized version of font scale matrix to compute
395 * extents in. This is to minimize error caused by the cairo_fixed_t
398 double fixed_scale
, x_scale
, y_scale
;
400 user_scaled_font
->extent_scale
= user_scaled_font
->base
.scale_inverse
;
401 status
= _cairo_matrix_compute_basis_scale_factors (&user_scaled_font
->extent_scale
,
404 if (status
== CAIRO_STATUS_SUCCESS
) {
406 if (x_scale
== 0) x_scale
= 1.;
407 if (y_scale
== 0) y_scale
= 1.;
409 user_scaled_font
->snap_x_scale
= x_scale
;
410 user_scaled_font
->snap_y_scale
= y_scale
;
412 /* since glyphs are pretty much 1.0x1.0, we can reduce error by
413 * scaling to a larger square. say, 1024.x1024. */
415 x_scale
/= fixed_scale
;
416 y_scale
/= fixed_scale
;
418 cairo_matrix_scale (&user_scaled_font
->extent_scale
, 1. / x_scale
, 1. / y_scale
);
420 user_scaled_font
->extent_x_scale
= x_scale
;
421 user_scaled_font
->extent_y_scale
= y_scale
;
425 if (status
== CAIRO_STATUS_SUCCESS
&&
426 font_face
->scaled_font_methods
.init
!= NULL
)
428 /* Lock the scaled_font mutex such that user doesn't accidentally try
429 * to use it just yet. */
430 CAIRO_MUTEX_LOCK (user_scaled_font
->base
.mutex
);
432 /* Give away fontmap lock such that user-font can use other fonts */
433 status
= _cairo_scaled_font_register_placeholder_and_unlock_font_map (&user_scaled_font
->base
);
434 if (status
== CAIRO_STATUS_SUCCESS
) {
437 cr
= _cairo_user_scaled_font_create_meta_context (user_scaled_font
);
439 status
= font_face
->scaled_font_methods
.init (&user_scaled_font
->base
,
443 if (status
== CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED
)
444 status
= CAIRO_STATUS_SUCCESS
;
446 if (status
== CAIRO_STATUS_SUCCESS
)
447 status
= cairo_status (cr
);
451 _cairo_scaled_font_unregister_placeholder_and_lock_font_map (&user_scaled_font
->base
);
454 CAIRO_MUTEX_UNLOCK (user_scaled_font
->base
.mutex
);
457 if (status
== CAIRO_STATUS_SUCCESS
)
458 status
= _cairo_scaled_font_set_metrics (&user_scaled_font
->base
, &font_extents
);
460 if (status
!= CAIRO_STATUS_SUCCESS
) {
461 _cairo_scaled_font_fini (&user_scaled_font
->base
);
462 free (user_scaled_font
);
464 user_scaled_font
->default_glyph_extents
.x_bearing
= 0.;
465 user_scaled_font
->default_glyph_extents
.y_bearing
= -font_extents
.ascent
;
466 user_scaled_font
->default_glyph_extents
.width
= 0.;
467 user_scaled_font
->default_glyph_extents
.height
= font_extents
.ascent
+ font_extents
.descent
;
468 user_scaled_font
->default_glyph_extents
.x_advance
= font_extents
.max_x_advance
;
469 user_scaled_font
->default_glyph_extents
.y_advance
= 0.;
471 *scaled_font
= &user_scaled_font
->base
;
477 const cairo_font_face_backend_t _cairo_user_font_face_backend
= {
478 CAIRO_FONT_TYPE_USER
,
479 _cairo_user_font_face_create_for_toy
,
481 _cairo_user_font_face_scaled_font_create
486 _cairo_font_face_is_user (cairo_font_face_t
*font_face
)
488 return font_face
->backend
== &_cairo_user_font_face_backend
;
491 /* Implement the public interface */
494 * cairo_user_font_face_create:
496 * Creates a new user font-face.
498 * Use the setter functions to associate callbacks with the returned
499 * user font. The only mandatory callback is render_glyph.
501 * After the font-face is created, the user can attach arbitrary data
502 * (the actual font data) to it using cairo_font_face_set_user_data()
503 * and access it from the user-font callbacks by using
504 * cairo_scaled_font_get_font_face() followed by
505 * cairo_font_face_get_user_data().
507 * Return value: a newly created #cairo_font_face_t. Free with
508 * cairo_font_face_destroy() when you are done using it.
513 cairo_user_font_face_create (void)
515 cairo_user_font_face_t
*font_face
;
517 font_face
= malloc (sizeof (cairo_user_font_face_t
));
519 _cairo_error_throw (CAIRO_STATUS_NO_MEMORY
);
520 return (cairo_font_face_t
*)&_cairo_font_face_nil
;
523 _cairo_font_face_init (&font_face
->base
, &_cairo_user_font_face_backend
);
525 font_face
->immutable
= FALSE
;
526 memset (&font_face
->scaled_font_methods
, 0, sizeof (font_face
->scaled_font_methods
));
528 return &font_face
->base
;
530 slim_hidden_def(cairo_user_font_face_create
);
532 /* User-font method setters */
536 * cairo_user_font_face_set_init_func:
537 * @font_face: A user font face
538 * @init_func: The init callback, or %NULL
540 * Sets the scaled-font initialization function of a user-font.
541 * See #cairo_user_scaled_font_init_func_t for details of how the callback
544 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
545 * error will occur. A user font-face is immutable as soon as a scaled-font
546 * is created from it.
551 cairo_user_font_face_set_init_func (cairo_font_face_t
*font_face
,
552 cairo_user_scaled_font_init_func_t init_func
)
554 cairo_user_font_face_t
*user_font_face
;
556 if (font_face
->status
)
559 if (! _cairo_font_face_is_user (font_face
)) {
560 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_FONT_TYPE_MISMATCH
))
564 user_font_face
= (cairo_user_font_face_t
*) font_face
;
565 if (user_font_face
->immutable
) {
566 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_USER_FONT_IMMUTABLE
))
569 user_font_face
->scaled_font_methods
.init
= init_func
;
571 slim_hidden_def(cairo_user_font_face_set_init_func
);
574 * cairo_user_font_face_set_render_glyph_func:
575 * @font_face: A user font face
576 * @render_glyph_func: The render_glyph callback, or %NULL
578 * Sets the glyph rendering function of a user-font.
579 * See #cairo_user_scaled_font_render_glyph_func_t for details of how the callback
582 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
583 * error will occur. A user font-face is immutable as soon as a scaled-font
584 * is created from it.
586 * The render_glyph callback is the only mandatory callback of a user-font.
587 * If the callback is %NULL and a glyph is tried to be rendered using
588 * @font_face, a %CAIRO_STATUS_USER_FONT_ERROR will occur.
593 cairo_user_font_face_set_render_glyph_func (cairo_font_face_t
*font_face
,
594 cairo_user_scaled_font_render_glyph_func_t render_glyph_func
)
596 cairo_user_font_face_t
*user_font_face
;
598 if (font_face
->status
)
601 if (! _cairo_font_face_is_user (font_face
)) {
602 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_FONT_TYPE_MISMATCH
))
606 user_font_face
= (cairo_user_font_face_t
*) font_face
;
607 if (user_font_face
->immutable
) {
608 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_USER_FONT_IMMUTABLE
))
611 user_font_face
->scaled_font_methods
.render_glyph
= render_glyph_func
;
613 slim_hidden_def(cairo_user_font_face_set_render_glyph_func
);
616 * cairo_user_font_face_set_text_to_glyphs_func:
617 * @font_face: A user font face
618 * @text_to_glyphs_func: The text_to_glyphs callback, or %NULL
620 * Sets th text-to-glyphs conversion function of a user-font.
621 * See #cairo_user_scaled_font_text_to_glyphs_func_t for details of how the callback
624 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
625 * error will occur. A user font-face is immutable as soon as a scaled-font
626 * is created from it.
631 cairo_user_font_face_set_text_to_glyphs_func (cairo_font_face_t
*font_face
,
632 cairo_user_scaled_font_text_to_glyphs_func_t text_to_glyphs_func
)
634 cairo_user_font_face_t
*user_font_face
;
636 if (font_face
->status
)
639 if (! _cairo_font_face_is_user (font_face
)) {
640 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_FONT_TYPE_MISMATCH
))
644 user_font_face
= (cairo_user_font_face_t
*) font_face
;
645 if (user_font_face
->immutable
) {
646 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_USER_FONT_IMMUTABLE
))
649 user_font_face
->scaled_font_methods
.text_to_glyphs
= text_to_glyphs_func
;
653 * cairo_user_font_face_set_unicode_to_glyph_func:
654 * @font_face: A user font face
655 * @unicode_to_glyph_func: The unicode_to_glyph callback, or %NULL
657 * Sets the unicode-to-glyph conversion function of a user-font.
658 * See #cairo_user_scaled_font_unicode_to_glyph_func_t for details of how the callback
661 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
662 * error will occur. A user font-face is immutable as soon as a scaled-font
663 * is created from it.
668 cairo_user_font_face_set_unicode_to_glyph_func (cairo_font_face_t
*font_face
,
669 cairo_user_scaled_font_unicode_to_glyph_func_t unicode_to_glyph_func
)
671 cairo_user_font_face_t
*user_font_face
;
672 if (font_face
->status
)
675 if (! _cairo_font_face_is_user (font_face
)) {
676 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_FONT_TYPE_MISMATCH
))
680 user_font_face
= (cairo_user_font_face_t
*) font_face
;
681 if (user_font_face
->immutable
) {
682 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_USER_FONT_IMMUTABLE
))
685 user_font_face
->scaled_font_methods
.unicode_to_glyph
= unicode_to_glyph_func
;
687 slim_hidden_def(cairo_user_font_face_set_unicode_to_glyph_func
);
689 /* User-font method getters */
692 * cairo_user_font_face_get_init_func:
693 * @font_face: A user font face
695 * Gets the scaled-font initialization function of a user-font.
697 * Return value: The init callback of @font_face
698 * or %NULL if none set or an error has occurred.
702 cairo_user_scaled_font_init_func_t
703 cairo_user_font_face_get_init_func (cairo_font_face_t
*font_face
)
705 cairo_user_font_face_t
*user_font_face
;
707 if (font_face
->status
)
710 if (! _cairo_font_face_is_user (font_face
)) {
711 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_FONT_TYPE_MISMATCH
))
715 user_font_face
= (cairo_user_font_face_t
*) font_face
;
716 return user_font_face
->scaled_font_methods
.init
;
720 * cairo_user_font_face_get_render_glyph_func:
721 * @font_face: A user font face
723 * Gets the glyph rendering function of a user-font.
725 * Return value: The render_glyph callback of @font_face
726 * or %NULL if none set or an error has occurred.
730 cairo_user_scaled_font_render_glyph_func_t
731 cairo_user_font_face_get_render_glyph_func (cairo_font_face_t
*font_face
)
733 cairo_user_font_face_t
*user_font_face
;
735 if (font_face
->status
)
738 if (! _cairo_font_face_is_user (font_face
)) {
739 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_FONT_TYPE_MISMATCH
))
743 user_font_face
= (cairo_user_font_face_t
*) font_face
;
744 return user_font_face
->scaled_font_methods
.render_glyph
;
748 * cairo_user_font_face_get_text_to_glyphs_func:
749 * @font_face: A user font face
751 * Gets the text-to-glyphs conversion function of a user-font.
753 * Return value: The text_to_glyphs callback of @font_face
754 * or %NULL if none set or an error occurred.
758 cairo_user_scaled_font_text_to_glyphs_func_t
759 cairo_user_font_face_get_text_to_glyphs_func (cairo_font_face_t
*font_face
)
761 cairo_user_font_face_t
*user_font_face
;
763 if (font_face
->status
)
766 if (! _cairo_font_face_is_user (font_face
)) {
767 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_FONT_TYPE_MISMATCH
))
771 user_font_face
= (cairo_user_font_face_t
*) font_face
;
772 return user_font_face
->scaled_font_methods
.text_to_glyphs
;
776 * cairo_user_font_face_get_unicode_to_glyph_func:
777 * @font_face: A user font face
779 * Gets the unicode-to-glyph conversion function of a user-font.
781 * Return value: The unicode_to_glyph callback of @font_face
782 * or %NULL if none set or an error occurred.
786 cairo_user_scaled_font_unicode_to_glyph_func_t
787 cairo_user_font_face_get_unicode_to_glyph_func (cairo_font_face_t
*font_face
)
789 cairo_user_font_face_t
*user_font_face
;
791 if (font_face
->status
)
794 if (! _cairo_font_face_is_user (font_face
)) {
795 if (_cairo_font_face_set_error (font_face
, CAIRO_STATUS_FONT_TYPE_MISMATCH
))
799 user_font_face
= (cairo_user_font_face_t
*) font_face
;
800 return user_font_face
->scaled_font_methods
.unicode_to_glyph
;