mirror of
				https://github.com/chibicitiberiu/rainmeter-studio.git
				synced 2024-02-24 04:33:31 +00:00 
			
		
		
		
	Gfx: Avoid clipping with D2D when not needed
This commit is contained in:
		@@ -52,7 +52,8 @@ Microsoft::WRL::ComPtr<IWICImagingFactory> CanvasD2D::c_WICFactory;
 | 
			
		||||
 | 
			
		||||
CanvasD2D::CanvasD2D() : Canvas(),
 | 
			
		||||
	m_Bitmap(),
 | 
			
		||||
	m_TextAntiAliasing(false)
 | 
			
		||||
	m_TextAntiAliasing(false),
 | 
			
		||||
	m_CanUseAxisAlignClip(false)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -169,8 +170,8 @@ bool CanvasD2D::BeginTargetDraw()
 | 
			
		||||
 | 
			
		||||
		m_Target->BeginDraw();
 | 
			
		||||
 | 
			
		||||
		// Apply any transforms that occurred before creation of m_Target
 | 
			
		||||
		m_Target->SetTransform(GetCurrentTransform());
 | 
			
		||||
		// Apply any transforms that occurred before creation of |m_Target|.
 | 
			
		||||
		UpdateTargetTransform();
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
@@ -227,13 +228,18 @@ bool CanvasD2D::IsTransparentPixel(int x, int y)
 | 
			
		||||
	return transparent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
D2D1_MATRIX_3X2_F CanvasD2D::GetCurrentTransform()
 | 
			
		||||
