mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 18:35:41 +00:00
- rewrite NtGdiPolyPolyDraw, optimizing it and making it more windows compatible
- Make PolyCounts ULONGs, not DWORDS or INTs. - Remove GdiCreatePolyPolygonRgn and use IntCreatePolyPolygonRgn instead to get rid of code-duplication. - IntGdiPolygon: rename UnsafePoints to Points svn path=/trunk/; revision=36686
This commit is contained in:
parent
8a8e0aaae0
commit
419b09b96a
6 changed files with 142 additions and 309 deletions
|
@ -93,7 +93,7 @@ IntGdiPolyBezierTo(DC *dc,
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntGdiPolyPolyline(DC *dc,
|
IntGdiPolyPolyline(DC *dc,
|
||||||
LPPOINT pt,
|
LPPOINT pt,
|
||||||
LPDWORD PolyPoints,
|
PULONG PolyPoints,
|
||||||
DWORD Count);
|
DWORD Count);
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
|
@ -125,7 +125,7 @@ IntGdiPolygon(PDC dc,
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntGdiPolyPolygon(DC *dc,
|
IntGdiPolyPolygon(DC *dc,
|
||||||
LPPOINT Points,
|
LPPOINT Points,
|
||||||
LPINT PolyCounts,
|
PULONG PolyCounts,
|
||||||
int Count);
|
int Count);
|
||||||
|
|
||||||
BOOL FASTCALL IntGdiGradientFill(DC *dc,
|
BOOL FASTCALL IntGdiGradientFill(DC *dc,
|
||||||
|
|
|
@ -43,7 +43,7 @@ VOID FASTCALL IntGdiReleaseVisRgn(PDC);
|
||||||
|
|
||||||
INT STDCALL IntGdiGetRgnBox(HRGN, LPRECT);
|
INT STDCALL IntGdiGetRgnBox(HRGN, LPRECT);
|
||||||
BOOL FASTCALL IntGdiPaintRgn(PDC, HRGN );
|
BOOL FASTCALL IntGdiPaintRgn(PDC, HRGN );
|
||||||
HRGN FASTCALL GdiCreatePolyPolygonRgn(CONST PPOINT, CONST PINT, INT, INT );
|
HRGN FASTCALL IntCreatePolyPolygonRgn(PPOINT, PULONG, INT, INT);
|
||||||
|
|
||||||
INT FASTCALL IntGdiCombineRgn(PROSRGNDATA, PROSRGNDATA, PROSRGNDATA, INT);
|
INT FASTCALL IntGdiCombineRgn(PROSRGNDATA, PROSRGNDATA, PROSRGNDATA, INT);
|
||||||
INT FASTCALL REGION_Complexity(PROSRGNDATA);
|
INT FASTCALL REGION_Complexity(PROSRGNDATA);
|
||||||
|
|
|
@ -51,7 +51,7 @@ BOOL FASTCALL IntDrawRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntGdiPolygon(PDC dc,
|
IntGdiPolygon(PDC dc,
|
||||||
PPOINT UnsafePoints,
|
PPOINT Points,
|
||||||
int Count)
|
int Count)
|
||||||
{
|
{
|
||||||
BITMAPOBJ *BitmapObj;
|
BITMAPOBJ *BitmapObj;
|
||||||
|
@ -64,7 +64,7 @@ IntGdiPolygon(PDC dc,
|
||||||
|
|
||||||
ASSERT(dc); // caller's responsibility to pass a valid dc
|
ASSERT(dc); // caller's responsibility to pass a valid dc
|
||||||
|
|
||||||
if ( NULL == UnsafePoints || Count < 2 )
|
if (!Points || Count < 2 )
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -74,25 +74,25 @@ IntGdiPolygon(PDC dc,
|
||||||
if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
|
if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
|
||||||
|
|
||||||
/* Convert to screen coordinates */
|
/* Convert to screen coordinates */
|
||||||
IntLPtoDP(dc, UnsafePoints, Count);
|
IntLPtoDP(dc, Points, Count);
|
||||||
for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++)
|
for (CurrentPoint = 0; CurrentPoint < Count; CurrentPoint++)
|
||||||
{
|
{
|
||||||
UnsafePoints[CurrentPoint].x += dc->ptlDCOrig.x;
|
Points[CurrentPoint].x += dc->ptlDCOrig.x;
|
||||||
UnsafePoints[CurrentPoint].y += dc->ptlDCOrig.y;
|
Points[CurrentPoint].y += dc->ptlDCOrig.y;
|
||||||
}
|
}
|
||||||
// No need to have path here.
|
// No need to have path here.
|
||||||
{
|
{
|
||||||
DestRect.left = UnsafePoints[0].x;
|
DestRect.left = Points[0].x;
|
||||||
DestRect.right = UnsafePoints[0].x;
|
DestRect.right = Points[0].x;
|
||||||
DestRect.top = UnsafePoints[0].y;
|
DestRect.top = Points[0].y;
|
||||||
DestRect.bottom = UnsafePoints[0].y;
|
DestRect.bottom = Points[0].y;
|
||||||
|
|
||||||
for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint)
|
for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint)
|
||||||
{
|
{
|
||||||
DestRect.left = min(DestRect.left, UnsafePoints[CurrentPoint].x);
|
DestRect.left = min(DestRect.left, Points[CurrentPoint].x);
|
||||||
DestRect.right = max(DestRect.right, UnsafePoints[CurrentPoint].x);
|
DestRect.right = max(DestRect.right, Points[CurrentPoint].x);
|
||||||
DestRect.top = min(DestRect.top, UnsafePoints[CurrentPoint].y);
|
DestRect.top = min(DestRect.top, Points[CurrentPoint].y);
|
||||||
DestRect.bottom = max(DestRect.bottom, UnsafePoints[CurrentPoint].y);
|
DestRect.bottom = max(DestRect.bottom, Points[CurrentPoint].y);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Special locking order to avoid lock-ups */
|
/* Special locking order to avoid lock-ups */
|
||||||
|
@ -106,7 +106,7 @@ IntGdiPolygon(PDC dc,
|
||||||
if (FillBrushObj && !(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
|
if (FillBrushObj && !(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
|
||||||
{
|
{
|
||||||
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
|
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
|
||||||
ret = FillPolygon ( dc, BitmapObj, &FillBrushInst.BrushObject, ROP2_TO_MIX(Dc_Attr->jROP2), UnsafePoints, Count, DestRect );
|
ret = FillPolygon ( dc, BitmapObj, &FillBrushInst.BrushObject, ROP2_TO_MIX(Dc_Attr->jROP2), Points, Count, DestRect );
|
||||||
}
|
}
|
||||||
if (FillBrushObj)
|
if (FillBrushObj)
|
||||||
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
BRUSHOBJ_UnlockBrush(FillBrushObj);
|
||||||
|
@ -122,16 +122,16 @@ IntGdiPolygon(PDC dc,
|
||||||
{
|
{
|
||||||
|
|
||||||
// DPRINT1("Polygon Making line from (%d,%d) to (%d,%d)\n",
|
// DPRINT1("Polygon Making line from (%d,%d) to (%d,%d)\n",
|
||||||
// UnsafePoints[0].x, UnsafePoints[0].y,
|
// Points[0].x, Points[0].y,
|
||||||
// UnsafePoints[1].x, UnsafePoints[1].y );
|
// Points[1].x, Points[1].y );
|
||||||
|
|
||||||
ret = IntEngLineTo(&BitmapObj->SurfObj,
|
ret = IntEngLineTo(&BitmapObj->SurfObj,
|
||||||
dc->CombinedClip,
|
dc->CombinedClip,
|
||||||
&PenBrushInst.BrushObject,
|
&PenBrushInst.BrushObject,
|
||||||
UnsafePoints[i].x, /* From */
|
Points[i].x, /* From */
|
||||||
UnsafePoints[i].y,
|
Points[i].y,
|
||||||
UnsafePoints[i+1].x, /* To */
|
Points[i+1].x, /* To */
|
||||||
UnsafePoints[i+1].y,
|
Points[i+1].y,
|
||||||
&DestRect,
|
&DestRect,
|
||||||
ROP2_TO_MIX(Dc_Attr->jROP2)); /* MIX */
|
ROP2_TO_MIX(Dc_Attr->jROP2)); /* MIX */
|
||||||
if (!ret) break;
|
if (!ret) break;
|
||||||
|
@ -142,10 +142,10 @@ IntGdiPolygon(PDC dc,
|
||||||
ret = IntEngLineTo(&BitmapObj->SurfObj,
|
ret = IntEngLineTo(&BitmapObj->SurfObj,
|
||||||
dc->CombinedClip,
|
dc->CombinedClip,
|
||||||
&PenBrushInst.BrushObject,
|
&PenBrushInst.BrushObject,
|
||||||
UnsafePoints[Count-1].x, /* From */
|
Points[Count-1].x, /* From */
|
||||||
UnsafePoints[Count-1].y,
|
Points[Count-1].y,
|
||||||
UnsafePoints[0].x, /* To */
|
Points[0].x, /* To */
|
||||||
UnsafePoints[0].y,
|
Points[0].y,
|
||||||
&DestRect,
|
&DestRect,
|
||||||
ROP2_TO_MIX(Dc_Attr->jROP2)); /* MIX */
|
ROP2_TO_MIX(Dc_Attr->jROP2)); /* MIX */
|
||||||
}
|
}
|
||||||
|
@ -161,11 +161,11 @@ IntGdiPolygon(PDC dc,
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntGdiPolyPolygon(DC *dc,
|
IntGdiPolyPolygon(DC *dc,
|
||||||
LPPOINT Points,
|
LPPOINT Points,
|
||||||
LPINT PolyCounts,
|
PULONG PolyCounts,
|
||||||
int Count)
|
int Count)
|
||||||
{
|
{
|
||||||
if (PATH_IsPathOpen(dc->DcLevel))
|
if (PATH_IsPathOpen(dc->DcLevel))
|
||||||
return PATH_PolyPolygon ( dc, Points, PolyCounts, Count);
|
return PATH_PolyPolygon ( dc, Points, (PINT)PolyCounts, Count);
|
||||||
|
|
||||||
while (--Count >=0)
|
while (--Count >=0)
|
||||||
{
|
{
|
||||||
|
@ -336,185 +336,152 @@ extern BOOL FillPolygon(PDC dc,
|
||||||
ULONG_PTR
|
ULONG_PTR
|
||||||
STDCALL
|
STDCALL
|
||||||
NtGdiPolyPolyDraw( IN HDC hDC,
|
NtGdiPolyPolyDraw( IN HDC hDC,
|
||||||
IN PPOINT Points,
|
IN PPOINT UnsafePoints,
|
||||||
IN PULONG PolyCounts,
|
IN PULONG UnsafeCounts,
|
||||||
IN ULONG Count,
|
IN ULONG Count,
|
||||||
IN INT iFunc )
|
IN INT iFunc )
|
||||||
{
|
{
|
||||||
DC *dc;
|
DC *dc;
|
||||||
LPPOINT Safept;
|
PVOID pTemp;
|
||||||
LPINT SafePolyPoints;
|
LPPOINT SafePoints;
|
||||||
|
PULONG SafeCounts;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
BOOL Ret = TRUE;
|
BOOL Ret = TRUE;
|
||||||
INT nPoints, nEmpty, nInvalid, i;
|
INT nPoints = 0, nMaxPoints = 0, nInvalid = 0, i;
|
||||||
|
|
||||||
if (iFunc == GdiPolyPolyRgn)
|
if (!UnsafePoints || !UnsafeCounts ||
|
||||||
|
Count == 0 || iFunc == 0 || iFunc > GdiPolyPolyRgn)
|
||||||
{
|
{
|
||||||
return (ULONG_PTR) GdiCreatePolyPolygonRgn((CONST PPOINT) Points,
|
/* Windows doesn't set last error */
|
||||||
(CONST PINT) PolyCounts,
|
|
||||||
Count,
|
|
||||||
(INT) hDC);
|
|
||||||
}
|
|
||||||
dc = DC_LockDc(hDC);
|
|
||||||
if (!dc)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (dc->DC_Type == DC_TYPE_INFO)
|
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
DC_UnlockDc(dc);
|
ProbeForRead(UnsafePoints, Count * sizeof(POINT), 1);
|
||||||
/* Yes, Windows really returns TRUE in this case */
|
ProbeForRead(UnsafeCounts, Count * sizeof(ULONG), 1);
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Count > 0)
|
/* Count points and validate poligons */
|
||||||
{
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
ProbeForRead(Points,
|
|
||||||
Count * sizeof(POINT),
|
|
||||||
1);
|
|
||||||
ProbeForRead(PolyCounts,
|
|
||||||
Count * sizeof(INT),
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DC_UnlockDc(dc);
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
SafePolyPoints = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_SHAPE);
|
|
||||||
if (!SafePolyPoints)
|
|
||||||
{
|
|
||||||
DC_UnlockDc(dc);
|
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
/* pointers already probed! */
|
|
||||||
RtlCopyMemory(SafePolyPoints,
|
|
||||||
PolyCounts,
|
|
||||||
Count * sizeof(INT));
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DC_UnlockDc(dc);
|
|
||||||
ExFreePool(SafePolyPoints);
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* validate poligons */
|
|
||||||
nPoints = 0;
|
|
||||||
nEmpty = 0;
|
|
||||||
nInvalid = 0;
|
|
||||||
for (i = 0; i < Count; i++)
|
for (i = 0; i < Count; i++)
|
||||||
{
|
{
|
||||||
if (SafePolyPoints[i] == 0)
|
if (UnsafeCounts[i] < 2)
|
||||||
{
|
|
||||||
nEmpty++;
|
|
||||||
}
|
|
||||||
if (SafePolyPoints[i] == 1)
|
|
||||||
{
|
{
|
||||||
nInvalid++;
|
nInvalid++;
|
||||||
}
|
}
|
||||||
nPoints += SafePolyPoints[i];
|
nPoints += UnsafeCounts[i];
|
||||||
}
|
nMaxPoints = max(nMaxPoints, UnsafeCounts[i]);
|
||||||
|
|
||||||
if (nEmpty == Count)
|
|
||||||
{
|
|
||||||
/* if all polygon counts are zero, return without setting a last error code. */
|
|
||||||
ExFreePool(SafePolyPoints);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if (nInvalid != 0)
|
|
||||||
{
|
|
||||||
/* if at least one poly count is 1, fail */
|
|
||||||
ExFreePool(SafePolyPoints);
|
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Safept = ExAllocatePoolWithTag(PagedPool, nPoints * sizeof(POINT), TAG_SHAPE);
|
|
||||||
if (!Safept)
|
|
||||||
{
|
|
||||||
DC_UnlockDc(dc);
|
|
||||||
ExFreePool(SafePolyPoints);
|
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
/* pointers already probed! */
|
|
||||||
RtlCopyMemory(Safept,
|
|
||||||
Points,
|
|
||||||
nPoints * sizeof(POINT));
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DC_UnlockDc(dc);
|
|
||||||
ExFreePool(SafePolyPoints);
|
|
||||||
ExFreePool(Safept);
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
_SEH_HANDLE
|
||||||
{
|
{
|
||||||
DC_UnlockDc(dc);
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Windows doesn't set last error */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nPoints == 0 || nPoints < nMaxPoints)
|
||||||
|
{
|
||||||
|
/* If all polygon counts are zero, or we have overflow,
|
||||||
|
return without setting a last error code. */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nInvalid != 0)
|
||||||
|
{
|
||||||
|
/* If at least one poly count is 0 or 1, fail */
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allocate one buffer for both counts and points */
|
||||||
|
pTemp = ExAllocatePoolWithTag(PagedPool,
|
||||||
|
Count * sizeof(ULONG) + nPoints * sizeof(POINT),
|
||||||
|
TAG_SHAPE);
|
||||||
|
if (!pTemp)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
SafeCounts = pTemp;
|
||||||
|
SafePoints = (PVOID)(SafeCounts + Count);
|
||||||
|
|
||||||
|
_SEH_TRY
|
||||||
|
{
|
||||||
|
/* Pointers already probed! */
|
||||||
|
RtlCopyMemory(SafeCounts, UnsafeCounts, Count * sizeof(ULONG));
|
||||||
|
RtlCopyMemory(SafePoints, UnsafePoints, nPoints * sizeof(POINT));
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExFreePool(pTemp);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Special handling for GdiPolyPolyRgn */
|
||||||
|
if (iFunc == GdiPolyPolyRgn)
|
||||||
|
{
|
||||||
|
HRGN hRgn;
|
||||||
|
hRgn = IntCreatePolyPolygonRgn(SafePoints, SafeCounts, Count, (INT_PTR)hDC);
|
||||||
|
ExFreePool(pTemp);
|
||||||
|
return (ULONG_PTR)hRgn;
|
||||||
|
}
|
||||||
|
|
||||||
|
dc = DC_LockDc(hDC);
|
||||||
|
if (!dc)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
|
ExFreePool(pTemp);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dc->DC_Type == DC_TYPE_INFO)
|
||||||
|
{
|
||||||
|
DC_UnlockDc(dc);
|
||||||
|
ExFreePool(pTemp);
|
||||||
|
/* Yes, Windows really returns TRUE in this case */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform the actual work */
|
||||||
switch (iFunc)
|
switch (iFunc)
|
||||||
{
|
{
|
||||||
case GdiPolyPolygon:
|
case GdiPolyPolygon:
|
||||||
Ret = IntGdiPolyPolygon(dc, Safept, SafePolyPoints, Count);
|
Ret = IntGdiPolyPolygon(dc, SafePoints, SafeCounts, Count);
|
||||||
break;
|
break;
|
||||||
case GdiPolyPolyLine:
|
case GdiPolyPolyLine:
|
||||||
Ret = IntGdiPolyPolyline(dc, Safept, (LPDWORD) SafePolyPoints, Count);
|
Ret = IntGdiPolyPolyline(dc, SafePoints, SafeCounts, Count);
|
||||||
break;
|
break;
|
||||||
case GdiPolyBezier:
|
case GdiPolyBezier:
|
||||||
Ret = IntGdiPolyBezier(dc, Safept, *PolyCounts);
|
Ret = IntGdiPolyBezier(dc, SafePoints, *SafeCounts);
|
||||||
break;
|
break;
|
||||||
case GdiPolyLineTo:
|
case GdiPolyLineTo:
|
||||||
Ret = IntGdiPolylineTo(dc, Safept, *PolyCounts);
|
Ret = IntGdiPolylineTo(dc, SafePoints, *SafeCounts);
|
||||||
break;
|
break;
|
||||||
case GdiPolyBezierTo:
|
case GdiPolyBezierTo:
|
||||||
Ret = IntGdiPolyBezierTo(dc, Safept, *PolyCounts);
|
Ret = IntGdiPolyBezierTo(dc, SafePoints, *SafeCounts);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
Ret = FALSE;
|
Ret = FALSE;
|
||||||
}
|
}
|
||||||
ExFreePool(SafePolyPoints);
|
|
||||||
ExFreePool(Safept);
|
|
||||||
DC_UnlockDc(dc);
|
|
||||||
|
|
||||||
return (ULONG_PTR) Ret;
|
/* Cleanup and return */
|
||||||
|
DC_UnlockDc(dc);
|
||||||
|
ExFreePool(pTemp);
|
||||||
|
|
||||||
|
return (ULONG_PTR)Ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -350,12 +350,12 @@ IntGdiPolylineTo(DC *dc,
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntGdiPolyPolyline(DC *dc,
|
IntGdiPolyPolyline(DC *dc,
|
||||||
LPPOINT pt,
|
LPPOINT pt,
|
||||||
LPDWORD PolyPoints,
|
PULONG PolyPoints,
|
||||||
DWORD Count)
|
DWORD Count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
LPPOINT pts;
|
LPPOINT pts;
|
||||||
LPDWORD pc;
|
PULONG pc;
|
||||||
BOOL ret = FALSE; // default to failure
|
BOOL ret = FALSE; // default to failure
|
||||||
pts = pt;
|
pts = pt;
|
||||||
pc = PolyPoints;
|
pc = PolyPoints;
|
||||||
|
|
|
@ -1028,7 +1028,6 @@ PATH_FlattenPath(PPATH pPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRGN FASTCALL IntCreatePolyPolygonRgn(POINT *Pts, INT *Count, INT nbpolygons,INT mode);
|
|
||||||
/* PATH_PathToRegion
|
/* PATH_PathToRegion
|
||||||
*
|
*
|
||||||
* Creates a region from the specified path using the specified polygon
|
* Creates a region from the specified path using the specified polygon
|
||||||
|
@ -1042,7 +1041,7 @@ FASTCALL
|
||||||
PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn )
|
PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn )
|
||||||
{
|
{
|
||||||
int numStrokes, iStroke, i;
|
int numStrokes, iStroke, i;
|
||||||
INT *pNumPointsInStroke;
|
PULONG pNumPointsInStroke;
|
||||||
HRGN hrgn = 0;
|
HRGN hrgn = 0;
|
||||||
|
|
||||||
ASSERT(pPath!=NULL);
|
ASSERT(pPath!=NULL);
|
||||||
|
@ -1060,7 +1059,7 @@ PATH_PathToRegion ( PPATH pPath, INT nPolyFillMode, HRGN *pHrgn )
|
||||||
numStrokes++;
|
numStrokes++;
|
||||||
|
|
||||||
/* Allocate memory for number-of-points-in-stroke array */
|
/* Allocate memory for number-of-points-in-stroke array */
|
||||||
pNumPointsInStroke=(int *)ExAllocatePoolWithTag(PagedPool, sizeof(int) * numStrokes, TAG_PATH);
|
pNumPointsInStroke = ExAllocatePoolWithTag(PagedPool, sizeof(ULONG) * numStrokes, TAG_PATH);
|
||||||
if(!pNumPointsInStroke)
|
if(!pNumPointsInStroke)
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
|
|
@ -3560,7 +3560,7 @@ REGION_PtsToRegion(
|
||||||
*/
|
*/
|
||||||
static void FASTCALL
|
static void FASTCALL
|
||||||
REGION_CreateETandAET(
|
REGION_CreateETandAET(
|
||||||
const INT *Count,
|
const ULONG *Count,
|
||||||
INT nbpolygons,
|
INT nbpolygons,
|
||||||
const POINT *pts,
|
const POINT *pts,
|
||||||
EdgeTable *ET,
|
EdgeTable *ET,
|
||||||
|
@ -3657,7 +3657,7 @@ REGION_CreateETandAET(
|
||||||
HRGN FASTCALL
|
HRGN FASTCALL
|
||||||
IntCreatePolyPolygonRgn(
|
IntCreatePolyPolygonRgn(
|
||||||
POINT *Pts,
|
POINT *Pts,
|
||||||
INT *Count,
|
PULONG Count,
|
||||||
INT nbpolygons,
|
INT nbpolygons,
|
||||||
INT mode
|
INT mode
|
||||||
)
|
)
|
||||||
|
@ -3681,6 +3681,8 @@ IntCreatePolyPolygonRgn(
|
||||||
int numFullPtBlocks = 0;
|
int numFullPtBlocks = 0;
|
||||||
INT poly, total;
|
INT poly, total;
|
||||||
|
|
||||||
|
if (mode == 0 || mode > 2) return 0;
|
||||||
|
|
||||||
if (!(region = REGION_AllocRgnWithHandle(nbpolygons)))
|
if (!(region = REGION_AllocRgnWithHandle(nbpolygons)))
|
||||||
return 0;
|
return 0;
|
||||||
hrgn = region->BaseObject.hHmgr;
|
hrgn = region->BaseObject.hHmgr;
|
||||||
|
@ -3851,139 +3853,4 @@ IntCreatePolyPolygonRgn(
|
||||||
return hrgn;
|
return hrgn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HRGN
|
|
||||||
FASTCALL
|
|
||||||
GdiCreatePolyPolygonRgn(
|
|
||||||
CONST PPOINT pt,
|
|
||||||
CONST PINT PolyCounts,
|
|
||||||
INT Count,
|
|
||||||
INT PolyFillMode
|
|
||||||
)
|
|
||||||
{
|
|
||||||
POINT *Safept;
|
|
||||||
INT *SafePolyCounts;
|
|
||||||
INT nPoints, nEmpty, nInvalid, i;
|
|
||||||
HRGN hRgn;
|
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
|
||||||
|
|
||||||
if (pt == NULL || PolyCounts == NULL || Count == 0 ||
|
|
||||||
(PolyFillMode != WINDING && PolyFillMode != ALTERNATE))
|
|
||||||
{
|
|
||||||
/* Windows doesn't set a last error here */
|
|
||||||
return (HRGN)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
ProbeForRead(PolyCounts, Count * sizeof(INT), 1);
|
|
||||||
/* just probe one point for now, we don't know the length of the array yet */
|
|
||||||
ProbeForRead(pt, sizeof(POINT), 1);
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return (HRGN)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(SafePolyCounts = ExAllocatePoolWithTag(PagedPool, Count * sizeof(INT), TAG_REGION)))
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return (HRGN)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
/* pointers were already probed! */
|
|
||||||
RtlCopyMemory(SafePolyCounts,
|
|
||||||
PolyCounts,
|
|
||||||
Count * sizeof(INT));
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ExFreePool(SafePolyCounts);
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return (HRGN)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* validate poligons */
|
|
||||||
nPoints = 0;
|
|
||||||
nEmpty = 0;
|
|
||||||
nInvalid = 0;
|
|
||||||
for (i = 0; i < Count; i++)
|
|
||||||
{
|
|
||||||
if (SafePolyCounts[i] == 0)
|
|
||||||
{
|
|
||||||
nEmpty++;
|
|
||||||
}
|
|
||||||
if (SafePolyCounts[i] == 1)
|
|
||||||
{
|
|
||||||
nInvalid++;
|
|
||||||
}
|
|
||||||
nPoints += SafePolyCounts[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nEmpty == Count)
|
|
||||||
{
|
|
||||||
/* if all polygon counts are zero, return without setting a last error code. */
|
|
||||||
ExFreePool(SafePolyCounts);
|
|
||||||
return (HRGN)0;
|
|
||||||
}
|
|
||||||
if (nInvalid != 0)
|
|
||||||
{
|
|
||||||
/* if at least one poly count is 1, fail */
|
|
||||||
ExFreePool(SafePolyCounts);
|
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
||||||
return (HRGN)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* copy points */
|
|
||||||
if (!(Safept = ExAllocatePoolWithTag(PagedPool, nPoints * sizeof(POINT), TAG_REGION)))
|
|
||||||
{
|
|
||||||
ExFreePool(SafePolyCounts);
|
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return (HRGN)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
_SEH_TRY
|
|
||||||
{
|
|
||||||
ProbeForRead(pt, nPoints * sizeof(POINT), 1);
|
|
||||||
/* pointers were already probed! */
|
|
||||||
RtlCopyMemory(Safept,
|
|
||||||
pt,
|
|
||||||
nPoints * sizeof(POINT));
|
|
||||||
}
|
|
||||||
_SEH_HANDLE
|
|
||||||
{
|
|
||||||
Status = _SEH_GetExceptionCode();
|
|
||||||
}
|
|
||||||
_SEH_END;
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
ExFreePool(Safept);
|
|
||||||
ExFreePool(SafePolyCounts);
|
|
||||||
SetLastNtError(Status);
|
|
||||||
return (HRGN)0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now we're ready to calculate the region safely */
|
|
||||||
hRgn = IntCreatePolyPolygonRgn(Safept, SafePolyCounts, Count, PolyFillMode);
|
|
||||||
|
|
||||||
ExFreePool(Safept);
|
|
||||||
ExFreePool(SafePolyCounts);
|
|
||||||
return hRgn;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue