Subversion Repositories Scribus

Rev

Rev 14952 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
14952 fschmid 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
3
 *
4
 * Copyright © 2002 University of Southern California
5
 * Copyright © 2005 Red Hat Inc.
6
 *
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.
14
 *
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
18122 mrdocs 17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
14952 fschmid 18
 * You should have received a copy of the MPL along with this library
19
 * in the file COPYING-MPL-1.1
20
 *
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/
25
 *
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.
29
 *
30
 * The Original Code is the cairo graphics library.
31
 *
32
 * The Initial Developer of the Original Code is University of Southern
33
 * California.
34
 *
35
 * Contributor(s):
36
 *      Carl D. Worth <cworth@cworth.org>
37
 *      Graydon Hoare <graydon@redhat.com>
38
 *      Owen Taylor <otaylor@redhat.com>
39
 */
40
 
41
#include "cairoint.h"
42
 
43
/* #cairo_font_face_t */
44
 
45
const cairo_font_face_t _cairo_font_face_nil = {
46
    { 0 },                              /* hash_entry */
47
    CAIRO_STATUS_NO_MEMORY,             /* status */
48
    CAIRO_REFERENCE_COUNT_INVALID,      /* ref_count */
49
    { 0, 0, 0, NULL },                  /* user_data */
50
    NULL
51
};
52
 
53
cairo_status_t
54
_cairo_font_face_set_error (cairo_font_face_t *font_face,
55
                            cairo_status_t     status)
56
{
57
    if (status == CAIRO_STATUS_SUCCESS)
58
        return status;
59
 
60
    /* Don't overwrite an existing error. This preserves the first
61
     * error, which is the most significant. */
62
    _cairo_status_set_error (&font_face->status, status);
63
 
64
    return _cairo_error (status);
65
}
66
 
67
void
68
_cairo_font_face_init (cairo_font_face_t               *font_face,
69
                       const cairo_font_face_backend_t *backend)
70
{
71
    CAIRO_MUTEX_INITIALIZE ();
72
 
73
    font_face->status = CAIRO_STATUS_SUCCESS;
74
    CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
75
    font_face->backend = backend;
76
 
77
    _cairo_user_data_array_init (&font_face->user_data);
78
}
79
 
80
/**
81
 * cairo_font_face_reference:
82
 * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
83
 * function does nothing).
84
 *
85
 * Increases the reference count on @font_face by one. This prevents
86
 * @font_face from being destroyed until a matching call to
87
 * cairo_font_face_destroy() is made.
88
 *
89
 * The number of references to a #cairo_font_face_t can be get using
90
 * cairo_font_face_get_reference_count().
91
 *
92
 * Return value: the referenced #cairo_font_face_t.
93
 **/
