判断两个IDWriteFontFace实例是否对应同一字体及方案可靠性咨询
判断两个IDWriteFontFace实例是否指向同一字体文件的可靠性分析
问题背景
需要判断两个IDWriteFontFace实例是否代表同一字体文件(包含.ttc字体的索引),疑问通过对比IUnknown指针值的方案是否可靠,测试发现:
- 若使用
IDWriteGdiInterop::CreateFontFaceFromHdc创建IDWriteFontFace,即使使用不同HDC但相同LOGFONT,两次调用得到的IUnknown值相同 - 但将
IDWriteFontSet::GetMatchingFonts获取的IDWriteFontFace与CreateFontFaceFromHdc创建的实例对比时,即使指向同一文件,IUnknown值有时相同有时不同
结论:对比IUnknown指针的方案完全不可靠
DirectWrite的对象复用逻辑是内部实现细节,没有公开规范保证同一字体对应的IDWriteFontFace实例指针一定相同:
- 不同创建途径无指针一致性保证:
IDWriteGdiInterop和IDWriteFontSet属于不同的对象创建路径,DirectWrite没有义务返回同一个实例指针,哪怕指向同一字体资源。测试中出现的“有时相同”只是内部缓存的偶然结果,绝对不能依赖。 - 同一创建途径也不绝对可靠:虽然
CreateFontFaceFromHdc目前会返回同一实例,但这是内部缓存策略,微软可能在后续版本修改该逻辑,没有官方文档承诺这种行为会一直保持。
可靠的判断方式
要准确判断两个IDWriteFontFace是否指向同一字体文件(含TTC索引),需读取并对比以下核心信息:
- 调用
IDWriteFontFace::GetFontFaceReference获取IDWriteFontFaceReference实例 - 通过
IDWriteFontFaceReference::GetFontFile获取IDWriteFontFile实例 - 调用
IDWriteFontFile::GetReferenceKey获取字体文件的唯一标识,对比该标识是否一致(用于确认是同一物理文件/资源) - 调用
IDWriteFontFace::GetIndex获取字体在.ttc文件中的索引值,对比索引是否相同
只有字体文件标识一致且TTC索引相同,才能确定两个IDWriteFontFace指向同一字体资源。
内容的提问来源于stack exchange,提问作者jeremie bergeron
相关产品推荐
相关产品推荐

