【问题标题】:Get ABC character widths in SharpDX / DirectWrite在 SharpDX / DirectWrite 中获取 ABC 字符宽度
【发布时间】:2017-06-19 16:58:19
【问题描述】:

在 GDI 中获取我会调用 GetCharABCWidths 的字符的 ABC 宽度(左方位、右方位等)。

我如何使用 SharpDX 或 DirectWrite 实现相同的测量值,我是否应该期望这与 GDI 对于相同字符的值匹配?

到目前为止我做了什么?因缺少 Direct* 和 SharpDX 的文档而迷失方向。

【问题讨论】:

  • GetDesignGlyphMetrics,也许?我对 DirectWrite 不是很熟悉,但即使在 GDI 中,我也很少需要 GetCharABCWidths。通常,您真正需要知道的是特定字符串的尺寸(即使该字符串仅包含一个字符),因此您只需调用 DrawStringDT_CALCRECT 或其他什么。我确定 DirectWrite 有类似的“MeasureText”功能。
  • 是的@CodyGray,你会认为这将是 GDI 之后的小菜一碟。 GetDesignGlyphMetrics 返回一个结构,Obtains ideal (resolution-independent) glyph metrics in font design units 与好的 ole GDI 不太一样。事实上,我需要 A 和 B 宽度来满足一些准确的对齐需求。
  • 不,我真的不会。就我而言,GDI 是小菜一碟。这也是我可以在我的机器上获得的最清晰的文本渲染,并且是最快的。就我而言,从那以后的一切都是一种回归,至少对于文本输出和其他非图形密集型绘图任务而言。
  • 我开始意识到这一点。我的应用程序将作为一项服务运行,它引导我使用 DirectWrite 和 WARP。我只需要继续努力。出于兴趣,我是否应该期望 ABC 宽度在 GDI 和 DirectWrite 中匹配?

标签: c# sharpdx directwrite


【解决方案1】:
/// <summary>
///  Takes a string, text format, and associated constraints, and produces an object that represents the fully analyzed and formatted result.
/// </summary>
/// <param name="factory">an instance of <see cref="T:SharpDX.DirectWrite.Factory" /></param>
/// <param name="text">An array of characters that contains the string to create a new <see cref="T:SharpDX.DirectWrite.TextLayout" /> object from. This array must be of length stringLength and can contain embedded NULL characters.</param>
/// <param name="textFormat">A pointer to an object that indicates the format to apply to the string.</param>
/// <param name="maxWidth">The width of the layout box.</param>
/// <param name="maxHeight">The height of the layout box.</param>
/// <unmanaged>HRESULT CreateTextLayout([In, Buffer] const wchar* string,[None] UINT32 stringLength,[None] IDWriteTextFormat* textFormat,[None] FLOAT maxWidth,[None] FLOAT maxHeight,[Out] IDWriteTextLayout** textLayout)</unmanaged>
public TextLayout(Factory factory, string text, TextFormat textFormat, float maxWidth, float maxHeight)

示例代码:

using (var dwFactory = new SharpDX.DirectWrite.Factory())
{
  var textLayout = new TextLayout(dwFactory, "ABC", textFormat, float.PositiveInfinity, float.PositiveInfinity);
  var width = textLayout.Metrics.Width
  ...
}

【讨论】:

  • 感谢 Dan - 我非常感谢您的意见,但如何从中获取 char ABC 宽度并不明显,您能解释一下吗?
  • 当然。更新。您必须将“textFormat”设置为适当的值。
  • 好的,谢谢 - 到目前为止,我的理解是,当以指定的字体特征等布局时,这给出了第二个参数中字符串的宽度。我使用术语“ABC”的目的是解释我正在寻找与旧 GDI GetCharABCWidths() 相同的功能 - 我的 OP 中的链接 - 我认为该功能与 TextLayout() 功能不同,因为 GDI fn 提供左中和右方位(AKA 为 'ABC ' GDI 中的宽度)。我可能完全错了,但我认为 TextLayout() 给出了完整字符串的大小,而不是每个字符的度量?
  • 啊。正确的。我不确定您需要多少指标。如果只是字符宽度,也许你可以尝试类似: var widths = "ABC".Select(_ => new TextLayout(dwFactory, _.ToString(), textFormat, float.PositiveInfinity, float.PositiveInfinity)).ToList( );
  • 我也这么认为,但是我目前发现 TextLayout() 中的悬垂指标似乎在我们当前开发的所有情况下都为零。我有人对此进行调查,但想检查 SO 社区是否知道更合适的方法。另外,我有很多字符要测量,我担心重复使用 TextLayout() 会产生开销。一般来说,我希望 DirectWrite 能够提供与 GDI 相当或更好的功能,我只是很开心(!)试图在没有地图的情况下通过 Labyrinth 找到自己的方式。
猜你喜欢
  • 1970-01-01
  • 2011-08-01
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
  • 1970-01-01
  • 2014-03-20
  • 1970-01-01
  • 2012-03-06
相关资源
最近更新 更多