mirror of
https://github.com/reactos/reactos.git
synced 2025-06-10 04:14:53 +00:00
[Paint] Initial support for free selections, resizing selections and experimental selection transparency
svn path=/trunk/; revision=45113
This commit is contained in:
parent
d005d3aaa4
commit
d84c76f347
5 changed files with 244 additions and 24 deletions
|
@ -43,6 +43,7 @@ extern int rectSel_dest[4];
|
|||
extern HWND hSelection;
|
||||
extern HWND hImageArea;
|
||||
extern HBITMAP hSelBm;
|
||||
extern HBITMAP hSelMask;
|
||||
|
||||
extern int palColors[28];
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ int rectSel_dest[4];
|
|||
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,
|
||||
|
|
|
@ -27,6 +27,8 @@ placeSelWin()
|
|||
|
||||
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 @@ startPaintingL(HDC hdc, short x, short y, int fg, int bg)
|
|||
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 @@ whilePaintingL(HDC hdc, short x, short y, int fg, int bg)
|
|||
{
|
||||
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 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg)
|
|||
{
|
||||
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 @@ endPaintingL(HDC hdc, short x, short y, int fg, int bg)
|
|||
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 @@ startPaintingR(HDC hdc, short x, short y, int fg, int bg)
|
|||
case 15:
|
||||
case 16:
|
||||
newReversible();
|
||||
break;
|
||||
case 3:
|
||||
newReversible();
|
||||
Replace(hdc, x, y, x, y, fg, bg, rubberRadius);
|
||||
|
|
|
@ -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 @@ SelectionWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
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);
|
||||
if (transpBg == 0)
|
||||
BitBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3],
|
||||
hSelDC, 0, 0, SRCCOPY);
|
||||
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
|
||||
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);
|
||||
{
|
||||
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)
|
||||
MaskBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3],
|
||||
hSelDC, 0, 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
|
||||
else
|
||||
{
|
||||
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);
|
||||
|
|
|
@ -744,18 +744,15 @@ WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||
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:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue