1
/* cairo - a vector graphics library with display and print output
2
 *
3
 * Copyright © 2005 Red Hat Inc.
4
 *
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.
12
 *
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., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
16
 * You should have received a copy of the MPL along with this library
17
 * in the file COPYING-MPL-1.1
18
 *
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/
23
 *
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.
27
 *
28
 * The Original Code is the cairo graphics library.
29
 *
30
 * The Initial Developer of the Original Code is University of Southern
31
 * California.
32
 *
33
 * Contributor(s):
34
 *      Owen Taylor <otaylor@redhat.com>
35
 */
36

            
37
#include "cairoint.h"
38
#include "cairo-error-private.h"
39

            
40
/**
41
 * SECTION:cairo-font-options
42
 * @Title: cairo_font_options_t
43
 * @Short_Description: How a font should be rendered
44
 * @See_Also: #cairo_scaled_font_t
45
 *
46
 * The font options specify how fonts should be rendered.  Most of the 
47
 * time the font options implied by a surface are just right and do not 
48
 * need any changes, but for pixel-based targets tweaking font options 
49
 * may result in superior output on a particular display.
50
 **/
51

            
52
static const cairo_font_options_t _cairo_font_options_nil = {
53
    CAIRO_ANTIALIAS_DEFAULT,
54
    CAIRO_SUBPIXEL_ORDER_DEFAULT,
55
    CAIRO_LCD_FILTER_DEFAULT,
56
    CAIRO_HINT_STYLE_DEFAULT,
57
    CAIRO_HINT_METRICS_DEFAULT,
58
    CAIRO_ROUND_GLYPH_POS_DEFAULT,
59
    NULL, /* variations */
60
    CAIRO_COLOR_MODE_DEFAULT,
61
    CAIRO_COLOR_PALETTE_DEFAULT,
62
    NULL, 0, /* custom palette */
63
};
64

            
65
/**
66
 * _cairo_font_options_init_default:
67
 * @options: a #cairo_font_options_t
68
 *
69
 * Initializes all fields of the font options object to default values.
70
 **/
71
void
72
194061
_cairo_font_options_init_default (cairo_font_options_t *options)
73
{
74
194061
    options->antialias = CAIRO_ANTIALIAS_DEFAULT;
75
194061
    options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
76
194061
    options->lcd_filter = CAIRO_LCD_FILTER_DEFAULT;
77
194061
    options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
78
194061
    options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
79
194061
    options->round_glyph_positions = CAIRO_ROUND_GLYPH_POS_DEFAULT;
80
194061
    options->variations = NULL;
81
194061
    options->color_mode = CAIRO_COLOR_MODE_DEFAULT;
82
194061
    options->palette_index = CAIRO_COLOR_PALETTE_DEFAULT;
83
194061
    options->custom_palette = NULL;
84
194061
    options->custom_palette_size = 0;
85
194061
}
86

            
87
void
88
321195
_cairo_font_options_init_copy (cairo_font_options_t		*options,
89
			       const cairo_font_options_t	*other)
90
{
91
321195
    options->antialias = other->antialias;
92
321195
    options->subpixel_order = other->subpixel_order;
93
321195
    options->lcd_filter = other->lcd_filter;
94
321195
    options->hint_style = other->hint_style;
95
321195
    options->hint_metrics = other->hint_metrics;
96
321195
    options->round_glyph_positions = other->round_glyph_positions;
97
321195
    options->variations = other->variations ? strdup (other->variations) : NULL;
98
321195
    options->color_mode = other->color_mode;
99
321195
    options->palette_index = other->palette_index;
100
321195
    options->custom_palette_size = other->custom_palette_size;
101
321195
    options->custom_palette = NULL;
102
321195
    if (other->custom_palette) {
103
84
        options->custom_palette = (cairo_palette_color_t *) malloc (sizeof (cairo_palette_color_t) * options->custom_palette_size);
104
84
        memcpy (options->custom_palette, other->custom_palette, sizeof (cairo_palette_color_t) * options->custom_palette_size);
105
    }
106
321195
}
107

            
108
cairo_bool_t
109
30153
_cairo_font_options_compare (const cairo_font_options_t	*a,
110
                             const cairo_font_options_t	*b)
