1
/* -*- Mode: c; tab-width: 8; c-basic-offset: 4; indent-tabs-mode: t; -*- */
2
/* cairo - a vector graphics library with display and print output
3
 *
4
 * Copyright © 2006, 2008 Red Hat, Inc
5
 *
6
 * This library is free software; you can redistribute it and/or
7
 * modify it either under the terms of the GNU Lesser General Public
8
 * License version 2.1 as published by the Free Software Foundation
9
 * (the "LGPL") or, at your option, under the terms of the Mozilla
10
 * Public License Version 1.1 (the "MPL"). If you do not alter this
11
 * notice, a recipient may use your version of this file under either
12
 * the MPL or the LGPL.
13
 *
14
 * You should have received a copy of the LGPL along with this library
15
 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
16
 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
17
 * You should have received a copy of the MPL along with this library
18
 * in the file COPYING-MPL-1.1
19
 *
20
 * The contents of this file are subject to the Mozilla Public License
21
 * Version 1.1 (the "License"); you may not use this file except in
22
 * compliance with the License. You may obtain a copy of the License at
23
 * http://www.mozilla.org/MPL/
24
 *
25
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
26
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
27
 * the specific language governing rights and limitations.
28
 *
29
 * The Original Code is the cairo graphics library.
30
 *
31
 * The Initial Developer of the Original Code is Red Hat, Inc.
32
 *
33
 * Contributor(s):
34
 *      Kristian Høgsberg <krh@redhat.com>
35
 *      Behdad Esfahbod <behdad@behdad.org>
36
 */
37

            
38
#include "cairoint.h"
39
#include "cairo-user-font-private.h"
40
#include "cairo-recording-surface-private.h"
41
#include "cairo-analysis-surface-private.h"
42
#include "cairo-error-private.h"
43

            
44
/**
45
 * SECTION:cairo-user-fonts
46
 * @Title:User Fonts
47
 * @Short_Description: Font support with font data provided by the user
48
 *
49
 * The user-font feature allows the cairo user to provide drawings for glyphs
50
 * in a font.  This is most useful in implementing fonts in non-standard
51
 * formats, like SVG fonts and Flash fonts, but can also be used by games and
52
 * other application to draw "funky" fonts.
53
 **/
54

            
55
/**
56
 * CAIRO_HAS_USER_FONT:
57
 *
58
 * Defined if the user font backend is available.
59
 * This macro can be used to conditionally compile backend-specific code.
60
 * The user font backend is always built in versions of cairo that support
61
 * this feature (1.8 and later).
62
 *
63
 * Since: 1.8
64
 **/
65

            
66
typedef struct _cairo_user_scaled_font_methods {
67
    cairo_user_scaled_font_init_func_t			init;
68
    cairo_user_scaled_font_render_glyph_func_t		render_color_glyph;
69
    cairo_user_scaled_font_render_glyph_func_t		render_glyph;
70
    cairo_user_scaled_font_unicode_to_glyph_func_t	unicode_to_glyph;
71
    cairo_user_scaled_font_text_to_glyphs_func_t	text_to_glyphs;
72
} cairo_user_scaled_font_methods_t;
73

            
74
typedef struct _cairo_user_font_face {
75
    cairo_font_face_t	             base;
76

            
77
    /* Set to true after first scaled font is created.  At that point,
78
     * the scaled_font_methods cannot change anymore. */
79
    cairo_bool_t		     immutable;
80
    cairo_bool_t                     has_color;
81
    cairo_user_scaled_font_methods_t scaled_font_methods;
82
} cairo_user_font_face_t;
83

            
84
typedef struct _cairo_user_scaled_font {
85
    cairo_scaled_font_t  base;
86

            
87
    cairo_text_extents_t default_glyph_extents;
88

            
89
    /* space to compute extents in, and factors to convert back to user space */
90
    cairo_matrix_t extent_scale;
91
    double extent_x_scale;
92
    double extent_y_scale;
93

            
94
    /* multiplier for metrics hinting */
95
    double snap_x_scale;
96
    double snap_y_scale;
97

            
98
    cairo_pattern_t *foreground_marker;
99
    cairo_pattern_t *foreground_pattern;
100
    cairo_bool_t foreground_marker_used;
101
    cairo_bool_t foreground_colors_used;
102

            
103
} cairo_user_scaled_font_t;
104

            
105
/* #cairo_user_scaled_font_t */
106

            
107
static cairo_surface_t *
108
975
_cairo_user_scaled_font_create_recording_surface (cairo_user_scaled_font_t *scaled_font,
109
						  cairo_bool_t              color,
110
						  const cairo_color_t      *foreground_color)
111
{
112
    cairo_content_t content;
113

            
114
975
    if (color) {
115
150
	content = CAIRO_CONTENT_COLOR_ALPHA;
116
    } else {
117
825
	content = scaled_font->base.options.antialias == CAIRO_ANTIALIAS_SUBPIXEL ?
118
825
						         CAIRO_CONTENT_COLOR_ALPHA :
119
						         CAIRO_CONTENT_ALPHA;
120
    }
121

            
122
975
    if (scaled_font->foreground_pattern)
123
891
	cairo_pattern_destroy (scaled_font->foreground_pattern);
124

            
125
975
    scaled_font->foreground_marker_used = FALSE;
126
975
    scaled_font->foreground_colors_used = FALSE;
127
975
    if (foreground_color) {
128
897
	scaled_font->foreground_pattern = _cairo_pattern_create_solid (foreground_color);
129
    } else {
130
78
	scaled_font->foreground_pattern = cairo_pattern_create_rgb (0, 0, 0);
131
    }
132

            
133
975
    return cairo_recording_surface_create (content, NULL);
134
}
135

            
136
static cairo_t *
137
975
_cairo_user_scaled_font_create_recording_context (const cairo_user_scaled_font_t *scaled_font,
138
						  cairo_surface_t                *recording_surface,
139
						  cairo_bool_t                    color)
