ftglue.c revision 0d39df38
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 stream->pos = pos; 88 if ( stream->read ) 89 { 90 if ( stream->read( stream, pos, 0, 0 ) ) 91 error = FT_Err_Invalid_Stream_Operation; 92 } 93 else if ( pos > stream->size ) 94 error = FT_Err_Invalid_Stream_Operation; 95 96 LOG(( "ftglue:stream:seek(%ld) -> %d\n", pos, error )); 97 return error; 98} 99 100 101FTGLUE_APIDEF( FT_Error ) 102ftglue_stream_frame_enter( FT_Stream stream, 103 FT_ULong count ) 104{ 105 FT_Error error = FT_Err_Ok; 106 FT_ULong read_bytes; 107 108 if ( stream->read ) 109 { 110 /* allocate the frame in memory */ 111 FT_Memory memory = stream->memory; 112 113 114 if ( QALLOC( stream->base, count ) ) 115 goto Exit; 116 117 /* read it */ 118 read_bytes = stream->read( stream, stream->pos, 119 stream->base, count ); 120 if ( read_bytes < count ) 121 { 122 FREE( stream->base ); 123 error = FT_Err_Invalid_Stream_Operation; 124 } 125 stream->cursor = stream->base; 126 stream->limit = stream->cursor + count; 127 stream->pos += read_bytes; 128 } 129 else 130 { 131 /* check current and new position */ 132 if ( stream->pos >= stream->size || 133 stream->pos + count > stream->size ) 134 { 135 error = FT_Err_Invalid_Stream_Operation; 136 goto Exit; 137 } 138 139 /* set cursor */ 140 stream->cursor = stream->base + stream->pos; 141 stream->limit = stream->cursor + count; 142 stream->pos += count; 143 } 144 145Exit: 146 LOG(( "ftglue:stream:frame_enter(%ld) -> %d\n", count, error )); 147 return error; 148} 149 150 151FTGLUE_APIDEF( void ) 152ftglue_stream_frame_exit( FT_Stream stream ) 153{ 154 if ( stream->read ) 155 { 156 FT_Memory memory = stream->memory; 157 158 FREE( stream->base ); 159 } 160 stream->cursor = 0; 161 stream->limit = 0; 162 163 LOG(( "ftglue:stream:frame_exit()\n" )); 164} 165 166 167FTGLUE_APIDEF( FT_Error ) 168ftglue_face_goto_table( FT_Face face, 169 FT_ULong the_tag, 170 FT_Stream stream ) 171{ 172 FT_Error error; 173 174 LOG(( "ftglue_face_goto_table( %p, %c%c%c%c, %p )\n", 175 face, 176 (int)((the_tag >> 24) & 0xFF), 177 (int)((the_tag >> 16) & 0xFF), 178 (int)((the_tag >> 8) & 0xFF), 179 (int)(the_tag & 0xFF), 180 stream )); 181 182 if ( !FT_IS_SFNT(face) ) 183 { 184 LOG(( "not a SFNT face !!\n" )); 185 error = FT_Err_Invalid_Face_Handle; 186 } 187 else 188 { 189 /* parse the directory table directly, without using 190 * FreeType's built-in data structures 191 */ 192 FT_ULong offset = 0, sig; 193 FT_UInt count, nn; 194 195 if ( FILE_Seek( 0 ) || ACCESS_Frame( 4 ) ) 196 goto Exit; 197 198 sig = GET_Tag4(); 199 200 FORGET_Frame(); 201 202 if ( sig == FT_MAKE_TAG( 't', 't', 'c', 'f' ) ) 203 { 204 /* deal with TrueType collections */ 205 206 LOG(( ">> This is a TrueType Collection\n" )); 207 208 if ( FILE_Seek( 12 + face->face_index*4 ) || 209 ACCESS_Frame( 4 ) ) 210 goto Exit; 211 212 offset = GET_ULong(); 213 214 FORGET_Frame(); 215 } 216 217 LOG(( "TrueType offset = %ld\n", offset )); 218 219 if ( FILE_Seek( offset+4 ) || 220 ACCESS_Frame( 2 ) ) 221 goto Exit; 222 223 count = GET_UShort(); 224 225 FORGET_Frame(); 226 227 if ( FILE_Seek( offset+12 ) || 228 ACCESS_Frame( count*16 ) ) 229 goto Exit; 230 231 for ( nn = 0; nn < count; nn++ ) 232 { 233 FT_ULong tag = GET_ULong(); 234 FT_ULong checksum = GET_ULong(); 235 FT_ULong start = GET_ULong(); 236 FT_ULong size = GET_ULong(); 237 238 FT_UNUSED(checksum); 239 FT_UNUSED(size); 240 241 if ( tag == the_tag ) 242 { 243 LOG(( "TrueType table (start: %ld) (size: %ld)\n", start, size )); 244 error = ftglue_stream_seek( stream, start ); 245 goto FoundIt; 246 } 247 } 248 error = FT_Err_Table_Missing; 249 250 FoundIt: 251 FORGET_Frame(); 252 } 253 254Exit: 255 LOG(( "TrueType error=%d\n", error )); 256 257 return error; 258} 259 260#undef QALLOC 261#define __ftglue__ 262#include "fcaliastail.h" 263#undef __ftglue__ 264