111
{
112
30153
    if (a->antialias != b->antialias ||
113
162
        a->subpixel_order != b->subpixel_order ||
114
159
        a->lcd_filter != b->lcd_filter ||
115
159
        a->hint_style != b->hint_style ||
116
129
        a->hint_metrics != b->hint_metrics ||
117
30
        a->round_glyph_positions != b->round_glyph_positions ||
118
30
        a->color_mode != b->color_mode ||
119
24
        a->palette_index != b->palette_index ||
120
18
        a->custom_palette_size != b->custom_palette_size)
121
    {
122
30135
        return FALSE;
123
    }
124

            
125
18
    if (a->variations && b->variations && strcmp (a->variations, b->variations) != 0)
126
        return FALSE;
127
18
    else if (a->variations != b->variations)
128
        return FALSE;
129

            
130
18
    if (a->custom_palette && b->custom_palette &&
131
        memcmp (a->custom_palette, b->custom_palette, sizeof (cairo_palette_color_t) * a->custom_palette_size) != 0)
132
    {
133
        return FALSE;
134
    }
135
18
    else if (a->custom_palette != b->custom_palette)
136
    {
137
        return FALSE;
138
    }
139

            
140
18
    return TRUE;
141
}
142

            
143
/**
144
 * cairo_font_options_create:
145
 *
146
 * Allocates a new font options object with all options initialized
147
 *  to default values.
148
 *
149
 * Return value: a newly allocated #cairo_font_options_t. Free with
150
 *   cairo_font_options_destroy(). This function always returns a
151
 *   valid pointer; if memory cannot be allocated, then a special
152
 *   error object is returned where all operations on the object do nothing.
153
 *   You can check for this with cairo_font_options_status().
154
 *
155
 * Since: 1.0
156
 **/
157
cairo_font_options_t *
158
1891
cairo_font_options_create (void)
159
{
160
    cairo_font_options_t *options;
161

            
162
1891
    options = _cairo_calloc (sizeof (cairo_font_options_t));
163
1891
    if (!options) {
164
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
165
	return (cairo_font_options_t *) &_cairo_font_options_nil;
166
    }
167

            
168
1891
    _cairo_font_options_init_default (options);
169

            
170
1891
    return options;
171
}
172

            
173
/**
174
 * cairo_font_options_copy:
175
 * @original: a #cairo_font_options_t
176
 *
177
 * Allocates a new font options object copying the option values from
178
 *  @original.
179
 *
180
 * Return value: a newly allocated #cairo_font_options_t. Free with
181
 *   cairo_font_options_destroy(). This function always returns a
182
 *   valid pointer; if memory cannot be allocated, then a special
183
 *   error object is returned where all operations on the object do nothing.
184
 *   You can check for this with cairo_font_options_status().
185
 *
186
 * Since: 1.0
187
 **/
188
cairo_font_options_t *
189
1
cairo_font_options_copy (const cairo_font_options_t *original)
190
{
191
    cairo_font_options_t *options;
192

            
193
1
    if (cairo_font_options_status ((cairo_font_options_t *) original))
194
1
	return (cairo_font_options_t *) &_cairo_font_options_nil;
195

            
196
    options = _cairo_calloc (sizeof (cairo_font_options_t));
197
    if (!options) {
198
	_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
199
	return (cairo_font_options_t *) &_cairo_font_options_nil;
200
    }
201

            
202
    _cairo_font_options_init_copy (options, original);
203

            
204
    return options;
205
}
206

            
207
void
208
343931
_cairo_font_options_fini (cairo_font_options_t *options)
209
{
210
343931
    free (options->variations);
211
343931
    free (options->custom_palette);
212
343931
}
213

            
214
/**
215
 * cairo_font_options_destroy:
216
 * @options: a #cairo_font_options_t
217
 *
218
 * Destroys a #cairo_font_options_t object created with
219
 * cairo_font_options_create() or cairo_font_options_copy().
220
 *
221
 * Since: 1.0
222
 **/