140
{
141
    cairo_t *cr;
142

            
143
975
    cr = cairo_create (recording_surface);
144

            
145
975
    if (!_cairo_matrix_is_scale_0 (&scaled_font->base.scale)) {
146
        cairo_matrix_t scale;
147
975
	scale = scaled_font->base.scale;
148
975
	scale.x0 = scale.y0 = 0.;
149
975
	cairo_set_matrix (cr, &scale);
150
    }
151

            
152
975
    cairo_set_font_size (cr, 1.0);
153
975
    cairo_set_font_options (cr, &scaled_font->base.options);
154
975
    if (!color)
155
825
	cairo_set_source_rgb (cr, 1., 1., 1.);
156

            
157
975
    return cr;
158
}
159

            
160
static cairo_int_status_t
161
837
_cairo_user_scaled_glyph_init_record_glyph (cairo_user_scaled_font_t *scaled_font,
162
					    cairo_scaled_glyph_t     *scaled_glyph,
163
					    const cairo_color_t      *foreground_color)
164
{
165
837
    cairo_user_font_face_t *face =
166
	(cairo_user_font_face_t *) scaled_font->base.font_face;
167
837
    cairo_text_extents_t extents = scaled_font->default_glyph_extents;
168
837
    cairo_surface_t *recording_surface = NULL;
169
837
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
170
    cairo_t *cr;
171
837
    cairo_bool_t foreground_used = FALSE;
172

            
173
837
    if (!face->scaled_font_methods.render_color_glyph && !face->scaled_font_methods.render_glyph)
174
	return CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED;
175

            
176
    /* special case for 0 rank matrix (as in _cairo_scaled_font_init): empty surface */
177
837
    if (_cairo_matrix_is_scale_0 (&scaled_font->base.scale)) {
178
	recording_surface = _cairo_user_scaled_font_create_recording_surface (scaled_font, FALSE, foreground_color);
179
	_cairo_scaled_glyph_set_recording_surface (scaled_glyph,
180
						   &scaled_font->base,
181
						   recording_surface,
182
						   NULL);
183
    } else {
184
837
	status = CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED;
185

            
186
837
	if (face->scaled_font_methods.render_color_glyph &&
187
180
	    scaled_font->base.options.color_mode != CAIRO_COLOR_MODE_NO_COLOR)
188
	{
189
150
	    recording_surface = _cairo_user_scaled_font_create_recording_surface (scaled_font, TRUE, foreground_color);
190

            
191
150
	    cr = _cairo_user_scaled_font_create_recording_context (scaled_font, recording_surface, TRUE);
192
150
	    status = face->scaled_font_methods.render_color_glyph ((cairo_scaled_font_t *)scaled_font,
193
150
								   _cairo_scaled_glyph_index(scaled_glyph),
194
								   cr, &extents);
195
150
	    if (status == CAIRO_INT_STATUS_SUCCESS) {
196
90
		status = cairo_status (cr);
197
90
		scaled_glyph->color_glyph = TRUE;
198
90
		scaled_glyph->color_glyph_set = TRUE;
199
	    }
200

            
201
150
	    cairo_destroy (cr);
202
150
	    foreground_used = scaled_font->foreground_marker_used || scaled_font->foreground_colors_used;
203
	}
204

            
205
837
	if (status == (cairo_int_status_t)CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED &&
206
747
	    face->scaled_font_methods.render_glyph) {
207
747
	    if (recording_surface)
208
60
		cairo_surface_destroy (recording_surface);
209
747
	    recording_surface = _cairo_user_scaled_font_create_recording_surface (scaled_font, FALSE, foreground_color);
210
747
	    recording_surface->device_transform.x0 = .25 * _cairo_scaled_glyph_xphase (scaled_glyph);
211
747
	    recording_surface->device_transform.y0 = .25 * _cairo_scaled_glyph_yphase (scaled_glyph);
212

            
213
747
	    cr = _cairo_user_scaled_font_create_recording_context (scaled_font, recording_surface, FALSE);
214

            
215
747
	    status = face->scaled_font_methods.render_glyph ((cairo_scaled_font_t *)scaled_font,
216
747
							     _cairo_scaled_glyph_index(scaled_glyph),
217
							     cr, &extents);
218
747
	    if (status == CAIRO_INT_STATUS_SUCCESS) {
219
747
		status = cairo_status (cr);
220
747
		scaled_glyph->color_glyph = FALSE;
221
747
		scaled_glyph->color_glyph_set = TRUE;
222
	    }
223

            
224
747
	    cairo_destroy (cr);
225
747
	    foreground_used = FALSE;
226
	}
227

            
228
837
	if (status != CAIRO_INT_STATUS_SUCCESS) {
229
	    if (recording_surface)
230
		cairo_surface_destroy (recording_surface);
231
	    return status;
232
	}
233

            
234
837
	_cairo_scaled_glyph_set_recording_surface (scaled_glyph,
235
						   &scaled_font->base,
236
						   recording_surface,
237
						   foreground_used ? foreground_color : NULL);
238
    }
239

            
240
    /* set metrics */
241

            
242
837
    if (extents.width == 0.) {
243
	cairo_box_t bbox;
244
	double x1, y1, x2, y2;
245
	double x_scale, y_scale;
246

            
247
	/* Compute extents.x/y/width/height from recording_surface,
248
	 * in font space.
249
	 */
250
738
	status = _cairo_recording_surface_get_bbox ((cairo_recording_surface_t *) recording_surface,
251
						    &bbox,
252
738
						    &scaled_font->extent_scale);
253
738
	if (unlikely (status))
254
	    return status;
255

            
256
738
	_cairo_box_to_doubles (&bbox, &x1, &y1, &x2, &y2);
257

            
258
738
	x_scale = scaled_font->extent_x_scale;
259
738
	y_scale = scaled_font->extent_y_scale;
260
738
	extents.x_bearing = x1 * x_scale;
261
738
	extents.y_bearing = y1 * y_scale;
262
738
	extents.width     = (x2 - x1) * x_scale;
263
738
	extents.height    = (y2 - y1) * y_scale;
264
    }
265

            
266
837
    if (scaled_font->base.options.hint_metrics != CAIRO_HINT_METRICS_OFF) {
267
837
	extents.x_advance = _cairo_lround (extents.x_advance / scaled_font->snap_x_scale) * scaled_font->snap_x_scale;
268
837
	extents.y_advance = _cairo_lround (extents.y_advance / scaled_font->snap_y_scale) * scaled_font->snap_y_scale;
269
    }
270

            
271
837
    _cairo_scaled_glyph_set_metrics (scaled_glyph,
272
				     &scaled_font->base,
273
				     &extents);
274

            
275
837
    return status;
276
}
277

            
278
static cairo_int_status_t
279
792
_cairo_user_scaled_glyph_init_surface (cairo_user_scaled_font_t  *scaled_font,
280
				       cairo_scaled_glyph_t	 *scaled_glyph,
281
				       cairo_scaled_glyph_info_t  info,
282
				       const cairo_color_t       *foreground_color)
