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

commit e579220098b132dc25a51451c286e4493949a3d4
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Thu Nov 23 07:14:57 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Thu Nov 23 07:14:57 2023 +0900

    [MSPAINT] Introduce partial image history, Part 2 (#6005)
    
    Follow-up to #5994. Reduce the lag and the
    cost of drawing on large image.
    - Introduce partial image history on
      SmoothDrawTool and ShapeTool.
    - We can draw with pen smoothly even
      when the image is huge (10000x10000).
    CORE-19237
---
 base/applications/mspaint/canvas.cpp         |  20 +--
 base/applications/mspaint/common.h           |   1 +
 base/applications/mspaint/miniature.cpp      |   3 +-
 base/applications/mspaint/mouse.cpp          | 250 +++++++++++++++------------
 base/applications/mspaint/selectionmodel.cpp |  15 +-
 base/applications/mspaint/toolsmodel.h       |  20 +--
 base/applications/mspaint/winproc.cpp        |   5 +-
 7 files changed, 162 insertions(+), 152 deletions(-)

diff --git a/base/applications/mspaint/canvas.cpp 
b/base/applications/mspaint/canvas.cpp
index 6ebe32a48ec..99f1abf772b 100644
--- a/base/applications/mspaint/canvas.cpp
+++ b/base/applications/mspaint/canvas.cpp
@@ -40,18 +40,14 @@ RECT CCanvasWindow::GetBaseRect()
 
 VOID CCanvasWindow::ImageToCanvas(POINT& pt)
 {
-    pt.x = Zoomed(pt.x);
-    pt.y = Zoomed(pt.y);
+    Zoomed(pt);
     pt.x += GRIP_SIZE - GetScrollPos(SB_HORZ);
     pt.y += GRIP_SIZE - GetScrollPos(SB_VERT);
 }
 
 VOID CCanvasWindow::ImageToCanvas(RECT& rc)
 {
-    rc.left = Zoomed(rc.left);
-    rc.top = Zoomed(rc.top);
-    rc.right = Zoomed(rc.right);
-    rc.bottom = Zoomed(rc.bottom);
+    Zoomed(rc);
     ::OffsetRect(&rc, GRIP_SIZE - GetScrollPos(SB_HORZ), GRIP_SIZE - 
GetScrollPos(SB_VERT));
 }
 
@@ -61,8 +57,7 @@ VOID CCanvasWindow::CanvasToImage(POINT& pt, BOOL bZoomed)
     pt.y -= GRIP_SIZE - GetScrollPos(SB_VERT);
     if (bZoomed)
         return;
-    pt.x = UnZoomed(pt.x);
-    pt.y = UnZoomed(pt.y);
+    UnZoomed(pt);
 }
 
 VOID CCanvasWindow::CanvasToImage(RECT& rc, BOOL bZoomed)
@@ -70,15 +65,12 @@ VOID CCanvasWindow::CanvasToImage(RECT& rc, BOOL bZoomed)
     ::OffsetRect(&rc, GetScrollPos(SB_HORZ) - GRIP_SIZE, GetScrollPos(SB_VERT) 
- GRIP_SIZE);
     if (bZoomed)
         return;
-    rc.left = UnZoomed(rc.left);
-    rc.top = UnZoomed(rc.top);
-    rc.right = UnZoomed(rc.right);
-    rc.bottom = UnZoomed(rc.bottom);
+    UnZoomed(rc);
 }
 
 VOID CCanvasWindow::GetImageRect(RECT& rc)
 {
-    ::SetRect(&rc, 0, 0, imageModel.GetWidth(), imageModel.GetHeight());
+    rc = { 0, 0, imageModel.GetWidth(), imageModel.GetHeight() };
 }
 
 HITTEST CCanvasWindow::CanvasHitTest(POINT pt)