223
void
224
1889
cairo_font_options_destroy (cairo_font_options_t *options)
225
{
226
1889
    if (cairo_font_options_status (options))
227
2
	return;
228

            
229
1887
    _cairo_font_options_fini (options);
230
1887
    free (options);
231
}
232

            
233
/**
234
 * cairo_font_options_status:
235
 * @options: a #cairo_font_options_t
236
 *
237
 * Checks whether an error has previously occurred for this
238
 * font options object
239
 *
240
 * Return value: %CAIRO_STATUS_SUCCESS, %CAIRO_STATUS_NO_MEMORY, or
241
 *	%CAIRO_STATUS_NULL_POINTER.
242
 *
243
 * Since: 1.0
244
 **/
245
cairo_status_t
246
1256244
cairo_font_options_status (cairo_font_options_t *options)
247
{
248
1256244
    if (options == NULL)
249
23
	return CAIRO_STATUS_NULL_POINTER;
250
1256221
    else if (options == (cairo_font_options_t *) &_cairo_font_options_nil)
251
7
	return CAIRO_STATUS_NO_MEMORY;
252
    else
253
1256214
	return CAIRO_STATUS_SUCCESS;
254
}
255

            
256
/**
257
 * cairo_font_options_merge:
258
 * @options: a #cairo_font_options_t
259
 * @other: another #cairo_font_options_t
260
 *
261
 * Merges non-default options from @other into @options, replacing
262
 * existing values. This operation can be thought of as somewhat
263
 * similar to compositing @other onto @options with the operation
264
 * of %CAIRO_OPERATOR_OVER.
265
 *
266
 * Since: 1.0
267
 **/
268
void
269
130741
cairo_font_options_merge (cairo_font_options_t       *options,
270
			  const cairo_font_options_t *other)
271
{
272
130741
    if (cairo_font_options_status (options))
273
1
	return;
274

            
275
130740
    if (cairo_font_options_status ((cairo_font_options_t *) other))
276
2
	return;
277

            
278
130738
    if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
279
93960
	options->antialias = other->antialias;
280
130738
    if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
281
42
	options->subpixel_order = other->subpixel_order;
282
130738
    if (other->lcd_filter != CAIRO_LCD_FILTER_DEFAULT)
283
	options->lcd_filter = other->lcd_filter;
284
130738
    if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
285
93903
	options->hint_style = other->hint_style;
286
130738
    if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
287
93963
	options->hint_metrics = other->hint_metrics;
288
130738
    if (other->round_glyph_positions != CAIRO_ROUND_GLYPH_POS_DEFAULT)
289
27366
	options->round_glyph_positions = other->round_glyph_positions;
290

            
291
130738
    if (other->variations) {
292
3
      if (options->variations) {
293
        char *p;
294

            
295
        /* 'merge' variations by concatenating - later entries win */
296
        p = malloc (strlen (other->variations) + strlen (options->variations) + 2);
297
        p[0] = 0;
298
        strcat (p, options->variations);
299
        strcat (p, ",");
300
        strcat (p, other->variations);
301
        free (options->variations);
302
        options->variations = p;
303
      }
304
      else {
305
3
        options->variations = strdup (other->variations);
306
      }
307
    }
308

            
309
130738
    if (other->color_mode != CAIRO_COLOR_MODE_DEFAULT)
310
36
	options->color_mode = other->color_mode;
311
130738
    if (other->palette_index != CAIRO_COLOR_PALETTE_DEFAULT)
312
6
	options->palette_index = other->palette_index;
313
130738
    if (other->custom_palette) {
314
6
        options->custom_palette_size = other->custom_palette_size;
315
6
        free (options->custom_palette);
316
6
        options->custom_palette = (cairo_palette_color_t *) malloc (sizeof (cairo_palette_color_t) * options->custom_palette_size);
317
6
        memcpy (options->custom_palette, other->custom_palette, sizeof (cairo_palette_color_t) * options->custom_palette_size);
318
    }
319
}
320

            
321
/**
322
 * cairo_font_options_equal:
323
 * @options: a #cairo_font_options_t
324
 * @other: another #cairo_font_options_t
325
 *
326
 * Compares two font options objects for equality.
327
 *
328
 * Return value: %TRUE if all fields of the two font options objects match.
329
 *	Note that this function will return %FALSE if either object is in
330
 *	error.
331
 *
332
 * Since: 1.0
333
 **/
