使用
CreateFont
函数可以指定字体名称和其他属性。但是,如果我有一个 font.ttf
文件,并且希望 Windows 加载该特定字体,我该如何指定使用该文件?诚然,这种方法相对来说比较间接,但在运行于Windows 7+的环境下,你可以利用GDI与DWrite进行交互。
#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只是一个失败宏,当HRESULT失败时返回,并且ComPtr是一个辅助智能指针类(可用自己的替代,或者ATL CComPtr、WinRT ComPtr、VS2013 _com_ptr_t等)。
我非常确定你是做不到的。所有字体请求都通过字体映射器进行,并且它会选择最接近满足所给定规格的字体文件。虽然我不确定它是否在现实中这样做,但至少从理论上讲,它可以使用来自两个完全不同的字体文件的数据来创建一个逻辑字体。
ttf
文件以获取其所有属性,以便我可以安装它,然后将这些属性传递给 Windows,以获取特定的字体? - ClaudiuAddFontResourceEx("data/fonts/quantico.ttf", FR_PRIVATE)
似乎可以使嵌入式Webkit识别font-family:Quantico,即使该字体在我的游戏引擎中实际上并不可用。 - Петър ПетровEnumFonts()
来保存结果。然后使用AddFontResourceEx()
添加您自己的私有字体,并再次使用EnumFonts()
,区别在于您添加的内容。请注意,TTF和位图字体枚举方式不同,但对于此测试,这并不重要。CreateFontIndirect()
的字体名称硬编码为匹配即可。如果您不关心安装字体,可以使用AddFontResource
进行安装,然后您可以通过查看HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts
中的映射来获取物理.TTF和逻辑/系列名称之间的关系。
我在评论中提到了PrivateFontCollection,因为我认为您想暂时这样做;您可以使用PrivateFontCollection::AddFontFile
将TTF加载到PFC中,从集合中获取新的FontFamily
对象并检查GetFamilyName
。(我已经使用过此项的.net实现,但没有使用原始API)
foo.ttf
- 它并没有说明它的逻辑名称。 - Claudiu