Imported Upstream version 2.14.2
[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 #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__