]> git.wh0rd.org - fontconfig.git/blob - src/ftglue.c
413a933ab1b02e3b6171ec82faf86632196650fd
[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 #define FREE(_ptr) \
54 do { \
55 if ( (_ptr) ) \
56 { \
57 ftglue_free( memory, _ptr ); \
58 _ptr = NULL; \
59 } \
60 } while (0)
61
62
63 FTGLUE_APIDEF( FT_Pointer )
64 ftglue_alloc( FT_Memory memory,
65 FT_ULong size,
66 FT_Error *perror )
67 {
68 FT_Error error = 0;
69 FT_Pointer block = NULL;
70
71 if ( size > 0 )
72 {
73 block = memory->alloc( memory, size );
74 if ( !block )
75 error = FT_Err_Out_Of_Memory;
76 else
77 memset( (char*)block, 0, (size_t)size );
78 }
79
80 *perror = error;
81 return block;
82 }
83
84
85 FTGLUE_APIDEF( FT_Pointer )
86 ftglue_realloc( FT_Memory memory,
87 FT_Pointer block,
88 FT_ULong old_size,
89 FT_ULong new_size,
90 FT_Error *perror )
91 {
92 FT_Pointer block2 = NULL;
93 FT_Error error = 0;
94
95 if ( old_size == 0 || block == NULL )
96 {
97 block2 = ftglue_alloc( memory, new_size, &error );
98 }
99 else if ( new_size == 0 )
100 {
101 ftglue_free( memory, block );
102 }
103 else
104 {
105 block2 = memory->realloc( memory, old_size, new_size, block );
106 if ( block2 == NULL )
107 error = FT_Err_Out_Of_Memory;
108 else if ( new_size > old_size )
109 memset( (char*)block2 + old_size, 0, (size_t)(new_size - old_size) );
110 }
111
112 if ( !error )
113 block = block2;
114
115 *perror = error;
116 return block;
117 }
118
119
120 FTGLUE_APIDEF( void )
121 ftglue_free( FT_Memory memory,
122 FT_Pointer block )
123 {
124 if ( block )
125 memory->free( memory, block );
126 }
127
128
129 FTGLUE_APIDEF( FT_Long )
130 ftglue_stream_pos( FT_Stream stream )
131 {
132 LOG(( "ftglue:stream:pos() -> %ld\n", stream->pos ));
133 return stream->pos;
134 }
135
136
137 FTGLUE_APIDEF( FT_Error )
138 ftglue_stream_seek( FT_Stream stream,
139 FT_Long pos )
140 {
141 FT_Error error = 0;
142
143 stream->pos = pos;
144 if ( stream->read )
145 {
146 if ( stream->read( stream, pos, 0, 0 ) )
147 error = FT_Err_Invalid_Stream_Operation;
148 }
149 else if ( pos > stream->size )
150 error = FT_Err_Invalid_Stream_Operation;
151
152 LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error ));
153 return error;
154 }
155
156
157 FTGLUE_APIDEF( FT_Error )
158 ftglue_stream_frame_enter( FT_Stream stream,
159 FT_ULong count )
160 {
161 FT_Error error = FT_Err_Ok;
162 FT_ULong read_bytes;
163
164 if ( stream->read )
165 {
166 /* allocate the frame in memory */
167 FT_Memory memory = stream->memory;
168
169
170 if ( QALLOC( stream->base, count ) )
171 goto Exit;
172
173 /* read it */
174 read_bytes = stream->read( stream, stream->pos,
175 stream->base, count );
176 if ( read_bytes < count )
177 {
178 FREE( stream->base );
179 error = FT_Err_Invalid_Stream_Operation;
180 }
181 stream->cursor = stream->base;
182 stream->limit = stream->cursor + count;
183 stream->pos += read_bytes;
184 }
185 else
186 {
187 /* check current and new position */
188 if ( stream->pos >= stream->size ||
189 stream->pos + count > stream->size )
190 {
191 error = FT_Err_Invalid_Stream_Operation;
192 goto Exit;
193 }
194
195 /* set cursor */
196 stream->cursor = stream->base + stream->pos;
197 stream->limit = stream->cursor + count;
198 stream->pos += count;
199 }
200
201 Exit:
202 LOG(( "ftglue:stream:frame_enter(%ld) -> %d\n", count, error ));
203 return error;
204 }
205
206
207 FTGLUE_APIDEF( void )
208 ftglue_stream_frame_exit( FT_Stream stream )
209 {
210 if ( stream->read )
211 {
212 FT_Memory memory = stream->memory;
213
214 FREE( stream->base );
215 }
216 stream->cursor = 0;
217 stream->limit = 0;
218
219 LOG(( "ftglue:stream:frame_exit()\n" ));
220 }
221
222
223 FTGLUE_APIDEF( FT_Error )
224 ftglue_face_goto_table( FT_Face face,
225 FT_ULong the_tag,
226 FT_Stream stream )
227 {
228 FT_Error error;
229
230 LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
231 face,
232 (int)((the_tag >> 24) & 0xFF),
233 (int)((the_tag >> 16) & 0xFF),
234 (int)((the_tag >> 8) & 0xFF),
235 (int)(the_tag & 0xFF),
236 stream ));
237
238 if ( !FT_IS_SFNT(face) )
239 {
240 LOG(( "not a SFNT face !!\n" ));
241 error = FT_Err_Invalid_Face_Handle;
242 }
243 else
244 {
245 /* parse the directory table directly, without using
246 * FreeType's built-in data structures
247 */
248 FT_ULong offset = 0;
249 FT_UInt count, nn;
250
251 if ( face->num_faces > 1 )
252 {
253 /* deal with TrueType collections */
254
255 LOG(( ">> This is a TrueType Collection\n" ));
256
257 if ( FILE_Seek( 12 + face->face_index*4 ) ||
258 ACCESS_Frame( 4 ) )
259 goto Exit;
260
261 offset = GET_ULong();
262
263 FORGET_Frame();
264 }
265
266 LOG(( "TrueType offset = %ld\n", offset ));
267
268 if ( FILE_Seek( offset+4 ) ||
269 ACCESS_Frame( 2 ) )
270 goto Exit;
271
272 count = GET_UShort();
273
274 FORGET_Frame();
275
276 if ( FILE_Seek( offset+12 ) ||
277 ACCESS_Frame( count*16 ) )
278 goto Exit;
279
280 for ( nn = 0; nn < count; nn++ )
281 {
282 FT_ULong tag = GET_ULong();
283 FT_ULong checksum = GET_ULong();
284 FT_ULong start = GET_ULong();
285 FT_ULong size = GET_ULong();
286
287 FT_UNUSED(checksum);
288 FT_UNUSED(size);
289
290 if ( tag == the_tag )
291 {
292 LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size ));
293 error = ftglue_stream_seek( stream, start );
294 goto FoundIt;
295 }
296 }
297 error = TT_Err_Table_Missing;
298
299 FoundIt:
300 FORGET_Frame();
301 }
302
303 Exit:
304 LOG(( "TrueType error=%d\n", error ));
305
306 return error;
307 }
308
309 #undef QALLOC