From ef1cf223a720166cf27fa93d940b0287caaa6451 Mon Sep 17 00:00:00 2001 From: Birunthan Mohanathas Date: Mon, 25 Mar 2013 17:42:18 +0200 Subject: [PATCH] Change to use Gfx rendering --- Library/Meter.cpp | 27 +-- Library/Meter.h | 2 +- Library/MeterBar.cpp | 41 ++-- Library/MeterBar.h | 2 +- Library/MeterBitmap.cpp | 13 +- Library/MeterBitmap.h | 2 +- Library/MeterButton.cpp | 9 +- Library/MeterButton.h | 2 +- Library/MeterHistogram.cpp | 9 +- Library/MeterHistogram.h | 2 +- Library/MeterImage.cpp | 34 +-- Library/MeterImage.h | 2 +- Library/MeterLine.cpp | 9 +- Library/MeterLine.h | 2 +- Library/MeterRotator.cpp | 9 +- Library/MeterRotator.h | 2 +- Library/MeterRoundLine.cpp | 9 +- Library/MeterRoundLine.h | 2 +- Library/MeterString.cpp | 465 ++++++------------------------------- Library/MeterString.h | 14 +- Library/MeterWindow.cpp | 131 ++++------- Library/MeterWindow.h | 20 +- 22 files changed, 226 insertions(+), 582 deletions(-) diff --git a/Library/Meter.cpp b/Library/Meter.cpp index 637827ae..145cf11a 100644 --- a/Library/Meter.cpp +++ b/Library/Meter.cpp @@ -30,6 +30,7 @@ #include "MeterButton.h" #include "Measure.h" #include "Rainmeter.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; @@ -638,23 +639,11 @@ void CMeter::UpdateToolTip() /* ** Draws the solid background & bevel if such are defined */ -bool CMeter::Draw(Graphics& graphics) +bool CMeter::Draw(Gfx::Canvas& canvas) { if (IsHidden()) return false; - graphics.SetInterpolationMode(InterpolationModeDefault); - graphics.SetCompositingQuality(CompositingQualityDefault); - - if (m_AntiAlias) - { - graphics.SetSmoothingMode(SmoothingModeHighQuality); - graphics.SetPixelOffsetMode(PixelOffsetModeHighQuality); - } - else - { - graphics.SetSmoothingMode(SmoothingModeNone); - graphics.SetPixelOffsetMode(PixelOffsetModeDefault); - } + canvas.SetAntiAliasing(m_AntiAlias); if (m_SolidColor.GetA() != 0 || m_SolidColor2.GetA() != 0) { @@ -666,10 +655,12 @@ bool CMeter::Draw(Graphics& graphics) if (m_SolidColor.GetValue() == m_SolidColor2.GetValue()) { SolidBrush solid(m_SolidColor); - graphics.FillRectangle(&solid, r); + canvas.FillRectangle(r, solid); } else { + Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext(); + if (!m_AntiAlias) { // Fix the tiling issue in some GradientAngle values @@ -683,11 +674,15 @@ bool CMeter::Draw(Graphics& graphics) { graphics.SetPixelOffsetMode(PixelOffsetModeDefault); } + + canvas.EndGdiplusContext(); } } if (m_SolidBevel != BEVELTYPE_NONE) { + Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext(); + int x = GetX(); int y = GetY(); @@ -706,6 +701,8 @@ bool CMeter::Draw(Graphics& graphics) // The bevel is drawn outside the meter Rect rect(x - 2, y - 2, m_W + 4, m_H + 4); DrawBevel(graphics, rect, light, dark); + + canvas.EndGdiplusContext(); } return true; diff --git a/Library/Meter.h b/Library/Meter.h index 987bb4fb..52883647 100644 --- a/Library/Meter.h +++ b/Library/Meter.h @@ -40,7 +40,7 @@ public: virtual void Initialize(); virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); virtual bool HasActiveTransition() { return false; } virtual int GetW() { return m_Hidden ? 0 : m_W; } diff --git a/Library/MeterBar.cpp b/Library/MeterBar.cpp index 4225d2db..42fdd583 100644 --- a/Library/MeterBar.cpp +++ b/Library/MeterBar.cpp @@ -22,6 +22,7 @@ #include "Error.h" #include "Litestep.h" #include "Rainmeter.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; @@ -160,9 +161,9 @@ bool CMeterBar::Update() ** Draws the meter on the double buffer ** */ -bool CMeterBar::Draw(Graphics& graphics) +bool CMeterBar::Draw(Gfx::Canvas& canvas) { - if (!CMeter::Draw(graphics)) return false; + if (!CMeter::Draw(canvas)) return false; int x = GetX(); int y = GetY(); @@ -183,28 +184,26 @@ bool CMeterBar::Draw(Graphics& graphics) if (m_Border > 0) { Rect r2(x, y, m_W, m_Border); - graphics.DrawImage(drawBitmap, r2, 0, 0, m_W, m_Border, UnitPixel); + canvas.DrawBitmap(drawBitmap, r2, Rect(0, 0, m_W, m_Border)); r2.Y = y + size + m_Border; - graphics.DrawImage(drawBitmap, r2, 0, m_H - m_Border, m_W, m_Border, UnitPixel); + canvas.DrawBitmap(drawBitmap, r2, Rect(0, m_H - m_Border, m_W, m_Border)); } - // Blit the image Rect r(x, y + m_Border, m_W, size); - graphics.DrawImage(drawBitmap, r, 0, m_Border, m_W, size, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(0, m_Border, m_W, size)); } else { if (m_Border > 0) { Rect r2(x, y + m_H - size - 2 * m_Border, m_W, m_Border); - graphics.DrawImage(drawBitmap, r2, 0, 0, m_W, m_Border, UnitPixel); + canvas.DrawBitmap(drawBitmap, r2, Rect(0, 0, m_W, m_Border)); r2.Y = y + m_H - m_Border; - graphics.DrawImage(drawBitmap, r2, 0, m_H - m_Border, m_W, m_Border, UnitPixel); + canvas.DrawBitmap(drawBitmap, r2, Rect(0, m_H - m_Border, m_W, m_Border)); } - // Blit the image Rect r(x, y + m_H - size - m_Border, m_W, size); - graphics.DrawImage(drawBitmap, r, 0, m_H - size - m_Border, m_W, size, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(0, m_H - size - m_Border, m_W, size)); } } else @@ -213,12 +212,12 @@ bool CMeterBar::Draw(Graphics& graphics) if (m_Flip) { Rect r(x, y, m_W, size); - graphics.FillRectangle(&brush, r); + canvas.FillRectangle(r, brush); } else { Rect r(x, y + m_H - size, m_W, size); - graphics.FillRectangle(&brush, r); + canvas.FillRectangle(r, brush); } } } @@ -236,28 +235,26 @@ bool CMeterBar::Draw(Graphics& graphics) if (m_Border > 0) { Rect r2(x + m_W - size - 2 * m_Border, y, m_Border, m_H); - graphics.DrawImage(drawBitmap, r2, 0, 0, m_Border, m_H, UnitPixel); + canvas.DrawBitmap(drawBitmap, r2, Rect(0, 0, m_Border, m_H)); r2.X = x + m_W - m_Border; - graphics.DrawImage(drawBitmap, r2, m_W - m_Border, 0, m_Border, m_H, UnitPixel); + canvas.DrawBitmap(drawBitmap, r2, Rect(m_W - m_Border, 0, m_Border, m_H)); } - // Blit the image Rect r(x + m_W - size - m_Border, y, size, m_H); - graphics.DrawImage(drawBitmap, r, m_W - size - m_Border, 0, size, m_H, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(m_W - size - m_Border, 0, size, m_H)); } else { if (m_Border > 0) { Rect r2(x, y, m_Border, m_H); - graphics.DrawImage(drawBitmap, r2, 0, 0, m_Border, m_H, UnitPixel); + canvas.DrawBitmap(drawBitmap, r2, Rect(0, 0, m_Border, m_H)); r2.X = x + size + m_Border; - graphics.DrawImage(drawBitmap, r2, m_W - m_Border, 0, m_Border, m_H, UnitPixel); + canvas.DrawBitmap(drawBitmap, r2, Rect(m_W - m_Border, 0, m_Border, m_H)); } - // Blit the image Rect r(x + m_Border, y, size, m_H); - graphics.DrawImage(drawBitmap, r, m_Border, 0, size, m_H, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(m_Border, 0, size, m_H)); } } else @@ -266,12 +263,12 @@ bool CMeterBar::Draw(Graphics& graphics) if (m_Flip) { Rect r(x + m_W - size, y, size, m_H); - graphics.FillRectangle(&brush, r); + canvas.FillRectangle(r, brush); } else { Rect r(x, y, size, m_H); - graphics.FillRectangle(&brush, r); + canvas.FillRectangle(r, brush); } } } diff --git a/Library/MeterBar.h b/Library/MeterBar.h index 48047aaf..59afc08d 100644 --- a/Library/MeterBar.h +++ b/Library/MeterBar.h @@ -32,7 +32,7 @@ public: virtual void Initialize(); virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); protected: virtual void ReadOptions(CConfigParser& parser, const WCHAR* section); diff --git a/Library/MeterBitmap.cpp b/Library/MeterBitmap.cpp index e6147a90..47029b17 100644 --- a/Library/MeterBitmap.cpp +++ b/Library/MeterBitmap.cpp @@ -22,6 +22,7 @@ #include "Error.h" #include "Rainmeter.h" #include "System.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; @@ -270,9 +271,9 @@ bool CMeterBitmap::HasActiveTransition() ** Draws the meter on the double buffer ** */ -bool CMeterBitmap::Draw(Graphics& graphics) +bool CMeterBitmap::Draw(Gfx::Canvas& canvas) { - if (!CMeter::Draw(graphics)) return false; + if (!CMeter::Draw(canvas)) return false; int newY, newX; @@ -336,8 +337,6 @@ bool CMeterBitmap::Draw(Graphics& graphics) { offset = offset - (m_W + m_Separation); - Rect r(x + offset, y, m_W, m_H); - int realFrames = (m_FrameCount / (m_TransitionFrameCount + 1)); int frame = (value % realFrames) * (m_TransitionFrameCount + 1); @@ -377,7 +376,7 @@ bool CMeterBitmap::Draw(Graphics& graphics) newY = 0; } - graphics.DrawImage(bitmap, r, newX, newY, m_W, m_H, UnitPixel); + canvas.DrawBitmap(bitmap, Rect(x + offset, y, m_W, m_H), Rect(newX, newY, m_W, m_H)); if (m_FrameCount == 1) { value /= 2; @@ -446,9 +445,7 @@ bool CMeterBitmap::Draw(Graphics& graphics) newY = 0; } - // Blit the image - Rect r(x, y, m_W, m_H); - graphics.DrawImage(bitmap, r, newX, newY, m_W, m_H, UnitPixel); + canvas.DrawBitmap(bitmap, Rect(x, y, m_W, m_H), Rect(newX, newY, m_W, m_H)); } return true; diff --git a/Library/MeterBitmap.h b/Library/MeterBitmap.h index 6df71fc6..e16323f2 100644 --- a/Library/MeterBitmap.h +++ b/Library/MeterBitmap.h @@ -34,7 +34,7 @@ public: virtual void Initialize(); virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); virtual bool HasActiveTransition(); protected: diff --git a/Library/MeterButton.cpp b/Library/MeterButton.cpp index 86001baa..b45afa3d 100644 --- a/Library/MeterButton.cpp +++ b/Library/MeterButton.cpp @@ -21,6 +21,7 @@ #include "Measure.h" #include "Rainmeter.h" #include "Error.h" +#include "../Common/Gfx/Canvas.h" extern CRainmeter* Rainmeter; @@ -181,18 +182,22 @@ bool CMeterButton::Update() ** Draws the meter on the double buffer ** */ -bool CMeterButton::Draw(Graphics& graphics) +bool CMeterButton::Draw(Gfx::Canvas& canvas) { - if (!CMeter::Draw(graphics)) return false; + if (!CMeter::Draw(canvas)) return false; if (m_Bitmaps[m_State] == NULL) return false; // Unable to continue + Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext(); + int x = GetX(); int y = GetY(); // Blit the image graphics.DrawCachedBitmap(m_Bitmaps[m_State], x, y); + canvas.EndGdiplusContext(); + return true; } diff --git a/Library/MeterButton.h b/Library/MeterButton.h index 567ec776..36276b11 100644 --- a/Library/MeterButton.h +++ b/Library/MeterButton.h @@ -34,7 +34,7 @@ public: virtual void Initialize(); virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); bool MouseMove(POINT pos); bool MouseUp(POINT pos, bool execute); diff --git a/Library/MeterHistogram.cpp b/Library/MeterHistogram.cpp index 3904f1ad..1488eb37 100644 --- a/Library/MeterHistogram.cpp +++ b/Library/MeterHistogram.cpp @@ -21,6 +21,7 @@ #include "Measure.h" #include "Error.h" #include "Rainmeter.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; @@ -410,12 +411,14 @@ bool CMeterHistogram::Update() ** Draws the meter on the double buffer ** */ -bool CMeterHistogram::Draw(Graphics& graphics) +bool CMeterHistogram::Draw(Gfx::Canvas& canvas) { - if (!CMeter::Draw(graphics) || + if (!CMeter::Draw(canvas) || (m_Measures.size() >= 1 && !m_PrimaryValues) || (m_Measures.size() >= 2 && !m_SecondaryValues)) return false; + Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext(); + CMeasure* secondaryMeasure = (m_Measures.size() >= 2) ? m_Measures[1] : NULL; GraphicsPath primaryPath; @@ -633,6 +636,8 @@ bool CMeterHistogram::Draw(Graphics& graphics) } } + canvas.EndGdiplusContext(); + return true; } diff --git a/Library/MeterHistogram.h b/Library/MeterHistogram.h index 6e8ac5ca..f3cc274f 100644 --- a/Library/MeterHistogram.h +++ b/Library/MeterHistogram.h @@ -32,7 +32,7 @@ public: virtual void Initialize(); virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); protected: virtual void ReadOptions(CConfigParser& parser, const WCHAR* section); diff --git a/Library/MeterImage.cpp b/Library/MeterImage.cpp index 49417232..e4d7d7b1 100644 --- a/Library/MeterImage.cpp +++ b/Library/MeterImage.cpp @@ -22,6 +22,7 @@ #include "Error.h" #include "Rainmeter.h" #include "System.h" +#include "../Common/Gfx/Canvas.h" extern CRainmeter* Rainmeter; @@ -212,9 +213,9 @@ bool CMeterImage::Update() ** Draws the meter on the double buffer ** */ -bool CMeterImage::Draw(Graphics& graphics) +bool CMeterImage::Draw(Gfx::Canvas& canvas) { - if (!CMeter::Draw(graphics)) return false; + if (!CMeter::Draw(canvas)) return false; if (m_Image.IsLoaded()) { @@ -235,16 +236,19 @@ bool CMeterImage::Draw(Graphics& graphics) if (drawW == imageW && drawH == imageH && m_ScaleMargins.left == 0 && m_ScaleMargins.top == 0 && m_ScaleMargins.right == 0 && m_ScaleMargins.bottom == 0) { - Rect r(x, y, drawW, drawH); - graphics.DrawImage(drawBitmap, r, 0, 0, imageW, imageH, UnitPixel); + canvas.DrawBitmap(drawBitmap, Rect(x, y, drawW, drawH), Rect(0, 0, imageW, imageH)); } else if (m_DrawMode == DRAWMODE_TILE) { + Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext(); + ImageAttributes imgAttr; imgAttr.SetWrapMode(WrapModeTile); Rect r(x, y, drawW, drawH); graphics.DrawImage(drawBitmap, r, 0, 0, drawW, drawH, UnitPixel, &imgAttr); + + canvas.EndGdiplusContext(); } else if (m_DrawMode == DRAWMODE_KEEPRATIO || m_DrawMode == DRAWMODE_KEEPRATIOANDCROP) { @@ -290,11 +294,11 @@ bool CMeterImage::Draw(Graphics& graphics) } Rect r(x, y, drawW, drawH); - graphics.DrawImage(drawBitmap, r, cropX, cropY, cropW, cropH, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(cropX, cropY, cropW, cropH)); } else { - const RECT m = m_ScaleMargins; + const RECT& m = m_ScaleMargins; if (m.top > 0) { @@ -302,18 +306,18 @@ bool CMeterImage::Draw(Graphics& graphics) { // Top-Left Rect r(x, y, m.left, m.top); - graphics.DrawImage(drawBitmap, r, 0, 0, m.left, m.top, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(0, 0, m.left, m.top)); } // Top Rect r(x + m.left, y, drawW - m.left - m.right, m.top); - graphics.DrawImage(drawBitmap, r, m.left, 0, imageW - m.left - m.right, m.top, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(m.left, 0, imageW - m.left - m.right, m.top)); if (m.right > 0) { // Top-Right Rect r(x + drawW - m.right, y, m.right, m.top); - graphics.DrawImage(drawBitmap, r, imageW - m.right, 0, m.right, m.top, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(imageW - m.right, 0, m.right, m.top)); } } @@ -321,18 +325,18 @@ bool CMeterImage::Draw(Graphics& graphics) { // Left Rect r(x, y + m.top, m.left, drawH - m.top - m.bottom); - graphics.DrawImage(drawBitmap, r, 0, m.top, m.left, imageH - m.top - m.bottom, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(0, m.top, m.left, imageH - m.top - m.bottom)); } // Center Rect r(x + m.left, y + m.top, drawW - m.left - m.right, drawH - m.top - m.bottom); - graphics.DrawImage(drawBitmap, r, m.left, m.top, imageW - m.left - m.right, imageH - m.top - m.bottom, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(m.left, m.top, imageW - m.left - m.right, imageH - m.top - m.bottom)); if (m.right > 0) { // Right Rect r(x + drawW - m.right, y + m.top, m.right, drawH - m.top - m.bottom); - graphics.DrawImage(drawBitmap, r, imageW - m.right, m.top, m.right, imageH - m.top - m.bottom, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(imageW - m.right, m.top, m.right, imageH - m.top - m.bottom)); } if (m.bottom > 0) @@ -341,18 +345,18 @@ bool CMeterImage::Draw(Graphics& graphics) { // Bottom-Left Rect r(x, y + drawH - m.bottom, m.left, m.bottom); - graphics.DrawImage(drawBitmap, r, 0, imageH - m.bottom, m.left, m.bottom, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(0, imageH - m.bottom, m.left, m.bottom)); } // Bottom Rect r(x + m.left, y + drawH - m.bottom, drawW - m.left - m.right, m.bottom); - graphics.DrawImage(drawBitmap, r, m.left, imageH - m.bottom, imageW - m.left - m.right, m.bottom, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(m.left, imageH - m.bottom, imageW - m.left - m.right, m.bottom)); if (m.right > 0) { // Bottom-Right Rect r(x + drawW - m.right, y + drawH - m.bottom, m.right, m.bottom); - graphics.DrawImage(drawBitmap, r, imageW - m.right, imageH - m.bottom, m.right, m.bottom, UnitPixel); + canvas.DrawBitmap(drawBitmap, r, Rect(imageW - m.right, imageH - m.bottom, m.right, m.bottom)); } } } diff --git a/Library/MeterImage.h b/Library/MeterImage.h index 45859aa8..ddb3682b 100644 --- a/Library/MeterImage.h +++ b/Library/MeterImage.h @@ -32,7 +32,7 @@ public: virtual void Initialize(); virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); protected: virtual void ReadOptions(CConfigParser& parser, const WCHAR* section); diff --git a/Library/MeterLine.cpp b/Library/MeterLine.cpp index 620d9415..6b85ba83 100644 --- a/Library/MeterLine.cpp +++ b/Library/MeterLine.cpp @@ -20,6 +20,7 @@ #include "MeterLine.h" #include "Measure.h" #include "Error.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; @@ -218,10 +219,12 @@ bool CMeterLine::Update() ** Draws the meter on the double buffer ** */ -bool CMeterLine::Draw(Graphics& graphics) +bool CMeterLine::Draw(Gfx::Canvas& canvas) { int maxSize = m_GraphHorizontalOrientation ? m_H : m_W; - if (!CMeter::Draw(graphics) || maxSize <= 0) return false; + if (!CMeter::Draw(canvas) || maxSize <= 0) return false; + + Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext(); double maxValue = 0.0; int counter = 0; @@ -429,6 +432,8 @@ bool CMeterLine::Draw(Graphics& graphics) } } + canvas.EndGdiplusContext(); + return true; } diff --git a/Library/MeterLine.h b/Library/MeterLine.h index b51e22ee..e7896488 100644 --- a/Library/MeterLine.h +++ b/Library/MeterLine.h @@ -31,7 +31,7 @@ public: virtual void Initialize(); virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); protected: virtual void ReadOptions(CConfigParser& parser, const WCHAR* section); diff --git a/Library/MeterRotator.cpp b/Library/MeterRotator.cpp index 868f81ae..3e5d833b 100644 --- a/Library/MeterRotator.cpp +++ b/Library/MeterRotator.cpp @@ -22,6 +22,7 @@ #include "Error.h" #include "Litestep.h" #include "Rainmeter.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; @@ -145,9 +146,11 @@ bool CMeterRotator::Update() ** Draws the meter on the double buffer ** */ -bool CMeterRotator::Draw(Graphics& graphics) +bool CMeterRotator::Draw(Gfx::Canvas& canvas) { - if (!CMeter::Draw(graphics)) return false; + if (!CMeter::Draw(canvas)) return false; + + Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext(); if (m_Image.IsLoaded()) { @@ -176,5 +179,7 @@ bool CMeterRotator::Draw(Graphics& graphics) graphics.ResetTransform(); } + canvas.EndGdiplusContext(); + return true; } diff --git a/Library/MeterRotator.h b/Library/MeterRotator.h index 77973c06..169b339f 100644 --- a/Library/MeterRotator.h +++ b/Library/MeterRotator.h @@ -32,7 +32,7 @@ public: virtual void Initialize(); virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); protected: virtual void ReadOptions(CConfigParser& parser, const WCHAR* section); diff --git a/Library/MeterRoundLine.cpp b/Library/MeterRoundLine.cpp index eeab2c0e..dbde0511 100644 --- a/Library/MeterRoundLine.cpp +++ b/Library/MeterRoundLine.cpp @@ -20,6 +20,7 @@ #include "MeterRoundLine.h" #include "Measure.h" #include "Error.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; @@ -116,9 +117,11 @@ bool CMeterRoundLine::Update() ** Draws the meter on the double buffer ** */ -bool CMeterRoundLine::Draw(Graphics& graphics) +bool CMeterRoundLine::Draw(Gfx::Canvas& canvas) { - if (!CMeter::Draw(graphics)) return false; + if (!CMeter::Draw(canvas)) return false; + + Gdiplus::Graphics& graphics = canvas.BeginGdiplusContext(); // Calculate the center of for the line int x = GetX(); @@ -164,6 +167,8 @@ bool CMeterRoundLine::Draw(Graphics& graphics) graphics.DrawLine(&pen, sx, sy, ex, ey); } + canvas.EndGdiplusContext(); + return true; } diff --git a/Library/MeterRoundLine.h b/Library/MeterRoundLine.h index dd50339f..ab7e0abd 100644 --- a/Library/MeterRoundLine.h +++ b/Library/MeterRoundLine.h @@ -30,7 +30,7 @@ public: virtual UINT GetTypeID() { return TypeID(); } virtual bool Update(); - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); protected: virtual void ReadOptions(CConfigParser& parser, const WCHAR* section); diff --git a/Library/MeterString.cpp b/Library/MeterString.cpp index fe294438..7c45d650 100644 --- a/Library/MeterString.cpp +++ b/Library/MeterString.cpp @@ -21,12 +21,10 @@ #include "Rainmeter.h" #include "Measure.h" #include "Error.h" +#include "../Common/Gfx/Canvas.h" using namespace Gdiplus; -std::unordered_map CMeterString::c_FontFamilies; -std::unordered_map CMeterString::c_Fonts; - #define PI (3.14159265f) #define CONVERT_TO_DEGREES(X) ((X) * (180.0f / PI)) @@ -69,7 +67,6 @@ CMeterString::CMeterString(CMeterWindow* meterWindow, const WCHAR* name) : CMete m_Color(Color::White), m_EffectColor(Color::Black), m_AutoScale(AUTOSCALE_OFF), - m_Align(ALIGN_LEFT), m_Style(NORMAL), m_Effect(EFFECT_NONE), m_Case(TEXTCASE_NONE), @@ -81,8 +78,7 @@ CMeterString::CMeterString(CMeterWindow* meterWindow, const WCHAR* name) : CMete m_NeedsClipping(false), m_ClipStringW(-1), m_ClipStringH(-1), - m_Font(), - m_FontFamily(), + m_TextFormat(meterWindow->GetCanvas().CreateTextFormat()), m_NumOfDecimals(-1), m_Angle() { @@ -94,6 +90,8 @@ CMeterString::CMeterString(CMeterWindow* meterWindow, const WCHAR* name) : CMete */ CMeterString::~CMeterString() { + delete m_TextFormat; + m_TextFormat = NULL; } /* @@ -106,25 +104,15 @@ int CMeterString::GetX(bool abs) if (!abs) { - switch (m_Align) + switch (m_TextFormat->GetHorizontalAlignment()) { - case ALIGN_CENTER: // Same as ALIGN_CENTERTOP - case ALIGN_CENTERBOTTOM: - case ALIGN_CENTERCENTER: + case Gfx::HorizontalAlignment::Center: x -= m_W / 2; break; - case ALIGN_RIGHT: // Same as ALIGN_RIGHTTOP - case ALIGN_RIGHTBOTTOM: - case ALIGN_RIGHTCENTER: + case Gfx::HorizontalAlignment::Right: x -= m_W; break; - - case ALIGN_LEFT: // Same as ALIGN_LEFTTOP - case ALIGN_LEFTBOTTOM: - case ALIGN_LEFTCENTER: - // This is already correct - break; } } @@ -141,17 +129,13 @@ int CMeterString::GetY(bool abs) if (!abs) { - switch (m_Align) + switch (m_TextFormat->GetVerticalAlignment()) { - case ALIGN_LEFTCENTER: - case ALIGN_RIGHTCENTER: - case ALIGN_CENTERCENTER: + case Gfx::VerticalAlignment::Center: y -= m_H / 2; break; - case ALIGN_LEFTBOTTOM: - case ALIGN_RIGHTBOTTOM: - case ALIGN_CENTERBOTTOM: + case Gfx::VerticalAlignment::Bottom: y -= m_H; break; } @@ -167,164 +151,12 @@ int CMeterString::GetY(bool abs) void CMeterString::Initialize() { CMeter::Initialize(); - - // Check if the font family is in the cache and use it - std::wstring cacheKey; - std::wstring systemFontFaceKey = FontFaceToString(m_FontFace, NULL); - std::unordered_map::const_iterator iter = c_FontFamilies.find(systemFontFaceKey); - if (iter != c_FontFamilies.end()) - { - m_FontFamily = (*iter).second; - cacheKey = systemFontFaceKey; - } - else - { - m_FontFamily = NULL; - PrivateFontCollection* collection = m_MeterWindow->GetPrivateFontCollection(); - std::wstring privateFontFaceKey; - - if (collection) - { - // Check if the private font family is in the cache and use it - privateFontFaceKey = FontFaceToString(m_FontFace, collection); - iter = c_FontFamilies.find(privateFontFaceKey); - if (iter != c_FontFamilies.end()) - { - m_FontFamily = (*iter).second; - cacheKey = privateFontFaceKey; - } - } - - if (m_FontFamily == NULL) // Not found in the cache - { - m_FontFamily = new FontFamily(m_FontFace.c_str()); - Status status = m_FontFamily->GetLastStatus(); - - if (Ok == status) - { - cacheKey = systemFontFaceKey; - } - else - { - delete m_FontFamily; - - // It couldn't find the font family - // Therefore we look in the privatefontcollection of this meters MeterWindow - if (collection) - { - m_FontFamily = new FontFamily(m_FontFace.c_str(), collection); - status = m_FontFamily->GetLastStatus(); - - if (Ok == status) - { - cacheKey = privateFontFaceKey; - } - } - else - { - m_FontFamily = NULL; - } - - // It couldn't find the font family: Log it. - if (Ok != status) - { - LogWithArgs(LOG_ERROR, L"Unable to load font: %s", m_FontFace.c_str()); - - delete m_FontFamily; - m_FontFamily = NULL; - - cacheKey = L"<>"; // set dummy key - } - } - - if (m_FontFamily) - { - // Cache - //LogWithArgs(LOG_DEBUG, L"FontFamilyCache-Add: %s", cacheKey.c_str()); - c_FontFamilies[cacheKey] = m_FontFamily; - } - } - } - - FontStyle style = FontStyleRegular; - - switch (m_Style) - { - case ITALIC: - style = FontStyleItalic; - break; - - case BOLD: - style = FontStyleBold; - break; - - case BOLDITALIC: - style = FontStyleBoldItalic; - break; - } - - // Adjust the font size with screen DPI - HDC dc = GetDC(0); - int dpi = GetDeviceCaps(dc, LOGPIXELSX); - ReleaseDC(0, dc); - - REAL size = (REAL)m_FontSize * (96.0f / (REAL)dpi); - - // Check if the font is in the cache and use it - cacheKey += L'-'; - cacheKey += FontPropertiesToString(size, style); - std::unordered_map::const_iterator iter2 = c_Fonts.find(cacheKey); - if (iter2 != c_Fonts.end()) - { - m_Font = (*iter2).second; - } - else - { - m_Font = NULL; - - if (m_FontSize != 0) - { - if (m_FontFamily) - { - m_Font = new Gdiplus::Font(m_FontFamily, size, style); - Status status = m_Font->GetLastStatus(); - - if (Ok != status) - { - if (FontStyleNotFound == status) - { - LogWithArgs(LOG_ERROR, L"Invalid StringStyle for font: %s", m_FontFace.c_str()); - } - else - { - LogWithArgs(LOG_ERROR, L"Invalid font: %s", m_FontFace.c_str()); - } - - delete m_Font; - m_Font = NULL; - } - } - - if (m_Font == NULL) - { - // Use default font ("Arial" or GenericSansSerif) - m_Font = new Gdiplus::Font(L"Arial", size, style); - if (Ok != m_Font->GetLastStatus()) - { - delete m_Font; - m_Font = NULL; - } - } - - if (m_Font) - { - // Cache - //LogWithArgs(LOG_DEBUG, L"FontCache-Add: %s", cacheKey.c_str()); - c_Fonts[cacheKey] = m_Font; - } - } - } + m_TextFormat->SetProperties( + m_FontFace.c_str(), + m_FontSize, + m_Style & BOLD, + m_Style & ITALIC); } /* @@ -409,46 +241,35 @@ void CMeterString::ReadOptions(CConfigParser& parser, const WCHAR* section) m_NoDecimals = (scale.find(L'.') == std::wstring::npos); m_Scale = parser.ParseDouble(scale.c_str(), 1); - const WCHAR* align = parser.ReadString(section, L"StringAlign", L"LEFT").c_str(); - if (_wcsicmp(align, L"LEFT") == 0 || _wcsicmp(align, L"LEFTTOP") == 0) + const WCHAR* hAlign = parser.ReadString(section, L"StringAlign", L"LEFT").c_str(); + const WCHAR* vAlign = NULL; + if (_wcsnicmp(hAlign, L"LEFT", 4) == 0) { - m_Align = ALIGN_LEFT; + m_TextFormat->SetHorizontalAlignment(Gfx::HorizontalAlignment::Left); + vAlign = hAlign + 4; } - else if (_wcsicmp(align, L"RIGHT") == 0 || _wcsicmp(align, L"RIGHTTOP") == 0) + else if (_wcsnicmp(hAlign, L"RIGHT", 5) == 0) { - m_Align = ALIGN_RIGHT; + m_TextFormat->SetHorizontalAlignment(Gfx::HorizontalAlignment::Right); + vAlign = hAlign + 5; } - else if (_wcsicmp(align, L"CENTER") == 0 || _wcsicmp(align, L"CENTERTOP") == 0) + else if (_wcsnicmp(hAlign, L"CENTER", 6) == 0) { - m_Align = ALIGN_CENTER; + m_TextFormat->SetHorizontalAlignment(Gfx::HorizontalAlignment::Center); + vAlign = hAlign + 6; } - else if (_wcsicmp(align, L"LEFTBOTTOM") == 0) + + if (!vAlign || _wcsicmp(vAlign, L"TOP") == 0) { - m_Align = ALIGN_LEFTBOTTOM; + m_TextFormat->SetVerticalAlignment(Gfx::VerticalAlignment::Top); } - else if (_wcsicmp(align, L"RIGHTBOTTOM") == 0) + else if (_wcsicmp(vAlign, L"BOTTOM") == 0) { - m_Align = ALIGN_RIGHTBOTTOM; + m_TextFormat->SetVerticalAlignment(Gfx::VerticalAlignment::Bottom); } - else if (_wcsicmp(align, L"CENTERBOTTOM") == 0) + else if (_wcsicmp(vAlign, L"CENTER") == 0) { - m_Align = ALIGN_CENTERBOTTOM; - } - else if (_wcsicmp(align, L"LEFTCENTER") == 0) - { - m_Align = ALIGN_LEFTCENTER; - } - else if (_wcsicmp(align, L"RIGHTCENTER") == 0) - { - m_Align = ALIGN_RIGHTCENTER; - } - else if (_wcsicmp(align, L"CENTERCENTER") == 0) - { - m_Align = ALIGN_CENTERCENTER; - } - else - { - LogWithArgs(LOG_ERROR, L"StringAlign=%s is not valid in [%s]", align, m_Name.c_str()); + m_TextFormat->SetVerticalAlignment(Gfx::VerticalAlignment::Center); } const WCHAR* stringCase = parser.ReadString(section, L"StringCase", L"NONE").c_str(); @@ -570,8 +391,7 @@ bool CMeterString::Update() { // Calculate the text size RectF rect; - Graphics graphics(m_MeterWindow->GetDoubleBuffer()); - if (DrawString(graphics, &rect)) + if (DrawString(m_MeterWindow->GetCanvas(), &rect)) { m_W = (int)rect.Width; m_H = (int)rect.Height; @@ -592,111 +412,45 @@ bool CMeterString::Update() ** Draws the meter on the double buffer ** */ -bool CMeterString::Draw(Graphics& graphics) +bool CMeterString::Draw(Gfx::Canvas& canvas) { - if (!CMeter::Draw(graphics)) return false; + if (!CMeter::Draw(canvas)) return false; - return DrawString(graphics, NULL); + return DrawString(canvas, NULL); } /* ** Draws the string or calculates it's size ** */ -bool CMeterString::DrawString(Graphics& graphics, RectF* rect) +bool CMeterString::DrawString(Gfx::Canvas& canvas, RectF* rect) { - if (m_Font == NULL) return false; + if (!m_TextFormat->IsInitialized()) return false; LPCWSTR string = m_String.c_str(); - int stringLen = (int)m_String.length(); + UINT stringLen = (UINT)m_String.length(); - StringFormat stringFormat; + canvas.SetTextAntiAliasing(m_AntiAlias); - if (m_AntiAlias) - { - graphics.SetTextRenderingHint(TextRenderingHintAntiAlias); - } - else - { - graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixelGridFit); - } + //CharacterRange range(0, stringLen); + //stringFormat.SetMeasurableCharacterRanges(1, &range); - switch (m_Align) - { - case ALIGN_CENTERCENTER: - stringFormat.SetAlignment(StringAlignmentCenter); - stringFormat.SetLineAlignment(StringAlignmentCenter); - break; - - case ALIGN_RIGHTCENTER: - stringFormat.SetAlignment(StringAlignmentFar); - stringFormat.SetLineAlignment(StringAlignmentCenter); - break; - - case ALIGN_LEFTCENTER: - stringFormat.SetAlignment(StringAlignmentNear); - stringFormat.SetLineAlignment(StringAlignmentCenter); - break; - - case ALIGN_CENTERBOTTOM: - stringFormat.SetAlignment(StringAlignmentCenter); - stringFormat.SetLineAlignment(StringAlignmentFar); - break; - - case ALIGN_RIGHTBOTTOM: - stringFormat.SetAlignment(StringAlignmentFar); - stringFormat.SetLineAlignment(StringAlignmentFar); - break; - - case ALIGN_LEFTBOTTOM: - stringFormat.SetAlignment(StringAlignmentNear); - stringFormat.SetLineAlignment(StringAlignmentFar); - break; - - case ALIGN_CENTER: // Same as CenterTop - stringFormat.SetAlignment(StringAlignmentCenter); - stringFormat.SetLineAlignment(StringAlignmentNear); - break; - - case ALIGN_RIGHT: // Same as RightTop - stringFormat.SetAlignment(StringAlignmentFar); - stringFormat.SetLineAlignment(StringAlignmentNear); - break; - - case ALIGN_LEFT: // Same as LeftTop - stringFormat.SetAlignment(StringAlignmentNear); - stringFormat.SetLineAlignment(StringAlignmentNear); - break; - } - - CharacterRange range(0, stringLen); - stringFormat.SetMeasurableCharacterRanges(1, &range); - - if (m_ClipType == CLIP_ON || (m_NeedsClipping && m_ClipType == CLIP_AUTO) || - m_ClipType == CLIP_AUTO && m_WDefined && m_HDefined) - { - stringFormat.SetTrimming(StringTrimmingEllipsisCharacter); - } - else - { - stringFormat.SetTrimming(StringTrimmingNone); - stringFormat.SetFormatFlags(StringFormatFlagsNoClip | StringFormatFlagsNoWrap); - } + m_TextFormat->SetTrimming( + m_ClipType == CLIP_ON || + (m_ClipType == CLIP_AUTO && (m_NeedsClipping || (m_WDefined && m_HDefined)))); REAL x = (REAL)GetX(); REAL y = (REAL)GetY(); if (rect) { - PointF pos(x, y); - Status status = graphics.MeasureString(string, stringLen, m_Font, pos, &stringFormat, rect); - - if (m_ClipType == CLIP_AUTO && status == Ok) + rect->X = x; + rect->Y = y;; + if (canvas.MeasureTextW(string, stringLen, *m_TextFormat, *rect) && + m_ClipType == CLIP_AUTO) { // Set initial clipping m_NeedsClipping = false; - stringFormat.SetTrimming(StringTrimmingNone); - stringFormat.SetFormatFlags(StringFormatFlagsNoClip); REAL w, h; bool updateSize = true; @@ -749,20 +503,6 @@ bool CMeterString::DrawString(Graphics& graphics, RectF* rect) updateSize = false; } - else if (m_ClipStringH == -1) - { - if (rect->Width > m_ClipStringW) - { - w = (REAL)m_ClipStringW; - m_NeedsClipping = true; - } - else - { - w = rect->Width; - } - - h = rect->Height; - } else { if (rect->Width > m_ClipStringW) @@ -781,12 +521,10 @@ bool CMeterString::DrawString(Graphics& graphics, RectF* rect) if (updateSize) { - int lines = 0; + UINT lines = 0; RectF layout(x, y, w, h); - - status = graphics.MeasureString(string, stringLen, m_Font, layout, &stringFormat, &layout, NULL, &lines); - - if (status == Ok && lines != 0) + if (canvas.MeasureTextLinesW(string, stringLen, *m_TextFormat, layout, lines) && + lines != 0) { rect->Width = w; rect->Height = layout.Height; @@ -806,9 +544,10 @@ bool CMeterString::DrawString(Graphics& graphics, RectF* rect) if (m_Angle != 0.0f) { - graphics.TranslateTransform((Gdiplus::REAL)CMeter::GetX(), y); - graphics.RotateTransform(CONVERT_TO_DEGREES(m_Angle)); - graphics.TranslateTransform(-(Gdiplus::REAL)CMeter::GetX(), -y); + // TODO FIXME + //graphics.TranslateTransform((Gdiplus::REAL)CMeter::GetX(), y); + //graphics.RotateTransform(CONVERT_TO_DEGREES(m_Angle)); + //graphics.TranslateTransform(-(Gdiplus::REAL)CMeter::GetX(), -y); } if (m_Effect != EFFECT_NONE) @@ -819,27 +558,28 @@ bool CMeterString::DrawString(Graphics& graphics, RectF* rect) if (m_Effect == EFFECT_SHADOW) { rcEffect.Offset(1, 1); - graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); + canvas.DrawTextW(string, (UINT)stringLen, *m_TextFormat, rcEffect, solidBrush); } else //if (m_Effect == EFFECT_BORDER) { rcEffect.Offset(0, 1); - graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); + canvas.DrawTextW(string, (UINT)stringLen, *m_TextFormat, rcEffect, solidBrush); rcEffect.Offset(1, -1); - graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); + canvas.DrawTextW(string, (UINT)stringLen, *m_TextFormat, rcEffect, solidBrush); rcEffect.Offset(-1, -1); - graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); + canvas.DrawTextW(string, (UINT)stringLen, *m_TextFormat, rcEffect, solidBrush); rcEffect.Offset(-1, 1); - graphics.DrawString(string, stringLen, m_Font, rcEffect, &stringFormat, &solidBrush); + canvas.DrawTextW(string, (UINT)stringLen, *m_TextFormat, rcEffect, solidBrush); } } SolidBrush solidBrush(m_Color); - graphics.DrawString(string, stringLen, m_Font, rcDest, &stringFormat, &solidBrush); + canvas.DrawTextW(string, (UINT)stringLen, *m_TextFormat, rcDest, solidBrush); if (m_Angle != 0.0f) { - graphics.ResetTransform(); + // TODO FIXME + //graphics.ResetTransform(); } } @@ -865,81 +605,6 @@ void CMeterString::BindMeasures(CConfigParser& parser, const WCHAR* section) */ void CMeterString::FreeFontCache(PrivateFontCollection* collection) { - std::wstring prefix; - - if (collection) - { - WCHAR buffer[32]; - size_t len = _snwprintf_s(buffer, _TRUNCATE, L"<%p>", collection); - - prefix.assign(buffer, len); - _wcsupr(&prefix[0]); - } - - std::unordered_map::iterator iter2 = c_Fonts.begin(); - while (iter2 != c_Fonts.end()) - { - if (collection == NULL || wcsncmp((*iter2).first.c_str(), prefix.c_str(), prefix.length()) == 0) - { - //LogWithArgs(LOG_DEBUG, L"FontCache-Remove: %s", (*iter2).first.c_str()); - delete (*iter2).second; - - if (collection) - { - c_Fonts.erase(iter2++); - continue; - } - } - ++iter2; - } - if (collection == NULL) c_Fonts.clear(); - - std::unordered_map::iterator iter = c_FontFamilies.begin(); - while (iter != c_FontFamilies.end()) - { - if (collection == NULL || wcsncmp((*iter).first.c_str(), prefix.c_str(), prefix.length()) == 0) - { - //LogWithArgs(LOG_DEBUG, L"FontFamilyCache-Remove: %s", (*iter).first.c_str()); - delete (*iter).second; - - if (collection) - { - c_FontFamilies.erase(iter++); - continue; - } - } - ++iter; - } - if (collection == NULL) c_FontFamilies.clear(); -} - -/* -** Static helper to convert font name to a string so it can be used as a key for the cache map. -** -*/ -std::wstring CMeterString::FontFaceToString(const std::wstring& fontFace, PrivateFontCollection* collection) -{ - WCHAR buffer[32]; - size_t len = _snwprintf_s(buffer, _TRUNCATE, L"<%p>", collection); - - std::wstring strTmp; - strTmp.reserve(len + fontFace.size()); - strTmp.assign(buffer, len); - strTmp += fontFace; - _wcsupr(&strTmp[0]); - return strTmp; -} - -/* -** Static helper to convert font properties to a string so it can be used as a key for the cache map. -** -*/ -std::wstring CMeterString::FontPropertiesToString(REAL size, FontStyle style) -{ - WCHAR buffer[64]; - size_t len = _snwprintf_s(buffer, _TRUNCATE, L"%.1f-%i", size, (int)style); - - return std::wstring(buffer, len); } /* diff --git a/Library/MeterString.h b/Library/MeterString.h index e6b677a9..9324210f 100644 --- a/Library/MeterString.h +++ b/Library/MeterString.h @@ -37,7 +37,7 @@ public: virtual void Initialize(); virtual bool Update(); void SetText(const WCHAR* text) { m_Text = text; } - virtual bool Draw(Gdiplus::Graphics& graphics); + virtual bool Draw(Gfx::Canvas& canvas); Gdiplus::RectF GetRect() { return m_Rect; } static void FreeFontCache(Gdiplus::PrivateFontCollection* collection = NULL); @@ -83,7 +83,7 @@ private: CLIP_AUTO }; - bool DrawString(Gdiplus::Graphics& graphics, Gdiplus::RectF* rect); + bool DrawString(Gfx::Canvas& canvas, Gdiplus::RectF* rect); Gdiplus::Color m_Color; Gdiplus::Color m_EffectColor; @@ -92,7 +92,6 @@ private: std::wstring m_Text; std::wstring m_FontFace; AUTOSCALE m_AutoScale; - METER_ALIGNMENT m_Align; TEXTSTYLE m_Style; TEXTEFFECT m_Effect; TEXTCASE m_Case; @@ -104,19 +103,12 @@ private: bool m_NeedsClipping; int m_ClipStringW; int m_ClipStringH; - Gdiplus::Font* m_Font; - Gdiplus::FontFamily* m_FontFamily; + Gfx::TextFormat* m_TextFormat; int m_NumOfDecimals; Gdiplus::REAL m_Angle; Gdiplus::RectF m_Rect; std::wstring m_String; - - static std::wstring FontFaceToString(const std::wstring& fontFace, Gdiplus::PrivateFontCollection* collection); - static std::wstring FontPropertiesToString(Gdiplus::REAL size, Gdiplus::FontStyle style); - - static std::unordered_map c_FontFamilies; // Cache for the font families - static std::unordered_map c_Fonts; // Cache for the fonts }; #endif diff --git a/Library/MeterWindow.cpp b/Library/MeterWindow.cpp index ea9882a2..b35c9477 100644 --- a/Library/MeterWindow.cpp +++ b/Library/MeterWindow.cpp @@ -36,6 +36,8 @@ #include "TintedImage.h" #include "MeasureScript.h" #include "../Version.h" +#include "../Common/Gfx/CanvasGDIP.h" +#include "../Common/Gfx/CanvasD2D.h" using namespace Gdiplus; @@ -74,11 +76,7 @@ extern CRainmeter* Rainmeter; ** */ CMeterWindow::CMeterWindow(const std::wstring& folderPath, const std::wstring& file) : m_FolderPath(folderPath), m_FileName(file), - m_DoubleBuffer(), - m_DIBSectionBuffer(), - m_DIBSectionBufferPixels(), - m_DIBSectionBufferW(), - m_DIBSectionBufferH(), + m_Canvas(), m_Background(), m_BackgroundSize(), m_Window(), @@ -145,6 +143,9 @@ CMeterWindow::CMeterWindow(const std::wstring& folderPath, const std::wstring& f m_FontCollection(), m_ToolTipHidden(false) { + m_Canvas = Platform::IsAtLeastWinVista() ? + (Gfx::Canvas*)new Gfx::CanvasD2D() : (Gfx::Canvas*)new Gfx::CanvasGDIP(); + if (!c_DwmInstance && Platform::IsAtLeastWinVista()) { c_DwmInstance = CSystem::RmLoadLibrary(L"dwmapi.dll"); @@ -201,6 +202,9 @@ CMeterWindow::~CMeterWindow() c_DwmIsCompositionEnabled = NULL; } } + + delete m_Canvas; + m_Canvas = NULL; } /* @@ -260,16 +264,6 @@ void CMeterWindow::Dispose(bool refresh) if (!refresh) { - // Destroy double buffers and window - delete m_DoubleBuffer; - m_DoubleBuffer = NULL; - - if (m_DIBSectionBuffer) - { - DeleteObject(m_DIBSectionBuffer); - m_DIBSectionBuffer = NULL; - } - if (m_Window) { DestroyWindow(m_Window); @@ -2439,25 +2433,7 @@ bool CMeterWindow::ResizeWindow(bool reset) */ void CMeterWindow::CreateDoubleBuffer(int cx, int cy) { - // Create DIBSection bitmap - BITMAPV4HEADER bmiHeader = {sizeof(BITMAPV4HEADER)}; - bmiHeader.bV4Width = cx; - bmiHeader.bV4Height = -cy; // top-down DIB - bmiHeader.bV4Planes = 1; - bmiHeader.bV4BitCount = 32; - bmiHeader.bV4V4Compression = BI_BITFIELDS; - bmiHeader.bV4RedMask = 0x00FF0000; - bmiHeader.bV4GreenMask = 0x0000FF00; - bmiHeader.bV4BlueMask = 0x000000FF; - bmiHeader.bV4AlphaMask = 0xFF000000; - - m_DIBSectionBuffer = CreateDIBSection(NULL, (BITMAPINFO*)&bmiHeader, DIB_RGB_COLORS, (void**)&m_DIBSectionBufferPixels, NULL, 0); - - // Create GDI+ bitmap from DIBSection's pixels - m_DoubleBuffer = new Bitmap(cx, cy, cx * 4, PixelFormat32bppPARGB, (BYTE*)m_DIBSectionBufferPixels); - - m_DIBSectionBufferW = cx; - m_DIBSectionBufferH = cy; + m_Canvas->Resize(cx, cy); } /* @@ -2484,29 +2460,26 @@ void CMeterWindow::Redraw() cy = 1; } - if (cx != m_DIBSectionBufferW || cy != m_DIBSectionBufferH || m_DIBSectionBufferPixels == NULL) + if (cx != m_Canvas->GetW() || cy != m_Canvas->GetH()) { - delete m_DoubleBuffer; - if (m_DIBSectionBuffer) DeleteObject(m_DIBSectionBuffer); - m_DIBSectionBufferPixels = NULL; - CreateDoubleBuffer(cx, cy); } - else - { - memset(m_DIBSectionBufferPixels, 0, cx * cy * 4); - } } + if (!m_Canvas->BeginDraw()) + { + return; + } + + m_Canvas->Clear(); + if (m_WindowW != 0 && m_WindowH != 0) { - Graphics graphics(m_DoubleBuffer); - if (m_Background) { - // Copy the background over the doublebuffer - Rect r(0, 0, m_WindowW, m_WindowH); - graphics.DrawImage(m_Background, r, 0, 0, m_Background->GetWidth(), m_Background->GetHeight(), UnitPixel); + const Rect dst(0, 0, m_WindowW, m_WindowH); + const Rect src(0, 0, m_Background->GetWidth(), m_Background->GetHeight()); + m_Canvas->DrawBitmap(m_Background, dst, src); } else if (m_BackgroundMode == BGMODE_SOLID) { @@ -2517,12 +2490,14 @@ void CMeterWindow::Redraw() { if (m_SolidColor.GetValue() == m_SolidColor2.GetValue()) { - graphics.Clear(m_SolidColor); + m_Canvas->Clear(m_SolidColor); } else { + Gdiplus::Graphics& graphics = m_Canvas->BeginGdiplusContext(); LinearGradientBrush gradient(r, m_SolidColor, m_SolidColor2, m_SolidAngle, TRUE); graphics.FillRectangle(&gradient, r); + m_Canvas->EndGdiplusContext(); } } @@ -2540,7 +2515,9 @@ void CMeterWindow::Redraw() Pen light(lightColor); Pen dark(darkColor); + Gdiplus::Graphics& graphics = m_Canvas->BeginGdiplusContext(); CMeter::DrawBevel(graphics, r, light, dark); + m_Canvas->EndGdiplusContext(); } } @@ -2551,22 +2528,24 @@ void CMeterWindow::Redraw() const Matrix* matrix = (*j)->GetTransformationMatrix(); if (matrix && !matrix->IsIdentity()) { - // Change the world matrix - graphics.SetTransform(matrix); + // TODO FIXME: Change the world matrix + //m_Canvas->GetGraphics().SetTransform(matrix); - (*j)->Draw(graphics); + (*j)->Draw(*m_Canvas); - // Set back to identity matrix - graphics.ResetTransform(); + // TODO FIXME: Set back to identity matrix + //m_Canvas->GetGraphics().ResetTransform(); } else { - (*j)->Draw(graphics); + (*j)->Draw(*m_Canvas); } } } - UpdateWindow(m_TransparencyValue, false); + UpdateWindow(m_TransparencyValue, false, true); + + m_Canvas->EndDraw(); } /* @@ -2738,7 +2717,7 @@ void CMeterWindow::Update(bool refresh) ** Updates the window contents ** */ -void CMeterWindow::UpdateWindow(int alpha, bool reset) +void CMeterWindow::UpdateWindow(int alpha, bool reset, bool canvasBeginDrawCalled) { if (reset) { @@ -2746,25 +2725,25 @@ void CMeterWindow::UpdateWindow(int alpha, bool reset) } BLENDFUNCTION blendPixelFunction = {AC_SRC_OVER, 0, alpha, AC_SRC_ALPHA}; - POINT ptWindowScreenPosition = {m_ScreenX, m_ScreenY}; POINT ptSrc = {0, 0}; - SIZE szWindow = {m_DIBSectionBufferW, m_DIBSectionBufferH}; + SIZE szWindow = {m_WindowW, m_WindowH}; - HDC dcScreen = GetDC(0); - HDC dcMemory = CreateCompatibleDC(dcScreen); - SelectObject(dcMemory, m_DIBSectionBuffer); + if (!canvasBeginDrawCalled) m_Canvas->BeginDraw(); - BOOL ret = UpdateLayeredWindow(m_Window, dcScreen, &ptWindowScreenPosition, &szWindow, dcMemory, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA); - if (!ret) + HDC dcScreen = GetDC(NULL); + HDC dcMemory = m_Canvas->GetDC(); + if (!UpdateLayeredWindow(m_Window, dcScreen, NULL, &szWindow, dcMemory, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA)) { - // Retry after resetting WS_EX_LAYERED flag + // Retry after resetting WS_EX_LAYERED flag. RemoveWindowExStyle(WS_EX_LAYERED); AddWindowExStyle(WS_EX_LAYERED); - UpdateLayeredWindow(m_Window, dcScreen, &ptWindowScreenPosition, &szWindow, dcMemory, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA); + UpdateLayeredWindow(m_Window, dcScreen, NULL, &szWindow, dcMemory, &ptSrc, 0, &blendPixelFunction, ULW_ALPHA); } - ReleaseDC(0, dcScreen); - DeleteDC(dcMemory); + ReleaseDC(NULL, dcScreen); + m_Canvas->ReleaseDC(dcMemory); + + if (!canvasBeginDrawCalled) m_Canvas->EndDraw(); m_TransparencyValue = alpha; } @@ -3066,21 +3045,7 @@ HWND CMeterWindow::GetWindowFromPoint(POINT pos) */ bool CMeterWindow::HitTest(int x, int y) { - if (x >= 0 && y >= 0 && x < m_WindowW && y < m_WindowH) - { - // Check transparent pixels - if (m_DIBSectionBufferPixels) - { - DWORD pixel = m_DIBSectionBufferPixels[y * m_WindowW + x]; // top-down DIB - return ((pixel & 0xFF000000) != 0); - } - else - { - return true; - } - } - - return false; + return m_Canvas->IsTransparentPixel(x, y); } /* diff --git a/Library/MeterWindow.h b/Library/MeterWindow.h index b38f1ec3..cb87ba1d 100644 --- a/Library/MeterWindow.h +++ b/Library/MeterWindow.h @@ -20,7 +20,6 @@ #define __METERWINDOW_H__ #include -#include #include #include #include @@ -152,6 +151,13 @@ class CRainmeter; class CMeasure; class CMeter; +namespace Gfx { + +class Canvas; +class TextFormat; + +} // namespace Gfx + class CMeterWindow : public CGroup { public: @@ -194,7 +200,7 @@ public: void SetResizeWindowMode(RESIZEMODE mode) { if (m_ResizeWindow != RESIZEMODE_RESET || mode != RESIZEMODE_CHECK) m_ResizeWindow = mode; } - Gdiplus::Bitmap* GetDoubleBuffer() { return m_DoubleBuffer; } + Gfx::Canvas& GetCanvas() { return *m_Canvas; } HWND GetWindow() { return m_Window; } CConfigParser& GetParser() { return m_Parser; } @@ -327,7 +333,7 @@ private: bool UpdateMeasure(CMeasure* measure, bool force); bool UpdateMeter(CMeter* meter, bool& bActiveTransition, bool force); void Update(bool refresh); - void UpdateWindow(int alpha, bool reset); + void UpdateWindow(int alpha, bool reset, bool canvasBeginDrawCalled = false); void ReadOptions(); void WriteOptions(INT setting = OPTION_ALL); bool ReadSkin(); @@ -360,13 +366,9 @@ private: void Dispose(bool refresh); void CreateDoubleBuffer(int cx, int cy); - CConfigParser m_Parser; + Gfx::Canvas* m_Canvas; - Gdiplus::Bitmap* m_DoubleBuffer; - HBITMAP m_DIBSectionBuffer; - LPDWORD m_DIBSectionBufferPixels; - int m_DIBSectionBufferW; - int m_DIBSectionBufferH; + CConfigParser m_Parser; Gdiplus::Bitmap* m_Background; SIZE m_BackgroundSize;