ftifi.c
来自「字体缩放显示」· C语言 代码 · 共 1,682 行 · 第 1/5 页
C
1,682 行
/* A simple function for comparing strings without case sensitivity. Just *//* returns zero if strings match, one otherwise. I wrote this because *//* stricmp is not available in the subsystem run-time library (probably *//* because it uses locales). toupper() is unfortunately unavailable too. *//* */#define toupper( c ) ( ((c) >= 'a') && ((c) <= 'z') ? (c) - 'a' + 'A' : (c) )staticint mystricmp(const char *s1, const char *s2) { int i = 0; int match = 0; int len = strlen(s1); if (len != strlen(s2)) return 1; /* no match */ while (i < len) { if (toupper(s1[i]) != toupper(s2[i])) { match = 1; break; } i++; } return match;}/* DBCS enabled strrchr (only looks for SBCS chars though) */staticchar *mystrrchr(char *s, char c) { int i = 0; int lastfound = -1; int len = strlen(s); while (i <= len) { if (IsDBCSChar(s[i])) { i += 2; continue; } if (s[i] == c) lastfound = i; i++; } if (lastfound == -1) return NULL; else return s + lastfound;}/* -------------------------------------------------------------------------*//* here begin the exported functions *//* -------------------------------------------------------------------------*//****************************************************************************//* *//* ConvertFontFile : *//* *//* Install/delete font file *//* */LONG _System ConvertFontFile( PSZ source, PSZ dest_dir, PSZ new_name ){ PSZ source_name; COPY("ConvertFontFile: Src = "); CAT(source); if (dest_dir) { CAT(", DestDir = "); CAT(dest_dir); } CAT("\r\n"); WRITE; if (dest_dir && new_name) { /* install the font file */ source_name = mystrrchr( source, '\\' ); /* find the last backslash */ if (!source_name) ERRRET(-1); source_name++; strcpy( new_name, source_name ); /* check if file is to be copied onto itself */ if (strncmp(source, dest_dir, strlen(dest_dir)) == 0) return OK; /* do nothing */ if ( DosCopy( source, dest_dir, DCPY_EXISTING) ) /* overwrite file */ ERRRET(-1); /* XXX : we should probably set the error condition */ COPY(" -> Name: "); CAT(new_name); CAT("\r\n"); WRITE; } else { COPY("Delete file "); CAT(source); CAT("\r\n"); WRITE; DosDelete(source); /* fail quietly */ } return OK;}/****************************************************************************//* *//* LoadFontFile : *//* *//* open a font file and return a handle for it *//* */HFF _System LoadFontFile( PSZ file_name ){ PSZ extension; PFontFile cur_file; PListElement element; COPY( "LoadFontFile " ); CAT( file_name ); CAT( "\r\n" ); WRITE; /* first check if the file extension is supported */ extension = mystrrchr( file_name, '.' ); /* find the last dot */ if ( extension == NULL || (mystricmp(extension, ".TTF") && mystricmp(extension, ".TTC")) ) return ((HFF)-1); /* now actually open the file */ cur_file = New_FontFile( file_name ); if (cur_file) return cur_file->hff; else return (HFF)-1;}/****************************************************************************//* *//* UnloadFontFile : *//* *//* destroy resources associated with a given HFF *//* */LONG _System UnloadFontFile( HFF hff ){ PListElement element; COPY("UnloadFontFile: hff = "); CATI((int) hff); CAT("\r\n"); WRITE; /* look in the live list first */ for (element = liveFiles.head; element; element = element->next) { if (element->key == (long)hff) { PFontFile file = (PFontFile)element->data; if (--file->ref_count > 0) /* don't really close, return OK */ return 0; List_Remove( &liveFiles, element ); Done_Element( element ); Done_FontFile( &file ); return 0; } } /* now look in sleep list */ for (element = idleFiles.head; element; element = element->next) { if (element->key == (long)hff) { PFontFile file = (PFontFile)element->data; if (--file->ref_count > 0) /* don't really close, return OK */ return 0; List_Remove( &idleFiles, element ); Done_Element( element ); Done_FontFile( &file ); return 0; } } /* didn't find the file */ return -1;}/****************************************************************************//* *//* QueryFaces : *//* *//* Return font metrics. This routine has to do a lot of not very *//* hard work. *//* */LONG _System QueryFaces( HFF hff, PIFIMETRICS pifiMetrics, ULONG cMetricLen, ULONG cFontCount, ULONG cStart){ static TT_Face_Properties properties; static IFIMETRICS ifi; /* temporary structure */ PFontFace pface; TT_Header *phead; TT_Horizontal_Header *phhea; TT_OS2 *pOS2; TT_Postscript *ppost; PIFIMETRICS pifi2; PFontFile file; LONG index, faceIndex, ifiCount = 0; char *name; COPY( "QueryFaces: hff = " ); CATI( hff ); CAT( ", cFontCount = " ); CATI( cFontCount ); CAT( ", cStart = " ); CATI( cStart ); CAT( ", cMetricLen = " ); CATI( cMetricLen ); CAT( "\r\n"); WRITE; file = getFontFile(hff); if (!file) ERRRET(-1) /* error, invalid handle */ if (cMetricLen == 0) { /* only number of faces is requested */ #ifdef FAKE_TNR /* create an alias for Times New Roman */ pface = &(file->faces[0]); name = LookupName(pface->face, TT_NAME_ID_FONT_FAMILY); if (!strcmp(name, "Times New Roman")) { file->flags |= FL_FLAG_FAKE_ROMAN; return 2; } #endif if (file->flags & FL_FLAG_DBCS_FILE) return file->numFaces * 2; else return file->numFaces; } for (faceIndex = 0; faceIndex < file->numFaces; faceIndex++) { /* get pointer to this face's data */ pface = &(file->faces[faceIndex]); TT_Get_Face_Properties( pface->face, &properties ); pOS2 = properties.os2; phead = properties.header; phhea = properties.horizontal; ppost = properties.postscript; /* get font name and check it's really found */ name = LookupName(pface->face, TT_NAME_ID_FONT_FAMILY); if (name == NULL) ERET1(Fail); strncpy(ifi.szFamilyname, name, FACESIZE); ifi.szFamilyname[FACESIZE - 1] = '\0'; name = LookupName(pface->face, TT_NAME_ID_FULL_NAME); if (name == NULL) { ERET1(Fail); } strncpy(ifi.szFacename, name, FACESIZE); ifi.szFacename[FACESIZE - 1] = '\0'; /* If Unicode cmap exists in font and it contains more than 1024 glyphs, */ /* then do not translate from UGL to Unicode and use straight Unicode. */ /* But first check if it's a DBCS font and handle it properly */ if ((pface->charMode == TRANSLATE_UGL) && (properties.num_Glyphs > 1024)) { LONG specEnc; BOOL UDCflag = FALSE; /* !!!!TODO: UDC support */ specEnc = interfaceSEId(pface->face, UDCflag, PSEID_UNICODE); switch (specEnc) { case PSEID_SHIFTJIS: strcpy( ifi.szGlyphlistName, "PMJPN" ); pface->charMode = TRANSLATE_UNI_SJIS; break; case PSEID_BIG5: strcpy( ifi.szGlyphlistName, "PMCHT" ); pface->charMode = TRANSLATE_UNI_BIG5; break; default: /* do use straight Unicode */ strcpy( ifi.szGlyphlistName, "UNICODE" ); pface->charMode = TRANSLATE_UNICODE; /* straight Unicode */ }#if 0 strcpy( ifi.szGlyphlistName, "PMJPN" ); pface->charMode = TRANSLATE_UNI_SJIS;#endif } else if (pface->charMode == TRANSLATE_SYMBOL) /* symbol encoding */ strcpy(ifi.szGlyphlistName, "SYMBOL"); else if (pface->charMode == TRANSLATE_BIG5) /* Big5 encoding */ strcpy(ifi.szGlyphlistName, "PMCHT"); else if (pface->charMode == TRANSLATE_SJIS) strcpy(ifi.szGlyphlistName, "PMJPN"); /* ShiftJIS encoding */ else strcpy(ifi.szGlyphlistName, "PM383"); ifi.idRegistry = 0; ifi.lCapEmHeight = phead->Units_Per_EM; /* ??? probably correct */ ifi.lXHeight = phead->yMax /2; /* IBM TRUETYPE.DLL does */ ifi.lMaxAscender = pOS2->usWinAscent; if ((LONG)pOS2->usWinDescent >= 0) ifi.lMaxDescender = pOS2->usWinDescent; else ifi.lMaxDescender = -pOS2->usWinDescent; ifi.lLowerCaseAscent = phhea->Ascender; ifi.lLowerCaseDescent = -phhea->Descender; ifi.lInternalLeading = ifi.lMaxAscender + ifi.lMaxDescender - ifi.lCapEmHeight; ifi.lExternalLeading = 0; ifi.lAveCharWidth = pOS2->xAvgCharWidth; ifi.lMaxCharInc = phhea->advance_Width_Max; ifi.lEmInc = phead->Units_Per_EM; ifi.lMaxBaselineExt = ifi.lMaxAscender + ifi.lMaxDescender; ifi.fxCharSlope = -ppost->italicAngle; /* is this correct ? */ ifi.fxInlineDir = 0; ifi.fxCharRot = 0; ifi.usWeightClass = pOS2->usWeightClass; /* hopefully OK */ ifi.usWidthClass = pOS2->usWidthClass; ifi.lEmSquareSizeX = phead->Units_Per_EM; ifi.lEmSquareSizeY = phead->Units_Per_EM; /* probably correct */ ifi.giFirstChar = 0; /* following values should work */ ifi.giLastChar = 503; /* either 383 or 503 */ ifi.giDefaultChar = 0; ifi.giBreakChar = 32; ifi.usNominalPointSize = 120; /* these are simply constants */ ifi.usMinimumPointSize = 10; ifi.usMaximumPointSize = 10000; /* limit to 1000 pt (like the ATM fonts) */ ifi.fsType = pOS2->fsType & IFIMETRICS_LICENSED; /* ??? */ ifi.fsDefn =
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?