ReactOS  0.4.15-dev-5500-g82cf6c2
selectionmodel.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: PAINT for ReactOS
3  * LICENSE: LGPL
4  * FILE: base/applications/mspaint/selectionmodel.cpp
5  * PURPOSE: Keep track of selection parameters, notify listeners
6  * PROGRAMMERS: Benedikt Freisen
7  * Katayama Hirofumi MZ
8  */
9 
10 /* INCLUDES *********************************************************/
11 
12 #include "precomp.h"
13 
14 /* FUNCTIONS ********************************************************/
15 
17  : m_hDC(CreateCompatibleDC(NULL))
18  , m_hBm(NULL)
19  , m_hMask(NULL)
20  , m_ptStack(NULL)
21  , m_iPtSP(0)
22 {
25 }
26 
28 {
29  DeleteDC(m_hDC);
30  ResetPtStack();
31  if (m_hBm)
32  {
34  }
35  if (m_hMask)
36  {
38  }
39 }
40 
42 {
43  if (m_ptStack != NULL)
45  m_ptStack = NULL;
46  m_iPtSP = 0;
47 }
48 
50 {
51  if (m_iPtSP % 1024 == 0)
52  {
53  if (m_ptStack)
55  else
57  }
58  m_ptStack[m_iPtSP].x = x;
59  m_ptStack[m_iPtSP].y = y;
60  m_iPtSP++;
61 }
62 
64 {
65  int i;
68  for (i = 0; i < m_iPtSP; i++)
69  {
70  if (m_ptStack[i].x < m_rcSrc.left)
72  if (m_ptStack[i].y < m_rcSrc.top)
73  m_rcSrc.top = m_ptStack[i].y;
74  if (m_ptStack[i].x > m_rcSrc.right)
76  if (m_ptStack[i].y > m_rcSrc.bottom)
78  }
79  m_rcSrc.right += 1;
80  m_rcSrc.bottom += 1;
85 
86  if (m_iPtSP > 1)
87  {
91  POINT *m_ptStackCopy = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * m_iPtSP);
92  for (i = 0; i < m_iPtSP; i++)
93  {
94  m_ptStackCopy[i].x = m_ptStack[i].x - m_rcSrc.left;
95  m_ptStackCopy[i].y = m_ptStack[i].y - m_rcSrc.top;
96  }
97  Poly(m_hDC, m_ptStackCopy, m_iPtSP, 0x00ffffff, 0x00ffffff, 1, 2, TRUE, FALSE);
98  HeapFree(GetProcessHeap(), 0, m_ptStackCopy);
103  }
104 }
105 
107 {
111  Rect(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 0x00ffffff, 0x00ffffff, 1, 2);
114  m_rcSrc.top, SRCCOPY);
115 }
116 
118 {
119  Poly(hDCImage, m_ptStack, m_iPtSP, crBg, crBg, 1, 2, TRUE, FALSE);
120 }
121 
123 {
124  Rect(hDCImage, m_rcSrc.left, m_rcSrc.top, m_rcSrc.right, m_rcSrc.bottom, crBg, crBg, 0, 1);
125 }
126 
127 void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent)
128 {
129  if (!bBgTransparent)
131  m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
132  else
134  m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND), crBg);
135 }
136 
138 {
140 }
141 
143 {
144  HDC hTempDC;
145  HBITMAP hTempBm;
146  hTempDC = CreateCompatibleDC(m_hDC);
148  SelectObject(hTempDC, hTempBm);
150  StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0,
153  m_hBm = hTempBm;
155  SelectObject(hTempDC, hTempBm);
157  StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0,
160  m_hMask = hTempBm;
162  DeleteDC(hTempDC);
163 }
164 
166 {
167  HDC hTempDC;
168  HBITMAP hTempMask;
169 
170  m_hBm = CopyDIBImage(hBm);
172 
174  m_rcDest.left = x;
175  m_rcDest.top = y;
178 
179  hTempDC = CreateCompatibleDC(m_hDC);
180  hTempMask = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL);
181  SelectObject(hTempDC, hTempMask);
182  Rect(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 0x00ffffff, 0x00ffffff, 1, 1);
184  m_hMask = hTempMask;
185  DeleteDC(hTempDC);
186 }
187 
189 {
197 }
198 
200 {
208 }
209 
211 {
212  HBITMAP hbm;
213  switch (iN)
214  {
215  case 1:
216  case 3:
222  DeleteObject(hbm);
225  placeSelWin();
226  break;
227  case 2:
234  break;
235  }
237 }
238 
239 void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int nSkewDegY)
240 {
241  if (nStretchPercentX == 100 && nStretchPercentY == 100 && nSkewDegX == 0 && nSkewDegY == 0)
242  return;
243 
246 
247  INT oldWidth = RECT_WIDTH(m_rcDest);
248  INT oldHeight = RECT_HEIGHT(m_rcDest);
249  INT newWidth = oldWidth * nStretchPercentX / 100;
250  INT newHeight = oldHeight * nStretchPercentY / 100;
251 
252  if (oldWidth != newWidth || oldHeight != newHeight)
253  {
255  HBITMAP hbm0 = CopyDIBImage(m_hBm, newWidth, newHeight);
257  DeleteObject(hbm0);
258  }
259 
260  if (nSkewDegX)
261  {
263  HBITMAP hbm1 = SkewDIB(m_hDC, m_hBm, nSkewDegX, FALSE);
265  DeleteObject(hbm1);
266  }
267 
268  if (nSkewDegY)
269  {
271  HBITMAP hbm2 = SkewDIB(m_hDC, m_hBm, nSkewDegY, TRUE);
273  DeleteObject(hbm2);
274  }
275 
278  placeSelWin();
280 }
281 
283 {
284  return m_hBm;
285 }
286 
288 {
289  return m_iPtSP;
290 }
291 
293 {
294  Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); /* draw the freehand selection inverted/xored */
295 }
296 
298 {
299  m_rcDest.left = m_rcSrc.left = min(ptFrom.x, ptTo.x);
300  m_rcDest.top = m_rcSrc.top = min(ptFrom.y, ptTo.y);
301  m_rcDest.right = m_rcSrc.right = max(ptFrom.x, ptTo.x);
302  m_rcDest.bottom = m_rcSrc.bottom = max(ptFrom.y, ptTo.y);
303 }
304 
306 {
309 }
310 
312 {
313  return (RECT_WIDTH(m_rcSrc) != 0) && (RECT_HEIGHT(m_rcSrc) != 0);
314 }
315 
316 void SelectionModel::ModifyDestRect(POINT& ptDelta, int iAction)
317 {
318  POINT ptDeltaUsed;
319 
320  switch (iAction)
321  {
322  case ACTION_MOVE: /* move selection */
323  ptDeltaUsed.x = ptDelta.x;
324  ptDeltaUsed.y = ptDelta.y;
325  OffsetRect(&m_rcDest, ptDeltaUsed.x, ptDeltaUsed.y);
326  break;
327  case ACTION_RESIZE_TOP_LEFT: /* resize at upper left corner */
328  ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
329  ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
330  m_rcDest.left += ptDeltaUsed.x;
331  m_rcDest.top += ptDeltaUsed.y;
332  break;
333  case ACTION_RESIZE_TOP: /* resize at top edge */
334  ptDeltaUsed.x = ptDelta.x;
335  ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
336  m_rcDest.top += ptDeltaUsed.y;
337  break;
338  case ACTION_RESIZE_TOP_RIGHT: /* resize at upper right corner */
339  ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
340  ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
341  m_rcDest.top += ptDeltaUsed.y;
342  m_rcDest.right += ptDeltaUsed.x;
343  break;
344  case ACTION_RESIZE_LEFT: /* resize at left edge */
345  ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
346  ptDeltaUsed.y = ptDelta.y;
347  m_rcDest.left += ptDeltaUsed.x;
348  break;
349  case ACTION_RESIZE_RIGHT: /* resize at right edge */
350  ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
351  ptDeltaUsed.y = ptDelta.y;
352  m_rcDest.right += ptDeltaUsed.x;
353  break;
354  case ACTION_RESIZE_BOTTOM_LEFT: /* resize at lower left corner */
355  ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
356  ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
357  m_rcDest.left += ptDeltaUsed.x;
358  m_rcDest.bottom += ptDeltaUsed.y;
359  break;
360  case ACTION_RESIZE_BOTTOM: /* resize at bottom edge */
361  ptDeltaUsed.x = ptDelta.x;
362  ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
363  m_rcDest.bottom += ptDeltaUsed.y;
364  break;
365  case ACTION_RESIZE_BOTTOM_RIGHT: /* resize at lower right corner */
366  ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
367  ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
368  m_rcDest.right += ptDeltaUsed.x;
369  m_rcDest.bottom += ptDeltaUsed.y;
370  break;
371  }
372  ptDelta.x -= ptDeltaUsed.x;
373  ptDelta.y -= ptDeltaUsed.y;
374 }
375 
377 {
378  return m_rcDest.right - m_rcDest.left;
379 }
380 
382 {
383  return m_rcDest.bottom - m_rcDest.top;
384 }
385 
387 {
388  return m_rcDest.left;
389 }
390 
392 {
393  return m_rcDest.top;
394 }
395 
397 {
399 }
400 
402 {
403  *prc = m_rcDest;
404 }
void DrawSelectionStretched(HDC hDCImage)
void StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX=0, int nSkewDegY=0)
int PtStackSize() const
void CopyPrevious(void)
Definition: history.cpp:47
#define max(a, b)
Definition: svc.c:63
void RotateNTimes90Degrees(int iN)
void DrawFramePoly(HDC hDCImage)
#define SW_SHOWNOACTIVATE
Definition: winuser.h:768
long y
Definition: polytest.cpp:48
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
void placeSelWin(void)
Definition: mouse.cpp:20
#define MAXLONG
Definition: umtypes.h:116
long x
Definition: polytest.cpp:48
#define ACTION_RESIZE_TOP_LEFT
LONG GetDestRectLeft() const
static HBITMAP CopyDIBImage(HBITMAP hbm, INT cx=0, INT cy=0)
Definition: dib.h:14
#define TRUE
Definition: types.h:120
void InsertFromHBITMAP(HBITMAP hBm, INT x=0, INT y=0)
void PushToPtStack(LONG x, LONG y)
static HDC
Definition: imagelist.c:92
LONG top
Definition: windef.h:307
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
BOOL WINAPI DeleteObject(_In_ HGDIOBJ)
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
#define ACTION_RESIZE_RIGHT
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
void CalculateContents(HDC hDCImage)
int GetDIBHeight(HBITMAP hBitmap)
Definition: dib.cpp:62
LONG left
Definition: windef.h:306
LONG GetDestRectWidth() const
LONG right
Definition: windef.h:308
void GetRect(LPRECT prc) const
int32_t INT
Definition: typedefs.h:58
BOOL WINAPI StretchBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_opt_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ DWORD)
#define RECT_HEIGHT(a)
Definition: common.h:21
HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical)
Definition: dib.cpp:252
int GetDIBWidth(HBITMAP hBitmap)
Definition: dib.cpp:54
#define RECT_WIDTH(a)
Definition: common.h:18
#define ACTION_RESIZE_BOTTOM_LEFT
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
HBITMAP CreateDIBWithProperties(int width, int height)
Definition: dib.cpp:17
#define MAKEROP4(f, b)
Definition: wingdi.h:2946
#define ACTION_RESIZE_TOP_RIGHT
void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg)
void Poly(HDC hdc, POINT *lpPoints, int nCount, COLORREF fg, COLORREF bg, int thickness, int style, BOOL closed, BOOL inverted)
Definition: drawing.cpp:70
#define POINT
Definition: precomp.h:30
void ModifyDestRect(POINT &ptDelta, int iAction)
void DrawBackgroundRect(HDC hDCImage, COLORREF crBg)
#define ACTION_MOVE
#define GetProcessHeap()
Definition: compat.h:736
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
DWORD COLORREF
Definition: windef.h:300
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight)
Definition: dib.cpp:213
#define ACTION_RESIZE_TOP
#define ACTION_RESIZE_LEFT
#define WM_SELECTIONMODELREFRESHNEEDED
Definition: precomp.h:39
BOOL IsSrcRectSizeNonzero() const
ImageModel imageModel
Definition: main.cpp:32
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
#define WHITENESS
Definition: wingdi.h:337
void ForceRefreshSelectionContents()
Definition: selection.cpp:24
LONG GetDestRectHeight() const
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void SetSrcRectSizeToZero()
BOOL WINAPI DeleteDC(_In_ HDC)
BOOL ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask, DWORD dwRop, COLORREF keyColor)
Definition: drawing.cpp:312
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
#define HeapReAlloc
Definition: compat.h:734
HBITMAP GetBitmap() const
#define min(a, b)
Definition: monoChain.cc:55
#define SRCAND
Definition: wingdi.h:330
#define NULL
Definition: types.h:112
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
void DrawSelection(HDC hDCImage, COLORREF crBg=0, BOOL bBgTransparent=FALSE)
void CalculateBoundingBoxAndContents(HDC hDCImage)
LONG GetDestRectTop() const
LONG bottom
Definition: windef.h:309
#define ACTION_RESIZE_BOTTOM
BOOL WINAPI MaskBlt(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int, _In_ HDC, _In_ int, _In_ int, _In_ HBITMAP, _In_ int, _In_ int, _In_ DWORD)
void NotifyRefreshNeeded()
static HBITMAP
Definition: button.c:44
void DeleteSelection()
Definition: history.cpp:293
#define ACTION_RESIZE_BOTTOM_RIGHT
_Out_ LPRECT prc
Definition: ntgdi.h:1658
#define HEAP_GENERATE_EXCEPTIONS
Definition: nt_native.h:1694
void ResetToPrevious(void)
Definition: history.cpp:100
#define HeapFree(x, y, z)
Definition: compat.h:735
#define SRCCOPY
Definition: wingdi.h:333
static VOID NTAPI BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Delta *Height) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Delta)
Definition: common.c:49
struct Rect Rect
CSelectionWindow selectionWindow
Definition: main.cpp:71
void SetSrcAndDestRectFromPoints(const POINT &ptFrom, const POINT &ptTo)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)