mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
Gfx: Handle failed creation of D2D text layout
This commit is contained in:
parent
6d243711a6
commit
ca41a4575c
@ -318,69 +318,68 @@ void CanvasD2D::DrawTextW(const WCHAR* str, UINT strLen, const TextFormat& forma
|
|||||||
|
|
||||||
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> solidBrush;
|
Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> solidBrush;
|
||||||
HRESULT hr = m_Target->CreateSolidColorBrush(ToColorF(color), solidBrush.GetAddressOf());
|
HRESULT hr = m_Target->CreateSolidColorBrush(ToColorF(color), solidBrush.GetAddressOf());
|
||||||
if (SUCCEEDED(hr))
|
if (FAILED(hr)) return;
|
||||||
|
|
||||||
|
TextFormatD2D& formatD2D = (TextFormatD2D&)format;
|
||||||
|
if (!formatD2D.CreateLayout(
|
||||||
|
str, strLen, rect.Width, rect.Height, !m_AccurateText && m_TextAntiAliasing)) return;
|
||||||
|
|
||||||
|
D2D1_POINT_2F drawPosition;
|
||||||
|
drawPosition.x = [&]()
|
||||||
{
|
{
|
||||||
TextFormatD2D& formatD2D = (TextFormatD2D&)format;
|
if (!m_AccurateText)
|
||||||
formatD2D.CreateLayout(
|
|
||||||
str, strLen, rect.Width, rect.Height, !m_AccurateText && m_TextAntiAliasing);
|
|
||||||
|
|
||||||
D2D1_POINT_2F drawPosition;
|
|
||||||
drawPosition.x = [&]()
|
|
||||||
{
|
{
|
||||||
if (!m_AccurateText)
|
const float xOffset = formatD2D.m_TextFormat->GetFontSize() / 6.0f;
|
||||||
|
switch (formatD2D.GetHorizontalAlignment())
|
||||||
{
|
{
|
||||||
const float xOffset = formatD2D.m_TextFormat->GetFontSize() / 6.0f;
|
case HorizontalAlignment::Left: return rect.X + xOffset;
|
||||||
switch (formatD2D.GetHorizontalAlignment())
|
case HorizontalAlignment::Right: return rect.X - xOffset;
|
||||||
{
|
|
||||||
case HorizontalAlignment::Left: return rect.X + xOffset;
|
|
||||||
case HorizontalAlignment::Right: return rect.X - xOffset;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rect.X;
|
|
||||||
} ();
|
|
||||||
|
|
||||||
drawPosition.y = [&]()
|
|
||||||
{
|
|
||||||
// GDI+ compatibility.
|
|
||||||
float yPos = rect.Y - formatD2D.m_LineGap;
|
|
||||||
switch (formatD2D.GetVerticalAlignment())
|
|
||||||
{
|
|
||||||
case VerticalAlignment::Bottom: yPos -= formatD2D.m_ExtraHeight; break;
|
|
||||||
case VerticalAlignment::Center: yPos -= formatD2D.m_ExtraHeight / 2; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return yPos;
|
|
||||||
} ();
|
|
||||||
|
|
||||||
if (formatD2D.m_Trimming)
|
|
||||||
{
|
|
||||||
D2D1_RECT_F clipRect = ToRectF(rect);
|
|
||||||
|
|
||||||
if (m_CanUseAxisAlignClip)
|
|
||||||
{
|
|
||||||
m_Target->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_ALIASED);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const D2D1_LAYER_PARAMETERS layerParams =
|
|
||||||
D2D1::LayerParameters(clipRect, nullptr, D2D1_ANTIALIAS_MODE_ALIASED);
|
|
||||||
m_Target->PushLayer(layerParams, nullptr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Target->DrawTextLayout(drawPosition, formatD2D.m_TextLayout.Get(), solidBrush.Get());
|
return rect.X;
|
||||||
|
} ();
|
||||||
|
|
||||||
if (formatD2D.m_Trimming)
|
drawPosition.y = [&]()
|
||||||
|
{
|
||||||
|
// GDI+ compatibility.
|
||||||
|
float yPos = rect.Y - formatD2D.m_LineGap;
|
||||||
|
switch (formatD2D.GetVerticalAlignment())
|
||||||
{
|
{
|
||||||
if (m_CanUseAxisAlignClip)
|
case VerticalAlignment::Bottom: yPos -= formatD2D.m_ExtraHeight; break;
|
||||||
{
|
case VerticalAlignment::Center: yPos -= formatD2D.m_ExtraHeight / 2; break;
|
||||||
m_Target->PopAxisAlignedClip();
|
}
|
||||||
}
|
|
||||||
else
|
return yPos;
|
||||||
{
|
} ();
|
||||||
m_Target->PopLayer();
|
|
||||||
}
|
if (formatD2D.m_Trimming)
|
||||||
|
{
|
||||||
|
D2D1_RECT_F clipRect = ToRectF(rect);
|
||||||
|
|
||||||
|
if (m_CanUseAxisAlignClip)
|
||||||
|
{
|
||||||
|
m_Target->PushAxisAlignedClip(clipRect, D2D1_ANTIALIAS_MODE_ALIASED);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const D2D1_LAYER_PARAMETERS layerParams =
|
||||||
|
D2D1::LayerParameters(clipRect, nullptr, D2D1_ANTIALIAS_MODE_ALIASED);
|
||||||
|
m_Target->PushLayer(layerParams, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Target->DrawTextLayout(drawPosition, formatD2D.m_TextLayout.Get(), solidBrush.Get());
|
||||||
|
|
||||||
|
if (formatD2D.m_Trimming)
|
||||||
|
{
|
||||||
|
if (m_CanUseAxisAlignClip)
|
||||||
|
{
|
||||||
|
m_Target->PopAxisAlignedClip();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_Target->PopLayer();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ void TextFormatD2D::Dispose()
|
|||||||
m_LineGap = 0.0f;
|
m_LineGap = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextFormatD2D::CreateLayout(
|
bool TextFormatD2D::CreateLayout(
|
||||||
const WCHAR* str, UINT strLen, float maxW, float maxH, bool gdiEmulation)
|
const WCHAR* str, UINT strLen, float maxW, float maxH, bool gdiEmulation)
|
||||||
{
|
{
|
||||||
bool strChanged = false;
|
bool strChanged = false;
|
||||||
@ -84,38 +84,38 @@ void TextFormatD2D::CreateLayout(
|
|||||||
{
|
{
|
||||||
CanvasD2D::c_DWFactory->CreateTextLayout(
|
CanvasD2D::c_DWFactory->CreateTextLayout(
|
||||||
str, strLen, m_TextFormat.Get(), maxW, maxH, m_TextLayout.ReleaseAndGetAddressOf());
|
str, strLen, m_TextFormat.Get(), maxW, maxH, m_TextLayout.ReleaseAndGetAddressOf());
|
||||||
|
if (!m_TextLayout) return false;
|
||||||
|
|
||||||
if (m_TextLayout)
|
if (gdiEmulation)
|
||||||
{
|
{
|
||||||
if (gdiEmulation)
|
Microsoft::WRL::ComPtr<IDWriteTextLayout1> textLayout1;
|
||||||
{
|
m_TextLayout.As(&textLayout1);
|
||||||
Microsoft::WRL::ComPtr<IDWriteTextLayout1> textLayout1;
|
|
||||||
m_TextLayout.As(&textLayout1);
|
|
||||||
|
|
||||||
const float xOffset = m_TextFormat->GetFontSize() / 6.0f;
|
const float xOffset = m_TextFormat->GetFontSize() / 6.0f;
|
||||||
const float emOffset = xOffset / 24.0f;
|
const float emOffset = xOffset / 24.0f;
|
||||||
const DWRITE_TEXT_RANGE range = {0, strLen};
|
const DWRITE_TEXT_RANGE range = {0, strLen};
|
||||||
textLayout1->SetCharacterSpacing(emOffset, emOffset, 0.0f, range);
|
textLayout1->SetCharacterSpacing(emOffset, emOffset, 0.0f, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT32 lineCount = 0;
|
UINT32 lineCount = 0;
|
||||||
DWRITE_LINE_METRICS lineMetrics[2];
|
DWRITE_LINE_METRICS lineMetrics[2];
|
||||||
HRESULT hr = m_TextLayout->GetLineMetrics(lineMetrics, _countof(lineMetrics), &lineCount);
|
HRESULT hr = m_TextLayout->GetLineMetrics(lineMetrics, _countof(lineMetrics), &lineCount);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
|
{
|
||||||
|
// If only one line is visible, disable wrapping so that as much text as possible is shown
|
||||||
|
// after trimming.
|
||||||
|
// TODO: Fix this for when more than one line is visible.
|
||||||
|
if (lineCount >= 2 &&
|
||||||
|
lineMetrics[0].isTrimmed &&
|
||||||
|
lineMetrics[1].isTrimmed &&
|
||||||
|
lineMetrics[1].height == 0.0f)
|
||||||
{
|
{
|
||||||
// If only one line is visible, disable wrapping so that as much text as possible is shown
|
m_TextLayout->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
||||||
// after trimming.
|
|
||||||
// TODO: Fix this for when more than one line is visible.
|
|
||||||
if (lineCount >= 2 &&
|
|
||||||
lineMetrics[0].isTrimmed &&
|
|
||||||
lineMetrics[1].isTrimmed &&
|
|
||||||
lineMetrics[1].height == 0.0f)
|
|
||||||
{
|
|
||||||
m_TextLayout->SetWordWrapping(DWRITE_WORD_WRAPPING_NO_WRAP);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextFormatD2D::SetProperties(
|
void TextFormatD2D::SetProperties(
|
||||||
|
@ -55,8 +55,8 @@ private:
|
|||||||
|
|
||||||
// Creates a new DirectWrite text layout if |str| has changed since last call. Since creating
|
// Creates a new DirectWrite text layout if |str| has changed since last call. Since creating
|
||||||
// the layout is costly, it is more efficient to keep reusing the text layout until the text
|
// the layout is costly, it is more efficient to keep reusing the text layout until the text
|
||||||
// changes.
|
// changes. Returns true if the layout is valid for use.
|
||||||
void CreateLayout(const WCHAR* str, UINT strLen, float maxW, float maxH, bool gdiEmulation);
|
bool CreateLayout(const WCHAR* str, UINT strLen, float maxW, float maxH, bool gdiEmulation);
|
||||||
|
|
||||||
DWRITE_TEXT_METRICS GetMetrics(
|
DWRITE_TEXT_METRICS GetMetrics(
|
||||||
const WCHAR* str, UINT strLen, bool gdiEmulation, float maxWidth = 10000.0f);
|
const WCHAR* str, UINT strLen, bool gdiEmulation, float maxWidth = 10000.0f);
|
||||||
|
Loading…
Reference in New Issue
Block a user