我们如何知道真字体的代码点是否高于 0xFFFF ?
3 回答
有一个 API (GetFontUnicodeRanges/GetGlyphIndices),但我怀疑你知道它不会超过 0xFFFF。
有两种明显的以编程方式查找的方法:
- 解析
.ttf
文件(规范是开放式的) - 尝试测量您感兴趣的字符的输出,并将测量结果与已知的替换字符进行比较
这个答案有一个 .NET/C# 解决方案:Get supported characters of a font - in C#
如果运行 Windows 7+,您可以调用 DirectWriteIDWriteFontFace::GetGlyphIndices
从给定代码点的 cmap 或(Win 8+ 或 Windows 7 的平台更新)中获取名义字形 id,IDWriteFontFace1::GetUnicodeRanges
如果您只想知道所有范围。GDIGetGlyphIndices
和 UniscribeScriptGetCmap
仅支持基本的多语言平面。
ScriptShape
API to the rescue. Windows 7 and higher. Unlike ScriptGetCMap
, it supports UTF-16 surrogate pairs. For unsupported by the font characters, it returns a zero glyph index.
The sample below assumes a one glyph string. The buffers are all static. See the API docs for buffer size requirements.
wchar_t ws[] = L""; // Known astral plane character
SelectObject(hDC, hFont); // Font to analyze - construct your own
SCRIPT_CACHE ScCache = nullptr; //One of those per font, per size.
HRESULT hr;
SCRIPT_ITEM si[3]; // Static buffers here :(
int ci;
WORD Glyphs[10], Clust[10];
SCRIPT_VISATTR sva[10];
hr = ScriptItemize(ws, wcslen(ws), 2, nullptr, nullptr, si, &ci);
int ng;
hr = ScriptShape(hDC, &ScCache, s, s[1] ? 2 : 1, _countof(Glyphs), &si[0].a, Glyphs, Clust, sva, &ng);
// For the win!
bool FontSupportsThisGlyph = (ng == 1 && Glyphs[0] != 0);