Author: bfreisen
Date: Sun Jan 17 00:21:45 2010
New Revision: 45113
URL:
http://svn.reactos.org/svn/reactos?rev=45113&view=rev
Log:
[Paint] Initial support for free selections, resizing selections and experimental
selection transparency
Modified:
trunk/reactos/base/applications/paint/globalvar.h
trunk/reactos/base/applications/paint/main.c
trunk/reactos/base/applications/paint/mouse.c
trunk/reactos/base/applications/paint/selection.c
trunk/reactos/base/applications/paint/winproc.c
Modified: trunk/reactos/base/applications/paint/globalvar.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/paint/gl…
==============================================================================
--- trunk/reactos/base/applications/paint/globalvar.h [iso-8859-1] (original)
+++ trunk/reactos/base/applications/paint/globalvar.h [iso-8859-1] Sun Jan 17 00:21:45
2010
@@ -43,6 +43,7 @@
extern HWND hSelection;
extern HWND hImageArea;
extern HBITMAP hSelBm;
+extern HBITMAP hSelMask;
extern int palColors[28];
Modified: trunk/reactos/base/applications/paint/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/paint/ma…
==============================================================================
--- trunk/reactos/base/applications/paint/main.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/paint/main.c [iso-8859-1] Sun Jan 17 00:21:45 2010
@@ -60,6 +60,7 @@
HWND hSelection;
HWND hImageArea;
HBITMAP hSelBm;
+HBITMAP hSelMask;
/* initial palette colors; may be changed by the user during execution */
int palColors[28] = { 0x000000, 0x464646, 0x787878, 0x300099, 0x241ced, 0x0078ff,
0x0ec2ff,
Modified: trunk/reactos/base/applications/paint/mouse.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/paint/mo…
==============================================================================
--- trunk/reactos/base/applications/paint/mouse.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/paint/mouse.c [iso-8859-1] Sun Jan 17 00:21:45 2010
@@ -27,6 +27,8 @@
POINT pointStack[256];
short pointSP;
+POINT *ptStack = NULL;
+int ptSP = 0;
void
startPaintingL(HDC hdc, short x, short y, int fg, int bg)
@@ -38,15 +40,25 @@
switch (activeTool)
{
case 1:
+ ShowWindow(hSelection, SW_HIDE);
+ if (ptStack != NULL)
+ HeapFree(GetProcessHeap(), 0, ptStack);
+ ptStack = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT)
* 1024);
+ ptSP = 0;
+ ptStack[0].x = x;
+ ptStack[0].y = y;
+ break;
case 10:
case 11:
case 13:
case 15:
case 16:
newReversible();
+ break;
case 2:
newReversible();
ShowWindow(hSelection, SW_HIDE);
+ rectSel_src[2] = rectSel_src[3] = 0;
break;
case 3:
newReversible();
@@ -96,6 +108,17 @@
{
switch (activeTool)
{
+ case 1:
+ if (ptSP == 0)
+ newReversible();
+ ptSP++;
+ if (ptSP % 1024 == 0)
+ ptStack = HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
ptStack, sizeof(POINT) * (ptSP + 1024));
+ ptStack[ptSP].x = max(0, min(x, imgXRes));
+ ptStack[ptSP].y = max(0, min(y, imgYRes));
+ resetToU1();
+ Poly(hdc, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE);
+ break;
case 2:
{
short tempX;
@@ -174,6 +197,56 @@
{
switch (activeTool)
{
+ case 1:
+ {
+ POINT *ptStackCopy;
+ int i;
+ rectSel_src[0] = rectSel_src[1] = 0x7fffffff;
+ rectSel_src[2] = rectSel_src[3] = 0;
+ for (i = 0; i <= ptSP; i++)
+ {
+ if (ptStack[i].x < rectSel_src[0])
+ rectSel_src[0] = ptStack[i].x;
+ if (ptStack[i].y < rectSel_src[1])
+ rectSel_src[1] = ptStack[i].y;
+ if (ptStack[i].x > rectSel_src[2])
+ rectSel_src[2] = ptStack[i].x;
+ if (ptStack[i].y > rectSel_src[3])
+ rectSel_src[3] = ptStack[i].y;
+ }
+ rectSel_src[2] += 1 - rectSel_src[0];
+ rectSel_src[3] += 1 - rectSel_src[1];
+ rectSel_dest[0] = rectSel_src[0];
+ rectSel_dest[1] = rectSel_src[1];
+ rectSel_dest[2] = rectSel_src[2];
+ rectSel_dest[3] = rectSel_src[3];
+ if (ptSP != 0)
+ {
+ DeleteObject(hSelMask);
+ hSelMask = CreateBitmap(rectSel_src[2], rectSel_src[3], 1, 1, NULL);
+ DeleteObject(SelectObject(hSelDC, hSelMask));
+ ptStackCopy = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
sizeof(POINT) * (ptSP + 1));
+ for (i = 0; i <= ptSP; i++)
+ {
+ ptStackCopy[i].x = ptStack[i].x - rectSel_src[0];
+ ptStackCopy[i].y = ptStack[i].y - rectSel_src[1];
+ }
+ Poly(hSelDC, ptStackCopy, ptSP + 1, 0x00ffffff, 0x00ffffff, 1, 2, TRUE);
+ HeapFree(GetProcessHeap(), 0, ptStackCopy);
+ SelectObject(hSelDC, hSelBm = CreateDIBWithProperties(rectSel_src[2],
rectSel_src[3]));
+ resetToU1();
+ MaskBlt(hSelDC, 0, 0, rectSel_src[2], rectSel_src[3], hDrawingDC,
rectSel_src[0],
+ rectSel_src[1], hSelMask, 0, 0, MAKEROP4(SRCCOPY, WHITENESS));
+ Poly(hdc, ptStack, ptSP + 1, bg, bg, 1, 2, TRUE);
+ newReversible();
+
+ placeSelWin();
+ ShowWindow(hSelection, SW_SHOW);
+ }
+ HeapFree(GetProcessHeap(), 0, ptStack);
+ ptStack = NULL;
+ break;
+ }
case 2:
resetToU1();
if ((rectSel_src[2] != 0) && (rectSel_src[3] != 0))
@@ -181,8 +254,12 @@
DeleteObject(SelectObject
(hSelDC, hSelBm =
(HBITMAP) CreateDIBWithProperties(rectSel_src[2],
rectSel_src[3])));
+ DeleteObject(hSelMask);
BitBlt(hSelDC, 0, 0, rectSel_src[2], rectSel_src[3], hDrawingDC,
rectSel_src[0],
rectSel_src[1], SRCCOPY);
+ Rect(hdc, rectSel_src[0], rectSel_src[1], rectSel_src[0] +
rectSel_src[2],
+ rectSel_src[1] + rectSel_src[3], bgColor, bgColor, 0, TRUE);
+ newReversible();
placeSelWin();
ShowWindow(hSelection, SW_SHOW);
}
@@ -255,6 +332,7 @@
case 15:
case 16:
newReversible();
+ break;
case 3:
newReversible();
Replace(hdc, x, y, x, y, fg, bg, rubberRadius);
Modified: trunk/reactos/base/applications/paint/selection.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/paint/se…
==============================================================================
--- trunk/reactos/base/applications/paint/selection.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/paint/selection.c [iso-8859-1] Sun Jan 17 00:21:45
2010
@@ -13,12 +13,51 @@
#include "drawing.h"
#include "history.h"
#include "mouse.h"
+#include "dib.h"
/* FUNCTIONS ********************************************************/
+LPCTSTR cursors[9] = { IDC_SIZEALL, IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW,
+ IDC_SIZEWE, IDC_SIZEWE, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE
+};
+
BOOL moving = FALSE;
+int action = 0;
short xPos;
short yPos;
+short xFrac;
+short yFrac;
+
+int
+identifyCorner(short x, short y, short w, short h)
+{
+ if (y < 3)
+ {
+ if (x < 3)
+ return 1;
+ if ((x < w / 2 + 2) && (x >= w / 2 - 1))
+ return 2;
+ if (x >= w - 3)
+ return 3;
+ }
+ if ((y < h / 2 + 2) && (y >= h / 2 - 1))
+ {
+ if (x < 3)
+ return 4;
+ if (x >= w - 3)
+ return 5;
+ }
+ if (y >= h - 3)
+ {
+ if (x < 3)
+ return 6;
+ if ((x < w / 2 + 2) && (x >= w / 2 - 1))
+ return 7;
+ if (x >= w - 3)
+ return 8;
+ }
+ return 0;
+}
LRESULT CALLBACK
SelectionWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
@@ -41,36 +80,140 @@
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
SetCapture(hwnd);
+ if (action != 0)
+ SetCursor(LoadCursor(NULL, cursors[action]));
moving = TRUE;
break;
case WM_MOUSEMOVE:
if (moving)
{
+ int xDelta;
+ int yDelta;
resetToU1();
- rectSel_dest[0] += (short)LOWORD(lParam) - xPos;
- rectSel_dest[1] += (short)HIWORD(lParam) - yPos;
-
- Rect(hDrawingDC, rectSel_src[0], rectSel_src[1], rectSel_src[0] +
rectSel_src[2],
- rectSel_src[1] + rectSel_src[3], bgColor, bgColor, 0, TRUE);
+ xFrac += (short)LOWORD(lParam) - xPos;
+ yFrac += (short)HIWORD(lParam) - yPos;
+ if (zoom < 1000)
+ {
+ xDelta = xFrac * 1000 / zoom;
+ xFrac = 0;
+ yDelta = yFrac * 1000 / zoom;
+ yFrac = 0;
+ }
+ else
+ {
+ xDelta = xFrac * 1000 / zoom;
+ xFrac -= (xFrac * 1000 / zoom) * zoom / 1000;
+ yDelta = yFrac * 1000 / zoom;
+ yFrac -= (yFrac * 1000 / zoom) * zoom / 1000;
+ }
+ switch (action)
+ {
+ case 0:
+ rectSel_dest[0] += xDelta;
+ rectSel_dest[1] += yDelta;
+ break;
+ case 1:
+ rectSel_dest[0] += xDelta;
+ rectSel_dest[1] += yDelta;
+ rectSel_dest[2] -= xDelta;
+ rectSel_dest[3] -= yDelta;
+ break;
+ case 2:
+ rectSel_dest[1] += yDelta;
+ rectSel_dest[3] -= yDelta;
+ break;
+ case 3:
+ rectSel_dest[2] += xDelta;
+ rectSel_dest[1] += yDelta;
+ break;
+ case 4:
+ rectSel_dest[0] += xDelta;
+ rectSel_dest[2] -= xDelta;
+ break;
+ case 5:
+ rectSel_dest[2] += xDelta;
+ break;
+ case 6:
+ rectSel_dest[0] += xDelta;
+ rectSel_dest[2] -= xDelta;
+ rectSel_dest[3] += yDelta;
+ break;
+ case 7:
+ rectSel_dest[3] += yDelta;
+ break;
+ case 8:
+ rectSel_dest[2] += xDelta;
+ rectSel_dest[3] += yDelta;
+ break;
+ }
+
+ if (action != 0)
+ StretchBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1],
rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0, GetDIBWidth(hSelBm), GetDIBHeight(hSelBm),
SRCCOPY);
+ else
if (transpBg == 0)
- BitBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2],
rectSel_dest[3],
- hSelDC, 0, 0, SRCCOPY);
+ MaskBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1],
rectSel_dest[2], rectSel_dest[3],
+ hSelDC, 0, 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
else
- BitBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2],
rectSel_dest[3],
- hSelDC, 0, 0, SRCAND);
- //TransparentBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1],
rectSel_dest[2], rectSel_dest[3],
- // hSelDC, 0, 0, rectSel_dest[2], rectSel_dest[3],
bgColor);
+ {
+ HBITMAP tempMask;
+ HBRUSH oldBrush;
+ HDC tempDC;
+ tempMask = CreateBitmap(rectSel_dest[2], rectSel_dest[3], 1, 1,
NULL);
+ oldBrush = SelectObject(hSelDC, CreateSolidBrush(bgColor));
+ tempDC = CreateCompatibleDC(hSelDC);
+ SelectObject(tempDC, tempMask);
+ MaskBlt(tempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0,
hSelMask, 0, 0,
+ MAKEROP4(NOTSRCCOPY, BLACKNESS));
+ DeleteDC(tempDC);
+ DeleteObject(SelectObject(hSelDC, oldBrush));
+
+ MaskBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1],
rectSel_dest[2], rectSel_dest[3],
+ hSelDC, 0, 0, tempMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
+ DeleteObject(tempMask);
+ }
SendMessage(hImageArea, WM_PAINT, 0, 0);
xPos = LOWORD(lParam);
yPos = HIWORD(lParam);
//SendMessage(hwnd, WM_PAINT, 0, 0);
}
+ else
+ {
+ int w = rectSel_dest[2] * zoom / 1000 + 6;
+ int h = rectSel_dest[3] * zoom / 1000 + 6;
+ xPos = LOWORD(lParam);
+ yPos = HIWORD(lParam);
+ action = identifyCorner(xPos, yPos, w, h);
+ if (action != 0)
+ SetCursor(LoadCursor(NULL, cursors[action]));
+ }
break;
case WM_LBUTTONUP:
if (moving)
{
moving = FALSE;
ReleaseCapture();
+ if (action != 0)
+ {
+ HDC hTempDC;
+ HBITMAP hTempBm;
+ hTempDC = CreateCompatibleDC(hSelDC);
+ hTempBm = CreateDIBWithProperties(rectSel_dest[2], rectSel_dest[3]);
+ SelectObject(hTempDC, hTempBm);
+ SelectObject(hSelDC, hSelBm);
+ StretchBlt(hTempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC,
0, 0,
+ GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY);
+ DeleteObject(hSelBm);
+ hSelBm = hTempBm;
+ hTempBm = CreateBitmap(rectSel_dest[2], rectSel_dest[3], 1, 1,
NULL);
+ SelectObject(hTempDC, hTempBm);
+ SelectObject(hSelDC, hSelMask);
+ StretchBlt(hTempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC,
0, 0,
+ GetDIBWidth(hSelMask), GetDIBHeight(hSelMask), SRCCOPY);
+ DeleteObject(hSelMask);
+ hSelMask = hTempBm;
+ SelectObject(hSelDC, hSelBm);
+ DeleteDC(hTempDC);
+ }
placeSelWin();
ShowWindow(hSelection, SW_HIDE);
ShowWindow(hSelection, SW_SHOW);
Modified: trunk/reactos/base/applications/paint/winproc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/paint/wi…
==============================================================================
--- trunk/reactos/base/applications/paint/winproc.c [iso-8859-1] (original)
+++ trunk/reactos/base/applications/paint/winproc.c [iso-8859-1] Sun Jan 17 00:21:45 2010
@@ -744,18 +744,15 @@
break;
case IDM_EDITDELETESELECTION:
{
- /* FIXME: deleting freeform selections unsupported */
- RECT selectionRect, areaRect;
- long x1, x2, y1, y2;
-
- GetWindowRect(hSelection, &selectionRect);
- GetWindowRect(hImageArea, &areaRect);
- x1 = ((selectionRect.left - areaRect.left) / (zoom / 1000)) + 1;
- y1 = ((selectionRect.top - areaRect.top) / (zoom / 1000)) + 1;
- x2 = (selectionRect.right - areaRect.left) / (zoom / 1000);
- y2 = (selectionRect.bottom - areaRect.top) / (zoom / 1000);
- Rect(hDrawingDC, x1, y1, x2, y2, bgColor, bgColor, 0, TRUE);
- ShowWindow(hSelection, SW_HIDE);
+ /* remove selection window and already painted content using undo(),
+ paint Rect for rectangular selections and nothing for freeform
selections */
+ undo();
+ if (activeTool == 2)
+ {
+ newReversible();
+ Rect(hDrawingDC, rectSel_dest[0], rectSel_dest[1],
rectSel_dest[2] + rectSel_dest[0],
+ rectSel_dest[3] + rectSel_dest[1], bgColor, bgColor, 0,
TRUE);
+ }
break;
}
case IDM_EDITSELECTALL: