summaryrefslogtreecommitdiff
path: root/src/select/font_face.c
blob: ea790eb4cbf31cf8a9b5f3449f2e678ad329ec77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
 * This file is part of LibCSS.
 * Licensed under the MIT License,
 *                http://www.opensource.org/licenses/mit-license.php
 * Copyright 2011 Things Made Out Of Other Things Ltd.
 * Written by James Montgomerie <jamie@th.ingsmadeoutofotherthin.gs>
 */

#include <string.h>

#include "select/font_face.h"

static void font_faces_srcs_destroy(css_font_face *font_face)
{
	uint32_t i;
	css_font_face_src *srcs = font_face->srcs;

	for (i = 0; i < font_face->n_srcs; ++i) {
		if (srcs[i].location != NULL) {
			lwc_string_unref(srcs[i].location);
		}
	}
	
	free(srcs);
	font_face->srcs = NULL;
}

static const css_font_face default_font_face = {
	NULL,
	NULL,
	0,
	{ (CSS_FONT_WEIGHT_NORMAL << 2) | CSS_FONT_STYLE_NORMAL }
};

/**
 * Create a font-face
 *
 * \param result  Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_NOMEM on memory exhaustion,
 *         CSS_BADPARM on bad parameters.
 */
css_error css__font_face_create(css_font_face **result)
{
	css_font_face *f;
	
	if (result == NULL)
		return CSS_BADPARM;
	
	f = malloc(sizeof(css_font_face));
	if (f == NULL)
		return CSS_NOMEM;
	
	memcpy(f, &default_font_face, sizeof(css_font_face));
	
	*result = f;
	
	return CSS_OK;
}

/**
 * Destroy a font-face
 *
 * \param font_face  Font-face to destroy
 * \return CSS_OK on success, appropriate error otherwise
 */
css_error css__font_face_destroy(css_font_face *font_face)
{	
	if (font_face == NULL)
		return CSS_BADPARM;

	if (font_face->font_family != NULL)
		lwc_string_unref(font_face->font_family);
	
	if (font_face->srcs != NULL)
		font_faces_srcs_destroy(font_face);

	free(font_face);
	
	return CSS_OK;
}


/**
 * Set a font-face's font-family name
 *
 * \param font_face    The font-face
 * \param font_family  Font-family name
 * \param result       Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_BADPARM on bad parameters.
 */
css_error css__font_face_set_font_family(css_font_face *font_face,
		lwc_string *font_family)
{
	if (font_face == NULL || font_family == NULL)
		return CSS_BADPARM;
	
	if (font_face->font_family != NULL)
		lwc_string_unref(font_face->font_family);
		
	font_face->font_family = lwc_string_ref(font_family);

	return CSS_OK;
}

/**
 * Get a font-face's font-family name
 *
 * \param font_face  The font-face
 * \param result     Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_BADPARM on bad parameters.
 */
css_error css_font_face_get_font_family(const css_font_face *font_face,
		lwc_string **font_family)
{
	if (font_face == NULL || font_family == NULL)
		return CSS_BADPARM;
	
	*font_family = font_face->font_family;
	
	return CSS_OK;
}

/**
 * Get the style of font for a font-face.
 *
 * \param src  The font-face
 * \return The style, as a css_font_style_e
 */
uint8_t css_font_face_font_style(const css_font_face *font_face)
{
	return font_face->bits[0] & 0x3;
}

/**
 * Get the weight of font for a font-face.
 *
 * \param src  The font-face
 * \return The style, as a css_font_weight_e
 */
uint8_t css_font_face_font_weight(const css_font_face *font_face)
{
	return (font_face->bits[0] >> 2) & 0xf;
}

/**
 * Get the number of potential src locations for a font-face
 *
 * \param font_face  The font-face
 * \param count      Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_BADPARM on bad parameters.
 */
css_error css_font_face_count_srcs(const css_font_face *font_face, 
		uint32_t *count)
{
	if (font_face == NULL || count == NULL)
		return CSS_BADPARM;

	*count = font_face->n_srcs;
	return CSS_OK;
}

/**
 * Get a specific src location from a font-face
 *
 * \param font_face  The font-face
 * \param index	     The index for the wanted src.
 * \param count      Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_BADPARM on bad parameters.
 */
css_error css_font_face_get_src(const css_font_face *font_face,
		uint32_t index, const css_font_face_src **src)
{
	if (font_face == NULL || src == NULL || index >= font_face->n_srcs)
		return CSS_BADPARM;

	*src = &(font_face->srcs[index]);
	
	return CSS_OK;
}

/**
 * Get the location for a font-face src.
 *
 * \param font_face  The font-face
 * \param count      Pointer to location to receive result
 * \return CSS_OK on success,
 *         CSS_BADPARM on bad parameters.
 *
 * \note  The type of location (local or URL) can be gathered from 
 *        css_font_face_src_location_type, and the format of font (if specified)
 *        from css_font_face_src_format.
 */
css_error css_font_face_src_get_location(const css_font_face_src *src,
		lwc_string **location)
{
	if (src == NULL || location == NULL) 
		return CSS_BADPARM;
	
	*location = src->location;

	return CSS_OK;	
}

/**
 * Get the location type for a font-face src.
 *
 * \param src  The font-face src
 * \return The location type
 */
css_font_face_location_type css_font_face_src_location_type(
		const css_font_face_src *src)
{
	return src->bits[0] & 0x3;
}

/**
 * Get the format of font for a font-face src.
 *
 * \param src  The font-face src
 * \return The format, if specified
 */
css_font_face_format css_font_face_src_format(const css_font_face_src *src)
{
	return (src->bits[0] >> 2) & 0x1f;
}

/**
 * Set a font-faces array of srcs.
 *
 * \param font_face  The font-face 
 * \param srcs	     The array of css_font_face_srcs
 * \param n_srcs     The count of css_font_face_srcs in the array 
 * \return The format, if specified
 */
css_error css__font_face_set_srcs(css_font_face *font_face,
		css_font_face_src *srcs, uint32_t n_srcs)
{
	if (font_face->srcs != NULL)
		font_faces_srcs_destroy(font_face);
	
	font_face->srcs = srcs;
	font_face->n_srcs = n_srcs;
	
	return CSS_OK;
}