如何从字体文件名得到字体在系统中的名称

comana 2012-12-15 08:30:18
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给老外的话,老外根本不知道是宋体,该怎么用呢?
...全文
1146 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
warrior20146 2014-04-15
  • 打赏
  • 举报
回复
从注册表中查找
侧耳-倾听 2013-07-14
  • 打赏
  • 举报
回复
怎么才能取到中文名啊 如“幼圆”而不是“YOU YUAN”。
comana 2012-12-16
  • 打赏
  • 举报
回复
引用 1 楼 tiger9991 的回复:
这个问题我刚刚解决过。 上代码,分数拿来 C/C++ code?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980……
麻烦再问个问题,你这个代码好像对于中文字体无效,比如simsun.ttc,这里这句就返回了,有什么办法吗?

if(ttOffsetTable.uMajorVersion != 1 || ttOffsetTable.uMinorVersion != 0)
            return csRetVal;
comana 2012-12-15
  • 打赏
  • 举报
回复
引用 1 楼 tiger9991 的回复:
这个问题我刚刚解决过。 上代码,分数拿来 C/C++ code?1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980……
太厉害了,多谢!
hurryboylqs 2012-12-15
  • 打赏
  • 举报
回复
EnumFontFamilies不是可以得到系统已经安装的所有字体吗
傻X 2012-12-15
  • 打赏
  • 举报
回复
这个问题我刚刚解决过。 上代码,分数拿来

typedef struct _tagTT_OFFSET_TABLE{
	USHORT	uMajorVersion;
	USHORT	uMinorVersion;
	USHORT	uNumOfTables;
	USHORT	uSearchRange;
	USHORT	uEntrySelector;
	USHORT	uRangeShift;
}TT_OFFSET_TABLE;

typedef struct _tagTT_TABLE_DIRECTORY{
	char	szTag[4];			//table name
	ULONG	uCheckSum;			//Check sum
	ULONG	uOffset;			//Offset from beginning of file
	ULONG	uLength;			//length of the table in bytes
}TT_TABLE_DIRECTORY;

typedef struct _tagTT_NAME_TABLE_HEADER{
	USHORT	uFSelector;			//format selector. Always 0
	USHORT	uNRCount;			//Name Records count
	USHORT	uStorageOffset;		//Offset for strings storage, from start of the table
}TT_NAME_TABLE_HEADER;

typedef struct _tagTT_NAME_RECORD{
	USHORT	uPlatformID;
	USHORT	uEncodingID;
	USHORT	uLanguageID;
	USHORT	uNameID;
	USHORT	uStringLength;
	USHORT	uStringOffset;	//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;
}

16,470

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