334
cairo_bool_t
335
246174
cairo_font_options_equal (const cairo_font_options_t *options,
336
			  const cairo_font_options_t *other)
337
{
338
246174
    if (cairo_font_options_status ((cairo_font_options_t *) options))
339
3
	return FALSE;
340
246171
    if (cairo_font_options_status ((cairo_font_options_t *) other))
341
2
	return FALSE;
342

            
343
246169
    if (options == other)
344
1
	return TRUE;
345

            
346
492267
    return (options->antialias == other->antialias &&
347
246099
	    options->subpixel_order == other->subpixel_order &&
348
246099
	    options->lcd_filter == other->lcd_filter &&
349
246099
	    options->hint_style == other->hint_style &&
350
246087
	    options->hint_metrics == other->hint_metrics &&
351
240399
	    options->round_glyph_positions == other->round_glyph_positions &&
352
240372
            ((options->variations == NULL && other->variations == NULL) ||
353
             (options->variations != NULL && other->variations != NULL &&
354
              strcmp (options->variations, other->variations) == 0)) &&
355
240372
	    options->color_mode == other->color_mode &&
356
732630
	    options->palette_index == other->palette_index &&
357
240363
            ((options->custom_palette == NULL && other->custom_palette == NULL) ||
358
6
             (options->custom_palette != NULL && other->custom_palette != NULL &&
359
              options->custom_palette_size == other->custom_palette_size &&
360
              memcmp (options->custom_palette, other->custom_palette,
361
                      sizeof (cairo_palette_color_t) * options->custom_palette_size) == 0)));
362
}
363

            
364
/**
365
 * cairo_font_options_hash:
366
 * @options: a #cairo_font_options_t
367
 *
368
 * Compute a hash for the font options object; this value will
369
 * be useful when storing an object containing a #cairo_font_options_t
370
 * in a hash table.
371
 *
372
 * Return value: the hash value for the font options object.
373
 *   The return value can be cast to a 32-bit type if a
374
 *   32-bit hash value is needed.
375
 *
376
 * Since: 1.0
377
 **/
378
unsigned long
379
81685
cairo_font_options_hash (const cairo_font_options_t *options)
380
{
381
81685
    unsigned long hash = 0;
382

            
383
81685
    if (cairo_font_options_status ((cairo_font_options_t *) options))
384
4
	options = &_cairo_font_options_nil; /* force default values */
385

            
386
81685
    if (options->variations)
387
8
      hash = _cairo_string_hash (options->variations, strlen (options->variations));
388

            
389
81685
    hash ^= options->palette_index;
390

            
391
81685
    return ((options->antialias) |
392
81685
	    (options->subpixel_order << 4) |
393
81685
	    (options->lcd_filter << 8) |
394
81685
	    (options->hint_style << 12) |
395
81685
	    (options->hint_metrics << 16) |
396
81685
            (options->color_mode << 20)) ^ hash;
397
}
398

            
399
/**
400
 * cairo_font_options_set_antialias:
401
 * @options: a #cairo_font_options_t
402
 * @antialias: the new antialiasing mode
403
 *
404
 * Sets the antialiasing mode for the font options object. This
405
 * specifies the type of antialiasing to do when rendering text.
406
 *
407
 * Since: 1.0
408
 **/
409
void
410
1784
cairo_font_options_set_antialias (cairo_font_options_t *options,
411
				  cairo_antialias_t     antialias)
