You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SharpDX 4.2.0使用自定义TrueType字体绘图报错,求解决方案

解决SharpDX 4.2.0自定义字体绘制时的ObjectDisposedException问题

核心原因

SharpDX 4.x对COM对象的引用计数管理做了更严格的调整,3.0.0版本的示例代码没有适配这种变化,导致字体相关的COM对象被提前释放,调用DrawText时触发异常。

具体修复步骤

1. 绑定字体加载器与DWrite工厂的生命周期

SharpDX 4.x中,自定义字体加载器(CustomFontCollectionLoader/CustomFontFileLoader)必须存活到DWrite工厂被释放为止:

  • 将加载器实例声明为类级成员变量,而非局部变量,避免被GC提前回收。
  • 不要在加载完字体后手动调用加载器的Dispose()方法,SharpDX会在DWrite工厂释放时自动处理这些依赖对象。

2. 修正字体集合的创建逻辑

创建FontCollection时,确保加载器被正确注册到DWrite工厂:

// 类级成员变量
private CustomFontCollectionLoader _fontCollectionLoader;
private FontCollection _customFontCollection;

// 初始化逻辑
var factory = new SharpDX.DirectWrite.Factory();
var fontBytes = File.ReadAllBytes("your-custom-font.ttf");
var fontFileStream = new CustomFontFileStream(fontBytes);
var fontFileLoader = new CustomFontFileLoader(fontFileStream);

_fontCollectionLoader = new CustomFontCollectionLoader(fontFileLoader);
factory.RegisterFontCollectionLoader(_fontCollectionLoader);

var collectionKey = new FontCollectionKey(Guid.NewGuid().ToByteArray());
_customFontCollection = new FontCollection(factory, _fontCollectionLoader, collectionKey);

3. 管控TextFormat/TextLayout的生命周期

  • 确保TextFormat和TextLayout的创建晚于字体集合,且它们的生命周期不超过DWrite工厂和字体集合。
  • 不要在这些对象被使用前释放任何依赖项。

4. 禁止手动Dispose依赖对象

SharpDX 4.x的COM对象采用自动引用计数,手动调用Dispose()会提前释放对象,导致后续绘制时引用失效。除非确定对象不再被使用,否则不要手动调用该方法。

5. 验证字体加载状态

创建TextFormat后,可通过以下代码确认字体是否正确加载:

var textFormat = new TextFormat(factory, "Your Custom Font Name", _customFontCollection, FontWeight.Normal, FontStyle.Normal, FontStretch.Normal, 16);
// 检查字体家族是否有效
if (textFormat.FontFamily.FamilyNames.Count == 0)
{
    throw new InvalidOperationException("自定义字体未正确加载");
}

额外注意事项

  • 确保D2D RenderTarget和DWrite工厂的线程模型一致(默认均为单线程公寓STA),跨线程访问COM对象也会触发异常。
  • 若使用内存流加载字体,需确保流对象在字体使用期间保持存活,不要提前关闭或释放。

内容的提问来源于stack exchange,提问作者Undead

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 07:10:28