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