读书人

怎么从字体文件名得到字体在系统中的名

发布时间: 2013-01-12 16:25:03 作者: rapoo

如何从字体文件名得到字体在系统中的名称
C:\Windows\Fonts里面的字体文件很多,比如simsun.ttc这个文件实际上是“宋体”的字库,我在程序里面把宋体赋值给cfont或者LOGFONT就可以了,比如这样


m_strFont.Format("宋体");
LOGFONT lf;
pElement->GetLogFont(&lf);
_tcscpy(lf.lfFaceName, m_strFont);
pElement->SetFont(&lf);

但是我现在想在程序里面维护一个表,扫描C:\Windows\Fonts里面的所有的文件,所有的ttc或者ttf文件,然后把它们当做我程序里面可以使用的字体提供给用户------因为我需要ttf文件来保存字体库,所以必须知道ttc/ttf文件名跟系统字体的对应关系,请问我如何才能知道?
比如,随便一个字体文件,plantc.ttf我该如何设置CFONT或者LOGFONT才能使用这个字体?就像simsun.ttc给老外的话,老外根本不知道是宋体,该怎么用呢?
[解决办法]
这个问题我刚刚解决过。

上代码,分数拿来

typedef struct _tagTT_OFFSET_TABLE{
USHORTuMajorVersion;
USHORTuMinorVersion;
USHORTuNumOfTables;
USHORTuSearchRange;
USHORTuEntrySelector;
USHORTuRangeShift;
}TT_OFFSET_TABLE;

typedef struct _tagTT_TABLE_DIRECTORY{
charszTag[4];//table name
ULONGuCheckSum;//Check sum
ULONGuOffset;//Offset from beginning of file
ULONGuLength;//length of the table in bytes
}TT_TABLE_DIRECTORY;

typedef struct _tagTT_NAME_TABLE_HEADER{
USHORTuFSelector;//format selector. Always 0
USHORTuNRCount;//Name Records count
USHORTuStorageOffset;//Offset for strings storage, from start of the table
}TT_NAME_TABLE_HEADER;

typedef struct _tagTT_NAME_RECORD{
USHORTuPlatformID;
USHORTuEncodingID;
USHORTuLanguageID;
USHORTuNameID;
USHORTuStringLength;
USHORTuStringOffset;//from start of storage area
}TT_NAME_RECORD;

#define SWAPWORD(x)MAKEWORD(HIBYTE(x), LOBYTE(x))
#define SWAPLONG(x)MAKELONG(SWAPWORD(HIWORD(x)), SWAPWORD(LOWORD(x)))


CString GetFontNameFromFile(LPCTSTR lpszFilePath)
{
CFile f;
CString csRetVal;

if(f.Open(lpszFilePath, CFile::modeRead
[解决办法]
CFile::shareDenyWrite)){
TT_OFFSET_TABLE ttOffsetTable;
f.Read(&ttOffsetTable, sizeof(TT_OFFSET_TABLE));
ttOffsetTable.uNumOfTables = SWAPWORD(ttOffsetTable.uNumOfTables);
ttOffsetTable.uMajorVersion = SWAPWORD(ttOffsetTable.uMajorVersion);
ttOffsetTable.uMinorVersion = SWAPWORD(ttOffsetTable.uMinorVersion);

//check is this is a true type font and the version is 1.0
if(ttOffsetTable.uMajorVersion != 1
[解决办法]
ttOffsetTable.uMinorVersion != 0)
return csRetVal;

TT_TABLE_DIRECTORY tblDir;
BOOL bFound = FALSE;
CString csTemp;

for(int i=0; i< ttOffsetTable.uNumOfTables; i++){
f.Read(&tblDir, sizeof(TT_TABLE_DIRECTORY));
strncpy(csTemp.GetBuffer(5), tblDir.szTag, 4);
csTemp.ReleaseBuffer(4);
if(csTemp.CompareNoCase(_T("name")) == 0){
bFound = TRUE;
tblDir.uLength = SWAPLONG(tblDir.uLength);
tblDir.uOffset = SWAPLONG(tblDir.uOffset);
break;
}
}

if(bFound){
f.Seek(tblDir.uOffset, CFile::begin);


TT_NAME_TABLE_HEADER ttNTHeader;
f.Read(&ttNTHeader, sizeof(TT_NAME_TABLE_HEADER));
ttNTHeader.uNRCount = SWAPWORD(ttNTHeader.uNRCount);
ttNTHeader.uStorageOffset = SWAPWORD(ttNTHeader.uStorageOffset);
TT_NAME_RECORD ttRecord;
bFound = FALSE;

for(int i=0; i<ttNTHeader.uNRCount; i++){
f.Read(&ttRecord, sizeof(TT_NAME_RECORD));
ttRecord.uNameID = SWAPWORD(ttRecord.uNameID);
if(ttRecord.uNameID == 1){
ttRecord.uStringLength = SWAPWORD(ttRecord.uStringLength);
ttRecord.uStringOffset = SWAPWORD(ttRecord.uStringOffset);
int nPos = f.GetPosition();
f.Seek(tblDir.uOffset + ttRecord.uStringOffset + ttNTHeader.uStorageOffset, CFile::begin);

//bug fix: see the post by SimonSays to read more about it
TCHAR lpszNameBuf = csTemp.GetBuffer(ttRecord.uStringLength + 1);
ZeroMemory(lpszNameBuf, ttRecord.uStringLength + 1);
f.Read(lpszNameBuf, ttRecord.uStringLength);
csTemp.ReleaseBuffer();
if(csTemp.GetLength() > 0){
csRetVal = csTemp;
break;
}
f.Seek(nPos, CFile::begin);
}
}
}
f.Close();
}
return csRetVal;
}

读书人网 >VC/MFC

热点推荐