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

如何向SharpDX.DirectWrite.Factory添加嵌入式字体资源?

解决NinjaTrader 8中嵌入式FontAwesome字体无法通过SharpDX.DirectWrite加载的问题

1. 先确认嵌入式字体资源的配置正确性

  • 右键项目中的.ttf/.otf文件,设置生成操作为Embedded Resource,复制到输出目录选择不复制
  • 注意资源的完整命名规则:如果字体放在项目的Fonts子文件夹下,资源全名格式为[你的DLL命名空间].Fonts.[字体文件名],例如MyIndicatorDLL.Fonts.FontAwesome6FreeSolid.ttf

2. 绕过自定义FontLoader,直接给宿主Factory加载字体流

NinjaTrader 8的SharpDX.DirectWrite.Factory是提前初始化完成的,不会自动关联你注册的自定义FontLoader,因此需要手动将字体流加载到已有Factory实例中:

private SharpDX.DirectWrite.FontCollection _fontCollection;
private SharpDX.DirectWrite.FontFamily _fontAwesomeFamily;

protected override void OnStateChange()
{
    if (State == State.SetDefaults)
    {
        // 获取宿主已初始化的DirectWrite Factory
        var dwriteFactory = ChartControl.DirectWriteFactory;
        
        // 读取嵌入式字体资源流
        var assembly = typeof(YourIndicatorClass).Assembly;
        using (var fontStream = assembly.GetManifestResourceStream("MyIndicatorDLL.Fonts.FontAwesome6FreeSolid.ttf"))
        {
            if (fontStream == null)
                throw new InvalidOperationException("无法找到嵌入式字体资源");
            
            // 将资源流转换为SharpDX兼容的MemoryStream
            using (var memoryStream = new SharpDX.IO.MemoryStream(fontStream))
            {
                // 创建字体集合并加载字体
                _fontCollection = new SharpDX.DirectWrite.FontCollection(dwriteFactory, new FontFileStream(memoryStream));
                _fontAwesomeFamily = _fontCollection.GetFontFamily(0);
            }
        }
    }
}

3. 渲染时使用加载好的字体家族

在OnRender方法中,不要直接指定字体名称,而是用已加载的FontFamily创建TextFormat,避免系统 fallback 到Arial:

protected override void OnRender(ChartControl chartControl, ChartScale chartScale)
{
    base.OnRender(chartControl, chartScale);
    
    var dwriteFactory = chartControl.DirectWriteFactory;
    // 使用加载好的FontAwesome字体家族创建TextFormat
    using (var textFormat = new SharpDX.DirectWrite.TextFormat(dwriteFactory, _fontAwesomeFamily, SharpDX.DirectWrite.FontWeight.Regular, SharpDX.DirectWrite.FontStyle.Normal, 16))
    using (var textLayout = new SharpDX.DirectWrite.TextLayout(dwriteFactory, "\uf005", textFormat, 100, 100))
    {
        // 渲染图标到指定位置
        var renderTarget = chartControl.RenderTarget;
        renderTarget.DrawTextLayout(new SharpDX.Vector2(50, 50), textLayout, new SharpDX.Direct2D1.SolidColorBrush(renderTarget, SharpDX.Color.Red));
    }
}

4. 关键验证点

  • 检查资源流读取状态:加载时输出fontStream.Length,确认值大于0,说明资源读取成功
  • 验证FontFamily有效性:输出_fontAwesomeFamily.FamilyNames.GetString(SharpDX.DirectWrite.LocaleName.GetUserDefaultLocaleName()),确认返回FontAwesome的官方名称(如Font Awesome 6 Free)
  • 确保使用正确的Unicode字符:FontAwesome图标对应的字符需用\u开头的Unicode转义格式,例如\uf005对应实心星标,不要使用HTML实体编码

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:03:19