https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9afcbea24e25f1ee46dd85fe28772dba8bd5ec09

commit 9afcbea24e25f1ee46dd85fe28772dba8bd5ec09
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Mon Jun 19 09:56:02 2023 +0900
Commit:     Katayama Hirofumi MZ <[email protected]>
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;

Reply via email to