https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2d9091904730fcec3b743…
commit 2d9091904730fcec3b743d8af3cba0aa8aae1553
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Feb 14 12:08:34 2022 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Mon Feb 14 12:08:34 2022 +0900
[MSPAINT] Implement canvas rotation (#4360)
- Add Rotate90DegreeBlt function to dib.cpp.
- Implement ImageModel::RotateNTimes90Degrees and
SelectionModel::RotateNTimes90Degrees.
- Improve ToolsModel::SetBackgroundTransparent.
- Extend and improve SelectionModel::InsertFromHBITMAP.
CORE-16634
---
base/applications/mspaint/dib.cpp | 35 ++++++++++++++++++++++++++++
base/applications/mspaint/dib.h | 2 ++
base/applications/mspaint/history.cpp | 16 ++++++++++++-
base/applications/mspaint/main.cpp | 3 ++-
base/applications/mspaint/selection.cpp | 1 +
base/applications/mspaint/selectionmodel.cpp | 24 +++++++++++++++----
base/applications/mspaint/selectionmodel.h | 2 +-
base/applications/mspaint/toolsmodel.cpp | 2 ++
base/applications/mspaint/winproc.cpp | 8 +++++++
9 files changed, 86 insertions(+), 7 deletions(-)
diff --git a/base/applications/mspaint/dib.cpp b/base/applications/mspaint/dib.cpp
index 53a12f71602..711071752ad 100644
--- a/base/applications/mspaint/dib.cpp
+++ b/base/applications/mspaint/dib.cpp
@@ -208,3 +208,38 @@ HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile)
return hBitmap;
}
+
+HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight)
+{
+ HBITMAP hbm2 = CreateDIBWithProperties(cy, cx);
+ if (!hbm2)
+ return NULL;
+
+ HDC hDC2 = CreateCompatibleDC(NULL);
+ HGDIOBJ hbm2Old = SelectObject(hDC2, hbm2);
+ if (bRight)
+ {
+ for (INT y = 0; y < cy; ++y)
+ {
+ for (INT x = 0; x < cx; ++x)
+ {
+ COLORREF rgb = GetPixel(hDC1, x, y);
+ SetPixelV(hDC2, cy - (y + 1), x, rgb);
+ }
+ }
+ }
+ else
+ {
+ for (INT y = 0; y < cy; ++y)
+ {
+ for (INT x = 0; x < cx; ++x)
+ {
+ COLORREF rgb = GetPixel(hDC1, x, y);
+ SetPixelV(hDC2, y, cx - (x + 1), rgb);
+ }
+ }
+ }
+ SelectObject(hDC2, hbm2Old);
+ DeleteDC(hDC2);
+ return hbm2;
+}
diff --git a/base/applications/mspaint/dib.h b/base/applications/mspaint/dib.h
index 21c73a7dd13..b045be15a50 100644
--- a/base/applications/mspaint/dib.h
+++ b/base/applications/mspaint/dib.h
@@ -27,3 +27,5 @@ HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile);
void ShowFileLoadError(LPCTSTR name);
HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL isFile);
+
+HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight);
diff --git a/base/applications/mspaint/history.cpp
b/base/applications/mspaint/history.cpp
index bc0749148fa..d771fd37225 100644
--- a/base/applications/mspaint/history.cpp
+++ b/base/applications/mspaint/history.cpp
@@ -245,11 +245,25 @@ void ImageModel::FlipVertically()
void ImageModel::RotateNTimes90Degrees(int iN)
{
- if (iN == 2)
+ switch (iN)
{
+ case 1:
+ case 3:
+ DeleteObject(hBms[(currInd + 1) % HISTORYSIZE]);
+ hBms[(currInd + 1) % HISTORYSIZE] = Rotate90DegreeBlt(hDrawingDC, GetWidth(),
GetHeight(), iN == 1);
+ currInd = (currInd + 1) % HISTORYSIZE;
+ if (undoSteps < HISTORYSIZE - 1)
+ undoSteps++;
+ redoSteps = 0;
+ SelectObject(hDrawingDC, hBms[currInd]);
+ imageSaved = FALSE;
+ NotifyDimensionsChanged();
+ break;
+ case 2:
CopyPrevious();
StretchBlt(hDrawingDC, GetWidth() - 1, GetHeight() - 1, -GetWidth(),
-GetHeight(), GetDC(),
0, 0, GetWidth(), GetHeight(), SRCCOPY);
+ break;
}
NotifyImageChanged();
}
diff --git a/base/applications/mspaint/main.cpp b/base/applications/mspaint/main.cpp
index 4d285c2874d..f040ad7d300 100644
--- a/base/applications/mspaint/main.cpp
+++ b/base/applications/mspaint/main.cpp
@@ -344,7 +344,8 @@ _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR
lpszArgument
if (fontsDialog.IsWindow() && IsDialogMessage(fontsDialog,
&messages))
continue;
- TranslateAccelerator(hwnd, haccel, &messages);
+ if (TranslateAccelerator(hwnd, haccel, &messages))
+ continue;
/* Translate virtual-key messages into character messages */
TranslateMessage(&messages);
diff --git a/base/applications/mspaint/selection.cpp
b/base/applications/mspaint/selection.cpp
index d3e7fe6065a..992b946a28a 100644
--- a/base/applications/mspaint/selection.cpp
+++ b/base/applications/mspaint/selection.cpp
@@ -266,6 +266,7 @@ LRESULT CSelectionWindow::OnToolsModelSettingsChanged(UINT nMsg,
WPARAM wParam,
LRESULT CSelectionWindow::OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bHandled)
{
+ ForceRefreshSelectionContents();
return 0;
}
diff --git a/base/applications/mspaint/selectionmodel.cpp
b/base/applications/mspaint/selectionmodel.cpp
index 86d34dbd86d..c65ae21ac84 100644
--- a/base/applications/mspaint/selectionmodel.cpp
+++ b/base/applications/mspaint/selectionmodel.cpp
@@ -165,7 +165,7 @@ void SelectionModel::ScaleContentsToFit()
DeleteDC(hTempDC);
}
-void SelectionModel::InsertFromHBITMAP(HBITMAP hBm)
+void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y)
{
HDC hTempDC;
HBITMAP hTempMask;
@@ -174,14 +174,15 @@ void SelectionModel::InsertFromHBITMAP(HBITMAP hBm)
DeleteObject(SelectObject(m_hDC, m_hBm));
SetRectEmpty(&m_rcSrc);
- m_rcDest.left = m_rcDest.top = 0;
+ m_rcDest.left = x;
+ m_rcDest.top = y;
m_rcDest.right = m_rcDest.left + GetDIBWidth(m_hBm);
m_rcDest.bottom = m_rcDest.top + GetDIBHeight(m_hBm);
hTempDC = CreateCompatibleDC(m_hDC);
hTempMask = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL);
SelectObject(hTempDC, hTempMask);
- Rect(hTempDC, m_rcDest.left, m_rcDest.top, m_rcDest.right, m_rcDest.bottom,
0x00ffffff, 0x00ffffff, 1, 1);
+ Rect(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 0x00ffffff,
0x00ffffff, 1, 1);
DeleteObject(m_hMask);
m_hMask = hTempMask;
DeleteDC(hTempDC);
@@ -211,14 +212,29 @@ void SelectionModel::FlipVertically()
void SelectionModel::RotateNTimes90Degrees(int iN)
{
- if (iN == 2)
+ HBITMAP hbm;
+ switch (iN)
{
+ case 1:
+ case 3:
+ imageModel.DeleteSelection();
+ imageModel.CopyPrevious();
+ SelectObject(m_hDC, m_hBm);
+ hbm = Rotate90DegreeBlt(m_hDC, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), iN ==
1);
+ InsertFromHBITMAP(hbm, m_rcDest.left, m_rcDest.top);
+ DeleteObject(hbm);
+ selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
+ selectionWindow.ForceRefreshSelectionContents();
+ placeSelWin();
+ break;
+ case 2:
SelectObject(m_hDC, m_hMask);
StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, RECT_HEIGHT(m_rcDest) - 1,
-RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC,
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
SelectObject(m_hDC, m_hBm);
StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, RECT_HEIGHT(m_rcDest) - 1,
-RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC,
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
+ break;
}
NotifyRefreshNeeded();
}
diff --git a/base/applications/mspaint/selectionmodel.h
b/base/applications/mspaint/selectionmodel.h
index 0243bc08f96..b3a6982dffe 100644
--- a/base/applications/mspaint/selectionmodel.h
+++ b/base/applications/mspaint/selectionmodel.h
@@ -50,7 +50,7 @@ public:
void DrawSelection(HDC hDCImage, COLORREF crBg = 0, BOOL bBgTransparent = FALSE);
void DrawSelectionStretched(HDC hDCImage);
void ScaleContentsToFit();
- void InsertFromHBITMAP(HBITMAP hBm);
+ void InsertFromHBITMAP(HBITMAP hBm, INT x = 0, INT y = 0);
void FlipHorizontally();
void FlipVertically();
void RotateNTimes90Degrees(int iN);
diff --git a/base/applications/mspaint/toolsmodel.cpp
b/base/applications/mspaint/toolsmodel.cpp
index e42b04c6230..5d5c7fecd0d 100644
--- a/base/applications/mspaint/toolsmodel.cpp
+++ b/base/applications/mspaint/toolsmodel.cpp
@@ -141,6 +141,8 @@ void ToolsModel::SetBackgroundTransparent(BOOL bTransparent)
{
m_transpBg = bTransparent;
NotifyToolSettingsChanged();
+ if (selectionWindow.IsWindow())
+ selectionWindow.ForceRefreshSelectionContents();
}
int ToolsModel::GetZoom() const
diff --git a/base/applications/mspaint/winproc.cpp
b/base/applications/mspaint/winproc.cpp
index b76a310070b..3bc14f6ae72 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -664,6 +664,10 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
imageModel.FlipVertically();
break;
case 3: /* rotate 90 degrees */
+ if (::IsWindowVisible(selectionWindow))
+ selectionModel.RotateNTimes90Degrees(1);
+ else
+ imageModel.RotateNTimes90Degrees(1);
break;
case 4: /* rotate 180 degrees */
if (::IsWindowVisible(selectionWindow))
@@ -672,6 +676,10 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
imageModel.RotateNTimes90Degrees(2);
break;
case 5: /* rotate 270 degrees */
+ if (::IsWindowVisible(selectionWindow))
+ selectionModel.RotateNTimes90Degrees(3);
+ else
+ imageModel.RotateNTimes90Degrees(3);
break;
}
break;