如何向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
相关产品推荐
相关产品推荐

