📄 ftifi.c
字号:
return (PFontFile)(element->data); } /* the file may be asleep, look in the second list */ element = List_Find( &idleFiles, (long)hff ); if (element) { /* we need to awake the font, but before that, we must be sure */ /* that there is enough room in the live list */ if ( liveFiles.count >= max_open_files ) if (Sleep_FontFile( (PFontFile)(liveFiles.tail->data) )) ERRRET( NULL ); if ( Wake_FontFile( (PFontFile)(element->data) ) ) ERRRET( NULL ); COPY ( "hff " ); CATI( hff ); CAT( " awoken\n" ); WRITE; return (PFontFile)(element->data); } COPY( "Could not find hff " ); CATI( hff ); CAT( " in lists\n" ); WRITE;#ifdef DEBUG /* dump files lists */ COPY( "Live files : " ); CATI( liveFiles.count ); CAT( "\r\n" ); WRITE; for (element = liveFiles.head; element; element = element->next) { COPY( ((PFontFile)(element->data))->filename ); CAT("\r\n");WRITE; } COPY( "Idle files : " ); CATI( idleFiles.count ); CAT( "\r\n" ); WRITE; for (element = idleFiles.head; element; element = element->next) { COPY( ((PFontFile)(element->data))->filename ); CAT("\r\n");WRITE; }#endif /* could not find the HFF in the list */ return NULL;}/****************************************************************************//* *//* getFontSize : *//* *//* return pointer to a TFontSize given a HFC handle, NULL if error *//* */static PFontSize getFontSize( HFC hfc ){ int i; for ( i = 0; i < MAX_CONTEXTS; i++ ) if ( contexts[i].hfc == hfc ) { return &contexts[i]; } return NULL;}#ifdef USE_UCONV/* maximum number of cached UCONV objects */#define MAX_UCONV_CACHE 10/* UCONV object used for conversion from UGL to Unicode */#define UCONV_TYPE_UGL 1/* UCONV objects used for conversion from local DBCS codepage to Unicode */#define UCONV_TYPE_BIG5 2#define UCONV_TYPE_SJIS 4/* UCONV objects cache entry */typedef struct _UCACHEENTRY { UconvObject object; /* actual UCONV object */ PID pid; /* process ID the object is valid for */ ULONG type; /* type of UCONV object (UGL or DBCS) */} UCACHEENTRY, *PUCACHEENTRY;/* UCONV globals */static UCACHEENTRY UconvCache[MAX_UCONV_CACHE]; /* 10 should do it */static int slotsUsed = 0; /* number of cache slots used *//****************************************************************************//* *//* getUconvObject : *//* *//* a function to cache UCONV objects based on current process. The only *//* problem is that FT/2 currently doesn't keep track of processes and *//* consequently the objects aren't freed when a process ends. But UCONV *//* frees the objects itself anyway. */int getUconvObject(UniChar *name, UconvObject *ConvObj, ULONG UconvType) { PPIB ppib; /* process/thread info blocks */ PTIB ptib; PID curPid; /* current process ID */ int i; /* query current process ID */ if (DosGetInfoBlocks(&ptib, &ppib)) return -1; curPid = ppib->pib_ulpid; if (slotsUsed == 0) { /* initialize cache */ if (UniCreateUconvObject(name, ConvObj) != ULS_SUCCESS) return -1; UconvCache[0].object = *ConvObj; UconvCache[0].pid = curPid; UconvCache[0].type = UconvType; for (i = 1; i < MAX_UCONV_CACHE; i++) { UconvCache[i].object = NULL; UconvCache[i].pid = 0; } slotsUsed = 1; return 0; } /* search cache for available conversion object */ i = 0; while ((UconvCache[i].pid != curPid || UconvCache[i].type != UconvType) && i < slotsUsed) i++; if (i < slotsUsed) { /* entry found in cache */ *ConvObj = UconvCache[i].object; return 0; } /* if cache is full, remove first entry and shift the others 'down' */ if (slotsUsed == MAX_UCONV_CACHE) { UniFreeUconvObject(UconvCache[0].object); for (i = 1; i < MAX_UCONV_CACHE; i++) { UconvCache[i - 1].object = UconvCache[i].object; UconvCache[i - 1].pid = UconvCache[i].pid; UconvCache[i - 1].type = UconvCache[i].type; } } if (UniCreateUconvObject(name, ConvObj) != ULS_SUCCESS) return -1; if (slotsUsed < MAX_UCONV_CACHE) slotsUsed++; UconvCache[slotsUsed - 1].object = *ConvObj; UconvCache[slotsUsed - 1].pid = curPid; UconvCache[slotsUsed - 1].type = UconvType; return 0;}/****************************************************************************//* *//* CleanUCONVCache : *//* *//* When process is terminated, removes this process' entries in the UCONV *//* object cache. Errors are disregarded at this point. */void CleanUCONVCache(void) { PPIB ppib; /* process/thread info blocks */ PTIB ptib; PID curPid; /* current process ID */ int i = 0, j; /* query current process ID */ if (DosGetInfoBlocks(&ptib, &ppib)) return; curPid = ppib->pib_ulpid; while (i < slotsUsed) { /* if PID matches, remove the entry and shift the others 'down' (or up?) */ if (UconvCache[i].pid == curPid) { UniFreeUconvObject(UconvCache[i].object); for (j = i + 1; j < slotsUsed; j++) { UconvCache[j - 1].object = UconvCache[j].object; UconvCache[j - 1].pid = UconvCache[j].pid; UconvCache[j - 1].type = UconvCache[j].type; } slotsUsed--; } i++; }}#endif /* USE_UCONV *//****************************************************************************//* *//* PM2TT : *//* *//* a function to convert PM codepoint to TT glyph index. This is the real *//* tricky part. *//* mode = TRANSLATE_UGL - translate UGL to Unicode *//* mode = TRANSLATE_SYMBOL - no translation - symbol font *//* mode = TRANSLATE_UNICODE- no translation - Unicode */static int PM2TT( TT_CharMap charMap, ULONG mode, int index){#ifdef USE_UCONV /* Brand new version that uses UCONV.DLL. This should make FreeType/2 */ /* smaller and at the same time more flexible as it now should use */ /* the Unicode translation tables supplied with base OS/2 Warp 4. */ /* Unfortunately there's a complication (again) since UCONV objects */ /* created in one process can't be used in another. Therefore we */ /* keep a small cache of recently used UCONV objects. */ static UconvObject UGLObj = NULL; /* UGL->Unicode conversion object */ static BOOL UconvSet = FALSE; char char_data[2], *pin_char_str; size_t in_bytes_left, uni_chars_left, num_subs; UniChar *pout_uni_str, uni_buffer[4]; int rc; static UniChar uglName[10] = L"OS2UGL"; static UniChar uglNameBig5[10] = L"IBM-950"; static UniChar uglNameSJIS[10] = L"IBM-943"; switch (mode) { case TRANSLATE_UGL: if (UconvSet == FALSE) { switch (iLangId) { /* select proper conversion table */ case TT_MS_LANGID_GREEK_GREECE: strncpy((char*)uglName, (char*)L"OS2UGLG", 16); break; case TT_MS_LANGID_HEBREW_ISRAEL: strncpy((char*)uglName, (char*)L"OS2UGLH", 16); break; case TT_MS_LANGID_ARABIC_SAUDI_ARABIA: strncpy((char*)uglName, (char*)L"OS2UGLA", 16); break; } UconvSet = TRUE; } /* get Uconv object - either new or cached */ if (getUconvObject(uglName, &UGLObj, UCONV_TYPE_UGL) != 0) return 0; if (index > MAX_GLYPH) return 0; char_data[0] = index; char_data[1] = index >> 8; pout_uni_str = uni_buffer; pin_char_str = char_data; in_bytes_left = 2; uni_chars_left = 1; rc = UniUconvToUcs(UGLObj, (void**)&pin_char_str, &in_bytes_left, &pout_uni_str, &uni_chars_left, &num_subs); if (rc != ULS_SUCCESS) return 0; else return TT_Char_Index(charMap, ((unsigned short*)uni_buffer)[0]); case TRANSLATE_SYMBOL: case TRANSLATE_UNICODE: case TRANSLATE_BIG5: case TRANSLATE_SJIS: return TT_Char_Index(charMap, index); case TRANSLATE_UNI_BIG5: case TRANSLATE_UNI_SJIS: /* get Uconv object - either new or cached */ switch (mode) { /* get proper conversion object */ case TRANSLATE_UNI_BIG5: if (getUconvObject(uglNameBig5, &UGLObj, UCONV_TYPE_BIG5) != 0) return 0; break; case TRANSLATE_UNI_SJIS: if (getUconvObject(uglNameSJIS, &UGLObj, UCONV_TYPE_SJIS) != 0) return 0; break; } /* Note the bytes are swapped here for double byte chars! */ if (index & 0xFF00) { char_data[0] = (index & 0xFF00) >> 8; char_data[1] = index & 0x00FF; } else { char_data[0] = index; char_data[1] = 0; } pout_uni_str = uni_buffer; pin_char_str = char_data; in_bytes_left = 2; uni_chars_left = 2; rc = UniUconvToUcs(UGLObj, (void**)&pin_char_str, &in_bytes_left, &pout_uni_str, &uni_chars_left, &num_subs); if (rc != ULS_SUCCESS) return 0; else return TT_Char_Index(charMap, ((unsigned short*)uni_buffer)[0]); default: return 0; }#else switch (mode) { /* convert from PM383 to Unicode */ case TRANSLATE_UGL: /* TODO: Hebrew and Arabic UGL */ if (iLangId == TT_MS_LANGID_GREEK_GREECE) /* use Greek UGL */ if ((index >= GREEK_START) && (index < GREEK_START + GREEK_GLYPHS)) return TT_Char_Index(charMap, SubUGLGreek[index - GREEK_START]); if (index <= MAX_GLYPH) return TT_Char_Index(charMap, UGL2Uni[index]); else ERRRET(0); case TRANSLATE_SYMBOL : case TRANSLATE_UNICODE: case TRANSLATE_BIG5: case TRANSLATE_SJIS: return TT_Char_Index(charMap, index); default: return 0; }#endif}/****************************************************************************//* *//* mystricmp : *//* */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -