是的,可以这样做。这是来自 chrome 项目的稍微修改的代码片段,
// Callback to |EnumEnhMetaFile()| to intercept font creation.
int CALLBACK MetaFileEnumProc(HDC hdc,
HANDLETABLE* table,
CONST ENHMETARECORD* record,
int table_entries,
LPARAM log_font)
{
if (record->iType == EMR_EXTCREATEFONTINDIRECTW) {
const EMREXTCREATEFONTINDIRECTW* create_font_record =
reinterpret_cast<const EMREXTCREATEFONTINDIRECTW*>(record);
*reinterpret_cast<LOGFONT*>(log_font) = create_font_record->elfw.elfLogFont;
}
return 1;
}
// Finds a fallback font to use to render the specified |text| with respect to
// an initial |font|. Returns the resulting font via out param |result|. Returns
// |true| if a fallback font was found.
// Adapted from WebKit's |FontCache::GetFontDataForCharacters()|.
// TODO(asvitkine): This should be moved to font_fallback_win.cc.
bool ChooseFallbackFont(HDC hdc,
HFONT font,
const wchar_t* text,
int text_length,
LOGFONT* result)
{
// Use a meta file to intercept the fallback font chosen by Uniscribe.
HDC meta_file_dc = CreateEnhMetaFile(hdc, NULL, NULL, NULL);
if (!meta_file_dc)
return false;
if (font)
SelectObject(meta_file_dc, font);
SCRIPT_STRING_ANALYSIS script_analysis;
HRESULT hresult =
ScriptStringAnalyse(meta_file_dc, text, text_length, 0, -1,
SSA_METAFILE | SSA_FALLBACK | SSA_GLYPHS | SSA_LINK,
0, NULL, NULL, NULL, NULL, NULL, &script_analysis);
if (SUCCEEDED(hresult)) {
hresult = ScriptStringOut(script_analysis, 0, 0, 0, NULL, 0, 0, FALSE);
ScriptStringFree(&script_analysis);
}
bool found_fallback = false;
HENHMETAFILE meta_file = CloseEnhMetaFile(meta_file_dc);
if (SUCCEEDED(hresult)) {
LOGFONT log_font;
log_font.lfFaceName[0] = 0;
EnumEnhMetaFile(0, meta_file, MetaFileEnumProc, &log_font, NULL);
if (log_font.lfFaceName[0]) {
*result = log_font;
found_fallback = true;
}
}
DeleteEnhMetaFile(meta_file);
return found_fallback;
}
示例代码:
std::wstring arabicStr = L"ششش";
hdc = BeginPaint(hWnd, &ps);
LOGFONT logFont = {0};
wcscpy_s(logFont.lfFaceName, L"微软雅黑");
HFONT hFont = CreateFontIndirect(&logFont);
ChooseFallbackFont(hdc, hFont, arabicStr.c_str(), arabicStr.length(), &logFont);
ATLTRACE(logFont.lfFaceName);
HFONT hFontNew = CreateFontIndirect(&logFont);
HFONT hFontOld = (HFONT)SelectObject(hdc, hFontNew);
wchar_t glyphs[10] = {0};
GCP_RESULTS gcpRet = {0};
gcpRet.lStructSize = sizeof(gcpRet);
gcpRet.lpGlyphs = glyphs;
gcpRet.nGlyphs = 10;
ATLASSERT(GetCharacterPlacement(hdc, arabicStr.c_str(), arabicStr.length(), GCP_MAXEXTENT, &gcpRet,
GCP_DISPLAYZWG | GCP_GLYPHSHAPE | GCP_REORDER ));
RECT rcClient;
GetClientRect(hWnd, &rcClient);
ExtTextOut(hdc, 200, 200, ETO_GLYPH_INDEX | ETO_RTLREADING, &rcClient, gcpRet.lpGlyphs, gcpRet.nGlyphs, NULL);
SelectObject(hdc, hFontOld);
DeleteObject(hFontNew);
DeleteObject(hFont);
EndPaint(hWnd, &ps);
微软雅黑
是一种不支持阿拉伯语的字体,所以我们需要一个用于阿拉伯语的备用字体。在我的框中,GDI 自动选择Microsoft Sans Serif
阿拉伯语。