@@ -689,7 +681,7 @@ LRESULT CCanvasWindow::OnKeyDown(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL&
 {
     if (wParam == VK_ESCAPE && ::GetCapture() == m_hWnd)
     {
-        // Cancel dragging
+        cancelDrawing();
         ::ReleaseCapture();
         m_nMouseDownMsg = 0;
         m_hitCanvasSizeBox = HIT_NONE;
diff --git a/base/applications/mspaint/common.h 
b/base/applications/mspaint/common.h
index 7f640110806..cc3795c1eca 100644
--- a/base/applications/mspaint/common.h
+++ b/base/applications/mspaint/common.h
@@ -46,6 +46,7 @@ enum HITTEST // hit
 void ShowOutOfMemory(void);
 BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1);
 BOOL OpenMailer(HWND hWnd, LPCWSTR pszPathName);
+void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const POINT *pPoints);
 
 #define DEG2RAD(degree) (((degree) * M_PI) / 180)
 #define RAD2DEG(radian) ((LONG)(((radian) * 180) / M_PI))
diff --git a/base/applications/mspaint/miniature.cpp 
b/base/applications/mspaint/miniature.cpp
index 907dcf5d759..1278dc27385 100644
--- a/base/applications/mspaint/miniature.cpp
+++ b/base/applications/mspaint/miniature.cpp
@@ -122,7 +122,6 @@ LRESULT CMiniatureWindow::OnGetMinMaxInfo(UINT nMsg, WPARAM 
wParam, LPARAM lPara
 {
     // Avoid too small
     LPMINMAXINFO pInfo = (LPMINMAXINFO)lParam;
-    pInfo->ptMinTrackSize.x = 100;
-    pInfo->ptMinTrackSize.y = 75;
+    pInfo->ptMinTrackSize = { 100, 75 };
     return 0;
 }
diff --git a/base/applications/mspaint/mouse.cpp 
b/base/applications/mspaint/mouse.cpp
index 2aa17872c81..9c268514b15 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -9,9 +9,11 @@
 /* INCLUDES *********************************************************/
 
 #include "precomp.h"
+#include <atlalloc.h>
 
-INT ToolBase::s_pointSP = 0;
-POINT ToolBase::s_pointStack[256] = { { 0 } };
+SIZE_T ToolBase::s_pointSP = 0;
+static SIZE_T s_maxPointSP = 0;
+static CHeapPtr<POINT, CLocalAllocator> s_pointStack;
 static POINT g_ptStart, g_ptEnd;
 
 /* FUNCTIONS ********************************************************/
@@ -51,11 +53,31 @@ BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1)
     return (abs(x1 - x0) <= cxThreshold) && (abs(y1 - y0) <= cyThreshold);
 }
 
+void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const POINT *pPoints)
+{
+    POINT ptMin = { MAXLONG, MAXLONG }, ptMax = { (LONG)MINLONG, (LONG)MINLONG 
};
+    while (cPoints-- > 0)
+    {
+        LONG x = pPoints->x, y = pPoints->y;
+        ptMin = { min(x, ptMin.x), min(y, ptMin.y) };
+        ptMax = { max(x, ptMax.x), max(y, ptMax.y) };
+        ++pPoints;
+    }
+
+    ptMax.x += 1;
+    ptMax.y += 1;
+
+    CRect rc(ptMin, ptMax);
+    rcBoundary = rc;
+}
+
 void ToolBase::reset()
 {
     s_pointSP = 0;
-    g_ptStart.x = g_ptStart.y = g_ptEnd.x = g_ptEnd.y = -1;
+    g_ptEnd = g_ptStart = { -1, -1 };
+
     selectionModel.ResetPtStack();
+
     if (selectionModel.m_bShow)
     {
         selectionModel.Landing();
@@ -93,6 +115,24 @@ void ToolBase::OnDrawSelectionOnCanvas(HDC hdc)
     drawSizeBoxes(hdc, &rcSelection, TRUE);
 }
 
+void ToolBase::pushToPtStack(LONG x, LONG y)
+{
+    if (s_pointSP >= s_maxPointSP)
+    {
+        SIZE_T newMax = s_maxPointSP + 512;
+        SIZE_T cbNew = newMax * sizeof(POINT);
+        if (!s_pointStack.ReallocateBytes(cbNew))
+        {
+            ATLTRACE("%d, %d, %d\n", (INT)s_pointSP, (INT)s_maxPointSP, 
(INT)cbNew);
+            return;
+        }
+
+        s_maxPointSP = newMax;
+    }
+
+    s_pointStack[s_pointSP++] = { x, y };
+}
+
 /* TOOLS ********************************************************/
 
 // TOOL_FREESEL
@@ -410,43 +450,43 @@ struct SmoothDrawTool : ToolBase
 {
     DIRECTION m_direction = NO_DIRECTION;
     BOOL m_bShiftDown = FALSE;
+    BOOL m_bLeftButton = FALSE;
 
     SmoothDrawTool(TOOLTYPE type) : ToolBase(type)
     {
     }
 
-    virtual void draw(BOOL bLeftButton, LONG x, LONG y) = 0;
+    virtual void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) = 0;
 
     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) 
