Get precise text width and height for IDWriteTextLayout Combine GetOverhangMetrics() and GetMetrics()

單用 GetMetrics() 所取得的物件高度 (metrics.height),在畫小寫的 y 或類似的字元時會發生誤差。而且字元上方也會加入空白產生排版的錯誤。

要取得真實沒有 padding 和誤差的長寬,要使用 GetOverhangMetrics() 取得 layout 四個方向的空白區域,正值表示超出 layout,負值表示空白在 layout 內,然後再參考 GetMetrics() 取得的 top, left, layoutWidth, layoutHeight 來計算真正有畫圖的區域範圍。

bool get_rect(IDWriteTextLayout* layout, D2D1_RECT_F& out)
{
    HRESULT hr = E_FAIL;
    DWRITE_TEXT_METRICS metrics;
    DWRITE_OVERHANG_METRICS overhang_metrics;

    if (layout == NULL)
    {
        return false;
    }

    hr = layout->GetOverhangMetrics(&overhang_metrics);
    if (SUCCEEDED(hr))
    {
        hr = layout->GetMetrics(&metrics);
    }

    if (SUCCEEDED(hr))
    {
        out = D2D1::RectF(
            metrics.left - overhang_metrics.left,
            metrics.top - overhang_metrics.top,
            metrics.layoutWidth + overhang_metrics.right,
            metrics.layoutHeight + overhang_metrics.bottom);
        return true;
    }

    return false;
}