94
cairo_font_face_t *
95
cairo_font_face_reference (cairo_font_face_t *font_face)
96
{
97
    if (font_face == NULL ||
98
            CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
99
        return font_face;
100
 
101
    /* We would normally assert that we have a reference here but we
102
     * can't get away with that due to the zombie case as documented
103
     * in _cairo_ft_font_face_destroy. */
104
 
105
    _cairo_reference_count_inc (&font_face->ref_count);
106
 
107
    return font_face;
108
}
109
slim_hidden_def (cairo_font_face_reference);
110
 
111
/**
112
 * cairo_font_face_destroy:
113
 * @font_face: a #cairo_font_face_t
114
 *
115
 * Decreases the reference count on @font_face by one. If the result
116
 * is zero, then @font_face and all associated resources are freed.
117
 * See cairo_font_face_reference().
118
 **/
119
void
120
cairo_font_face_destroy (cairo_font_face_t *font_face)
121
{
122
    if (font_face == NULL ||
123
            CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
124
        return;
125
 
126
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
127
 
128
    if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
129
        return;
130
 
131
    if (font_face->backend->destroy)
132
        font_face->backend->destroy (font_face);
133
 
134
    /* We allow resurrection to deal with some memory management for the
135
     * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
136
     * need to effectively mutually reference each other
137
     */
138
    if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
139
        return;
140
 
141
    _cairo_user_data_array_fini (&font_face->user_data);
142
 
143
    free (font_face);
144
}
145
slim_hidden_def (cairo_font_face_destroy);
146
 
147
/**
148
 * cairo_font_face_get_type:
149
 * @font_face: a font face
150
 *
151
 * This function returns the type of the backend used to create
152
 * a font face. See #cairo_font_type_t for available types.
153
 *
154
 * Return value: The type of @font_face.
155
 *
156
 * Since: 1.2
157
 **/
158
cairo_font_type_t
159
cairo_font_face_get_type (cairo_font_face_t *font_face)
160
{
161
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
162
        return CAIRO_FONT_TYPE_TOY;
163
 
164
    return font_face->backend->type;
165
}
166
 
167
/**
168
 * cairo_font_face_get_reference_count:
169
 * @font_face: a #cairo_font_face_t
170
 *
171
 * Returns the current reference count of @font_face.
172
 *
173
 * Return value: the current reference count of @font_face.  If the
174
 * object is a nil object, 0 will be returned.
175
 *
176
 * Since: 1.4
177
 **/
178
unsigned int
179
cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
180
{
181
    if (font_face == NULL ||
182
            CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
183
        return 0;
184
 
185
    return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
186
}
187
 
188
/**
189
 * cairo_font_face_status:
190
 * @font_face: a #cairo_font_face_t
191
 *
192
 * Checks whether an error has previously occurred for this
193
 * font face
194
 *
195
 * Return value: %CAIRO_STATUS_SUCCESS or another error such as
196
 *   %CAIRO_STATUS_NO_MEMORY.
197
 **/
198
cairo_status_t
199
cairo_font_face_status (cairo_font_face_t *font_face)
200
{
201
    return font_face->status;
202
}
203
 
204
/**
205
 * cairo_font_face_get_user_data:
206
 * @font_face: a #cairo_font_face_t
207
 * @key: the address of the #cairo_user_data_key_t the user data was
208
 * attached to
209
 *
210
 * Return user data previously attached to @font_face using the specified
211
 * key.  If no user data has been attached with the given key this
212
 * function returns %NULL.
213
 *
214
 * Return value: the user data previously attached or %NULL.
215
 **/
216
void *
217
cairo_font_face_get_user_data (cairo_font_face_t           *font_face,
218
                               const cairo_user_data_key_t *key)
219
{
220
    return _cairo_user_data_array_get_data (&font_face->user_data,
221
                                            key);
222
}
223
slim_hidden_def (cairo_font_face_get_user_data);
224
 
225
/**
226
 * cairo_font_face_set_user_data:
227
 * @font_face: a #cairo_font_face_t
228
 * @key: the address of a #cairo_user_data_key_t to attach the user data to
229
 * @user_data: the user data to attach to the font face
230
 * @destroy: a #cairo_destroy_func_t which will be called when the
231
 * font face is destroyed or when new user data is attached using the
232
 * same key.
233
 *
234
 * Attach user data to @font_face.  To remove user data from a font face,
235
 * call this function with the key that was used to set it and %NULL
236
 * for @data.
237
 *
238
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
239
 * slot could not be allocated for the user data.
240
 **/
241
cairo_status_t
242
cairo_font_face_set_user_data (cairo_font_face_t           *font_face,
243
                               const cairo_user_data_key_t *key,
244
                               void                        *user_data,
245
                               cairo_destroy_func_t         destroy)
246
{
247
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
248
        return font_face->status;
249
 
250
    return _cairo_user_data_array_set_data (&font_face->user_data,
251
                                            key, user_data, destroy);
252
}
253
slim_hidden_def (cairo_font_face_set_user_data);
254
 
255
void
256
_cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
257
                           const cairo_unscaled_font_backend_t *backend)
258
{
259
    CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
260
    unscaled_font->backend = backend;
261
}
262
 
263
cairo_unscaled_font_t *
264
_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
265
{
266
    if (unscaled_font == NULL)
267
        return NULL;
268
 
269
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
270
 
271
    _cairo_reference_count_inc (&unscaled_font->ref_count);
272
 
273
    return unscaled_font;
274
}
275
 
276
void
277
_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
278
{
279
    if (unscaled_font == NULL)
280
        return;
281
 
282
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
283
 
284
    if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
285
        return;
286
 
287
    unscaled_font->backend->destroy (unscaled_font);
288
 
289
    free (unscaled_font);
290
}