diff --git a/Common/Gfx/CanvasD2D.cpp b/Common/Gfx/CanvasD2D.cpp index 52429d6f..4db268cb 100644 --- a/Common/Gfx/CanvasD2D.cpp +++ b/Common/Gfx/CanvasD2D.cpp @@ -19,6 +19,7 @@ #include "CanvasD2D.h" #include "TextFormatD2D.h" #include "Util/DWriteFontCollectionLoader.h" +#include "Util/DWriteHelpers.h" #include "Util/WICBitmapLockGDIP.h" #include "../../Library/Litestep.h" @@ -321,7 +322,7 @@ void CanvasD2D::DrawTextW(const WCHAR* str, UINT strLen, const TextFormat& forma if (!m_AccurateText && m_TextAntiAliasing) { - float emOffset = xOffset / 25.0f; + const float emOffset = xOffset / 25.0f; DWRITE_TEXT_RANGE range = {0, strLen}; Microsoft::WRL::ComPtr textLayout; @@ -349,23 +350,10 @@ bool CanvasD2D::MeasureTextW(const WCHAR* str, UINT strLen, const TextFormat& fo textLayout.GetAddressOf()); if (SUCCEEDED(hr)) { - DWRITE_TEXT_METRICS metrics; - textLayout->GetMetrics(&metrics); - - if (!m_AccurateText) - { - float size = 0.0f; - textLayout->GetFontSize(0, &size); - - rect.Width = floor(metrics.width + (size / 2.05f) + (metrics.width / 55.0f) - 0.5f); - rect.Height = floor(metrics.height + (size / 9.25f) + 0.3f); - } - else - { - rect.Width = metrics.width; - rect.Height = metrics.height; - } - + const DWRITE_TEXT_METRICS metrics = + Util::GetAdjustedDWriteTextLayoutMetrics(textLayout.Get(), !m_AccurateText); + rect.Width = metrics.width; + rect.Height = metrics.height; return true; } @@ -386,23 +374,10 @@ bool CanvasD2D::MeasureTextLinesW(const WCHAR* str, UINT strLen, const TextForma textLayout.GetAddressOf()); if (SUCCEEDED(hr)) { - DWRITE_TEXT_METRICS metrics; - textLayout->GetMetrics(&metrics); - - if (!m_AccurateText) - { - float size = 0.0f; - textLayout->GetFontSize(0, &size); - - rect.Width = floor(metrics.width + (size / 2.05f) + (metrics.width / 55.0f) - 0.5f); - rect.Height = floor(metrics.height + (size / 9.25f) + 0.3f); - } - else - { - rect.Width = metrics.width; - rect.Height = metrics.height + 1.0f; - } - + const DWRITE_TEXT_METRICS metrics = + Util::GetAdjustedDWriteTextLayoutMetrics(textLayout.Get(), !m_AccurateText); + rect.Width = metrics.width; + rect.Height = metrics.height; lines = metrics.lineCount; return true; } diff --git a/Common/Gfx/Util/DWriteHelpers.cpp b/Common/Gfx/Util/DWriteHelpers.cpp index a93d6377..1f564acd 100644 --- a/Common/Gfx/Util/DWriteHelpers.cpp +++ b/Common/Gfx/Util/DWriteHelpers.cpp @@ -18,10 +18,34 @@ #include "DWriteHelpers.h" #include +#include namespace Gfx { namespace Util { +DWRITE_TEXT_METRICS GetAdjustedDWriteTextLayoutMetrics( + IDWriteTextLayout* textLayout, bool gdiEmulation) +{ + DWRITE_TEXT_METRICS metrics; + textLayout->GetMetrics(&metrics); + + if (gdiEmulation) + { + float size = 0.0f; + textLayout->GetFontSize(0, &size); + metrics.width = floor(metrics.width + (size / 2.05f) + (metrics.width / 55.0f) - 0.5f); + metrics.height = floor(metrics.height + (size / 9.25f) + 0.3f); + } + else + { + // GDI+ draws multi-line text even though the last line may be clipped slightly at the bottom. + // This is a workaround to emulate that behaviour. + metrics.height += 1.0f; + } + + return metrics; +} + HRESULT GetDWritePropertiesFromGDIProperties( IDWriteFactory* factory, const WCHAR* gdiFamilyName, const bool gdiBold, const bool gdiItalic, DWRITE_FONT_WEIGHT& dwriteFontWeight, DWRITE_FONT_STYLE& dwriteFontStyle, diff --git a/Common/Gfx/Util/DWriteHelpers.h b/Common/Gfx/Util/DWriteHelpers.h index 1140e2a5..278f0b36 100644 --- a/Common/Gfx/Util/DWriteHelpers.h +++ b/Common/Gfx/Util/DWriteHelpers.h @@ -24,6 +24,11 @@ namespace Gfx { namespace Util { +// If |gdiEmulation| is true, the returns metrics have similar characteristics to those provided +// by GDI+. +DWRITE_TEXT_METRICS GetAdjustedDWriteTextLayoutMetrics( + IDWriteTextLayout* textLayout, bool gdiEmulation); + // Maps the GDI family name and italic/bold flags to the DirectWrite family name, weight, style, // and stretch. HRESULT GetDWritePropertiesFromGDIProperties(