412
{
413
1784
    if (cairo_font_options_status (options))
414
1
	return;
415

            
416
1783
    options->antialias = antialias;
417
}
418

            
419
/**
420
 * cairo_font_options_get_antialias:
421
 * @options: a #cairo_font_options_t
422
 *
423
 * Gets the antialiasing mode for the font options object.
424
 *
425
 * Return value: the antialiasing mode
426
 *
427
 * Since: 1.0
428
 **/
429
cairo_antialias_t
430
2
cairo_font_options_get_antialias (const cairo_font_options_t *options)
431
{
432
2
    if (cairo_font_options_status ((cairo_font_options_t *) options))
433
1
	return CAIRO_ANTIALIAS_DEFAULT;
434

            
435
1
    return options->antialias;
436
}
437

            
438
/**
439
 * cairo_font_options_set_subpixel_order:
440
 * @options: a #cairo_font_options_t
441
 * @subpixel_order: the new subpixel order
442
 *
443
 * Sets the subpixel order for the font options object. The subpixel
444
 * order specifies the order of color elements within each pixel on
445
 * the display device when rendering with an antialiasing mode of
446
 * %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
447
 * #cairo_subpixel_order_t for full details.
448
 *
449
 * Since: 1.0
450
 **/
451
void
452
22
cairo_font_options_set_subpixel_order (cairo_font_options_t   *options,
453
				       cairo_subpixel_order_t  subpixel_order)
454
{
455
22
    if (cairo_font_options_status (options))
456
1
	return;
457

            
458
21
    options->subpixel_order = subpixel_order;
459
}
460

            
461
/**
462
 * cairo_font_options_get_subpixel_order:
463
 * @options: a #cairo_font_options_t
464
 *
465
 * Gets the subpixel order for the font options object.
466
 * See the documentation for #cairo_subpixel_order_t for full details.
467
 *
468
 * Return value: the subpixel order for the font options object
469
 *
470
 * Since: 1.0
471
 **/
472
cairo_subpixel_order_t
473
2
cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
474
{
475
2
    if (cairo_font_options_status ((cairo_font_options_t *) options))
476
1
	return CAIRO_SUBPIXEL_ORDER_DEFAULT;
477

            
478
1
    return options->subpixel_order;
479
}
480

            
481
/**
482
 * _cairo_font_options_set_lcd_filter:
483
 * @options: a #cairo_font_options_t
484
 * @lcd_filter: the new LCD filter
485
 *
486
 * Sets the LCD filter for the font options object. The LCD filter
487
 * specifies how pixels are filtered when rendered with an antialiasing
488
 * mode of %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
489
 * #cairo_lcd_filter_t for full details.
490
 **/
491
void
492
_cairo_font_options_set_lcd_filter (cairo_font_options_t *options,
493
				    cairo_lcd_filter_t    lcd_filter)
494
{
495
    if (cairo_font_options_status (options))
496
	return;
497

            
498
    options->lcd_filter = lcd_filter;
499
}
500

            
501
/**
502
 * _cairo_font_options_get_lcd_filter:
503
 * @options: a #cairo_font_options_t
504
 *
505
 * Gets the LCD filter for the font options object.
506
 * See the documentation for #cairo_lcd_filter_t for full details.
507
 *
508
 * Return value: the LCD filter for the font options object
509
 **/
510
cairo_lcd_filter_t
511
_cairo_font_options_get_lcd_filter (const cairo_font_options_t *options)
512
{
513
    if (cairo_font_options_status ((cairo_font_options_t *) options))
514
	return CAIRO_LCD_FILTER_DEFAULT;
515

            
516
    return options->lcd_filter;
517
}
518

            
519
/**
520
 * _cairo_font_options_set_round_glyph_positions:
521
 * @options: a #cairo_font_options_t
522
 * @round: the new rounding value
523
 *
524
 * Sets the rounding options for the font options object. If rounding is set, a
525
 * glyph's position will be rounded to integer values.
526
 **/
527
void
528
22058
_cairo_font_options_set_round_glyph_positions (cairo_font_options_t *options,
529
					       cairo_round_glyph_positions_t  round)
