mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 23:13:04 +00:00
[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
This commit is contained in:
parent
5c2ec83fa7
commit
fd1e158480
2 changed files with 27 additions and 17 deletions
|
@ -91,29 +91,43 @@ HITTEST CCanvasWindow::CanvasHitTest(POINT pt)
|
||||||
|
|
||||||
VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint)
|
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
|
// We use a memory bitmap to reduce flickering
|
||||||
HDC hdcMem0 = ::CreateCompatibleDC(hDC);
|
HDC hdcMem0 = ::CreateCompatibleDC(hDC);
|
||||||
m_ahbmCached[0] = CachedBufferDIB(m_ahbmCached[0], rcClient.right, rcClient.bottom);
|
m_ahbmCached[0] = CachedBufferDIB(m_ahbmCached[0], rcClient.right, rcClient.bottom);
|
||||||
HGDIOBJ hbm0Old = ::SelectObject(hdcMem0, m_ahbmCached[0]);
|
HGDIOBJ hbm0Old = ::SelectObject(hdcMem0, m_ahbmCached[0]);
|
||||||
|
|
||||||
// Fill the background on hdcMem0
|
// Fill the background on hdcMem0
|
||||||
::FillRect(hdcMem0, &rcPaint, (HBRUSH)(COLOR_APPWORKSPACE + 1));
|
::FillRect(hdcMem0, &rcCanvasDraw, (HBRUSH)(COLOR_APPWORKSPACE + 1));
|
||||||
|
|
||||||
// Draw the sizeboxes if necessary
|
// Draw the sizeboxes if necessary
|
||||||
RECT rcBase = GetBaseRect();
|
RECT rcBase = GetBaseRect();
|
||||||
if (!selectionModel.m_bShow && !::IsWindowVisible(textEditWindow))
|
if (!selectionModel.m_bShow && !::IsWindowVisible(textEditWindow))
|
||||||
drawSizeBoxes(hdcMem0, &rcBase, FALSE, &rcPaint);
|
drawSizeBoxes(hdcMem0, &rcBase, FALSE, &rcCanvasDraw);
|
||||||
|
|
||||||
// Calculate image size
|
// Calculate image size
|
||||||
CRect rcImage;
|
CRect rcImage;
|
||||||
GetImageRect(rcImage);
|
GetImageRect(rcImage);
|
||||||
SIZE sizeImage = { imageModel.GetWidth(), imageModel.GetHeight() };
|
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
|
// hdcMem1 <-- imageModel
|
||||||
HDC hdcMem1 = ::CreateCompatibleDC(hDC);
|
HDC hdcMem1 = ::CreateCompatibleDC(hDC);
|
||||||
m_ahbmCached[1] = CachedBufferDIB(m_ahbmCached[1], sizeImage.cx, sizeImage.cy);
|
m_ahbmCached[1] = CachedBufferDIB(m_ahbmCached[1], sizeImage.cx, sizeImage.cy);
|
||||||
HGDIOBJ hbm1Old = ::SelectObject(hdcMem1, m_ahbmCached[1]);
|
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
|
// Draw overlay #1 on hdcMem1
|
||||||
toolsModel.OnDrawOverlayOnImage(hdcMem1);
|
toolsModel.OnDrawOverlayOnImage(hdcMem1);
|
||||||
|
@ -158,10 +172,8 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint)
|
||||||
DrawXorRect(hdcMem0, &m_rcResizing);
|
DrawXorRect(hdcMem0, &m_rcResizing);
|
||||||
|
|
||||||
// Transfer the bits (hDC <-- hdcMem0)
|
// Transfer the bits (hDC <-- hdcMem0)
|
||||||
::BitBlt(hDC,
|
::BitBlt(hDC, rcCanvasDraw.left, rcCanvasDraw.top, rcCanvasDraw.Width(), rcCanvasDraw.Height(),
|
||||||
rcPaint.left, rcPaint.top,
|
hdcMem0, rcCanvasDraw.left, rcCanvasDraw.top, SRCCOPY);
|
||||||
rcPaint.right - rcPaint.left, rcPaint.bottom - rcPaint.top,
|
|
||||||
hdcMem0, rcPaint.left, rcPaint.top, SRCCOPY);
|
|
||||||
|
|
||||||
// Clean up hdcMem0
|
// Clean up hdcMem0
|
||||||
::SelectObject(hdcMem0, hbm0Old);
|
::SelectObject(hdcMem0, hbm0Old);
|
||||||
|
|
|
@ -421,6 +421,7 @@ RestrictDrawDirection(DIRECTION dir, LONG x0, LONG y0, LONG& x1, LONG& y1)
|
||||||
struct SmoothDrawTool : ToolBase
|
struct SmoothDrawTool : ToolBase
|
||||||
{
|
{
|
||||||
DIRECTION m_direction = NO_DIRECTION;
|
DIRECTION m_direction = NO_DIRECTION;
|
||||||
|
BOOL m_bShiftDown = FALSE;
|
||||||
|
|
||||||
SmoothDrawTool(TOOLTYPE type) : ToolBase(type)
|
SmoothDrawTool(TOOLTYPE type) : ToolBase(type)
|
||||||
{
|
{
|
||||||
|
@ -433,11 +434,12 @@ struct SmoothDrawTool : ToolBase
|
||||||
m_direction = NO_DIRECTION;
|
m_direction = NO_DIRECTION;
|
||||||
imageModel.PushImageForUndo();
|
imageModel.PushImageForUndo();
|
||||||
imageModel.NotifyImageChanged();
|
imageModel.NotifyImageChanged();
|
||||||
|
m_bShiftDown = (::GetKeyState(VK_SHIFT) & 0x8000); // Is Shift key pressed?
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
|
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)
|
if (m_direction == NO_DIRECTION)
|
||||||
{
|
{
|
||||||
|
@ -450,15 +452,11 @@ struct SmoothDrawTool : ToolBase
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_direction != NO_DIRECTION)
|
|
||||||
{
|
|
||||||
m_direction = NO_DIRECTION;
|
|
||||||
draw(bLeftButton, x, y);
|
draw(bLeftButton, x, y);
|
||||||
g_ptStart.x = g_ptEnd.x = x;
|
g_ptStart.x = g_ptEnd.x = x;
|
||||||
g_ptStart.y = g_ptEnd.y = y;
|
g_ptStart.y = g_ptEnd.y = y;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
draw(bLeftButton, x, y);
|
draw(bLeftButton, x, y);
|
||||||
imageModel.NotifyImageChanged();
|
imageModel.NotifyImageChanged();
|
||||||
|
@ -467,7 +465,7 @@ struct SmoothDrawTool : ToolBase
|
||||||
|
|
||||||
BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
|
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);
|
RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue