📄 ftifi.c
字号:
};/* Flag : The font face has a fixed pitch width */#define FC_FLAG_FIXED_WIDTH 1/* Flag : Effectively duplicated FL_FLAG_DBCS_FILE. This info is *//* kept twice for simplified access */#define FC_FLAG_DBCS_FACE 2/* Flag : This face is an alias */#define FL_FLAG_FAKE_ROMAN 8/* Flag : The font file has a live FreeType face object */#define FL_FLAG_LIVE_FACE 16/* Flag : A font file's face has a context open - DON'T CLOSE IT! */#define FL_FLAG_CONTEXT_OPEN 32/* Flag : This file has been already opened previously*/#define FL_FLAG_ALREADY_USED 64/* Flag : This is a font including DBCS characters; this also means *//* the font driver presents to the system a second, vertically *//* rendered, version of this typeface with name prepended by *//* an '@' (used in horizontal-only word processors) *//* Note : For TTCs, the whole collection is either DBCS or not. I've *//* no idea if there are any TTCs with both DBCS and non-DBCS *//* faces. It's possible, but sounds unlikely. */#define FL_FLAG_DBCS_FILE 128/* Note, we'll only keep the first max_open_files files with opened *//* FreeType objects/instances.. */int max_open_files = 10;/* number of processes using the font driver; used by the init/term *//* routine */ULONG ulProcessCount = 0;/* the list of live faces */static TList liveFiles = { NULL, NULL, 0 };/* the list of sleeping faces */static TList idleFiles = { NULL, NULL, 0 };/****************************************************************************//* *//* TFontSize : *//* *//* a structure related to a opened font context (a.k.a. instance or *//* transform/pointsize). It exactly corresponds to a HFC. *//* */typedef struct _TFontSize TFontSize, *PFontSize;struct _TFontSize{ PListElement element; /* List element for this font size */ HFC hfc; /* HFC handle used from outside */ TT_Instance instance; /* handle to FreeType instance */ BOOL transformed; /* TRUE = rotation/shearing used (rare) */ BOOL vertical; /* TRUE = vertically rendered DBCS face */ TT_Matrix matrix; /* transformation matrix */ PFontFile file; /* HFF this context belongs to */ ULONG faceIndex; /* index of face in a font (for TTCs) *//* TList outlines;*/ /* outlines cache list */};/****************************************************************************//* array of font context handles. Note that there isn't more than one font *//* context open at any time anyway, but we want to be safe.. *//* */#define MAX_CONTEXTS 5static TFontSize contexts[MAX_CONTEXTS]; /* this is rather too much *//****************************************************************************//* few globals used for NLS *//* *//* Note: most of the internationalization (I18N) code was kindly provided *//* by Ken Borgendale and Marc L Cohen from IBM (big thanks!). I also *//* received help from Tetsuro Nishimura from IBM Japan. *//* I was also unable to test the I18N code on actual Japanese, Chinese... *//* etc. systems. But it might work. *//* */static ULONG ScriptTag = -1;static ULONG LangSysTag = -1;static ULONG iLangId = TT_MS_LANGID_ENGLISH_UNITED_STATES; /* language ID */static ULONG uLastGlyph = 255; /* last glyph for language */static PSZ pGlyphlistName = "SYMBOL"; /* PM383, PMJPN, PMKOR.... */static BOOL isGBK = TRUE; /* only used for Chinese */static ULONG ulCp[2] = {1}; /* codepages used */static UCHAR DBCSLead[12]; /* DBCS lead byte table *//* rather simple-minded test to decide if given glyph index is a 'halfchar',*//* i.e. Latin character in a DBCS font which is _not_ to be rotated */#define is_HALFCHAR(_x) ((_x) < 0x0400)/****************************************************************************//* *//* interfaceSEId: *//* *//* interfaceSEId (Interface-specific Encoding Id) determines what encoding *//* the font driver should use if a font includes a Unicode encoding. *//* */LONG interfaceSEId(TT_Face face, BOOL UDCflag, LONG encoding);/****************************************************************************//* *//* LookUpName : *//* *//* this function tries to find M$ English name for a face *//* length is limited to FACESIZE (defined by OS/2); returns NULL if *//* unsuccessful. warning: the string gets overwritten on the next *//* invocation *//* *//* TODO: needs enhancing for I18N */static char* LookupName(TT_Face face, int index );/****************************************************************************//* *//* GetCharMap : *//* *//* get suitable charmap from font *//* */static ULONG GetCharmap(TT_Face face);/****************************************************************************//* *//* GetOutlineLen : *//* *//* get # of bytes needed for glyph outline *//* */static int GetOutlineLen(TT_Outline *ol);/****************************************************************************//* *//* GetOutline : *//* *//* get glyph outline in PM format *//* */static int GetOutline(TT_Outline *ol, PBYTE pb);/****************************************************************************//* *//* IsDBCSChar : *//* *//* Returns TRUE if character is first byte of a DBCS char, FALSE otherwise *//* */BOOL IsDBCSChar(UCHAR c){ ULONG i; for (i = 0; DBCSLead[i] && DBCSLead[i+1]; i += 2) if ((c >= DBCSLead[i]) && (c <= DBCSLead[i+1])) return TRUE; return FALSE;}/****************************************************************************//* *//* TT_Alloc & TT_Free : *//* *//* The following two functions are declared here because including *//* the entire ttmemory.h creates more problems than it solves *//* */TT_Error TT_Alloc( long Size, void** P );TT_Error TT_Free( void** P );TT_Error TTMemory_Init(void);static TT_Error error;#define ALLOC( p, size ) TT_Alloc( (size), (void**)&(p) )#define FREE( p ) TT_Free( (void**)&(p) )/****************************************************************************//* *//* New_Element : *//* *//* return a fresh list element. Either new or recycled. *//* returns NULL if out of memory. *//* */static PListElement New_Element( void ){ PListElement e = free_elements; if (e) free_elements = e->next; else { if ( ALLOC( e, sizeof(TListElement) ) ) return NULL; } e->next = e->prev = e->data = NULL; e->key = 0; return e;}/****************************************************************************//* *//* Done_Element : *//* *//* recycles an old list element *//* */static void Done_Element( PListElement element ){ element->next = free_elements; free_elements = element;}/****************************************************************************//* *//* List_Insert : *//* *//* inserts a new object at the head of a given list *//* returns 0 in case of success, -1 otherwise. *//* */static int List_Insert( PList list, PListElement element ){ if (!list || !element) return -1; element->next = list->head; if (list->head) list->head->prev = element; element->prev = NULL; list->head = element; if (!list->tail) list->tail = element; list->count++; return 0;}/****************************************************************************//* *//* List_Remove : *//* *//* removes an element from its list. Returns 0 in case of success, *//* -1 otherwise. WARNING : this function doesn't check that the *//* element is part of the list. *//* */static int List_Remove( PList list, PListElement element ){ if (!element) return -1; if (element->prev) element->prev->next = element->next; else list->head = element->next; if (element->next) element->next->prev = element->prev; else list->tail = element->prev; element->next = element->prev = NULL; list->count --; return 0;}/****************************************************************************//* *//* List_Find : *//* *//* Look for a given object with a specified key. Returns NULL if the *//* list is empty, or the object wasn't found. *//* */static PListElement List_Find( PList list, long key ){ static PListElement cur; for ( cur=list->head; cur; cur = cur->next ) if ( cur->key == key ) return cur; /* not found */ return NULL;}/****************************************************************************//* *//* Sleep_FontFile : *//* *//* closes a font file's FreeType objects to leave room in memory. *//* */static int Sleep_FontFile( PFontFile cur_file ){ int i; if (!(cur_file->flags & FL_FLAG_LIVE_FACE)) ERRRET(-1); /* already asleep */ /* is this face in use? */ if (cur_file->flags & FL_FLAG_CONTEXT_OPEN) { /* move face to top of the list */ if (List_Remove( &liveFiles, cur_file->element )) ERRRET(-1); if (List_Insert( &liveFiles, cur_file->element )) ERRRET(-1); cur_file = (PFontFile)(liveFiles.tail->data); } /* remove the face from the live list */ if (List_Remove( &liveFiles, cur_file->element )) ERRRET(-1); /* add it to the sleep list */ if (List_Insert( &idleFiles, cur_file->element )) ERRRET(-1); /* deactivate its objects - we ignore errors there */ for (i = 0; i < cur_file->numFaces; i++) { TT_Done_Glyph( cur_file->faces[i].glyph ); TT_Close_Face( cur_file->faces[i].face ); } cur_file->flags &= ~FL_FLAG_LIVE_FACE; return 0;}/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -