ReactOS 0.4.15-dev-6068-g8061a6f
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#include "precomp.h"
11
13
14/* FUNCTIONS ********************************************************/
15
17 : m_hbmColor(NULL)
18 , m_hbmMask(NULL)
19 , m_ptStack(NULL)
20 , m_iPtSP(0)
21 , m_bShow(FALSE)
22{
24 m_ptHit.x = m_ptHit.y = -1;
25}
26
28{
29 ClearColor();
30 ClearMask();
32}
33
35{
36 if (m_ptStack)
37 {
40 }
41 m_iPtSP = 0;
42}
43
45{
46#define GROW_COUNT 256
47 if (m_iPtSP % GROW_COUNT == 0)
48 {
49 INT nNewCount = m_iPtSP + GROW_COUNT;
50 LPPOINT pptNew = (LPPOINT)realloc(m_ptStack, sizeof(POINT) * nNewCount);
51 if (pptNew == NULL)
52 return;
53 m_ptStack = pptNew;
54 }
56 m_iPtSP++;
57#undef GROW_COUNT
58}
59
61{
62 if (bPlus)
63 {
64 for (INT i = 0; i < m_iPtSP; ++i)
65 {
66 POINT& pt = m_ptStack[i];
67 pt.x += m_rc.left;
68 pt.y += m_rc.top;
69 }
70 }
71 else
72 {
73 for (INT i = 0; i < m_iPtSP; ++i)
74 {
75 POINT& pt = m_ptStack[i];
76 pt.x -= m_rc.left;
77 pt.y -= m_rc.top;
78 }
79 }
80}
81
83{
84 CRect rc = { MAXLONG, MAXLONG, 0, 0 };
85 for (INT i = 0; i < m_iPtSP; ++i)
86 {
87 POINT& pt = m_ptStack[i];
88 rc.left = min(pt.x, rc.left);
89 rc.top = min(pt.y, rc.top);
90 rc.right = max(pt.x, rc.right);
91 rc.bottom = max(pt.y, rc.bottom);
92 }
93 rc.right += 1;
94 rc.bottom += 1;
95
96 m_rc = rc;
97
99
100 ClearMask();
101
103 m_hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL);
109 ::SelectObject(hdcMem, hbrOld);
110 ::SelectObject(hdcMem, hPenOld);
111 ::SelectObject(hdcMem, hbmOld);
113}
114
116{
118
119 HGDIOBJ hPenOld = ::SelectObject(hDCImage, ::GetStockObject(NULL_PEN));
120 HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::CreateSolidBrush(crBg));
121 ::Polygon(hDCImage, m_ptStack, m_iPtSP);
122 ::DeleteObject(::SelectObject(hDCImage, hbrOld));
123 ::SelectObject(hDCImage, hPenOld);
124
126}
127
129{
130 Rect(hDCImage, m_rc.left, m_rc.top, m_rc.right, m_rc.bottom, crBg, crBg, 0, 1);
131}
132
133void SelectionModel::DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg, BOOL bBgTransparent)
134{
135 CRect rc = *prc;
136 if (::IsRectEmpty(&rc))
137 return;
138
139 BITMAP bm;
140 GetObject(m_hbmColor, sizeof(BITMAP), &bm);
141
142 COLORREF keyColor = (bBgTransparent ? crBg : CLR_INVALID);
143
144 HDC hMemDC = CreateCompatibleDC(hDCImage);
145 HGDIOBJ hbmOld = SelectObject(hMemDC, m_hbmColor);
146 ColorKeyedMaskBlt(hDCImage, rc.left, rc.top, rc.Width(), rc.Height(),
147 hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, m_hbmMask, keyColor);
148 SelectObject(hMemDC, hbmOld);
149 DeleteDC(hMemDC);
150}
151
153{
154 ClearColor();
155
156 HDC hMemDC = ::CreateCompatibleDC(NULL);
157 m_hbmColor = CreateColorDIB(m_rc.Width(), m_rc.Height(), RGB(255, 255, 255));
158 HGDIOBJ hbmOld = ::SelectObject(hMemDC, m_hbmColor);
159 ::BitBlt(hMemDC, 0, 0, m_rc.Width(), m_rc.Height(), hDCImage, m_rc.left, m_rc.top, SRCCOPY);
160 ::SelectObject(hMemDC, hbmOld);
161 ::DeleteDC(hMemDC);
162}
163
165{
167 return FALSE;
168
169 HDC hDCImage = imageModel.GetDC();
170 GetSelectionContents(hDCImage);
171
173 {
175 }
176 else
177 {
178 ClearMask();
180 }
181
182 canvasWindow.Invalidate(FALSE);
183 return TRUE;
184}
185
187{
188 if (!m_hbmColor)
189 return;
190
192
194 ClearMask();
195 ClearColor();
196
198}
199
201{
204
205 m_rc.left = x;
206 m_rc.top = y;
207 m_rc.right = m_rc.left + GetDIBWidth(hBm);
209
210 ClearMask();
211}
212
214{
215 TakeOff();
216
218 if (m_hbmMask)
219 {
222 hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
223 }
224 if (m_hbmColor)
225 {
228 hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
229 }
231
233}
234
236{
237 TakeOff();
238
240 if (m_hbmMask)
241 {
244 hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
245 }
246 if (m_hbmColor)
247 {
250 hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
251 }
253
255}
256
258{
259 HBITMAP hbm;
260 HGDIOBJ hbmOld;
262
263 switch (iN)
264 {
265 case 1:
266 case 3:
267 TakeOff();
268 if (m_hbmColor)
269 {
272 ::SelectObject(hdcMem, hbmOld);
274 m_hbmColor = hbm;
275 }
276 if (m_hbmMask)
277 {
280 ::SelectObject(hdcMem, hbmOld);
282 m_hbmMask = hbm;
283 }
284 break;
285
286 case 2:
287 TakeOff();
288 if (m_hbmColor)
289 {
292 hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
293 ::SelectObject(hdcMem, hbmOld);
294 }
295 if (m_hbmMask)
296 {
299 hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
300 ::SelectObject(hdcMem, hbmOld);
301 }
302 break;
303 }
304
307}
308
309void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int nSkewDegY)
310{
311 if (nStretchPercentX == 100 && nStretchPercentY == 100 && nSkewDegX == 0 && nSkewDegY == 0)
312 return;
313
314 TakeOff();
315
316 INT oldWidth = m_rc.Width();
317 INT oldHeight = m_rc.Height();
318 INT newWidth = oldWidth * nStretchPercentX / 100;
319 INT newHeight = oldHeight * nStretchPercentY / 100;
320
321 if (oldWidth != newWidth || oldHeight != newHeight)
322 {
323 HBITMAP hbm0 = CopyDIBImage(m_hbmColor, newWidth, newHeight);
325 ::DeleteObject(hbm0);
326 }
327
329
330 if (nSkewDegX)
331 {
333 HBITMAP hbm1 = SkewDIB(hDC, m_hbmColor, nSkewDegX, FALSE);
335 ::DeleteObject(hbm1);
336 }
337
338 if (nSkewDegY)
339 {
341 HBITMAP hbm2 = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE);
343 ::DeleteObject(hbm2);
344 }
345
347
348 m_bShow = TRUE;
350}
351
353{
354 if (m_hbmColor == NULL)
356 return m_hbmColor;
357}
358
360{
361 return m_iPtSP;
362}
363
365{
366 /* draw the freehand selection inverted/xored */
367 Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE);
368}
369
370void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo)
371{
372 m_rc.left = min(ptFrom.x, ptTo.x);
373 m_rc.top = min(ptFrom.y, ptTo.y);
374 m_rc.right = max(ptFrom.x, ptTo.x);
375 m_rc.bottom = max(ptFrom.y, ptTo.y);
376}
377
379{
380 switch (hit)
381 {
382 case HIT_NONE:
383 break;
384 case HIT_UPPER_LEFT:
385 m_rc.left += pt.x - m_ptHit.x;
386 m_rc.top += pt.y - m_ptHit.y;
387 break;
388 case HIT_UPPER_CENTER:
389 m_rc.top += pt.y - m_ptHit.y;
390 break;
391 case HIT_UPPER_RIGHT:
392 m_rc.right += pt.x - m_ptHit.x;
393 m_rc.top += pt.y - m_ptHit.y;
394 break;
395 case HIT_MIDDLE_LEFT:
396 m_rc.left += pt.x - m_ptHit.x;
397 break;
398 case HIT_MIDDLE_RIGHT:
399 m_rc.right += pt.x - m_ptHit.x;
400 break;
401 case HIT_LOWER_LEFT:
402 m_rc.left += pt.x - m_ptHit.x;
403 m_rc.bottom += pt.y - m_ptHit.y;
404 break;
405 case HIT_LOWER_CENTER:
406 m_rc.bottom += pt.y - m_ptHit.y;
407 break;
408 case HIT_LOWER_RIGHT:
409 m_rc.right += pt.x - m_ptHit.x;
410 m_rc.bottom += pt.y - m_ptHit.y;
411 break;
412 case HIT_BORDER:
413 case HIT_INNER:
414 OffsetRect(&m_rc, pt.x - m_ptHit.x, pt.y - m_ptHit.y);
415 break;
416 }
417 m_ptHit = pt;
418}
419
421{
422 canvasWindow.Invalidate(FALSE);
423}
424
426{
427 if (m_hbmMask)
428 {
430 m_hbmMask = NULL;
431 }
432}
433
435{
436 if (m_hbmColor)
437 {
440 }
441}
442
444{
445 if (!m_bShow)
446 return;
447
449 if (m_bShow)
451
452 m_bShow = FALSE;
453 canvasWindow.Invalidate(FALSE);
454}
static HDC hDC
Definition: 3dtext.c:33
CANVAS_HITTEST
Definition: common.h:41
@ HIT_NONE
Definition: common.h:42
@ HIT_BORDER
Definition: common.h:51
@ HIT_LOWER_RIGHT
Definition: common.h:50
@ HIT_LOWER_CENTER
Definition: common.h:49
@ HIT_UPPER_LEFT
Definition: common.h:43
@ HIT_INNER
Definition: common.h:52
@ HIT_LOWER_LEFT
Definition: common.h:48
@ HIT_UPPER_CENTER
Definition: common.h:44
@ HIT_UPPER_RIGHT
Definition: common.h:45
@ HIT_MIDDLE_RIGHT
Definition: common.h:47
@ HIT_MIDDLE_LEFT
Definition: common.h:46
static HBITMAP CopyDIBImage(HBITMAP hbm, INT cx=0, INT cy=0)
Definition: dib.h:14
CCanvasWindow canvasWindow
Definition: canvas.cpp:11
int Width() const
Definition: atltypes.h:407
int Height() const
Definition: atltypes.h:318
void CopyPrevious(void)
Definition: history.cpp:47
void Undo(BOOL bClearRedo=FALSE)
Definition: history.cpp:60
HDC GetDC()
Definition: history.cpp:239
COLORREF GetBgColor() const
HBITMAP m_hbmColor
void InsertFromHBITMAP(HBITMAP hBm, INT x=0, INT y=0)
void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg)
void RotateNTimes90Degrees(int iN)
void StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int nSkewDegY)
void GetSelectionContents(HDC hDCImage)
void NotifyRefreshNeeded()
void PushToPtStack(POINT pt)
void BuildMaskFromPtStack()
int PtStackSize() const
void Dragging(CANVAS_HITTEST hit, POINT pt)
void ShiftPtStack(BOOL bPlus)
void DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg=0, BOOL bBgTransparent=FALSE)
void DrawFramePoly(HDC hDCImage)
void SetRectFromPoints(const POINT &ptFrom, const POINT &ptTo)
void DrawBackgroundRect(HDC hDCImage, COLORREF crBg)
BOOL IsBackgroundTransparent() const
Definition: toolsmodel.cpp:135
TOOLTYPE GetActiveTool() const
Definition: toolsmodel.cpp:76
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono)
Definition: dib.cpp:224
HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical)
Definition: dib.cpp:267
int GetDIBHeight(HBITMAP hBitmap)
Definition: dib.cpp:72
HBITMAP CreateColorDIB(int width, int height, COLORREF rgb)
Definition: dib.cpp:41
int GetDIBWidth(HBITMAP hBitmap)
Definition: dib.cpp:64
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define pt(x, y)
Definition: drawing.c:79
void Poly(HDC hdc, POINT *lpPoints, int nCount, COLORREF fg, COLORREF bg, int thickness, int style, BOOL closed, BOOL inverted)
Definition: drawing.cpp:70
BOOL ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight, HBITMAP hbmMask, COLORREF keyColor)
Definition: drawing.cpp:292
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
#define RGB(r, g, b)
Definition: precomp.h:62
unsigned int BOOL
Definition: ntddk_ex.h:94
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
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
ToolsModel toolsModel
Definition: toolsmodel.cpp:11
ImageModel imageModel
Definition: history.cpp:11
PaletteModel paletteModel
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:92
#define min(a, b)
Definition: monoChain.cc:55
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
_Out_ LPRECT prc
Definition: ntgdi.h:1658
BOOL Polygon(CONST PPOINT UnsafePoints, int Count, int polyFillMode)
Definition: polytest.cpp:730
#define GROW_COUNT
SelectionModel selectionModel
Definition: bl.h:1331
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
#define max(a, b)
Definition: svc.c:63
@ TOOL_FREESEL
Definition: toolsmodel.h:13
int32_t INT
Definition: typedefs.h:58
#define MAXLONG
Definition: umtypes.h:116
HDC hdcMem
Definition: welcome.c:104
#define LPPOINT
Definition: precomp.h:31
DWORD COLORREF
Definition: windef.h:300
HGDIOBJ WINAPI GetStockObject(_In_ int)
HBITMAP WINAPI CreateBitmap(_In_ INT cx, _In_ INT cy, _In_ UINT cPlanes, _In_ UINT cBitsPerPel, _In_opt_ const VOID *pvBits)
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
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 CLR_INVALID
Definition: wingdi.h:883
#define SRCCOPY
Definition: wingdi.h:333
#define WHITE_BRUSH
Definition: wingdi.h:902
#define NULL_PEN
Definition: wingdi.h:904
#define BLACK_BRUSH
Definition: wingdi.h:896
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
#define GetObject
Definition: wingdi.h:4468
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
BOOL WINAPI DeleteDC(_In_ HDC)
BOOL WINAPI IsRectEmpty(_In_ LPCRECT)
BOOL WINAPI SetRectEmpty(_Out_ LPRECT)
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)