mirror of
https://github.com/reactos/reactos.git
synced 2025-02-20 15:35:04 +00:00
[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
This commit is contained in:
parent
f6bd638b4d
commit
9afcbea24e
8 changed files with 111 additions and 27 deletions
|
@ -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))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
if (hbmMask)
|
||||
{
|
||||
::DeleteObject(m_hbmMask);
|
||||
m_hbmMask = CopyMonoImage(hbmMask);
|
||||
}
|
||||
else
|
||||
{
|
||||
ClearMask();
|
||||
}
|
||||
|
||||
NotifyContentChanged();
|
||||
|
||||
ClearMask();
|
||||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -82,6 +82,8 @@ private:
|
|||
public:
|
||||
ToolsModel();
|
||||
~ToolsModel();
|
||||
|
||||
BOOL IsSelection() const;
|
||||
int GetLineWidth() const;
|
||||
void SetLineWidth(int nLineWidth);
|
||||
int GetShapeStyle() const;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue