https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9afcbea24e25f1ee46dd85...
commit 9afcbea24e25f1ee46dd85fe28772dba8bd5ec09 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Mon Jun 19 09:56:02 2023 +0900 Commit: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com CommitDate: Mon Jun 19 09:56:02 2023 +0900
[MSPAINT] Realize Masked Skew
- Add CreateMonoBitmap and CopyMonoImage functions to dib.cpp. - Add bMono parameter to SkewDIB function. - Add hbmMask parameter to InsertFromHBITMAP function. - Add ToolsModel::IsSelection. CORE-18867 --- base/applications/mspaint/canvas.cpp | 2 +- base/applications/mspaint/dib.cpp | 57 ++++++++++++++++++++++++++- base/applications/mspaint/dib.h | 5 ++- base/applications/mspaint/selectionmodel.cpp | 58 ++++++++++++++++++++-------- base/applications/mspaint/selectionmodel.h | 2 +- base/applications/mspaint/toolsmodel.cpp | 5 +++ base/applications/mspaint/toolsmodel.h | 2 + base/applications/mspaint/winproc.cpp | 7 +--- 8 files changed, 111 insertions(+), 27 deletions(-)
diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp index 8588aa76522..85b53df3273 100644 --- a/base/applications/mspaint/canvas.cpp +++ b/base/applications/mspaint/canvas.cpp @@ -449,7 +449,7 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL { toolsModel.OnMouseMove(TRUE, pt.x, pt.y); Invalidate(FALSE); - if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL)) + if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || toolsModel.IsSelection()) { CString strSize; if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0)) diff --git a/base/applications/mspaint/dib.cpp b/base/applications/mspaint/dib.cpp index cb34859bd56..d72136f79d6 100644 --- a/base/applications/mspaint/dib.cpp +++ b/base/applications/mspaint/dib.cpp @@ -36,6 +36,26 @@ CreateDIBWithProperties(int width, int height) return CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, NULL, NULL, 0); }
+HBITMAP +CreateMonoBitmap(int width, int height, BOOL bWhite) +{ + HBITMAP hbm = CreateBitmap(width, height, 1, 1, NULL); + if (hbm == NULL) + return NULL; + + if (bWhite) + { + HDC hdc = CreateCompatibleDC(NULL); + HGDIOBJ hbmOld = SelectObject(hdc, hbm); + RECT rc = { 0, 0, width, height }; + FillRect(hdc, &rc, (HBRUSH)GetStockObject(WHITE_BRUSH)); + SelectObject(hdc, hbmOld); + DeleteDC(hdc); + } + + return hbm; +} + HBITMAP CreateColorDIB(int width, int height, COLORREF rgb) { @@ -59,6 +79,34 @@ CreateColorDIB(int width, int height, COLORREF rgb) return ret; }
+HBITMAP CopyMonoImage(HBITMAP hbm, INT cx, INT cy) +{ + BITMAP bm; + if (!GetObject(hbm, sizeof(bm), &bm)) + return NULL; + + if (cx == 0 || cy == 0) + { + cx = bm.bmWidth; + cy = bm.bmHeight; + } + + HBITMAP hbmNew = CreateBitmap(cx, cy, 1, 1, NULL); + if (!hbmNew) + return NULL; + + HDC hdc1 = CreateCompatibleDC(NULL); + HDC hdc2 = CreateCompatibleDC(NULL); + HGDIOBJ hbm1Old = SelectObject(hdc1, hbm); + HGDIOBJ hbm2Old = SelectObject(hdc2, hbmNew); + StretchBlt(hdc2, 0, 0, cx, cy, hdc1, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY); + SelectObject(hdc1, hbm1Old); + SelectObject(hdc1, hbm2Old); + DeleteDC(hdc1); + DeleteDC(hdc2); + return hbmNew; +} + HBITMAP CachedBufferDIB(HBITMAP hbm, int minimalWidth, int minimalHeight) { if (minimalWidth <= 0) @@ -283,7 +331,7 @@ HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono) #define M_PI 3.14159265 #endif
-HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical) +HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical, BOOL bMono) { if (nDegree == 0) return CopyDIBImage(hbm); @@ -301,7 +349,11 @@ HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical) if (dx == 0 && dy == 0) return CopyDIBImage(hbm);
- HBITMAP hbmNew = CreateColorDIB(cx + dx, cy + dy, RGB(255, 255, 255)); + HBITMAP hbmNew; + if (bMono) + hbmNew = CreateMonoBitmap(cx + dx, cy + dy, FALSE); + else + hbmNew = CreateColorDIB(cx + dx, cy + dy, RGB(255, 255, 255)); if (!hbmNew) return NULL;
@@ -329,6 +381,7 @@ HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical) BitBlt(hDC2, delta, y, cx, 1, hDC1, 0, y, SRCCOPY); } } + SelectObject(hDC2, hbm2Old); DeleteDC(hDC2); return hbmNew; diff --git a/base/applications/mspaint/dib.h b/base/applications/mspaint/dib.h index 4958f612673..0aa6fa41796 100644 --- a/base/applications/mspaint/dib.h +++ b/base/applications/mspaint/dib.h @@ -9,9 +9,12 @@ #pragma once
HBITMAP CreateDIBWithProperties(int width, int height); +HBITMAP CreateMonoBitmap(int width, int height, BOOL bWhite); HBITMAP CreateColorDIB(int width, int height, COLORREF rgb); HBITMAP CachedBufferDIB(HBITMAP hbm, int minimalWidth, int minimalHeight);
+HBITMAP CopyMonoImage(HBITMAP hbm, INT cx = 0, INT cy = 0); + static inline HBITMAP CopyDIBImage(HBITMAP hbm, INT cx = 0, INT cy = 0) { return (HBITMAP)CopyImage(hbm, IMAGE_BITMAP, cx, cy, LR_COPYRETURNORG | LR_CREATEDIBSECTION); @@ -31,7 +34,7 @@ HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL i
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono);
-HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical); +HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical, BOOL bMono = FALSE);
float PpcmFromDpi(float dpi);
diff --git a/base/applications/mspaint/selectionmodel.cpp b/base/applications/mspaint/selectionmodel.cpp index fb28ad5033a..b96213313b1 100644 --- a/base/applications/mspaint/selectionmodel.cpp +++ b/base/applications/mspaint/selectionmodel.cpp @@ -209,19 +209,27 @@ void SelectionModel::Landing() HideSelection(); }
-void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y) +void SelectionModel::InsertFromHBITMAP(HBITMAP hbmColor, INT x, INT y, HBITMAP hbmMask) { ::DeleteObject(m_hbmColor); - m_hbmColor = CopyDIBImage(hBm); + m_hbmColor = CopyDIBImage(hbmColor);
m_rc.left = x; m_rc.top = y; - m_rc.right = x + GetDIBWidth(hBm); - m_rc.bottom = y + GetDIBHeight(hBm); + m_rc.right = x + GetDIBWidth(hbmColor); + m_rc.bottom = y + GetDIBHeight(hbmColor);
- NotifyContentChanged(); + if (hbmMask) + { + ::DeleteObject(m_hbmMask); + m_hbmMask = CopyMonoImage(hbmMask); + } + else + { + ClearMask(); + }
- ClearMask(); + NotifyContentChanged(); }
void SelectionModel::FlipHorizontally() @@ -336,29 +344,45 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int INT newWidth = oldWidth * nStretchPercentX / 100; INT newHeight = oldHeight * nStretchPercentY / 100;
+ HBITMAP hbmColor, hbmMask; + HGDIOBJ hbmOld; + + if (m_hbmMask == NULL) + m_hbmMask = CreateMonoBitmap(newWidth, newHeight, TRUE); + if (oldWidth != newWidth || oldHeight != newHeight) { - HBITMAP hbm0 = CopyDIBImage(m_hbmColor, newWidth, newHeight); - InsertFromHBITMAP(hbm0, m_rc.left, m_rc.top); - ::DeleteObject(hbm0); + hbmColor = CopyDIBImage(m_hbmColor, newWidth, newHeight); + hbmMask = CopyMonoImage(m_hbmMask, newWidth, newHeight); + InsertFromHBITMAP(hbmColor, m_rc.left, m_rc.top, hbmMask); + ::DeleteObject(hbmColor); + ::DeleteObject(hbmMask); }
HDC hDC = ::CreateCompatibleDC(NULL);
if (nSkewDegX) { - ::SelectObject(hDC, m_hbmColor); - HBITMAP hbm1 = SkewDIB(hDC, m_hbmColor, nSkewDegX, FALSE); - InsertFromHBITMAP(hbm1, m_rc.left, m_rc.top); - ::DeleteObject(hbm1); + hbmOld = ::SelectObject(hDC, m_hbmColor); + hbmColor = SkewDIB(hDC, m_hbmColor, nSkewDegX, FALSE); + ::SelectObject(hDC, m_hbmMask); + hbmMask = SkewDIB(hDC, m_hbmMask, nSkewDegX, FALSE, TRUE); + InsertFromHBITMAP(hbmColor, m_rc.left, m_rc.top, hbmMask); + ::SelectObject(hDC, hbmOld); + ::DeleteObject(hbmColor); + ::DeleteObject(hbmMask); }
if (nSkewDegY) { - ::SelectObject(hDC, m_hbmColor); - HBITMAP hbm2 = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE); - InsertFromHBITMAP(hbm2, m_rc.left, m_rc.top); - ::DeleteObject(hbm2); + hbmOld = ::SelectObject(hDC, m_hbmColor); + hbmColor = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE); + ::SelectObject(hDC, m_hbmMask); + hbmMask = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE, TRUE); + InsertFromHBITMAP(hbmColor, m_rc.left, m_rc.top, hbmMask); + ::SelectObject(hDC, hbmOld); + ::DeleteObject(hbmColor); + ::DeleteObject(hbmMask); }
::DeleteDC(hDC); diff --git a/base/applications/mspaint/selectionmodel.h b/base/applications/mspaint/selectionmodel.h index 230c87dfdf5..248ae03f0d6 100644 --- a/base/applications/mspaint/selectionmodel.h +++ b/base/applications/mspaint/selectionmodel.h @@ -47,7 +47,7 @@ public: void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg); void DrawBackgroundRect(HDC hDCImage, COLORREF crBg); void DrawSelection(HDC hDCImage, COLORREF crBg = 0, BOOL bBgTransparent = FALSE); - void InsertFromHBITMAP(HBITMAP hBm, INT x = 0, INT y = 0); + void InsertFromHBITMAP(HBITMAP hbmColor, INT x = 0, INT y = 0, HBITMAP hbmMask = NULL);
// operation void FlipHorizontally(); diff --git a/base/applications/mspaint/toolsmodel.cpp b/base/applications/mspaint/toolsmodel.cpp index 76a123513b5..7593bc964c4 100644 --- a/base/applications/mspaint/toolsmodel.cpp +++ b/base/applications/mspaint/toolsmodel.cpp @@ -40,6 +40,11 @@ ToolBase *ToolsModel::GetOrCreateTool(TOOLTYPE nTool) return m_tools[nTool]; }
+BOOL ToolsModel::IsSelection() const +{ + return (GetActiveTool() == TOOL_RECTSEL || GetActiveTool() == TOOL_FREESEL); +} + int ToolsModel::GetLineWidth() const { return m_lineWidth; diff --git a/base/applications/mspaint/toolsmodel.h b/base/applications/mspaint/toolsmodel.h index b8c819590a7..b31183b3584 100644 --- a/base/applications/mspaint/toolsmodel.h +++ b/base/applications/mspaint/toolsmodel.h @@ -82,6 +82,8 @@ private: public: ToolsModel(); ~ToolsModel(); + + BOOL IsSelection() const; int GetLineWidth() const; void SetLineWidth(int nLineWidth); int GetShapeStyle() const; diff --git a/base/applications/mspaint/winproc.cpp b/base/applications/mspaint/winproc.cpp index 72947626a8c..7a22b153794 100644 --- a/base/applications/mspaint/winproc.cpp +++ b/base/applications/mspaint/winproc.cpp @@ -419,9 +419,7 @@ void CMainWindow::ProcessFileMenu(HMENU hPopupMenu) LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { HMENU menu = (HMENU)wParam; - BOOL trueSelection = - (selectionModel.m_bShow && - ((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() == TOOL_RECTSEL))); + BOOL trueSelection = (selectionModel.m_bShow && toolsModel.IsSelection()); BOOL textShown = (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow)); DWORD dwStart = 0, dwEnd = 0; if (textShown) @@ -667,8 +665,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH } if (selectionModel.m_bShow) { - if (toolsModel.GetActiveTool() == TOOL_RECTSEL || - toolsModel.GetActiveTool() == TOOL_FREESEL) + if (toolsModel.IsSelection()) { canvasWindow.cancelDrawing(); break;