283
{
284
    cairo_surface_t *surface;
285
    cairo_format_t format;
286
    int width, height;
287
792
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
288
    cairo_bool_t foreground_used;
289

            
290
    /* TODO
291
     * extend the glyph cache to support argb glyphs.
292
     * need to figure out the semantics and interaction with subpixel
293
     * rendering first.
294
     */
295

            
296
    /* Only one info type at a time handled in this function */
297
792
    assert (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE || info == CAIRO_SCALED_GLYPH_INFO_SURFACE);
298

            
299
792
    width = _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.x) -
300
792
	_cairo_fixed_integer_floor (scaled_glyph->bbox.p1.x);
301
792
    height = _cairo_fixed_integer_ceil (scaled_glyph->bbox.p2.y) -
302
792
	_cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y);
303

            
304
792
    if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) {
305
90
	format = CAIRO_FORMAT_ARGB32;
306
    } else {
307
702
	switch (scaled_font->base.options.antialias) {
308
450
	    default:
309
	    case CAIRO_ANTIALIAS_DEFAULT:
310
	    case CAIRO_ANTIALIAS_FAST:
311
	    case CAIRO_ANTIALIAS_GOOD:
312
	    case CAIRO_ANTIALIAS_GRAY:
313
450
		format = CAIRO_FORMAT_A8;
314
450
		break;
315
135
	    case CAIRO_ANTIALIAS_NONE:
316
135
		format = CAIRO_FORMAT_A1;
317
135
		break;
318
117
	    case CAIRO_ANTIALIAS_BEST:
319
	    case CAIRO_ANTIALIAS_SUBPIXEL:
320
117
		format = CAIRO_FORMAT_ARGB32;
321
117
		break;
322
	}
323
    }
324
792
    surface = cairo_image_surface_create (format, width, height);
325

            
326
1584
    cairo_surface_set_device_offset (surface,
327
792
				     - _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.x),
328
792
				     - _cairo_fixed_integer_floor (scaled_glyph->bbox.p1.y));
329

            
330
792
    if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) {
331
90
	status = _cairo_recording_surface_replay_with_foreground_color (scaled_glyph->recording_surface,
332
									surface,
333
									foreground_color,
334
									&foreground_used);
335
	
336
    } else {
337
702
	status = _cairo_recording_surface_replay (scaled_glyph->recording_surface, surface);
338
702
	foreground_used = FALSE;
339
    }
340
792
    if (unlikely (status)) {
341
	cairo_surface_destroy(surface);
342
	return status;
343
    }
344

            
345
792
    foreground_used = foreground_used || scaled_glyph->recording_uses_foreground_color;
346
    
347
792
    if (info == CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) {
348
90
	_cairo_scaled_glyph_set_color_surface (scaled_glyph,
349
					       &scaled_font->base,
350
					       (cairo_image_surface_t *)surface,
351
90
					       foreground_used ? foreground_color : NULL);
352
90
	surface = NULL;
353
    } else {
354
702
	_cairo_scaled_glyph_set_surface (scaled_glyph,
355
					 &scaled_font->base,
356
					 (cairo_image_surface_t *) surface);
357
702
	surface = NULL;
358
    }
359

            
360
792
    if (surface)
361
	cairo_surface_destroy (surface);
362

            
363
792
    return status;
364
}
365

            
366
static void
367
_cairo_user_scaled_glyph_fini (void			 *abstract_font)
368
{
369
    cairo_user_scaled_font_t *scaled_font = abstract_font;
370

            
371
    if (scaled_font->foreground_pattern)
372
	cairo_pattern_destroy (scaled_font->foreground_pattern);
373

            
374
    if (scaled_font->foreground_marker)
375
	cairo_pattern_destroy (scaled_font->foreground_marker);
376
}
377

            
378
static cairo_int_status_t
379
1875
_cairo_user_scaled_glyph_init (void			 *abstract_font,
380
			       cairo_scaled_glyph_t	 *scaled_glyph,
381
			       cairo_scaled_glyph_info_t  info,
382
			       const cairo_color_t       *foreground_color)
383
{
384
1875
    cairo_int_status_t status = CAIRO_STATUS_SUCCESS;
385
1875
    cairo_user_scaled_font_t *scaled_font = abstract_font;
386

            
387
1875
    if (!scaled_glyph->recording_surface || (info & CAIRO_SCALED_GLYPH_INFO_RECORDING_SURFACE)) {
388
837
	status = _cairo_user_scaled_glyph_init_record_glyph (scaled_font, scaled_glyph, foreground_color);
389
837
	if (status)
390
	    return status;
391
    }
392

            
393
1875
    if (info & CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE) {
394
120
	if (!scaled_glyph->color_glyph )
395
30
	    return CAIRO_INT_STATUS_UNSUPPORTED;
396

            
397
90
	status = _cairo_user_scaled_glyph_init_surface (scaled_font,
398
							scaled_glyph,
399
							CAIRO_SCALED_GLYPH_INFO_COLOR_SURFACE,
400
							foreground_color);
401
90
	if (status)
402
	    return status;
403
    }
404

            
405
1845
    if (info & CAIRO_SCALED_GLYPH_INFO_SURFACE) {
406
702
	status = _cairo_user_scaled_glyph_init_surface (scaled_font,
407
							scaled_glyph,
408
							CAIRO_SCALED_GLYPH_INFO_SURFACE,
409
							NULL);
410
702
	if (status)
411
	    return status;
412
    }
413

            
414
1845
    if (info & CAIRO_SCALED_GLYPH_INFO_PATH) {
415
327
	cairo_path_fixed_t *path = _cairo_path_fixed_create ();
416
327
	if (!path)
417
	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
418

            
419
327
	status = _cairo_recording_surface_get_path (scaled_glyph->recording_surface, path);
420
327
	if (unlikely (status)) {
421
36
	    _cairo_path_fixed_destroy (path);
422
36
	    return status;
423
	}
424

            
425
291
	_cairo_scaled_glyph_set_path (scaled_glyph,
426
				      &scaled_font->base,
427
				      path);
428
    }
429

            
430
1809
    return status;
431
}
432

            
433
static unsigned long
434
1611
_cairo_user_ucs4_to_index (void	    *abstract_font,
435
			   uint32_t  ucs4)
436
{
437
1611
    cairo_user_scaled_font_t *scaled_font = abstract_font;
438
1611
    cairo_user_font_face_t *face =
439
	(cairo_user_font_face_t *) scaled_font->base.font_face;
440
1611
    unsigned long glyph = 0;
441

            
442
1611
    if (face->scaled_font_methods.unicode_to_glyph) {
443
	cairo_status_t status;
444

            
445
1341
	status = face->scaled_font_methods.unicode_to_glyph (&scaled_font->base,
446
							     ucs4, &glyph);
447

            
448
1341
	if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED)
449
	    goto not_implemented;
450

            
451
1341
	if (status != CAIRO_STATUS_SUCCESS) {
452
	    status = _cairo_scaled_font_set_error (&scaled_font->base, status);
453
	    glyph = 0;
454
	}
455

            
456
    } else {
457
270
not_implemented:
458
270
	glyph = ucs4;
459
    }
460

            
461
1611
    return glyph;
462
}
463

            
464
static cairo_bool_t
465
732
_cairo_user_has_color_glyphs (void         *abstract_font)
466
{
467
732
    cairo_user_scaled_font_t *scaled_font = abstract_font;
468
732
    cairo_user_font_face_t *face =
469
	(cairo_user_font_face_t *) scaled_font->base.font_face;
470

            
471
732
    return face->has_color;
472
}
473

            
474
static cairo_int_status_t
475
423
_cairo_user_text_to_glyphs (void		      *abstract_font,
476
			    double		       x,
477
			    double		       y,
478
			    const char		      *utf8,
479
			    int			       utf8_len,
480
			    cairo_glyph_t	     **glyphs,
481
			    int			       *num_glyphs,
482
			    cairo_text_cluster_t      **clusters,
483
			    int			       *num_clusters,
484
			    cairo_text_cluster_flags_t *cluster_flags)
485
{
486
423
    cairo_int_status_t status = CAIRO_INT_STATUS_UNSUPPORTED;
487

            
488
423
    cairo_user_scaled_font_t *scaled_font = abstract_font;
489
423
    cairo_user_font_face_t *face =
490
	(cairo_user_font_face_t *) scaled_font->base.font_face;
491

            
492
423
    if (face->scaled_font_methods.text_to_glyphs) {
493
	int i;
494
18
	cairo_glyph_t *orig_glyphs = *glyphs;
495
18
	int orig_num_glyphs = *num_glyphs;
496

            
497
18
	status = face->scaled_font_methods.text_to_glyphs (&scaled_font->base,
498
							   utf8, utf8_len,
499
							   glyphs, num_glyphs,
500
							   clusters, num_clusters, cluster_flags);
501

            
502
18
	if (status != CAIRO_INT_STATUS_SUCCESS &&
503
	    status != CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED)
504
	    return status;
505

            
506
18
	if (status == CAIRO_INT_STATUS_USER_FONT_NOT_IMPLEMENTED ||
507
18
	    *num_glyphs < 0) {
508
	    if (orig_glyphs != *glyphs) {
509
		cairo_glyph_free (*glyphs);
510
		*glyphs = orig_glyphs;
511
	    }
512
	    *num_glyphs = orig_num_glyphs;
513
	    return CAIRO_INT_STATUS_UNSUPPORTED;
514
	}
515

            
516
	/* Convert from font space to user space and add x,y */
517
243
	for (i = 0; i < *num_glyphs; i++) {
518
225
	    double gx = (*glyphs)[i].x;
519
225
	    double gy = (*glyphs)[i].y;
520

            
521
225
	    cairo_matrix_transform_point (&scaled_font->base.font_matrix,
522
					  &gx, &gy);
523

            
524
225
	    (*glyphs)[i].x = gx + x;
525
225
	    (*glyphs)[i].y = gy + y;
526
	}
527
    }
528

            
529
423
    return status;
530
}
531

            
532
static cairo_status_t
533
_cairo_user_font_face_scaled_font_create (void                        *abstract_face,
534
					  const cairo_matrix_t        *font_matrix,
535
					  const cairo_matrix_t        *ctm,
536
					  const cairo_font_options_t  *options,
537
					  cairo_scaled_font_t        **scaled_font);
538

            
539
static cairo_status_t
540
27
_cairo_user_font_face_create_for_toy (cairo_toy_font_face_t   *toy_face,
541
				      cairo_font_face_t      **font_face)
542
{
543
27
    return _cairo_font_face_twin_create_for_toy (toy_face, font_face);
544
}
545

            
546
static const cairo_scaled_font_backend_t _cairo_user_scaled_font_backend = {
547
    CAIRO_FONT_TYPE_USER,
548
    _cairo_user_scaled_glyph_fini,
549
    _cairo_user_scaled_glyph_init,
550
    _cairo_user_text_to_glyphs,
551
    _cairo_user_ucs4_to_index,
552
    NULL,	/* load_truetype_table */
553
    NULL,	/* index_to_ucs4 */
554
    NULL,       /* is_synthetic */
555
    NULL,       /* index_to_glyph_name */
556
    NULL,       /* load_type1_data */
557
    _cairo_user_has_color_glyphs,
558
};
559

            
560
/* #cairo_user_font_face_t */
561

            
562
static cairo_status_t
563
84
_cairo_user_font_face_scaled_font_create (void                        *abstract_face,
564
					  const cairo_matrix_t        *font_matrix,
565
					  const cairo_matrix_t        *ctm,
566
					  const cairo_font_options_t  *options,
567
					  cairo_scaled_font_t        **scaled_font)
