]>
Commit | Line | Data |
---|---|---|
824c7bf0 PL |
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 ) | |
d8951c0c PL |
53 | #define FREE(_ptr) \ |
54 | do { \ | |
55 | if ( (_ptr) ) \ | |
56 | { \ | |
57 | ftglue_free( memory, _ptr ); \ | |
58 | _ptr = NULL; \ | |
59 | } \ | |
60 | } while (0) | |
824c7bf0 PL |
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 | ||
824c7bf0 PL |
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 */ | |
824c7bf0 PL |
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 )); | |
1c14f2d9 | 293 | error = ftglue_stream_seek( stream, start ); |
824c7bf0 PL |
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 | |
23816bf9 KP |
310 | #define __ftglue__ |
311 | #include "fcaliastail.h" | |
312 | #undef __ftglue__ |