FT_Stream_TryRead( FT_Stream stream, FT_Byte* buffer, FT_ULong count ) { FT_ULong read_bytes = 0; if ( stream->pos >= stream->size ) goto Exit; if ( stream->read ) read_bytes = stream->read( stream, stream->pos, buffer, count ); else { read_bytes = stream->size - stream->pos; if ( read_bytes > count ) read_bytes = count; FT_MEM_COPY( buffer, stream->base + stream->pos, read_bytes ); } stream->pos += read_bytes; Exit: return read_bytes; }
cff_index_get_name( CFF_Font font, FT_UInt element ) { CFF_Index idx = &font->name_index; FT_Memory memory = idx->stream->memory; FT_Byte* bytes; FT_ULong byte_len; FT_Error error; FT_String* name = 0; error = cff_index_access_element( idx, element, &bytes, &byte_len ); if ( error ) goto Exit; if ( !FT_ALLOC( name, byte_len + 1 ) ) { FT_MEM_COPY( name, bytes, byte_len ); name[byte_len] = 0; } cff_index_forget_element( idx, &bytes ); Exit: return name; }
static FT_Error t1_get_glyph_name( T1_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) { FT_String* gname; gname = face->type1.glyph_names[glyph_index]; if ( buffer_max > 0 ) { FT_UInt len = (FT_UInt)( ft_strlen( gname ) ); if (len >= buffer_max) len = buffer_max - 1; FT_MEM_COPY( buffer, gname, len ); ((FT_Byte*)buffer)[len] = 0; } return T1_Err_Ok; }
static FT_Error ft_bzip2_file_fill_input( FT_BZip2File zip ) { bz_stream* bzstream = &zip->bzstream; FT_Stream stream = zip->source; FT_ULong size; if ( stream->read ) { size = stream->read( stream, stream->pos, zip->input, FT_BZIP2_BUFFER_SIZE ); if ( size == 0 ) return FT_THROW( Invalid_Stream_Operation ); } else { size = stream->size - stream->pos; if ( size > FT_BZIP2_BUFFER_SIZE ) size = FT_BZIP2_BUFFER_SIZE; if ( size == 0 ) return FT_THROW( Invalid_Stream_Operation ); FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); } stream->pos += size; bzstream->next_in = (char*)zip->input; bzstream->avail_in = size; return FT_Err_Ok; }
FT_Get_WinFNT_Header( FT_Face face, FT_WinFNT_HeaderRec *header ) { FT_Error error; error = FT_Err_Invalid_Argument; if ( face != NULL && face->driver != NULL ) { FT_Module driver = (FT_Module) face->driver; if ( driver->clazz && driver->clazz->module_name && ft_strcmp( driver->clazz->module_name, "winfonts" ) == 0 ) { FNT_Face fnt_face = (FNT_Face)face; FNT_Font font = fnt_face->font; if ( font ) { FT_MEM_COPY( header, &font->header, sizeof ( *header ) ); error = FT_Err_Ok; } } } return error; }
static FT_Error ft_gzip_file_fill_input( FT_GZipFile zip ) { z_stream* zstream = &zip->zstream; FT_Stream stream = zip->source; FT_ULong size; if ( stream->read ) { size = stream->read( stream, stream->pos, zip->input, FT_GZIP_BUFFER_SIZE ); if ( size == 0 ) return Gzip_Err_Invalid_Stream_Operation; } else { size = stream->size - stream->pos; if ( size > FT_GZIP_BUFFER_SIZE ) size = FT_GZIP_BUFFER_SIZE; if ( size == 0 ) return Gzip_Err_Invalid_Stream_Operation; FT_MEM_COPY( zip->input, stream->base + stream->pos, size ); } stream->pos += size; zstream->next_in = zip->input; zstream->avail_in = size; return Gzip_Err_Ok; }
static FT_Error reallocate_t1_table( PS_Table table, FT_Long new_size ) { FT_Memory memory = table->memory; FT_Byte* old_base = table->block; FT_Error error; /* allocate new base block */ if ( FT_ALLOC( table->block, new_size ) ) { table->block = old_base; return error; } /* copy elements and shift offsets */ if (old_base ) { FT_MEM_COPY( table->block, old_base, table->capacity ); shift_elements( table, old_base ); FT_FREE( old_base ); } table->capacity = new_size; return PSaux_Err_Ok; }
cff_index_get_sid_string( CFF_Index idx, FT_UInt sid, PSNames_Service psnames_service ) { /* if it is not a standard string, return it */ if ( sid > 390 ) return cff_index_get_name( idx, sid - 391 ); /* that's a standard string, fetch a copy from the PSName module */ { FT_String* name = 0; const char* adobe_name = psnames_service->adobe_std_strings( sid ); FT_UInt len; if ( adobe_name ) { FT_Memory memory = idx->stream->memory; FT_Error error; len = (FT_UInt)ft_strlen( adobe_name ); if ( !FT_ALLOC( name, len + 1 ) ) { FT_MEM_COPY( name, adobe_name, len ); name[len] = 0; } FT_UNUSED( error ); } return name; } }
cf2_arrstack_push( CF2_ArrStack arrstack, const void* ptr ) { FT_ASSERT( arrstack != NULL ); if ( arrstack->count == arrstack->allocated ) { /* grow the buffer by one chunk */ if ( !cf2_arrstack_setNumElements( arrstack, arrstack->allocated + arrstack->chunk ) ) { /* on error, ignore the push */ return; } } FT_ASSERT( ptr != NULL ); { size_t offset = arrstack->count * arrstack->sizeItem; void* newPtr = (FT_Byte*)arrstack->ptr + offset; FT_MEM_COPY( newPtr, ptr, arrstack->sizeItem ); arrstack->count += 1; } }
static FT_Error get_sfnt_glyph_name( TT_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) { FT_String* gname; FT_Error error; error = TT_Get_PS_Name( face, glyph_index, &gname ); if ( !error && buffer_max > 0 ) { FT_UInt len = (FT_UInt)( ft_strlen( gname ) ); if ( len >= buffer_max ) len = buffer_max - 1; FT_MEM_COPY( buffer, gname, len ); ((FT_Byte*)buffer)[len] = 0; } return error; }
static FT_ULong ft_gzip_file_io( FT_GZipFile zip, FT_ULong pos, FT_Byte* buffer, FT_ULong count ) { FT_ULong result = 0; FT_Error error; /* Reset inflate stream if we're seeking backwards. */ /* Yes, that is not too efficient, but it saves memory :-) */ if ( pos < zip->pos ) { error = ft_gzip_file_reset( zip ); if ( error ) goto Exit; } /* skip unwanted bytes */ if ( pos > zip->pos ) { error = ft_gzip_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); if ( error ) goto Exit; } if ( count == 0 ) goto Exit; /* now read the data */ for (;;) { FT_ULong delta; delta = (FT_ULong)( zip->limit - zip->cursor ); if ( delta >= count ) delta = count; FT_MEM_COPY( buffer, zip->cursor, delta ); buffer += delta; result += delta; zip->cursor += delta; zip->pos += delta; count -= delta; if ( count == 0 ) break; error = ft_gzip_file_fill_output( zip ); if ( error ) break; } Exit: return result; }
FT_Bitmap_Copy( FT_Library library, const FT_Bitmap *source, FT_Bitmap *target) { FT_Memory memory = library->memory; FT_Error error = FT_Err_Ok; FT_Int pitch = source->pitch; FT_ULong size; if ( source == target ) return FT_Err_Ok; if ( source->buffer == NULL ) { *target = *source; return FT_Err_Ok; } if ( pitch < 0 ) pitch = -pitch; size = (FT_ULong)( pitch * source->rows ); if ( target->buffer ) { FT_Int target_pitch = target->pitch; FT_ULong target_size; if ( target_pitch < 0 ) target_pitch = -target_pitch; target_size = (FT_ULong)( target_pitch * target->rows ); if ( target_size != size ) (void)FT_QREALLOC( target->buffer, target_size, size ); } else (void)FT_QALLOC( target->buffer, size ); if ( !error ) { unsigned char *p; p = target->buffer; *target = *source; target->buffer = p; FT_MEM_COPY( target->buffer, source->buffer, size ); } return error; }
static FT_Error ft_outline_glyph_init( FT_OutlineGlyph glyph, FT_GlyphSlot slot ) { FT_Error error = FT_Err_Ok; FT_Library library = FT_GLYPH(glyph)->library; FT_Outline* source = &slot->outline; FT_Outline* target = &glyph->outline; /* check format in glyph slot */ if ( slot->format != ft_glyph_format_outline ) { error = FT_Err_Invalid_Glyph_Format; goto Exit; } /* allocate new outline */ error = FT_Outline_New( library, source->n_points, source->n_contours, &glyph->outline ); if ( error ) goto Exit; /* copy it */ FT_MEM_COPY( target->points, source->points, source->n_points * sizeof ( FT_Vector ) ); FT_MEM_COPY( target->tags, source->tags, source->n_points * sizeof ( FT_Byte ) ); FT_MEM_COPY( target->contours, source->contours, source->n_contours * sizeof ( FT_Short ) ); /* copy all flags, except the `ft_outline_owner' one */ target->flags = source->flags | ft_outline_owner; Exit: return error; }
static FT_Error cff_get_glyph_name( CFF_Face face, FT_UInt glyph_index, FT_Pointer buffer, FT_UInt buffer_max ) { CFF_Font font = (CFF_Font)face->extra.data; FT_Memory memory = FT_FACE_MEMORY( face ); FT_String* gname; FT_UShort sid; FT_Service_PsCMaps psnames; FT_Error error; FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS ); if ( !psnames ) { FT_ERROR(( "cff_get_glyph_name:" )); FT_ERROR(( " cannot get glyph name from CFF & CEF fonts\n" )); FT_ERROR(( " " )); FT_ERROR(( " without the `PSNames' module\n" )); error = CFF_Err_Unknown_File_Format; goto Exit; } /* first, locate the sid in the charset table */ sid = font->charset.sids[glyph_index]; /* now, lookup the name itself */ gname = cff_index_get_sid_string( &font->string_index, sid, psnames ); if ( gname && buffer_max > 0 ) { FT_UInt len = (FT_UInt)ft_strlen( gname ); if ( len >= buffer_max ) len = buffer_max - 1; FT_MEM_COPY( buffer, gname, len ); ((FT_Byte*)buffer)[len] = 0; } FT_FREE( gname ); error = CFF_Err_Ok; Exit: return error; }
/* read a glyph name and return the equivalent glyph index */ static FT_UInt afm_atoindex( FT_Byte** start, FT_Byte* limit, T1_Font type1 ) { FT_Byte* p = *start; FT_PtrDist len; FT_UInt result = 0; char temp[64]; /* skip whitespace */ while ( p < limit && ( *p == ' ' || *p == '\t' || *p == ':' || *p == ';' ) ) p++; *start = p; /* now, read glyph name */ while ( p < limit && IS_ALPHANUM( *p ) ) p++; len = p - *start; if ( len > 0 && len < 64 ) { FT_Int n; /* copy glyph name to intermediate array */ FT_MEM_COPY( temp, *start, len ); temp[len] = 0; /* lookup glyph name in face array */ for ( n = 0; n < type1->num_glyphs; n++ ) { char* gname = (char*)type1->glyph_names[n]; if ( gname && gname[0] == temp[0] && ft_strcmp( gname, temp ) == 0 ) { result = n; break; } } } *start = p; return result; }
static FT_String* CFF_StrCopy( FT_Memory memory, const FT_String* source ) { FT_Error error; FT_String* result = 0; FT_Int len = (FT_Int)ft_strlen( source ); if ( !FT_ALLOC( result, len + 1 ) ) { FT_MEM_COPY( result, source, len ); result[len] = 0; } FT_UNUSED( error ); return result; }
cff_index_get_sid_string( CFF_Index idx, FT_UInt sid, FT_Service_PsCMaps psnames ) { /* value 0xFFFFU indicates a missing dictionary entry */ if ( sid == 0xFFFFU ) return 0; /* if it is not a standard string, return it */ if ( sid > 390 ) return cff_index_get_name( idx, sid - 391 ); /* CID-keyed CFF fonts don't have glyph names */ if ( !psnames ) return 0; /* that's a standard string, fetch a copy from the PSName module */ { FT_String* name = 0; const char* adobe_name = psnames->adobe_std_strings( sid ); FT_UInt len; if ( adobe_name ) { FT_Memory memory = idx->stream->memory; FT_Error error; len = (FT_UInt)ft_strlen( adobe_name ); if ( !FT_ALLOC( name, len + 1 ) ) { FT_MEM_COPY( name, adobe_name, len ); name[len] = 0; } FT_UNUSED( error ); } return name; } }
FT_Stream_ReadAt( FT_Stream stream, FT_ULong pos, FT_Byte* buffer, FT_ULong count ) { FT_Error error = FT_Err_Ok; FT_ULong read_bytes; if ( pos >= stream->size ) { FT_ERROR(( "FT_Stream_ReadAt:" " invalid i/o; pos = 0x%lx, size = 0x%lx\n", pos, stream->size )); return FT_Err_Invalid_Stream_Operation; } if ( stream->read ) read_bytes = stream->read( stream, pos, buffer, count ); else { read_bytes = stream->size - pos; if ( read_bytes > count ) read_bytes = count; FT_MEM_COPY( buffer, stream->base + pos, read_bytes ); } stream->pos = pos + read_bytes; if ( read_bytes < count ) { FT_ERROR(( "FT_Stream_ReadAt:" " invalid read; expected %lu bytes, got %lu\n", count, read_bytes )); error = FT_Err_Invalid_Stream_Operation; } return error; }
static FT_Error ftc_sbit_copy_bitmap( FTC_SBit sbit, FT_Bitmap* bitmap, FT_Memory memory ) { FT_Error error; FT_Int pitch = bitmap->pitch; FT_ULong size; if ( pitch < 0 ) pitch = -pitch; size = (FT_ULong)( pitch * bitmap->rows ); if ( !FT_ALLOC( sbit->buffer, size ) ) FT_MEM_COPY( sbit->buffer, bitmap->buffer, size ); return error; }
/* * Load a name from the auxiliary data. Since this extracts undocumented * strings from the font file, we need to be careful here. */ static FT_Error pfr_aux_name_load( FT_Byte* p, FT_UInt len, FT_Memory memory, FT_String* *astring ) { FT_Error error = FT_Err_Ok; FT_String* result = NULL; FT_UInt n, ok; if ( *astring ) FT_FREE( *astring ); if ( len > 0 && p[len - 1] == 0 ) len--; /* check that each character is ASCII */ /* for making sure not to load garbage */ ok = ( len > 0 ); for ( n = 0; n < len; n++ ) if ( p[n] < 32 || p[n] > 127 ) { ok = 0; break; } if ( ok ) { if ( FT_ALLOC( result, len + 1 ) ) goto Exit; FT_MEM_COPY( result, p, len ); result[len] = 0; } Exit: *astring = result; return error; }
pfr_extra_item_load_font_id( FT_Byte* p, FT_Byte* limit, PFR_PhyFont phy_font ) { FT_Error error = FT_Err_Ok; FT_Memory memory = phy_font->memory; FT_UInt len = (FT_UInt)( limit - p ); if ( phy_font->font_id ) goto Exit; if ( FT_ALLOC( phy_font->font_id, len + 1 ) ) goto Exit; /* copy font ID name, and terminate it for safety */ FT_MEM_COPY( phy_font->font_id, p, len ); phy_font->font_id[len] = 0; Exit: return error; }
static FT_Error ft_bitmap_copy( FT_Memory memory, FT_Bitmap* source, FT_Bitmap* target ) { FT_Error error; FT_Int pitch = source->pitch; FT_ULong size; *target = *source; if ( pitch < 0 ) pitch = -pitch; size = (FT_ULong)( pitch * source->rows ); if ( !FT_ALLOC( target->buffer, size ) ) FT_MEM_COPY( target->buffer, source->buffer, size ); return error; }
static OSErr FT_FSpMakePath( const FSSpec* spec_p, UInt8* path, UInt32 maxPathSize ) { OSErr err; FSSpec spec = *spec_p; short vRefNum; long dirID; Str255 parDir_name; FT_MEM_SET( path, 0, maxPathSize ); while ( 1 ) { int child_namelen = ft_strlen( (char *)path ); unsigned char node_namelen = spec.name[0]; unsigned char* node_name = spec.name + 1; if ( node_namelen + child_namelen > maxPathSize ) return errFSNameTooLong; FT_MEM_MOVE( path + node_namelen + 1, path, child_namelen ); FT_MEM_COPY( path, node_name, node_namelen ); if ( child_namelen > 0 ) path[node_namelen] = ':'; vRefNum = spec.vRefNum; dirID = spec.parID; parDir_name[0] = '\0'; err = FSMakeFSSpec( vRefNum, dirID, parDir_name, &spec ); if ( noErr != err || dirID == spec.parID ) break; } return noErr; }
FT_Stream_ReadFields( FT_Stream stream, const FT_Frame_Field* fields, void* structure ) { FT_Error error; FT_Bool frame_accessed = 0; FT_Byte* cursor = stream->cursor; if ( !fields || !stream ) return FT_Err_Invalid_Argument; error = FT_Err_Ok; do { FT_ULong value; FT_Int sign_shift; FT_Byte* p; switch ( fields->value ) { case ft_frame_start: /* access a new frame */ error = FT_Stream_EnterFrame( stream, fields->offset ); if ( error ) goto Exit; frame_accessed = 1; cursor = stream->cursor; fields++; continue; /* loop! */ case ft_frame_bytes: /* read a byte sequence */ case ft_frame_skip: /* skip some bytes */ { FT_UInt len = fields->size; if ( cursor + len > stream->limit ) { error = FT_Err_Invalid_Stream_Operation; goto Exit; } if ( fields->value == ft_frame_bytes ) { p = (FT_Byte*)structure + fields->offset; FT_MEM_COPY( p, cursor, len ); } cursor += len; fields++; continue; } case ft_frame_byte: case ft_frame_schar: /* read a single byte */ value = FT_NEXT_BYTE(cursor); sign_shift = 24; break; case ft_frame_short_be: case ft_frame_ushort_be: /* read a 2-byte big-endian short */ value = FT_NEXT_USHORT(cursor); sign_shift = 16; break; case ft_frame_short_le: case ft_frame_ushort_le: /* read a 2-byte little-endian short */ value = FT_NEXT_USHORT_LE(cursor); sign_shift = 16; break; case ft_frame_long_be: case ft_frame_ulong_be: /* read a 4-byte big-endian long */ value = FT_NEXT_ULONG(cursor); sign_shift = 0; break; case ft_frame_long_le: case ft_frame_ulong_le: /* read a 4-byte little-endian long */ value = FT_NEXT_ULONG_LE(cursor); sign_shift = 0; break; case ft_frame_off3_be: case ft_frame_uoff3_be: /* read a 3-byte big-endian long */ value = FT_NEXT_UOFF3(cursor); sign_shift = 8; break; case ft_frame_off3_le: case ft_frame_uoff3_le: /* read a 3-byte little-endian long */ value = FT_NEXT_UOFF3_LE(cursor); sign_shift = 8; break; default: /* otherwise, exit the loop */ stream->cursor = cursor; goto Exit; } /* now, compute the signed value is necessary */ if ( fields->value & FT_FRAME_OP_SIGNED ) value = (FT_ULong)( (FT_Int32)( value << sign_shift ) >> sign_shift ); /* finally, store the value in the object */ p = (FT_Byte*)structure + fields->offset; switch ( fields->size ) { case (8 / FT_CHAR_BIT): *(FT_Byte*)p = (FT_Byte)value; break; case (16 / FT_CHAR_BIT): *(FT_UShort*)p = (FT_UShort)value; break; case (32 / FT_CHAR_BIT): *(FT_UInt32*)p = (FT_UInt32)value; break; default: /* for 64-bit systems */ *(FT_ULong*)p = (FT_ULong)value; } /* go to next field */ fields++; } while ( 1 ); Exit: /* close the frame if it was opened by this read */ if ( frame_accessed ) FT_Stream_ExitFrame( stream ); return error; }
static FT_Class ft_metaclass_get_class( FT_MetaClass meta, FT_Type ctype ) { FT_ClassHNodeRec keynode, *node, **pnode; FT_Memory memory; FT_ClassRec* clazz; FT_Class parent; FT_Error error; keynode.hnode.hash = FT_TYPE_HASH( ctype ); keynode.type = ctype; pnode = (FT_ClassHNode*) ft_hash_lookup( &meta->type_to_class, (FT_HashNode) &keynode ); node = *pnode; if ( node != NULL ) { clazz = (FT_ClassRec*) node->clazz; goto Exit; } memory = FT_CLASS__MEMORY(meta); clazz = NULL; parent = NULL; if ( ctype->super != NULL ) { FT_ASSERT( ctype->super->class_size <= ctype->class_size ); FT_ASSERT( ctype->super->obj_size <= ctype->obj_size ); parent = ft_metaclass_get_class( meta, ctype->super ); } if ( !FT_NEW( node ) ) { if ( !FT_ALLOC( clazz, ctype->class_size ) ) { if ( parent ) FT_MEM_COPY( (FT_ClassRec*)clazz, parent, parent->type->class_size ); clazz->object.clazz = (FT_Class) meta; clazz->object.ref_count = 1; clazz->memory = memory; clazz->library = FT_CLASS__LIBRARY(meta); clazz->super = parent; clazz->type = ctype; clazz->info = NULL; clazz->magic = FT_MAGIC_CLASS; clazz->class_done = ctype->class_done; clazz->obj_size = ctype->obj_size; clazz->obj_init = ctype->obj_init; clazz->obj_done = ctype->obj_done; if ( parent ) { if ( clazz->class_done == NULL ) clazz->class_done = parent->class_done; if ( clazz->obj_init == NULL ) clazz->obj_init = parent->obj_init; if ( clazz->obj_done == NULL ) clazz->obj_done = parent->obj_done; } /* find class initializer, if any */ { FT_Type ztype = ctype; FT_Object_InitFunc cinit = NULL; do { cinit = ztype->class_init; if ( cinit != NULL ) break; ztype = ztype->super; } while ( ztype != NULL ); /* then call it when needed */ if ( cinit != NULL ) error = cinit( (FT_Object) clazz, NULL ); } } if (error) { if ( clazz ) { /* we always call the class destructor when */ /* an error was detected in the constructor !! */ if ( clazz->class_done ) clazz->class_done( (FT_Object) clazz ); FT_FREE( clazz ); } FT_FREE( node ); } } Exit: return (FT_Class) clazz; }
static FT_Error RunIns( TT_ExecContext exc ) { FT_Int A, diff, key; FT_Long next_IP; FT_String ch, oldch = '\0', *temp; FT_Error error = 0; TT_GlyphZoneRec save; TT_GlyphZoneRec pts; const FT_String* round_str[8] = { "to half-grid", "to grid", "to double grid", "down to grid", "up to grid", "off", "super", "super 45" }; /* only debug the requested code range */ if (exc->curRange != (FT_Int)debug_coderange) return TT_RunIns(exc); exc->pts.n_points = exc->zp0.n_points; exc->pts.n_contours = exc->zp0.n_contours; pts = exc->pts; save.n_points = pts.n_points; save.n_contours = pts.n_contours; save.org = (FT_Vector*)malloc( 2 * sizeof( FT_F26Dot6 ) * save.n_points ); save.cur = (FT_Vector*)malloc( 2 * sizeof( FT_F26Dot6 ) * save.n_points ); save.tags = (FT_Byte*)malloc( save.n_points ); exc->instruction_trap = 1; do { if ( CUR.IP < CUR.codeSize ) { Calc_Length( exc ); CUR.args = CUR.top - (Pop_Push_Count[CUR.opcode] >> 4); /* `args' is the top of the stack once arguments have been popped. */ /* One can also interpret it as the index of the last argument. */ /* Print the current line. We use a 80-columns console with the */ /* following formatting: */ /* */ /* [loc]:[addr] [opcode] [disassemby] [a][b]|[c][d] */ /* */ { char temp[80]; int n, col, pop; int args = CUR.args; sprintf( temp, "%78c\n", ' ' ); /* first letter of location */ switch ( CUR.curRange ) { case tt_coderange_glyph: temp[0] = 'g'; break; case tt_coderange_cvt: temp[0] = 'c'; break; default: temp[0] = 'f'; } /* current IP */ sprintf( temp+1, "%04lx: %02x %-36.36s", CUR.IP, CUR.opcode, Cur_U_Line(&CUR) ); strncpy( temp+46, " (", 2 ); args = CUR.top - 1; pop = Pop_Push_Count[CUR.opcode] >> 4; col = 48; /* special case for IP */ if (CUR.opcode == 0x39) pop = exc->GS.loop; for ( n = 6; n > 0; n-- ) { if ( pop == 0 ) temp[col-1] = (temp[col-1] == '(' ? ' ' : ')' ); if ( args < CUR.top && args >= 0 ) sprintf( temp+col, "%04lx", CUR.stack[args] ); else sprintf( temp+col, " " ); temp[col+4] = ' '; col += 5; pop--; args--; } temp[78] = '\n'; temp[79] = '\0'; printf( "%s", temp ); } /* First, check for empty stack and overflow */ if ( CUR.args < 0 ) { printf( "ERROR : Too Few Arguments\n" ); CUR.error = TT_Err_Too_Few_Arguments; goto LErrorLabel_; } CUR.new_top = CUR.args + (Pop_Push_Count[CUR.opcode] & 15); /* new_top is the new top of the stack, after the instruction's */ /* execution. top will be set to new_top after the 'case' */ if ( CUR.new_top > CUR.stackSize ) { printf( "ERROR : Stack overflow\n" ); CUR.error = TT_Err_Stack_Overflow; goto LErrorLabel_; } } else printf( "End of program reached.\n" ); key = 0; do { /* read keyboard */ ch = getch(); switch ( ch ) { /* Help - show keybindings */ case '?': printf( "TTDebug Help\n\n" ); printf( "? Show this page\n" ); printf( "q Quit debugger\n" ); printf( "n Skip to next instruction\n" ); printf( "s Step into\n" ); printf( "v Show vector info\n" ); printf( "g Show graphics state\n" ); printf( "p Show points zone\n\n" ); break; /* Show vectors */ case 'v': printf( "freedom (%04hx,%04hx)\n", exc->GS.freeVector.x, exc->GS.freeVector.y ); printf( "projection (%04hx,%04hx)\n", exc->GS.projVector.x, exc->GS.projVector.y ); printf( "dual (%04hx,%04hx)\n\n", exc->GS.dualVector.x, exc->GS.dualVector.y ); break; /* Show graphics state */ case 'g': printf( "rounding %s\n", round_str[exc->GS.round_state] ); printf( "min dist %04lx\n", exc->GS.minimum_distance ); printf( "cvt_cutin %04lx\n", exc->GS.control_value_cutin ); printf( "RP 0,1,2 %4x %4x %4x\n", exc->GS.rp0, exc->GS.rp1, exc->GS.rp2 ); break; /* Show points table */ case 'p': for ( A = 0; A < exc->pts.n_points; A++ ) { printf( "%3hd ", A ); printf( "(%6d,%6d) - ", pts.orus[A].x, pts.orus[A].y ); printf( "(%8ld,%8ld) - ", pts.org[A].x, pts.org[A].y ); printf( "(%8ld,%8ld)\n", pts.cur[A].x, pts.cur[A].y ); } printf(( "\n" )); break; default: key = 1; } } while ( !key ); FT_MEM_COPY( save.org, pts.org, pts.n_points * sizeof ( FT_Vector ) ); FT_MEM_COPY( save.cur, pts.cur, pts.n_points * sizeof ( FT_Vector ) ); FT_MEM_COPY( save.tags, pts.tags, pts.n_points ); /* a return indicate the last command */ if (ch == '\r') ch = oldch; switch ( ch ) { /* Quit debugger */ case 'q': goto LErrorLabel_; /* Step over */ case 'n': if ( exc->IP < exc->codeSize ) { /* `step over' is equivalent to `step into' except if */ /* the current opcode is a CALL or LOOPCALL */ if ( CUR.opcode != 0x2a && CUR.opcode != 0x2b ) goto Step_into; /* otherwise, loop execution until we reach the next opcode */ next_IP = CUR.IP + CUR.length; while ( exc->IP != next_IP ) { if ( ( error = TT_RunIns( exc ) ) != 0 ) goto LErrorLabel_; } } oldch = ch; break; /* Step into */ case 's': if ( exc->IP < exc->codeSize ) Step_into: if ( ( error = TT_RunIns( exc ) ) != 0 ) goto LErrorLabel_; oldch = ch; break; default: printf( "unknown command. Press ? for help\n" ); oldch = '\0'; } for ( A = 0; A < pts.n_points; A++ ) { diff = 0; if ( save.org[A].x != pts.org[A].x ) diff |= 1; if ( save.org[A].y != pts.org[A].y ) diff |= 2; if ( save.cur[A].x != pts.cur[A].x ) diff |= 4; if ( save.cur[A].y != pts.cur[A].y ) diff |= 8; if ( save.tags[A] != pts.tags[A] ) diff |= 16; if ( diff ) { printf( "%3hd ", A ); printf( "%6d,%6d ", pts.orus[A].x, pts.orus[A].y ); if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx "; printf( temp, old_tag_to_new(save.tags[A]) ); if ( diff & 1 ) temp = "(%8ld)"; else temp = " %8ld "; printf( temp, save.org[A].x ); if ( diff & 2 ) temp = "(%8ld)"; else temp = " %8ld "; printf( temp, save.org[A].y ); if ( diff & 4 ) temp = "(%8ld)"; else temp = " %8ld "; printf( temp, save.cur[A].x ); if ( diff & 8 ) temp = "(%8ld)"; else temp = " %8ld "; printf( temp, save.cur[A].y ); printf( "\n" ); printf( " " ); if ( diff & 16 ) temp = "[%01hx]"; else temp = " "; printf( temp, old_tag_to_new(pts.tags[A]) ); if ( diff & 1 ) temp = "[%8ld]"; else temp = " "; printf( temp, pts.org[A].x ); if ( diff & 2 ) temp = "[%8ld]"; else temp = " "; printf( temp, pts.org[A].y ); if ( diff & 4 ) temp = "[%8ld]"; else temp = " "; printf( temp, pts.cur[A].x ); if ( diff & 8 ) temp = "[%8ld]"; else temp = " "; printf( temp, pts.cur[A].y ); printf( "\n" ); } } } while ( TRUE );
FT_Bitmap_Copy( FT_Library library, const FT_Bitmap *source, FT_Bitmap *target) { FT_Memory memory; FT_Error error = FT_Err_Ok; FT_Int pitch; FT_ULong size; FT_Int source_pitch_sign, target_pitch_sign; if ( !library ) return FT_THROW( Invalid_Library_Handle ); if ( !source || !target ) return FT_THROW( Invalid_Argument ); if ( source == target ) return FT_Err_Ok; source_pitch_sign = source->pitch < 0 ? -1 : 1; target_pitch_sign = target->pitch < 0 ? -1 : 1; if ( source->buffer == NULL ) { *target = *source; if ( source_pitch_sign != target_pitch_sign ) target->pitch = -target->pitch; return FT_Err_Ok; } memory = library->memory; pitch = source->pitch; if ( pitch < 0 ) pitch = -pitch; size = (FT_ULong)pitch * source->rows; if ( target->buffer ) { FT_Int target_pitch = target->pitch; FT_ULong target_size; if ( target_pitch < 0 ) target_pitch = -target_pitch; target_size = (FT_ULong)target_pitch * target->rows; if ( target_size != size ) (void)FT_QREALLOC( target->buffer, target_size, size ); } else (void)FT_QALLOC( target->buffer, size ); if ( !error ) { unsigned char *p; p = target->buffer; *target = *source; target->buffer = p; if ( source_pitch_sign == target_pitch_sign ) FT_MEM_COPY( target->buffer, source->buffer, size ); else { /* take care of bitmap flow */ FT_UInt i; FT_Byte* s = source->buffer; FT_Byte* t = target->buffer; t += pitch * ( target->rows - 1 ); for ( i = target->rows; i > 0; i-- ) { FT_ARRAY_COPY( t, s, pitch ); s += pitch; t -= pitch; } } } return error; }
static FT_ULong ft_lzw_file_io( FT_LZWFile zip, FT_ULong pos, FT_Byte* buffer, FT_ULong count ) { FT_ULong result = 0; FT_Error error; /* seeking backwards. */ if ( pos < zip->pos ) { /* If the new position is within the output buffer, simply */ /* decrement pointers, otherwise we reset the stream completely! */ if ( ( zip->pos - pos ) <= (FT_ULong)( zip->cursor - zip->buffer ) ) { zip->cursor -= zip->pos - pos; zip->pos = pos; } else { error = ft_lzw_file_reset( zip ); if ( error ) goto Exit; } } /* skip unwanted bytes */ if ( pos > zip->pos ) { error = ft_lzw_file_skip_output( zip, (FT_ULong)( pos - zip->pos ) ); if ( error ) goto Exit; } if ( count == 0 ) goto Exit; /* now read the data */ for (;;) { FT_ULong delta; delta = (FT_ULong)( zip->limit - zip->cursor ); if ( delta >= count ) delta = count; FT_MEM_COPY( buffer + result, zip->cursor, delta ); result += delta; zip->cursor += delta; zip->pos += delta; count -= delta; if ( count == 0 ) break; error = ft_lzw_file_fill_output( zip ); if ( error ) break; } Exit: return result; }
static FT_Error RunIns( TT_ExecContext exc ) { FT_Int A, diff, key; FT_Long next_IP; FT_String ch, oldch = '\0'; TT_GlyphZoneRec save; TT_GlyphZoneRec pts; const FT_String* code_range; const FT_String* round_str[8] = { "to half-grid", "to grid", "to double grid", "down to grid", "up to grid", "off", "super", "super 45" }; error = FT_Err_Ok; CUR.pts.n_points = CUR.zp0.n_points; CUR.pts.n_contours = CUR.zp0.n_contours; pts = CUR.pts; save.n_points = pts.n_points; save.n_contours = pts.n_contours; save.org = (FT_Vector*)malloc( 2 * sizeof( FT_F26Dot6 ) * save.n_points ); save.cur = (FT_Vector*)malloc( 2 * sizeof( FT_F26Dot6 ) * save.n_points ); save.tags = (FT_Byte*)malloc( save.n_points ); CUR.instruction_trap = 1; switch ( CUR.curRange ) { case tt_coderange_glyph: code_range = "glyf"; break; case tt_coderange_cvt: code_range = "prep"; break; default: code_range = "fpgm"; } printf( "Entering `%s' table.\n" "\n", code_range ); do { if ( CUR.IP < CUR.codeSize ) { Calc_Length( exc ); CUR.args = CUR.top - ( Pop_Push_Count[CUR.opcode] >> 4 ); /* `args' is the top of the stack once arguments have been popped. */ /* One can also interpret it as the index of the last argument. */ /* Print the current line. We use an 80-columns console with the */ /* following formatting: */ /* */ /* [loc]:[addr] [opcode] [disassemby] [a][b]|[c][d] */ { char temp[80]; int n, col, pop; int args = CUR.args; sprintf( temp, "%78c\n", ' ' ); /* first letter of location */ switch ( CUR.curRange ) { case tt_coderange_glyph: temp[0] = 'g'; break; case tt_coderange_cvt: temp[0] = 'c'; break; default: temp[0] = 'f'; } /* current IP */ sprintf( temp + 1, "%04lx: %02x %-36.36s", CUR.IP, CUR.opcode, Cur_U_Line( &CUR ) ); strncpy( temp + 46, " (", 2 ); args = CUR.top - 1; pop = Pop_Push_Count[CUR.opcode] >> 4; col = 48; /* special case for IP */ if ( CUR.opcode == 0x39 ) pop = CUR.GS.loop; for ( n = 6; n > 0; n-- ) { if ( pop == 0 ) temp[col - 1] = temp[col - 1] == '(' ? ' ' : ')'; if ( args < CUR.top && args >= 0 ) sprintf( temp + col, "%04lx", CUR.stack[args] ); else sprintf( temp + col, " " ); temp[col + 4] = ' '; col += 5; pop--; args--; } temp[78] = '\n'; temp[79] = '\0'; printf( "%s", temp ); } /* First, check for empty stack and overflow */ if ( CUR.args < 0 ) { printf( "ERROR: Too Few Arguments\n" ); CUR.error = TT_Err_Too_Few_Arguments; goto LErrorLabel_; } CUR.new_top = CUR.args + ( Pop_Push_Count[CUR.opcode] & 15 ); /* `new_top' is the new top of the stack, after the instruction's */ /* execution. `top' will be set to `new_top' after the 'case'. */ if ( CUR.new_top > CUR.stackSize ) { printf( "ERROR: Stack overflow\n" ); CUR.error = TT_Err_Stack_Overflow; goto LErrorLabel_; } } else { if ( CUR.curRange == tt_coderange_glyph ) printf( "End of program reached.\n" ); else { printf( "\n" ); goto LErrorLabel_; } } key = 0; do { /* read keyboard */ ch = getch(); switch ( ch ) { /* Help - show keybindings */ case '?': printf( "\n" "ttdebug Help\n" "\n" "? show this page\n" "q quit debugger\n" "c continue to next code range\n" "n skip to next instruction\n" "s step into\n" "v show vector info\n" "g show graphics state\n" "p show points zone\n" "f toggle between floating and fixed point number format\n" "l show last bytecode instruction\n" "\n" "\n" " Format of point changes:\n" "\n" " idx orus.x orus.y tags org.x org.y cur.x cur.y\n" "\n" " The first line gives the values before the instruction,\n" " the second line the changes after the instruction,\n" " indicated by parentheses and brackets for emphasis.\n" "\n" " Tag values (which are ORed):\n" "\n" " 1 on curve\n" " 2 touched along the X axis\n" " 4 touched along the Y axis\n" "\n" ); break; /* Toggle between floating and fixed point format */ case 'f': use_float = !use_float; printf( "use %s point format for displaying values\n", use_float ? "floating" : "fixed" ); printf( "\n" ); break; /* Show vectors */ case 'v': if ( use_float ) { /* 2.14 numbers */ printf( "freedom (%.5f, %.5f)\n", CUR.GS.freeVector.x / 16384.0, CUR.GS.freeVector.y / 16384.0 ); printf( "projection (%.5f, %.5f)\n", CUR.GS.projVector.x / 16384.0, CUR.GS.projVector.y / 16384.0 ); printf( "dual (%.5f, %.5f)\n", CUR.GS.dualVector.x / 16384.0, CUR.GS.dualVector.y / 16384.0 ); printf( "\n" ); } else { printf( "freedom ($%04hx, $%04hx)\n", CUR.GS.freeVector.x, CUR.GS.freeVector.y ); printf( "projection ($%04hx, $%04hx)\n", CUR.GS.projVector.x, CUR.GS.projVector.y ); printf( "dual ($%04hx, $%04hx)\n", CUR.GS.dualVector.x, CUR.GS.dualVector.y ); printf( "\n" ); } break; /* Show graphics state */ case 'g': printf( "rounding state %s\n", round_str[CUR.GS.round_state] ); if ( use_float ) { /* 26.6 numbers */ printf( "minimum distance %.2f\n", CUR.GS.minimum_distance / 64.0 ); printf( "CVT cut-in %.2f\n", CUR.GS.control_value_cutin / 64.0 ); } else { printf( "minimum distance $%04lx\n", CUR.GS.minimum_distance ); printf( "CVT cut-in $%04lx\n", CUR.GS.control_value_cutin ); } printf( "ref. points 0,1,2 %d, %d, %d\n", CUR.GS.rp0, CUR.GS.rp1, CUR.GS.rp2 ); printf( "\n" ); break; /* Show points table */ case 'p': if ( CUR.pts.n_points ) { printf( "idx " "orig. unscaled - " "orig. scaled - " "current scaled \n" ); printf( "-----" "------------------" "----------------------" "-------------------\n" ); } else printf( "not yet in `glyf' program\n" ); for ( A = 0; A < CUR.pts.n_points; A++ ) { printf( "%3d ", A ); printf( "(%6ld,%6ld) - ", pts.orus[A].x, pts.orus[A].y ); if ( use_float ) { printf( "(%8.2f,%8.2f) - ", pts.org[A].x / 64.0, pts.org[A].y / 64.0 ); printf( "(%8.2f,%8.2f)\n", pts.cur[A].x / 64.0, pts.cur[A].y / 64.0 ); } else { printf( "(%8ld,%8ld) - ", pts.org[A].x, pts.org[A].y ); printf( "(%8ld,%8ld)\n", pts.cur[A].x, pts.cur[A].y ); } } printf( "\n" ); break; default: key = 1; } } while ( !key ); FT_MEM_COPY( save.org, pts.org, pts.n_points * sizeof ( FT_Vector ) ); FT_MEM_COPY( save.cur, pts.cur, pts.n_points * sizeof ( FT_Vector ) ); FT_MEM_COPY( save.tags, pts.tags, pts.n_points ); /* a return indicates the last command */ if ( ch == '\r' ) ch = oldch; switch ( ch ) { /* quit debugger */ case 'q': error = Quit; goto LErrorLabel_; /* continue */ case 'c': if ( CUR.IP < CUR.codeSize ) { /* loop execution until we reach end of current code range */ while ( CUR.IP < CUR.codeSize ) { if ( ( error = TT_RunIns( exc ) ) != 0 ) goto LErrorLabel_; } } /* step over */ case 'n': if ( CUR.IP < CUR.codeSize ) { /* `step over' is equivalent to `step into' except if */ /* the current opcode is a CALL or LOOPCALL */ if ( CUR.opcode != 0x2a && CUR.opcode != 0x2b ) goto Step_into; /* otherwise, loop execution until we reach the next opcode */ next_IP = CUR.IP + CUR.length; while ( CUR.IP != next_IP ) { if ( ( error = TT_RunIns( exc ) ) != 0 ) goto LErrorLabel_; } } oldch = ch; break; /* step into */ case 's': if ( CUR.IP < CUR.codeSize ) Step_into: if ( ( error = TT_RunIns( exc ) ) != 0 ) goto LErrorLabel_; oldch = ch; break; /* show last bytecode instruction */ case 'l': oldch = ch; break; default: printf( "Unknown command. Press ? for help\n" ); oldch = '\0'; } for ( A = 0; A < pts.n_points; A++ ) { diff = 0; if ( save.org[A].x != pts.org[A].x ) diff |= 1; if ( save.org[A].y != pts.org[A].y ) diff |= 2; if ( save.cur[A].x != pts.cur[A].x ) diff |= 4; if ( save.cur[A].y != pts.cur[A].y ) diff |= 8; if ( save.tags[A] != pts.tags[A] ) diff |= 16; if ( diff ) { const FT_String* temp; printf( "%3d ", A ); printf( "%6ld,%6ld ", pts.orus[A].x, pts.orus[A].y ); if ( diff & 16 ) temp = "(%01hx)"; else temp = " %01hx "; printf( temp, old_tag_to_new( save.tags[A] ) ); if ( diff & 1 ) temp = use_float ? "(%8.2f)" : "(%8ld)"; else temp = use_float ? " %8.2f " : " %8ld "; if ( use_float ) printf( temp, save.org[A].x / 64.0 ); else printf( temp, save.org[A].x ); if ( diff & 2 ) temp = use_float ? "(%8.2f)" : "(%8ld)"; else temp = use_float ? " %8.2f " : " %8ld "; if ( use_float ) printf( temp, save.org[A].y / 64.0 ); else printf( temp, save.org[A].y ); if ( diff & 4 ) temp = use_float ? "(%8.2f)" : "(%8ld)"; else temp = use_float ? " %8.2f " : " %8ld "; if ( use_float ) printf( temp, save.cur[A].x / 64.0 ); else printf( temp, save.cur[A].x ); if ( diff & 8 ) temp = use_float ? "(%8.2f)" : "(%8ld)"; else temp = use_float ? " %8.2f " : " %8ld "; if ( use_float ) printf( temp, save.cur[A].y / 64.0 ); else printf( temp, save.cur[A].y ); printf( "\n" ); printf( " " ); if ( diff & 16 ) temp = "[%01hx]"; else temp = " "; printf( temp, old_tag_to_new( pts.tags[A] ) ); if ( diff & 1 ) temp = use_float ? "[%8.2f]" : "[%8ld]"; else temp = " "; if ( use_float ) printf( temp, pts.org[A].x / 64.0 ); else printf( temp, pts.org[A].x ); if ( diff & 2 ) temp = use_float ? "[%8.2f]" : "[%8ld]"; else temp = " "; if ( use_float ) printf( temp, pts.org[A].y / 64.0 ); else printf( temp, pts.org[A].y ); if ( diff & 4 ) temp = use_float ? "[%8.2f]" : "[%8ld]"; else temp = " "; if ( use_float ) printf( temp, pts.cur[A].x / 64.0 ); else printf( temp, pts.cur[A].x ); if ( diff & 8 ) temp = use_float ? "[%8.2f]" : "[%8ld]"; else temp = " "; if ( use_float ) printf( temp, pts.cur[A].y / 64.0 ); else printf( temp, pts.cur[A].y ); printf( "\n" ); } } } while ( TRUE );
/* entries to C-style strings (this is, NULL-terminated). */ static FT_Error cff_index_get_pointers( CFF_Index idx, FT_Byte*** table, FT_Byte** pool ) { FT_Error error = FT_Err_Ok; FT_Memory memory = idx->stream->memory; FT_Byte** t = NULL; FT_Byte* new_bytes = NULL; *table = NULL; if ( idx->offsets == NULL ) { error = cff_index_load_offsets( idx ); if ( error ) goto Exit; } if ( idx->count > 0 && !FT_NEW_ARRAY( t, idx->count + 1 ) && ( !pool || !FT_ALLOC( new_bytes, idx->data_size + idx->count ) ) ) { FT_ULong n, cur_offset; FT_ULong extra = 0; FT_Byte* org_bytes = idx->bytes; /* at this point, `idx->offsets' can't be NULL */ cur_offset = idx->offsets[0] - 1; /* sanity check */ if ( cur_offset != 0 ) { FT_TRACE0(( "cff_index_get_pointers:" " invalid first offset value %d set to zero\n", cur_offset )); cur_offset = 0; } if ( !pool ) t[0] = org_bytes + cur_offset; else t[0] = new_bytes + cur_offset; for ( n = 1; n <= idx->count; n++ ) { FT_ULong next_offset = idx->offsets[n] - 1; /* two sanity checks for invalid offset tables */ if ( next_offset < cur_offset ) next_offset = cur_offset; else if ( next_offset > idx->data_size ) next_offset = idx->data_size; if ( !pool ) t[n] = org_bytes + next_offset; else { t[n] = new_bytes + next_offset + extra; if ( next_offset != cur_offset ) { FT_MEM_COPY( t[n - 1], org_bytes + cur_offset, t[n] - t[n - 1] ); t[n][0] = '\0'; t[n] += 1; extra++; } } cur_offset = next_offset; } *table = t; if ( pool ) *pool = new_bytes; } Exit: return error; }