override
     {
         m_direction = NO_DIRECTION;
-        imageModel.PushImageForUndo();
-        imageModel.NotifyImageChanged();
         m_bShiftDown = (::GetKeyState(VK_SHIFT) & 0x8000); // Is Shift key 
pressed?
+        m_bLeftButton = bLeftButton;
+        s_pointSP = 0;
+        pushToPtStack(x, y);
+        pushToPtStack(x, y); // We have to draw the first point
+        imageModel.NotifyImageChanged();
     }
 
     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
     {
-        if (m_bShiftDown)
+        if (!m_bShiftDown)
         {
-            if (m_direction == NO_DIRECTION)
-            {
-                m_direction = GetDirection(g_ptStart.x, g_ptStart.y, x, y);
-                if (m_direction == NO_DIRECTION)
-                    return FALSE;
-            }
-
-            RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y);
+            pushToPtStack(x, y);
+            imageModel.NotifyImageChanged();
+            return TRUE;
         }
-        else
+
+        if (m_direction == NO_DIRECTION)
         {
-            draw(bLeftButton, x, y);
-            g_ptStart.x = g_ptEnd.x = x;
-            g_ptStart.y = g_ptEnd.y = y;
-            return TRUE;
+            m_direction = GetDirection(g_ptStart.x, g_ptStart.y, x, y);
+            if (m_direction == NO_DIRECTION)
+                return FALSE;
         }
 
-        draw(bLeftButton, x, y);
+        RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y);
+        pushToPtStack(x, y);
         imageModel.NotifyImageChanged();
         return TRUE;
     }
@@ -454,24 +494,30 @@ struct SmoothDrawTool : ToolBase
     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
     {
         if (m_bShiftDown && m_direction != NO_DIRECTION)
-        {
             RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y);
-        }
 
-        draw(bLeftButton, x, y);
+        pushToPtStack(x, y);
+
+        CRect rcPartial;
+        getBoundaryOfPtStack(rcPartial, s_pointSP, s_pointStack);
+
+        SIZE size = toolsModel.GetToolSize();
+        rcPartial.InflateRect((size.cx + 1) / 2, (size.cy + 1) / 2);
+
+        imageModel.PushImageForUndo(rcPartial);
+
+        OnDrawOverlayOnImage(m_hdc);
+        imageModel.NotifyImageChanged();
         OnEndDraw(FALSE);
         return TRUE;
     }
 
-    void OnEndDraw(BOOL bCancel) override
+    void OnDrawOverlayOnImage(HDC hdc) override
     {
-        if (bCancel)
+        for (SIZE_T i = 1; i < s_pointSP; ++i)
         {
-            LONG x = 0, y = 0;
-            OnButtonUp(FALSE, x, y);
-            imageModel.Undo(TRUE);
+            OnDraw(hdc, m_bLeftButton, s_pointStack[i - 1], s_pointStack[i]);
         }
-        ToolBase::OnEndDraw(bCancel);
     }
 };
 
@@ -482,12 +528,12 @@ struct RubberTool : SmoothDrawTool
     {
     }
 