530
{
531
22058
    if (cairo_font_options_status (options))
532
	return;
533

            
534
22058
    options->round_glyph_positions = round;
535
}
536

            
537
/**
538
 * _cairo_font_options_get_round_glyph_positions:
539
 * @options: a #cairo_font_options_t
540
 *
541
 * Gets the glyph position rounding option for the font options object.
542
 *
543
 * Return value: The round glyph posistions flag for the font options object.
544
 **/
545
cairo_round_glyph_positions_t
546
97962
_cairo_font_options_get_round_glyph_positions (const cairo_font_options_t *options)
547
{
548
97962
    if (cairo_font_options_status ((cairo_font_options_t *) options))
549
	return CAIRO_ROUND_GLYPH_POS_DEFAULT;
550

            
551
97962
    return options->round_glyph_positions;
552
}
553

            
554
/**
555
 * cairo_font_options_set_hint_style:
556
 * @options: a #cairo_font_options_t
557
 * @hint_style: the new hint style
558
 *
559
 * Sets the hint style for font outlines for the font options object.
560
 * This controls whether to fit font outlines to the pixel grid,
561
 * and if so, whether to optimize for fidelity or contrast.
562
 * See the documentation for #cairo_hint_style_t for full details.
563
 *
564
 * Since: 1.0
565
 **/
566
void
567
1775
cairo_font_options_set_hint_style (cairo_font_options_t *options,
568
				   cairo_hint_style_t    hint_style)
569
{
570
1775
    if (cairo_font_options_status (options))
571
1
	return;
572

            
573
1774
    options->hint_style = hint_style;
574
}
575

            
576
/**
577
 * cairo_font_options_get_hint_style:
578
 * @options: a #cairo_font_options_t
579
 *
580
 * Gets the hint style for font outlines for the font options object.
581
 * See the documentation for #cairo_hint_style_t for full details.
582
 *
583
 * Return value: the hint style for the font options object
584
 *
585
 * Since: 1.0
586
 **/
587
cairo_hint_style_t
588
2
cairo_font_options_get_hint_style (const cairo_font_options_t *options)
589
{
590
2
    if (cairo_font_options_status ((cairo_font_options_t *) options))
591
1
	return CAIRO_HINT_STYLE_DEFAULT;
592

            
593
1
    return options->hint_style;
594
}
595

            
596
/**
597
 * cairo_font_options_set_hint_metrics:
598
 * @options: a #cairo_font_options_t
599
 * @hint_metrics: the new metrics hinting mode
600
 *
601
 * Sets the metrics hinting mode for the font options object. This
602
 * controls whether metrics are quantized to integer values in
603
 * device units.
604
 * See the documentation for #cairo_hint_metrics_t for full details.
605
 *
606
 * Since: 1.0
607
 **/
608
void
609
23808
cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
610
				     cairo_hint_metrics_t  hint_metrics)
611
{
612
23808
    if (cairo_font_options_status (options))
613
1
	return;
614

            
615
23807
    options->hint_metrics = hint_metrics;
616
}
617

            
618
/**
619
 * cairo_font_options_get_hint_metrics:
620
 * @options: a #cairo_font_options_t
621
 *
622
 * Gets the metrics hinting mode for the font options object.
623
 * See the documentation for #cairo_hint_metrics_t for full details.
624
 *
625
 * Return value: the metrics hinting mode for the font options object
626
 *
627
 * Since: 1.0
628
 **/
629
cairo_hint_metrics_t
630
2
cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
631
{
632
2
    if (cairo_font_options_status ((cairo_font_options_t *) options))
633
1
	return CAIRO_HINT_METRICS_DEFAULT;
634

            
635
1
    return options->hint_metrics;
636
}
637

            
638
/**
639
 * cairo_font_options_set_variations:
640
 * @options: a #cairo_font_options_t
641
 * @variations: the new font variations, or %NULL
642
 *
643
 * Sets the OpenType font variations for the font options object.
644
 * Font variations are specified as a string with a format that
645
 * is similar to the CSS font-variation-settings. The string contains
646
 * a comma-separated list of axis assignments, which each assignment
647
 * consists of a 4-character axis name and a value, separated by
648
 * whitespace and optional equals sign.
649
 *
650
 * Examples:
651
 *
652
 * wght=200,wdth=140.5
653
 *
654
 * wght 200 , wdth 140.5
655
 *
656
 * Since: 1.16
657
 **/
