mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 09:23:06 +00:00
[MSPAINT] Make selection window-less (#5208)
- Delete selection.cpp and selection.h and selectionWindow. - Extend ColorKeyedMaskBlt function. - Implement selection resizing. CORE-18867
This commit is contained in:
parent
3f5bcf5775
commit
aac89519ec
23 changed files with 702 additions and 829 deletions
|
@ -14,225 +14,295 @@ SelectionModel selectionModel;
|
|||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
SelectionModel::SelectionModel()
|
||||
: m_hDC(CreateCompatibleDC(NULL))
|
||||
, m_hBm(NULL)
|
||||
, m_hMask(NULL)
|
||||
: m_hbmColor(NULL)
|
||||
, m_hbmMask(NULL)
|
||||
, m_ptStack(NULL)
|
||||
, m_iPtSP(0)
|
||||
, m_bShow(FALSE)
|
||||
{
|
||||
SetRectEmpty(&m_rcSrc);
|
||||
SetRectEmpty(&m_rcDest);
|
||||
::SetRectEmpty(&m_rc);
|
||||
m_ptHit.x = m_ptHit.y = -1;
|
||||
}
|
||||
|
||||
SelectionModel::~SelectionModel()
|
||||
{
|
||||
DeleteDC(m_hDC);
|
||||
ClearColor();
|
||||
ClearMask();
|
||||
ResetPtStack();
|
||||
if (m_hBm)
|
||||
{
|
||||
DeleteObject(m_hBm);
|
||||
}
|
||||
if (m_hMask)
|
||||
{
|
||||
DeleteObject(m_hMask);
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::ResetPtStack()
|
||||
{
|
||||
if (m_ptStack != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, m_ptStack);
|
||||
m_ptStack = NULL;
|
||||
if (m_ptStack)
|
||||
{
|
||||
free(m_ptStack);
|
||||
m_ptStack = NULL;
|
||||
}
|
||||
m_iPtSP = 0;
|
||||
}
|
||||
|
||||
void SelectionModel::PushToPtStack(LONG x, LONG y)
|
||||
void SelectionModel::PushToPtStack(POINT pt)
|
||||
{
|
||||
if (m_iPtSP % 1024 == 0)
|
||||
#define GROW_COUNT 256
|
||||
if (m_iPtSP % GROW_COUNT == 0)
|
||||
{
|
||||
if (m_ptStack)
|
||||
m_ptStack = (POINT*) HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, m_ptStack, sizeof(POINT) * (m_iPtSP + 1024));
|
||||
else
|
||||
m_ptStack = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * 1024);
|
||||
INT nNewCount = m_iPtSP + GROW_COUNT;
|
||||
LPPOINT pptNew = (LPPOINT)realloc(m_ptStack, sizeof(POINT) * nNewCount);
|
||||
if (pptNew == NULL)
|
||||
return;
|
||||
m_ptStack = pptNew;
|
||||
}
|
||||
m_ptStack[m_iPtSP].x = x;
|
||||
m_ptStack[m_iPtSP].y = y;
|
||||
m_ptStack[m_iPtSP] = pt;
|
||||
m_iPtSP++;
|
||||
#undef GROW_COUNT
|
||||
}
|
||||
|
||||
void SelectionModel::CalculateBoundingBoxAndContents(HDC hDCImage)
|
||||
void SelectionModel::ShiftPtStack(BOOL bPlus)
|
||||
{
|
||||
int i;
|
||||
m_rcSrc.left = m_rcSrc.top = MAXLONG;
|
||||
m_rcSrc.right = m_rcSrc.bottom = 0;
|
||||
for (i = 0; i < m_iPtSP; i++)
|
||||
if (bPlus)
|
||||
{
|
||||
if (m_ptStack[i].x < m_rcSrc.left)
|
||||
m_rcSrc.left = m_ptStack[i].x;
|
||||
if (m_ptStack[i].y < m_rcSrc.top)
|
||||
m_rcSrc.top = m_ptStack[i].y;
|
||||
if (m_ptStack[i].x > m_rcSrc.right)
|
||||
m_rcSrc.right = m_ptStack[i].x;
|
||||
if (m_ptStack[i].y > m_rcSrc.bottom)
|
||||
m_rcSrc.bottom = m_ptStack[i].y;
|
||||
}
|
||||
m_rcSrc.right += 1;
|
||||
m_rcSrc.bottom += 1;
|
||||
m_rcDest.left = m_rcSrc.left;
|
||||
m_rcDest.top = m_rcSrc.top;
|
||||
m_rcDest.right = m_rcSrc.right;
|
||||
m_rcDest.bottom = m_rcSrc.bottom;
|
||||
|
||||
if (m_iPtSP > 1)
|
||||
{
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = CreateBitmap(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 1, 1, NULL);
|
||||
DeleteObject(SelectObject(m_hDC, m_hMask));
|
||||
POINT *m_ptStackCopy = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * m_iPtSP);
|
||||
for (i = 0; i < m_iPtSP; i++)
|
||||
for (INT i = 0; i < m_iPtSP; ++i)
|
||||
{
|
||||
m_ptStackCopy[i].x = m_ptStack[i].x - m_rcSrc.left;
|
||||
m_ptStackCopy[i].y = m_ptStack[i].y - m_rcSrc.top;
|
||||
POINT& pt = m_ptStack[i];
|
||||
pt.x += m_rc.left;
|
||||
pt.y += m_rc.top;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (INT i = 0; i < m_iPtSP; ++i)
|
||||
{
|
||||
POINT& pt = m_ptStack[i];
|
||||
pt.x -= m_rc.left;
|
||||
pt.y -= m_rc.top;
|
||||
}
|
||||
Poly(m_hDC, m_ptStackCopy, m_iPtSP, 0x00ffffff, 0x00ffffff, 1, 2, TRUE, FALSE);
|
||||
HeapFree(GetProcessHeap(), 0, m_ptStackCopy);
|
||||
SelectObject(m_hDC, m_hBm = CreateDIBWithProperties(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc)));
|
||||
imageModel.ResetToPrevious();
|
||||
MaskBlt(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), hDCImage, m_rcSrc.left,
|
||||
m_rcSrc.top, m_hMask, 0, 0, MAKEROP4(SRCCOPY, WHITENESS));
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::CalculateContents(HDC hDCImage)
|
||||
void SelectionModel::BuildMaskFromPtStack()
|
||||
{
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = CreateBitmap(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 1, 1, NULL);
|
||||
DeleteObject(SelectObject(m_hDC, m_hMask));
|
||||
Rect(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 0x00ffffff, 0x00ffffff, 1, 2);
|
||||
SelectObject(m_hDC, m_hBm = CreateDIBWithProperties(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc)));
|
||||
BitBlt(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), hDCImage, m_rcSrc.left,
|
||||
m_rcSrc.top, SRCCOPY);
|
||||
CRect rc = { MAXLONG, MAXLONG, 0, 0 };
|
||||
for (INT i = 0; i < m_iPtSP; ++i)
|
||||
{
|
||||
POINT& pt = m_ptStack[i];
|
||||
rc.left = min(pt.x, rc.left);
|
||||
rc.top = min(pt.y, rc.top);
|
||||
rc.right = max(pt.x, rc.right);
|
||||
rc.bottom = max(pt.y, rc.bottom);
|
||||
}
|
||||
rc.right += 1;
|
||||
rc.bottom += 1;
|
||||
|
||||
m_rc = rc;
|
||||
|
||||
ShiftPtStack(FALSE);
|
||||
|
||||
ClearMask();
|
||||
|
||||
HDC hdcMem = ::CreateCompatibleDC(NULL);
|
||||
m_hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL);
|
||||
HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmMask);
|
||||
FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH));
|
||||
HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN));
|
||||
HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH));
|
||||
::Polygon(hdcMem, m_ptStack, m_iPtSP);
|
||||
::SelectObject(hdcMem, hbrOld);
|
||||
::SelectObject(hdcMem, hPenOld);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
::DeleteDC(hdcMem);
|
||||
}
|
||||
|
||||
void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg)
|
||||
{
|
||||
Poly(hDCImage, m_ptStack, m_iPtSP, crBg, crBg, 1, 2, TRUE, FALSE);
|
||||
ShiftPtStack(TRUE);
|
||||
|
||||
HGDIOBJ hPenOld = ::SelectObject(hDCImage, ::GetStockObject(NULL_PEN));
|
||||
HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::CreateSolidBrush(crBg));
|
||||
::Polygon(hDCImage, m_ptStack, m_iPtSP);
|
||||
::DeleteObject(::SelectObject(hDCImage, hbrOld));
|
||||
::SelectObject(hDCImage, hPenOld);
|
||||
|
||||
ShiftPtStack(FALSE);
|
||||
}
|
||||
|
||||
void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg)
|
||||
{
|
||||
Rect(hDCImage, m_rcSrc.left, m_rcSrc.top, m_rcSrc.right, m_rcSrc.bottom, crBg, crBg, 0, 1);
|
||||
Rect(hDCImage, m_rc.left, m_rc.top, m_rc.right, m_rc.bottom, crBg, crBg, 0, 1);
|
||||
}
|
||||
|
||||
void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent)
|
||||
void SelectionModel::DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg, BOOL bBgTransparent)
|
||||
{
|
||||
if (!bBgTransparent)
|
||||
MaskBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest),
|
||||
m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
|
||||
CRect rc = *prc;
|
||||
if (::IsRectEmpty(&rc))
|
||||
return;
|
||||
|
||||
BITMAP bm;
|
||||
GetObject(m_hbmColor, sizeof(BITMAP), &bm);
|
||||
|
||||
COLORREF keyColor = (bBgTransparent ? crBg : CLR_INVALID);
|
||||
|
||||
HDC hMemDC = CreateCompatibleDC(hDCImage);
|
||||
HGDIOBJ hbmOld = SelectObject(hMemDC, m_hbmColor);
|
||||
ColorKeyedMaskBlt(hDCImage, rc.left, rc.top, rc.Width(), rc.Height(),
|
||||
hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, m_hbmMask, keyColor);
|
||||
SelectObject(hMemDC, hbmOld);
|
||||
DeleteDC(hMemDC);
|
||||
}
|
||||
|
||||
void SelectionModel::GetSelectionContents(HDC hDCImage)
|
||||
{
|
||||
ClearColor();
|
||||
|
||||
HDC hMemDC = ::CreateCompatibleDC(NULL);
|
||||
m_hbmColor = CreateColorDIB(m_rc.Width(), m_rc.Height(), RGB(255, 255, 255));
|
||||
HGDIOBJ hbmOld = ::SelectObject(hMemDC, m_hbmColor);
|
||||
::BitBlt(hMemDC, 0, 0, m_rc.Width(), m_rc.Height(), hDCImage, m_rc.left, m_rc.top, SRCCOPY);
|
||||
::SelectObject(hMemDC, hbmOld);
|
||||
::DeleteDC(hMemDC);
|
||||
}
|
||||
|
||||
BOOL SelectionModel::TakeOff()
|
||||
{
|
||||
if (m_hbmColor || ::IsRectEmpty(&m_rc))
|
||||
return FALSE;
|
||||
|
||||
HDC hDCImage = imageModel.GetDC();
|
||||
GetSelectionContents(hDCImage);
|
||||
|
||||
if (toolsModel.GetActiveTool() == TOOL_FREESEL)
|
||||
{
|
||||
DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor());
|
||||
}
|
||||
else
|
||||
ColorKeyedMaskBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest),
|
||||
m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND), crBg);
|
||||
{
|
||||
ClearMask();
|
||||
DrawBackgroundRect(hDCImage, paletteModel.GetBgColor());
|
||||
}
|
||||
|
||||
imageArea.Invalidate(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void SelectionModel::DrawSelectionStretched(HDC hDCImage)
|
||||
void SelectionModel::Landing()
|
||||
{
|
||||
StretchBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0, GetDIBWidth(m_hBm), GetDIBHeight(m_hBm), SRCCOPY);
|
||||
}
|
||||
if (!m_hbmColor)
|
||||
return;
|
||||
|
||||
void SelectionModel::ScaleContentsToFit()
|
||||
{
|
||||
HDC hTempDC;
|
||||
HBITMAP hTempBm;
|
||||
hTempDC = CreateCompatibleDC(m_hDC);
|
||||
hTempBm = CreateDIBWithProperties(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest));
|
||||
SelectObject(hTempDC, hTempBm);
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0,
|
||||
GetDIBWidth(m_hBm), GetDIBHeight(m_hBm), SRCCOPY);
|
||||
DeleteObject(m_hBm);
|
||||
m_hBm = hTempBm;
|
||||
hTempBm = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL);
|
||||
SelectObject(hTempDC, hTempBm);
|
||||
SelectObject(m_hDC, m_hMask);
|
||||
StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0,
|
||||
GetDIBWidth(m_hMask), GetDIBHeight(m_hMask), SRCCOPY);
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = hTempBm;
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
DeleteDC(hTempDC);
|
||||
DrawSelection(imageModel.GetDC(), &m_rc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
|
||||
|
||||
::SetRectEmpty(&m_rc);
|
||||
ClearMask();
|
||||
ClearColor();
|
||||
|
||||
imageModel.CopyPrevious();
|
||||
}
|
||||
|
||||
void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y)
|
||||
{
|
||||
HDC hTempDC;
|
||||
HBITMAP hTempMask;
|
||||
m_hbmColor = CopyDIBImage(hBm);
|
||||
::DeleteObject(m_hbmColor);
|
||||
|
||||
m_hBm = CopyDIBImage(hBm);
|
||||
DeleteObject(SelectObject(m_hDC, m_hBm));
|
||||
m_rc.left = x;
|
||||
m_rc.top = y;
|
||||
m_rc.right = m_rc.left + GetDIBWidth(hBm);
|
||||
m_rc.bottom = m_rc.top + GetDIBHeight(hBm);
|
||||
|
||||
SetRectEmpty(&m_rcSrc);
|
||||
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, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 0x00ffffff, 0x00ffffff, 1, 1);
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = hTempMask;
|
||||
DeleteDC(hTempDC);
|
||||
ClearMask();
|
||||
}
|
||||
|
||||
void SelectionModel::FlipHorizontally()
|
||||
{
|
||||
SelectObject(m_hDC, m_hMask);
|
||||
StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, 0, -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, 0, -RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC,
|
||||
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
|
||||
TakeOff();
|
||||
|
||||
HDC hdcMem = ::CreateCompatibleDC(NULL);
|
||||
if (m_hbmMask)
|
||||
{
|
||||
::SelectObject(hdcMem, m_hbmMask);
|
||||
::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
}
|
||||
if (m_hbmColor)
|
||||
{
|
||||
::SelectObject(hdcMem, m_hbmColor);
|
||||
::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
}
|
||||
::DeleteDC(hdcMem);
|
||||
|
||||
NotifyRefreshNeeded();
|
||||
}
|
||||
|
||||
void SelectionModel::FlipVertically()
|
||||
{
|
||||
SelectObject(m_hDC, m_hMask);
|
||||
StretchBlt(m_hDC, 0, 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, 0, 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);
|
||||
TakeOff();
|
||||
|
||||
HDC hdcMem = ::CreateCompatibleDC(NULL);
|
||||
if (m_hbmMask)
|
||||
{
|
||||
::SelectObject(hdcMem, m_hbmMask);
|
||||
::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
}
|
||||
if (m_hbmColor)
|
||||
{
|
||||
::SelectObject(hdcMem, m_hbmColor);
|
||||
::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
}
|
||||
::DeleteDC(hdcMem);
|
||||
|
||||
NotifyRefreshNeeded();
|
||||
}
|
||||
|
||||
void SelectionModel::RotateNTimes90Degrees(int iN)
|
||||
{
|
||||
HBITMAP hbm;
|
||||
HGDIOBJ hbmOld;
|
||||
HDC hdcMem = ::CreateCompatibleDC(NULL);
|
||||
|
||||
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;
|
||||
case 1:
|
||||
case 3:
|
||||
TakeOff();
|
||||
if (m_hbmColor)
|
||||
{
|
||||
hbmOld = ::SelectObject(hdcMem, m_hbmColor);
|
||||
hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1, FALSE);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
::DeleteObject(m_hbmColor);
|
||||
m_hbmColor = hbm;
|
||||
}
|
||||
if (m_hbmMask)
|
||||
{
|
||||
hbmOld = ::SelectObject(hdcMem, m_hbmMask);
|
||||
hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1, TRUE);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
::DeleteObject(m_hbmMask);
|
||||
m_hbmMask = hbm;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
TakeOff();
|
||||
if (m_hbmColor)
|
||||
{
|
||||
hbmOld = ::SelectObject(hdcMem, m_hbmColor);
|
||||
::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(), -m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
}
|
||||
if (m_hbmMask)
|
||||
{
|
||||
hbmOld = ::SelectObject(hdcMem, m_hbmMask);
|
||||
::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(), -m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
::DeleteDC(hdcMem);
|
||||
NotifyRefreshNeeded();
|
||||
}
|
||||
|
||||
|
@ -241,47 +311,47 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int
|
|||
if (nStretchPercentX == 100 && nStretchPercentY == 100 && nSkewDegX == 0 && nSkewDegY == 0)
|
||||
return;
|
||||
|
||||
imageModel.DeleteSelection();
|
||||
imageModel.CopyPrevious();
|
||||
TakeOff();
|
||||
|
||||
INT oldWidth = RECT_WIDTH(m_rcDest);
|
||||
INT oldHeight = RECT_HEIGHT(m_rcDest);
|
||||
INT oldWidth = m_rc.Width();
|
||||
INT oldHeight = m_rc.Height();
|
||||
INT newWidth = oldWidth * nStretchPercentX / 100;
|
||||
INT newHeight = oldHeight * nStretchPercentY / 100;
|
||||
|
||||
if (oldWidth != newWidth || oldHeight != newHeight)
|
||||
{
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
HBITMAP hbm0 = CopyDIBImage(m_hBm, newWidth, newHeight);
|
||||
InsertFromHBITMAP(hbm0, m_rcDest.left, m_rcDest.top);
|
||||
DeleteObject(hbm0);
|
||||
HBITMAP hbm0 = CopyDIBImage(m_hbmColor, newWidth, newHeight);
|
||||
InsertFromHBITMAP(hbm0, m_rc.left, m_rc.top);
|
||||
::DeleteObject(hbm0);
|
||||
}
|
||||
|
||||
HDC hDC = ::CreateCompatibleDC(NULL);
|
||||
|
||||
if (nSkewDegX)
|
||||
{
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
HBITMAP hbm1 = SkewDIB(m_hDC, m_hBm, nSkewDegX, FALSE);
|
||||
InsertFromHBITMAP(hbm1, m_rcDest.left, m_rcDest.top);
|
||||
DeleteObject(hbm1);
|
||||
::SelectObject(hDC, m_hbmColor);
|
||||
HBITMAP hbm1 = SkewDIB(hDC, m_hbmColor, nSkewDegX, FALSE);
|
||||
InsertFromHBITMAP(hbm1, m_rc.left, m_rc.top);
|
||||
::DeleteObject(hbm1);
|
||||
}
|
||||
|
||||
if (nSkewDegY)
|
||||
{
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
HBITMAP hbm2 = SkewDIB(m_hDC, m_hBm, nSkewDegY, TRUE);
|
||||
InsertFromHBITMAP(hbm2, m_rcDest.left, m_rcDest.top);
|
||||
DeleteObject(hbm2);
|
||||
::SelectObject(hDC, m_hbmColor);
|
||||
HBITMAP hbm2 = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE);
|
||||
InsertFromHBITMAP(hbm2, m_rc.left, m_rc.top);
|
||||
::DeleteObject(hbm2);
|
||||
}
|
||||
|
||||
selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
selectionWindow.ForceRefreshSelectionContents();
|
||||
placeSelWin();
|
||||
::DeleteDC(hDC);
|
||||
|
||||
m_bShow = TRUE;
|
||||
NotifyRefreshNeeded();
|
||||
}
|
||||
|
||||
HBITMAP SelectionModel::GetBitmap() const
|
||||
{
|
||||
return m_hBm;
|
||||
return m_hbmColor;
|
||||
}
|
||||
|
||||
int SelectionModel::PtStackSize() const
|
||||
|
@ -291,114 +361,92 @@ int SelectionModel::PtStackSize() const
|
|||
|
||||
void SelectionModel::DrawFramePoly(HDC hDCImage)
|
||||
{
|
||||
Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); /* draw the freehand selection inverted/xored */
|
||||
/* draw the freehand selection inverted/xored */
|
||||
Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE);
|
||||
}
|
||||
|
||||
void SelectionModel::SetSrcAndDestRectFromPoints(const POINT& ptFrom, const POINT& ptTo)
|
||||
void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo)
|
||||
{
|
||||
m_rcDest.left = m_rcSrc.left = min(ptFrom.x, ptTo.x);
|
||||
m_rcDest.top = m_rcSrc.top = min(ptFrom.y, ptTo.y);
|
||||
m_rcDest.right = m_rcSrc.right = max(ptFrom.x, ptTo.x);
|
||||
m_rcDest.bottom = m_rcSrc.bottom = max(ptFrom.y, ptTo.y);
|
||||
m_rc.left = min(ptFrom.x, ptTo.x);
|
||||
m_rc.top = min(ptFrom.y, ptTo.y);
|
||||
m_rc.right = max(ptFrom.x, ptTo.x);
|
||||
m_rc.bottom = max(ptFrom.y, ptTo.y);
|
||||
}
|
||||
|
||||
void SelectionModel::SetSrcRectSizeToZero()
|
||||
void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt)
|
||||
{
|
||||
m_rcSrc.right = m_rcSrc.left;
|
||||
m_rcSrc.bottom = m_rcSrc.top;
|
||||
}
|
||||
|
||||
BOOL SelectionModel::IsSrcRectSizeNonzero() const
|
||||
{
|
||||
return (RECT_WIDTH(m_rcSrc) != 0) && (RECT_HEIGHT(m_rcSrc) != 0);
|
||||
}
|
||||
|
||||
void SelectionModel::ModifyDestRect(POINT& ptDelta, int iAction)
|
||||
{
|
||||
POINT ptDeltaUsed;
|
||||
|
||||
switch (iAction)
|
||||
switch (hit)
|
||||
{
|
||||
case ACTION_MOVE: /* move selection */
|
||||
ptDeltaUsed.x = ptDelta.x;
|
||||
ptDeltaUsed.y = ptDelta.y;
|
||||
OffsetRect(&m_rcDest, ptDeltaUsed.x, ptDeltaUsed.y);
|
||||
case HIT_NONE:
|
||||
break;
|
||||
case ACTION_RESIZE_TOP_LEFT: /* resize at upper left corner */
|
||||
ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
|
||||
ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
|
||||
m_rcDest.left += ptDeltaUsed.x;
|
||||
m_rcDest.top += ptDeltaUsed.y;
|
||||
case HIT_UPPER_LEFT:
|
||||
m_rc.left += pt.x - m_ptHit.x;
|
||||
m_rc.top += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_TOP: /* resize at top edge */
|
||||
ptDeltaUsed.x = ptDelta.x;
|
||||
ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
|
||||
m_rcDest.top += ptDeltaUsed.y;
|
||||
case HIT_UPPER_CENTER:
|
||||
m_rc.top += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_TOP_RIGHT: /* resize at upper right corner */
|
||||
ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
|
||||
ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
|
||||
m_rcDest.top += ptDeltaUsed.y;
|
||||
m_rcDest.right += ptDeltaUsed.x;
|
||||
case HIT_UPPER_RIGHT:
|
||||
m_rc.right += pt.x - m_ptHit.x;
|
||||
m_rc.top += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_LEFT: /* resize at left edge */
|
||||
ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
|
||||
ptDeltaUsed.y = ptDelta.y;
|
||||
m_rcDest.left += ptDeltaUsed.x;
|
||||
case HIT_MIDDLE_LEFT:
|
||||
m_rc.left += pt.x - m_ptHit.x;
|
||||
break;
|
||||
case ACTION_RESIZE_RIGHT: /* resize at right edge */
|
||||
ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
|
||||
ptDeltaUsed.y = ptDelta.y;
|
||||
m_rcDest.right += ptDeltaUsed.x;
|
||||
case HIT_MIDDLE_RIGHT:
|
||||
m_rc.right += pt.x - m_ptHit.x;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM_LEFT: /* resize at lower left corner */
|
||||
ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
|
||||
ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
|
||||
m_rcDest.left += ptDeltaUsed.x;
|
||||
m_rcDest.bottom += ptDeltaUsed.y;
|
||||
case HIT_LOWER_LEFT:
|
||||
m_rc.left += pt.x - m_ptHit.x;
|
||||
m_rc.bottom += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM: /* resize at bottom edge */
|
||||
ptDeltaUsed.x = ptDelta.x;
|
||||
ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
|
||||
m_rcDest.bottom += ptDeltaUsed.y;
|
||||
case HIT_LOWER_CENTER:
|
||||
m_rc.bottom += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM_RIGHT: /* resize at lower right corner */
|
||||
ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
|
||||
ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
|
||||
m_rcDest.right += ptDeltaUsed.x;
|
||||
m_rcDest.bottom += ptDeltaUsed.y;
|
||||
case HIT_LOWER_RIGHT:
|
||||
m_rc.right += pt.x - m_ptHit.x;
|
||||
m_rc.bottom += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case HIT_BORDER:
|
||||
case HIT_INNER:
|
||||
OffsetRect(&m_rc, pt.x - m_ptHit.x, pt.y - m_ptHit.y);
|
||||
break;
|
||||
}
|
||||
ptDelta.x -= ptDeltaUsed.x;
|
||||
ptDelta.y -= ptDeltaUsed.y;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectWidth() const
|
||||
{
|
||||
return m_rcDest.right - m_rcDest.left;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectHeight() const
|
||||
{
|
||||
return m_rcDest.bottom - m_rcDest.top;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectLeft() const
|
||||
{
|
||||
return m_rcDest.left;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectTop() const
|
||||
{
|
||||
return m_rcDest.top;
|
||||
m_ptHit = pt;
|
||||
}
|
||||
|
||||
void SelectionModel::NotifyRefreshNeeded()
|
||||
{
|
||||
selectionWindow.SendMessage(WM_SELECTIONMODELREFRESHNEEDED);
|
||||
imageArea.Invalidate(FALSE);
|
||||
}
|
||||
|
||||
void SelectionModel::GetRect(LPRECT prc) const
|
||||
void SelectionModel::ClearMask()
|
||||
{
|
||||
*prc = m_rcDest;
|
||||
if (m_hbmMask)
|
||||
{
|
||||
::DeleteObject(m_hbmMask);
|
||||
m_hbmMask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::ClearColor()
|
||||
{
|
||||
if (m_hbmColor)
|
||||
{
|
||||
::DeleteObject(m_hbmColor);
|
||||
m_hbmColor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::CancelSelection()
|
||||
{
|
||||
if (!m_bShow)
|
||||
return;
|
||||
|
||||
imageModel.CopyPrevious();
|
||||
if (m_bShow)
|
||||
imageModel.Undo(TRUE);
|
||||
|
||||
m_bShow = FALSE;
|
||||
imageArea.Invalidate(FALSE);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue