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 static void
64 ftglue_free( FT_Memory memory,
65 FT_Pointer block )
66 {
67 if ( block )
68 memory->free( memory, block );
69 }
70
71 FTGLUE_APIDEF( FT_Long )
72 ftglue_stream_pos( FT_Stream stream )
73 {
74 LOG(( "ftglue:stream:pos() -> %ld\n", stream->pos ));
75 return stream->pos;
76 }
77
78
79 FTGLUE_APIDEF( FT_Error )
80 ftglue_stream_seek( FT_Stream stream,
81 FT_Long pos )
82 {
83 FT_Error error = 0;
84
85 if ( stream->read )
86 {
87 if ( stream->read( stream, pos, 0, 0 ) )
88 error = FT_Err_Invalid_Stream_Operation;
89 }
90 else if ( pos < 0 || (FT_ULong) pos > stream->size )
91 error = FT_Err_Invalid_Stream_Operation;
92
93 if ( !error )
94 stream->pos = pos;
95 LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error ));
96 return error;
97 }
98
99
100 FTGLUE_APIDEF( FT_Error )
101 ftglue_stream_frame_enter( FT_Stream stream,
102 FT_ULong count )
103 {
104 FT_Error error = FT_Err_Ok;
105 FT_ULong read_bytes;
106
107 if ( stream->read )
108 {
109 /* allocate the frame in memory */
110 FT_Memory memory = stream->memory;
111
112
113 if ( QALLOC( stream->base, count ) )
114 goto Exit;
115
116 /* read it */
117 read_bytes = stream->read( stream, stream->pos,
118 stream->base, count );
119 if ( read_bytes < count )
120 {
121 FREE( stream->base );
122 error = FT_Err_Invalid_Stream_Operation;
123 }
124 stream->cursor = stream->base;
125 stream->limit = stream->cursor + count;
126 stream->pos += read_bytes;
127 }
128 else
129 {
130 /* check current and new position */
131 if ( stream->pos >= stream->size ||
132 stream->pos + count > stream->size )
133 {
134 error = FT_Err_Invalid_Stream_Operation;
135 goto Exit;
136 }
137
138 /* set cursor */
139 stream->cursor = stream->base + stream->pos;
140 stream->limit = stream->cursor + count;
141 stream->pos += count;
142 }
143
144 Exit:
145 LOG(( "ftglue:stream:frame_enter(%ld) -> %d\n", count, error ));
146 return error;
147 }
148
149
150 FTGLUE_APIDEF( void )
151 ftglue_stream_frame_exit( FT_Stream stream )
152 {
153 if ( stream->read )
154 {
155 FT_Memory memory = stream->memory;
156
157 FREE( stream->base );
158 }
159 stream->cursor = 0;
160 stream->limit = 0;
161
162 LOG(( "ftglue:stream:frame_exit()\n" ));
163 }
164
165
166 FTGLUE_APIDEF( FT_Error )
167 ftglue_face_goto_table( FT_Face face,
168 FT_ULong the_tag,
169 FT_Stream stream )
170 {
171 FT_Error error;
172
173 LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
174 face,
175 (int)((the_tag >> 24) & 0xFF),
176 (int)((the_tag >> 16) & 0xFF),
177 (int)((the_tag >> 8) & 0xFF),
178 (int)(the_tag & 0xFF),
179 stream ));
180
181 if ( !FT_IS_SFNT(face) )
182 {
183 LOG(( "not a SFNT face !!\n" ));
184 error = FT_Err_Invalid_Face_Handle;
185 }
186 else
187 {
188 /* parse the directory table directly, without using
189 * FreeType's built-in data structures
190 */
191 FT_ULong offset = 0, sig;
192 FT_UInt count, nn;
193
194 if ( FILE_Seek( 0 ) || ACCESS_Frame( 4 ) )
195 goto Exit;
196
197 sig = GET_Tag4();
198
199 FORGET_Frame();
200
201 if ( sig == FT_MAKE_TAG( 't', 't', 'c', 'f' ) )
202 {
203 /* deal with TrueType collections */
204
205 LOG(( ">> This is a TrueType Collection\n" ));
206
207 if ( FILE_Seek( 12 + face->face_index*4 ) ||
208 ACCESS_Frame( 4 ) )
209 goto Exit;
210
211 offset = GET_ULong();
212
213 FORGET_Frame();
214 }
215
216 LOG(( "TrueType offset = %ld\n", offset ));
217
218 if ( FILE_Seek( offset+4 ) ||
219 ACCESS_Frame( 2 ) )
220 goto Exit;
221
222 count = GET_UShort();
223
224 FORGET_Frame();
225
226 if ( FILE_Seek( offset+12 ) ||
227 ACCESS_Frame( count*16 ) )
228 goto Exit;
229
230 for ( nn = 0; nn < count; nn++ )
231 {
232 FT_ULong tag = GET_ULong();
233 FT_ULong checksum FC_UNUSED = GET_ULong();
234 FT_ULong start = GET_ULong();
235 FT_ULong size FC_UNUSED = GET_ULong();
236
237 if ( tag == the_tag )
238 {
239 LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size ));
240 error = ftglue_stream_seek( stream, start );
241 goto FoundIt;
242 }
243 }
244 error = FT_Err_Table_Missing;
245
246 FoundIt:
247 FORGET_Frame();
248 }
249
250 Exit:
251 LOG(( "TrueType error=%d\n", error ));
252
253 return error;
254 }
255
256 #undef QALLOC
257 #include "fcaliastail.h"
258 #undef __ftglue__