https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2d9091904730fcec3b743d...
commit 2d9091904730fcec3b743d8af3cba0aa8aae1553 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Mon Feb 14 12:08:34 2022 +0900 Commit: GitHub noreply@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;