ReactOS 0.4.17-dev-243-g1369312
canvas.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4 * PURPOSE: Providing the canvas window class
5 * COPYRIGHT: Copyright 2015 Benedikt Freisen <b.freisen@gmx.net>
6 * Copyright 2026 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7 */
8
9#include "precomp.h"
10
12
13/* FUNCTIONS ********************************************************/
14
17{
18 const INT diameter = 2 * radius;
19 if (diameter <= 2)
20 {
22 return hCursor ? CopyCursor(hCursor) : NULL;
23 }
24
25 const INT crosshair1 = 6, crosshair2 = crosshair1 - 2;
26 const INT width = diameter + 2 * crosshair1, height = diameter + 2 * crosshair1;
27 const DWORD hotX = width / 2, hotY = height / 2;
28
29 HDC hdcScreen = ::GetDC(NULL);
30 if (!hdcScreen)
31 return NULL;
32 HDC hdcMem = ::CreateCompatibleDC(hdcScreen);
33 if (!hdcMem)
34 {
35 ::ReleaseDC(NULL, hdcScreen);
36 return NULL;
37 }
38
39 RECT rc = { 0, 0, width, height };
40
41 // Create the AND mask bitmap. This must be monochrome (1bpp):
42 // white bits are transparent, black bits are opaque.
43 HBITMAP hbmMask = ::CreateBitmap(width, height, 1, 1, NULL);
44 if (hbmMask)
45 {
46 HBITMAP hbmOld = (HBITMAP)::SelectObject(hdcMem, hbmMask);
47
48 // Fill with white brush
50
51 if (!is_rubber)
52 {
53 // Draw crosshair with white pen
55 ::MoveToEx(hdcMem, 0, hotY, NULL);
56 ::LineTo(hdcMem, crosshair2, hotY);
57 ::MoveToEx(hdcMem, width - crosshair2, hotY, NULL);
58 ::LineTo(hdcMem, width, hotY);
59 ::MoveToEx(hdcMem, hotX, 0, NULL);
60 ::LineTo(hdcMem, hotX, crosshair2);
61 ::MoveToEx(hdcMem, hotX, height - crosshair2, NULL);
62 ::LineTo(hdcMem, hotX, height);
63 }
64
65 // Draw brush or erase with black color
66 if (is_rubber)
67 Erase(hdcMem, hotX, hotY, hotX, hotY, RGB(0, 0, 0), radius + 1);
68 else
69 Brush(hdcMem, hotX, hotY, hotX, hotY, RGB(0, 0, 0), style, diameter);
70
71 if (is_rubber)
72 InflateRect(&rc, -1, -1);
73
74 ::SelectObject(hdcMem, hbmOld);
75 }
76
77 // Create the color (XOR) bitmap
78 HBITMAP hbmColor = ::CreateCompatibleBitmap(hdcScreen, width, height);
79 if (hbmColor)
80 {
81 HBITMAP hbmOld = (HBITMAP)::SelectObject(hdcMem, hbmColor);
82
83 // Fill with black brush
85
86 if (is_rubber)
87 {
88 // Draw for rubber border
89 INT avg = (GetRValue(color) + GetGValue(color) + GetBValue(color)) / 3;
90 COLORREF color2 = (avg > 255 / 2) ? RGB(0, 0, 0) : RGB(255, 255, 255);
91 Erase(hdcMem, hotX, hotY, hotX, hotY, color2, radius + 1);
92 }
93 else
94 {
95 // Draw crosshair with white pen
97 ::MoveToEx(hdcMem, 0, hotY, NULL);
98 ::LineTo(hdcMem, crosshair2, hotY);
99 ::MoveToEx(hdcMem, width - crosshair2, hotY, NULL);
100 ::LineTo(hdcMem, width, hotY);
101 ::MoveToEx(hdcMem, hotX, 0, NULL);
102 ::LineTo(hdcMem, hotX, crosshair2);
103 ::MoveToEx(hdcMem, hotX, height - crosshair2, NULL);
104 ::LineTo(hdcMem, hotX, height);
105 }
106
107 // Draw brush or erase with color
108 if (is_rubber)
109 Erase(hdcMem, hotX, hotY, hotX, hotY, color, radius);
110 else
111 Brush(hdcMem, hotX, hotY, hotX, hotY, color, style, diameter);
112
113 ::SelectObject(hdcMem, hbmOld);
114 }
115
116 ::ReleaseDC(NULL, hdcScreen);
118
119 ICONINFO ii = { FALSE, hotX, hotY, hbmMask, hbmColor };
120 HCURSOR hCursor = (HCURSOR)::CreateIconIndirect(&ii);
121
122 ::DeleteObject(hbmMask);
123 ::DeleteObject(hbmColor);
124
125 return hCursor;
126}
127
129{
130 if (m_hCursor && m_style == style && m_radius == radius && m_color == color &&
131 m_is_rubber == is_rubber)
132 {
133 return;
134 }
135
136 if (m_hCursor)
138
139 m_hCursor = CreateStyledCursor(style, radius, color, is_rubber);
140 m_style = style;
141 m_radius = radius;
142 m_color = color;
143 m_is_rubber = is_rubber;
144}
145
146CCanvasWindow::CCanvasWindow()
147 : m_drawing(FALSE)
148 , m_hitCanvasSizeBox(HIT_NONE)
149 , m_ptOrig { -1, -1 }
150{
151 m_rcResizing.SetRectEmpty();
152}
153
155{
156}
157
159{
160 CRect rcBase;
161 GetImageRect(rcBase);
162 ImageToCanvas(rcBase);
164 return rcBase;
165}
166
168{
169 Zoomed(pt);
172}
173
175{
176 Zoomed(rc);
178}
179
181{
184 UnZoomed(pt);
185}
186
188{
190 UnZoomed(rc);
191}
192
194{
195 rc = { 0, 0, imageModel.GetWidth(), imageModel.GetHeight() };
196}
197
199{
201 return HIT_INNER;
202 RECT rcBase = GetBaseRect();
203 return getSizeBoxHitTest(pt, &rcBase);
204}
205
207{
208 CRect rcImage;
209 GetImageRect(rcImage);
210 ImageToCanvas(rcImage);
211
212 // Calculate the zoom rectangle
213 INT oldZoom = toolsModel.GetZoom();
214 GetClientRect(rcView);
215 LONG cxView = rcView.right * oldZoom / newZoom, cyView = rcView.bottom * oldZoom / newZoom;
216 rcView.SetRect(ptTarget.x - cxView / 2, ptTarget.y - cyView / 2,
217 ptTarget.x + cxView / 2, ptTarget.y + cyView / 2);
218
219 // Shift the rectangle if necessary
220 INT dx = 0, dy = 0;
221 if (rcView.left < rcImage.left)
222 dx = rcImage.left - rcView.left;
223 else if (rcImage.right < rcView.right)
224 dx = rcImage.right - rcView.right;
225 if (rcView.top < rcImage.top)
226 dy = rcImage.top - rcView.top;
227 else if (rcImage.bottom < rcView.bottom)
228 dy = rcImage.bottom - rcView.bottom;
229 rcView.OffsetRect(dx, dy);
230
231 rcView.IntersectRect(&rcView, &rcImage);
232}
233
235{
236 POINT pt = { left, top };
238
239 toolsModel.SetZoom(newZoom);
241 pt.x += GetScrollPos(SB_HORZ);
242 pt.y += GetScrollPos(SB_VERT);
243
245 updateScrollPos(pt.x, pt.y);
246 Invalidate(TRUE);
247}
248
250{
251 // This is the target area we have to draw on
252 CRect rcCanvasDraw;
253 rcCanvasDraw.IntersectRect(&rcClient, &rcPaint);
254
255 // Calculate image size
256 CRect rcImage;
257 GetImageRect(rcImage);
258 SIZE sizeImage = { imageModel.GetWidth(), imageModel.GetHeight() };
259
260 // We use a memory bitmap to reduce flickering
261 HBITMAP hbmCache1 = CreateDIBWithProperties(rcClient.right, rcClient.bottom);
262 if (!hbmCache1)
263 return FALSE; // Out of memory
264 HBITMAP hbmCache2 = CreateDIBWithProperties(sizeImage.cx, sizeImage.cy);
265 if (!hbmCache2)
266 {
267 ::DeleteObject(hbmCache1);
268 return FALSE; // Out of memory
269 }
270
271 HDC hdcMem0 = ::CreateCompatibleDC(hDC);
272 HGDIOBJ hbm0Old = ::SelectObject(hdcMem0, hbmCache1);
273
274 // Fill the background on hdcMem0
275 ::FillRect(hdcMem0, &rcCanvasDraw, (HBRUSH)(COLOR_APPWORKSPACE + 1));
276
277 // Draw the sizeboxes if necessary
278 RECT rcBase = GetBaseRect();
280 drawSizeBoxes(hdcMem0, &rcBase, FALSE, &rcCanvasDraw);
281
282 // Calculate the target area on the image
283 CRect rcImageDraw = rcCanvasDraw;
284 CanvasToImage(rcImageDraw);
285 rcImageDraw.IntersectRect(&rcImageDraw, &rcImage);
286
287 // Consider rounding down by zooming
288 rcImageDraw.right += 1;
289 rcImageDraw.bottom += 1;
290
291 // hdcMem1 <-- imageModel
292 HDC hdcMem1 = ::CreateCompatibleDC(hDC);
293 HGDIOBJ hbm1Old = ::SelectObject(hdcMem1, hbmCache2);
294 ::BitBlt(hdcMem1, rcImageDraw.left, rcImageDraw.top, rcImageDraw.Width(), rcImageDraw.Height(),
295 imageModel.GetDC(), rcImageDraw.left, rcImageDraw.top, SRCCOPY);
296
297 // Draw overlay #1 on hdcMem1
299
300 // Transfer the bits with stretch (hdcMem0 <-- hdcMem1)
301 ImageToCanvas(rcImage);
302 ::StretchBlt(hdcMem0, rcImage.left, rcImage.top, rcImage.Width(), rcImage.Height(),
303 hdcMem1, 0, 0, sizeImage.cx, sizeImage.cy, SRCCOPY);
304
305 // Clean up hdcMem1
306 ::SelectObject(hdcMem1, hbm1Old);
307 ::DeleteDC(hdcMem1);
308
309 // Draw the grid on hdcMem0
310 if (g_showGrid && toolsModel.GetZoom() >= 4000)
311 {
312 HPEN oldPen = (HPEN) ::SelectObject(hdcMem0, ::CreatePen(PS_SOLID, 1, RGB(160, 160, 160)));
313 for (INT counter = 0; counter < sizeImage.cy; counter++)
314 {
315 POINT pt0 = { 0, counter }, pt1 = { sizeImage.cx, counter };
316 ImageToCanvas(pt0);
317 ImageToCanvas(pt1);
318 ::MoveToEx(hdcMem0, pt0.x, pt0.y, NULL);
319 ::LineTo(hdcMem0, pt1.x, pt1.y);
320 }
321 for (INT counter = 0; counter < sizeImage.cx; counter++)
322 {
323 POINT pt0 = { counter, 0 }, pt1 = { counter, sizeImage.cy };
324 ImageToCanvas(pt0);
325 ImageToCanvas(pt1);
326 ::MoveToEx(hdcMem0, pt0.x, pt0.y, NULL);
327 ::LineTo(hdcMem0, pt1.x, pt1.y);
328 }
329 ::DeleteObject(::SelectObject(hdcMem0, oldPen));
330 }
331
332 // Draw overlay #2 on hdcMem0
334
335 // Draw new frame on hdcMem0 if any
337 DrawXorRect(hdcMem0, &m_rcResizing);
338
339 // Transfer the bits (hDC <-- hdcMem0)
340 ::BitBlt(hDC, rcCanvasDraw.left, rcCanvasDraw.top, rcCanvasDraw.Width(), rcCanvasDraw.Height(),
341 hdcMem0, rcCanvasDraw.left, rcCanvasDraw.top, SRCCOPY);
342
343 // Clean up hdcMem0
344 ::SelectObject(hdcMem0, hbm0Old);
345 ::DeleteDC(hdcMem0);
346 ::DeleteObject(hbmCache2);
347 ::DeleteObject(hbmCache1);
348
349 return TRUE;
350}
351
353{
354 CRect rcClient;
355 GetClientRect(&rcClient);
356
357 CSize sizePage(rcClient.right, rcClient.bottom);
358 CSize sizeZoomed = { Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()) };
359 CSize sizeWhole = { sizeZoomed.cx + (GRIP_SIZE * 2), sizeZoomed.cy + (GRIP_SIZE * 2) };
360
361 // show/hide the scrollbars
362 ShowScrollBar(SB_HORZ, sizePage.cx < sizeWhole.cx);
363 ShowScrollBar(SB_VERT, sizePage.cy < sizeWhole.cy);
364
365 if (sizePage.cx < sizeWhole.cx || sizePage.cy < sizeWhole.cy)
366 {
367 GetClientRect(&rcClient); // Scrollbars might change, get client rectangle again
368 sizePage = CSize(rcClient.right, rcClient.bottom);
369 }
370
371 SCROLLINFO si = { sizeof(si), SIF_PAGE | SIF_RANGE };
372 si.nMin = 0;
373
374 si.nMax = sizeWhole.cx;
375 si.nPage = sizePage.cx;
377
378 si.nMax = sizeWhole.cy;
379 si.nPage = sizePage.cy;
381}
382
384{
387}
388
390{
391 if (m_hWnd)
393
394 return 0;
395}
396
398{
400 si.cbSize = sizeof(SCROLLINFO);
401 si.fMask = SIF_ALL;
402 GetScrollInfo(fnBar, &si);
403 switch (LOWORD(wParam))
404 {
405 case SB_THUMBTRACK:
406 case SB_THUMBPOSITION:
407 si.nPos = (SHORT)HIWORD(wParam);
408 break;
409 case SB_LINELEFT:
410 si.nPos -= 5;
411 break;
412 case SB_LINERIGHT:
413 si.nPos += 5;
414 break;
415 case SB_PAGELEFT:
416 si.nPos -= si.nPage;
417 break;
418 case SB_PAGERIGHT:
419 si.nPos += si.nPage;
420 break;
421 }
422 si.nPos = max(min(si.nPos, si.nMax), si.nMin);
423 SetScrollInfo(fnBar, &si);
424 Invalidate();
425}
426
428{
430 return 0;
431}
432
434{
436 return 0;
437}
438
440{
442
443 m_nMouseDownMsg = nMsg;
444 BOOL bLeftButton = (nMsg == WM_LBUTTONDOWN);
445
446 if (nMsg == WM_MBUTTONDOWN)
447 {
448 m_ptOrig = pt;
449 SetCapture();
451 return 0;
452 }
453
454 HITTEST hitSelection = selectionModel.hitTest(pt);
455 if (hitSelection != HIT_NONE)
456 {
457 m_drawing = TRUE;
459 SetCapture();
460 toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE);
461 Invalidate();
462 return 0;
463 }
464
465 HITTEST hit = CanvasHitTest(pt);
466 if (hit == HIT_NONE || hit == HIT_BORDER)
467 {
468 switch (toolsModel.GetActiveTool())
469 {
470 case TOOL_BEZIER:
471 case TOOL_SHAPE:
473 Invalidate();
474 break;
475
476 case TOOL_FREESEL:
477 case TOOL_RECTSEL:
479 Invalidate();
480 break;
481
482 default:
483 break;
484 }
485
486 toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions
487 return 0;
488 }
489
491
492 if (hit == HIT_INNER)
493 {
494 m_drawing = TRUE;
495 SetCapture();
496 toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE);
497 Invalidate();
498 return 0;
499 }
500
501 if (bLeftButton)
502 {
503 m_hitCanvasSizeBox = hit;
504 m_ptOrig = pt;
505 SetCapture();
506 }
507
508 return 0;
509}
510
512{
515
518 m_nMouseDownMsg = 0;
519
522 Invalidate();
523 return 0;
524}
525
527{
529
531 {
532 INT x = GetScrollPos(SB_HORZ) - (pt.x - m_ptOrig.x);
533 INT y = GetScrollPos(SB_VERT) - (pt.y - m_ptOrig.y);
536 m_ptOrig = pt;
537 return 0;
538 }
539
541
543 Invalidate();
544
546 {
547 TRACKMOUSEEVENT tme = { sizeof(tme) };
548 tme.dwFlags = TME_LEAVE;
549 tme.hwndTrack = m_hWnd;
550 tme.dwHoverTime = 0;
551 ::TrackMouseEvent(&tme);
552
553 if (!m_drawing)
554 {
555 CRect rcImage;
556 GetImageRect(rcImage);
557
558 CStringW strCoord;
559 if (rcImage.PtInRect(pt))
560 strCoord.Format(L"%ld, %ld", pt.x, pt.y);
562 }
563 }
564
566 {
568 return 0;
569 }
570
571 if (m_hitCanvasSizeBox == HIT_NONE || ::GetCapture() != m_hWnd)
572 return 0;
573
574 // Dragging now... Calculate the new size
575 INT cxImage = imageModel.GetWidth(), cyImage = imageModel.GetHeight();
576 INT cxDelta = pt.x - m_ptOrig.x;
577 INT cyDelta = pt.y - m_ptOrig.y;
578 switch (m_hitCanvasSizeBox)
579 {
580 case HIT_UPPER_LEFT:
581 cxImage -= cxDelta;
582 cyImage -= cyDelta;
583 break;
584 case HIT_UPPER_CENTER:
585 cyImage -= cyDelta;
586 break;
587 case HIT_UPPER_RIGHT:
588 cxImage += cxDelta;
589 cyImage -= cyDelta;
590 break;
591 case HIT_MIDDLE_LEFT:
592 cxImage -= cxDelta;
593 break;
594 case HIT_MIDDLE_RIGHT:
595 cxImage += cxDelta;
596 break;
597 case HIT_LOWER_LEFT:
598 cxImage -= cxDelta;
599 cyImage += cyDelta;
600 break;
601 case HIT_LOWER_CENTER:
602 cyImage += cyDelta;
603 break;
604 case HIT_LOWER_RIGHT:
605 cxImage += cxDelta;
606 cyImage += cyDelta;
607 break;
608 default:
609 return 0;
610 }
611
612 // Limit bitmap size
613 cxImage = max(1, cxImage);
614 cyImage = max(1, cyImage);
615 cxImage = min(MAXWORD, cxImage);
616 cyImage = min(MAXWORD, cyImage);
617
618 // Display new size
619 CStringW strSize;
620 strSize.Format(L"%d x %d", cxImage, cyImage);
622
623 // Dragging now... Fix the position...
624 CRect rcResizing = { 0, 0, cxImage, cyImage };
625 switch (m_hitCanvasSizeBox)
626 {
627 case HIT_UPPER_LEFT:
628 rcResizing.OffsetRect(cxDelta, cyDelta);
629 break;
630 case HIT_UPPER_CENTER:
631 rcResizing.OffsetRect(0, cyDelta);
632 break;
633 case HIT_UPPER_RIGHT:
634 rcResizing.OffsetRect(0, cyDelta);
635 break;
636 case HIT_MIDDLE_LEFT:
637 rcResizing.OffsetRect(cxDelta, 0);
638 break;
639 case HIT_LOWER_LEFT:
640 rcResizing.OffsetRect(cxDelta, 0);
641 break;
642 default:
643 break;
644 }
645 ImageToCanvas(rcResizing);
646 m_rcResizing = rcResizing;
647 Invalidate(TRUE);
648
649 return 0;
650}
651
653{
656
658
659 BOOL bLeftButton = (m_nMouseDownMsg == WM_LBUTTONDOWN);
660 m_nMouseDownMsg = 0;
661
662 if (m_drawing)
663 {
665 toolsModel.OnButtonUp(bLeftButton, pt.x, pt.y);
666 Invalidate(FALSE);
668 return 0;
669 }
670
671 if (m_hitCanvasSizeBox == HIT_NONE || !bLeftButton)
672 return 0;
673
674 // Resize the image
675 INT cxImage = imageModel.GetWidth(), cyImage = imageModel.GetHeight();
676 INT cxDelta = pt.x - m_ptOrig.x;
677 INT cyDelta = pt.y - m_ptOrig.y;
678 switch (m_hitCanvasSizeBox)
679 {
680 case HIT_UPPER_LEFT:
681 imageModel.Crop(cxImage - cxDelta, cyImage - cyDelta, cxDelta, cyDelta);
682 break;
683 case HIT_UPPER_CENTER:
684 imageModel.Crop(cxImage, cyImage - cyDelta, 0, cyDelta);
685 break;
686 case HIT_UPPER_RIGHT:
687 imageModel.Crop(cxImage + cxDelta, cyImage - cyDelta, 0, cyDelta);
688 break;
689 case HIT_MIDDLE_LEFT:
690 imageModel.Crop(cxImage - cxDelta, cyImage, cxDelta, 0);
691 break;
692 case HIT_MIDDLE_RIGHT:
693 imageModel.Crop(cxImage + cxDelta, cyImage, 0, 0);
694 break;
695 case HIT_LOWER_LEFT:
696 imageModel.Crop(cxImage - cxDelta, cyImage + cyDelta, cxDelta, 0);
697 break;
698 case HIT_LOWER_CENTER:
699 imageModel.Crop(cxImage, cyImage + cyDelta, 0, 0);
700 break;
701 case HIT_LOWER_RIGHT:
702 imageModel.Crop(cxImage + cxDelta, cyImage + cyDelta, 0, 0);
703 break;
704 default:
705 break;
706 }
708
710
712 toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions
714 Invalidate(TRUE);
715 return 0;
716}
717
719{
721 {
722 bHandled = FALSE;
723 return 0;
724 }
725
727 {
729 return 0;
730 }
731
732 POINT pt;
735
736 CRect rcClient;
737 GetClientRect(&rcClient);
738
739 if (!rcClient.PtInRect(pt))
740 {
741 bHandled = FALSE;
742 return 0;
743 }
744
745 HITTEST hitSelection = selectionModel.hitTest(pt);
746 if (hitSelection != HIT_NONE)
747 {
748 if (!setCursorOnSizeBox(hitSelection))
750 return 0;
751 }
752
753 CRect rcImage;
754 GetImageRect(rcImage);
755 ImageToCanvas(rcImage);
756
757 if (rcImage.PtInRect(pt))
758 {
759 switch (toolsModel.GetActiveTool())
760 {
761 case TOOL_FILL:
763 break;
764 case TOOL_COLOR:
766 break;
767 case TOOL_ZOOM:
769 break;
770 case TOOL_PEN:
772 break;
773 case TOOL_AIRBRUSH:
775 break;
776 case TOOL_RUBBER:
777 {
781 break;
782 }
783 case TOOL_BRUSH:
784 {
789 break;
790 }
791 default:
793 }
794 return 0;
795 }
796
798 bHandled = FALSE;
799
800 return 0;
801}
802
804{
805 if (wParam == VK_ESCAPE)
806 {
809 m_nMouseDownMsg = 0;
812 Invalidate(TRUE);
813 }
814
815 return 0;
816}
817
819{
820 // Cancel dragging
823 Invalidate(TRUE);
824 return 0;
825}
826
828{
829 return ::SendMessageW(GetParent(), nMsg, wParam, lParam);
830}
831
833{
835 return 0;
836}
837
839{
840 return TRUE; // do nothing => transparent background
841}
842
844{
845 RECT rcClient;
846 GetClientRect(&rcClient);
847
848 static BOOL s_bShowedOutOfMemory = FALSE; // Don't show "Out Of Memory" message multiple time
849
850 PAINTSTRUCT ps;
851 HDC hDC = BeginPaint(&ps);
852
853 if (DoDraw(hDC, rcClient, ps.rcPaint))
854 {
855 s_bShowedOutOfMemory = FALSE;
856 }
857 else if (!s_bShowedOutOfMemory)
858 {
860 s_bShowedOutOfMemory = TRUE;
861 imageModel.ClearHistory(); // Reduce memory usage
862 }
863
864 EndPaint(&ps);
865 return 0;
866}
867
869{
871 toolsModel.OnEndDraw(bCancel);
872 Invalidate(FALSE);
873}
874
876{
880}
881
883{
885 return 0;
886}
static HDC hDC
Definition: 3dtext.c:33
Arabic default style
Definition: afstyles.h:94
#define IDC_ZOOM
Definition: resource.h:16
HWND g_hStatusBar
Definition: main.cpp:23
BOOL g_imageSaved
Definition: main.cpp:21
BOOL g_showGrid
Definition: main.cpp:22
void ShowOutOfMemory(void)
Definition: main.cpp:34
HINSTANCE g_hinstExe
Definition: main.cpp:17
ToolsModel toolsModel
Definition: toolsmodel.cpp:10
#define GRIP_SIZE
Definition: precomp.h:43
SelectionModel selectionModel
HITTEST
Definition: precomp.h:55
@ HIT_NONE
Definition: precomp.h:56
@ HIT_BORDER
Definition: precomp.h:65
@ HIT_LOWER_RIGHT
Definition: precomp.h:64
@ HIT_LOWER_CENTER
Definition: precomp.h:63
@ HIT_UPPER_LEFT
Definition: precomp.h:57
@ HIT_INNER
Definition: precomp.h:66
@ HIT_LOWER_LEFT
Definition: precomp.h:62
@ HIT_UPPER_CENTER
Definition: precomp.h:58
@ HIT_UPPER_RIGHT
Definition: precomp.h:59
@ HIT_MIDDLE_RIGHT
Definition: precomp.h:61
@ HIT_MIDDLE_LEFT
Definition: precomp.h:60
CTextEditWindow textEditWindow
Definition: textedit.cpp:12
#define IDC_FILL
Definition: resource.h:20
#define IDC_PEN
Definition: resource.h:23
#define IDC_COLOR
Definition: resource.h:21
#define IDC_AIRBRUSH
Definition: resource.h:24
#define IDC_HANDDRAG
Definition: resource.h:25
CCanvasWindow canvasWindow
Definition: canvas.cpp:11
void __cdecl Format(UINT nFormatID,...)
Definition: cstringt.h:818
VOID OnHVScroll(WPARAM wParam, INT fnBar)
Definition: canvas.cpp:397
BOOL m_drawing
Definition: canvas.h:75
VOID OnEndDraw(BOOL bCancel)
Definition: canvas.cpp:868
LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:838
LRESULT OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:803
CStyledCursor m_hRubberCursor
Definition: canvas.h:92
CStyledCursor m_hBrushCursor
Definition: canvas.h:91
LRESULT OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:832
LRESULT OnVScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:433
LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:718
HITTEST m_hitCanvasSizeBox
Definition: canvas.h:90
LRESULT OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:882
VOID ImageToCanvas(POINT &pt)
Definition: canvas.cpp:167
LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:389
LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:843
LRESULT OnCancelMode(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:818
VOID CanvasToImage(POINT &pt)
Definition: canvas.cpp:180
VOID updateScrollPos(INT x=0, INT y=0)
Definition: canvas.cpp:383
CRect m_rcResizing
Definition: canvas.h:94
UINT m_nMouseDownMsg
Definition: canvas.h:115
virtual ~CCanvasWindow()
Definition: canvas.cpp:154
HITTEST CanvasHitTest(POINT pt)
Definition: canvas.cpp:198
LRESULT OnButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:652
LRESULT OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:427
LRESULT OnButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:511
BOOL DoDraw(HDC hDC, RECT &rcClient, RECT &rcPaint)
Definition: canvas.cpp:249
VOID GetImageRect(RECT &rc)
Definition: canvas.cpp:193
POINT m_ptOrig
Definition: canvas.h:93
VOID updateScrollRange()
Definition: canvas.cpp:352
LRESULT OnButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:439
LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:526
VOID getNewZoomRect(CRect &rcView, INT newZoom, CPoint ptTarget)
Definition: canvas.cpp:206
RECT GetBaseRect()
Definition: canvas.cpp:158
LRESULT OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:875
VOID zoomTo(INT newZoom, LONG left=0, LONG top=0)
Definition: canvas.cpp:234
LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL &bHandled)
Definition: canvas.cpp:827
void SetRectEmpty() noexcept
Definition: atltypes.h:431
BOOL IntersectRect(LPCRECT lpRect1, LPCRECT lpRect2) noexcept
Definition: atltypes.h:346
void InflateRect(int x, int y) noexcept
Definition: atltypes.h:323
void OffsetRect(int x, int y) noexcept
Definition: atltypes.h:403
BOOL PtInRect(POINT point) const noexcept
Definition: atltypes.h:418
void SetRect(int x1, int y1, int x2, int y2) noexcept
Definition: atltypes.h:423
int Width() const noexcept
Definition: atltypes.h:461
int Height() const noexcept
Definition: atltypes.h:318
BOOL IsRectEmpty() const noexcept
Definition: atltypes.h:351
COLORREF m_color
Definition: canvas.h:36
HCURSOR m_hCursor
Definition: canvas.h:33
static HCURSOR CreateStyledCursor(BrushStyle style, INT radius, COLORREF color, BOOL is_rubber)
Definition: canvas.cpp:16
void SetCursor()
Definition: canvas.h:24
BOOL m_is_rubber
Definition: canvas.h:37
BrushStyle m_style
Definition: canvas.h:34
void SetStyle(BrushStyle style, INT radius, COLORREF color, BOOL is_rubber)
Definition: canvas.cpp:128
INT m_radius
Definition: canvas.h:35
static BOOL IsWaiting()
Definition: CWaitCursor.h:40
int GetWidth() const
Definition: history.cpp:254
void NotifyImageChanged()
Definition: history.cpp:23
void Crop(int nWidth, int nHeight, int nOffsetX=0, int nOffsetY=0)
Definition: history.cpp:191
int GetHeight() const
Definition: history.cpp:259
HDC GetDC()
Definition: history.cpp:272
void ClearHistory(void)
Definition: history.cpp:114
COLORREF GetBgColor() const
COLORREF GetFgColor() const
HITTEST hitTest(POINT ptCanvas)
void OnDrawOverlayOnCanvas(HDC hdc)
Definition: mouse.cpp:1191
void OnDrawOverlayOnImage(HDC hdc)
Definition: mouse.cpp:1186
void OnEndDraw(BOOL bCancel)
Definition: mouse.cpp:1178
int GetZoom() const
Definition: toolsmodel.cpp:270
BOOL IsSelection() const
Definition: toolsmodel.cpp:41
void resetTool()
Definition: toolsmodel.cpp:311
void DrawWithMouseTool(POINT pt, WPARAM wParam)
Definition: mouse.cpp:1201
BrushStyle GetBrushStyle() const
Definition: toolsmodel.cpp:130
void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
Definition: mouse.cpp:1152
void SetZoom(int nZoom)
Definition: toolsmodel.cpp:275
int GetRubberRadius() const
Definition: toolsmodel.cpp:202
TOOLTYPE GetActiveTool() const
Definition: toolsmodel.cpp:142
void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
Definition: mouse.cpp:1169
INT GetBrushWidth() const
Definition: toolsmodel.cpp:70
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
HBITMAP CreateDIBWithProperties(int width, int height)
Definition: dib.cpp:32
#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 DrawXorRect(HDC hdc, const RECT *prc)
Definition: drawing.cpp:362
void Erase(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF color, LONG radius)
Definition: drawing.cpp:115
static VOID BitBlt(_In_ ULONG Left, _In_ ULONG Top, _In_ ULONG Width, _In_ ULONG Height, _In_reads_bytes_(Height *Stride) PUCHAR Buffer, _In_ ULONG BitsPerPixel, _In_ ULONG Stride)
Definition: common.c:42
#define RGB(r, g, b)
Definition: precomp.h:67
#define GetBValue(quad)
Definition: precomp.h:71
#define GetGValue(quad)
Definition: precomp.h:70
#define GetRValue(quad)
Definition: precomp.h:69
#define L(x)
Definition: resources.c:13
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
pKey DeleteObject()
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint color
Definition: glext.h:6243
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
ImageModel imageModel
Definition: history.cpp:11
GLint dy
Definition: linetemp.h:97
GLint dx
Definition: linetemp.h:97
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
static HBITMAP
Definition: button.c:44
static HDC
Definition: imagelist.c:88
static SYSTEM_INFO si
Definition: virtual.c:39
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
#define MAXWORD
PaletteModel paletteModel
#define LOWORD(l)
Definition: pedump.c:82
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define TME_LEAVE
Definition: commctrl.h:4998
#define SB_SETTEXT
Definition: commctrl.h:1954
BOOL setCursorOnSizeBox(HITTEST hit)
Definition: sizebox.cpp:20
VOID drawSizeBoxes(HDC hdc, LPCRECT prcBase, BOOL bDrawFrame, LPCRECT prcPaint)
Definition: sizebox.cpp:103
HITTEST getSizeBoxHitTest(POINT pt, LPCRECT prcBase)
Definition: sizebox.cpp:80
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:108
LONG bottom
Definition: windef.h:109
LONG top
Definition: windef.h:107
LONG left
Definition: windef.h:106
LONG cx
Definition: windef.h:134
LONG cy
Definition: windef.h:135
#define max(a, b)
Definition: svc.c:63
static int UnZoomed(int xy)
Definition: toolsmodel.h:156
@ TOOL_AIRBRUSH
Definition: toolsmodel.h:20
@ TOOL_COLOR
Definition: toolsmodel.h:16
@ TOOL_SHAPE
Definition: toolsmodel.h:25
@ TOOL_RUBBER
Definition: toolsmodel.h:14
@ TOOL_BRUSH
Definition: toolsmodel.h:19
@ TOOL_BEZIER
Definition: toolsmodel.h:23
@ TOOL_FILL
Definition: toolsmodel.h:15
@ TOOL_PEN
Definition: toolsmodel.h:18
@ TOOL_FREESEL
Definition: toolsmodel.h:12
@ TOOL_ZOOM
Definition: toolsmodel.h:17
@ TOOL_RECTSEL
Definition: toolsmodel.h:13
static int Zoomed(int xy)
Definition: toolsmodel.h:151
BrushStyle
Definition: toolsmodel.h:32
@ BrushStyleSquare
Definition: toolsmodel.h:34
const uint16_t * LPCWSTR
Definition: typedefs.h:57
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
HDC hdcMem
Definition: welcome.c:104
DWORD COLORREF
Definition: windef.h:100
HICON HCURSOR
Definition: windef.h:99
#define GET_Y_LPARAM(lp)
Definition: windowsx.h:300
#define GET_X_LPARAM(lp)
Definition: windowsx.h:299
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:1546
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
#define TRANSPARENT
Definition: wingdi.h:950
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 WHITE_PEN
Definition: wingdi.h:905
#define SRCCOPY
Definition: wingdi.h:333
#define WHITE_BRUSH
Definition: wingdi.h:902
#define NULL_BRUSH
Definition: wingdi.h:901
#define BLACK_BRUSH
Definition: wingdi.h:896
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
int WINAPI SetBkMode(_In_ HDC, _In_ int)
Definition: dc.c:1056
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:917
BOOL WINAPI DeleteDC(_In_ HDC)
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
#define PS_SOLID
Definition: wingdi.h:586
HWND WINAPI SetCapture(_In_ HWND hWnd)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define MAKEWPARAM(l, h)
Definition: winuser.h:4117
#define SB_THUMBTRACK
Definition: winuser.h:573
HICON WINAPI CreateIconIndirect(_In_ PICONINFO)
Definition: cursoricon.c:2975
#define WM_HSCROLL
Definition: winuser.h:1771
BOOL WINAPI DestroyCursor(_In_ HCURSOR)
Definition: cursoricon.c:3083
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
struct tagSCROLLINFO SCROLLINFO
#define WM_VSCROLL
Definition: winuser.h:1772
#define SIF_RANGE
Definition: winuser.h:1246
#define SB_PAGERIGHT
Definition: winuser.h:571
#define SB_VERT
Definition: winuser.h:553
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1806
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:3064
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define SIF_PAGE
Definition: winuser.h:1244
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define IDC_SIZEALL
Definition: winuser.h:704
BOOL WINAPI TrackMouseEvent(_Inout_ LPTRACKMOUSEEVENT)
#define CopyCursor(c)
Definition: winuser.h:4389
#define SB_LINERIGHT
Definition: winuser.h:567
#define WM_LBUTTONDOWN
Definition: winuser.h:1804
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2474
int WINAPI SetScrollPos(_In_ HWND, _In_ int, _In_ int, _In_ BOOL)
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define IDC_CROSS
Definition: winuser.h:698
#define SB_LINELEFT
Definition: winuser.h:566
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define COLOR_APPWORKSPACE
Definition: winuser.h:936
#define SIF_ALL
Definition: winuser.h:1243
#define SendMessage
Definition: winuser.h:6009
#define LoadCursor
Definition: winuser.h:5978
HDC WINAPI GetDC(_In_opt_ HWND)
HWND WINAPI GetParent(_In_ HWND)
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
BOOL WINAPI ShowScrollBar(_In_ HWND, _In_ int, _In_ BOOL)
int WINAPI GetScrollPos(_In_ HWND, _In_ int)
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI InflateRect(_Inout_ LPRECT, _In_ int, _In_ int)
BOOL WINAPI GetScrollInfo(_In_ HWND, _In_ int, _Inout_ LPSCROLLINFO)
#define VK_ESCAPE
Definition: winuser.h:2250
BOOL WINAPI IsWindowVisible(_In_ HWND)
#define WM_MBUTTONDOWN
Definition: winuser.h:1810
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SB_HORZ
Definition: winuser.h:552
#define SB_PAGELEFT
Definition: winuser.h:570
#define SB_THUMBPOSITION
Definition: winuser.h:572
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)