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