首页 > 代码库 > 使用DirectWrite测量Direct2D文字大小
使用DirectWrite测量Direct2D文字大小
转载请注明出处:http://www.cnblogs.com/Ray1024
一、概述
最近在使用Direct2D和DirectWrite写引擎,在引擎中需要实现文本标签控件。但是文本标签的尺寸最好不是由我们人为指定的,要不然的话就会出现标签中文本溢出、空白存留等等问题,这样很影响美观。这就需要我们在文本标签的创建时根据文本的字体格式、文字排版等等因素来确定标签大小,而不是人为地指定大小,即实现标签大小的自适应功能(根据文本的内容、字体、格式等等因素得出的宽高来设置标签的大小)。
然而,想要实现标签大小的自适应功能,就需要测量Direct2D文本的大小。但是,如何测量Direct2D文字的大小呢,我在Direct2D中找了很久也没有找到合适的方法,在搜索引擎中也没有找到理想的解决方法。最后,在DirectWrite的MSDN文档中找到了解决方法。
这篇文章就来介绍一下怎样使用DirectWrite来测量Direct2D文本的大小。
二、解决方法
以下是我实现的一段用于测量文本宽高尺寸的函数,先贴代码:
// 使用IDWriteTextLayout获取文本大小 HRESULT GetTextSize(const WCHAR* text, IDWriteTextFormat* pTextFormat, D2D1_SIZE_F& size) { HRESULT hr = S_OK; IDWriteTextLayout* pTextLayout = NULL; // 创建文本布局 hr = m_pDWriteFactory->CreateTextLayout(text, wcslen(text), pTextFormat, 0.0f, 0.0f, &pTextLayout); if (SUCCEEDED(hr)) { // 获取文本尺寸 DWRITE_TEXT_METRICS textMetrics; hr = pTextLayout->GetMetrics(&textMetrics); size = D2D1::SizeF(ceil(textMetrics.widthIncludingTrailingWhitespace), ceil(textMetrics.height)); } SafeRelease(&pTextLayout); return hr; }
如上代码中,测量文本尺寸过程如下:
1. 使用文本和字体创建IDWriteTextLayout对象
2. 从创建成功的IDWriteTextLayout对象中获取文本大小信息DWRITE_TEXT_METRICS结构体
3. 将文本信息结构体中的文本尺寸放到参数的size中,用于返回文本尺寸
三、深入解析
上面测量文字大小的代码中,关键的工具就是DirectWrite中的IDWriteTextLayout接口。IDWriteTextLayout接口表示经过完全分析和格式化后的文本块,简单地说就是一个布局后的文本。这个接口中有一个成员函数IDWriteTextLayout::GetMetrics(),我们需要的文本大小信息就可以通过这个函数来获取。重点介绍一下这个函数:
IDWriteTextLayout::GetMetrics 方法介绍 功能 检索格式化后的字符串的总体度量。 语法 virtual HRESULT GetMetrics([out] DWRITE_TEXT_METRICS *textMetrics);参数 textMetrics [out] 此方法返回时,将包含格式化后文本与所关联内容的度量距离。 返回值 如果该方法成功,则返回 S_OK。 否则,将返回错误代码。HRESULT.
此函数的功能简单的说,就是获取IDWriteLayout对象布局后的文本信息,使用参数来返回我们需要的信息。
关于DWRITE_TEXT_METRICS类型的参数,这是一个结构体,用来盛放取出的文本布局信息。我们来看一下它的成员:
// 布局后与文本相关的信息 struct DWRITE_TEXT_METRICS { FLOAT left; // 格式化文本布局框的最左点 FLOAT top; // 格式化文本布局框的最上点 FLOAT width; // 格式化文本的宽度忽略多余的空白处 FLOAT widthIncludingTrailingWhitespace; // 格式化文本的宽度,考虑每行结尾处的尾部空格 FLOAT height; // 格式化文本的高度,空字符串的高度由默认字体行高的大小决定 FLOAT layoutWidth; // 布局的初始宽度,根据文本是否被换行,它可以大于或小于文本内容宽度 FLOAT layoutHeight; // 布局的初始高度,根据文本的长度,它可以大于或小于文本内容高度 UINT32 maxBidiReorderingDepth; // 任一行文本的最大重新排序计数,用于计算命中测试框的最大数量,如布局没有双向文本或根本没有文本,则最小级别为1 UINT32 lineCount; // 文本的总行数 };
这个结构体的成员很多,而且都是一些非常有用的信息啊。了解了DWRITE_TEXT_METRICS这个结构体之后,我们就知道取出的文本布局信息都有什么了。那我们除了获取文本大小,还可以获取文本的左上角坐标、总行数等等信息,看来我们可以从这了解很多文本的信息了。
四、结语
上面的介绍应该让大家可以完全理解了如何使用DirectWrite测量文本尺寸的过程了。
如有错误,欢迎指正。
使用DirectWrite测量Direct2D文字大小