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); }