diff --git a/Common/Gfx/Canvas.cpp b/Common/Gfx/Canvas.cpp index b2fe0c58..a1efd504 100644 --- a/Common/Gfx/Canvas.cpp +++ b/Common/Gfx/Canvas.cpp @@ -17,6 +17,9 @@ */ #include "Canvas.h" +#include "CanvasD2D.h" +#include "CanvasGDIP.h" +#include "../Platform.h" namespace Gfx { @@ -31,6 +34,34 @@ Canvas::~Canvas() { } +Canvas* Canvas::Create(Renderer renderer) +{ + if (renderer == Renderer::GDIP) + { + return new CanvasGDIP(); + } + else if (renderer == Renderer::D2D && Platform::IsAtLeastWin7()) + { + if (CanvasD2D::Initialize()) + { + return new CanvasD2D(); + } + + CanvasD2D::Finalize(); + } + else if (renderer == Renderer::PreferD2D) + { + if (Canvas* canvas = Create(Renderer::D2D)) + { + return canvas; + } + + return Create(Renderer::GDIP); + } + + return nullptr; +}; + void Canvas::Resize(int w, int h) { m_W = w; diff --git a/Common/Gfx/Canvas.h b/Common/Gfx/Canvas.h index 9f3f50c4..8f3cb7d1 100644 --- a/Common/Gfx/Canvas.h +++ b/Common/Gfx/Canvas.h @@ -26,12 +26,24 @@ namespace Gfx { +enum class Renderer +{ + GDIP, + D2D, + + // Attempts to use D2D. If D2D is not available, fallbacks to use GDI+. + PreferD2D +}; + // Provides methods for drawing text, bitmaps, etc. class __declspec(novtable) Canvas { public: virtual ~Canvas(); + // Creates the canvas using the specified rendering engine. May return nullptr. + static Canvas* Create(Renderer renderer); + int GetW() const { return m_W; } int GetH() const { return m_H; } diff --git a/Common/Gfx/CanvasD2D.cpp b/Common/Gfx/CanvasD2D.cpp index 52903fba..a29aba13 100644 --- a/Common/Gfx/CanvasD2D.cpp +++ b/Common/Gfx/CanvasD2D.cpp @@ -53,7 +53,6 @@ CanvasD2D::CanvasD2D() : Canvas(), m_Bitmap(), m_TextAntiAliasing(false) { - Initialize(); } CanvasD2D::~CanvasD2D() diff --git a/Common/Gfx/CanvasD2D.h b/Common/Gfx/CanvasD2D.h index 1c889355..bb15b4eb 100644 --- a/Common/Gfx/CanvasD2D.h +++ b/Common/Gfx/CanvasD2D.h @@ -38,9 +38,6 @@ namespace Gfx { class CanvasD2D : public Canvas { public: - CanvasD2D(); - ~CanvasD2D(); - virtual void Resize(int w, int h); virtual bool BeginDraw(); @@ -75,9 +72,12 @@ public: virtual void FillRectangle(Gdiplus::Rect& rect, const Gdiplus::SolidBrush& brush) override; private: + friend class Canvas; friend class FontCollectionD2D; friend class TextFormatD2D; + CanvasD2D(); + ~CanvasD2D(); CanvasD2D(const CanvasD2D& other) {} static bool Initialize(); diff --git a/Common/Gfx/CanvasGDIP.h b/Common/Gfx/CanvasGDIP.h index 4685969b..7205e2bf 100644 --- a/Common/Gfx/CanvasGDIP.h +++ b/Common/Gfx/CanvasGDIP.h @@ -32,9 +32,6 @@ namespace Gfx { class CanvasGDIP : public Canvas { public: - CanvasGDIP(); - ~CanvasGDIP(); - virtual void Resize(int w, int h); virtual bool BeginDraw(); @@ -69,6 +66,10 @@ public: virtual void FillRectangle(Gdiplus::Rect& rect, const Gdiplus::SolidBrush& brush) override; private: + friend class Canvas; + + CanvasGDIP(); + ~CanvasGDIP(); CanvasGDIP(const CanvasGDIP& other) {} void Dispose(); diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index 83580899..6940cb0c 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -37,8 +37,7 @@ #include "MeasureScript.h" #include "../Version.h" #include "../Common/PathUtil.h" -#include "../Common/Gfx/CanvasD2D.h" -#include "../Common/Gfx/CanvasGDIP.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; @@ -2078,8 +2077,7 @@ bool MeterWindow::ReadSkin() useD2D = 0!=m_Parser.ReadInt(L"Rainmeter", L"__UseD2D", useD2D ? 1 : 0); } - m_Canvas = (Platform::IsAtLeastWinVista() && useD2D) ? - (Gfx::Canvas*)new Gfx::CanvasD2D() : (Gfx::Canvas*)new Gfx::CanvasGDIP(); + m_Canvas = Gfx::Canvas::Create(useD2D ? Gfx::Renderer::PreferD2D : Gfx::Renderer::GDIP); // Gotta have some kind of buffer during initialization CreateDoubleBuffer(1, 1);