ftglue.c revision 5e61939b
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 < 0 || (FT_ULong) 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#include "fcaliastail.h" 263#undef __ftglue__ 264