1 /* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
2 /* cairo - a vector graphics library with display and print output
4 * Copyright © 2002 University of Southern California
5 * Copyright © 2005 Red Hat Inc.
7 * This library is free software; you can redistribute it and/or
8 * modify it either under the terms of the GNU Lesser General Public
9 * License version 2.1 as published by the Free Software Foundation
10 * (the "LGPL") or, at your option, under the terms of the Mozilla
11 * Public License Version 1.1 (the "MPL"). If you do not alter this
12 * notice, a recipient may use your version of this file under either
13 * the MPL or the LGPL.
15 * You should have received a copy of the LGPL along with this library
16 * in the file COPYING-LGPL-2.1; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA
18 * You should have received a copy of the MPL along with this library
19 * in the file COPYING-MPL-1.1
21 * The contents of this file are subject to the Mozilla Public License
22 * Version 1.1 (the "License"); you may not use this file except in
23 * compliance with the License. You may obtain a copy of the License at
24 * http://www.mozilla.org/MPL/
26 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
27 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28 * the specific language governing rights and limitations.
30 * The Original Code is the cairo graphics library.
32 * The Initial Developer of the Original Code is University of Southern
36 * Carl D. Worth <cworth@cworth.org>
37 * Graydon Hoare <graydon@redhat.com>
38 * Owen Taylor <otaylor@redhat.com>
42 #include "cairo-error-private.h"
45 * SECTION:cairo-font-face
46 * @Title: cairo_font_face_t
47 * @Short_Description: Base class for font faces
48 * @See_Also: #cairo_scaled_font_t
50 * #cairo_font_face_t represents a particular font at a particular weight,
51 * slant, and other characteristic but no size, transformation, or size.
53 * Font faces are created using <firstterm>font-backend</firstterm>-specific
54 * constructors, typically of the form
55 * <function>cairo_<emphasis>backend</emphasis>_font_face_create(<!-- -->)</function>,
56 * or implicitly using the <firstterm>toy</firstterm> text API by way of
57 * cairo_select_font_face(). The resulting face can be accessed using
58 * cairo_get_font_face().
61 /* #cairo_font_face_t */
63 const cairo_font_face_t _cairo_font_face_nil = {
64 { 0 }, /* hash_entry */
65 CAIRO_STATUS_NO_MEMORY, /* status */
66 CAIRO_REFERENCE_COUNT_INVALID, /* ref_count */
67 { 0, 0, 0, NULL }, /* user_data */
72 _cairo_font_face_set_error (cairo_font_face_t *font_face,
73 cairo_status_t status)
75 if (status == CAIRO_STATUS_SUCCESS)
78 /* Don't overwrite an existing error. This preserves the first
79 * error, which is the most significant. */
80 _cairo_status_set_error (&font_face->status, status);
82 return _cairo_error (status);
86 _cairo_font_face_init (cairo_font_face_t *font_face,
87 const cairo_font_face_backend_t *backend)
89 CAIRO_MUTEX_INITIALIZE ();
91 font_face->status = CAIRO_STATUS_SUCCESS;
92 CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
93 font_face->backend = backend;
95 _cairo_user_data_array_init (&font_face->user_data);
99 * cairo_font_face_reference:
100 * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
101 * function does nothing).
103 * Increases the reference count on @font_face by one. This prevents
104 * @font_face from being destroyed until a matching call to
105 * cairo_font_face_destroy() is made.
107 * The number of references to a #cairo_font_face_t can be get using
108 * cairo_font_face_get_reference_count().
110 * Return value: the referenced #cairo_font_face_t.
115 cairo_font_face_reference (cairo_font_face_t *font_face)
117 if (font_face == NULL ||
118 CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
121 /* We would normally assert that we have a reference here but we
122 * can't get away with that due to the zombie case as documented
123 * in _cairo_ft_font_face_destroy. */
125 _cairo_reference_count_inc (&font_face->ref_count);
129 slim_hidden_def (cairo_font_face_reference);
132 * cairo_font_face_destroy:
133 * @font_face: a #cairo_font_face_t
135 * Decreases the reference count on @font_face by one. If the result
136 * is zero, then @font_face and all associated resources are freed.
137 * See cairo_font_face_reference().
142 cairo_font_face_destroy (cairo_font_face_t *font_face)
144 if (font_face == NULL ||
145 CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
148 assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
150 if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
153 if (font_face->backend->destroy)
154 font_face->backend->destroy (font_face);
156 /* We allow resurrection to deal with some memory management for the
157 * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
158 * need to effectively mutually reference each other
160 if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
163 _cairo_user_data_array_fini (&font_face->user_data);
167 slim_hidden_def (cairo_font_face_destroy);
170 * cairo_font_face_get_type:
171 * @font_face: a font face
173 * This function returns the type of the backend used to create
174 * a font face. See #cairo_font_type_t for available types.
176 * Return value: The type of @font_face.
181 cairo_font_face_get_type (cairo_font_face_t *font_face)
183 if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
184 return CAIRO_FONT_TYPE_TOY;
186 return font_face->backend->type;
190 * cairo_font_face_get_reference_count:
191 * @font_face: a #cairo_font_face_t
193 * Returns the current reference count of @font_face.
195 * Return value: the current reference count of @font_face. If the
196 * object is a nil object, 0 will be returned.
201 cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
203 if (font_face == NULL ||
204 CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
207 return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
211 * cairo_font_face_status:
212 * @font_face: a #cairo_font_face_t
214 * Checks whether an error has previously occurred for this
217 * Return value: %CAIRO_STATUS_SUCCESS or another error such as
218 * %CAIRO_STATUS_NO_MEMORY.
223 cairo_font_face_status (cairo_font_face_t *font_face)
225 return font_face->status;
229 * cairo_font_face_get_user_data:
230 * @font_face: a #cairo_font_face_t
231 * @key: the address of the #cairo_user_data_key_t the user data was
234 * Return user data previously attached to @font_face using the specified
235 * key. If no user data has been attached with the given key this
236 * function returns %NULL.
238 * Return value: the user data previously attached or %NULL.
243 cairo_font_face_get_user_data (cairo_font_face_t *font_face,
244 const cairo_user_data_key_t *key)
246 return _cairo_user_data_array_get_data (&font_face->user_data,
249 slim_hidden_def (cairo_font_face_get_user_data);
252 * cairo_font_face_set_user_data:
253 * @font_face: a #cairo_font_face_t
254 * @key: the address of a #cairo_user_data_key_t to attach the user data to
255 * @user_data: the user data to attach to the font face
256 * @destroy: a #cairo_destroy_func_t which will be called when the
257 * font face is destroyed or when new user data is attached using the
260 * Attach user data to @font_face. To remove user data from a font face,
261 * call this function with the key that was used to set it and %NULL
264 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
265 * slot could not be allocated for the user data.
270 cairo_font_face_set_user_data (cairo_font_face_t *font_face,
271 const cairo_user_data_key_t *key,
273 cairo_destroy_func_t destroy)
275 if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
276 return font_face->status;
278 return _cairo_user_data_array_set_data (&font_face->user_data,
279 key, user_data, destroy);
281 slim_hidden_def (cairo_font_face_set_user_data);
284 _cairo_unscaled_font_init (cairo_unscaled_font_t *unscaled_font,
285 const cairo_unscaled_font_backend_t *backend)
287 CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
288 unscaled_font->backend = backend;
291 cairo_unscaled_font_t *
292 _cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
294 if (unscaled_font == NULL)
297 assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
299 _cairo_reference_count_inc (&unscaled_font->ref_count);
301 return unscaled_font;
305 _cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
307 if (unscaled_font == NULL)
310 assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
312 if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
315 unscaled_font->backend->destroy (unscaled_font);
317 free (unscaled_font);