568
{
569
84
    cairo_status_t status = CAIRO_STATUS_SUCCESS;
570
84
    cairo_user_font_face_t *font_face = abstract_face;
571
84
    cairo_user_scaled_font_t *user_scaled_font = NULL;
572
84
    cairo_font_extents_t font_extents = {1., 0., 1., 1., 0.};
573

            
574
84
    font_face->immutable = TRUE;
575

            
576
84
    user_scaled_font = _cairo_calloc (sizeof (cairo_user_scaled_font_t));
577
84
    if (unlikely (user_scaled_font == NULL))
578
	return _cairo_error (CAIRO_STATUS_NO_MEMORY);
579

            
580
84
    status = _cairo_scaled_font_init (&user_scaled_font->base,
581
				      &font_face->base,
582
				      font_matrix, ctm, options,
583
				      &_cairo_user_scaled_font_backend);
584

            
585
84
    if (unlikely (status)) {
586
	free (user_scaled_font);
587
	return status;
588
    }
589

            
590
84
    user_scaled_font->foreground_pattern = NULL;
591
84
    user_scaled_font->foreground_marker = _cairo_pattern_create_foreground_marker ();
592

            
593
    /* XXX metrics hinting? */
594

            
595
    /* compute a normalized version of font scale matrix to compute
596
     * extents in.  This is to minimize error caused by the cairo_fixed_t
597
     * representation. */
598
    {
599
	double fixed_scale, x_scale, y_scale;
600

            
601
84
	user_scaled_font->snap_x_scale = 1.0;
602
84
	user_scaled_font->snap_y_scale = 1.0;
603
84
	user_scaled_font->extent_scale = user_scaled_font->base.scale_inverse;
604
84
	status = _cairo_matrix_compute_basis_scale_factors (&user_scaled_font->extent_scale,
605
						      &x_scale, &y_scale,
606
						      1);
607
84
	if (status == CAIRO_STATUS_SUCCESS) {
608

            
609
84
	    if (x_scale == 0) x_scale = 1.;
610
84
	    if (y_scale == 0) y_scale = 1.;
611

            
612
84
	    user_scaled_font->snap_x_scale = x_scale;
613
84
	    user_scaled_font->snap_y_scale = y_scale;
614

            
615
	    /* since glyphs are pretty much 1.0x1.0, we can reduce error by
616
	     * scaling to a larger square.  say, 1024.x1024. */
617
84
	    fixed_scale = 1024.;
618
84
	    x_scale /= fixed_scale;
619
84
	    y_scale /= fixed_scale;
620

            
621
84
	    cairo_matrix_scale (&user_scaled_font->extent_scale, 1. / x_scale, 1. / y_scale);
622

            
623
84
	    user_scaled_font->extent_x_scale = x_scale;
624
84
	    user_scaled_font->extent_y_scale = y_scale;
625
	}
626
    }
627

            
628
84
    if (status == CAIRO_STATUS_SUCCESS &&
629
84
	font_face->scaled_font_methods.init != NULL)
630
    {
631
	/* Lock the scaled_font mutex such that user doesn't accidentally try
632
         * to use it just yet. */
633
78
	CAIRO_MUTEX_LOCK (user_scaled_font->base.mutex);
634

            
635
	/* Give away fontmap lock such that user-font can use other fonts */
636
78
	status = _cairo_scaled_font_register_placeholder_and_unlock_font_map (&user_scaled_font->base);
637
78
	if (status == CAIRO_STATUS_SUCCESS) {
638
	    cairo_surface_t *recording_surface;
639
	    cairo_t *cr;
640

            
641
78
	    recording_surface = _cairo_user_scaled_font_create_recording_surface (user_scaled_font, FALSE, NULL);
642
78
	    cr = _cairo_user_scaled_font_create_recording_context (user_scaled_font, recording_surface, FALSE);
643
78
	    cairo_surface_destroy (recording_surface);
644

            
645
78
	    status = font_face->scaled_font_methods.init (&user_scaled_font->base,
646
							  cr,
647
							  &font_extents);
648

            
649
78
	    if (status == CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED)
650
		status = CAIRO_STATUS_SUCCESS;
651

            
652
78
	    if (status == CAIRO_STATUS_SUCCESS)
653
78
		status = cairo_status (cr);
654

            
655
78
	    cairo_destroy (cr);
656

            
657
78
	    _cairo_scaled_font_unregister_placeholder_and_lock_font_map (&user_scaled_font->base);
658
	}
659

            
660
78
	CAIRO_MUTEX_UNLOCK (user_scaled_font->base.mutex);
661
    }
662

            
663
84
    if (status == CAIRO_STATUS_SUCCESS)
664
84
	status = _cairo_scaled_font_set_metrics (&user_scaled_font->base, &font_extents);
665

            
666
84
    if (status != CAIRO_STATUS_SUCCESS) {
667
        _cairo_scaled_font_fini (&user_scaled_font->base);
668
	free (user_scaled_font);
669
    } else {
670
84
        user_scaled_font->default_glyph_extents.x_bearing = 0.;
671
84
        user_scaled_font->default_glyph_extents.y_bearing = -font_extents.ascent;
672
84
        user_scaled_font->default_glyph_extents.width = 0.;
673
84
        user_scaled_font->default_glyph_extents.height = font_extents.ascent + font_extents.descent;
674
84
        user_scaled_font->default_glyph_extents.x_advance = font_extents.max_x_advance;
675
84
        user_scaled_font->default_glyph_extents.y_advance = 0.;
676

            
677
84
	*scaled_font = &user_scaled_font->base;
678
    }
679

            
680
84
    return status;
681
}
682

            
683
const cairo_font_face_backend_t _cairo_user_font_face_backend = {
684
    CAIRO_FONT_TYPE_USER,
685
    _cairo_user_font_face_create_for_toy,
686
    _cairo_font_face_destroy,
687
    _cairo_user_font_face_scaled_font_create
688
};
689

            
690

            
691
cairo_bool_t
692
141
_cairo_font_face_is_user (cairo_font_face_t *font_face)
693
{
694
141
    return font_face->backend == &_cairo_user_font_face_backend;
695
}
696

            
697
/* Implement the public interface */
698

            
699
/**
700
 * cairo_user_font_face_create:
701
 *
702
 * Creates a new user font-face.
703
 *
704
 * Use the setter functions to associate callbacks with the returned
705
 * user font.  The only mandatory callback is render_glyph.
706
 *
707
 * After the font-face is created, the user can attach arbitrary data
708
 * (the actual font data) to it using cairo_font_face_set_user_data()
709
 * and access it from the user-font callbacks by using
710
 * cairo_scaled_font_get_font_face() followed by
711
 * cairo_font_face_get_user_data().
712
 *
713
 * Return value: a newly created #cairo_font_face_t. Free with
714
 *  cairo_font_face_destroy() when you are done using it.
715
 *
716
 * Since: 1.8
717
 **/
