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