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

commit fd1e158480bc35b9d2918853cd7f2cffc6a6e602
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Mon Oct 16 09:09:40 2023 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Mon Oct 16 09:09:40 2023 +0900

    [MSPAINT] Calculate intersection to reduce bits transfer (#5795)
    
    Drawing lines smoothly on big image.
    - In CCanvasWindow::DoDraw, calculate the
      intersection to reduce bits transfer.
    - Improve SmoothDrawTool in handling Shift key.
    CORE-19094, CORE-19237
---
 base/applications/mspaint/canvas.cpp | 26 +++++++++++++++++++-------
 base/applications/mspaint/mouse.cpp  | 18 ++++++++----------
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/base/applications/mspaint/canvas.cpp 
b/base/applications/mspaint/canvas.cpp
index 680acd6fe56..60aa29929b5 100644
--- a/base/applications/mspaint/canvas.cpp
+++ b/base/applications/mspaint/canvas.cpp
@@ -91,29 +91,43 @@ HITTEST CCanvasWindow::CanvasHitTest(POINT pt)
 
 VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint)
 {
+    // This is the target area we have to draw on
+    CRect rcCanvasDraw;
+    rcCanvasDraw.IntersectRect(&rcClient, &rcPaint);
+
     // We use a memory bitmap to reduce flickering
     HDC hdcMem0 = ::CreateCompatibleDC(hDC);
     m_ahbmCached[0] = CachedBufferDIB(m_ahbmCached[0], rcClient.right, 
rcClient.bottom);
     HGDIOBJ hbm0Old = ::SelectObject(hdcMem0, m_ahbmCached[0]);
 
     // Fill the background on hdcMem0
-    ::FillRect(hdcMem0, &rcPaint, (HBRUSH)(COLOR_APPWORKSPACE + 1));
+    ::FillRect(hdcMem0, &rcCanvasDraw, (HBRUSH)(COLOR_APPWORKSPACE + 1));
 
     // Draw the sizeboxes if necessary
     RECT rcBase = GetBaseRect();
     if (!selectionModel.m_bShow && !::IsWindowVisible(textEditWindow))
-        drawSizeBoxes(hdcMem0, &rcBase, FALSE, &rcPaint);
+        drawSizeBoxes(hdcMem0, &rcBase, FALSE, &rcCanvasDraw);
 
     // Calculate image size
     CRect rcImage;
     GetImageRect(rcImage);
     SIZE sizeImage = { imageModel.GetWidth(), imageModel.GetHeight() };
 
+    // Calculate the target area on the image
+    CRect rcImageDraw = rcCanvasDraw;
+    CanvasToImage(rcImageDraw);
+    rcImageDraw.IntersectRect(&rcImageDraw, &rcImage);
+
+    // Consider rounding down by zooming
+    rcImageDraw.right += 1;
+    rcImageDraw.bottom += 1;
+
     // hdcMem1 <-- imageModel
     HDC hdcMem1 = ::CreateCompatibleDC(hDC);
     m_ahbmCached[1] = CachedBufferDIB(m_ahbmCached[1], sizeImage.cx, 
sizeImage.cy);
     HGDIOBJ hbm1Old = ::SelectObject(hdcMem1, m_ahbmCached[1]);
-    BitBlt(hdcMem1, 0, 0, sizeImage.cx, sizeImage.cy, imageModel.GetDC(), 0, 
0, SRCCOPY);
+    ::BitBlt(hdcMem1, rcImageDraw.left, rcImageDraw.top, rcImageDraw.Width(), 
rcImageDraw.Height(),
+             imageModel.GetDC(), rcImageDraw.left, rcImageDraw.top, SRCCOPY);
 
     // Draw overlay #1 on hdcMem1
     toolsModel.OnDrawOverlayOnImage(hdcMem1);
@@ -158,10 +172,8 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& 
rcPaint)
         DrawXorRect(hdcMem0, &m_rcResizing);
 
     // Transfer the bits (hDC <-- hdcMem0)
-    ::BitBlt(hDC,
-             rcPaint.left, rcPaint.top,
-             rcPaint.right - rcPaint.left, rcPaint.bottom - rcPaint.top,
-             hdcMem0, rcPaint.left, rcPaint.top, SRCCOPY);
+    ::BitBlt(hDC, rcCanvasDraw.left, rcCanvasDraw.top, rcCanvasDraw.Width(), 
rcCanvasDraw.Height(),
+             hdcMem0, rcCanvasDraw.left, rcCanvasDraw.top, SRCCOPY);
 
     // Clean up hdcMem0
     ::SelectObject(hdcMem0, hbm0Old);
diff --git a/base/applications/mspaint/mouse.cpp 
b/base/applications/mspaint/mouse.cpp
index 4984ab63432..dc9ce6b89a2 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -421,6 +421,7 @@ RestrictDrawDirection(DIRECTION dir, LONG x0, LONG y0, 
LONG& x1, LONG& y1)
 struct SmoothDrawTool : ToolBase
 {
     DIRECTION m_direction = NO_DIRECTION;
+    BOOL m_bShiftDown = FALSE;
 
     SmoothDrawTool(TOOLTYPE type) : ToolBase(type)
     {
@@ -433,11 +434,12 @@ struct SmoothDrawTool : ToolBase
         m_direction = NO_DIRECTION;
         imageModel.PushImageForUndo();
         imageModel.NotifyImageChanged();
+        m_bShiftDown = (::GetKeyState(VK_SHIFT) & 0x8000); // Is Shift key 
pressed?
     }
 
     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
     {
-        if (::GetKeyState(VK_SHIFT) < 0) // Shift key is pressed
+        if (m_bShiftDown)
         {
             if (m_direction == NO_DIRECTION)
             {
@@ -450,14 +452,10 @@ struct SmoothDrawTool : ToolBase
         }
         else
         {
-            if (m_direction != NO_DIRECTION)
-            {
-                m_direction = NO_DIRECTION;
-                draw(bLeftButton, x, y);
-                g_ptStart.x = g_ptEnd.x = x;
-                g_ptStart.y = g_ptEnd.y = y;
-                return TRUE;
-            }
+            draw(bLeftButton, x, y);
+            g_ptStart.x = g_ptEnd.x = x;
+            g_ptStart.y = g_ptEnd.y = y;
+            return TRUE;
         }
 
         draw(bLeftButton, x, y);
@@ -467,7 +465,7 @@ struct SmoothDrawTool : ToolBase
 
     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
     {
-        if (m_direction != NO_DIRECTION)
+        if (m_bShiftDown && m_direction != NO_DIRECTION)
         {
             RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y);
         }

Reply via email to