📄 ttobjs.c
字号:
/******************************************************************* * * ttobjs.c 1.0 * * Objects manager. * * Copyright 1996-1999 by * David Turner, Robert Wilhelm, and Werner Lemberg. * * This file is part of the FreeType project, and may only be used * modified and distributed under the terms of the FreeType project * license, LICENSE.TXT. By continuing to use, modify, or distribute * this file you indicate that you have read the license and * understand and accept it fully. * ******************************************************************/#include "ttobjs.h"#include "ttfile.h"#include "ttcalc.h"#include "ttmemory.h"#include "ttload.h"#include "ttinterp.h"#include "ttdebug.h"/* Add extensions definition */#ifdef TT_CONFIG_OPTION_EXTEND_ENGINE#include "ttextend.h"#endif/* Required by tracing mode */#undef TT_COMPONENT#define TT_COMPONENT trace_objs/******************************************************************* * * Function : New_Context * * Description : Creates a new execution context for a given * face object. * ******************************************************************/ LOCAL_FUNC PExecution_Context New_Context( PFace face ) { PEngine_Instance engine; PExecution_Context exec; if ( !face ) return NULL; engine = face->engine; CACHE_New( engine->objs_exec_cache, exec, face ); return exec; }/******************************************************************* * * Function : Done_Context * * Description : Discards an execution context. * ******************************************************************/ LOCAL_FUNC TT_Error Done_Context( PExecution_Context exec ) { PEngine_Instance engine; if ( !exec ) return TT_Err_Ok; engine = exec->face->engine; return CACHE_Done( engine->objs_exec_cache, exec ); }#if 0/******************************************************************* * * Function : New_Instance * * Description : Creates a new instance for a given face object. * ******************************************************************/ LOCAL_FUNC PInstance New_Instance( PFace face ) { PInstance ins; if ( !face ) return NULL; CACHE_New( &face->instances, ins, face ); return ins; }/******************************************************************* * * Function : Done_Instance * * Description : Discards an instance. * ******************************************************************/ LOCAL_FUNC TT_Error Done_Instance( PInstance instance ) { return CACHE_Done( &instance->owner->instances, instance ); }#endif/******************************************************************* * * * GLYPH ZONE FUNCTIONS * * * * * *******************************************************************//******************************************************************* * * Function : New_Glyph_Zone * * Description : Allocates a new glyph zone * * Input : pts pointer to the target glyph zone record * maxPoints capacity of glyph zone in points * maxContours capacity of glyph zone in contours * * Return : Error code. * *****************************************************************/ static TT_Error New_Glyph_Zone( PGlyph_Zone pts, UShort maxPoints, UShort maxContours ) { TT_Error error; if ( ALLOC( pts->org, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) || ALLOC( pts->cur, maxPoints * 2 * sizeof ( TT_F26Dot6 ) ) || ALLOC( pts->touch, maxPoints * sizeof ( Byte ) ) || ALLOC( pts->contours, maxContours * sizeof ( Short ) ) ) return error; return TT_Err_Ok; }/******************************************************************* * * Function : Done_Glyph_Zone * * Description : Deallocates a glyph zone * * Input : pts pointer to the target glyph zone record * * Return : Error code. * *****************************************************************/ static TT_Error Done_Glyph_Zone( PGlyph_Zone pts ) { FREE( pts->contours ); FREE( pts->touch ); FREE( pts->cur ); FREE( pts->org ); return TT_Err_Ok; }/******************************************************************* * * * CODERANGE FUNCTIONS * * * *******************************************************************//******************************************************************* * * Function : Goto_CodeRange * * Description : Switch to a new code range (updates Code and IP). * * Input : exec target execution context * range new execution code range * IP new IP in new code range * * Output : SUCCESS on success. FAILURE on error (no code range). * *****************************************************************/ LOCAL_FUNC TT_Error Goto_CodeRange( PExecution_Context exec, Int range, ULong IP ) { PCodeRange cr; if ( range < 1 || range > 3 ) return TT_Err_Bad_Argument; cr = &exec->codeRangeTable[range - 1]; if ( cr->Base == NULL ) return TT_Err_Invalid_CodeRange; /* NOTE: Because the last instruction of a program may be a CALL */ /* which will return to the first byte *after* the code */ /* range, we test for IP <= Size, instead of IP < Size. */ if ( IP > cr->Size ) return TT_Err_Code_Overflow; exec->code = cr->Base; exec->codeSize = cr->Size; exec->IP = IP; exec->curRange = range; return TT_Err_Ok; }#if 0/******************************************************************* * * Function : Get_CodeRange * * Description : Returns a pointer to a given code range. Should * be used only by the debugger. Returns NULL if * 'range' is out of current bounds. * * Input : exec target execution context * range new execution code range * * Output : Pointer to the code range record. NULL on failure. * *****************************************************************/ LOCAL_FUNC PCodeRange Get_CodeRange( PExecution_Context exec, Int range ) { if ( range < 1 || range > 3 ) return NULL; else /* arrays start with 1 in Pascal, and with 0 in C */ return &exec->codeRangeTable[range - 1]; }#endif/******************************************************************* * * Function : Set_CodeRange * * Description : Sets a code range. * * Input : exec target execution context * range code range index * base new code base * length range size in bytes * * Output : SUCCESS on success. FAILURE on error. * *****************************************************************/ LOCAL_FUNC TT_Error Set_CodeRange( PExecution_Context exec, Int range, void* base, ULong length ) { if ( range < 1 || range > 3 ) return TT_Err_Bad_Argument; exec->codeRangeTable[range - 1].Base = (Byte*)base; exec->codeRangeTable[range - 1].Size = length; return TT_Err_Ok; }/******************************************************************* * * Function : Clear_CodeRange * * Description : Clears a code range. * * Input : exec target execution context * range code range index * * Output : SUCCESS on success. FAILURE on error. * * Note : Does not set the Error variable. * *****************************************************************/ LOCAL_FUNC TT_Error Clear_CodeRange( PExecution_Context exec, Int range ) { if ( range < 1 || range > 3 ) return TT_Err_Bad_Argument; exec->codeRangeTable[range - 1].Base = NULL; exec->codeRangeTable[range - 1].Size = 0; return TT_Err_Ok; }/******************************************************************* * * * EXECUTION CONTEXT ROUTINES * * * *******************************************************************//******************************************************************* * * Function : Context_Destroy * *****************************************************************/ LOCAL_FUNC TT_Error Context_Destroy( void* _context ) { PExecution_Context exec = (PExecution_Context)_context; if ( !exec ) return TT_Err_Ok; /* free composite load stack */ FREE( exec->loadStack ); exec->loadSize = 0; /* points zone */ Done_Glyph_Zone( &exec->pts ); exec->maxPoints = 0; exec->maxContours = 0; /* free stack */ FREE( exec->stack ); exec->stackSize = 0; /* free call stack */ FREE( exec->callStack ); exec->callSize = 0; exec->callTop = 0; /* free glyph code range */ FREE( exec->glyphIns ); exec->glyphSize = 0; exec->instance = NULL; exec->face = NULL; return TT_Err_Ok; }/******************************************************************* * * Function : Context_Create * *****************************************************************/ LOCAL_FUNC TT_Error Context_Create( void* _context, void* _face ) { PExecution_Context exec = (PExecution_Context)_context; PFace face = (PFace)_face; TT_Error error; /* XXX : We don't reserve arrays anymore, this is done automatically */ /* during a "Context_Load".. */ exec->callSize = 32; if ( ALLOC_ARRAY( exec->callStack, exec->callSize, TCallRecord ) ) goto Fail_Memory; /* all values in the context are set to 0 already, but this is */ /* here as a remainder */ exec->maxPoints = 0; exec->maxContours = 0; exec->stackSize = 0; exec->loadSize = 0; exec->glyphSize = 0; exec->stack = NULL; exec->loadStack = NULL; exec->glyphIns = NULL; exec->face = face; exec->instance = NULL; return TT_Err_Ok; Fail_Memory: Context_Destroy( exec ); return error; }/******************************************************************* * * Function : Context_Load * *****************************************************************//****************************************************************//* *//* Update_Max : Reallocate a buffer if it needs to *//* *//* input: size address of buffer's current size *//* expressed in elements *//* *//* multiplier size in bytes of each element in the *//* buffer *//* *//* buff address of the buffer base pointer *//* *//* new_max new capacity (size) of the buffer */ static TT_Error Update_Max( ULong* size, ULong multiplier, void** buff, ULong new_max ) { TT_Error error; if ( *size < new_max ) { FREE( *buff ); if ( ALLOC( *buff, new_max * multiplier ) ) return error; *size = new_max; } return TT_Err_Ok; }/****************************************************************//* *//* Update_Zone: Reallocate a zone if it needs to *//* *//* input: zone address of the target zone *//* *//* maxPoints address of the zone's current capacity *//* in points *//* *//* maxContours address of the zone's current capacity *//* in contours *//* *//* newPoints new capacity in points *//* *//* newContours new capacity in contours *//* */ static TT_Error Update_Zone( PGlyph_Zone zone, UShort* maxPoints, UShort* maxContours, UShort newPoints, UShort newContours ) { if ( *maxPoints < newPoints || *maxContours < newContours ) { TT_Error error; Done_Glyph_Zone( zone ); error = New_Glyph_Zone( zone, newPoints, newContours ); if ( error ) return error; *maxPoints = newPoints;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -