首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Direct2D 文字測量完全指南:IDWriteTextLayout 實戰詳解

     編輯:關於C語言

背景痛點

開發自繪 GUI 框架(支援 GDI/Direct2D 雙引擎切換)時,自動佈局系統必須精準測量文字尺寸。GDI 有 GetTextExtentPoint32 等現成 API,但 Direct2D 無直接對應函數,官方文檔也語焉不詳,網上甚至流傳「辦不到」的謬論。經遍歷 MSDN,找到基於 IDWriteTextLayout 的標準解法。

核心步驟:兩階段建構

階段一:建立 IDWriteTextFormat(字體描述)

IDWriteFactory* dwriteFactory = GetDirectWriteFactory();
IDWriteTextFormat* format = nullptr;

HRESULT hr = dwriteFactory->CreateTextFormat(
    fontFamily,                    // 字體名稱 (L"Microsoft YaHei")
    nullptr,                       // 字體集合(null 為系統預設)
    fontWeight,                    // DWRITE_FONT_WEIGHT_NORMAL/BOLD
    fontStyle,                     // DWRITE_FONT_STYLE_NORMAL/ITALIC
    DWRITE_FONT_STRETCH_NORMAL,    // 字寬
    fontSize,                      // 點陣大小 (FLOAT)
    L"",                           // 語系(空字串為使用者預設)
    &format                        // 輸出介面
);

if (SUCCEEDED(hr)) {
    format->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP); // 禁止自動換行
    // format 現在可作為 ID2D1RenderTarget::DrawText 的字體參數
}

階段二:建立 IDWriteTextLayout 並取得度量

IDWriteTextLayout* textLayout = nullptr;
hr = dwriteFactory->CreateTextLayout(
    textBuffer,        // 文字內容 (WCHAR*)
    textLength,        // 字元數
    textFormat,        // 上一步建立的 IDWriteTextFormat
    0,                 // 排版寬度(0 為不限制)
    0,                 // 排版高度(0 為不限制)
    &textLayout
);

if (SUCCEEDED(hr)) {
    DWRITE_TEXT_METRICS metrics;
    hr = textLayout->GetMetrics(&metrics);
    if (SUCCEEDED(hr)) {
        // 關鍵尺寸:含尾隨空白的寬度、高度
        Size textSize(
            (int)ceil(metrics.widthIncludingTrailingWhitespace),
            (int)ceil(metrics.height)
        );
        // textSize 即為所需文字區域大小
    }
    textLayout->Release(); // 記得釋放 COM 介面
}

關鍵點解析

  • IDWriteTextFormat 相當於 GDI 的 HFONT,描述字體屬性,可重複使用。
  • IDWriteTextLayout 才是排版引擎,綁定具體文字內容,提供 GetMetrics、HitTest、Draw 等豐富功能。
  • widthIncludingTrailingWhitespace 包含行尾空白,佈局計算通常應用此值;width 則不含尾隨空白。
  • 所有尺寸單位為 DIP(Device Independent Pixels),Direct2D 轉譯時會自動套用 DPI 縮放。

實戰整合:WPF 風格自動佈局系統

作者構建了類 WPF 的 Vczh Library++ 3.0,支援:

  • 聲明式佈局(類似 TableLayoutPanel/Grid)
  • 控制項模板化(Button 含動畫邊框、漸層、文字自動對齊)
  • GDI / Direct2D 運行時切換(專案含 DebugDirect2D/ReleaseDirect2D 配置)

Direct2D 渲染 Win7 風格按鈕示例

完整專案下載

Candidate\GUI\GuiDemo\GuiDemo.sln,按 F5 即可體驗。專案已指定 DXSDK 路徑,若編譯失敗請調整為本機安裝路徑。

總結

Direct2D 文字測量的正規路徑:IDWriteFactory → CreateTextFormat → CreateTextLayout → GetMetrics。雖比 GDI 繞彎,但功能更強(複雜排版、OpenType 特性、Hit Testing),且為現代 Windows 圖形堆疊基石。掌握此模式,即可構建高效能、高保真、DPI 感知的文字渲染系統。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved