ad28745e6b9236fba128ef321d79e21a61e8ec8d
[framework/graphics/cairo.git] / src / cairo-font-options.c
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 };
60
61 /**
62  * _cairo_font_options_init_default:
63  * @options: a #cairo_font_options_t
64  *
65  * Initializes all fields of the font options object to default values.
66  **/
67 void
68 _cairo_font_options_init_default (cairo_font_options_t *options)
69 {
70     options->antialias = CAIRO_ANTIALIAS_DEFAULT;
71     options->subpixel_order = CAIRO_SUBPIXEL_ORDER_DEFAULT;
72     options->lcd_filter = CAIRO_LCD_FILTER_DEFAULT;
73     options->hint_style = CAIRO_HINT_STYLE_DEFAULT;
74     options->hint_metrics = CAIRO_HINT_METRICS_DEFAULT;
75     options->round_glyph_positions = CAIRO_ROUND_GLYPH_POS_DEFAULT;
76 }
77
78 void
79 _cairo_font_options_init_copy (cairo_font_options_t             *options,
80                                const cairo_font_options_t       *other)
81 {
82     options->antialias = other->antialias;
83     options->subpixel_order = other->subpixel_order;
84     options->lcd_filter = other->lcd_filter;
85     options->hint_style = other->hint_style;
86     options->hint_metrics = other->hint_metrics;
87     options->round_glyph_positions = other->round_glyph_positions;
88 }
89
90 /**
91  * cairo_font_options_create:
92  *
93  * Allocates a new font options object with all options initialized
94  *  to default values.
95  *
96  * Return value: a newly allocated #cairo_font_options_t. Free with
97  *   cairo_font_options_destroy(). This function always returns a
98  *   valid pointer; if memory cannot be allocated, then a special
99  *   error object is returned where all operations on the object do nothing.
100  *   You can check for this with cairo_font_options_status().
101  *
102  * Since: 1.0
103  **/
104 cairo_font_options_t *
105 cairo_font_options_create (void)
106 {
107     cairo_font_options_t *options;
108
109     options = malloc (sizeof (cairo_font_options_t));
110     if (!options) {
111         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
112         return (cairo_font_options_t *) &_cairo_font_options_nil;
113     }
114
115     _cairo_font_options_init_default (options);
116
117     return options;
118 }
119
120 /**
121  * cairo_font_options_copy:
122  * @original: a #cairo_font_options_t
123  *
124  * Allocates a new font options object copying the option values from
125  *  @original.
126  *
127  * Return value: a newly allocated #cairo_font_options_t. Free with
128  *   cairo_font_options_destroy(). This function always returns a
129  *   valid pointer; if memory cannot be allocated, then a special
130  *   error object is returned where all operations on the object do nothing.
131  *   You can check for this with cairo_font_options_status().
132  *
133  * Since: 1.0
134  **/
135 cairo_font_options_t *
136 cairo_font_options_copy (const cairo_font_options_t *original)
137 {
138     cairo_font_options_t *options;
139
140     if (cairo_font_options_status ((cairo_font_options_t *) original))
141         return (cairo_font_options_t *) &_cairo_font_options_nil;
142
143     options = malloc (sizeof (cairo_font_options_t));
144     if (!options) {
145         _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
146         return (cairo_font_options_t *) &_cairo_font_options_nil;
147     }
148
149     _cairo_font_options_init_copy (options, original);
150
151     return options;
152 }
153
154 /**
155  * cairo_font_options_destroy:
156  * @options: a #cairo_font_options_t
157  *
158  * Destroys a #cairo_font_options_t object created with
159  * cairo_font_options_create() or cairo_font_options_copy().
160  *
161  * Since: 1.0
162  **/
163 void
164 cairo_font_options_destroy (cairo_font_options_t *options)
165 {
166     if (cairo_font_options_status (options))
167         return;
168
169     free (options);
170 }
171
172 /**
173  * cairo_font_options_status:
174  * @options: a #cairo_font_options_t
175  *
176  * Checks whether an error has previously occurred for this
177  * font options object
178  *
179  * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY
180  *
181  * Since: 1.0
182  **/
183 cairo_status_t
184 cairo_font_options_status (cairo_font_options_t *options)
185 {
186     if (options == NULL)
187         return CAIRO_STATUS_NULL_POINTER;
188     else if (options == (cairo_font_options_t *) &_cairo_font_options_nil)
189         return CAIRO_STATUS_NO_MEMORY;
190     else
191         return CAIRO_STATUS_SUCCESS;
192 }
193 slim_hidden_def (cairo_font_options_status);
194
195 /**
196  * cairo_font_options_merge:
197  * @options: a #cairo_font_options_t
198  * @other: another #cairo_font_options_t
199  *
200  * Merges non-default options from @other into @options, replacing
201  * existing values. This operation can be thought of as somewhat
202  * similar to compositing @other onto @options with the operation
203  * of %CAIRO_OPERATOR_OVER.
204  *
205  * Since: 1.0
206  **/
207 void
208 cairo_font_options_merge (cairo_font_options_t       *options,
209                           const cairo_font_options_t *other)
210 {
211     if (cairo_font_options_status (options))
212         return;
213
214     if (cairo_font_options_status ((cairo_font_options_t *) other))
215         return;
216
217     if (other->antialias != CAIRO_ANTIALIAS_DEFAULT)
218         options->antialias = other->antialias;
219     if (other->subpixel_order != CAIRO_SUBPIXEL_ORDER_DEFAULT)
220         options->subpixel_order = other->subpixel_order;
221     if (other->lcd_filter != CAIRO_LCD_FILTER_DEFAULT)
222         options->lcd_filter = other->lcd_filter;
223     if (other->hint_style != CAIRO_HINT_STYLE_DEFAULT)
224         options->hint_style = other->hint_style;
225     if (other->hint_metrics != CAIRO_HINT_METRICS_DEFAULT)
226         options->hint_metrics = other->hint_metrics;
227     if (other->round_glyph_positions != CAIRO_ROUND_GLYPH_POS_DEFAULT)
228         options->round_glyph_positions = other->round_glyph_positions;
229 }
230 slim_hidden_def (cairo_font_options_merge);
231
232 /**
233  * cairo_font_options_equal:
234  * @options: a #cairo_font_options_t
235  * @other: another #cairo_font_options_t
236  *
237  * Compares two font options objects for equality.
238  *
239  * Return value: %TRUE if all fields of the two font options objects match.
240  *      Note that this function will return %FALSE if either object is in
241  *      error.
242  *
243  * Since: 1.0
244  **/
245 cairo_bool_t
246 cairo_font_options_equal (const cairo_font_options_t *options,
247                           const cairo_font_options_t *other)
248 {
249     if (cairo_font_options_status ((cairo_font_options_t *) options))
250         return FALSE;
251     if (cairo_font_options_status ((cairo_font_options_t *) other))
252         return FALSE;
253
254     if (options == other)
255         return TRUE;
256
257     return (options->antialias == other->antialias &&
258             options->subpixel_order == other->subpixel_order &&
259             options->lcd_filter == other->lcd_filter &&
260             options->hint_style == other->hint_style &&
261             options->hint_metrics == other->hint_metrics &&
262             options->round_glyph_positions == other->round_glyph_positions);
263 }
264 slim_hidden_def (cairo_font_options_equal);
265
266 /**
267  * cairo_font_options_hash:
268  * @options: a #cairo_font_options_t
269  *
270  * Compute a hash for the font options object; this value will
271  * be useful when storing an object containing a #cairo_font_options_t
272  * in a hash table.
273  *
274  * Return value: the hash value for the font options object.
275  *   The return value can be cast to a 32-bit type if a
276  *   32-bit hash value is needed.
277  *
278  * Since: 1.0
279  **/
280 unsigned long
281 cairo_font_options_hash (const cairo_font_options_t *options)
282 {
283     if (cairo_font_options_status ((cairo_font_options_t *) options))
284         options = &_cairo_font_options_nil; /* force default values */
285
286     return ((options->antialias) |
287             (options->subpixel_order << 4) |
288             (options->lcd_filter << 8) |
289             (options->hint_style << 12) |
290             (options->hint_metrics << 16));
291 }
292 slim_hidden_def (cairo_font_options_hash);
293
294 /**
295  * cairo_font_options_set_antialias:
296  * @options: a #cairo_font_options_t
297  * @antialias: the new antialiasing mode
298  *
299  * Sets the antialiasing mode for the font options object. This
300  * specifies the type of antialiasing to do when rendering text.
301  *
302  * Since: 1.0
303  **/
304 void
305 cairo_font_options_set_antialias (cairo_font_options_t *options,
306                                   cairo_antialias_t     antialias)
307 {
308     if (cairo_font_options_status (options))
309         return;
310
311     options->antialias = antialias;
312 }
313 slim_hidden_def (cairo_font_options_set_antialias);
314
315 /**
316  * cairo_font_options_get_antialias:
317  * @options: a #cairo_font_options_t
318  *
319  * Gets the antialiasing mode for the font options object.
320  *
321  * Return value: the antialiasing mode
322  *
323  * Since: 1.0
324  **/
325 cairo_antialias_t
326 cairo_font_options_get_antialias (const cairo_font_options_t *options)
327 {
328     if (cairo_font_options_status ((cairo_font_options_t *) options))
329         return CAIRO_ANTIALIAS_DEFAULT;
330
331     return options->antialias;
332 }
333
334 /**
335  * cairo_font_options_set_subpixel_order:
336  * @options: a #cairo_font_options_t
337  * @subpixel_order: the new subpixel order
338  *
339  * Sets the subpixel order for the font options object. The subpixel
340  * order specifies the order of color elements within each pixel on
341  * the display device when rendering with an antialiasing mode of
342  * %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
343  * #cairo_subpixel_order_t for full details.
344  *
345  * Since: 1.0
346  **/
347 void
348 cairo_font_options_set_subpixel_order (cairo_font_options_t   *options,
349                                        cairo_subpixel_order_t  subpixel_order)
350 {
351     if (cairo_font_options_status (options))
352         return;
353
354     options->subpixel_order = subpixel_order;
355 }
356 slim_hidden_def (cairo_font_options_set_subpixel_order);
357
358 /**
359  * cairo_font_options_get_subpixel_order:
360  * @options: a #cairo_font_options_t
361  *
362  * Gets the subpixel order for the font options object.
363  * See the documentation for #cairo_subpixel_order_t for full details.
364  *
365  * Return value: the subpixel order for the font options object
366  *
367  * Since: 1.0
368  **/
369 cairo_subpixel_order_t
370 cairo_font_options_get_subpixel_order (const cairo_font_options_t *options)
371 {
372     if (cairo_font_options_status ((cairo_font_options_t *) options))
373         return CAIRO_SUBPIXEL_ORDER_DEFAULT;
374
375     return options->subpixel_order;
376 }
377
378 /**
379  * _cairo_font_options_set_lcd_filter:
380  * @options: a #cairo_font_options_t
381  * @lcd_filter: the new LCD filter
382  *
383  * Sets the LCD filter for the font options object. The LCD filter
384  * specifies how pixels are filtered when rendered with an antialiasing
385  * mode of %CAIRO_ANTIALIAS_SUBPIXEL. See the documentation for
386  * #cairo_lcd_filter_t for full details.
387  **/
388 void
389 _cairo_font_options_set_lcd_filter (cairo_font_options_t *options,
390                                     cairo_lcd_filter_t    lcd_filter)
391 {
392     if (cairo_font_options_status (options))
393         return;
394
395     options->lcd_filter = lcd_filter;
396 }
397
398 /**
399  * _cairo_font_options_get_lcd_filter:
400  * @options: a #cairo_font_options_t
401  *
402  * Gets the LCD filter for the font options object.
403  * See the documentation for #cairo_lcd_filter_t for full details.
404  *
405  * Return value: the LCD filter for the font options object
406  **/
407 cairo_lcd_filter_t
408 _cairo_font_options_get_lcd_filter (const cairo_font_options_t *options)
409 {
410     if (cairo_font_options_status ((cairo_font_options_t *) options))
411         return CAIRO_LCD_FILTER_DEFAULT;
412
413     return options->lcd_filter;
414 }
415
416 /**
417  * _cairo_font_options_set_round_glyph_positions:
418  * @options: a #cairo_font_options_t
419  * @round: the new rounding value
420  *
421  * Sets the rounding options for the font options object. If rounding is set, a
422  * glyph's position will be rounded to integer values.
423  **/
424 void
425 _cairo_font_options_set_round_glyph_positions (cairo_font_options_t *options,
426                                                cairo_round_glyph_positions_t  round)
427 {
428     if (cairo_font_options_status (options))
429         return;
430
431     options->round_glyph_positions = round;
432 }
433
434 /**
435  * _cairo_font_options_get_round_glyph_positions:
436  * @options: a #cairo_font_options_t
437  *
438  * Gets the glyph position rounding option for the font options object.
439  *
440  * Return value: The round glyph posistions flag for the font options object.
441  **/
442 cairo_round_glyph_positions_t
443 _cairo_font_options_get_round_glyph_positions (const cairo_font_options_t *options)
444 {
445     if (cairo_font_options_status ((cairo_font_options_t *) options))
446         return CAIRO_ROUND_GLYPH_POS_DEFAULT;
447
448     return options->round_glyph_positions;
449 }
450
451 /**
452  * cairo_font_options_set_hint_style:
453  * @options: a #cairo_font_options_t
454  * @hint_style: the new hint style
455  *
456  * Sets the hint style for font outlines for the font options object.
457  * This controls whether to fit font outlines to the pixel grid,
458  * and if so, whether to optimize for fidelity or contrast.
459  * See the documentation for #cairo_hint_style_t for full details.
460  *
461  * Since: 1.0
462  **/
463 void
464 cairo_font_options_set_hint_style (cairo_font_options_t *options,
465                                    cairo_hint_style_t    hint_style)
466 {
467     if (cairo_font_options_status (options))
468         return;
469
470     options->hint_style = hint_style;
471 }
472 slim_hidden_def (cairo_font_options_set_hint_style);
473
474 /**
475  * cairo_font_options_get_hint_style:
476  * @options: a #cairo_font_options_t
477  *
478  * Gets the hint style for font outlines for the font options object.
479  * See the documentation for #cairo_hint_style_t for full details.
480  *
481  * Return value: the hint style for the font options object
482  *
483  * Since: 1.0
484  **/
485 cairo_hint_style_t
486 cairo_font_options_get_hint_style (const cairo_font_options_t *options)
487 {
488     if (cairo_font_options_status ((cairo_font_options_t *) options))
489         return CAIRO_HINT_STYLE_DEFAULT;
490
491     return options->hint_style;
492 }
493
494 /**
495  * cairo_font_options_set_hint_metrics:
496  * @options: a #cairo_font_options_t
497  * @hint_metrics: the new metrics hinting mode
498  *
499  * Sets the metrics hinting mode for the font options object. This
500  * controls whether metrics are quantized to integer values in
501  * device units.
502  * See the documentation for #cairo_hint_metrics_t for full details.
503  *
504  * Since: 1.0
505  **/
506 void
507 cairo_font_options_set_hint_metrics (cairo_font_options_t *options,
508                                      cairo_hint_metrics_t  hint_metrics)
509 {
510     if (cairo_font_options_status (options))
511         return;
512
513     options->hint_metrics = hint_metrics;
514 }
515 slim_hidden_def (cairo_font_options_set_hint_metrics);
516
517 /**
518  * cairo_font_options_get_hint_metrics:
519  * @options: a #cairo_font_options_t
520  *
521  * Gets the metrics hinting mode for the font options object.
522  * See the documentation for #cairo_hint_metrics_t for full details.
523  *
524  * Return value: the metrics hinting mode for the font options object
525  *
526  * Since: 1.0
527  **/
528 cairo_hint_metrics_t
529 cairo_font_options_get_hint_metrics (const cairo_font_options_t *options)
530 {
531     if (cairo_font_options_status ((cairo_font_options_t *) options))
532         return CAIRO_HINT_METRICS_DEFAULT;
533
534     return options->hint_metrics;
535 }