void CanvasD2D::UpdateTargetTransform()
 | 
			
		||||
{
 | 
			
		||||
	D2D1_MATRIX_3X2_F d2dMatrix;
 | 
			
		||||
	Gdiplus::Matrix gdipMatrix;
 | 
			
		||||
	m_GdipGraphics->GetTransform(&gdipMatrix);
 | 
			
		||||
 | 
			
		||||
	D2D1_MATRIX_3X2_F d2dMatrix;
 | 
			
		||||
	gdipMatrix.GetElements((Gdiplus::REAL*)&d2dMatrix);
 | 
			
		||||
	return d2dMatrix;
 | 
			
		||||
 | 
			
		||||
	m_Target->SetTransform(d2dMatrix);
 | 
			
		||||
	m_CanUseAxisAlignClip =
 | 
			
		||||
		d2dMatrix._12 == 0.0f && d2dMatrix._21 == 0.0f &&
 | 
			
		||||
		d2dMatrix._31 == 0.0f && d2dMatrix._32 == 0.0f;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CanvasD2D::SetTransform(const Gdiplus::Matrix& matrix)
 | 
			
		||||
@@ -242,7 +248,7 @@ void CanvasD2D::SetTransform(const Gdiplus::Matrix& matrix)
 | 
			
		||||
 | 
			
		||||
	if (m_Target)
 | 
			
		||||
	{
 | 
			
		||||
		m_Target->SetTransform(GetCurrentTransform());
 | 
			
		||||
		UpdateTargetTransform();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -264,7 +270,7 @@ void CanvasD2D::RotateTransform(float angle, float x, float y, float dx, float d
 | 
			
		||||
 | 
			
		||||
	if (m_Target)
 | 
			
		||||
	{
 | 
			
		||||
		m_Target->SetTransform(GetCurrentTransform());
 | 
			
		||||
		UpdateTargetTransform();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -344,36 +350,34 @@ void CanvasD2D::DrawTextW(const WCHAR* str, UINT strLen, const TextFormat& forma
 | 
			
		||||
			return yPos;
 | 
			
		||||
		} ();
 | 
			
		||||
 | 
			
		||||
		DWRITE_OVERHANG_METRICS overhangMetrics;
 | 
			
		||||
		formatD2D.m_TextLayout->GetOverhangMetrics(&overhangMetrics);
 | 
			
		||||
 | 
			
		||||
		D2D1::Matrix3x2F transformMatrix;
 | 
			
		||||
		m_Target->GetTransform(&transformMatrix);
 | 
			
		||||
		const bool identityTransform = transformMatrix.IsIdentity();
 | 
			
		||||
 | 
			
		||||
		// TODO: Determine if we can avoid clipping.
 | 
			
		||||
		D2D1_RECT_F clipRect = ToRectF(rect);
 | 
			
		||||
		clipRect.bottom += ceil(overhangMetrics.bottom);
 | 
			
		||||
		if (identityTransform)
 | 
			
		||||
		if (formatD2D.m_Trimming)
 | 
			
		||||
		{
 | 
			
		||||
			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);
 | 
			
		||||
			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 (identityTransform)
 | 
			
		||||
		if (formatD2D.m_Trimming)
 | 
			
		||||
		{
 | 
			
		||||
			m_Target->PopAxisAlignedClip();
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			m_Target->PopLayer();
 | 
			
		||||
			if (m_CanUseAxisAlignClip)
 | 
			
		||||
			{
 | 
			
		||||
				m_Target->PopAxisAlignedClip();
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				m_Target->PopLayer();
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -86,8 +86,8 @@ private:
 | 
			
		||||
	bool BeginTargetDraw();
 | 
			
		||||
	void EndTargetDraw();
 | 
			
		||||
 | 
			
		||||
	// Retrieves current GDI+ transform (if any) and converts to a D2D Matrix
 | 
			
		||||
	D2D1_MATRIX_3X2_F GetCurrentTransform();
 | 
			
		||||
	// Sets the |m_Target| transformation to be equal to that of |m_GdipGraphics|.
 | 
			
		||||
	void UpdateTargetTransform();
 | 
			
		||||
 | 
			
		||||
	Microsoft::WRL::ComPtr<ID2D1RenderTarget> m_Target;
 | 
			
		||||
	Util::WICBitmapDIB m_Bitmap;
 | 
			
		||||
@@ -98,6 +98,9 @@ private:
 | 
			
		||||
 | 
			
		||||
	bool m_TextAntiAliasing;
 | 
			
		||||
 | 
			
		||||
	// |true| if PushAxisAlignedClip()/PopAxisAlignedClip() can be used.
 | 
			
		||||
	bool m_CanUseAxisAlignClip;
 | 
			
		||||
 | 
			
		||||
	static UINT c_Instances;
 | 
			
		||||
	static Microsoft::WRL::ComPtr<ID2D1Factory1> c_D2DFactory;
 | 
			
		||||
	static Microsoft::WRL::ComPtr<IDWriteFactory1> c_DWFactory;
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,8 @@ namespace Gfx {
 | 
			
		||||
 | 
			
		||||
TextFormatD2D::TextFormatD2D() :
 | 
			
		||||
	m_ExtraHeight(),
 | 
			
		||||
	m_LineGap()
 | 
			
		||||
	m_LineGap(),
 | 
			
		||||
	m_Trimming()
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -297,6 +298,7 @@ DWRITE_TEXT_METRICS TextFormatD2D::GetMetrics(
 | 
			
		||||
 | 
			
		||||
void TextFormatD2D::SetTrimming(bool trim)
 | 
			
		||||
{
 | 
			
		||||
	m_Trimming = trim;
 | 
			
		||||
	IDWriteInlineObject* inlineObject = nullptr;
 | 
			
		||||
	DWRITE_TRIMMING trimming = {};
 | 
			
		||||
	DWRITE_WORD_WRAPPING wordWrapping = DWRITE_WORD_WRAPPING_NO_WRAP;
 | 
			
		||||
 
 | 
			
		||||
@@ -70,6 +70,9 @@ private:
 | 
			
		||||
	// Used to emulate GDI+ behaviour.
 | 
			
		||||
	float m_ExtraHeight;
 | 
			
		||||
	float m_LineGap;
 | 
			
		||||
 | 
			
		||||
	// Contains the value passed to the last call of of SetTrimming().
 | 
			
		||||
	bool m_Trimming;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
}  // namespace Gfx
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user