-    void draw(BOOL bLeftButton, LONG x, LONG y) override
+    void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
     {
         if (bLeftButton)
-            Erase(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, m_bg, 
toolsModel.GetRubberRadius());
+            Erase(hdc, pt0.x, pt0.y, pt1.x, pt1.y, m_bg, 
toolsModel.GetRubberRadius());
         else
-            Replace(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, m_fg, m_bg, 
toolsModel.GetRubberRadius());
+            Replace(hdc, pt0.x, pt0.y, pt1.x, pt1.y, m_fg, m_bg, 
toolsModel.GetRubberRadius());
     }
 
     void OnSpecialTweak(BOOL bMinus) override
@@ -617,10 +663,10 @@ struct PenTool : SmoothDrawTool
     {
     }
 
-    void draw(BOOL bLeftButton, LONG x, LONG y) override
+    void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
     {
         COLORREF rgb = bLeftButton ? m_fg : m_bg;
-        Line(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, rgb, toolsModel.GetPenWidth());
+        Line(hdc, pt0.x, pt0.y, pt1.x, pt1.y, rgb, toolsModel.GetPenWidth());
     }
 
     void OnSpecialTweak(BOOL bMinus) override
@@ -636,10 +682,10 @@ struct BrushTool : SmoothDrawTool
     {
     }
 
