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