2003-05-18 17:16:18 +00:00
|
|
|
/*
|
|
|
|
* ReactOS W32 Subsystem
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2003-08-16 05:00:14 +00:00
|
|
|
/* $Id: fillshap.c,v 1.24 2003/08/16 05:00:14 royce Exp $ */
|
1999-07-22 16:21:53 +00:00
|
|
|
|
|
|
|
#undef WIN32_LEAN_AND_MEAN
|
|
|
|
#include <windows.h>
|
2002-09-08 10:23:54 +00:00
|
|
|
#include <ddk/ntddk.h>
|
1999-07-22 16:21:53 +00:00
|
|
|
#include <win32k/fillshap.h>
|
2000-06-16 07:25:41 +00:00
|
|
|
#include <win32k/dc.h>
|
|
|
|
#include <win32k/pen.h>
|
2003-06-25 16:55:33 +00:00
|
|
|
#include <include/error.h>
|
2002-09-01 20:39:56 +00:00
|
|
|
#include <include/object.h>
|
2003-02-15 19:16:34 +00:00
|
|
|
#include <include/inteng.h>
|
2003-05-18 17:16:18 +00:00
|
|
|
#include <include/path.h>
|
|
|
|
#include <include/paint.h>
|
2003-06-25 16:55:33 +00:00
|
|
|
#include <internal/safe.h>
|
1999-07-22 16:21:53 +00:00
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
#define NDEBUG
|
2000-06-29 23:35:53 +00:00
|
|
|
#include <win32k/debug1.h>
|
1999-07-22 16:21:53 +00:00
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
W32kChord(HDC hDC,
|
1999-07-22 16:21:53 +00:00
|
|
|
int LeftRect,
|
|
|
|
int TopRect,
|
|
|
|
int RightRect,
|
|
|
|
int BottomRect,
|
|
|
|
int XRadial1,
|
|
|
|
int YRadial1,
|
|
|
|
int XRadial2,
|
|
|
|
int YRadial2)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
W32kEllipse(HDC hDC,
|
1999-07-22 16:21:53 +00:00
|
|
|
int LeftRect,
|
|
|
|
int TopRect,
|
|
|
|
int RightRect,
|
|
|
|
int BottomRect)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
W32kPie(HDC hDC,
|
1999-07-22 16:21:53 +00:00
|
|
|
int LeftRect,
|
|
|
|
int TopRect,
|
|
|
|
int RightRect,
|
|
|
|
int BottomRect,
|
|
|
|
int XRadial1,
|
|
|
|
int YRadial1,
|
|
|
|
int XRadial2,
|
|
|
|
int YRadial2)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
#if 0
|
|
|
|
|
2003-03-20 03:07:38 +00:00
|
|
|
//When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
|
|
|
|
//even-numbered polygon sides on each scan line. That is, GDI fills the area between the
|
|
|
|
//first and second side, between the third and fourth side, and so on.
|
2003-08-16 04:47:41 +00:00
|
|
|
|
|
|
|
//WINDING Selects winding mode (fills any region with a nonzero winding value).
|
|
|
|
//When the fill mode is WINDING, GDI fills any region that has a nonzero winding value.
|
|
|
|
//This value is defined as the number of times a pen used to draw the polygon would go around the region.
|
|
|
|
//The direction of each edge of the polygon is important.
|
|
|
|
|
|
|
|
extern BOOL FillPolygon(PDC dc,
|
2003-08-15 18:51:32 +00:00
|
|
|
SURFOBJ *SurfObj,
|
|
|
|
PBRUSHOBJ BrushObj,
|
|
|
|
MIX RopMode,
|
|
|
|
CONST PPOINT Points,
|
|
|
|
int Count,
|
|
|
|
RECTL BoundRect);
|
2003-03-20 03:07:38 +00:00
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
#endif
|
2003-03-20 03:07:38 +00:00
|
|
|
|
|
|
|
//This implementation is blatantly ripped off from W32kRectangle
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
W32kPolygon(HDC hDC,
|
2003-06-25 16:55:33 +00:00
|
|
|
CONST PPOINT UnsafePoints,
|
|
|
|
int Count)
|
1999-07-22 16:21:53 +00:00
|
|
|
{
|
2003-06-25 16:55:33 +00:00
|
|
|
DC *dc = DC_HandleToPtr(hDC);
|
|
|
|
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
|
|
|
|
PBRUSHOBJ OutBrushObj, FillBrushObj;
|
|
|
|
BOOL ret;
|
|
|
|
PRECTL RectBounds;
|
|
|
|
PENOBJ *pen;
|
|
|
|
RECTL DestRect;
|
|
|
|
int CurrentPoint;
|
|
|
|
PPOINT Points;
|
|
|
|
NTSTATUS Status;
|
2003-03-20 03:07:38 +00:00
|
|
|
|
2003-03-20 08:22:01 +00:00
|
|
|
DPRINT("In W32kPolygon()\n");
|
2003-03-20 03:07:38 +00:00
|
|
|
|
2003-08-15 18:51:32 +00:00
|
|
|
if (NULL == dc || NULL == UnsafePoints || Count < 2)
|
2003-06-25 16:55:33 +00:00
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-03-20 03:07:38 +00:00
|
|
|
|
2003-06-25 16:55:33 +00:00
|
|
|
/* Copy points from userspace to kernelspace */
|
|
|
|
Points = ExAllocatePool(PagedPool, Count * sizeof(POINT));
|
|
|
|
if (NULL == Points)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
Status = MmCopyFromCaller(Points, UnsafePoints, Count * sizeof(POINT));
|
|
|
|
if (! NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
SetLastNtError(Status);
|
|
|
|
ExFreePool(Points);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-03-20 03:07:38 +00:00
|
|
|
|
2003-06-25 16:55:33 +00:00
|
|
|
/* Convert to screen coordinates */
|
|
|
|
for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++)
|
|
|
|
{
|
|
|
|
Points[CurrentPoint].x += dc->w.DCOrgX;
|
|
|
|
Points[CurrentPoint].y += dc->w.DCOrgY;
|
|
|
|
}
|
2003-03-20 03:07:38 +00:00
|
|
|
|
|
|
|
RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
|
|
|
//ei not yet implemented ASSERT(RectBounds);
|
|
|
|
|
2003-06-25 16:55:33 +00:00
|
|
|
if (PATH_IsPathOpen(dc->w.path))
|
2003-08-15 18:51:32 +00:00
|
|
|
{
|
2003-03-20 03:07:38 +00:00
|
|
|
ret = PATH_Polygon(hDC, Points, Count);
|
2003-08-15 18:51:32 +00:00
|
|
|
}
|
|
|
|
else
|
2003-06-25 16:55:33 +00:00
|
|
|
{
|
|
|
|
/* Get the current pen. */
|
|
|
|
pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
|
2003-03-20 03:07:38 +00:00
|
|
|
ASSERT(pen);
|
2003-06-25 16:55:33 +00:00
|
|
|
OutBrushObj = (PBRUSHOBJ) PenToBrushObj(dc, pen);
|
|
|
|
GDIOBJ_UnlockObj(dc->w.hPen, GO_PEN_MAGIC);
|
2003-08-15 18:51:32 +00:00
|
|
|
|
2003-06-25 16:55:33 +00:00
|
|
|
DestRect.left = Points[0].x;
|
|
|
|
DestRect.right = Points[0].x;
|
|
|
|
DestRect.top = Points[0].y;
|
|
|
|
DestRect.bottom = Points[0].y;
|
2003-08-15 18:51:32 +00:00
|
|
|
|
2003-06-25 16:55:33 +00:00
|
|
|
for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint)
|
|
|
|
{
|
|
|
|
DestRect.left = MIN(DestRect.left, Points[CurrentPoint].x);
|
|
|
|
DestRect.right = MAX(DestRect.right, Points[CurrentPoint].x);
|
|
|
|
DestRect.top = MIN(DestRect.top, Points[CurrentPoint].y);
|
|
|
|
DestRect.bottom = MAX(DestRect.bottom, Points[CurrentPoint].y);
|
|
|
|
}
|
2003-03-20 03:07:38 +00:00
|
|
|
|
2003-06-25 16:55:33 +00:00
|
|
|
/* Now fill the polygon with the current brush. */
|
|
|
|
FillBrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
|
2003-08-16 04:47:41 +00:00
|
|
|
|
2003-08-15 18:51:32 +00:00
|
|
|
#if 1
|
2003-08-16 04:47:41 +00:00
|
|
|
ret = FillPolygon ( dc, SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect);
|
2003-08-15 18:51:32 +00:00
|
|
|
#endif
|
2003-03-20 03:07:38 +00:00
|
|
|
// Draw the Polygon Edges with the current pen
|
2003-06-25 16:55:33 +00:00
|
|
|
for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint)
|
2003-08-15 18:51:32 +00:00
|
|
|
{
|
|
|
|
POINT To, From; //, Next;
|
2003-06-25 16:55:33 +00:00
|
|
|
|
|
|
|
/* Let CurrentPoint be i
|
|
|
|
* if i+1 > Count, Draw a line from Points[i] to Points[0]
|
|
|
|
* Draw a line from Points[i] to Points[i+1]
|
|
|
|
*/
|
|
|
|
From = Points[CurrentPoint];
|
|
|
|
if (Count <= CurrentPoint + 1)
|
|
|
|
{
|
|
|
|
To = Points[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
To = Points[CurrentPoint + 1];
|
|
|
|
}
|
|
|
|
|
|
|
|
DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y );
|
|
|
|
ret = IntEngLineTo(SurfObj,
|
2003-07-14 09:43:11 +00:00
|
|
|
dc->CombinedClip,
|
2003-06-25 16:55:33 +00:00
|
|
|
OutBrushObj,
|
|
|
|
From.x,
|
|
|
|
From.y,
|
|
|
|
To.x,
|
|
|
|
To.y,
|
|
|
|
&DestRect,
|
|
|
|
dc->w.ROPmode); /* MIX */
|
2003-03-20 03:07:38 +00:00
|
|
|
|
2003-06-25 16:55:33 +00:00
|
|
|
}
|
2003-08-15 18:51:32 +00:00
|
|
|
#if 0
|
2003-08-16 04:47:41 +00:00
|
|
|
ret = FillPolygon ( dc, SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect);
|
2003-08-15 18:51:32 +00:00
|
|
|
#endif
|
2003-06-25 16:55:33 +00:00
|
|
|
GDIOBJ_UnlockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
|
|
|
|
}
|
2003-03-20 03:07:38 +00:00
|
|
|
|
|
|
|
GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
2003-06-25 16:55:33 +00:00
|
|
|
DC_ReleasePtr(hDC);
|
|
|
|
ExFreePool(Points);
|
|
|
|
|
2003-03-20 03:07:38 +00:00
|
|
|
return ret;
|
1999-07-22 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
2003-03-20 03:07:38 +00:00
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
W32kPolyPolygon(HDC hDC,
|
1999-07-22 16:21:53 +00:00
|
|
|
CONST LPPOINT Points,
|
|
|
|
CONST LPINT PolyCounts,
|
|
|
|
int Count)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
W32kRectangle(HDC hDC,
|
1999-07-22 16:21:53 +00:00
|
|
|
int LeftRect,
|
|
|
|
int TopRect,
|
|
|
|
int RightRect,
|
|
|
|
int BottomRect)
|
|
|
|
{
|
2001-03-31 15:35:08 +00:00
|
|
|
DC *dc = DC_HandleToPtr(hDC);
|
2002-09-01 20:39:56 +00:00
|
|
|
SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
|
2002-09-08 10:23:54 +00:00
|
|
|
PBRUSHOBJ BrushObj;
|
2001-03-31 15:35:08 +00:00
|
|
|
BOOL ret;
|
2002-07-13 21:37:27 +00:00
|
|
|
PRECTL RectBounds;
|
|
|
|
PENOBJ * pen;
|
2002-09-01 20:39:56 +00:00
|
|
|
RECTL DestRect;
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2002-07-13 21:37:27 +00:00
|
|
|
if(!dc)
|
|
|
|
return FALSE;
|
|
|
|
|
|
|
|
RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
|
|
|
//ei not yet implemented ASSERT(RectBounds);
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2003-08-15 18:51:32 +00:00
|
|
|
if(PATH_IsPathOpen(dc->w.path))
|
|
|
|
{
|
2001-03-31 15:35:08 +00:00
|
|
|
ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
|
2003-08-15 18:51:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2001-06-02 08:43:48 +00:00
|
|
|
// Draw the rectangle with the current pen
|
2002-09-01 20:39:56 +00:00
|
|
|
pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
|
|
|
|
ASSERT(pen);
|
2002-09-08 10:23:54 +00:00
|
|
|
BrushObj = (PBRUSHOBJ)PenToBrushObj(dc, pen);
|
2002-09-01 20:39:56 +00:00
|
|
|
GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC );
|
|
|
|
|
|
|
|
LeftRect += dc->w.DCOrgX;
|
2003-08-16 05:00:14 +00:00
|
|
|
RightRect += dc->w.DCOrgX - 1;
|
2002-09-01 20:39:56 +00:00
|
|
|
TopRect += dc->w.DCOrgY;
|
2003-08-16 05:00:14 +00:00
|
|
|
BottomRect += dc->w.DCOrgY - 1;
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2003-02-15 19:16:34 +00:00
|
|
|
ret = IntEngLineTo(SurfObj,
|
2003-07-14 09:43:11 +00:00
|
|
|
dc->CombinedClip,
|
2003-02-15 19:16:34 +00:00
|
|
|
BrushObj,
|
|
|
|
LeftRect, TopRect, RightRect, TopRect,
|
|
|
|
RectBounds, // Bounding rectangle
|
|
|
|
dc->w.ROPmode); // MIX
|
|
|
|
|
|
|
|
ret = IntEngLineTo(SurfObj,
|
2003-07-14 09:43:11 +00:00
|
|
|
dc->CombinedClip,
|
2003-02-15 19:16:34 +00:00
|
|
|
BrushObj,
|
|
|
|
RightRect, TopRect, RightRect, BottomRect,
|
|
|
|
RectBounds, // Bounding rectangle
|
|
|
|
dc->w.ROPmode); // MIX
|
|
|
|
|
|
|
|
ret = IntEngLineTo(SurfObj,
|
2003-07-14 09:43:11 +00:00
|
|
|
dc->CombinedClip,
|
2003-02-15 19:16:34 +00:00
|
|
|
BrushObj,
|
2003-08-16 05:00:14 +00:00
|
|
|
RightRect, BottomRect, LeftRect, BottomRect,
|
2003-02-15 19:16:34 +00:00
|
|
|
RectBounds, // Bounding rectangle
|
|
|
|
dc->w.ROPmode); // MIX
|
|
|
|
|
|
|
|
ret = IntEngLineTo(SurfObj,
|
2003-07-14 09:43:11 +00:00
|
|
|
dc->CombinedClip,
|
2003-02-15 19:16:34 +00:00
|
|
|
BrushObj,
|
2003-08-16 05:00:14 +00:00
|
|
|
LeftRect, BottomRect, LeftRect, TopRect,
|
2003-02-15 19:16:34 +00:00
|
|
|
RectBounds, // Bounding rectangle
|
|
|
|
dc->w.ROPmode); // MIX */
|
2001-03-31 15:35:08 +00:00
|
|
|
|
2002-09-21 10:39:54 +00:00
|
|
|
// FIXME: BrushObj is obtained above; decide which one is correct
|
2002-09-01 20:39:56 +00:00
|
|
|
BrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
|
2002-09-21 10:39:54 +00:00
|
|
|
|
|
|
|
if (BrushObj)
|
|
|
|
{
|
|
|
|
if (BrushObj->logbrush.lbStyle != BS_NULL)
|
2003-01-18 20:47:32 +00:00
|
|
|
{
|
2002-09-21 10:39:54 +00:00
|
|
|
DestRect.left = LeftRect + 1;
|
2003-08-16 05:00:14 +00:00
|
|
|
DestRect.right = RightRect;
|
2002-09-21 10:39:54 +00:00
|
|
|
DestRect.top = TopRect + 1;
|
2003-08-16 05:00:14 +00:00
|
|
|
DestRect.bottom = BottomRect;
|
|
|
|
ret = IntEngBitBlt(SurfObj,
|
2002-09-21 10:39:54 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&DestRect,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
BrushObj,
|
|
|
|
NULL,
|
|
|
|
PATCOPY);
|
|
|
|
}
|
|
|
|
}
|
2003-01-18 20:47:32 +00:00
|
|
|
GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC );
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
2000-06-16 07:25:41 +00:00
|
|
|
|
|
|
|
// FIXME: Move current position in DC?
|
2002-07-13 21:37:27 +00:00
|
|
|
GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
|
|
|
|
DC_ReleasePtr( hDC );
|
2000-06-16 07:25:41 +00:00
|
|
|
return TRUE;
|
1999-07-22 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
W32kRoundRect(HDC hDC,
|
1999-07-22 16:21:53 +00:00
|
|
|
int LeftRect,
|
2002-07-13 21:37:27 +00:00
|
|
|
int TopRect,
|
|
|
|
int RightRect,
|
1999-07-22 16:21:53 +00:00
|
|
|
int BottomRect,
|
|
|
|
int Width,
|
|
|
|
int Height)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
}
|
2003-05-18 17:16:18 +00:00
|
|
|
/* EOF */
|