使用CreateFont
可以指定字体名称和一堆其他属性。但是,如果我有一个font.ttf
文件,我想要通过Windows加载该特定字体怎么办?如何指定要使用的特定文件?
答案 0 :(得分:3)
我很确定你做不到。所有字体请求都通过字体映射器,它会选择最接近您提供的规范的字体文件。虽然我不确定它在现实中是否存在,但它至少在理论上可以使用(例如)来自两个完全独立的字体文件的数据来创建一个逻辑字体。
答案 1 :(得分:3)
这无疑是间接的,但是你可以在Windows 7 +上运行时使用带有DWrite的GDI互操作。
#include <Windows.h>
#include <WindowsX.h>
#include <DWrite.h>
...
// Make the font file visible to GDI.
AddFontResourceEx(fontFileName, FR_PRIVATE, 0);
if (SUCCEEDED(GetLogFontFromFileName(fontFileName, &logFont)))
{
logFont.lfHeight = -long(desiredPpem);
HFONT hf = CreateFontIndirect(&logFont);
HFONT oldFont = SelectFont(hdc, hf);
...
// Do stuff...
...
SelectFont(hdc, oldFont);
}
RemoveFontResource(fontFileName);
....
HRESULT GetLogFontFromFileName(_In_z_ wchar const* fontFileName, _Out_ LOGFONT* logFont)
{
// DWrite objects
ComPtr<IDWriteFactory> dwriteFactory;
ComPtr<IDWriteFontFace> fontFace;
ComPtr<IDWriteFontFile> fontFile;
ComPtr<IDWriteGdiInterop> gdiInterop;
// Set up our DWrite factory and interop interface.
IFR(DWriteCreateFactory(
DWRITE_FACTORY_TYPE_SHARED,
__uuidof(IDWriteFactory),
reinterpret_cast<IUnknown**>(&dwriteFactory)
);
IFR(g_dwriteFactory->GetGdiInterop(&gdiInterop));
// Open the file and determine the font type.
IFR(g_dwriteFactory->CreateFontFileReference(fontFileName, nullptr, &fontFile));
BOOL isSupportedFontType = false;
DWRITE_FONT_FILE_TYPE fontFileType;
DWRITE_FONT_FACE_TYPE fontFaceType;
UINT32 numberOfFaces = 0;
IFR(fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces));
if (!isSupportedFontType)
return DWRITE_E_FILEFORMAT;
// Set up a font face from the array of font files (just one)
ComPtr<IDWriteFontFile> fontFileArray[] = {fontFile};
IFR(g_dwriteFactory->CreateFontFace(
fontFaceType,
ARRAYSIZE(fontFileArray), // file count
&fontFileArray[0], // or GetAddressOf if WRL ComPtr
0, // faceIndex
DWRITE_FONT_SIMULATIONS_NONE,
&fontFace
);
// Get the necessary logical font information.
IFR(gdiInterop->ConvertFontFaceToLOGFONT(fontFace, OUT logFont));
return S_OK;
}
其中IFR只是在FAILED HRESULT上返回的失败宏,而ComPtr是辅助智能指针类(替换为您自己的,或ATL CComPtr,WinRT ComPtr,VS2013 _com_ptr_t ......)。
答案 2 :(得分:2)
一种可能性是EnumFonts()
,保存结果。然后再次添加AddFontResourceEx()
和EnumFonts()
的私有字体,区别在于您添加的内容。请注意,TTF和位图字体的枚举方式不同,但对于此测试,这应该无关紧要。
如果您使用的是位图字体,则可以轻松解析它们(.FNT和.FON)。 TTF您可能需要构建(或借用另一个评论者建议的FreeType)解析器来从TTF文件中提取“名称”表。
对于您正在控制或提供应用的字体,这似乎很多工作。
我们使用AddFontResourceEx()添加私有字体,但由于我们控制了我们添加的字体,我们只需将传递给CreateFontIndirect()
的字体名称硬编码即可。
答案 3 :(得分:1)
如果您不关心安装字体,可以使用AddFontResource
进行安装,那么您可以通过查看HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
中的映射来获取物理.TTF与其逻辑/系列名称之间的关系。
我在评论中提到了PrivateFontCollection 因为我以为你想暂时这样做;您可以使用PrivateFontCollection::AddFontFile
将TTF加载到PFC中,从集合中获取新的FontFamily
对象。考试GetFamilyName
。 (我已经完成了类似的.net实现,但不是原始API)