1c2c66affSColin Finck /* 2c2c66affSColin Finck * PROJECT: PAINT for ReactOS 3c2c66affSColin Finck * LICENSE: LGPL 4c2c66affSColin Finck * FILE: base/applications/mspaint/selectionmodel.cpp 5c2c66affSColin Finck * PURPOSE: Keep track of selection parameters, notify listeners 6c2c66affSColin Finck * PROGRAMMERS: Benedikt Freisen 73fa95ab9SKatayama Hirofumi MZ * Katayama Hirofumi MZ 8c2c66affSColin Finck */ 9c2c66affSColin Finck 10c2c66affSColin Finck #include "precomp.h" 11c2c66affSColin Finck 1229e147beSKatayama Hirofumi MZ SelectionModel selectionModel; 1329e147beSKatayama Hirofumi MZ 14c2c66affSColin Finck /* FUNCTIONS ********************************************************/ 15c2c66affSColin Finck 16c2c66affSColin Finck SelectionModel::SelectionModel() 17aac89519SKatayama Hirofumi MZ : m_hbmColor(NULL) 18aac89519SKatayama Hirofumi MZ , m_hbmMask(NULL) 193fa95ab9SKatayama Hirofumi MZ , m_ptStack(NULL) 203fa95ab9SKatayama Hirofumi MZ , m_iPtSP(0) 21*17bdf554SKatayama Hirofumi MZ , m_rgbBack(RGB(255, 255, 255)) 22aac89519SKatayama Hirofumi MZ , m_bShow(FALSE) 237aadc1e1SKatayama Hirofumi MZ , m_bContentChanged(FALSE) 24c2c66affSColin Finck { 25aac89519SKatayama Hirofumi MZ ::SetRectEmpty(&m_rc); 26e8c7e300SKatayama Hirofumi MZ ::SetRectEmpty(&m_rcOld); 27aac89519SKatayama Hirofumi MZ m_ptHit.x = m_ptHit.y = -1; 283fa95ab9SKatayama Hirofumi MZ } 29c2c66affSColin Finck 303fa95ab9SKatayama Hirofumi MZ SelectionModel::~SelectionModel() 313fa95ab9SKatayama Hirofumi MZ { 32aac89519SKatayama Hirofumi MZ ClearColor(); 33aac89519SKatayama Hirofumi MZ ClearMask(); 343fa95ab9SKatayama Hirofumi MZ ResetPtStack(); 35c2c66affSColin Finck } 36c2c66affSColin Finck 37c2c66affSColin Finck void SelectionModel::ResetPtStack() 38c2c66affSColin Finck { 39aac89519SKatayama Hirofumi MZ if (m_ptStack) 40aac89519SKatayama Hirofumi MZ { 41aac89519SKatayama Hirofumi MZ free(m_ptStack); 42c2c66affSColin Finck m_ptStack = NULL; 43aac89519SKatayama Hirofumi MZ } 44c2c66affSColin Finck m_iPtSP = 0; 45c2c66affSColin Finck } 46c2c66affSColin Finck 47aac89519SKatayama Hirofumi MZ void SelectionModel::PushToPtStack(POINT pt) 48c2c66affSColin Finck { 49aac89519SKatayama Hirofumi MZ #define GROW_COUNT 256 50aac89519SKatayama Hirofumi MZ if (m_iPtSP % GROW_COUNT == 0) 51c2c66affSColin Finck { 52aac89519SKatayama Hirofumi MZ INT nNewCount = m_iPtSP + GROW_COUNT; 53aac89519SKatayama Hirofumi MZ LPPOINT pptNew = (LPPOINT)realloc(m_ptStack, sizeof(POINT) * nNewCount); 54aac89519SKatayama Hirofumi MZ if (pptNew == NULL) 55aac89519SKatayama Hirofumi MZ return; 56aac89519SKatayama Hirofumi MZ m_ptStack = pptNew; 57c2c66affSColin Finck } 58aac89519SKatayama Hirofumi MZ m_ptStack[m_iPtSP] = pt; 59c2c66affSColin Finck m_iPtSP++; 60aac89519SKatayama Hirofumi MZ #undef GROW_COUNT 61c2c66affSColin Finck } 62c2c66affSColin Finck 63e8c7e300SKatayama Hirofumi MZ void SelectionModel::ShiftPtStack(INT dx, INT dy) 64c2c66affSColin Finck { 65aac89519SKatayama Hirofumi MZ for (INT i = 0; i < m_iPtSP; ++i) 66aac89519SKatayama Hirofumi MZ { 67aac89519SKatayama Hirofumi MZ POINT& pt = m_ptStack[i]; 68e8c7e300SKatayama Hirofumi MZ pt.x += dx; 69e8c7e300SKatayama Hirofumi MZ pt.y += dy; 70c2c66affSColin Finck } 71c2c66affSColin Finck } 72c2c66affSColin Finck 73aac89519SKatayama Hirofumi MZ void SelectionModel::BuildMaskFromPtStack() 74c2c66affSColin Finck { 75aac89519SKatayama Hirofumi MZ CRect rc = { MAXLONG, MAXLONG, 0, 0 }; 76aac89519SKatayama Hirofumi MZ for (INT i = 0; i < m_iPtSP; ++i) 77aac89519SKatayama Hirofumi MZ { 78aac89519SKatayama Hirofumi MZ POINT& pt = m_ptStack[i]; 79aac89519SKatayama Hirofumi MZ rc.left = min(pt.x, rc.left); 80aac89519SKatayama Hirofumi MZ rc.top = min(pt.y, rc.top); 81aac89519SKatayama Hirofumi MZ rc.right = max(pt.x, rc.right); 82aac89519SKatayama Hirofumi MZ rc.bottom = max(pt.y, rc.bottom); 83aac89519SKatayama Hirofumi MZ } 84aac89519SKatayama Hirofumi MZ rc.right += 1; 85aac89519SKatayama Hirofumi MZ rc.bottom += 1; 86aac89519SKatayama Hirofumi MZ 87e8c7e300SKatayama Hirofumi MZ m_rc = m_rcOld = rc; 88aac89519SKatayama Hirofumi MZ 89aac89519SKatayama Hirofumi MZ ClearMask(); 90aac89519SKatayama Hirofumi MZ 91e8c7e300SKatayama Hirofumi MZ ShiftPtStack(-m_rcOld.left, -m_rcOld.top); 92e8c7e300SKatayama Hirofumi MZ 93aac89519SKatayama Hirofumi MZ HDC hdcMem = ::CreateCompatibleDC(NULL); 94aac89519SKatayama Hirofumi MZ m_hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL); 95aac89519SKatayama Hirofumi MZ HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmMask); 96e8c7e300SKatayama Hirofumi MZ ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH)); 97aac89519SKatayama Hirofumi MZ HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN)); 98aac89519SKatayama Hirofumi MZ HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH)); 99aac89519SKatayama Hirofumi MZ ::Polygon(hdcMem, m_ptStack, m_iPtSP); 100aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, hbrOld); 101aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, hPenOld); 102aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, hbmOld); 103aac89519SKatayama Hirofumi MZ ::DeleteDC(hdcMem); 104e8c7e300SKatayama Hirofumi MZ 105e8c7e300SKatayama Hirofumi MZ ShiftPtStack(+m_rcOld.left, +m_rcOld.top); 106c2c66affSColin Finck } 107c2c66affSColin Finck 108c2c66affSColin Finck void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg) 109c2c66affSColin Finck { 110e8c7e300SKatayama Hirofumi MZ if (::IsRectEmpty(&m_rcOld)) 111e8c7e300SKatayama Hirofumi MZ return; 112aac89519SKatayama Hirofumi MZ 113aac89519SKatayama Hirofumi MZ HGDIOBJ hPenOld = ::SelectObject(hDCImage, ::GetStockObject(NULL_PEN)); 114aac89519SKatayama Hirofumi MZ HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::CreateSolidBrush(crBg)); 115aac89519SKatayama Hirofumi MZ ::Polygon(hDCImage, m_ptStack, m_iPtSP); 116aac89519SKatayama Hirofumi MZ ::DeleteObject(::SelectObject(hDCImage, hbrOld)); 117aac89519SKatayama Hirofumi MZ ::SelectObject(hDCImage, hPenOld); 118c2c66affSColin Finck } 119c2c66affSColin Finck 120c2c66affSColin Finck void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg) 121c2c66affSColin Finck { 122e8c7e300SKatayama Hirofumi MZ if (::IsRectEmpty(&m_rcOld)) 123e8c7e300SKatayama Hirofumi MZ return; 124e8c7e300SKatayama Hirofumi MZ 125e8c7e300SKatayama Hirofumi MZ Rect(hDCImage, m_rcOld.left, m_rcOld.top, m_rcOld.right, m_rcOld.bottom, crBg, crBg, 0, 1); 126c2c66affSColin Finck } 127c2c66affSColin Finck 1287aadc1e1SKatayama Hirofumi MZ void SelectionModel::DrawBackground(HDC hDCImage) 1297aadc1e1SKatayama Hirofumi MZ { 1307aadc1e1SKatayama Hirofumi MZ if (toolsModel.GetActiveTool() == TOOL_FREESEL) 1317aadc1e1SKatayama Hirofumi MZ DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor()); 1327aadc1e1SKatayama Hirofumi MZ else 1337aadc1e1SKatayama Hirofumi MZ DrawBackgroundRect(hDCImage, paletteModel.GetBgColor()); 1347aadc1e1SKatayama Hirofumi MZ } 1357aadc1e1SKatayama Hirofumi MZ 136e8c7e300SKatayama Hirofumi MZ void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent) 137c2c66affSColin Finck { 138e8c7e300SKatayama Hirofumi MZ CRect rc = m_rc; 139aac89519SKatayama Hirofumi MZ if (::IsRectEmpty(&rc)) 140aac89519SKatayama Hirofumi MZ return; 141aac89519SKatayama Hirofumi MZ 142aac89519SKatayama Hirofumi MZ BITMAP bm; 143e8c7e300SKatayama Hirofumi MZ if (!GetObject(m_hbmColor, sizeof(BITMAP), &bm)) 144e8c7e300SKatayama Hirofumi MZ return; 145aac89519SKatayama Hirofumi MZ 146aac89519SKatayama Hirofumi MZ COLORREF keyColor = (bBgTransparent ? crBg : CLR_INVALID); 147aac89519SKatayama Hirofumi MZ 148aac89519SKatayama Hirofumi MZ HDC hMemDC = CreateCompatibleDC(hDCImage); 149aac89519SKatayama Hirofumi MZ HGDIOBJ hbmOld = SelectObject(hMemDC, m_hbmColor); 150aac89519SKatayama Hirofumi MZ ColorKeyedMaskBlt(hDCImage, rc.left, rc.top, rc.Width(), rc.Height(), 151aac89519SKatayama Hirofumi MZ hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, m_hbmMask, keyColor); 152aac89519SKatayama Hirofumi MZ SelectObject(hMemDC, hbmOld); 153aac89519SKatayama Hirofumi MZ DeleteDC(hMemDC); 154aac89519SKatayama Hirofumi MZ } 155aac89519SKatayama Hirofumi MZ 156aac89519SKatayama Hirofumi MZ void SelectionModel::GetSelectionContents(HDC hDCImage) 157aac89519SKatayama Hirofumi MZ { 158aac89519SKatayama Hirofumi MZ ClearColor(); 159aac89519SKatayama Hirofumi MZ 160aac89519SKatayama Hirofumi MZ HDC hMemDC = ::CreateCompatibleDC(NULL); 161aac89519SKatayama Hirofumi MZ m_hbmColor = CreateColorDIB(m_rc.Width(), m_rc.Height(), RGB(255, 255, 255)); 162aac89519SKatayama Hirofumi MZ HGDIOBJ hbmOld = ::SelectObject(hMemDC, m_hbmColor); 163aac89519SKatayama Hirofumi MZ ::BitBlt(hMemDC, 0, 0, m_rc.Width(), m_rc.Height(), hDCImage, m_rc.left, m_rc.top, SRCCOPY); 164aac89519SKatayama Hirofumi MZ ::SelectObject(hMemDC, hbmOld); 165aac89519SKatayama Hirofumi MZ ::DeleteDC(hMemDC); 166aac89519SKatayama Hirofumi MZ } 167aac89519SKatayama Hirofumi MZ 168e8c7e300SKatayama Hirofumi MZ BOOL SelectionModel::IsLanded() const 169e8c7e300SKatayama Hirofumi MZ { 170e8c7e300SKatayama Hirofumi MZ return !m_hbmColor; 171e8c7e300SKatayama Hirofumi MZ } 172e8c7e300SKatayama Hirofumi MZ 173aac89519SKatayama Hirofumi MZ BOOL SelectionModel::TakeOff() 174aac89519SKatayama Hirofumi MZ { 175e8c7e300SKatayama Hirofumi MZ if (!IsLanded() || ::IsRectEmpty(&m_rc)) 176aac89519SKatayama Hirofumi MZ return FALSE; 177aac89519SKatayama Hirofumi MZ 178e8c7e300SKatayama Hirofumi MZ m_rgbBack = paletteModel.GetBgColor(); 179e8c7e300SKatayama Hirofumi MZ GetSelectionContents(imageModel.GetDC()); 180aac89519SKatayama Hirofumi MZ 181e8c7e300SKatayama Hirofumi MZ if (toolsModel.GetActiveTool() == TOOL_RECTSEL) 182aac89519SKatayama Hirofumi MZ ClearMask(); 183e8c7e300SKatayama Hirofumi MZ 184e8c7e300SKatayama Hirofumi MZ m_rcOld = m_rc; 185c2c66affSColin Finck 186bfd42c67SKatayama Hirofumi MZ imageModel.NotifyImageChanged(); 187aac89519SKatayama Hirofumi MZ return TRUE; 188c2c66affSColin Finck } 189c2c66affSColin Finck 190aac89519SKatayama Hirofumi MZ void SelectionModel::Landing() 191c2c66affSColin Finck { 192e8c7e300SKatayama Hirofumi MZ if (IsLanded() && !m_bShow) 193e8c7e300SKatayama Hirofumi MZ { 194e8c7e300SKatayama Hirofumi MZ imageModel.NotifyImageChanged(); 195aac89519SKatayama Hirofumi MZ return; 196e8c7e300SKatayama Hirofumi MZ } 197aac89519SKatayama Hirofumi MZ 198e8c7e300SKatayama Hirofumi MZ m_bShow = FALSE; 199aac89519SKatayama Hirofumi MZ 2007aadc1e1SKatayama Hirofumi MZ if (m_bContentChanged || 2017aadc1e1SKatayama Hirofumi MZ (!::EqualRect(m_rc, m_rcOld) && !::IsRectEmpty(m_rc) && !::IsRectEmpty(m_rcOld))) 202e8c7e300SKatayama Hirofumi MZ { 2032b623c1dSKatayama Hirofumi MZ imageModel.PushImageForUndo(); 204e8c7e300SKatayama Hirofumi MZ 205e8c7e300SKatayama Hirofumi MZ canvasWindow.m_drawing = FALSE; 206e8c7e300SKatayama Hirofumi MZ toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); 207e8c7e300SKatayama Hirofumi MZ } 208e8c7e300SKatayama Hirofumi MZ 209e8c7e300SKatayama Hirofumi MZ HideSelection(); 210c2c66affSColin Finck } 211c2c66affSColin Finck 2122d909190SKatayama Hirofumi MZ void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y) 213c2c66affSColin Finck { 214aac89519SKatayama Hirofumi MZ ::DeleteObject(m_hbmColor); 215639739a7SKatayama Hirofumi MZ m_hbmColor = CopyDIBImage(hBm); 216c2c66affSColin Finck 217aac89519SKatayama Hirofumi MZ m_rc.left = x; 218aac89519SKatayama Hirofumi MZ m_rc.top = y; 2199f56e67bSKatayama Hirofumi MZ m_rc.right = x + GetDIBWidth(hBm); 2209f56e67bSKatayama Hirofumi MZ m_rc.bottom = y + GetDIBHeight(hBm); 2219f56e67bSKatayama Hirofumi MZ 2227aadc1e1SKatayama Hirofumi MZ NotifyContentChanged(); 223c2c66affSColin Finck 224aac89519SKatayama Hirofumi MZ ClearMask(); 225c2c66affSColin Finck } 226c2c66affSColin Finck 227c2c66affSColin Finck void SelectionModel::FlipHorizontally() 228c2c66affSColin Finck { 229aac89519SKatayama Hirofumi MZ TakeOff(); 230aac89519SKatayama Hirofumi MZ 231aac89519SKatayama Hirofumi MZ HDC hdcMem = ::CreateCompatibleDC(NULL); 232aac89519SKatayama Hirofumi MZ if (m_hbmMask) 233aac89519SKatayama Hirofumi MZ { 234aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, m_hbmMask); 235aac89519SKatayama Hirofumi MZ ::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(), 236aac89519SKatayama Hirofumi MZ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); 237aac89519SKatayama Hirofumi MZ } 238aac89519SKatayama Hirofumi MZ if (m_hbmColor) 239aac89519SKatayama Hirofumi MZ { 240aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, m_hbmColor); 241aac89519SKatayama Hirofumi MZ ::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(), 242aac89519SKatayama Hirofumi MZ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); 243aac89519SKatayama Hirofumi MZ } 244aac89519SKatayama Hirofumi MZ ::DeleteDC(hdcMem); 245aac89519SKatayama Hirofumi MZ 2467aadc1e1SKatayama Hirofumi MZ NotifyContentChanged(); 247c2c66affSColin Finck } 248c2c66affSColin Finck 249c2c66affSColin Finck void SelectionModel::FlipVertically() 250c2c66affSColin Finck { 251aac89519SKatayama Hirofumi MZ TakeOff(); 252aac89519SKatayama Hirofumi MZ 253aac89519SKatayama Hirofumi MZ HDC hdcMem = ::CreateCompatibleDC(NULL); 254aac89519SKatayama Hirofumi MZ if (m_hbmMask) 255aac89519SKatayama Hirofumi MZ { 256aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, m_hbmMask); 257aac89519SKatayama Hirofumi MZ ::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(), 258aac89519SKatayama Hirofumi MZ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); 259aac89519SKatayama Hirofumi MZ } 260aac89519SKatayama Hirofumi MZ if (m_hbmColor) 261aac89519SKatayama Hirofumi MZ { 262aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, m_hbmColor); 263aac89519SKatayama Hirofumi MZ ::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(), 264aac89519SKatayama Hirofumi MZ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); 265aac89519SKatayama Hirofumi MZ } 266aac89519SKatayama Hirofumi MZ ::DeleteDC(hdcMem); 267aac89519SKatayama Hirofumi MZ 2687aadc1e1SKatayama Hirofumi MZ NotifyContentChanged(); 269c2c66affSColin Finck } 270c2c66affSColin Finck 271c2c66affSColin Finck void SelectionModel::RotateNTimes90Degrees(int iN) 272c2c66affSColin Finck { 2732d909190SKatayama Hirofumi MZ HBITMAP hbm; 274aac89519SKatayama Hirofumi MZ HGDIOBJ hbmOld; 275aac89519SKatayama Hirofumi MZ HDC hdcMem = ::CreateCompatibleDC(NULL); 276aac89519SKatayama Hirofumi MZ 2772d909190SKatayama Hirofumi MZ switch (iN) 278c2c66affSColin Finck { 2797aadc1e1SKatayama Hirofumi MZ case 1: /* rotate 90 degrees */ 2807aadc1e1SKatayama Hirofumi MZ case 3: /* rotate 270 degrees */ 281aac89519SKatayama Hirofumi MZ TakeOff(); 2827aadc1e1SKatayama Hirofumi MZ 283aac89519SKatayama Hirofumi MZ if (m_hbmColor) 284aac89519SKatayama Hirofumi MZ { 285aac89519SKatayama Hirofumi MZ hbmOld = ::SelectObject(hdcMem, m_hbmColor); 286aac89519SKatayama Hirofumi MZ hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1, FALSE); 287aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, hbmOld); 288aac89519SKatayama Hirofumi MZ ::DeleteObject(m_hbmColor); 289aac89519SKatayama Hirofumi MZ m_hbmColor = hbm; 290aac89519SKatayama Hirofumi MZ } 291aac89519SKatayama Hirofumi MZ if (m_hbmMask) 292aac89519SKatayama Hirofumi MZ { 293aac89519SKatayama Hirofumi MZ hbmOld = ::SelectObject(hdcMem, m_hbmMask); 294aac89519SKatayama Hirofumi MZ hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1, TRUE); 295aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, hbmOld); 296aac89519SKatayama Hirofumi MZ ::DeleteObject(m_hbmMask); 297aac89519SKatayama Hirofumi MZ m_hbmMask = hbm; 298aac89519SKatayama Hirofumi MZ } 2997aadc1e1SKatayama Hirofumi MZ 3007aadc1e1SKatayama Hirofumi MZ SwapWidthAndHeight(); 3012d909190SKatayama Hirofumi MZ break; 302aac89519SKatayama Hirofumi MZ 3037aadc1e1SKatayama Hirofumi MZ case 2: /* rotate 180 degrees */ 304aac89519SKatayama Hirofumi MZ TakeOff(); 3057aadc1e1SKatayama Hirofumi MZ 306aac89519SKatayama Hirofumi MZ if (m_hbmColor) 307aac89519SKatayama Hirofumi MZ { 308aac89519SKatayama Hirofumi MZ hbmOld = ::SelectObject(hdcMem, m_hbmColor); 309aac89519SKatayama Hirofumi MZ ::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(), -m_rc.Height(), 310aac89519SKatayama Hirofumi MZ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); 311aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, hbmOld); 312aac89519SKatayama Hirofumi MZ } 313aac89519SKatayama Hirofumi MZ if (m_hbmMask) 314aac89519SKatayama Hirofumi MZ { 315aac89519SKatayama Hirofumi MZ hbmOld = ::SelectObject(hdcMem, m_hbmMask); 316aac89519SKatayama Hirofumi MZ ::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(), -m_rc.Height(), 317aac89519SKatayama Hirofumi MZ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY); 318aac89519SKatayama Hirofumi MZ ::SelectObject(hdcMem, hbmOld); 319aac89519SKatayama Hirofumi MZ } 3202d909190SKatayama Hirofumi MZ break; 321c2c66affSColin Finck } 322aac89519SKatayama Hirofumi MZ 323aac89519SKatayama Hirofumi MZ ::DeleteDC(hdcMem); 3247aadc1e1SKatayama Hirofumi MZ NotifyContentChanged(); 325c2c66affSColin Finck } 326c2c66affSColin Finck 327dfd06ee8SKatayama Hirofumi MZ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int nSkewDegY) 328dfd06ee8SKatayama Hirofumi MZ { 329dfd06ee8SKatayama Hirofumi MZ if (nStretchPercentX == 100 && nStretchPercentY == 100 && nSkewDegX == 0 && nSkewDegY == 0) 330dfd06ee8SKatayama Hirofumi MZ return; 331dfd06ee8SKatayama Hirofumi MZ 332aac89519SKatayama Hirofumi MZ TakeOff(); 333dfd06ee8SKatayama Hirofumi MZ 334aac89519SKatayama Hirofumi MZ INT oldWidth = m_rc.Width(); 335aac89519SKatayama Hirofumi MZ INT oldHeight = m_rc.Height(); 336dfd06ee8SKatayama Hirofumi MZ INT newWidth = oldWidth * nStretchPercentX / 100; 337dfd06ee8SKatayama Hirofumi MZ INT newHeight = oldHeight * nStretchPercentY / 100; 338dfd06ee8SKatayama Hirofumi MZ 339dfd06ee8SKatayama Hirofumi MZ if (oldWidth != newWidth || oldHeight != newHeight) 340dfd06ee8SKatayama Hirofumi MZ { 341aac89519SKatayama Hirofumi MZ HBITMAP hbm0 = CopyDIBImage(m_hbmColor, newWidth, newHeight); 342aac89519SKatayama Hirofumi MZ InsertFromHBITMAP(hbm0, m_rc.left, m_rc.top); 343aac89519SKatayama Hirofumi MZ ::DeleteObject(hbm0); 344dfd06ee8SKatayama Hirofumi MZ } 345dfd06ee8SKatayama Hirofumi MZ 346aac89519SKatayama Hirofumi MZ HDC hDC = ::CreateCompatibleDC(NULL); 347aac89519SKatayama Hirofumi MZ 348dfd06ee8SKatayama Hirofumi MZ if (nSkewDegX) 349dfd06ee8SKatayama Hirofumi MZ { 350aac89519SKatayama Hirofumi MZ ::SelectObject(hDC, m_hbmColor); 351aac89519SKatayama Hirofumi MZ HBITMAP hbm1 = SkewDIB(hDC, m_hbmColor, nSkewDegX, FALSE); 352aac89519SKatayama Hirofumi MZ InsertFromHBITMAP(hbm1, m_rc.left, m_rc.top); 353aac89519SKatayama Hirofumi MZ ::DeleteObject(hbm1); 354dfd06ee8SKatayama Hirofumi MZ } 355dfd06ee8SKatayama Hirofumi MZ 356dfd06ee8SKatayama Hirofumi MZ if (nSkewDegY) 357dfd06ee8SKatayama Hirofumi MZ { 358aac89519SKatayama Hirofumi MZ ::SelectObject(hDC, m_hbmColor); 359aac89519SKatayama Hirofumi MZ HBITMAP hbm2 = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE); 360aac89519SKatayama Hirofumi MZ InsertFromHBITMAP(hbm2, m_rc.left, m_rc.top); 361aac89519SKatayama Hirofumi MZ ::DeleteObject(hbm2); 362dfd06ee8SKatayama Hirofumi MZ } 363dfd06ee8SKatayama Hirofumi MZ 364aac89519SKatayama Hirofumi MZ ::DeleteDC(hDC); 365aac89519SKatayama Hirofumi MZ 366aac89519SKatayama Hirofumi MZ m_bShow = TRUE; 3677aadc1e1SKatayama Hirofumi MZ NotifyContentChanged(); 368dfd06ee8SKatayama Hirofumi MZ } 369dfd06ee8SKatayama Hirofumi MZ 370e8c7e300SKatayama Hirofumi MZ HBITMAP SelectionModel::CopyBitmap() 371c2c66affSColin Finck { 37296c7fe4cSKatayama Hirofumi MZ if (m_hbmColor == NULL) 37396c7fe4cSKatayama Hirofumi MZ GetSelectionContents(imageModel.GetDC()); 374e8c7e300SKatayama Hirofumi MZ return CopyDIBImage(m_hbmColor); 375c2c66affSColin Finck } 376c2c66affSColin Finck 377b5536e44SKatayama Hirofumi MZ int SelectionModel::PtStackSize() const 378c2c66affSColin Finck { 379c2c66affSColin Finck return m_iPtSP; 380c2c66affSColin Finck } 381c2c66affSColin Finck 382c2c66affSColin Finck void SelectionModel::DrawFramePoly(HDC hDCImage) 383c2c66affSColin Finck { 384aac89519SKatayama Hirofumi MZ /* draw the freehand selection inverted/xored */ 385aac89519SKatayama Hirofumi MZ Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); 386c2c66affSColin Finck } 387c2c66affSColin Finck 388aac89519SKatayama Hirofumi MZ void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo) 389c2c66affSColin Finck { 390aac89519SKatayama Hirofumi MZ m_rc.left = min(ptFrom.x, ptTo.x); 391aac89519SKatayama Hirofumi MZ m_rc.top = min(ptFrom.y, ptTo.y); 392aac89519SKatayama Hirofumi MZ m_rc.right = max(ptFrom.x, ptTo.x); 393aac89519SKatayama Hirofumi MZ m_rc.bottom = max(ptFrom.y, ptTo.y); 394c2c66affSColin Finck } 395c2c66affSColin Finck 396aac89519SKatayama Hirofumi MZ void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt) 397c2c66affSColin Finck { 398aac89519SKatayama Hirofumi MZ switch (hit) 399c2c66affSColin Finck { 400aac89519SKatayama Hirofumi MZ case HIT_NONE: 401c2c66affSColin Finck break; 402aac89519SKatayama Hirofumi MZ case HIT_UPPER_LEFT: 403aac89519SKatayama Hirofumi MZ m_rc.left += pt.x - m_ptHit.x; 404aac89519SKatayama Hirofumi MZ m_rc.top += pt.y - m_ptHit.y; 405c2c66affSColin Finck break; 406aac89519SKatayama Hirofumi MZ case HIT_UPPER_CENTER: 407aac89519SKatayama Hirofumi MZ m_rc.top += pt.y - m_ptHit.y; 408c2c66affSColin Finck break; 409aac89519SKatayama Hirofumi MZ case HIT_UPPER_RIGHT: 410aac89519SKatayama Hirofumi MZ m_rc.right += pt.x - m_ptHit.x; 411aac89519SKatayama Hirofumi MZ m_rc.top += pt.y - m_ptHit.y; 412c2c66affSColin Finck break; 413aac89519SKatayama Hirofumi MZ case HIT_MIDDLE_LEFT: 414aac89519SKatayama Hirofumi MZ m_rc.left += pt.x - m_ptHit.x; 415c2c66affSColin Finck break; 416aac89519SKatayama Hirofumi MZ case HIT_MIDDLE_RIGHT: 417aac89519SKatayama Hirofumi MZ m_rc.right += pt.x - m_ptHit.x; 418c2c66affSColin Finck break; 419aac89519SKatayama Hirofumi MZ case HIT_LOWER_LEFT: 420aac89519SKatayama Hirofumi MZ m_rc.left += pt.x - m_ptHit.x; 421aac89519SKatayama Hirofumi MZ m_rc.bottom += pt.y - m_ptHit.y; 422c2c66affSColin Finck break; 423aac89519SKatayama Hirofumi MZ case HIT_LOWER_CENTER: 424aac89519SKatayama Hirofumi MZ m_rc.bottom += pt.y - m_ptHit.y; 425c2c66affSColin Finck break; 426aac89519SKatayama Hirofumi MZ case HIT_LOWER_RIGHT: 427aac89519SKatayama Hirofumi MZ m_rc.right += pt.x - m_ptHit.x; 428aac89519SKatayama Hirofumi MZ m_rc.bottom += pt.y - m_ptHit.y; 429aac89519SKatayama Hirofumi MZ break; 430aac89519SKatayama Hirofumi MZ case HIT_BORDER: 431aac89519SKatayama Hirofumi MZ case HIT_INNER: 432aac89519SKatayama Hirofumi MZ OffsetRect(&m_rc, pt.x - m_ptHit.x, pt.y - m_ptHit.y); 433c2c66affSColin Finck break; 434c2c66affSColin Finck } 435aac89519SKatayama Hirofumi MZ m_ptHit = pt; 436c2c66affSColin Finck } 437c2c66affSColin Finck 438aac89519SKatayama Hirofumi MZ void SelectionModel::ClearMask() 439361a2ce4SKatayama Hirofumi MZ { 440aac89519SKatayama Hirofumi MZ if (m_hbmMask) 441aac89519SKatayama Hirofumi MZ { 442aac89519SKatayama Hirofumi MZ ::DeleteObject(m_hbmMask); 443aac89519SKatayama Hirofumi MZ m_hbmMask = NULL; 444aac89519SKatayama Hirofumi MZ } 445aac89519SKatayama Hirofumi MZ } 446aac89519SKatayama Hirofumi MZ 447aac89519SKatayama Hirofumi MZ void SelectionModel::ClearColor() 448aac89519SKatayama Hirofumi MZ { 449aac89519SKatayama Hirofumi MZ if (m_hbmColor) 450aac89519SKatayama Hirofumi MZ { 451aac89519SKatayama Hirofumi MZ ::DeleteObject(m_hbmColor); 452aac89519SKatayama Hirofumi MZ m_hbmColor = NULL; 453aac89519SKatayama Hirofumi MZ } 454aac89519SKatayama Hirofumi MZ } 455aac89519SKatayama Hirofumi MZ 456e8c7e300SKatayama Hirofumi MZ void SelectionModel::HideSelection() 457e8c7e300SKatayama Hirofumi MZ { 4587aadc1e1SKatayama Hirofumi MZ m_bShow = m_bContentChanged = FALSE; 459e8c7e300SKatayama Hirofumi MZ ClearColor(); 460e8c7e300SKatayama Hirofumi MZ ClearMask(); 461e8c7e300SKatayama Hirofumi MZ ::SetRectEmpty(&m_rc); 462e8c7e300SKatayama Hirofumi MZ ::SetRectEmpty(&m_rcOld); 463e8c7e300SKatayama Hirofumi MZ imageModel.NotifyImageChanged(); 464e8c7e300SKatayama Hirofumi MZ } 465e8c7e300SKatayama Hirofumi MZ 466e8c7e300SKatayama Hirofumi MZ void SelectionModel::DeleteSelection() 467aac89519SKatayama Hirofumi MZ { 468aac89519SKatayama Hirofumi MZ if (!m_bShow) 469aac89519SKatayama Hirofumi MZ return; 470aac89519SKatayama Hirofumi MZ 471e8c7e300SKatayama Hirofumi MZ TakeOff(); 472e8c7e300SKatayama Hirofumi MZ imageModel.PushImageForUndo(); 4737aadc1e1SKatayama Hirofumi MZ DrawBackground(imageModel.GetDC()); 474e8c7e300SKatayama Hirofumi MZ 475e8c7e300SKatayama Hirofumi MZ HideSelection(); 476361a2ce4SKatayama Hirofumi MZ } 4777aadc1e1SKatayama Hirofumi MZ 4787aadc1e1SKatayama Hirofumi MZ void SelectionModel::InvertSelection() 4797aadc1e1SKatayama Hirofumi MZ { 4807aadc1e1SKatayama Hirofumi MZ TakeOff(); 4817aadc1e1SKatayama Hirofumi MZ 4827aadc1e1SKatayama Hirofumi MZ BITMAP bm; 4837aadc1e1SKatayama Hirofumi MZ ::GetObject(m_hbmColor, sizeof(bm), &bm); 4847aadc1e1SKatayama Hirofumi MZ 4857aadc1e1SKatayama Hirofumi MZ HDC hdc = ::CreateCompatibleDC(NULL); 4867aadc1e1SKatayama Hirofumi MZ HGDIOBJ hbmOld = ::SelectObject(hdc, m_hbmColor); 4877aadc1e1SKatayama Hirofumi MZ RECT rc = { 0, 0, bm.bmWidth, bm.bmHeight }; 4887aadc1e1SKatayama Hirofumi MZ ::InvertRect(hdc, &rc); 4897aadc1e1SKatayama Hirofumi MZ ::SelectObject(hdc, hbmOld); 4907aadc1e1SKatayama Hirofumi MZ ::DeleteDC(hdc); 4917aadc1e1SKatayama Hirofumi MZ 4927aadc1e1SKatayama Hirofumi MZ NotifyContentChanged(); 4937aadc1e1SKatayama Hirofumi MZ } 4947aadc1e1SKatayama Hirofumi MZ 4957aadc1e1SKatayama Hirofumi MZ void SelectionModel::NotifyContentChanged() 4967aadc1e1SKatayama Hirofumi MZ { 4977aadc1e1SKatayama Hirofumi MZ m_bContentChanged = TRUE; 4987aadc1e1SKatayama Hirofumi MZ imageModel.NotifyImageChanged(); 4997aadc1e1SKatayama Hirofumi MZ } 5007aadc1e1SKatayama Hirofumi MZ 5017aadc1e1SKatayama Hirofumi MZ void SelectionModel::SwapWidthAndHeight() 5027aadc1e1SKatayama Hirofumi MZ { 5037aadc1e1SKatayama Hirofumi MZ INT cx = m_rc.Width(); 5047aadc1e1SKatayama Hirofumi MZ INT cy = m_rc.Height(); 5057aadc1e1SKatayama Hirofumi MZ m_rc.right = m_rc.left + cy; 5067aadc1e1SKatayama Hirofumi MZ m_rc.bottom = m_rc.top + cx; 5077aadc1e1SKatayama Hirofumi MZ } 508