zoukankan      html  css  js  c++  java
  • 使用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测量文本尺寸的过程了。

    如有错误,欢迎指正。

  • 相关阅读:
    golang strings.Split函数
    Launch agent by connecting it to the master
    使用srvany.exe把程序安装成windows服务的方法
    区别对待 .gz 文件 和 .tar.gz 文件
    go 使用 sort 对切片进行排序
    Go数组遍历与排序
    Container killed on request. Exit code is 143
    ERROR tool.ImportTool
    报错笔记:sqoop 执行import命令报错
    连不上网
  • 原文地址:https://www.cnblogs.com/Ray1024/p/6027052.html
Copyright © 2011-2022 走看看