2011-04-08 108 views
7

我的目标: 我想获得IDWriteTextFormat字体的高度,以便我可以计算在特定高度的IDWriteTextLayout中可以放入多少行文本。Directwrite:获取字体高度

我的问题: 现在,我使用这个代码来计算行的可见的数字:

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中的文本按行存储)中的多行文本拉入布局,并在每次窗口滚动或调整大小时重新创建它。

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

回答

6

我找到了answer。 要查找的DirectWrite线(字体高度加上间隙)的间距,你必须做一些类似于如下:

inline int kmTextCtrl::GetVisLines() const 
{ 

    IDWriteFontCollection* collection; 
    TCHAR name[64]; UINT32 findex; BOOL exists; 
    pTextFormat->GetFontFamilyName(name, 64); 
    pTextFormat->GetFontCollection(&collection); 
    collection->FindFamilyName(name, &findex, &exists); 
    IDWriteFontFamily *ffamily; 
    collection->GetFontFamily(findex, &ffamily); 
    IDWriteFont* font; 
    ffamily->GetFirstMatchingFont(pTextFormat->GetFontWeight(), pTextFormat->GetFontStretch(), pTextFormat->GetFontStyle(), &font); 
    DWRITE_FONT_METRICS metrics; 
    font->GetMetrics(&metrics); 
    float ratio = pTextFormat->GetFontSize()/(float)metrics.designUnitsPerEm; 
    float size = (metrics.ascent + metrics.descent + metrics.lineGap) * ratio; 
    float height = GetHeight(); 
    int retval = static_cast<int>(height/size); 
    ffamily->Release(); 
    collection->Release(); 
    font->Release(); 
    return retval; 
} 

当然,你可能不希望你的所有,都必须这样做调用常用的内联函数。

+0

这绝对是一种错误的方法。请参阅Dwayne的解决方案。 – bunglehead 2016-05-21 09:46:17

+0

@bunglehead为什么这是错的? – 2017-10-13 13:30:51

+0

@DmitriNesteruk,因为它做了太多的假设。例如,即使不考虑稍后根据实际文本数据使用不同的字体,也可以开始测量线条。接下来,它忽略行间距模式,并假定布局计算间距的方式为(上升+下降+ lineGap)。请参阅上面评分最高的答案,它更好地解释了为什么这是不可靠的解决方案。 – bunglehead 2017-10-14 20:33:46