]> git.wh0rd.org - fontconfig.git/blob - src/ftglue.c
Get rid of the use of freetype internal headers in fcfreetype.c, since
[fontconfig.git] / src / ftglue.c
1 /* ftglue.c: Glue code for compiling the OpenType code from
2 * FreeType 1 using only the public API of FreeType 2
3 *
4 * By David Turner, The FreeType Project (www.freetype.org)
5 *
6 * This code is explicitely put in the public domain
7 *
8 * See ftglue.h for more information.
9 */
10
11 #include "ftglue.h"
12
13 #if 0
14 #include <stdio.h>
15 #define LOG(x) ftglue_log x
16
17 static void
18 ftglue_log( const char* format, ... )
19 {
20 va_list ap;
21
22 va_start( ap, format );
23 vfprintf( stderr, format, ap );
24 va_end( ap );
25 }
26
27 #else
28 #define LOG(x) do {} while (0)
29 #endif
30
31 /* only used internally */
32 static FT_Pointer
33 ftglue_qalloc( FT_Memory memory,
34 FT_ULong size,
35 FT_Error *perror )
36 {
37 FT_Error error = 0;
38 FT_Pointer block = NULL;
39
40 if ( size > 0 )
41 {
42 block = memory->alloc( memory, size );
43 if ( !block )
44 error = FT_Err_Out_Of_Memory;
45 }
46
47 *perror = error;
48 return block;
49 }
50
51 #undef QALLOC /* just in case */
52 #define QALLOC(ptr,size) ( (ptr) = ftglue_qalloc( memory, (size), &error ), error != 0 )
53
54
55 FTGLUE_APIDEF( FT_Pointer )
56 ftglue_alloc( FT_Memory memory,
57 FT_ULong size,
58 FT_Error *perror )
59 {
60 FT_Error error = 0;
61 FT_Pointer block = NULL;
62
63 if ( size > 0 )
64 {
65 block = memory->alloc( memory, size );
66 if ( !block )
67 error = FT_Err_Out_Of_Memory;
68 else
69 memset( (char*)block, 0, (size_t)size );
70 }
71
72 *perror = error;
73 return block;
74 }
75
76
77 FTGLUE_APIDEF( FT_Pointer )
78 ftglue_realloc( FT_Memory memory,
79 FT_Pointer block,
80 FT_ULong old_size,
81 FT_ULong new_size,
82 FT_Error *perror )
83 {
84 FT_Pointer block2 = NULL;
85 FT_Error error = 0;
86
87 if ( old_size == 0 || block == NULL )
88 {
89 block2 = ftglue_alloc( memory, new_size, &error );
90 }
91 else if ( new_size == 0 )
92 {
93 ftglue_free( memory, block );
94 }
95 else
96 {
97 block2 = memory->realloc( memory, old_size, new_size, block );
98 if ( block2 == NULL )
99 error = FT_Err_Out_Of_Memory;
100 else if ( new_size > old_size )
101 memset( (char*)block2 + old_size, 0, (size_t)(new_size - old_size) );
102 }
103
104 if ( !error )
105 block = block2;
106
107 *perror = error;
108 return block;
109 }
110
111
112 FTGLUE_APIDEF( void )
113 ftglue_free( FT_Memory memory,
114 FT_Pointer block )
115 {
116 if ( block )
117 memory->free( memory, block );
118 }
119
120
121 FTGLUE_APIDEF( FT_Long )
122 ftglue_stream_pos( FT_Stream stream )
123 {
124 LOG(( "ftglue:stream:pos() -> %ld\n", stream->pos ));
125 return stream->pos;
126 }
127
128
129 FTGLUE_APIDEF( FT_Error )
130 ftglue_stream_seek( FT_Stream stream,
131 FT_Long pos )
132 {
133 FT_Error error = 0;
134
135 stream->pos = pos;
136 if ( stream->read )
137 {
138 if ( stream->read( stream, pos, 0, 0 ) )
139 error = FT_Err_Invalid_Stream_Operation;
140 }
141 else if ( pos > stream->size )
142 error = FT_Err_Invalid_Stream_Operation;
143
144 LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error ));
145 return error;
146 }
147
148
149 FTGLUE_APIDEF( FT_Error )
150 ftglue_stream_frame_enter( FT_Stream stream,
151 FT_ULong count )
152 {
153 FT_Error error = FT_Err_Ok;
154 FT_ULong read_bytes;
155
156 if ( stream->read )
157 {
158 /* allocate the frame in memory */
159 FT_Memory memory = stream->memory;
160
161
162 if ( QALLOC( stream->base, count ) )
163 goto Exit;
164
165 /* read it */
166 read_bytes = stream->read( stream, stream->pos,
167 stream->base, count );
168 if ( read_bytes < count )
169 {
170 FREE( stream->base );
171 error = FT_Err_Invalid_Stream_Operation;
172 }
173 stream->cursor = stream->base;
174 stream->limit = stream->cursor + count;
175 stream->pos += read_bytes;
176 }
177 else
178 {
179 /* check current and new position */
180 if ( stream->pos >= stream->size ||
181 stream->pos + count > stream->size )
182 {
183 error = FT_Err_Invalid_Stream_Operation;
184 goto Exit;
185 }
186
187 /* set cursor */
188 stream->cursor = stream->base + stream->pos;
189 stream->limit = stream->cursor + count;
190 stream->pos += count;
191 }
192
193 Exit:
194 LOG(( "ftglue:stream:frame_enter(%ld) -> %d\n", count, error ));
195 return error;
196 }
197
198
199 FTGLUE_APIDEF( void )
200 ftglue_stream_frame_exit( FT_Stream stream )
201 {
202 if ( stream->read )
203 {
204 FT_Memory memory = stream->memory;
205
206 FREE( stream->base );
207 }
208 stream->cursor = 0;
209 stream->limit = 0;
210
211 LOG(( "ftglue:stream:frame_exit()\n" ));
212 }
213
214
215 FTGLUE_APIDEF( FT_Byte )
216 ftglue_stream_get_byte( FT_Stream stream )
217 {
218 FT_Byte result = 0;
219
220 if ( stream->cursor < stream->limit )
221 result = *stream->cursor++;
222
223 return result;
224 }
225
226
227 FTGLUE_APIDEF( FT_Short )
228 ftglue_stream_get_short( FT_Stream stream )
229 {
230 FT_Byte* p;
231 FT_Short result = 0;
232
233 p = stream->cursor;
234 if ( p + 2 <= stream->limit )
235 {
236 result = (FT_Short)((p[0] << 8) | p[1]);
237 stream->cursor = p+2;
238 }
239 return result;
240 }
241
242
243 FTGLUE_APIDEF( FT_Long )
244 ftglue_stream_get_long( FT_Stream stream )
245 {
246 FT_Byte* p;
247 FT_Long result = 0;
248
249 p = stream->cursor;
250 if ( p + 4 <= stream->limit )
251 {
252 result = (FT_Long)(((FT_Long)p[0] << 24) |
253 ((FT_Long)p[1] << 16) |
254 ((FT_Long)p[2] << 8) |
255 p[3] );
256 stream->cursor = p+4;
257 }
258 return result;
259 }
260
261
262 FTGLUE_APIDEF( FT_Error )
263 ftglue_face_goto_table( FT_Face face,
264 FT_ULong the_tag,
265 FT_Stream stream )
266 {
267 FT_Error error;
268
269 LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
270 face,
271 (int)((the_tag >> 24) & 0xFF),
272 (int)((the_tag >> 16) & 0xFF),
273 (int)((the_tag >> 8) & 0xFF),
274 (int)(the_tag & 0xFF),
275 stream ));
276
277 if ( !FT_IS_SFNT(face) )
278 {
279 LOG(( "not a SFNT face !!\n" ));
280 error = FT_Err_Invalid_Face_Handle;
281 }
282 else
283 {
284 /* parse the directory table directly, without using
285 * FreeType's built-in data structures
286 */
287 FT_ULong offset = 0;
288 FT_UInt count, nn;
289
290 if ( face->num_faces > 1 )
291 {
292 /* deal with TrueType collections */
293 FT_ULong offset;
294
295 LOG(( ">> This is a TrueType Collection\n" ));
296
297 if ( FILE_Seek( 12 + face->face_index*4 ) ||
298 ACCESS_Frame( 4 ) )
299 goto Exit;
300
301 offset = GET_ULong();
302
303 FORGET_Frame();
304 }
305
306 LOG(( "TrueType offset = %ld\n", offset ));
307
308 if ( FILE_Seek( offset+4 ) ||
309 ACCESS_Frame( 2 ) )
310 goto Exit;
311
312 count = GET_UShort();
313
314 FORGET_Frame();
315
316 if ( FILE_Seek( offset+12 ) ||
317 ACCESS_Frame( count*16 ) )
318 goto Exit;
319
320 for ( nn = 0; nn < count; nn++ )
321 {
322 FT_ULong tag = GET_ULong();
323 FT_ULong checksum = GET_ULong();
324 FT_ULong start = GET_ULong();
325 FT_ULong size = GET_ULong();
326
327 FT_UNUSED(checksum);
328 FT_UNUSED(size);
329
330 if ( tag == the_tag )
331 {
332 LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size ));
333 error = ftglue_stream_seek( stream, offset+start );
334 goto FoundIt;
335 }
336 }
337 error = TT_Err_Table_Missing;
338
339 FoundIt:
340 FORGET_Frame();
341 }
342
343 Exit:
344 LOG(( "TrueType error=%d\n", error ));
345
346 return error;
347 }
348
349 #undef QALLOC