使用DirectWrite測量Direct2D文字大小

來源:互聯網
上載者:User

標籤:ceil   格式化   virt   實現   寬度   換行   height   排版   white   

轉載請註明出處: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; // 格式化文本的高度,Null 字元串的高度由預設字型行高的大小決定         FLOAT layoutWidth; // 布局的初始寬度,根據文本是否被換行,它可以大於或小於常值內容寬度         FLOAT layoutHeight; // 布局的初始高度,根據文本的長度,它可以大於或小於常值內容高度         UINT32 maxBidiReorderingDepth; // 任一行文本的最大重新排序計數,用於計算點擊測試框的最大數量,如布局沒有雙向文本或根本沒有文本,則最小層級為1         UINT32 lineCount; // 文本的總行數     };         

這個結構體的成員很多,而且都是一些非常有用的資訊啊。瞭解了DWRITE_TEXT_METRICS這個結構體之後,我們就知道取出的文本布局資訊都有什麼了。那我們除了擷取文字大小,還可以擷取文本的左上方座標、總行數等等資訊,看來我們可以從這瞭解很多文本的資訊了。

 

四、結語

上面的介紹應該讓大家可以完全理解了如何使用DirectWrite測量文本尺寸的過程了。

如有錯誤,歡迎指正。

使用DirectWrite測量Direct2D文字大小

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.