-    void draw(BOOL bLeftButton, LONG x, LONG y) override
+    void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
     {
         COLORREF rgb = bLeftButton ? m_fg : m_bg;
-        Brush(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, rgb, 
toolsModel.GetBrushStyle(),
+        Brush(hdc, pt0.x, pt0.y, pt1.x, pt1.y, rgb, toolsModel.GetBrushStyle(),
               toolsModel.GetBrushWidth());
     }
 
@@ -652,14 +698,28 @@ struct BrushTool : SmoothDrawTool
 // TOOL_AIRBRUSH
 struct AirBrushTool : SmoothDrawTool
 {
+    DWORD m_dwTick = 0;
+
     AirBrushTool() : SmoothDrawTool(TOOL_AIRBRUSH)
     {
     }
 
-    void draw(BOOL bLeftButton, LONG x, LONG y) override
+    void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) 
override
+    {
+        m_dwTick = GetTickCount();
+        SmoothDrawTool::OnButtonDown(bLeftButton, x, y, bDoubleClick);
+    }
+
+    void OnDrawOverlayOnImage(HDC hdc) override
+    {
+        srand(m_dwTick);
+        SmoothDrawTool::OnDrawOverlayOnImage(hdc);
+    }
+
+    void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
     {
         COLORREF rgb = bLeftButton ? m_fg : m_bg;
-        Airbrush(m_hdc, x, y, rgb, toolsModel.GetAirBrushRadius());
+        Airbrush(hdc, pt1.x, pt1.y, rgb, toolsModel.GetAirBrushRadius());
     }
 
     void OnSpecialTweak(BOOL bMinus) override
@@ -823,7 +883,6 @@ struct LineTool : TwoPointDrawTool
 struct BezierTool : ToolBase
 {
     BOOL m_bLeftButton = FALSE;
-    BOOL m_bDrawing = FALSE;
 
     BezierTool() : ToolBase(TOOL_BEZIER)
     {
@@ -831,20 +890,17 @@ struct BezierTool : ToolBase
 
     void OnDrawOverlayOnImage(HDC hdc)
     {
-        if (!m_bDrawing)
-            return;
-
         COLORREF rgb = (m_bLeftButton ? m_fg : m_bg);
         switch (s_pointSP)
         {
-            case 1:
+            case 2:
                 Line(hdc, s_pointStack[0].x, s_pointStack[0].y, 
s_pointStack[1].x, s_pointStack[1].y, rgb,
                      toolsModel.GetLineWidth());
                 break;
-            case 2:
+            case 3:
                 Bezier(hdc, s_pointStack[0], s_pointStack[2], s_pointStack[2], 
s_pointStack[1], rgb, toolsModel.GetLineWidth());
                 break;
-            case 3:
+            case 4:
                 Bezier(hdc, s_pointStack[0], s_pointStack[2], s_pointStack[3], 
s_pointStack[1], rgb, toolsModel.GetLineWidth());
                 break;
         }
@@ -854,18 +910,14 @@ struct BezierTool : ToolBase
     {
         m_bLeftButton = bLeftButton;
 
-        if (!m_bDrawing)
+        if (s_pointSP == 0)
         {
-            m_bDrawing = TRUE;
-            s_pointStack[s_pointSP].x = s_pointStack[s_pointSP + 1].x = x;
-            s_pointStack[s_pointSP].y = s_pointStack[s_pointSP + 1].y = y;
-            ++s_pointSP;
+            pushToPtStack(x, y);
+            pushToPtStack(x, y);
         }
         else
         {
-            ++s_pointSP;
-            s_pointStack[s_pointSP].x = x;
-            s_pointStack[s_pointSP].y = y;
+            s_pointStack[s_pointSP - 1] = { x, y };
         }
 
         imageModel.NotifyImageChanged();
@@ -873,33 +925,32 @@ struct BezierTool : ToolBase
 
     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
     {
-        s_pointStack[s_pointSP].x = x;
-        s_pointStack[s_pointSP].y = y;
+        if (s_pointSP > 0)
+            s_pointStack[s_pointSP - 1] = { x, y };
         imageModel.NotifyImageChanged();
         return TRUE;
     }
 
     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
     {
-        s_pointStack[s_pointSP].x = x;
-        s_pointStack[s_pointSP].y = y;
-        if (s_pointSP >= 3)
+        if (s_pointSP >= 4)
         {
             OnEndDraw(FALSE);
             return TRUE;
         }
+        pushToPtStack(x, y);
         imageModel.NotifyImageChanged();
         return TRUE;
     }
 
     void OnEndDraw(BOOL bCancel) override
     {
-        if (!bCancel)
+        if (!bCancel && s_pointSP > 1)
         {
+            // FIXME: I couldn't calculate boundary rectangle from Bezier curve
             imageModel.PushImageForUndo();
             OnDrawOverlayOnImage(m_hdc);
         }
-        m_bDrawing = FALSE;
         ToolBase::OnEndDraw(bCancel);
     }
 
@@ -945,9 +996,9 @@ struct ShapeTool : ToolBase
             return;
 
         if (m_bLeftButton)
-            Poly(hdc, s_pointStack, s_pointSP + 1, m_fg, m_bg, 
toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE);
+            Poly(hdc, s_pointStack, s_pointSP, m_fg, m_bg, 
toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE);
         else
-            Poly(hdc, s_pointStack, s_pointSP + 1, m_bg, m_fg, 
toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE);
+            Poly(hdc, s_pointStack, s_pointSP, m_bg, m_fg, 
toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE);
     }
 
     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) 
override
@@ -958,32 +1009,29 @@ struct ShapeTool : ToolBase
         if ((s_pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
             roundTo8Directions(s_pointStack[s_pointSP - 1].x, 
s_pointStack[s_pointSP - 1].y, x, y);
 
-        s_pointStack[s_pointSP].x = x;
-        s_pointStack[s_pointSP].y = y;
+        pushToPtStack(x, y);
 
-        if (s_pointSP && bDoubleClick)
+        if (s_pointSP > 1 && bDoubleClick)
         {
             OnEndDraw(FALSE);
             return;
         }
 
-        if (s_pointSP == 0)
-        {
-            s_pointSP++;
-            s_pointStack[s_pointSP].x = x;
-            s_pointStack[s_pointSP].y = y;
-        }
+        if (s_pointSP == 1)
+            pushToPtStack(x, y); // We have to draw the first point
 
         imageModel.NotifyImageChanged();
     }
 
     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
     {
-        if ((s_pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
-            roundTo8Directions(s_pointStack[s_pointSP - 1].x, 
s_pointStack[s_pointSP - 1].y, x, y);
+        if (s_pointSP > 1)
+        {
+            if (GetAsyncKeyState(VK_SHIFT) < 0)
+                roundTo8Directions(s_pointStack[s_pointSP - 2].x, 
s_pointStack[s_pointSP - 2].y, x, y);
 
-        s_pointStack[s_pointSP].x = x;
-        s_pointStack[s_pointSP].y = y;
+            s_pointStack[s_pointSP - 1] = { x, y };
+        }
 
         imageModel.NotifyImageChanged();
         return TRUE;
@@ -991,8 +1039,8 @@ struct ShapeTool : ToolBase
 
     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
     {
-        if ((s_pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
-            roundTo8Directions(s_pointStack[s_pointSP - 1].x, 
s_pointStack[s_pointSP - 1].y, x, y);
+        if ((s_pointSP > 1) && (GetAsyncKeyState(VK_SHIFT) < 0))
+            roundTo8Directions(s_pointStack[s_pointSP - 2].x, 
s_pointStack[s_pointSP - 2].y, x, y);
 
         m_bClosed = FALSE;
         if (nearlyEqualPoints(x, y, s_pointStack[0].x, s_pointStack[0].y))
@@ -1000,35 +1048,28 @@ struct ShapeTool : ToolBase
             OnEndDraw(FALSE);
             return TRUE;
         }
-        else
-        {
-            s_pointSP++;
-            s_pointStack[s_pointSP].x = x;
-            s_pointStack[s_pointSP].y = y;
-        }
-
-        if (s_pointSP == _countof(s_pointStack))
-            s_pointSP--;
 
+        pushToPtStack(x, y);
         imageModel.NotifyImageChanged();
         return TRUE;
     }
 
     void OnEndDraw(BOOL bCancel) override
     {
-        if (!bCancel)
+        if (!bCancel && s_pointSP > 1)
         {
-            if (s_pointSP)
-            {
-                --s_pointSP;
-                m_bClosed = TRUE;
+            CRect rcPartial;
+            getBoundaryOfPtStack(rcPartial, s_pointSP, s_pointStack);
 
-                imageModel.PushImageForUndo();
-                OnDrawOverlayOnImage(m_hdc);
-            }
-            m_bClosed = FALSE;
-            s_pointSP = 0;
+            SIZE size = toolsModel.GetToolSize();
+            rcPartial.InflateRect((size.cx + 1) / 2, (size.cy + 1) / 2);
+
+            imageModel.PushImageForUndo(rcPartial);
+
+            m_bClosed = TRUE;
+            OnDrawOverlayOnImage(m_hdc);
         }
+        m_bClosed = FALSE;
         ToolBase::OnEndDraw(bCancel);
     }
 
@@ -1107,8 +1148,7 @@ ToolBase::createToolObject(TOOLTYPE type)
 void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL 
bDoubleClick)
 {
     m_pToolObject->beginEvent();
-    g_ptStart.x = g_ptEnd.x = x;
-    g_ptStart.y = g_ptEnd.y = y;
+    g_ptEnd = g_ptStart = { x, y };
     m_pToolObject->OnButtonDown(bLeftButton, x, y, bDoubleClick);
     m_pToolObject->endEvent();
 }
@@ -1117,10 +1157,8 @@ void ToolsModel::OnMouseMove(BOOL bLeftButton, LONG x, 
LONG y)
 {
     m_pToolObject->beginEvent();
     if (m_pToolObject->OnMouseMove(bLeftButton, x, y))
-    {
-        g_ptEnd.x = x;
-        g_ptEnd.y = y;
-    }
+        g_ptEnd = { x, y };
+
     m_pToolObject->endEvent();
 }
 
@@ -1128,10 +1166,8 @@ void ToolsModel::OnButtonUp(BOOL bLeftButton, LONG x, 
LONG y)
 {
     m_pToolObject->beginEvent();
     if (m_pToolObject->OnButtonUp(bLeftButton, x, y))
-    {
-        g_ptEnd.x = x;
-        g_ptEnd.y = y;
-    }
+        g_ptEnd = { x, y };
+
     m_pToolObject->endEvent();
 }
 
diff --git a/base/applications/mspaint/selectionmodel.cpp 
b/base/applications/mspaint/selectionmodel.cpp
index 76333de6f45..3cf31aab9e0 100644
--- a/base/applications/mspaint/selectionmodel.cpp
+++ b/base/applications/mspaint/selectionmodel.cpp
@@ -23,7 +23,7 @@ SelectionModel::SelectionModel()
 {
     ::SetRectEmpty(&m_rc);
     ::SetRectEmpty(&m_rcOld);
-    m_ptHit.x = m_ptHit.y = -1;
+    m_ptHit = { -1, -1 };
 }
 
 SelectionModel::~SelectionModel()
@@ -71,17 +71,8 @@ void SelectionModel::ShiftPtStack(INT dx, INT dy)
 
 void SelectionModel::BuildMaskFromPtStack()
 {
-    CRect rc = { MAXLONG, MAXLONG, 0, 0 };
-    for (INT i = 0; i < m_iPtSP; ++i)
-    {
-        POINT& pt = m_ptStack[i];
-        rc.left = min(pt.x, rc.left);
-        rc.top = min(pt.y, rc.top);
-        rc.right = max(pt.x, rc.right);
-        rc.bottom = max(pt.y, rc.bottom);
-    }
-    rc.right += 1;
-    rc.bottom += 1;
+    CRect rc;
+    getBoundaryOfPtStack(rc, m_iPtSP, m_ptStack);
 
     m_rc = m_rcOld = rc;
 
diff --git a/base/applications/mspaint/toolsmodel.h 
b/base/applications/mspaint/toolsmodel.h
index 1bc5ee256c0..81af5af3d98 100644
--- a/base/applications/mspaint/toolsmodel.h
+++ b/base/applications/mspaint/toolsmodel.h
@@ -43,8 +43,7 @@ struct ToolBase
     TOOLTYPE m_tool;
     HDC m_hdc;
     COLORREF m_fg, m_bg;
-    static INT s_pointSP;
-    static POINT s_pointStack[256];
+    static SIZE_T s_pointSP;
 
     ToolBase(TOOLTYPE tool) : m_tool(tool), m_hdc(NULL) { }
     virtual ~ToolBase() { }
@@ -63,6 +62,7 @@ struct ToolBase
     void beginEvent();
     void endEvent();
     void reset();
+    void pushToPtStack(LONG x, LONG y);
 
     static ToolBase* createToolObject(TOOLTYPE type);
 
@@ -165,28 +165,20 @@ static inline int UnZoomed(int xy)
 
 static inline void Zoomed(POINT& pt)
 {
-    pt.x = Zoomed(pt.x);
-    pt.y = Zoomed(pt.y);
+    pt = { Zoomed(pt.x), Zoomed(pt.y) };
 }
 
 static inline void Zoomed(RECT& rc)
 {
-    rc.left = Zoomed(rc.left);
-    rc.top = Zoomed(rc.top);
-    rc.right = Zoomed(rc.right);
-    rc.bottom = Zoomed(rc.bottom);
+    rc = { Zoomed(rc.left), Zoomed(rc.top), Zoomed(rc.right), 
Zoomed(rc.bottom) };
 }
 
 static inline void UnZoomed(POINT& pt)
 {
-    pt.x = UnZoomed(pt.x);
-    pt.y = UnZoomed(pt.y);
+    pt = { UnZoomed(pt.x), UnZoomed(pt.y) };
 }
 
 static inline void UnZoomed(RECT& rc)
 {
-    rc.left = UnZoomed(rc.left);
-    rc.top = UnZoomed(rc.top);
-    rc.right = UnZoomed(rc.right);
-    rc.bottom = UnZoomed(rc.bottom);
+    rc = { UnZoomed(rc.left), UnZoomed(rc.top), UnZoomed(rc.right), 
UnZoomed(rc.bottom) };
 }
diff --git a/base/applications/mspaint/winproc.cpp 
b/base/applications/mspaint/winproc.cpp
index b7d825f1b01..a459dda4b76 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -498,9 +498,8 @@ LRESULT CMainWindow::OnSize(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bHand
 
 LRESULT CMainWindow::OnGetMinMaxInfo(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
 {
-    MINMAXINFO *mm = (LPMINMAXINFO) lParam;
-    mm->ptMinTrackSize.x = 330;
-    mm->ptMinTrackSize.y = 360;
+    MINMAXINFO *mm = (MINMAXINFO*)lParam;
+    mm->ptMinTrackSize = { 330, 360 };
     return 0;
 }
 

Reply via email to