Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1892 serge 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
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
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 
37
 *      Graydon Hoare 
38
 *      Owen Taylor 
39
 */
40
 
41
#include "cairoint.h"
42
#include "cairo-error-private.h"
43
 
44
/**
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
49
 *
50
 * #cairo_font_face_t represents a particular font at a particular weight,
51
 * slant, and other characteristic but no size, transformation, or size.
3959 Serge 52
 *
1892 serge 53
 * Font faces are created using font-backend-specific
54
 * constructors, typically of the form
3959 Serge 55
 * cairo_backend_font_face_create(),
56
 * or implicitly using the toy text API by way of
1892 serge 57
 * cairo_select_font_face().  The resulting face can be accessed using
58
 * cairo_get_font_face().
3959 Serge 59
 **/
1892 serge 60
 
61
/* #cairo_font_face_t */
62
 
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 */
68
    NULL
69
};
70
 
71
cairo_status_t
72
_cairo_font_face_set_error (cairo_font_face_t *font_face,
73
	                    cairo_status_t     status)
74
{
75
    if (status == CAIRO_STATUS_SUCCESS)
76
	return status;
77
 
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);
81
 
82
    return _cairo_error (status);
83
}
84
 
85
void
86
_cairo_font_face_init (cairo_font_face_t               *font_face,
87
		       const cairo_font_face_backend_t *backend)
88
{
89
    CAIRO_MUTEX_INITIALIZE ();
90
 
91
    font_face->status = CAIRO_STATUS_SUCCESS;
92
    CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
93
    font_face->backend = backend;
94
 
95
    _cairo_user_data_array_init (&font_face->user_data);
96
}
97
 
98
/**
99
 * cairo_font_face_reference:
100
 * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
101
 * function does nothing).
102
 *
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.
106
 *
107
 * The number of references to a #cairo_font_face_t can be get using
108
 * cairo_font_face_get_reference_count().
109
 *
110
 * Return value: the referenced #cairo_font_face_t.
3959 Serge 111
 *
112
 * Since: 1.0
1892 serge 113
 **/
114
cairo_font_face_t *
115
cairo_font_face_reference (cairo_font_face_t *font_face)
116
{
117
    if (font_face == NULL ||
118
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
119
	return font_face;
120
 
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. */
124
 
125
    _cairo_reference_count_inc (&font_face->ref_count);
126
 
127
    return font_face;
128
}
129
slim_hidden_def (cairo_font_face_reference);
130
 
131
/**
132
 * cairo_font_face_destroy:
133
 * @font_face: a #cairo_font_face_t
134
 *
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().
3959 Serge 138
 *
139
 * Since: 1.0
1892 serge 140
 **/
141
void
142
cairo_font_face_destroy (cairo_font_face_t *font_face)
143
{
144
    if (font_face == NULL ||
145
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
146
	return;
147
 
148
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
149
 
150
    if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
151
	return;
152
 
153
    if (font_face->backend->destroy)
154
	font_face->backend->destroy (font_face);
155
 
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
159
     */
160
    if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
161
	return;
162
 
163
    _cairo_user_data_array_fini (&font_face->user_data);
164
 
165
    free (font_face);
166
}
167
slim_hidden_def (cairo_font_face_destroy);
168
 
169
/**
170
 * cairo_font_face_get_type:
171
 * @font_face: a font face
172
 *
173
 * This function returns the type of the backend used to create
174
 * a font face. See #cairo_font_type_t for available types.
175
 *
176
 * Return value: The type of @font_face.
177
 *
178
 * Since: 1.2
179
 **/
180
cairo_font_type_t
181
cairo_font_face_get_type (cairo_font_face_t *font_face)
182
{
183
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
184
	return CAIRO_FONT_TYPE_TOY;
185
 
186
    return font_face->backend->type;
187
}
188
 
189
/**
190
 * cairo_font_face_get_reference_count:
191
 * @font_face: a #cairo_font_face_t
192
 *
193
 * Returns the current reference count of @font_face.
194
 *
195
 * Return value: the current reference count of @font_face.  If the
196
 * object is a nil object, 0 will be returned.
197
 *
198
 * Since: 1.4
199
 **/
200
unsigned int
201
cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
202
{
203
    if (font_face == NULL ||
204
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
205
	return 0;
206
 
207
    return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
208
}
209
 
210
/**
211
 * cairo_font_face_status:
212
 * @font_face: a #cairo_font_face_t
213
 *
214
 * Checks whether an error has previously occurred for this
215
 * font face
216
 *
217
 * Return value: %CAIRO_STATUS_SUCCESS or another error such as
218
 *   %CAIRO_STATUS_NO_MEMORY.
3959 Serge 219
 *
220
 * Since: 1.0
1892 serge 221
 **/
222
cairo_status_t
223
cairo_font_face_status (cairo_font_face_t *font_face)
224
{
225
    return font_face->status;
226
}
227
 
228
/**
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
232
 * attached to
233
 *
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.
237
 *
238
 * Return value: the user data previously attached or %NULL.
3959 Serge 239
 *
240
 * Since: 1.0
1892 serge 241
 **/
242
void *
243
cairo_font_face_get_user_data (cairo_font_face_t	   *font_face,
244
			       const cairo_user_data_key_t *key)
245
{
246
    return _cairo_user_data_array_get_data (&font_face->user_data,
247
					    key);
248
}
249
slim_hidden_def (cairo_font_face_get_user_data);
250
 
251
/**
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
258
 * same key.
259
 *
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
262
 * for @data.
263
 *
264
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
265
 * slot could not be allocated for the user data.
3959 Serge 266
 *
267
 * Since: 1.0
1892 serge 268
 **/
269
cairo_status_t
270
cairo_font_face_set_user_data (cairo_font_face_t	   *font_face,
271
			       const cairo_user_data_key_t *key,
272
			       void			   *user_data,
273
			       cairo_destroy_func_t	    destroy)
274
{
275
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
276
	return font_face->status;
277
 
278
    return _cairo_user_data_array_set_data (&font_face->user_data,
279
					    key, user_data, destroy);
280
}
281
slim_hidden_def (cairo_font_face_set_user_data);
282
 
283
void
284
_cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
285
			   const cairo_unscaled_font_backend_t *backend)
286
{
287
    CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
288
    unscaled_font->backend = backend;
289
}
290
 
291
cairo_unscaled_font_t *
292
_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
293
{
294
    if (unscaled_font == NULL)
295
	return NULL;
296
 
297
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
298
 
299
    _cairo_reference_count_inc (&unscaled_font->ref_count);
300
 
301
    return unscaled_font;
302
}
303
 
304
void
305
_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
306
{
307
    if (unscaled_font == NULL)
308
	return;
309
 
310
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
311
 
312
    if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
313
	return;
314
 
315
    unscaled_font->backend->destroy (unscaled_font);
316
 
317
    free (unscaled_font);
318
}