https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9afcbea24e25f1ee46dd8…
commit 9afcbea24e25f1ee46dd85fe28772dba8bd5ec09
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Mon Jun 19 09:56:02 2023 +0900
Commit: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)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;