718
cairo_font_face_t *
719
51
cairo_user_font_face_create (void)
720
{
721
    cairo_user_font_face_t *font_face;
722

            
723
51
    font_face = _cairo_calloc (sizeof (cairo_user_font_face_t));
724
51
    if (!font_face) {
725
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
726
	return (cairo_font_face_t *)&_cairo_font_face_nil;
727
    }
728

            
729
51
    _cairo_font_face_init (&font_face->base, &_cairo_user_font_face_backend);
730

            
731
51
    font_face->immutable = FALSE;
732
51
    font_face->has_color = FALSE;
733
51
    memset (&font_face->scaled_font_methods, 0, sizeof (font_face->scaled_font_methods));
734

            
735
51
    return &font_face->base;
736
}
737

            
738
/* User-font method setters */
739

            
740

            
741
/**
742
 * cairo_user_font_face_set_init_func:
743
 * @font_face: A user font face
744
 * @init_func: The init callback, or %NULL
745
 *
746
 * Sets the scaled-font initialization function of a user-font.
747
 * See #cairo_user_scaled_font_init_func_t for details of how the callback
748
 * works.
749
 *
750
 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
751
 * error will occur.  A user font-face is immutable as soon as a scaled-font
752
 * is created from it.
753
 *
754
 * Since: 1.8
755
 **/
756
void
757
45
cairo_user_font_face_set_init_func (cairo_font_face_t                  *font_face,
758
				    cairo_user_scaled_font_init_func_t  init_func)
759
{
760
    cairo_user_font_face_t *user_font_face;
761

            
762
45
    if (font_face->status)
763
	return;
764

            
765
45
    if (! _cairo_font_face_is_user (font_face)) {
766
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
767
	    return;
768
    }
769

            
770
45
    user_font_face = (cairo_user_font_face_t *) font_face;
771
45
    if (user_font_face->immutable) {
772
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE))
773
	    return;
774
    }
775
45
    user_font_face->scaled_font_methods.init = init_func;
776
}
777

            
778
/**
779
 * cairo_user_font_face_set_render_color_glyph_func:
780
 * @font_face: A user font face
781
 * @render_glyph_func: The render_glyph callback, or %NULL
782
 *
783
 * Sets the color glyph rendering function of a user-font.
784
 * See #cairo_user_scaled_font_render_glyph_func_t for details of how the callback
785
 * works.
786
 *
787
 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
788
 * error will occur.  A user font-face is immutable as soon as a scaled-font
789
 * is created from it.
790
 *
791
 * The render_glyph callback is the only mandatory callback of a
792
 * user-font. At least one of
793
 * cairo_user_font_face_set_render_color_glyph_func() or
794
 * cairo_user_font_face_set_render_glyph_func() must be called to set
795
 * a render callback. If both callbacks are set, the color glyph
796
 * render callback is invoked first. If the color glyph render
797
 * callback returns %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, the
798
 * non-color version of the callback is invoked.
799
 *
800
 * If the callback is %NULL and a glyph is tried to be rendered using
801
 * @font_face, a %CAIRO_STATUS_USER_FONT_ERROR will occur.
802
 *
803
 * Since: 1.18
804
 **/
805
void
806
6
cairo_user_font_face_set_render_color_glyph_func (cairo_font_face_t                          *font_face,
807
                                                  cairo_user_scaled_font_render_glyph_func_t  render_glyph_func)
808
{
809
    cairo_user_font_face_t *user_font_face;
810

            
811
6
    if (font_face->status)
812
	return;
813

            
814
6
    if (! _cairo_font_face_is_user (font_face)) {
815
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
816
	    return;
817
    }
818

            
819
6
    user_font_face = (cairo_user_font_face_t *) font_face;
820
6
    if (user_font_face->immutable) {
821
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE))
822
	    return;
823
    }
824
6
    user_font_face->scaled_font_methods.render_color_glyph = render_glyph_func;
825
6
    user_font_face->has_color = render_glyph_func ? TRUE : FALSE;
826
}
827

            
828
/**
829
 * cairo_user_font_face_set_render_glyph_func:
830
 * @font_face: A user font face
831
 * @render_glyph_func: The render_glyph callback, or %NULL
832
 *
833
 * Sets the glyph rendering function of a user-font.
834
 * See #cairo_user_scaled_font_render_glyph_func_t for details of how the callback
835
 * works.
836
 *
837
 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
838
 * error will occur.  A user font-face is immutable as soon as a scaled-font
839
 * is created from it.
840
 *
841
 * The render_glyph callback is the only mandatory callback of a
842
 * user-font. At least one of
843
 * cairo_user_font_face_set_render_color_glyph_func() or
844
 * cairo_user_font_face_set_render_glyph_func() must be called to set
845
 * a render callback. If both callbacks are set, the color glyph
846
 * render callback is invoked first. If the color glyph render
847
 * callback returns %CAIRO_STATUS_USER_FONT_NOT_IMPLEMENTED, the
848
 * non-color version of the callback is invoked.
849
 *
850
 * If the callback is %NULL and a glyph is tried to be rendered using
851
 * @font_face, a %CAIRO_STATUS_USER_FONT_ERROR will occur.
852
 *
853
 * Since: 1.8
854
 **/
855
void
856
48
cairo_user_font_face_set_render_glyph_func (cairo_font_face_t                          *font_face,
857
					    cairo_user_scaled_font_render_glyph_func_t  render_glyph_func)
858
{
859
    cairo_user_font_face_t *user_font_face;
860

            
861
48
    if (font_face->status)
862
	return;
863

            
864
48
    if (! _cairo_font_face_is_user (font_face)) {
865
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
866
	    return;
867
    }
868

            
869
48
    user_font_face = (cairo_user_font_face_t *) font_face;
870
48
    if (user_font_face->immutable) {
871
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE))
872
	    return;
873
    }
874
48
    user_font_face->scaled_font_methods.render_glyph = render_glyph_func;
875
}
876

            
877
/**
878
 * cairo_user_font_face_set_text_to_glyphs_func:
879
 * @font_face: A user font face
880
 * @text_to_glyphs_func: The text_to_glyphs callback, or %NULL
881
 *
882
 * Sets th text-to-glyphs conversion function of a user-font.
883
 * See #cairo_user_scaled_font_text_to_glyphs_func_t for details of how the callback
884
 * works.
885
 *
886
 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
887
 * error will occur.  A user font-face is immutable as soon as a scaled-font
888
 * is created from it.
889
 *
890
 * Since: 1.8
891
 **/
892
void
893
3
cairo_user_font_face_set_text_to_glyphs_func (cairo_font_face_t                            *font_face,
894
					      cairo_user_scaled_font_text_to_glyphs_func_t  text_to_glyphs_func)
895
{
896
    cairo_user_font_face_t *user_font_face;
897

            
898
3
    if (font_face->status)
899
	return;
900

            
901
3
    if (! _cairo_font_face_is_user (font_face)) {
902
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
903
	    return;
904
    }
905

            
906
3
    user_font_face = (cairo_user_font_face_t *) font_face;
907
3
    if (user_font_face->immutable) {
908
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE))
909
	    return;
910
    }
911
3
    user_font_face->scaled_font_methods.text_to_glyphs = text_to_glyphs_func;
912
}
913

            
914
/**
915
 * cairo_user_font_face_set_unicode_to_glyph_func:
916
 * @font_face: A user font face
917
 * @unicode_to_glyph_func: The unicode_to_glyph callback, or %NULL
918
 *
919
 * Sets the unicode-to-glyph conversion function of a user-font.
920
 * See #cairo_user_scaled_font_unicode_to_glyph_func_t for details of how the callback
921
 * works.
922
 *
923
 * The font-face should not be immutable or a %CAIRO_STATUS_USER_FONT_IMMUTABLE
924
 * error will occur.  A user font-face is immutable as soon as a scaled-font
925
 * is created from it.
926
 *
927
 * Since: 1.8
928
 **/
929
void
930
39
cairo_user_font_face_set_unicode_to_glyph_func (cairo_font_face_t                              *font_face,
931
						cairo_user_scaled_font_unicode_to_glyph_func_t  unicode_to_glyph_func)
932
{
933
    cairo_user_font_face_t *user_font_face;
934
39
    if (font_face->status)
935
	return;
936

            
937
39
    if (! _cairo_font_face_is_user (font_face)) {
938
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
939
	    return;
940
    }
941

            
942
39
    user_font_face = (cairo_user_font_face_t *) font_face;
943
39
    if (user_font_face->immutable) {
944
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_USER_FONT_IMMUTABLE))
945
	    return;
946
    }
947
39
    user_font_face->scaled_font_methods.unicode_to_glyph = unicode_to_glyph_func;
948
}
949

            
950
/* User-font method getters */
951

            
952
/**
953
 * cairo_user_font_face_get_init_func:
954
 * @font_face: A user font face
955
 *
956
 * Gets the scaled-font initialization function of a user-font.
957
 *
958
 * Return value: The init callback of @font_face
959
 * or %NULL if none set or an error has occurred.
960
 *
961
 * Since: 1.8
962
 **/
963
cairo_user_scaled_font_init_func_t
964
cairo_user_font_face_get_init_func (cairo_font_face_t *font_face)
965
{
966
    cairo_user_font_face_t *user_font_face;
967

            
968
    if (font_face->status)
969
	return NULL;
970

            
971
    if (! _cairo_font_face_is_user (font_face)) {
972
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
973
	    return NULL;
974
    }
975

            
976
    user_font_face = (cairo_user_font_face_t *) font_face;
977
    return user_font_face->scaled_font_methods.init;
978
}
979

            
980
/**
981
 * cairo_user_font_face_get_render_color_glyph_func:
982
 * @font_face: A user font face
983
 *
984
 * Gets the color glyph rendering function of a user-font.
985
 *
986
 * Return value: The render_glyph callback of @font_face
987
 * or %NULL if none set or an error has occurred.
988
 *
989
 * Since: 1.18
990
 **/
991
cairo_user_scaled_font_render_glyph_func_t
992
cairo_user_font_face_get_render_color_glyph_func (cairo_font_face_t *font_face)
993
{
994
    cairo_user_font_face_t *user_font_face;
995

            
996
    if (font_face->status)
997
	return NULL;
998

            
999
    if (! _cairo_font_face_is_user (font_face)) {
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
	    return NULL;
    }
    user_font_face = (cairo_user_font_face_t *) font_face;
    return user_font_face->scaled_font_methods.render_color_glyph;
}
/**
 * cairo_user_font_face_get_render_glyph_func:
 * @font_face: A user font face
 *
 * Gets the glyph rendering function of a user-font.
 *
 * Return value: The render_glyph callback of @font_face
 * or %NULL if none set or an error has occurred.
 *
 * Since: 1.8
 **/
cairo_user_scaled_font_render_glyph_func_t
cairo_user_font_face_get_render_glyph_func (cairo_font_face_t *font_face)
{
    cairo_user_font_face_t *user_font_face;
    if (font_face->status)
	return NULL;
    if (! _cairo_font_face_is_user (font_face)) {
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
	    return NULL;
    }
    user_font_face = (cairo_user_font_face_t *) font_face;
    return user_font_face->scaled_font_methods.render_glyph;
}
/**
 * cairo_user_font_face_get_text_to_glyphs_func:
 * @font_face: A user font face
 *
 * Gets the text-to-glyphs conversion function of a user-font.
 *
 * Return value: The text_to_glyphs callback of @font_face
 * or %NULL if none set or an error occurred.
 *
 * Since: 1.8
 **/
