Subversion Repositories Kolibri OS

Rev

Rev 1892 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1892 Rev 3959
1
/* -*- Mode: c; c-basic-offset: 4; indent-tabs-mode: t; tab-width: 8; -*- */
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
2
/* cairo - a vector graphics library with display and print output
3
 *
3
 *
4
 * Copyright © 2002 University of Southern California
4
 * Copyright © 2002 University of Southern California
5
 * Copyright © 2005 Red Hat Inc.
5
 * Copyright © 2005 Red Hat Inc.
6
 *
6
 *
7
 * This library is free software; you can redistribute it and/or
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
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
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
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
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
12
 * notice, a recipient may use your version of this file under either
13
 * the MPL or the LGPL.
13
 * the MPL or the LGPL.
14
 *
14
 *
15
 * You should have received a copy of the LGPL along with this library
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
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
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
18
 * You should have received a copy of the MPL along with this library
19
 * in the file COPYING-MPL-1.1
19
 * in the file COPYING-MPL-1.1
20
 *
20
 *
21
 * The contents of this file are subject to the Mozilla Public License
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
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
23
 * compliance with the License. You may obtain a copy of the License at
24
 * http://www.mozilla.org/MPL/
24
 * http://www.mozilla.org/MPL/
25
 *
25
 *
26
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY
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
27
 * OF ANY KIND, either express or implied. See the LGPL or the MPL for
28
 * the specific language governing rights and limitations.
28
 * the specific language governing rights and limitations.
29
 *
29
 *
30
 * The Original Code is the cairo graphics library.
30
 * The Original Code is the cairo graphics library.
31
 *
31
 *
32
 * The Initial Developer of the Original Code is University of Southern
32
 * The Initial Developer of the Original Code is University of Southern
33
 * California.
33
 * California.
34
 *
34
 *
35
 * Contributor(s):
35
 * Contributor(s):
36
 *	Carl D. Worth 
36
 *	Carl D. Worth 
37
 *      Graydon Hoare 
37
 *      Graydon Hoare 
38
 *      Owen Taylor 
38
 *      Owen Taylor 
39
 */
39
 */
40
 
40
 
41
#include "cairoint.h"
41
#include "cairoint.h"
42
#include "cairo-error-private.h"
42
#include "cairo-error-private.h"
43
 
43
 
44
/**
44
/**
45
 * SECTION:cairo-font-face
45
 * SECTION:cairo-font-face
46
 * @Title: cairo_font_face_t
46
 * @Title: cairo_font_face_t
47
 * @Short_Description: Base class for font faces
47
 * @Short_Description: Base class for font faces
48
 * @See_Also: #cairo_scaled_font_t
48
 * @See_Also: #cairo_scaled_font_t
49
 *
49
 *
50
 * #cairo_font_face_t represents a particular font at a particular weight,
50
 * #cairo_font_face_t represents a particular font at a particular weight,
51
 * slant, and other characteristic but no size, transformation, or size.
51
 * slant, and other characteristic but no size, transformation, or size.
52
 * 
52
 *
53
 * Font faces are created using font-backend-specific
53
 * Font faces are created using font-backend-specific
54
 * constructors, typically of the form
54
 * constructors, typically of the form
55
 * cairo_backend_font_face_create(), or implicitly
55
 * cairo_backend_font_face_create(),
56
 * using the toy text API by way of 
56
 * or implicitly using the toy text API by way of
57
 * cairo_select_font_face().  The resulting face can be accessed using
57
 * cairo_select_font_face().  The resulting face can be accessed using
58
 * cairo_get_font_face().
58
 * cairo_get_font_face().
59
 */
59
 **/
60
 
60
 
61
/* #cairo_font_face_t */
61
/* #cairo_font_face_t */
62
 
62
 
63
const cairo_font_face_t _cairo_font_face_nil = {
63
const cairo_font_face_t _cairo_font_face_nil = {
64
    { 0 },				/* hash_entry */
64
    { 0 },				/* hash_entry */
65
    CAIRO_STATUS_NO_MEMORY,		/* status */
65
    CAIRO_STATUS_NO_MEMORY,		/* status */
66
    CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */
66
    CAIRO_REFERENCE_COUNT_INVALID,	/* ref_count */
67
    { 0, 0, 0, NULL },			/* user_data */
67
    { 0, 0, 0, NULL },			/* user_data */
68
    NULL
68
    NULL
69
};
69
};
70
 
70
 
71
cairo_status_t
71
cairo_status_t
72
_cairo_font_face_set_error (cairo_font_face_t *font_face,
72
_cairo_font_face_set_error (cairo_font_face_t *font_face,
73
	                    cairo_status_t     status)
73
	                    cairo_status_t     status)
74
{
74
{
75
    if (status == CAIRO_STATUS_SUCCESS)
75
    if (status == CAIRO_STATUS_SUCCESS)
76
	return status;
76
	return status;
77
 
77
 
78
    /* Don't overwrite an existing error. This preserves the first
78
    /* Don't overwrite an existing error. This preserves the first
79
     * error, which is the most significant. */
79
     * error, which is the most significant. */
80
    _cairo_status_set_error (&font_face->status, status);
80
    _cairo_status_set_error (&font_face->status, status);
81
 
81
 
82
    return _cairo_error (status);
82
    return _cairo_error (status);
83
}
83
}
84
 
84
 
85
void
85
void
86
_cairo_font_face_init (cairo_font_face_t               *font_face,
86
_cairo_font_face_init (cairo_font_face_t               *font_face,
87
		       const cairo_font_face_backend_t *backend)
87
		       const cairo_font_face_backend_t *backend)
88
{
88
{
89
    CAIRO_MUTEX_INITIALIZE ();
89
    CAIRO_MUTEX_INITIALIZE ();
90
 
90
 
91
    font_face->status = CAIRO_STATUS_SUCCESS;
91
    font_face->status = CAIRO_STATUS_SUCCESS;
92
    CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
92
    CAIRO_REFERENCE_COUNT_INIT (&font_face->ref_count, 1);
93
    font_face->backend = backend;
93
    font_face->backend = backend;
94
 
94
 
95
    _cairo_user_data_array_init (&font_face->user_data);
95
    _cairo_user_data_array_init (&font_face->user_data);
96
}
96
}
97
 
97
 
98
/**
98
/**
99
 * cairo_font_face_reference:
99
 * cairo_font_face_reference:
100
 * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
100
 * @font_face: a #cairo_font_face_t, (may be %NULL in which case this
101
 * function does nothing).
101
 * function does nothing).
102
 *
102
 *
103
 * Increases the reference count on @font_face by one. This prevents
103
 * Increases the reference count on @font_face by one. This prevents
104
 * @font_face from being destroyed until a matching call to
104
 * @font_face from being destroyed until a matching call to
105
 * cairo_font_face_destroy() is made.
105
 * cairo_font_face_destroy() is made.
106
 *
106
 *
107
 * The number of references to a #cairo_font_face_t can be get using
107
 * The number of references to a #cairo_font_face_t can be get using
108
 * cairo_font_face_get_reference_count().
108
 * cairo_font_face_get_reference_count().
109
 *
109
 *
110
 * Return value: the referenced #cairo_font_face_t.
110
 * Return value: the referenced #cairo_font_face_t.
-
 
111
 *
-
 
112
 * Since: 1.0
111
 **/
113
 **/
