使用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測量文本尺寸的過程了。

如有錯誤,歡迎指正。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM