1 /* ftglue.c: Glue code for compiling the OpenType code from
2 * FreeType 1 using only the public API of FreeType 2
4 * By David Turner, The FreeType Project (www.freetype.org)
6 * This code is explicitely put in the public domain
8 * See ftglue.h for more information.
15 #define LOG(x) ftglue_log x
18 ftglue_log( const char* format
, ... )
22 va_start( ap
, format
);
23 vfprintf( stderr
, format
, ap
);
28 #define LOG(x) do {} while (0)
31 /* only used internally */
33 ftglue_qalloc( FT_Memory memory
,
38 FT_Pointer block
= NULL
;
42 block
= memory
->alloc( memory
, size
);
44 error
= FT_Err_Out_Of_Memory
;
51 #undef QALLOC /* just in case */
52 #define QALLOC(ptr,size) ( (ptr) = ftglue_qalloc( memory, (size), &error ), error != 0 )
55 FTGLUE_APIDEF( FT_Pointer
)
56 ftglue_alloc( FT_Memory memory
,
61 FT_Pointer block
= NULL
;
65 block
= memory
->alloc( memory
, size
);
67 error
= FT_Err_Out_Of_Memory
;
69 memset( (char*)block
, 0, (size_t)size
);
77 FTGLUE_APIDEF( FT_Pointer
)
78 ftglue_realloc( FT_Memory memory
,
84 FT_Pointer block2
= NULL
;
87 if ( old_size
== 0 || block
== NULL
)
89 block2
= ftglue_alloc( memory
, new_size
, &error
);
91 else if ( new_size
== 0 )
93 ftglue_free( memory
, block
);
97 block2
= memory
->realloc( memory
, old_size
, new_size
, block
);
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
) );
112 FTGLUE_APIDEF( void )
113 ftglue_free( FT_Memory memory
,
117 memory
->free( memory
, block
);
121 FTGLUE_APIDEF( FT_Long
)
122 ftglue_stream_pos( FT_Stream stream
)
124 LOG(( "ftglue:stream:pos() -> %ld\n", stream
->pos
));
129 FTGLUE_APIDEF( FT_Error
)
130 ftglue_stream_seek( FT_Stream stream
,
138 if ( stream
->read( stream
, pos
, 0, 0 ) )
139 error
= FT_Err_Invalid_Stream_Operation
;
141 else if ( pos
> stream
->size
)
142 error
= FT_Err_Invalid_Stream_Operation
;
144 LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos
, error
));
149 FTGLUE_APIDEF( FT_Error
)
150 ftglue_stream_frame_enter( FT_Stream stream
,
153 FT_Error error
= FT_Err_Ok
;
158 /* allocate the frame in memory */
159 FT_Memory memory
= stream
->memory
;
162 if ( QALLOC( stream
->base
, count
) )
166 read_bytes
= stream
->read( stream
, stream
->pos
,
167 stream
->base
, count
);
168 if ( read_bytes
< count
)
170 FREE( stream
->base
);
171 error
= FT_Err_Invalid_Stream_Operation
;
173 stream
->cursor
= stream
->base
;
174 stream
->limit
= stream
->cursor
+ count
;
175 stream
->pos
+= read_bytes
;
179 /* check current and new position */
180 if ( stream
->pos
>= stream
->size
||
181 stream
->pos
+ count
> stream
->size
)
183 error
= FT_Err_Invalid_Stream_Operation
;
188 stream
->cursor
= stream
->base
+ stream
->pos
;
189 stream
->limit
= stream
->cursor
+ count
;
190 stream
->pos
+= count
;
194 LOG(( "ftglue:stream:frame_enter(%ld) -> %d\n", count
, error
));
199 FTGLUE_APIDEF( void )
200 ftglue_stream_frame_exit( FT_Stream stream
)
204 FT_Memory memory
= stream
->memory
;
206 FREE( stream
->base
);
211 LOG(( "ftglue:stream:frame_exit()\n" ));
215 FTGLUE_APIDEF( FT_Byte
)
216 ftglue_stream_get_byte( FT_Stream stream
)
220 if ( stream
->cursor
< stream
->limit
)
221 result
= *stream
->cursor
++;
227 FTGLUE_APIDEF( FT_Short
)
228 ftglue_stream_get_short( FT_Stream stream
)
234 if ( p
+ 2 <= stream
->limit
)
236 result
= (FT_Short
)((p
[0] << 8) | p
[1]);
237 stream
->cursor
= p
+2;
243 FTGLUE_APIDEF( FT_Long
)
244 ftglue_stream_get_long( FT_Stream stream
)
250 if ( p
+ 4 <= stream
->limit
)
252 result
= (FT_Long
)(((FT_Long
)p
[0] << 24) |
253 ((FT_Long
)p
[1] << 16) |
254 ((FT_Long
)p
[2] << 8) |
256 stream
->cursor
= p
+4;
262 FTGLUE_APIDEF( FT_Error
)
263 ftglue_face_goto_table( FT_Face face
,
269 LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n",
271 (int)((the_tag
>> 24) & 0xFF),
272 (int)((the_tag
>> 16) & 0xFF),
273 (int)((the_tag
>> 8) & 0xFF),
274 (int)(the_tag
& 0xFF),
277 if ( !FT_IS_SFNT(face
) )
279 LOG(( "not a SFNT face !!\n" ));
280 error
= FT_Err_Invalid_Face_Handle
;
284 /* parse the directory table directly, without using
285 * FreeType's built-in data structures
290 if ( face
->num_faces
> 1 )
292 /* deal with TrueType collections */
295 LOG(( ">> This is a TrueType Collection\n" ));
297 if ( FILE_Seek( 12 + face
->face_index
*4 ) ||
301 offset
= GET_ULong();
306 LOG(( "TrueType offset = %ld\n", offset
));
308 if ( FILE_Seek( offset
+4 ) ||
312 count
= GET_UShort();
316 if ( FILE_Seek( offset
+12 ) ||
317 ACCESS_Frame( count
*16 ) )
320 for ( nn
= 0; nn
< count
; nn
++ )
322 FT_ULong tag
= GET_ULong();
323 FT_ULong checksum
= GET_ULong();
324 FT_ULong start
= GET_ULong();
325 FT_ULong size
= GET_ULong();
330 if ( tag
== the_tag
)
332 LOG(( "TrueType table (start: %ld) (size: %ld)\n", start
, size
));
333 error
= ftglue_stream_seek( stream
, offset
+start
);
337 error
= TT_Err_Table_Missing
;
344 LOG(( "TrueType error=%d\n", error
));