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