]> git.wh0rd.org - fontconfig.git/blob - src/ftglue.c
Bug 44826 - <alias> must contain only a single <family>
[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 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 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
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",
173 face,
174 (int)((the_tag >> 24) & 0xFF),
175 (int)((the_tag >> 16) & 0xFF),
176 (int)((the_tag >> 8) & 0xFF),
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 */
190 FT_ULong offset = 0, sig;
191 FT_UInt count, nn;
192
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' ) )
201 {
202 /* deal with TrueType collections */
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);
238
239 if ( tag == the_tag )
240 {
241 LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size ));
242 error = ftglue_stream_seek( stream, start );
243 goto FoundIt;
244 }
245 }
246 error = FT_Err_Table_Missing;
247
248 FoundIt:
249 FORGET_Frame();
250 }
251
252 Exit:
253 LOG(( "TrueType error=%d\n", error ));
254
255 return error;
256 }
257
258 #undef QALLOC
259 #define __ftglue__
260 #include "fcaliastail.h"
261 #undef __ftglue__