cairo_user_scaled_font_text_to_glyphs_func_t
cairo_user_font_face_get_text_to_glyphs_func (cairo_font_face_t *font_face)
{
    cairo_user_font_face_t *user_font_face;
    if (font_face->status)
	return NULL;
    if (! _cairo_font_face_is_user (font_face)) {
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
	    return NULL;
    }
    user_font_face = (cairo_user_font_face_t *) font_face;
    return user_font_face->scaled_font_methods.text_to_glyphs;
}
/**
 * cairo_user_font_face_get_unicode_to_glyph_func:
 * @font_face: A user font face
 *
 * Gets the unicode-to-glyph conversion function of a user-font.
 *
 * Return value: The unicode_to_glyph callback of @font_face
 * or %NULL if none set or an error occurred.
 *
 * Since: 1.8
 **/
cairo_user_scaled_font_unicode_to_glyph_func_t
cairo_user_font_face_get_unicode_to_glyph_func (cairo_font_face_t *font_face)
{
    cairo_user_font_face_t *user_font_face;
    if (font_face->status)
	return NULL;
    if (! _cairo_font_face_is_user (font_face)) {
	if (_cairo_font_face_set_error (font_face, CAIRO_STATUS_FONT_TYPE_MISMATCH))
	    return NULL;
    }
    user_font_face = (cairo_user_font_face_t *) font_face;
    return user_font_face->scaled_font_methods.unicode_to_glyph;
}
/**
 * cairo_user_scaled_font_get_foreground_marker:
 * @scaled_font: A user scaled font
 *
 * Gets the foreground pattern of the glyph currently being
 * rendered. A #cairo_user_scaled_font_render_glyph_func_t function
 * that has been set with
 * cairo_user_font_face_set_render_color_glyph_func() may call this
 * function to retrieve the current foreground pattern for the glyph
 * being rendered. The function should not be called outside of a
 * cairo_user_font_face_set_render_color_glyph_func() callback.
 *
 * The foreground marker pattern contains an internal marker to
 * indicate that it is to be substituted with the current source when
 * rendered to a surface. Querying the foreground marker will reveal a
 * solid black color, however this is not representative of the color
 * that will actually be used. Similarly, setting a solid black color
 * will render black, not the foreground pattern when the glyph is
 * painted to a surface. Using the foreground marker as the source
 * instead of cairo_user_scaled_font_get_foreground_source() in a
 * color render callback has the following benefits:
 *
 * 1. Cairo only needs to call the render callback once as it can
 * cache the recording. Cairo will substitute the actual foreground
 * color when rendering the recording.
 *
 * 2. On backends that have the concept of a foreground color in fonts such as
 * PDF, PostScript, and SVG, cairo can generate more optimal
 * output. The glyph can be included in an embedded font.
 *
 * The one drawback of the using foreground marker is the render
 * callback can not access the color components of the pattern as the
 * actual foreground pattern is not available at the time the render
 * callback is invoked. If the render callback needs to query the
 * foreground pattern, use
 * cairo_user_scaled_font_get_foreground_source().
 *
 * If the render callback simply wants to call cairo_set_source() with
 * the foreground pattern,
 * cairo_user_scaled_font_get_foreground_marker() is the preferred
 * function to use as it results in better performance than
 * cairo_user_scaled_font_get_foreground_source().
 *
 * Return value: the current foreground source marker pattern. This
 * object is owned by cairo. This object must not be modified or used
 * outside of a color render callback. To keep a reference to it,
 * you must call cairo_pattern_reference().
 *
 * Since: 1.18
 **/
cairo_pattern_t *
6
cairo_user_scaled_font_get_foreground_marker (cairo_scaled_font_t *scaled_font)
{
    cairo_user_scaled_font_t *user_scaled_font;
6
    if (scaled_font->backend != &_cairo_user_scaled_font_backend)
	return _cairo_pattern_create_in_error (CAIRO_STATUS_FONT_TYPE_MISMATCH);
6
    user_scaled_font = (cairo_user_scaled_font_t *)scaled_font;
6
    return user_scaled_font->foreground_marker;
}
/**
 * cairo_user_scaled_font_get_foreground_source:
 * @scaled_font: A user scaled font
 *
 * Gets the foreground pattern of the glyph currently being
 * rendered. A #cairo_user_scaled_font_render_glyph_func_t function
 * that has been set with
 * cairo_user_font_face_set_render_color_glyph_func() may call this
 * function to retrieve the current foreground pattern for the glyph
 * being rendered. The function should not be called outside of a
 * cairo_user_font_face_set_render_color_glyph_func() callback.
 *
 * This function returns the current source at the time the glyph is
 * rendered. Compared with
 * cairo_user_scaled_font_get_foreground_marker(), this function
 * returns the actual source pattern that will be used to render the
 * glyph.  The render callback is free to query the pattern and
 * extract color components or other pattern data. For example if the
 * render callback wants to create a gradient stop based on colors in
 * the foreground source pattern, it will need to use this function in
 * order to be able to query the colors in the foreground pattern.
 *
 * While this function does not have the restrictions on using the
 * pattern that cairo_user_scaled_font_get_foreground_marker() has, it
 * does incur a performance penalty. If a render callback calls this
 * function:
 *
 * 1. Cairo will call the render callback whenever the current pattern
 * of the context in which the glyph is rendered changes.
 *
 * 2. On backends that support font embedding (PDF, PostScript, and
 * SVG), cairo can not embed this glyph in a font. Instead the glyph
 * will be emitted as an image or sequence of drawing operations each
 * time it is used.
 *
 * Return value: the current foreground source pattern. This object is
 * owned by cairo. To keep a reference to it, you must call
 * cairo_pattern_reference().
 *
 * Since: 1.18
 **/
cairo_pattern_t *
36
cairo_user_scaled_font_get_foreground_source (cairo_scaled_font_t *scaled_font)
{
    cairo_user_scaled_font_t *user_scaled_font;
36
    if (scaled_font->backend != &_cairo_user_scaled_font_backend)
	return _cairo_pattern_create_in_error (CAIRO_STATUS_FONT_TYPE_MISMATCH);
36
    user_scaled_font = (cairo_user_scaled_font_t *)scaled_font;
36
    user_scaled_font->foreground_colors_used = TRUE;
36
    return user_scaled_font->foreground_pattern;
}