https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2f856f6f0d1a2053deec61fb8fa282a80b56210d

commit 2f856f6f0d1a2053deec61fb8fa282a80b56210d
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Fri Jun 16 08:05:23 2023 +0900
Commit:     Katayama Hirofumi MZ <[email protected]>
CommitDate: Fri Jun 16 08:05:23 2023 +0900

    [MSPAINT] Add CachedBufferDIB function and use it
    
    We do caching on buffering paint.
    This will improve performance a little.
    CORE-18867
---
 base/applications/mspaint/canvas.cpp    | 13 ++++++++++---
 base/applications/mspaint/canvas.h      |  2 ++
 base/applications/mspaint/dib.cpp       | 20 ++++++++++++++++++++
 base/applications/mspaint/dib.h         |  1 +
 base/applications/mspaint/miniature.cpp | 16 ++++++++++++++--
 base/applications/mspaint/miniature.h   |  7 ++++++-
 base/applications/mspaint/palette.cpp   | 17 ++++++++++++++---
 base/applications/mspaint/palette.h     |  6 ++++++
 8 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/base/applications/mspaint/canvas.cpp 
b/base/applications/mspaint/canvas.cpp
index b83a692ab7c..c36bd76faed 100644
--- a/base/applications/mspaint/canvas.cpp
+++ b/base/applications/mspaint/canvas.cpp
@@ -17,10 +17,17 @@ CCanvasWindow::CCanvasWindow()
     , m_hitSelection(HIT_NONE)
     , m_whereHit(HIT_NONE)
     , m_ptOrig { -1, -1 }
+    , m_hbmCached(NULL)
 {
     ::SetRectEmpty(&m_rcNew);
 }
 
+CCanvasWindow::~CCanvasWindow()
+{
+    if (m_hbmCached)
+        ::DeleteObject(m_hbmCached);
+}
+
 VOID CCanvasWindow::drawZoomFrame(INT mouseX, INT mouseY)
 {
     // FIXME: Draw the border of the area that is to be zoomed in
@@ -95,8 +102,8 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& 
rcPaint)
 {
     // We use a memory bitmap to reduce flickering
     HDC hdcMem = ::CreateCompatibleDC(hDC);
-    HBITMAP hbm = ::CreateCompatibleBitmap(hDC, rcClient.right, 
rcClient.bottom);
-    HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbm);
+    m_hbmCached = CachedBufferDIB(m_hbmCached, rcClient.right, 
rcClient.bottom);
+    HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmCached);
 
     // Fill the background
     ::FillRect(hdcMem, &rcPaint, (HBRUSH)(COLOR_APPWORKSPACE + 1));
@@ -164,7 +171,7 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& 
rcPaint)
              rcPaint.right - rcPaint.left, rcPaint.bottom - rcPaint.top,
              hdcMem, rcPaint.left, rcPaint.top, SRCCOPY);
 
-    ::DeleteObject(::SelectObject(hdcMem, hbmOld));
+    ::SelectObject(hdcMem, hbmOld);
     ::DeleteDC(hdcMem);
 }
 
diff --git a/base/applications/mspaint/canvas.h 
b/base/applications/mspaint/canvas.h
index 53d5fa1acc1..d76b3761b9c 100644
--- a/base/applications/mspaint/canvas.h
+++ b/base/applications/mspaint/canvas.h
@@ -36,6 +36,7 @@ public:
     END_MSG_MAP()
 
     CCanvasWindow();
+    virtual ~CCanvasWindow();
 
     BOOL m_drawing;
 
@@ -54,6 +55,7 @@ protected:
     CANVAS_HITTEST m_hitSelection;
     CANVAS_HITTEST m_whereHit;
     POINT m_ptOrig; // The origin of drag start
+    HBITMAP m_hbmCached; // The cached buffer bitmap
     CRect m_rcNew;
 
     CANVAS_HITTEST CanvasHitTest(POINT pt);
diff --git a/base/applications/mspaint/dib.cpp 
b/base/applications/mspaint/dib.cpp
index 3d74403cdda..1e7477c661e 100644
--- a/base/applications/mspaint/dib.cpp
+++ b/base/applications/mspaint/dib.cpp
@@ -59,6 +59,26 @@ CreateColorDIB(int width, int height, COLORREF rgb)
     return ret;
 }
 
+HBITMAP CachedBufferDIB(HBITMAP hbm, int minimalWidth, int minimalHeight)
+{
+    if (minimalWidth <= 0)
+        minimalWidth = 1;
+    if (minimalHeight <= 0)
+        minimalHeight = 1;
+
+    BITMAP bm;
+    if (!GetObject(hbm, sizeof(bm), &bm))
+        hbm = NULL;
+
+    if (hbm && minimalWidth <= bm.bmWidth && minimalHeight <= bm.bmHeight)
+        return hbm;
+
+    if (hbm)
+        DeleteObject(hbm);
+
+    return CreateDIBWithProperties((minimalWidth * 3) / 2, (minimalHeight * 3) 
/ 2);
+}
+
 int
 GetDIBWidth(HBITMAP hBitmap)
 {
diff --git a/base/applications/mspaint/dib.h b/base/applications/mspaint/dib.h
index cc873913114..f4043d83ca3 100644
--- a/base/applications/mspaint/dib.h
+++ b/base/applications/mspaint/dib.h
@@ -10,6 +10,7 @@
 
 HBITMAP CreateDIBWithProperties(int width, int height);
 HBITMAP CreateColorDIB(int width, int height, COLORREF rgb);
+HBITMAP CachedBufferDIB(HBITMAP hbm, int minimalWidth, int minimalHeight);
 
 static inline HBITMAP CopyDIBImage(HBITMAP hbm, INT cx = 0, INT cy = 0)
 {
diff --git a/base/applications/mspaint/miniature.cpp 
b/base/applications/mspaint/miniature.cpp
index 223b38e176a..b354de983b1 100644
--- a/base/applications/mspaint/miniature.cpp
+++ b/base/applications/mspaint/miniature.cpp
@@ -14,6 +14,17 @@ CMiniatureWindow miniature;
 
 /* FUNCTIONS ********************************************************/
 
+CMiniatureWindow::CMiniatureWindow()
+    : m_hbmCached(NULL)
+{
+}
+
+CMiniatureWindow::~CMiniatureWindow()
+{
+    if (m_hbmCached)
+        ::DeleteObject(m_hbmCached);
+}
+
 HWND CMiniatureWindow::DoCreate(HWND hwndParent)
 {
     if (m_hWnd)
@@ -82,7 +93,8 @@ LRESULT CMiniatureWindow::OnPaint(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL&
 
     // Use a memory bitmap to reduce flickering
     HDC hdcMem = ::CreateCompatibleDC(hDC);
-    HGDIOBJ hbmOld = ::SelectObject(hdcMem, ::CreateCompatibleBitmap(hDC, 
rc.right, rc.bottom));
+    m_hbmCached = CachedBufferDIB(m_hbmCached, rc.right, rc.bottom);
+    HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmCached);
 
     // FIXME: Consider aspect ratio
 
@@ -100,7 +112,7 @@ LRESULT CMiniatureWindow::OnPaint(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL&
     ::BitBlt(hDC, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY);
 
     // Clean up
-    ::DeleteObject(::SelectObject(hdcMem, hbmOld));
+    ::SelectObject(hdcMem, hbmOld);
     ::DeleteDC(hdcMem);
 
     EndPaint(&ps);
diff --git a/base/applications/mspaint/miniature.h 
b/base/applications/mspaint/miniature.h
index e1ec6657f88..9c01f1b9091 100644
--- a/base/applications/mspaint/miniature.h
+++ b/base/applications/mspaint/miniature.h
@@ -24,9 +24,14 @@ public:
         MESSAGE_HANDLER(WM_GETMINMAXINFO, OnGetMinMaxInfo)
     END_MSG_MAP()
 
+    CMiniatureWindow();
+    virtual ~CMiniatureWindow();
+
     HWND DoCreate(HWND hwndParent);
 
-private:
+protected:
+    HBITMAP m_hbmCached; // Cached buffer bitmap
+
     LRESULT OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
     LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
     LRESULT OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
diff --git a/base/applications/mspaint/palette.cpp 
b/base/applications/mspaint/palette.cpp
index acd5552defc..f268a982f49 100644
--- a/base/applications/mspaint/palette.cpp
+++ b/base/applications/mspaint/palette.cpp
@@ -21,6 +21,17 @@ CPaletteWindow paletteWindow;
 
 /* FUNCTIONS ********************************************************/
 
+CPaletteWindow::CPaletteWindow()
+    : m_hbmCached(NULL)
+{
+}
+
+CPaletteWindow::~CPaletteWindow()
+{
+    if (m_hbmCached)
+        ::DeleteObject(m_hbmCached);
+}
+
 static VOID drawColorBox(HDC hDC, LPCRECT prc, COLORREF rgbColor, UINT nBorder)
 {
     RECT rc = *prc;
@@ -76,8 +87,8 @@ LRESULT CPaletteWindow::OnPaint(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& b
     /* To avoid flickering, we use a memory bitmap.
        The left and top values are zeros in client rectangle */
     HDC hMemDC = ::CreateCompatibleDC(hDC);
-    HBITMAP hbm = ::CreateCompatibleBitmap(hDC, rcClient.right, 
rcClient.bottom);
-    HGDIOBJ hbmOld = ::SelectObject(hMemDC, hbm);
+    m_hbmCached = CachedBufferDIB(m_hbmCached, rcClient.right, 
rcClient.bottom);
+    HGDIOBJ hbmOld = ::SelectObject(hMemDC, m_hbmCached);
 
     /* Fill the background (since WM_ERASEBKGND handling is disabled) */
     ::FillRect(hMemDC, &rcClient, (HBRUSH)(COLOR_3DFACE + 1));
@@ -121,7 +132,7 @@ LRESULT CPaletteWindow::OnPaint(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& b
     /* Transfer bits (hDC <-- hMemDC) */
     ::BitBlt(hDC, 0, 0, rcClient.right, rcClient.bottom, hMemDC, 0, 0, 
SRCCOPY);
 
-    ::DeleteObject(::SelectObject(hMemDC, hbmOld));
+    ::SelectObject(hMemDC, hbmOld);
     ::DeleteDC(hMemDC);
     EndPaint(&ps);
     return 0;
diff --git a/base/applications/mspaint/palette.h 
b/base/applications/mspaint/palette.h
index c9e09e92708..fe23edda53f 100644
--- a/base/applications/mspaint/palette.h
+++ b/base/applications/mspaint/palette.h
@@ -30,6 +30,12 @@ public:
         MESSAGE_HANDLER(WM_PALETTEMODELPALETTECHANGED, 
OnPaletteModelPaletteChanged)
     END_MSG_MAP()
 
+    CPaletteWindow();
+    virtual ~CPaletteWindow();
+
+protected:
+    HBITMAP m_hbmCached; // Cached buffer bitmap
+
     LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 
bHandled);
     LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
     LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& 
bHandled);

Reply via email to