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.
|
|
|
|
*/
|
2004-05-10 17:07:20 +00:00
|
|
|
#include <w32k.h>
|
1999-07-22 16:21:53 +00:00
|
|
|
|
2003-09-12 22:17:06 +00:00
|
|
|
/*
|
|
|
|
* a couple macros to fill a single pixel or a line
|
|
|
|
*/
|
2004-07-14 20:48:58 +00:00
|
|
|
#define PUTPIXEL(x,y,BrushInst) \
|
2005-06-20 08:31:48 +00:00
|
|
|
ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
|
|
|
|
dc->CombinedClip, \
|
|
|
|
&BrushInst.BrushObject, \
|
|
|
|
x, y, (x)+1, y, \
|
|
|
|
&RectBounds, \
|
2005-02-05 10:19:49 +00:00
|
|
|
ROP2_TO_MIX(dc->w.ROPmode));
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2004-07-14 20:48:58 +00:00
|
|
|
#define PUTLINE(x1,y1,x2,y2,BrushInst) \
|
2005-06-20 08:31:48 +00:00
|
|
|
ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
|
|
|
|
dc->CombinedClip, \
|
|
|
|
&BrushInst.BrushObject, \
|
|
|
|
x1, y1, x2, y2, \
|
|
|
|
&RectBounds, \
|
2005-02-05 10:19:49 +00:00
|
|
|
ROP2_TO_MIX(dc->w.ROPmode));
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
BOOL FASTCALL
|
|
|
|
IntGdiPolygon(PDC dc,
|
|
|
|
PPOINT UnsafePoints,
|
|
|
|
int Count)
|
|
|
|
{
|
2004-07-03 13:55:37 +00:00
|
|
|
BITMAPOBJ *BitmapObj;
|
2004-04-05 21:26:25 +00:00
|
|
|
PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
|
2004-07-14 20:48:58 +00:00
|
|
|
GDIBRUSHINST PenBrushInst, FillBrushInst;
|
2003-12-13 10:57:29 +00:00
|
|
|
BOOL ret = FALSE; // default to failure
|
|
|
|
RECTL DestRect;
|
|
|
|
int CurrentPoint;
|
|
|
|
|
|
|
|
ASSERT(dc); // caller's responsibility to pass a valid dc
|
|
|
|
|
|
|
|
if ( NULL == UnsafePoints || Count < 2 )
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-07-03 13:55:37 +00:00
|
|
|
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
|
2004-12-12 01:40:39 +00:00
|
|
|
/* FIXME - BitmapObj can be NULL!!!! don't assert but handle this case gracefully! */
|
2004-07-03 13:55:37 +00:00
|
|
|
ASSERT(BitmapObj);
|
2003-12-13 10:57:29 +00:00
|
|
|
|
|
|
|
/* Convert to screen coordinates */
|
|
|
|
for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++)
|
|
|
|
{
|
2003-12-13 13:05:30 +00:00
|
|
|
UnsafePoints[CurrentPoint].x += dc->w.DCOrgX;
|
|
|
|
UnsafePoints[CurrentPoint].y += dc->w.DCOrgY;
|
2003-12-13 10:57:29 +00:00
|
|
|
}
|
|
|
|
|
2005-05-08 02:11:54 +00:00
|
|
|
if (PATH_IsPathOpen(dc->w.path))
|
2003-12-13 13:05:30 +00:00
|
|
|
ret = PATH_Polygon(dc, UnsafePoints, Count );
|
2003-12-13 10:57:29 +00:00
|
|
|
else
|
|
|
|
{
|
2003-12-13 13:05:30 +00:00
|
|
|
DestRect.left = UnsafePoints[0].x;
|
|
|
|
DestRect.right = UnsafePoints[0].x;
|
|
|
|
DestRect.top = UnsafePoints[0].y;
|
|
|
|
DestRect.bottom = UnsafePoints[0].y;
|
2003-12-13 10:57:29 +00:00
|
|
|
|
|
|
|
for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint)
|
|
|
|
{
|
2004-04-09 20:03:21 +00:00
|
|
|
DestRect.left = min(DestRect.left, UnsafePoints[CurrentPoint].x);
|
|
|
|
DestRect.right = max(DestRect.right, UnsafePoints[CurrentPoint].x);
|
|
|
|
DestRect.top = min(DestRect.top, UnsafePoints[CurrentPoint].y);
|
|
|
|
DestRect.bottom = max(DestRect.bottom, UnsafePoints[CurrentPoint].y);
|
2003-12-13 10:57:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Now fill the polygon with the current brush. */
|
|
|
|
FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
|
2005-02-20 18:01:03 +00:00
|
|
|
if (FillBrushObj && !(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
|
2004-07-14 20:48:58 +00:00
|
|
|
{
|
|
|
|
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
|
2005-02-05 10:19:49 +00:00
|
|
|
ret = FillPolygon ( dc, BitmapObj, &FillBrushInst.BrushObject, ROP2_TO_MIX(dc->w.ROPmode), UnsafePoints, Count, DestRect );
|
2004-07-14 20:48:58 +00:00
|
|
|
}
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
2003-12-13 10:57:29 +00:00
|
|
|
|
2004-04-05 21:26:25 +00:00
|
|
|
/* get BRUSHOBJ from current pen. */
|
|
|
|
PenBrushObj = PENOBJ_LockPen(dc->w.hPen);
|
2003-12-13 10:57:29 +00:00
|
|
|
// Draw the Polygon Edges with the current pen ( if not a NULL pen )
|
2005-02-20 18:01:03 +00:00
|
|
|
if (PenBrushObj && !(PenBrushObj->flAttrs & GDIBRUSH_IS_NULL))
|
2003-12-13 10:57:29 +00:00
|
|
|
{
|
2005-02-20 18:01:03 +00:00
|
|
|
IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
|
2003-12-13 10:57:29 +00:00
|
|
|
for ( CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint )
|
|
|
|
{
|
|
|
|
POINT To, From; //, Next;
|
|
|
|
|
|
|
|
/* 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]
|
|
|
|
*/
|
2003-12-13 13:05:30 +00:00
|
|
|
From = UnsafePoints[CurrentPoint];
|
2003-12-13 10:57:29 +00:00
|
|
|
if (Count <= CurrentPoint + 1)
|
2003-12-13 13:05:30 +00:00
|
|
|
To = UnsafePoints[0];
|
2003-12-13 10:57:29 +00:00
|
|
|
else
|
2003-12-13 13:05:30 +00:00
|
|
|
To = UnsafePoints[CurrentPoint + 1];
|
2003-12-13 10:57:29 +00:00
|
|
|
|
|
|
|
//DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y );
|
2005-06-20 08:31:48 +00:00
|
|
|
ret = IntEngLineTo(&BitmapObj->SurfObj,
|
2003-12-13 10:57:29 +00:00
|
|
|
dc->CombinedClip,
|
2004-07-14 20:48:58 +00:00
|
|
|
&PenBrushInst.BrushObject,
|
2003-12-13 10:57:29 +00:00
|
|
|
From.x,
|
|
|
|
From.y,
|
|
|
|
To.x,
|
|
|
|
To.y,
|
|
|
|
&DestRect,
|
2005-02-05 10:19:49 +00:00
|
|
|
ROP2_TO_MIX(dc->w.ROPmode)); /* MIX */
|
2003-12-13 10:57:29 +00:00
|
|
|
}
|
|
|
|
}
|
2005-06-07 16:34:07 +00:00
|
|
|
PENOBJ_UnlockPen(PenBrushObj);
|
2003-12-13 10:57:29 +00:00
|
|
|
}
|
|
|
|
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL FASTCALL
|
|
|
|
IntGdiPolyPolygon(DC *dc,
|
|
|
|
LPPOINT Points,
|
|
|
|
LPINT PolyCounts,
|
|
|
|
int Count)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
LPPOINT pt;
|
|
|
|
LPINT pc;
|
|
|
|
BOOL ret = FALSE; // default to failure
|
|
|
|
|
|
|
|
pt = Points;
|
|
|
|
pc = PolyCounts;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
for (i=0;i<Count;i++)
|
|
|
|
{
|
|
|
|
ret = IntGdiPolygon ( dc, pt, *pc );
|
|
|
|
if (ret == FALSE)
|
|
|
|
{
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
pt+=*pc++;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
NtGdiChord(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;
|
2004-07-14 20:48:58 +00:00
|
|
|
return FALSE;
|
1999-07-22 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
/*
|
|
|
|
* NtGdiEllipse
|
2005-05-08 02:11:54 +00:00
|
|
|
*
|
2004-02-04 22:10:00 +00:00
|
|
|
* Author
|
|
|
|
* Filip Navara
|
|
|
|
*
|
|
|
|
* Remarks
|
|
|
|
* This function uses optimized Bresenham's ellipse algorithm. It draws
|
|
|
|
* four lines of the ellipse in one pass.
|
|
|
|
*
|
|
|
|
* Todo
|
|
|
|
* Make it look like a Windows ellipse.
|
|
|
|
*/
|
|
|
|
|
|
|
|
BOOL STDCALL
|
|
|
|
NtGdiEllipse(
|
|
|
|
HDC hDC,
|
|
|
|
int nLeftRect,
|
|
|
|
int nTopRect,
|
|
|
|
int nRightRect,
|
|
|
|
int nBottomRect)
|
1999-07-22 16:21:53 +00:00
|
|
|
{
|
2004-02-04 22:10:00 +00:00
|
|
|
int ix, iy;
|
|
|
|
int A, B, C, D;
|
|
|
|
int da, db;
|
|
|
|
int NewA, NewB, NewC, NewD;
|
|
|
|
int nx, ny;
|
|
|
|
int CenterX, CenterY;
|
|
|
|
int RadiusX, RadiusY;
|
|
|
|
int Temp;
|
2004-04-05 21:26:25 +00:00
|
|
|
PGDIBRUSHOBJ FillBrush, PenBrush;
|
2004-07-14 20:48:58 +00:00
|
|
|
GDIBRUSHINST FillBrushInst, PenBrushInst;
|
2004-07-03 13:55:37 +00:00
|
|
|
BITMAPOBJ *BitmapObj;
|
2004-02-04 22:10:00 +00:00
|
|
|
RECTL RectBounds;
|
|
|
|
PDC dc;
|
|
|
|
BOOL ret = TRUE, Cond1, Cond2;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Check the parameters.
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (nRightRect <= nLeftRect || nBottomRect <= nTopRect)
|
|
|
|
{
|
2003-09-12 22:17:06 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
2004-02-04 22:10:00 +00:00
|
|
|
}
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
/*
|
|
|
|
* Get pointers to all necessary GDI objects.
|
|
|
|
*/
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
dc = DC_LockDc(hDC);
|
|
|
|
if (dc == NULL)
|
|
|
|
{
|
2003-09-23 21:48:18 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
2003-09-12 22:17:06 +00:00
|
|
|
return FALSE;
|
2004-02-04 22:10:00 +00:00
|
|
|
}
|
2005-03-07 22:24:33 +00:00
|
|
|
if (dc->IsIC)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-03-07 22:24:33 +00:00
|
|
|
/* Yes, Windows really returns TRUE in this case */
|
|
|
|
return TRUE;
|
|
|
|
}
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
FillBrush = BRUSHOBJ_LockBrush(dc->w.hBrush);
|
|
|
|
if (NULL == FillBrush)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2003-09-12 22:17:06 +00:00
|
|
|
SetLastWin32Error(ERROR_INTERNAL_ERROR);
|
|
|
|
return FALSE;
|
2004-02-04 22:10:00 +00:00
|
|
|
}
|
|
|
|
|
2004-04-05 21:26:25 +00:00
|
|
|
PenBrush = PENOBJ_LockPen(dc->w.hPen);
|
|
|
|
if (NULL == PenBrush)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrush);
|
|
|
|
DC_UnlockDc(dc);
|
2004-04-05 21:26:25 +00:00
|
|
|
SetLastWin32Error(ERROR_INTERNAL_ERROR);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-07-03 13:55:37 +00:00
|
|
|
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
|
2005-02-20 18:01:03 +00:00
|
|
|
if (NULL == BitmapObj)
|
2005-02-20 17:35:50 +00:00
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrush);
|
|
|
|
PENOBJ_UnlockPen(PenBrush);
|
|
|
|
DC_UnlockDc(dc);
|
2005-02-20 17:35:50 +00:00
|
|
|
SetLastWin32Error(ERROR_INTERNAL_ERROR);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2004-02-04 22:10:00 +00:00
|
|
|
|
2004-07-14 20:48:58 +00:00
|
|
|
IntGdiInitBrushInstance(&FillBrushInst, FillBrush, dc->XlateBrush);
|
|
|
|
IntGdiInitBrushInstance(&PenBrushInst, PenBrush, dc->XlatePen);
|
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
nLeftRect += dc->w.DCOrgX;
|
2004-03-03 04:09:20 +00:00
|
|
|
nRightRect += dc->w.DCOrgX - 1;
|
2004-02-04 22:10:00 +00:00
|
|
|
nTopRect += dc->w.DCOrgY;
|
2004-03-03 04:09:20 +00:00
|
|
|
nBottomRect += dc->w.DCOrgY - 1;
|
2004-02-04 22:10:00 +00:00
|
|
|
|
|
|
|
RadiusX = max((nRightRect - nLeftRect) >> 1, 1);
|
|
|
|
RadiusY = max((nBottomRect - nTopRect) >> 1, 1);
|
|
|
|
CenterX = nLeftRect + RadiusX;
|
|
|
|
CenterY = nTopRect + RadiusY;
|
|
|
|
|
|
|
|
RectBounds.left = nLeftRect;
|
|
|
|
RectBounds.right = nRightRect;
|
|
|
|
RectBounds.top = nTopRect;
|
|
|
|
RectBounds.bottom = nBottomRect;
|
|
|
|
|
|
|
|
if (RadiusX > RadiusY)
|
|
|
|
{
|
|
|
|
nx = RadiusX;
|
|
|
|
ny = RadiusY;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
nx = RadiusY;
|
|
|
|
ny = RadiusX;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
da = -1;
|
|
|
|
db = 0xFFFF;
|
2005-05-08 02:11:54 +00:00
|
|
|
ix = 0;
|
2004-02-04 22:10:00 +00:00
|
|
|
iy = nx * 64;
|
2005-05-08 02:11:54 +00:00
|
|
|
NewA = 0;
|
2004-02-04 22:10:00 +00:00
|
|
|
NewB = (iy + 32) >> 6;
|
2005-05-08 02:11:54 +00:00
|
|
|
NewC = 0;
|
2004-02-04 22:10:00 +00:00
|
|
|
NewD = (NewB * ny) / nx;
|
|
|
|
|
|
|
|
do {
|
2005-05-08 02:11:54 +00:00
|
|
|
A = NewA;
|
|
|
|
B = NewB;
|
|
|
|
C = NewC;
|
2004-02-04 22:10:00 +00:00
|
|
|
D = NewD;
|
|
|
|
|
|
|
|
ix += iy / nx;
|
|
|
|
iy -= ix / nx;
|
2005-05-08 02:11:54 +00:00
|
|
|
NewA = (ix + 32) >> 6;
|
2004-02-04 22:10:00 +00:00
|
|
|
NewB = (iy + 32) >> 6;
|
2005-05-08 02:11:54 +00:00
|
|
|
NewC = (NewA * ny) / nx;
|
2004-02-04 22:10:00 +00:00
|
|
|
NewD = (NewB * ny) / nx;
|
|
|
|
|
|
|
|
if (RadiusX > RadiusY)
|
|
|
|
{
|
|
|
|
Temp = A; A = C; C = Temp;
|
|
|
|
Temp = B; B = D; D = Temp;
|
|
|
|
Cond1 = ((C != NewA) || (B != NewD)) && (NewC <= NewD);
|
|
|
|
Cond2 = ((D != NewB) || (A != NewC)) && (NewC <= B);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Cond1 = ((C != NewC) || (B != NewB)) && (NewA <= NewB);
|
|
|
|
Cond2 = ((D != NewD) || (A != NewA)) && (NewA <= B);
|
|
|
|
}
|
2003-09-23 21:48:18 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
/*
|
|
|
|
* Draw the lines going from inner to outer (+ mirrored).
|
|
|
|
*/
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
if ((A > da) && (A < db))
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE(CenterX - D, CenterY + A, CenterX + D, CenterY + A, FillBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
if (A)
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE(CenterX - D, CenterY - A, CenterX + D, CenterY - A, FillBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
}
|
|
|
|
da = A;
|
|
|
|
}
|
2003-09-23 21:48:18 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
/*
|
|
|
|
* Draw the lines going from outer to inner (+ mirrored).
|
|
|
|
*/
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
if ((B < db) && (B > da))
|
2005-05-08 02:11:54 +00:00
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE(CenterX - C, CenterY + B, CenterX + C, CenterY + B, FillBrushInst);
|
|
|
|
PUTLINE(CenterX - C, CenterY - B, CenterX + C, CenterY - B, FillBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
db = B;
|
|
|
|
}
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
/*
|
|
|
|
* Draw the pixels on the margin.
|
|
|
|
*/
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
if (Cond1)
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL(CenterX + C, CenterY + B, PenBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
if (C)
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL(CenterX - C, CenterY + B, PenBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
if (B)
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL(CenterX + C, CenterY - B, PenBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
if (C)
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL(CenterX - C, CenterY - B, PenBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
}
|
|
|
|
}
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
if (Cond2)
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL(CenterX + D, CenterY + A, PenBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
if (D)
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL(CenterX - D, CenterY + A, PenBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
if (A)
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL(CenterX + D, CenterY - A, PenBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
if (D)
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL(CenterX - D, CenterY - A, PenBrushInst);
|
2004-02-04 22:10:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} while (B > A);
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
|
|
|
BRUSHOBJ_UnlockBrush(FillBrush);
|
|
|
|
PENOBJ_UnlockPen(PenBrush);
|
|
|
|
DC_UnlockDc(dc);
|
2003-09-12 22:17:06 +00:00
|
|
|
|
2004-02-04 22:10:00 +00:00
|
|
|
return ret;
|
1999-07-22 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
2003-12-12 14:22:37 +00:00
|
|
|
typedef struct tagSHAPEPOINT
|
|
|
|
{
|
|
|
|
int X;
|
|
|
|
int Y;
|
|
|
|
int Type;
|
|
|
|
} SHAPEPOINT, *PSHAPEPOINT;
|
|
|
|
|
|
|
|
#define SHAPEPOINT_TYPE_CIRCLE 'C'
|
|
|
|
#define SHAPEPOINT_TYPE_LINE_RIGHT 'R' /* Fill at right side of line */
|
|
|
|
#define SHAPEPOINT_TYPE_LINE_LEFT 'L' /* Fill at left side of line */
|
|
|
|
|
|
|
|
#define SETPOINT(x, y, type) \
|
|
|
|
ShapePoints[*PointCount].X = (x); \
|
|
|
|
ShapePoints[*PointCount].Y = (y); \
|
|
|
|
ShapePoints[*PointCount].Type = (type); \
|
|
|
|
(*PointCount)++
|
|
|
|
|
|
|
|
#define SETCIRCLEPOINT(x, y) \
|
|
|
|
SETPOINT(x, y, SHAPEPOINT_TYPE_CIRCLE)
|
|
|
|
|
|
|
|
#ifdef TODO
|
|
|
|
STATIC VOID
|
|
|
|
FASTCALL
|
|
|
|
CirclePoints(UINT *PointCount, PSHAPEPOINT ShapePoints, int Left, int Top,
|
|
|
|
int Right, int Bottom)
|
|
|
|
{
|
|
|
|
int X, X18, X27, X36, X45;
|
|
|
|
int Y, Y14, Y23, Y58, Y67;
|
|
|
|
int d, Radius;
|
|
|
|
BOOL Even;
|
|
|
|
|
|
|
|
Even = (0 == (Right - Left) % 2);
|
|
|
|
Right--;
|
|
|
|
Bottom--;
|
2004-03-27 00:35:02 +00:00
|
|
|
Radius = (Right - Left) >> 1;
|
2003-12-12 14:22:37 +00:00
|
|
|
|
|
|
|
if (Even)
|
|
|
|
{
|
|
|
|
X = 0;
|
|
|
|
Y = Radius;
|
|
|
|
d = 2 - Radius;
|
|
|
|
X18 = Right;
|
2004-03-27 00:35:02 +00:00
|
|
|
X27 = ((Left + Right) >> 1) + 1;
|
|
|
|
X36 = (Left + Right) >> 1;
|
2003-12-12 14:22:37 +00:00
|
|
|
X45 = Left;
|
|
|
|
Y14 = Top + Radius;
|
|
|
|
Y23 = Top;
|
|
|
|
Y58 = Top + Radius + 1;
|
|
|
|
Y67 = Top + (Right - Left);
|
|
|
|
ShapePoints[*PointCount].X = X27;
|
|
|
|
SETCIRCLEPOINT(X27, Y23);
|
|
|
|
SETCIRCLEPOINT(X36, Y23);
|
|
|
|
SETCIRCLEPOINT(X18, Y14);
|
|
|
|
SETCIRCLEPOINT(X45, Y14);
|
|
|
|
SETCIRCLEPOINT(X18, Y58);
|
|
|
|
SETCIRCLEPOINT(X45, Y58);
|
|
|
|
SETCIRCLEPOINT(X27, Y67);
|
|
|
|
SETCIRCLEPOINT(X36, Y67);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
X = 0;
|
|
|
|
Y = Radius;
|
|
|
|
d = 1 - Radius;
|
|
|
|
X18 = Right;
|
2004-03-27 00:35:02 +00:00
|
|
|
X27 = (Left + Right) >> 1;
|
|
|
|
X36 = (Left + Right) >> 1;
|
2003-12-12 14:22:37 +00:00
|
|
|
X45 = Left;
|
|
|
|
Y14 = Top + Radius;
|
|
|
|
Y23 = Top;
|
|
|
|
Y58 = Top + Radius;
|
|
|
|
Y67 = Top + (Right - Left);
|
|
|
|
SETCIRCLEPOINT(X27, Y23);
|
|
|
|
SETCIRCLEPOINT(X45, Y14);
|
|
|
|
SETCIRCLEPOINT(X18, Y58);
|
|
|
|
SETCIRCLEPOINT(X27, Y67);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (X < Y)
|
|
|
|
{
|
|
|
|
if (d < 0)
|
|
|
|
{
|
2004-03-27 00:35:02 +00:00
|
|
|
d += (X << 1) + (Even ? 4 : 3);
|
2003-12-12 14:22:37 +00:00
|
|
|
|
|
|
|
X27++;
|
|
|
|
X36--;
|
|
|
|
Y14--;
|
|
|
|
Y58++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-03-27 00:35:02 +00:00
|
|
|
d += ((X - Y) << 1) + 5;
|
2003-12-12 14:22:37 +00:00
|
|
|
Y--;
|
|
|
|
|
|
|
|
Y23++;
|
|
|
|
Y67--;
|
|
|
|
X18--;
|
|
|
|
X45++;
|
|
|
|
X27++;
|
|
|
|
X36--;
|
|
|
|
Y14--;
|
|
|
|
Y58++;
|
|
|
|
}
|
|
|
|
X++;
|
|
|
|
|
|
|
|
SETCIRCLEPOINT(X27, Y23);
|
|
|
|
SETCIRCLEPOINT(X36, Y23);
|
|
|
|
SETCIRCLEPOINT(X18, Y14);
|
|
|
|
SETCIRCLEPOINT(X45, Y14);
|
|
|
|
SETCIRCLEPOINT(X18, Y58);
|
|
|
|
SETCIRCLEPOINT(X45, Y58);
|
|
|
|
SETCIRCLEPOINT(X27, Y67);
|
|
|
|
SETCIRCLEPOINT(X36, Y67);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC VOID
|
|
|
|
LinePoints(UINT *PointCount, PSHAPEPOINT ShapePoints, int Left, int Top,
|
|
|
|
int Right, int Bottom, int XTo, int YTo, BOOL Start)
|
|
|
|
{
|
|
|
|
LONG x, y, deltax, deltay, i, xchange, ychange, error;
|
|
|
|
int Type;
|
|
|
|
|
2004-03-27 00:35:02 +00:00
|
|
|
x = (Right + Left) >> 1;
|
|
|
|
y = (Bottom + Top) >> 1;
|
2003-12-12 14:22:37 +00:00
|
|
|
deltax = XTo - x;
|
|
|
|
deltay = YTo - y;
|
|
|
|
|
|
|
|
if (deltax < 0)
|
|
|
|
{
|
|
|
|
xchange = -1;
|
|
|
|
deltax = - deltax;
|
|
|
|
x--;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
xchange = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (deltay < 0)
|
|
|
|
{
|
|
|
|
ychange = -1;
|
|
|
|
deltay = - deltay;
|
|
|
|
y--;
|
|
|
|
Type = (Start ? SHAPEPOINT_TYPE_LINE_LEFT : SHAPEPOINT_TYPE_LINE_RIGHT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ychange = 1;
|
|
|
|
Type = (Start ? SHAPEPOINT_TYPE_LINE_RIGHT : SHAPEPOINT_TYPE_LINE_LEFT);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (y == YTo)
|
|
|
|
{
|
|
|
|
for (i = x; i <= XTo; i++)
|
|
|
|
{
|
|
|
|
SETPOINT(i, y, Type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (x == XTo)
|
|
|
|
{
|
|
|
|
for (i = y; i <= YTo; i++)
|
|
|
|
{
|
|
|
|
SETPOINT(x, i, Type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
error = 0;
|
|
|
|
|
|
|
|
if (deltax < deltay)
|
|
|
|
{
|
|
|
|
for (i = 0; i < deltay; i++)
|
|
|
|
{
|
|
|
|
SETPOINT(x, y, Type);
|
|
|
|
y = y + ychange;
|
|
|
|
error = error + deltax;
|
|
|
|
|
|
|
|
if (deltay <= error)
|
|
|
|
{
|
|
|
|
x = x + xchange;
|
|
|
|
error = error - deltay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < deltax; i++)
|
|
|
|
{
|
|
|
|
SETPOINT(x, y, Type);
|
|
|
|
x = x + xchange;
|
|
|
|
error = error + deltay;
|
|
|
|
if (deltax <= error)
|
|
|
|
{
|
|
|
|
y = y + ychange;
|
|
|
|
error = error - deltax;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC int
|
|
|
|
CDECL
|
|
|
|
CompareShapePoints(const void *pv1, const void *pv2)
|
|
|
|
{
|
|
|
|
if (((const PSHAPEPOINT) pv1)->Y < ((const PSHAPEPOINT) pv2)->Y)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (((const PSHAPEPOINT) pv2)->Y < ((const PSHAPEPOINT) pv1)->Y)
|
|
|
|
{
|
|
|
|
return +1;
|
|
|
|
}
|
|
|
|
else if (((const PSHAPEPOINT) pv1)->X < ((const PSHAPEPOINT) pv2)->X)
|
|
|
|
{
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else if (((const PSHAPEPOINT) pv2)->X < ((const PSHAPEPOINT) pv1)->X)
|
|
|
|
{
|
|
|
|
return +1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
NtGdiPie(HDC hDC,
|
2003-12-12 14:22:37 +00:00
|
|
|
int Left,
|
|
|
|
int Top,
|
|
|
|
int Right,
|
|
|
|
int Bottom,
|
|
|
|
int XRadialStart,
|
|
|
|
int YRadialStart,
|
|
|
|
int XRadialEnd,
|
|
|
|
int YRadialEnd)
|
1999-07-22 16:21:53 +00:00
|
|
|
{
|
2003-12-12 14:22:37 +00:00
|
|
|
#ifdef TODO
|
|
|
|
PDC dc;
|
|
|
|
RECTL RectBounds;
|
2004-04-09 20:03:21 +00:00
|
|
|
SURFOBJ *SurfObj;
|
2003-12-12 14:22:37 +00:00
|
|
|
BRUSHOBJ PenBrushObj;
|
|
|
|
PBRUSHOBJ FillBrushObj;
|
|
|
|
PSHAPEPOINT ShapePoints;
|
|
|
|
UINT Point, PointCount;
|
|
|
|
BOOL ret = TRUE;
|
|
|
|
int Y, CircleStart, CircleEnd, LineStart, LineEnd;
|
|
|
|
BOOL FullFill;
|
|
|
|
|
|
|
|
if (Right <= Left || Bottom <= Top)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Right - Left != Bottom - Top)
|
|
|
|
{
|
|
|
|
UNIMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
dc = DC_LockDc ( hDC );
|
|
|
|
if (NULL == dc)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-03-07 22:24:33 +00:00
|
|
|
if (dc->IsIC)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-03-07 22:24:33 +00:00
|
|
|
/* Yes, Windows really returns TRUE in this case */
|
|
|
|
return TRUE;
|
|
|
|
}
|
2003-12-12 14:22:37 +00:00
|
|
|
|
|
|
|
FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
|
|
|
|
if (NULL == FillBrushObj)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2003-12-12 14:22:37 +00:00
|
|
|
SetLastWin32Error(ERROR_INTERNAL_ERROR);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Left += dc->w.DCOrgX;
|
|
|
|
Right += dc->w.DCOrgX;
|
|
|
|
Top += dc->w.DCOrgY;
|
|
|
|
Bottom += dc->w.DCOrgY;
|
|
|
|
XRadialStart += dc->w.DCOrgX;
|
|
|
|
YRadialStart += dc->w.DCOrgY;
|
|
|
|
XRadialEnd += dc->w.DCOrgX;
|
|
|
|
YRadialEnd += dc->w.DCOrgY;
|
|
|
|
|
|
|
|
RectBounds.left = Left;
|
|
|
|
RectBounds.right = Right;
|
|
|
|
RectBounds.top = Top;
|
|
|
|
RectBounds.bottom = Bottom;
|
|
|
|
|
2004-04-09 20:03:21 +00:00
|
|
|
SurfObj = (SURFOBJ*) AccessUserObject((ULONG)dc->Surface);
|
2003-12-12 14:22:37 +00:00
|
|
|
HPenToBrushObj(&PenBrushObj, dc->w.hPen);
|
|
|
|
|
|
|
|
/* Number of points for the circle is 4 * sqrt(2) * Radius, start
|
|
|
|
and end line have at most Radius points, so allocate at least
|
|
|
|
that much */
|
2004-02-19 21:12:11 +00:00
|
|
|
ShapePoints = ExAllocatePoolWithTag(PagedPool, 8 * (Right - Left + 1) / 2 * sizeof(SHAPEPOINT), TAG_SHAPE);
|
2003-12-12 14:22:37 +00:00
|
|
|
if (NULL == ShapePoints)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
|
|
|
DC_UnlockDc(dc);
|
2003-12-12 14:22:37 +00:00
|
|
|
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Left == Right)
|
|
|
|
{
|
|
|
|
PUTPIXEL(Left, Top, &PenBrushObj);
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
|
|
|
DC_UnlockDc(dc);
|
2003-12-12 14:22:37 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
PointCount = 0;
|
|
|
|
CirclePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom);
|
|
|
|
LinePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom,
|
|
|
|
XRadialStart, YRadialStart, TRUE);
|
|
|
|
LinePoints(&PointCount, ShapePoints, Left, Top, Right, Bottom,
|
|
|
|
XRadialEnd, YRadialEnd, FALSE);
|
|
|
|
ASSERT(PointCount <= 8 * (Right - Left + 1) / 2);
|
|
|
|
EngSort((PBYTE) ShapePoints, sizeof(SHAPEPOINT), PointCount, CompareShapePoints);
|
|
|
|
|
|
|
|
FullFill = TRUE;
|
|
|
|
Point = 0;
|
|
|
|
while (Point < PointCount)
|
|
|
|
{
|
|
|
|
Y = ShapePoints[Point].Y;
|
|
|
|
|
|
|
|
/* Skip any line pixels before circle */
|
|
|
|
while (Point < PointCount && ShapePoints[Point].Y == Y
|
|
|
|
&& SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type)
|
|
|
|
{
|
|
|
|
Point++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle left side of circle */
|
|
|
|
if (Point < PointCount && ShapePoints[Point].Y == Y)
|
|
|
|
{
|
|
|
|
CircleStart = ShapePoints[Point].X;
|
|
|
|
Point++;
|
|
|
|
while (Point < PointCount && ShapePoints[Point].Y == Y
|
|
|
|
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
|
|
|
|
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
|
|
|
|
{
|
|
|
|
Point++;
|
|
|
|
}
|
|
|
|
CircleEnd = ShapePoints[Point - 1].X;
|
|
|
|
|
|
|
|
PUTLINE(CircleStart, Y, CircleEnd + 1, Y, &PenBrushObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle line(s) (max 2) inside the circle */
|
|
|
|
while (Point < PointCount && ShapePoints[Point].Y == Y
|
|
|
|
&& SHAPEPOINT_TYPE_CIRCLE != ShapePoints[Point].Type)
|
|
|
|
{
|
|
|
|
LineStart = ShapePoints[Point].X;
|
|
|
|
Point++;
|
|
|
|
while (Point < PointCount && ShapePoints[Point].Y == Y
|
|
|
|
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
|
|
|
|
&& ShapePoints[Point].Type == ShapePoints[Point - 1].Type)
|
|
|
|
{
|
|
|
|
Point++;
|
|
|
|
}
|
|
|
|
LineEnd = ShapePoints[Point - 1].X;
|
|
|
|
|
|
|
|
PUTLINE(LineStart, Y, LineEnd + 1, Y, &PenBrushObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Handle right side of circle */
|
|
|
|
while (Point < PointCount && ShapePoints[Point].Y == Y
|
|
|
|
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
|
|
|
|
{
|
|
|
|
CircleStart = ShapePoints[Point].X;
|
|
|
|
Point++;
|
|
|
|
while (Point < PointCount && ShapePoints[Point].Y == Y
|
|
|
|
&& ShapePoints[Point].X == ShapePoints[Point - 1].X + 1
|
|
|
|
&& SHAPEPOINT_TYPE_CIRCLE == ShapePoints[Point].Type)
|
|
|
|
{
|
|
|
|
Point++;
|
|
|
|
}
|
|
|
|
CircleEnd = ShapePoints[Point - 1].X;
|
|
|
|
|
|
|
|
PUTLINE(CircleStart, Y, CircleEnd + 1, Y, &PenBrushObj);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Skip any line pixels after circle */
|
|
|
|
while (Point < PointCount && ShapePoints[Point].Y == Y)
|
|
|
|
{
|
|
|
|
Point++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ExFreePool(ShapePoints);
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
|
|
|
DC_UnlockDc(dc);
|
2003-12-12 14:22:37 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
#else
|
|
|
|
return TRUE;
|
|
|
|
#endif
|
1999-07-22 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
#if 0
|
|
|
|
|
2005-05-08 02:11:54 +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
|
|
|
|
2005-05-08 02:11:54 +00:00
|
|
|
//WINDING Selects winding mode (fills any region with a nonzero winding value).
|
2003-08-16 04:47:41 +00:00
|
|
|
//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.
|
2005-05-08 02:11:54 +00:00
|
|
|
//The direction of each edge of the polygon is important.
|
2003-08-16 04:47:41 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
2003-12-13 10:57:29 +00:00
|
|
|
STDCALL
|
|
|
|
NtGdiPolygon(HDC hDC,
|
2003-12-13 13:05:30 +00:00
|
|
|
CONST PPOINT UnsafePoints,
|
|
|
|
int Count)
|
1999-07-22 16:21:53 +00:00
|
|
|
{
|
2003-12-13 10:57:29 +00:00
|
|
|
DC *dc;
|
|
|
|
LPPOINT Safept;
|
2003-06-25 16:55:33 +00:00
|
|
|
NTSTATUS Status;
|
2004-03-04 01:50:26 +00:00
|
|
|
BOOL Ret = FALSE;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-03-04 01:50:26 +00:00
|
|
|
if ( Count < 2 )
|
2003-12-13 10:57:29 +00:00
|
|
|
{
|
2004-03-04 01:50:26 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
2003-12-13 10:57:29 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-03-04 01:50:26 +00:00
|
|
|
dc = DC_LockDc(hDC);
|
|
|
|
if(!dc)
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
else
|
2003-12-13 10:57:29 +00:00
|
|
|
{
|
2005-03-07 22:24:33 +00:00
|
|
|
if (dc->IsIC)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-03-07 22:24:33 +00:00
|
|
|
/* Yes, Windows really returns TRUE in this case */
|
|
|
|
return TRUE;
|
|
|
|
}
|
2004-06-20 00:45:37 +00:00
|
|
|
Safept = ExAllocatePoolWithTag(PagedPool, sizeof(POINT) * Count, TAG_SHAPE);
|
2003-12-13 10:57:29 +00:00
|
|
|
if(!Safept)
|
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
2004-03-04 01:50:26 +00:00
|
|
|
else
|
2003-06-25 16:55:33 +00:00
|
|
|
{
|
2004-03-04 01:50:26 +00:00
|
|
|
Status = MmCopyFromCaller(Safept, UnsafePoints, sizeof(POINT) * Count);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
SetLastNtError(Status);
|
|
|
|
else
|
|
|
|
Ret = IntGdiPolygon(dc, Safept, Count);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 13:05:30 +00:00
|
|
|
ExFreePool(Safept);
|
2003-06-25 16:55:33 +00:00
|
|
|
}
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2003-08-17 17:32:58 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +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
|
2003-12-13 13:05:30 +00:00
|
|
|
NtGdiPolyPolygon(HDC hDC,
|
|
|
|
CONST LPPOINT Points,
|
|
|
|
CONST LPINT PolyCounts,
|
|
|
|
int Count)
|
1999-07-22 16:21:53 +00:00
|
|
|
{
|
big patch by Jonathon Wilson for GDI32 & related stuff
changes are:
1.add some new functions to ascii.h and unicode.h
2.add some definitions to base.h
3.add a bunch of functions to funcs.h
4.add a few structures to structs.h
5.add definitions for some missing stuff to winddi.h
6.general fixes and updates to structures and definitions in winddi.h
7.add some other structures and definitions to winddi.h
8.add some Engxxx functions to winddi.h
9.a small fix in crtdll.def
10.add all the new defs to gdi32.def and gdi32.edf
11.add all the new stubs to gdi32 stubs.c
12.implement PolyPolygon and PolyPolyline
13.some fixes to msafd.def/msafd.edf
14.change WahCloseNotificationHelper to WahCloseNotificationHandleHelper in ws2help to match the microsoft definition
15.add d3d.h, d3dcaps.h, d3dtypes.h, ddraw.h, d3dhal.h, ddrawi.h to include and include\ddk (needed for the GdiEntryxx and DdEntryxx functions in gdi32.dll). Headers are modified versions of those from WINE (stuff removed that wont compile without OLE headers, some stuff added)
16.add ddentry.h which is used with the DdEntry and GdiEntry functions
and 17.fix some stuff in stubs.c of win32k
A fair few of these definitions could be wrong (some of them are educated guesses, like some of the Gdixxx functions)
If anyone has any corrections, any answers for the FIXMEs and structures I dont have definitions for, definitions for the remaining stuff in gdi32.def with a ; in front of it or whatever, do let me know.
Or if anyone wants to comment about my changes, please let me know.
svn path=/trunk/; revision=5867
2003-08-26 12:28:53 +00:00
|
|
|
DC *dc;
|
2003-12-13 10:57:29 +00:00
|
|
|
LPPOINT Safept;
|
|
|
|
LPINT SafePolyPoints;
|
|
|
|
NTSTATUS Status;
|
|
|
|
BOOL Ret;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
dc = DC_LockDc(hDC);
|
|
|
|
if(!dc)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-03-07 22:24:33 +00:00
|
|
|
if (dc->IsIC)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-03-07 22:24:33 +00:00
|
|
|
/* Yes, Windows really returns TRUE in this case */
|
|
|
|
return TRUE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
if(Count > 0)
|
|
|
|
{
|
2004-06-20 00:45:37 +00:00
|
|
|
Safept = ExAllocatePoolWithTag(PagedPool, (sizeof(POINT) + sizeof(INT)) * Count, TAG_SHAPE);
|
2003-12-13 10:57:29 +00:00
|
|
|
if(!Safept)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2003-12-13 10:57:29 +00:00
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
SafePolyPoints = (LPINT)&Safept[Count];
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
Status = MmCopyFromCaller(Safept, Points, sizeof(POINT) * Count);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2003-12-13 10:57:29 +00:00
|
|
|
ExFreePool(Safept);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
Status = MmCopyFromCaller(SafePolyPoints, PolyCounts, sizeof(INT) * Count);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2003-12-13 10:57:29 +00:00
|
|
|
ExFreePool(Safept);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
big patch by Jonathon Wilson for GDI32 & related stuff
changes are:
1.add some new functions to ascii.h and unicode.h
2.add some definitions to base.h
3.add a bunch of functions to funcs.h
4.add a few structures to structs.h
5.add definitions for some missing stuff to winddi.h
6.general fixes and updates to structures and definitions in winddi.h
7.add some other structures and definitions to winddi.h
8.add some Engxxx functions to winddi.h
9.a small fix in crtdll.def
10.add all the new defs to gdi32.def and gdi32.edf
11.add all the new stubs to gdi32 stubs.c
12.implement PolyPolygon and PolyPolyline
13.some fixes to msafd.def/msafd.edf
14.change WahCloseNotificationHelper to WahCloseNotificationHandleHelper in ws2help to match the microsoft definition
15.add d3d.h, d3dcaps.h, d3dtypes.h, ddraw.h, d3dhal.h, ddrawi.h to include and include\ddk (needed for the GdiEntryxx and DdEntryxx functions in gdi32.dll). Headers are modified versions of those from WINE (stuff removed that wont compile without OLE headers, some stuff added)
16.add ddentry.h which is used with the DdEntry and GdiEntry functions
and 17.fix some stuff in stubs.c of win32k
A fair few of these definitions could be wrong (some of them are educated guesses, like some of the Gdixxx functions)
If anyone has any corrections, any answers for the FIXMEs and structures I dont have definitions for, definitions for the remaining stuff in gdi32.def with a ; in front of it or whatever, do let me know.
Or if anyone wants to comment about my changes, please let me know.
svn path=/trunk/; revision=5867
2003-08-26 12:28:53 +00:00
|
|
|
else
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2003-12-13 10:57:29 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
big patch by Jonathon Wilson for GDI32 & related stuff
changes are:
1.add some new functions to ascii.h and unicode.h
2.add some definitions to base.h
3.add a bunch of functions to funcs.h
4.add a few structures to structs.h
5.add definitions for some missing stuff to winddi.h
6.general fixes and updates to structures and definitions in winddi.h
7.add some other structures and definitions to winddi.h
8.add some Engxxx functions to winddi.h
9.a small fix in crtdll.def
10.add all the new defs to gdi32.def and gdi32.edf
11.add all the new stubs to gdi32 stubs.c
12.implement PolyPolygon and PolyPolyline
13.some fixes to msafd.def/msafd.edf
14.change WahCloseNotificationHelper to WahCloseNotificationHandleHelper in ws2help to match the microsoft definition
15.add d3d.h, d3dcaps.h, d3dtypes.h, ddraw.h, d3dhal.h, ddrawi.h to include and include\ddk (needed for the GdiEntryxx and DdEntryxx functions in gdi32.dll). Headers are modified versions of those from WINE (stuff removed that wont compile without OLE headers, some stuff added)
16.add ddentry.h which is used with the DdEntry and GdiEntry functions
and 17.fix some stuff in stubs.c of win32k
A fair few of these definitions could be wrong (some of them are educated guesses, like some of the Gdixxx functions)
If anyone has any corrections, any answers for the FIXMEs and structures I dont have definitions for, definitions for the remaining stuff in gdi32.def with a ; in front of it or whatever, do let me know.
Or if anyone wants to comment about my changes, please let me know.
svn path=/trunk/; revision=5867
2003-08-26 12:28:53 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
Ret = IntGdiPolyPolygon(dc, Safept, SafePolyPoints, Count);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
ExFreePool(Safept);
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 10:57:29 +00:00
|
|
|
return Ret;
|
1999-07-22 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
2003-08-17 17:32:58 +00:00
|
|
|
FASTCALL
|
|
|
|
IntRectangle(PDC dc,
|
|
|
|
int LeftRect,
|
|
|
|
int TopRect,
|
|
|
|
int RightRect,
|
|
|
|
int BottomRect)
|
1999-07-22 16:21:53 +00:00
|
|
|
{
|
2004-07-03 13:55:37 +00:00
|
|
|
BITMAPOBJ *BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
|
2004-04-05 21:26:25 +00:00
|
|
|
PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
|
2004-07-14 20:48:58 +00:00
|
|
|
GDIBRUSHINST PenBrushInst, FillBrushInst;
|
2003-08-17 17:32:58 +00:00
|
|
|
BOOL ret = FALSE; // default to failure
|
|
|
|
RECTL DestRect;
|
2005-02-05 10:19:49 +00:00
|
|
|
MIX Mix;
|
2003-08-17 17:32:58 +00:00
|
|
|
|
|
|
|
ASSERT ( dc ); // caller's responsibility to set this up
|
2004-12-12 01:40:39 +00:00
|
|
|
/* FIXME - BitmapObj can be NULL!!! Don't assert but handle this case gracefully! */
|
2004-07-03 13:55:37 +00:00
|
|
|
ASSERT ( BitmapObj );
|
2003-08-17 17:32:58 +00:00
|
|
|
|
|
|
|
if ( PATH_IsPathOpen(dc->w.path) )
|
2003-08-15 18:51:32 +00:00
|
|
|
{
|
2003-08-17 17:32:58 +00:00
|
|
|
ret = PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
|
2003-08-15 18:51:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-08-17 17:32:58 +00:00
|
|
|
LeftRect += dc->w.DCOrgX;
|
|
|
|
RightRect += dc->w.DCOrgX - 1;
|
|
|
|
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-10-04 20:04:10 +00:00
|
|
|
DestRect.left = LeftRect;
|
|
|
|
DestRect.right = RightRect;
|
|
|
|
DestRect.top = TopRect;
|
|
|
|
DestRect.bottom = BottomRect;
|
|
|
|
|
2003-08-20 07:45:02 +00:00
|
|
|
FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
|
2003-08-17 17:32:58 +00:00
|
|
|
|
|
|
|
if ( FillBrushObj )
|
2002-09-21 10:39:54 +00:00
|
|
|
{
|
2004-04-05 21:26:25 +00:00
|
|
|
if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
|
2003-08-17 17:32:58 +00:00
|
|
|
{
|
2005-02-20 18:01:03 +00:00
|
|
|
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
|
2005-06-20 08:31:48 +00:00
|
|
|
ret = IntEngBitBlt(&BitmapObj->SurfObj,
|
2003-10-04 20:04:10 +00:00
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
dc->CombinedClip,
|
|
|
|
NULL,
|
|
|
|
&DestRect,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
2004-07-14 20:48:58 +00:00
|
|
|
&FillBrushInst.BrushObject,
|
2003-10-04 20:04:10 +00:00
|
|
|
NULL,
|
2005-02-06 18:27:06 +00:00
|
|
|
ROP3_TO_ROP4(PATCOPY));
|
2003-08-17 17:32:58 +00:00
|
|
|
}
|
2002-09-21 10:39:54 +00:00
|
|
|
}
|
2003-08-17 17:32:58 +00:00
|
|
|
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
2003-08-17 17:32:58 +00:00
|
|
|
|
2004-04-05 21:26:25 +00:00
|
|
|
/* get BRUSHOBJ from current pen. */
|
|
|
|
PenBrushObj = PENOBJ_LockPen(dc->w.hPen);
|
|
|
|
if (PenBrushObj == NULL)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
2004-04-05 21:26:25 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
2003-08-17 17:32:58 +00:00
|
|
|
|
2004-07-14 20:48:58 +00:00
|
|
|
IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
|
|
|
|
|
2003-08-17 17:32:58 +00:00
|
|
|
// Draw the rectangle with the current pen
|
|
|
|
|
|
|
|
ret = TRUE; // change default to success
|
|
|
|
|
2004-04-05 21:26:25 +00:00
|
|
|
if (!(PenBrushObj->flAttrs & GDIBRUSH_IS_NULL))
|
2003-08-17 17:32:58 +00:00
|
|
|
{
|
2005-02-05 10:19:49 +00:00
|
|
|
Mix = ROP2_TO_MIX(dc->w.ROPmode);
|
2005-06-20 08:31:48 +00:00
|
|
|
ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
|
2003-08-17 17:32:58 +00:00
|
|
|
dc->CombinedClip,
|
2004-07-14 20:48:58 +00:00
|
|
|
&PenBrushInst.BrushObject,
|
2003-08-17 17:32:58 +00:00
|
|
|
LeftRect, TopRect, RightRect, TopRect,
|
2003-10-04 20:04:10 +00:00
|
|
|
&DestRect, // Bounding rectangle
|
2005-02-05 10:19:49 +00:00
|
|
|
Mix);
|
2003-08-17 17:32:58 +00:00
|
|
|
|
2005-06-20 08:31:48 +00:00
|
|
|
ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
|
2003-08-17 17:32:58 +00:00
|
|
|
dc->CombinedClip,
|
2004-07-14 20:48:58 +00:00
|
|
|
&PenBrushInst.BrushObject,
|
2003-08-17 17:32:58 +00:00
|
|
|
RightRect, TopRect, RightRect, BottomRect,
|
2003-10-04 20:04:10 +00:00
|
|
|
&DestRect, // Bounding rectangle
|
2005-02-05 10:19:49 +00:00
|
|
|
Mix);
|
2003-08-17 17:32:58 +00:00
|
|
|
|
2005-06-20 08:31:48 +00:00
|
|
|
ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
|
2003-08-17 17:32:58 +00:00
|
|
|
dc->CombinedClip,
|
2004-07-14 20:48:58 +00:00
|
|
|
&PenBrushInst.BrushObject,
|
2003-08-17 17:32:58 +00:00
|
|
|
RightRect, BottomRect, LeftRect, BottomRect,
|
2003-10-04 20:04:10 +00:00
|
|
|
&DestRect, // Bounding rectangle
|
2005-02-05 10:19:49 +00:00
|
|
|
Mix);
|
2003-08-17 17:32:58 +00:00
|
|
|
|
2005-06-20 08:31:48 +00:00
|
|
|
ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
|
2003-08-17 17:32:58 +00:00
|
|
|
dc->CombinedClip,
|
2004-07-14 20:48:58 +00:00
|
|
|
&PenBrushInst.BrushObject,
|
2003-08-17 17:32:58 +00:00
|
|
|
LeftRect, BottomRect, LeftRect, TopRect,
|
2003-10-04 20:04:10 +00:00
|
|
|
&DestRect, // Bounding rectangle
|
2005-02-05 10:19:49 +00:00
|
|
|
Mix);
|
2003-08-17 17:32:58 +00:00
|
|
|
}
|
2004-04-05 21:26:25 +00:00
|
|
|
|
2005-06-07 16:34:07 +00:00
|
|
|
PENOBJ_UnlockPen(PenBrushObj);
|
2001-03-31 15:35:08 +00:00
|
|
|
}
|
2000-06-16 07:25:41 +00:00
|
|
|
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
2004-07-03 13:55:37 +00:00
|
|
|
|
2003-10-04 20:04:10 +00:00
|
|
|
/* Move current position in DC?
|
|
|
|
MSDN: The current position is neither used nor updated by Rectangle. */
|
|
|
|
|
2000-06-16 07:25:41 +00:00
|
|
|
return TRUE;
|
1999-07-22 16:21:53 +00:00
|
|
|
}
|
|
|
|
|
2003-08-17 17:32:58 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
2003-08-19 11:48:50 +00:00
|
|
|
NtGdiRectangle(HDC hDC,
|
2003-08-17 17:32:58 +00:00
|
|
|
int LeftRect,
|
|
|
|
int TopRect,
|
|
|
|
int RightRect,
|
|
|
|
int BottomRect)
|
|
|
|
{
|
2003-12-13 13:05:30 +00:00
|
|
|
DC *dc;
|
|
|
|
BOOL ret; // default to failure
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 13:05:30 +00:00
|
|
|
dc = DC_LockDc(hDC);
|
|
|
|
if(!dc)
|
2003-08-17 17:32:58 +00:00
|
|
|
{
|
2003-12-13 13:05:30 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
2003-08-17 17:32:58 +00:00
|
|
|
}
|
2005-03-07 22:24:33 +00:00
|
|
|
if (dc->IsIC)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-03-07 22:24:33 +00:00
|
|
|
/* Yes, Windows really returns TRUE in this case */
|
|
|
|
return TRUE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-12-13 13:05:30 +00:00
|
|
|
ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc ( dc );
|
2003-08-17 17:32:58 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2003-09-09 15:49:59 +00:00
|
|
|
|
|
|
|
BOOL
|
|
|
|
FASTCALL
|
|
|
|
IntRoundRect(
|
|
|
|
PDC dc,
|
|
|
|
int left,
|
|
|
|
int top,
|
|
|
|
int right,
|
|
|
|
int bottom,
|
2004-03-03 06:33:58 +00:00
|
|
|
int xCurveDiameter,
|
|
|
|
int yCurveDiameter)
|
2003-09-09 15:49:59 +00:00
|
|
|
{
|
2004-07-03 13:55:37 +00:00
|
|
|
BITMAPOBJ *BitmapObj;
|
2004-04-05 21:26:25 +00:00
|
|
|
PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
|
2004-07-14 20:48:58 +00:00
|
|
|
GDIBRUSHINST FillBrushInst, PenBrushInst;
|
2003-09-12 22:17:06 +00:00
|
|
|
RECTL RectBounds;
|
2003-09-09 15:49:59 +00:00
|
|
|
int i, col, row, width, height, x1, x1start, x2, x2start, y1, y2;
|
2004-03-03 06:33:58 +00:00
|
|
|
int xradius, yradius;
|
2003-09-09 15:49:59 +00:00
|
|
|
//float aspect_square;
|
|
|
|
long a_square, b_square,
|
|
|
|
two_a_square, two_b_square,
|
|
|
|
four_a_square, four_b_square,
|
|
|
|
d, dinc, ddec;
|
|
|
|
BOOL first,
|
|
|
|
ret = TRUE; // default to success
|
|
|
|
|
|
|
|
ASSERT ( dc ); // caller's responsibility to set this up
|
|
|
|
|
|
|
|
if ( PATH_IsPathOpen(dc->w.path) )
|
2004-03-03 06:33:58 +00:00
|
|
|
return PATH_RoundRect ( dc, left, top, right, bottom,
|
|
|
|
xCurveDiameter, yCurveDiameter );
|
2003-09-09 15:49:59 +00:00
|
|
|
|
2004-03-03 06:33:58 +00:00
|
|
|
xradius = xCurveDiameter >> 1;
|
|
|
|
yradius = yCurveDiameter >> 1;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-09-09 15:49:59 +00:00
|
|
|
left += dc->w.DCOrgX;
|
|
|
|
right += dc->w.DCOrgX;
|
|
|
|
top += dc->w.DCOrgY;
|
|
|
|
bottom += dc->w.DCOrgY;
|
|
|
|
|
2003-09-12 22:17:06 +00:00
|
|
|
RectBounds.left = left;
|
|
|
|
RectBounds.right = right;
|
|
|
|
RectBounds.top = top;
|
|
|
|
RectBounds.bottom = bottom;
|
2003-09-09 15:49:59 +00:00
|
|
|
|
2004-07-03 13:55:37 +00:00
|
|
|
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
|
2005-02-20 17:35:50 +00:00
|
|
|
if (!BitmapObj)
|
|
|
|
{
|
|
|
|
/* Nothing to do, as we don't have a bitmap */
|
|
|
|
SetLastWin32Error(ERROR_INTERNAL_ERROR);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2003-09-09 15:49:59 +00:00
|
|
|
|
|
|
|
FillBrushObj = BRUSHOBJ_LockBrush(dc->w.hBrush);
|
2005-02-20 17:35:50 +00:00
|
|
|
if (FillBrushObj)
|
2004-04-05 21:26:25 +00:00
|
|
|
{
|
2005-02-20 17:35:50 +00:00
|
|
|
if (FillBrushObj->flAttrs & GDIBRUSH_IS_NULL)
|
|
|
|
{
|
|
|
|
/* make null brush check simpler... */
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
2005-02-20 17:35:50 +00:00
|
|
|
FillBrushObj = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
|
|
|
|
}
|
2004-04-05 21:26:25 +00:00
|
|
|
}
|
2003-09-09 15:49:59 +00:00
|
|
|
|
2004-04-05 21:26:25 +00:00
|
|
|
PenBrushObj = PENOBJ_LockPen(dc->w.hPen);
|
2005-02-20 17:35:50 +00:00
|
|
|
if (PenBrushObj)
|
2004-04-05 21:26:25 +00:00
|
|
|
{
|
2005-02-20 17:35:50 +00:00
|
|
|
if (PenBrushObj->flAttrs & GDIBRUSH_IS_NULL)
|
|
|
|
{
|
|
|
|
/* make null pen check simpler... */
|
2005-06-07 16:34:07 +00:00
|
|
|
PENOBJ_UnlockPen(PenBrushObj);
|
2005-02-20 17:35:50 +00:00
|
|
|
PenBrushObj = NULL;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
|
|
|
|
}
|
2004-04-05 21:26:25 +00:00
|
|
|
}
|
2003-09-09 15:49:59 +00:00
|
|
|
|
|
|
|
right--;
|
|
|
|
bottom--;
|
|
|
|
|
|
|
|
width = right - left;
|
|
|
|
height = bottom - top;
|
|
|
|
|
|
|
|
if ( (xradius<<1) > width )
|
|
|
|
xradius = width >> 1;
|
|
|
|
if ( (yradius<<1) > height )
|
|
|
|
yradius = height >> 1;
|
|
|
|
|
|
|
|
b_square = yradius * yradius;
|
|
|
|
a_square = xradius * xradius;
|
|
|
|
row = yradius;
|
|
|
|
col = 0;
|
|
|
|
two_a_square = a_square << 1;
|
|
|
|
four_a_square = a_square << 2;
|
|
|
|
four_b_square = b_square << 2;
|
|
|
|
two_b_square = b_square << 1;
|
|
|
|
d = two_a_square * ((row - 1) * (row))
|
|
|
|
+ a_square
|
|
|
|
+ two_b_square * (1 - a_square);
|
|
|
|
|
|
|
|
x1 = left+xradius;
|
|
|
|
x2 = right-xradius;
|
|
|
|
y1 = top;
|
|
|
|
y2 = bottom;
|
|
|
|
|
|
|
|
x1start = x1;
|
|
|
|
x2start = x2;
|
|
|
|
|
|
|
|
dinc = two_b_square*3; /* two_b_square * (3 + (col << 1)); */
|
|
|
|
ddec = four_a_square * row;
|
|
|
|
|
|
|
|
first = TRUE;
|
|
|
|
for ( ;; )
|
|
|
|
{
|
|
|
|
if ( d >= 0 )
|
|
|
|
{
|
|
|
|
if ( FillBrushObj )
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( x1, y1, x2, y1, FillBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
if ( first )
|
|
|
|
{
|
|
|
|
if ( PenBrushObj )
|
|
|
|
{
|
|
|
|
if ( x1start > x1 )
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( x1, y1, x1start, y1, PenBrushInst );
|
|
|
|
PUTLINE ( x2start+1, y2, x2+1, y2, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL ( x1, y1, PenBrushInst );
|
|
|
|
PUTPIXEL ( x2, y2, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
first = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( FillBrushObj )
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( x1, y2, x2, y2, FillBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
if ( PenBrushObj )
|
|
|
|
{
|
|
|
|
if ( x1start >= x1 )
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( x1, y1, x1start+1, y1, PenBrushInst );
|
|
|
|
PUTLINE ( x2start, y2, x2+1, y2, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL ( x1, y1, PenBrushInst );
|
|
|
|
PUTPIXEL ( x2, y2, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ( PenBrushObj )
|
|
|
|
{
|
|
|
|
if ( x1start > x1 )
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( x1, y2, x1start+1, y2, PenBrushInst );
|
|
|
|
PUTLINE ( x2start, y1, x2+1, y1, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL ( x1, y2, PenBrushInst );
|
|
|
|
PUTPIXEL ( x2, y1, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
x1start = x1-1;
|
|
|
|
x2start = x2+1;
|
|
|
|
row--, y1++, y2--, ddec -= four_a_square;
|
|
|
|
d -= ddec;
|
|
|
|
}
|
|
|
|
|
|
|
|
int potential_steps = ( a_square * row ) / b_square - col + 1;
|
|
|
|
while ( d < 0 && potential_steps-- )
|
|
|
|
{
|
|
|
|
d += dinc; /* two_b_square * (3 + (col << 1)); */
|
|
|
|
col++, x1--, x2++, dinc += four_b_square;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( a_square * row <= b_square * col )
|
|
|
|
break;
|
|
|
|
};
|
|
|
|
|
|
|
|
d = two_b_square * (col + 1) * col
|
|
|
|
+ two_a_square * (row * (row - 2) + 1)
|
|
|
|
+ (1 - two_a_square) * b_square;
|
|
|
|
dinc = ddec; /* four_b_square * col; */
|
|
|
|
ddec = two_a_square * ((row << 1) - 3);
|
|
|
|
|
|
|
|
while ( row )
|
|
|
|
{
|
|
|
|
if ( FillBrushObj )
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( x1, y1, x2, y1, FillBrushInst );
|
|
|
|
PUTLINE ( x1, y2, x2, y2, FillBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
if ( PenBrushObj )
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL ( x2, y1, PenBrushInst );
|
|
|
|
PUTPIXEL ( x1, y2, PenBrushInst );
|
|
|
|
PUTPIXEL ( x2, y2, PenBrushInst );
|
|
|
|
PUTPIXEL ( x1, y1, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( d <= 0 )
|
|
|
|
{
|
|
|
|
col++, x1--, x2++, dinc += four_b_square;
|
|
|
|
d += dinc; //four_b_square * col;
|
|
|
|
}
|
|
|
|
|
|
|
|
row--, y1++, y2--, ddec -= four_a_square;
|
|
|
|
d -= ddec; //two_a_square * ((row << 1) - 3);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( FillBrushObj )
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( left, y1, right, y1, FillBrushInst );
|
|
|
|
PUTLINE ( left, y2, right, y2, FillBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
if ( PenBrushObj )
|
|
|
|
{
|
|
|
|
if ( x1 > (left+1) )
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( left, y1, x1, y1, PenBrushInst );
|
|
|
|
PUTLINE ( x2+1, y1, right, y1, PenBrushInst );
|
|
|
|
PUTLINE ( left+1, y2, x1, y2, PenBrushInst );
|
|
|
|
PUTLINE ( x2+1, y2, right+1, y2, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTPIXEL ( left, y1, PenBrushInst );
|
|
|
|
PUTPIXEL ( right, y2, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
x1 = left+xradius;
|
|
|
|
x2 = right-xradius;
|
|
|
|
y1 = top+yradius;
|
|
|
|
y2 = bottom-yradius;
|
|
|
|
|
|
|
|
if ( FillBrushObj )
|
|
|
|
{
|
|
|
|
for ( i = y1+1; i < y2; i++ )
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( left, i, right, i, FillBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if ( PenBrushObj )
|
|
|
|
{
|
2004-07-14 20:48:58 +00:00
|
|
|
PUTLINE ( x1, top, x2, top, PenBrushInst );
|
|
|
|
PUTLINE ( right, y1, right, y2, PenBrushInst );
|
|
|
|
PUTLINE ( x2, bottom, x1, bottom, PenBrushInst );
|
|
|
|
PUTLINE ( left, y2, left, y1, PenBrushInst );
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
|
|
|
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
2004-12-12 01:40:39 +00:00
|
|
|
if(PenBrushObj != NULL)
|
2005-06-07 16:34:07 +00:00
|
|
|
PENOBJ_UnlockPen(PenBrushObj);
|
2005-02-20 17:35:50 +00:00
|
|
|
if(FillBrushObj != NULL)
|
2005-06-07 16:34:07 +00:00
|
|
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
2003-09-09 15:49:59 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2000-02-20 22:52:50 +00:00
|
|
|
BOOL
|
|
|
|
STDCALL
|
2003-09-09 15:49:59 +00:00
|
|
|
NtGdiRoundRect(
|
|
|
|
HDC hDC,
|
|
|
|
int LeftRect,
|
|
|
|
int TopRect,
|
|
|
|
int RightRect,
|
|
|
|
int BottomRect,
|
|
|
|
int Width,
|
|
|
|
int Height)
|
1999-07-22 16:21:53 +00:00
|
|
|
{
|
2003-08-20 20:24:35 +00:00
|
|
|
DC *dc = DC_LockDc(hDC);
|
2003-09-09 15:49:59 +00:00
|
|
|
BOOL ret = FALSE; /* default to failure */
|
2003-08-20 20:24:35 +00:00
|
|
|
|
2003-09-09 15:49:59 +00:00
|
|
|
DPRINT("NtGdiRoundRect(0x%x,%i,%i,%i,%i,%i,%i)\n",hDC,LeftRect,TopRect,RightRect,BottomRect,Width,Height);
|
|
|
|
if ( !dc )
|
2003-08-20 20:24:35 +00:00
|
|
|
{
|
2003-09-09 15:49:59 +00:00
|
|
|
DPRINT1("NtGdiRoundRect() - hDC is invalid\n");
|
2003-12-13 13:05:30 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
2003-09-09 15:49:59 +00:00
|
|
|
}
|
2005-03-07 22:24:33 +00:00
|
|
|
else if (dc->IsIC)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-03-07 22:24:33 +00:00
|
|
|
/* Yes, Windows really returns TRUE in this case */
|
|
|
|
ret = TRUE;
|
|
|
|
}
|
2003-09-09 15:49:59 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
ret = IntRoundRect ( dc, LeftRect, TopRect, RightRect, BottomRect, Width, Height );
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc ( dc );
|
2003-08-20 20:24:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ret;
|
1999-07-22 16:21:53 +00:00
|
|
|
}
|
2004-02-08 21:37:53 +00:00
|
|
|
|
|
|
|
BOOL FASTCALL
|
|
|
|
IntGdiGradientFill(
|
|
|
|
DC *dc,
|
|
|
|
PTRIVERTEX pVertex,
|
|
|
|
ULONG uVertex,
|
|
|
|
PVOID pMesh,
|
|
|
|
ULONG uMesh,
|
|
|
|
ULONG ulMode)
|
|
|
|
{
|
2004-07-03 13:55:37 +00:00
|
|
|
BITMAPOBJ *BitmapObj;
|
2004-02-08 21:37:53 +00:00
|
|
|
PPALGDI PalDestGDI;
|
|
|
|
XLATEOBJ *XlateObj;
|
|
|
|
RECTL Extent;
|
|
|
|
POINTL DitherOrg;
|
|
|
|
ULONG Mode, i;
|
|
|
|
BOOL Ret;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
ASSERT(dc);
|
|
|
|
ASSERT(pVertex);
|
|
|
|
ASSERT(uVertex);
|
|
|
|
ASSERT(pMesh);
|
|
|
|
ASSERT(uMesh);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
/* check parameters */
|
|
|
|
if(ulMode & GRADIENT_FILL_TRIANGLE)
|
|
|
|
{
|
|
|
|
PGRADIENT_TRIANGLE tr = (PGRADIENT_TRIANGLE)pMesh;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
for(i = 0; i < uMesh; i++, tr++)
|
|
|
|
{
|
|
|
|
if(tr->Vertex1 >= uVertex ||
|
|
|
|
tr->Vertex2 >= uVertex ||
|
|
|
|
tr->Vertex3 >= uVertex)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
PGRADIENT_RECT rc = (PGRADIENT_RECT)pMesh;
|
|
|
|
for(i = 0; i < uMesh; i++, rc++)
|
|
|
|
{
|
|
|
|
if(rc->UpperLeft >= uVertex || rc->LowerRight >= uVertex)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
/* calculate extent */
|
|
|
|
Extent.left = Extent.right = pVertex->x;
|
|
|
|
Extent.top = Extent.bottom = pVertex->y;
|
|
|
|
for(i = 0; i < uVertex; i++)
|
|
|
|
{
|
|
|
|
Extent.left = min(Extent.left, (pVertex + i)->x);
|
|
|
|
Extent.right = max(Extent.right, (pVertex + i)->x);
|
|
|
|
Extent.top = min(Extent.top, (pVertex + i)->y);
|
|
|
|
Extent.bottom = max(Extent.bottom, (pVertex + i)->y);
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
DitherOrg.x = dc->w.DCOrgX;
|
|
|
|
DitherOrg.y = dc->w.DCOrgY;
|
|
|
|
Extent.left += DitherOrg.x;
|
|
|
|
Extent.right += DitherOrg.x;
|
|
|
|
Extent.top += DitherOrg.y;
|
|
|
|
Extent.bottom += DitherOrg.y;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-07-03 13:55:37 +00:00
|
|
|
BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
|
2004-12-12 01:40:39 +00:00
|
|
|
/* FIXME - BitmapObj can be NULL!!! Don't assert but handle this case gracefully! */
|
2004-07-03 13:55:37 +00:00
|
|
|
ASSERT(BitmapObj);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
PalDestGDI = PALETTE_LockPalette(dc->w.hPalette);
|
2004-12-12 01:40:39 +00:00
|
|
|
/* FIXME - PalDestGDI can be NULL!!! Don't assert but handle this case gracefully! */
|
2004-02-08 21:37:53 +00:00
|
|
|
ASSERT(PalDestGDI);
|
|
|
|
Mode = PalDestGDI->Mode;
|
2005-06-07 16:34:07 +00:00
|
|
|
PALETTE_UnlockPalette(PalDestGDI);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-04-09 20:03:21 +00:00
|
|
|
XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
|
2004-02-08 21:37:53 +00:00
|
|
|
ASSERT(XlateObj);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-06-20 08:31:48 +00:00
|
|
|
Ret = IntEngGradientFill(&BitmapObj->SurfObj,
|
2004-02-08 21:37:53 +00:00
|
|
|
dc->CombinedClip,
|
|
|
|
XlateObj,
|
|
|
|
pVertex,
|
|
|
|
uVertex,
|
|
|
|
pMesh,
|
|
|
|
uMesh,
|
|
|
|
&Extent,
|
|
|
|
&DitherOrg,
|
|
|
|
ulMode);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-06-07 16:34:07 +00:00
|
|
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
2004-02-08 21:37:53 +00:00
|
|
|
EngDeleteXlate(XlateObj);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
STDCALL
|
|
|
|
NtGdiGradientFill(
|
|
|
|
HDC hdc,
|
|
|
|
PTRIVERTEX pVertex,
|
|
|
|
ULONG uVertex,
|
|
|
|
PVOID pMesh,
|
|
|
|
ULONG uMesh,
|
|
|
|
ULONG ulMode)
|
|
|
|
{
|
|
|
|
DC *dc;
|
|
|
|
BOOL Ret;
|
|
|
|
PTRIVERTEX SafeVertex;
|
|
|
|
PVOID SafeMesh;
|
|
|
|
ULONG SizeMesh;
|
|
|
|
NTSTATUS Status;
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
dc = DC_LockDc(hdc);
|
|
|
|
if(!dc)
|
|
|
|
{
|
|
|
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-03-07 22:24:33 +00:00
|
|
|
if (dc->IsIC)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2005-03-07 22:24:33 +00:00
|
|
|
/* Yes, Windows really returns TRUE in this case */
|
|
|
|
return TRUE;
|
|
|
|
}
|
2004-02-08 21:37:53 +00:00
|
|
|
if(!pVertex || !uVertex || !pMesh || !uMesh)
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2004-02-08 21:37:53 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
switch(ulMode)
|
|
|
|
{
|
|
|
|
case GRADIENT_FILL_RECT_H:
|
|
|
|
case GRADIENT_FILL_RECT_V:
|
|
|
|
SizeMesh = uMesh * sizeof(GRADIENT_RECT);
|
|
|
|
break;
|
|
|
|
case GRADIENT_FILL_TRIANGLE:
|
|
|
|
SizeMesh = uMesh * sizeof(TRIVERTEX);
|
|
|
|
break;
|
|
|
|
default:
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2004-02-08 21:37:53 +00:00
|
|
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2004-02-19 21:12:11 +00:00
|
|
|
if(!(SafeVertex = ExAllocatePoolWithTag(PagedPool, (uVertex * sizeof(TRIVERTEX)) + SizeMesh, TAG_SHAPE)))
|
2004-02-08 21:37:53 +00:00
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2004-02-08 21:37:53 +00:00
|
|
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
Status = MmCopyFromCaller(SafeVertex, pVertex, uVertex * sizeof(TRIVERTEX));
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2004-02-08 21:37:53 +00:00
|
|
|
ExFreePool(SafeVertex);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
SafeMesh = (PTRIVERTEX)(SafeVertex + uVertex);
|
|
|
|
Status = MmCopyFromCaller(SafeMesh, pMesh, SizeMesh);
|
|
|
|
if(!NT_SUCCESS(Status))
|
|
|
|
{
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2004-02-08 21:37:53 +00:00
|
|
|
ExFreePool(SafeVertex);
|
|
|
|
SetLastNtError(Status);
|
|
|
|
return FALSE;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-02-08 21:37:53 +00:00
|
|
|
Ret = IntGdiGradientFill(dc, SafeVertex, uVertex, SafeMesh, uMesh, ulMode);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-06-07 16:34:07 +00:00
|
|
|
DC_UnlockDc(dc);
|
2004-02-08 21:37:53 +00:00
|
|
|
ExFreePool(SafeVertex);
|
|
|
|
return Ret;
|
|
|
|
}
|
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
/* EOF */
|