gpt4 book ai didi

c++ - Directwrite:获取字体的高度

转载 作者:可可西里 更新时间:2023-11-01 18:17:59 35 4
gpt4 key购买 nike

我的目标: 我想获取 IDWriteTextFormat 字体的高度,这样我就可以计算出在特定高度的 IDWriteTextLayout 中可以容纳多少行文本。

我的问题: 现在我正在使用这段代码来计算可见的行数:

inline int kmTextCtrl::GetVisLines() const
{

/* pTextFormat is an IDWriteTextFormat pointer, dpi_y is the desktop's vertical dpi,
and GetHeight() returns the height (in pixels) of the render target. */
float size = (pTextFormat->GetFontSize()/72.0f)*dpi_y;
return (int)(GetHeight()/size);
}

对于某些字体,计算似乎是准确的,但对于任何 TrueType 字体(例如:Courier New、Arial、Times New Roman)都不准确。对于这些字体,显示的文本被裁剪得远远低于渲染目标的垂直下边界。

一些上下文: 我正在制作一个文本回滚缓冲区控件,它使用 IDWriteTextLayout 将文本放入控件的呈现目标。我使用 GetVisLines() 的结果来确定将循环缓冲区(按行将文本存储在 std::strings 中)中的多少行文本拉入布局,并在每次滚动或调整窗口大小时重新创建它。

这是使用“ native ”Win32 API C++ 完成的。

最佳答案

最简单和最可靠的方法是仅向布局本身询问文本规范,因为这是它设计的两个目的之一,即绘图和测量。您将使用文本格式创建一个 IDWriteTextLayout 并调用 GetMetrics 以获取 DWRITE_TEXT_METRICS::height。我猜你正在使用 ID2D1RenderTarget::DrawText 并传递文本格式,所以你可能没有直接创建布局,但调用 DrawText 就像调用 CreateTextLayout 自己,然后是 DrawTextLayout

请注意,通过较低层来获得此答案(IDWriteFontFace 等)会做出某些假设,即通用的世界就绪文本控件不应假设,例如假设将使用基本字体并且所有的线都是相同的高度。只要所有字符都出现在给定的基本字体中,这就可以解决(很可能你主要显示英语,这就是为什么所有字符都显示得很好),但会加入一些 CJK 或 RTL 语言或表情符号(这是一种基本字体像 Times New Roman 肯定不支持),并且行高会根据替换的字体相应地增加或缩小。 GDI 重新缩放替代字体,使它们适合基本字体的高度,但这会导致泰语和藏语等语言的字母变形不佳,需要更多的上升和下降空间。 IDWriteTextLayout 和 WPF/Word 中的其他布局将所有字体字形保持相同的 em 大小,这意味着它们在彼此相邻时排列得更好;但这确实意味着行高是可变的。

如果您只是绘制每一行文本,就好像它们的高度都相同,您会看到字形之间的重叠和行间不均匀的基线,或者控件顶部和底部的剪裁。所以理想的做法是使用每行的实际高度;但是如果你需要它们都具有相同的高度(或者如果它使控制过于复杂),那么至少使用 SetLineSpacingDWRITE_LINE_SPACING_UNIFORM 设置一个明确的行间距基本字体 - 这样基线就会均匀间隔。

虽然出于好奇,IDWriteTextLayout 将行高计算为该行上所有运行高度的最大值,并且单次运行的高度(相同的字体和 em 大小)仅使用设计指标:ascent + descent,加上任何恰好存在的 lineGap(大多数字体将其设置为零,但 Gabriola 是大线间隙的一个很好的例子)。请注意,所有 em 大小均以 DIP 为单位(在典型的 96DPI 下表示 1:1,DIP 正好 == 像素),而不是点(1/72 英寸)。

(ascent + descent + lineGap) * emSize/designUnitsPerEm

关于c++ - Directwrite:获取字体的高度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5589913/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com