112
cairo_font_face_t *
114
cairo_font_face_t *
113
cairo_font_face_reference (cairo_font_face_t *font_face)
115
cairo_font_face_reference (cairo_font_face_t *font_face)
114
{
116
{
115
    if (font_face == NULL ||
117
    if (font_face == NULL ||
116
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
118
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
117
	return font_face;
119
	return font_face;
118
 
120
 
119
    /* We would normally assert that we have a reference here but we
121
    /* We would normally assert that we have a reference here but we
120
     * can't get away with that due to the zombie case as documented
122
     * can't get away with that due to the zombie case as documented
121
     * in _cairo_ft_font_face_destroy. */
123
     * in _cairo_ft_font_face_destroy. */
122
 
124
 
123
    _cairo_reference_count_inc (&font_face->ref_count);
125
    _cairo_reference_count_inc (&font_face->ref_count);
124
 
126
 
125
    return font_face;
127
    return font_face;
126
}
128
}
127
slim_hidden_def (cairo_font_face_reference);
129
slim_hidden_def (cairo_font_face_reference);
128
 
130
 
129
/**
131
/**
130
 * cairo_font_face_destroy:
132
 * cairo_font_face_destroy:
131
 * @font_face: a #cairo_font_face_t
133
 * @font_face: a #cairo_font_face_t
132
 *
134
 *
133
 * Decreases the reference count on @font_face by one. If the result
135
 * Decreases the reference count on @font_face by one. If the result
134
 * is zero, then @font_face and all associated resources are freed.
136
 * is zero, then @font_face and all associated resources are freed.
135
 * See cairo_font_face_reference().
137
 * See cairo_font_face_reference().
-
 
138
 *
-
 
139
 * Since: 1.0
136
 **/
140
 **/
137
void
141
void
138
cairo_font_face_destroy (cairo_font_face_t *font_face)
142
cairo_font_face_destroy (cairo_font_face_t *font_face)
139
{
143
{
140
    if (font_face == NULL ||
144
    if (font_face == NULL ||
141
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
145
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
142
	return;
146
	return;
143
 
147
 
144
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
148
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count));
145
 
149
 
146
    if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
150
    if (! _cairo_reference_count_dec_and_test (&font_face->ref_count))
147
	return;
151
	return;
148
 
152
 
149
    if (font_face->backend->destroy)
153
    if (font_face->backend->destroy)
150
	font_face->backend->destroy (font_face);
154
	font_face->backend->destroy (font_face);
151
 
155
 
152
    /* We allow resurrection to deal with some memory management for the
156
    /* We allow resurrection to deal with some memory management for the
153
     * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
157
     * FreeType backend where cairo_ft_font_face_t and cairo_ft_unscaled_font_t
154
     * need to effectively mutually reference each other
158
     * need to effectively mutually reference each other
155
     */
159
     */
156
    if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
160
    if (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&font_face->ref_count))
157
	return;
161
	return;
158
 
162
 
159
    _cairo_user_data_array_fini (&font_face->user_data);
163
    _cairo_user_data_array_fini (&font_face->user_data);
160
 
164
 
161
    free (font_face);
165
    free (font_face);
162
}
166
}
163
slim_hidden_def (cairo_font_face_destroy);
167
slim_hidden_def (cairo_font_face_destroy);
164
 
168
 
165
/**
169
/**
166
 * cairo_font_face_get_type:
170
 * cairo_font_face_get_type:
167
 * @font_face: a font face
171
 * @font_face: a font face
168
 *
172
 *
169
 * This function returns the type of the backend used to create
173
 * This function returns the type of the backend used to create
170
 * a font face. See #cairo_font_type_t for available types.
174
 * a font face. See #cairo_font_type_t for available types.
171
 *
175
 *
172
 * Return value: The type of @font_face.
176
 * Return value: The type of @font_face.
173
 *
177
 *
174
 * Since: 1.2
178
 * Since: 1.2
175
 **/
179
 **/
176
cairo_font_type_t
180
cairo_font_type_t
177
cairo_font_face_get_type (cairo_font_face_t *font_face)
181
cairo_font_face_get_type (cairo_font_face_t *font_face)
178
{
182
{
179
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
183
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
180
	return CAIRO_FONT_TYPE_TOY;
184
	return CAIRO_FONT_TYPE_TOY;
181
 
185
 
182
    return font_face->backend->type;
186
    return font_face->backend->type;
183
}
187
}
184
 
188
 
185
/**
189
/**
186
 * cairo_font_face_get_reference_count:
190
 * cairo_font_face_get_reference_count:
187
 * @font_face: a #cairo_font_face_t
191
 * @font_face: a #cairo_font_face_t
188
 *
192
 *
189
 * Returns the current reference count of @font_face.
193
 * Returns the current reference count of @font_face.
190
 *
194
 *
191
 * Return value: the current reference count of @font_face.  If the
195
 * Return value: the current reference count of @font_face.  If the
192
 * object is a nil object, 0 will be returned.
196
 * object is a nil object, 0 will be returned.
193
 *
197
 *
194
 * Since: 1.4
198
 * Since: 1.4
195
 **/
199
 **/
196
unsigned int
200
unsigned int
197
cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
201
cairo_font_face_get_reference_count (cairo_font_face_t *font_face)
198
{
202
{
199
    if (font_face == NULL ||
203
    if (font_face == NULL ||
200
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
204
	    CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
201
	return 0;
205
	return 0;
202
 
206
 
203
    return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
207
    return CAIRO_REFERENCE_COUNT_GET_VALUE (&font_face->ref_count);
204
}
208
}
205
 
209
 
206
/**
210
/**
207
 * cairo_font_face_status:
211
 * cairo_font_face_status:
208
 * @font_face: a #cairo_font_face_t
212
 * @font_face: a #cairo_font_face_t
209
 *
213
 *
210
 * Checks whether an error has previously occurred for this
214
 * Checks whether an error has previously occurred for this
211
 * font face
215
 * font face
212
 *
216
 *
213
 * Return value: %CAIRO_STATUS_SUCCESS or another error such as
217
 * Return value: %CAIRO_STATUS_SUCCESS or another error such as
214
 *   %CAIRO_STATUS_NO_MEMORY.
218
 *   %CAIRO_STATUS_NO_MEMORY.
-
 
219
 *
-
 
220
 * Since: 1.0
215
 **/
221
 **/
216
cairo_status_t
222
cairo_status_t
217
cairo_font_face_status (cairo_font_face_t *font_face)
223
cairo_font_face_status (cairo_font_face_t *font_face)
218
{
224
{
219
    return font_face->status;
225
    return font_face->status;
220
}
226
}
221
 
227
 
222
/**
228
/**
223
 * cairo_font_face_get_user_data:
229
 * cairo_font_face_get_user_data:
224
 * @font_face: a #cairo_font_face_t
230
 * @font_face: a #cairo_font_face_t
225
 * @key: the address of the #cairo_user_data_key_t the user data was
231
 * @key: the address of the #cairo_user_data_key_t the user data was
226
 * attached to
232
 * attached to
227
 *
233
 *
228
 * Return user data previously attached to @font_face using the specified
234
 * Return user data previously attached to @font_face using the specified
229
 * key.  If no user data has been attached with the given key this
235
 * key.  If no user data has been attached with the given key this
230
 * function returns %NULL.
236
 * function returns %NULL.
231
 *
237
 *
232
 * Return value: the user data previously attached or %NULL.
238
 * Return value: the user data previously attached or %NULL.
-
 
239
 *
-
 
240
 * Since: 1.0
233
 **/
241
 **/
234
void *
242
void *
235
cairo_font_face_get_user_data (cairo_font_face_t	   *font_face,
243
cairo_font_face_get_user_data (cairo_font_face_t	   *font_face,
236
			       const cairo_user_data_key_t *key)
244
			       const cairo_user_data_key_t *key)
237
{
245
{
238
    return _cairo_user_data_array_get_data (&font_face->user_data,
246
    return _cairo_user_data_array_get_data (&font_face->user_data,
239
					    key);
247
					    key);
240
}
248
}
241
slim_hidden_def (cairo_font_face_get_user_data);
249
slim_hidden_def (cairo_font_face_get_user_data);
242
 
250
 
243
/**
251
/**
244
 * cairo_font_face_set_user_data:
252
 * cairo_font_face_set_user_data:
245
 * @font_face: a #cairo_font_face_t
253
 * @font_face: a #cairo_font_face_t
246
 * @key: the address of a #cairo_user_data_key_t to attach the user data to
254
 * @key: the address of a #cairo_user_data_key_t to attach the user data to
247
 * @user_data: the user data to attach to the font face
255
 * @user_data: the user data to attach to the font face
248
 * @destroy: a #cairo_destroy_func_t which will be called when the
256
 * @destroy: a #cairo_destroy_func_t which will be called when the
249
 * font face is destroyed or when new user data is attached using the
257
 * font face is destroyed or when new user data is attached using the
250
 * same key.
258
 * same key.
251
 *
259
 *
252
 * Attach user data to @font_face.  To remove user data from a font face,
260
 * Attach user data to @font_face.  To remove user data from a font face,
253
 * call this function with the key that was used to set it and %NULL
261
 * call this function with the key that was used to set it and %NULL
254
 * for @data.
262
 * for @data.
255
 *
263
 *
256
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
264
 * Return value: %CAIRO_STATUS_SUCCESS or %CAIRO_STATUS_NO_MEMORY if a
257
 * slot could not be allocated for the user data.
265
 * slot could not be allocated for the user data.
-
 
266
 *
-
 
267
 * Since: 1.0
258
 **/
268
 **/
259
cairo_status_t
269
cairo_status_t
260
cairo_font_face_set_user_data (cairo_font_face_t	   *font_face,
270
cairo_font_face_set_user_data (cairo_font_face_t	   *font_face,
261
			       const cairo_user_data_key_t *key,
271
			       const cairo_user_data_key_t *key,
262
			       void			   *user_data,
272
			       void			   *user_data,
263
			       cairo_destroy_func_t	    destroy)
273
			       cairo_destroy_func_t	    destroy)
264
{
274
{
265
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
275
    if (CAIRO_REFERENCE_COUNT_IS_INVALID (&font_face->ref_count))
266
	return font_face->status;
276
	return font_face->status;
267
 
277
 
268
    return _cairo_user_data_array_set_data (&font_face->user_data,
278
    return _cairo_user_data_array_set_data (&font_face->user_data,
269
					    key, user_data, destroy);
279
					    key, user_data, destroy);
270
}
280
}
271
slim_hidden_def (cairo_font_face_set_user_data);
281
slim_hidden_def (cairo_font_face_set_user_data);
272
 
282
 
273
void
283
void
274
_cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
284
_cairo_unscaled_font_init (cairo_unscaled_font_t               *unscaled_font,
275
			   const cairo_unscaled_font_backend_t *backend)
285
			   const cairo_unscaled_font_backend_t *backend)
276
{
286
{
277
    CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
287
    CAIRO_REFERENCE_COUNT_INIT (&unscaled_font->ref_count, 1);
278
    unscaled_font->backend = backend;
288
    unscaled_font->backend = backend;
279
}
289
}
280
 
290
 
281
cairo_unscaled_font_t *
291
cairo_unscaled_font_t *
282
_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
292
_cairo_unscaled_font_reference (cairo_unscaled_font_t *unscaled_font)
283
{
293
{
284
    if (unscaled_font == NULL)
294
    if (unscaled_font == NULL)
285
	return NULL;
295
	return NULL;
286
 
296
 
287
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
297
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
288
 
298
 
289
    _cairo_reference_count_inc (&unscaled_font->ref_count);
299
    _cairo_reference_count_inc (&unscaled_font->ref_count);
290
 
300
 
291
    return unscaled_font;
301
    return unscaled_font;
292
}
302
}
293
 
303
 
294
void
304
void
295
_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
305
_cairo_unscaled_font_destroy (cairo_unscaled_font_t *unscaled_font)
296
{
306
{
297
    if (unscaled_font == NULL)
307
    if (unscaled_font == NULL)
298
	return;
308
	return;
299
 
309
 
300
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
310
    assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&unscaled_font->ref_count));
301
 
311
 
302
    if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
312
    if (! _cairo_reference_count_dec_and_test (&unscaled_font->ref_count))
303
	return;
313
	return;
304
 
314
 
305
    unscaled_font->backend->destroy (unscaled_font);
315
    unscaled_font->backend->destroy (unscaled_font);
306
 
316
 
307
    free (unscaled_font);
317
    free (unscaled_font);
308
}
318
}