658
void
659
4
cairo_font_options_set_variations (cairo_font_options_t *options,
660
                                   const char           *variations)
661
{
662
4
  char *tmp = variations ? strdup (variations) : NULL;
663
4
  free (options->variations);
664
4
  options->variations = tmp;
665
4
}
666

            
667
/**
668
 * cairo_font_options_get_variations:
669
 * @options: a #cairo_font_options_t
670
 *
671
 * Gets the OpenType font variations for the font options object.
672
 * See cairo_font_options_set_variations() for details about the
673
 * string format.
674
 *
675
 * Return value: the font variations for the font options object. The
676
 *   returned string belongs to the @options and must not be modified.
677
 *   It is valid until either the font options object is destroyed or
678
 *   the font variations in this object is modified with
679
 *   cairo_font_options_set_variations().
680
 *
681
 * Since: 1.16
682
 **/
683
const char *
684
1
cairo_font_options_get_variations (cairo_font_options_t *options)
685
{
686
1
  return options->variations;
687
}
688

            
689
/**
690
 * cairo_font_options_set_color_mode:
691
 * @options: a #cairo_font_options_t
692
 * @color_mode: the new color mode
693
 *
694
 * Sets the color mode for the font options object. This controls
695
 * whether color fonts are to be rendered in color or as outlines.
696
 * See the documentation for #cairo_color_mode_t for full details.
697
 *
698
 * Since: 1.18
699
 **/
700
cairo_public void
701
27
cairo_font_options_set_color_mode (cairo_font_options_t *options,
702
                                   cairo_color_mode_t    color_mode)
703
{
704
27
    if (cairo_font_options_status (options))
705
	return;
706

            
707
27
    options->color_mode = color_mode;
708
}
709

            
710
/**
711
 * cairo_font_options_get_color_mode:
712
 * @options: a #cairo_font_options_t
713
 *
714
 * Gets the color mode for the font options object.
715
 * See the documentation for #cairo_color_mode_t for full details.
716
 *
717
 * Return value: the color mode for the font options object
718
 *
719
 * Since: 1.18
720
 **/
721
cairo_public cairo_color_mode_t
722
cairo_font_options_get_color_mode (const cairo_font_options_t *options)
723
{
724
    if (cairo_font_options_status ((cairo_font_options_t *) options))
725
	return CAIRO_COLOR_MODE_DEFAULT;
726

            
727
    return options->color_mode;
728
}
729

            
730
/**
731
 * CAIRO_COLOR_PALETTE_DEFAULT:
732
 *
733
 * The default color palette index.
734
 *
735
 * Since: 1.18
736
 **/
737

            
738
/**
739
 * cairo_font_options_set_color_palette:
740
 * @options: a #cairo_font_options_t
741
 * @palette_index: the palette index in the CPAL table
742
 *
743
 * Sets the OpenType font color palette for the font options
744
 * object. OpenType color fonts with a CPAL table may contain multiple
745
 * palettes. The default color palette index is %CAIRO_COLOR_PALETTE_DEFAULT.
746
 *
747
 * If @palette_index is invalid, the default palette is used.
748
 *
749
 * Individual colors within the palette may be overriden with
750
 * cairo_font_options_set_custom_palette_color().
751
 *
752
 * Since: 1.18
753
 **/
754
void
755
10
cairo_font_options_set_color_palette (cairo_font_options_t *options,
756
                                      unsigned int          palette_index)
