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