void CanvasD2D::FillRectangle(Gdiplus::Rect& rect, const Gdiplus::SolidBrush& brush) { if (!m_Target) // Use GDI+ if D2D render target has not been created. { m_GdipGraphics->FillRectangle(&brush, rect); return; } Gdiplus::Color color; brush.GetColor(&color); Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> solidBrush; HRESULT hr = m_Target->CreateSolidColorBrush(ToColorF(color), solidBrush.GetAddressOf()); if (SUCCEEDED(hr)) { m_Target->FillRectangle(ToRectF(rect), solidBrush.Get()); } }
void CanvasD2D::FillRectangle(Gdiplus::Rect& rect, const Gdiplus::SolidBrush& brush) { if (!m_Target) // Use GDI+ if D2D render target has not been created. { m_GdipGraphics->FillRectangle(&brush, rect); return; } Gdiplus::Color color; brush.GetColor(&color); ID2D1SolidColorBrush* solidBrush; HRESULT hr = m_Target->CreateSolidColorBrush(ToColorF(color), &solidBrush); if (SUCCEEDED(hr)) { m_Target->FillRectangle(ToRectF(rect), solidBrush); solidBrush->Release(); } }
void CanvasD2D::DrawTextW(const WCHAR* str, UINT strLen, const TextFormat& format, Gdiplus::RectF& rect, const Gdiplus::SolidBrush& brush) { if (!BeginTargetDraw()) return; Gdiplus::Color color; brush.GetColor(&color); Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> solidBrush; HRESULT hr = m_Target->CreateSolidColorBrush(ToColorF(color), solidBrush.GetAddressOf()); if (SUCCEEDED(hr)) { TextFormatD2D& formatD2D = (TextFormatD2D&)format; const bool right = formatD2D.GetHorizontalAlignment() == Gfx::HorizontalAlignment::Right; formatD2D.CreateLayout(str, strLen, rect.Width, rect.Height); m_Target->DrawTextLayout( D2D1::Point2F(right ? rect.X - 2 : rect.X + 2.0f, rect.Y - 1.0f), formatD2D.m_TextLayout.Get(), solidBrush.Get()); } }
void CanvasD2D::DrawTextW(const WCHAR* str, UINT strLen, const TextFormat& format, Gdiplus::RectF& rect, const Gdiplus::SolidBrush& brush, bool applyInlineFormatting) { if (!BeginTargetDraw()) return; Gdiplus::Color color; brush.GetColor(&color); Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> solidBrush; HRESULT hr = m_Target->CreateSolidColorBrush(ToColorF(color), solidBrush.GetAddressOf()); if (FAILED(hr)) return; TextFormatD2D& formatD2D = (TextFormatD2D&)format; if (!formatD2D.CreateLayout( m_Target.Get(), str, strLen, rect.Width, rect.Height, !m_AccurateText && m_TextAntiAliasing)) return; D2D1_POINT_2F drawPosition; drawPosition.x = [&]() { if (!m_AccurateText) { const float xOffset = formatD2D.m_TextFormat->GetFontSize() / 6.0f; switch (formatD2D.GetHorizontalAlignment()) { 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); } } // When different "effects" are used with inline coloring options, we need to // remove the previous inline coloring, then reapply them (if needed) - instead // of destroying/recreating the text layout. formatD2D.ResetInlineColoring(solidBrush.Get(), strLen); if (applyInlineFormatting) { formatD2D.ApplyInlineColoring(m_Target.Get(), &drawPosition); } m_Target->DrawTextLayout(drawPosition, formatD2D.m_TextLayout.Get(), solidBrush.Get()); if (applyInlineFormatting) { // Inline gradients require the drawing position, so in case that position // changes, we need a way to reset it after drawing time so on the next // iteration it will know the correct position. formatD2D.ResetGradientPosition(&drawPosition); } if (formatD2D.m_Trimming) { if (m_CanUseAxisAlignClip) { m_Target->PopAxisAlignedClip(); } else { m_Target->PopLayer(); } } }
void CanvasD2D::DrawTextW(const WCHAR* str, UINT strLen, const TextFormat& format, Gdiplus::RectF& rect, const Gdiplus::SolidBrush& brush) { if (!BeginTargetDraw()) return; Gdiplus::Color color; brush.GetColor(&color); Microsoft::WRL::ComPtr<ID2D1SolidColorBrush> solidBrush; HRESULT hr = m_Target->CreateSolidColorBrush(ToColorF(color), solidBrush.GetAddressOf()); 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 = [&]() { if (!m_AccurateText) { const float xOffset = formatD2D.m_TextFormat->GetFontSize() / 6.0f; switch (formatD2D.GetHorizontalAlignment()) { 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()); if (formatD2D.m_Trimming) { if (m_CanUseAxisAlignClip) { m_Target->PopAxisAlignedClip(); } else { m_Target->PopLayer(); } } }