757
{
758
10
    if (cairo_font_options_status (options))
759
1
	return;
760

            
761
9
    options->palette_index = palette_index;
762
}
763

            
764
/**
765
 * cairo_font_options_get_color_palette:
766
 * @options: a #cairo_font_options_t
767
 *
768
 * Gets the current OpenType color font palette for the font options object.
769
 *
770
 * Return value: the palette index
771
 *
772
 * Since: 1.18
773
 **/
774
unsigned int
775
2
cairo_font_options_get_color_palette (const cairo_font_options_t *options)
776
{
777
2
    if (cairo_font_options_status ((cairo_font_options_t *) options))
778
1
	return CAIRO_COLOR_PALETTE_DEFAULT;
779

            
780
1
    return options->palette_index;
781
}
782

            
783
/**
784
 * cairo_font_options_set_custom_palette_color:
785
 * @options: a #cairo_font_options_t
786
 * @index: the index of the color to set
787
 * @red: red component of color
788
 * @green: green component of color
789
 * @blue: blue component of color
790
 * @alpha: alpha component of color
791
 *
792
 * Sets a custom palette color for the font options object. This
793
 * overrides the palette color at the specified color index. This override is
794
 * independent of the selected palette index and will remain in place
795
 * even if cairo_font_options_set_color_palette() is called to change
796
 * the palette index.
797
 *
798
 * It is only possible to override color indexes already in the font
799
 * palette.
800
 *
801
 * Since: 1.18
802
 */
803
void
804
9
cairo_font_options_set_custom_palette_color (cairo_font_options_t *options,
805
                                             unsigned int index,
806
                                             double red, double green,
807
                                             double blue, double alpha)
808
{
809
    unsigned int idx;
810

            
811
12
    for (idx = 0; idx < options->custom_palette_size; idx++) {
812
3
        if (options->custom_palette[idx].index == index) {
813
            break;
814
        }
815
    }
816

            
817
9
    if (idx == options->custom_palette_size) {
818
9
        options->custom_palette_size++;
819
9
        options->custom_palette = (cairo_palette_color_t *)
820
9
            _cairo_realloc_ab (options->custom_palette,
821
                               sizeof (cairo_palette_color_t),
822
9
                               options->custom_palette_size);
823
    }
824

            
825
    /* beware of holes */
826
9
    memset (&options->custom_palette[idx], 0, sizeof (cairo_palette_color_t));
827

            
828
9
    options->custom_palette[idx].index = index;
829
9
    options->custom_palette[idx].red = red;
830
9
    options->custom_palette[idx].green = green;
831
9
    options->custom_palette[idx].blue = blue;
832
9
    options->custom_palette[idx].alpha = alpha;
833
9
}
834

            
835
/**
836
 * cairo_font_options_get_custom_palette_color:
837
 * @options: a #cairo_font_options_t
838
 * @index: the index of the color to get
839
 * @red: return location for red component of color
840
 * @green: return location for green component of color
841
 * @blue: return location for blue component of color
842
 * @alpha: return location for alpha component of color
843
 *
844
 * Gets the custom palette color for the color index for the font options object.
845
 *
846
 * Returns: `CAIRO_STATUS_SUCCESS` if a custom palette color is
847
 * returned, `CAIRO_STATUS_INVALID_INDEX` if no custom color exists
848
 * for the color index.
849
 *
850
 * Since: 1.18
851
 */
852
cairo_status_t
853
cairo_font_options_get_custom_palette_color (cairo_font_options_t *options,
854
                                             unsigned int index,
855
                                             double *red, double *green,
856
                                             double *blue, double *alpha)
857
{
858
    unsigned int idx;
859

            
860
    for (idx = 0; idx < options->custom_palette_size; idx++) {
861
        if (options->custom_palette[idx].index == index) {
862
            *red = options->custom_palette[idx].red;
863
            *green = options->custom_palette[idx].green;
864
            *blue = options->custom_palette[idx].blue;
865
            *alpha = options->custom_palette[idx].alpha;
866
            return CAIRO_STATUS_SUCCESS;
867
        }
868
    }
869

            
870
    return CAIRO_STATUS_INVALID_INDEX;
871
}