* 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.
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-#include <w32k.h>
+#include <win32k.h>
#define NDEBUG
#include <debug.h>
int Count)
{
SURFACE *psurf;
- PBRUSH pbrushLine, pbrushFill;
- EBRUSHOBJ eboLine, eboFill;
+ PBRUSH pbrLine, pbrFill;
BOOL ret = FALSE; // default to failure
RECTL DestRect;
int CurrentPoint;
POINTL BrushOrigin;
// int Left;
// int Top;
-
+
ASSERT(dc); // caller's responsibility to pass a valid dc
if (!Points || Count < 2 )
DestRect.bottom = max(DestRect.bottom, Points[CurrentPoint].y);
}
- if (pdcattr->ulDirty_ & DC_BRUSH_DIRTY)
- IntGdiSelectBrush(dc,pdcattr->hbrush);
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
- if (pdcattr->ulDirty_ & DC_PEN_DIRTY)
- IntGdiSelectPen(dc,pdcattr->hpen);
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
/* Special locking order to avoid lock-ups */
- pbrushFill = BRUSH_LockBrush(pdcattr->hbrush);
- pbrushLine = PEN_LockPen(pdcattr->hpen);
- psurf = SURFACE_LockSurface(dc->rosdc.hBitmap);
+ pbrFill = dc->dclevel.pbrFill;
+ pbrLine = dc->dclevel.pbrLine;
+ psurf = dc->dclevel.pSurface;
/* FIXME - psurf can be NULL!!!! don't assert but handle this case gracefully! */
ASSERT(psurf);
- /* Now fill the polygon with the current brush. */
- if (pbrushFill && !(pbrushFill->flAttrs & GDIBRUSH_IS_NULL))
+ /* Now fill the polygon with the current fill brush. */
+ if (!(pbrFill->flAttrs & GDIBRUSH_IS_NULL))
{
- BrushOrigin = *((PPOINTL)&pbrushFill->ptOrigin);
+ BrushOrigin = *((PPOINTL)&pbrFill->ptOrigin);
BrushOrigin.x += dc->ptlDCOrig.x;
BrushOrigin.y += dc->ptlDCOrig.y;
- EBRUSHOBJ_vInit(&eboFill, pbrushFill, dc->rosdc.XlateBrush);
- ret = IntFillPolygon (dc, psurf, &eboFill.BrushObject, Points, Count,
- DestRect, &BrushOrigin);
+ ret = IntFillPolygon (dc,
+ psurf,
+ &dc->eboFill.BrushObject,
+ Points,
+ Count,
+ DestRect,
+ &BrushOrigin);
}
- if (pbrushFill)
- BRUSH_UnlockBrush(pbrushFill);
// Draw the Polygon Edges with the current pen ( if not a NULL pen )
- if (pbrushLine && !(pbrushLine->flAttrs & GDIBRUSH_IS_NULL))
+ if (!(pbrLine->flAttrs & GDIBRUSH_IS_NULL))
{
int i;
- EBRUSHOBJ_vInit(&eboLine, pbrushLine, dc->rosdc.XlatePen);
-
for (i = 0; i < Count-1; i++)
{
ret = IntEngLineTo(&psurf->SurfObj,
dc->rosdc.CombinedClip,
- &eboLine.BrushObject,
+ &dc->eboLine.BrushObject,
Points[i].x, /* From */
Points[i].y,
Points[i+1].x, /* To */
{
ret = IntEngLineTo(&psurf->SurfObj,
dc->rosdc.CombinedClip,
- &eboLine.BrushObject,
+ &dc->eboLine.BrushObject,
Points[Count-1].x, /* From */
Points[Count-1].y,
Points[0].x, /* To */
ROP2_TO_MIX(pdcattr->jROP2)); /* MIX */
}
}
- if (pbrushLine)
- PEN_UnlockPen(pbrushLine);
}
- SURFACE_UnlockSurface(psurf);
return ret;
}
pdcattr = dc->pdcattr;
- if (pdcattr->ulDirty_ & DC_BRUSH_DIRTY)
- IntGdiSelectBrush(dc,pdcattr->hbrush);
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
- if (pdcattr->ulDirty_ & DC_PEN_DIRTY)
- IntGdiSelectPen(dc,pdcattr->hpen);
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
pbrush = PEN_LockPen(pdcattr->hpen);
if (!pbrush)
}
if (!PenWidth) PenWidth = 1;
- pbrush->ptPenWidth.x = PenWidth;
+ pbrush->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.right = Right;
RectBounds.top = Top;
RectBounds.bottom = Bottom;
-
+
IntLPtoDP(dc, (LPPOINT)&RectBounds, 2);
-
+
RectBounds.left += dc->ptlDCOrig.x;
RectBounds.right += dc->ptlDCOrig.x;
RectBounds.top += dc->ptlDCOrig.y;
CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2);
pFillBrushObj = BRUSH_LockBrush(pdcattr->hbrush);
- if (NULL == pFillBrushObj)
+ if (NULL == pFillBrushObj)
{
DPRINT1("FillEllipse Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
return TRUE;
}
+ DC_vPrepareDCsForBlit(dc, dc->rosdc.CombinedClip->rclBounds,
+ NULL, dc->rosdc.CombinedClip->rclBounds);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (dc->pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
/* Perform the actual work */
switch (iFunc)
{
}
/* Cleanup and return */
+ DC_vFinishBlit(dc, NULL);
DC_UnlockDc(dc);
ExFreePool(pTemp);
int BottomRect)
{
SURFACE *psurf = NULL;
- PBRUSH pbrushLine = NULL, pbrushFill = NULL;
- EBRUSHOBJ eboLine, eboFill;
+ PBRUSH pbrLine, pbrFill;
BOOL ret = FALSE; // default to failure
RECTL DestRect;
MIX Mix;
pdcattr = dc->pdcattr;
- /* Do we rotate or shear? */
- if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE))
- {
-
- POINTL DestCoords[4];
- ULONG PolyCounts = 4;
- DestCoords[0].x = DestCoords[3].x = LeftRect;
- DestCoords[0].y = DestCoords[1].y = TopRect;
- DestCoords[1].x = DestCoords[2].x = RightRect;
- DestCoords[2].y = DestCoords[3].y = BottomRect;
- // Use IntGdiPolyPolygon so to support PATH.
- return IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1);
- }
// Rectangle Path only.
if ( PATH_IsPathOpen(dc->dclevel) )
{
DestRect.bottom--;
}
- if (pdcattr->ulDirty_ & DC_BRUSH_DIRTY)
- IntGdiSelectBrush(dc,pdcattr->hbrush);
+ DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
- if (pdcattr->ulDirty_ & DC_PEN_DIRTY)
- IntGdiSelectPen(dc,pdcattr->hpen);
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
- /* Special locking order to avoid lock-ups! */
- pbrushFill = BRUSH_LockBrush(pdcattr->hbrush);
- pbrushLine = PEN_LockPen(pdcattr->hpen);
- if (!pbrushLine)
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
+ pbrFill = dc->dclevel.pbrFill;
+ pbrLine = dc->dclevel.pbrLine;
+ if (!pbrLine)
{
ret = FALSE;
goto cleanup;
}
- psurf = SURFACE_LockSurface(dc->rosdc.hBitmap);
+
+ psurf = dc->dclevel.pSurface;
if (!psurf)
{
ret = FALSE;
goto cleanup;
}
- if ( pbrushFill )
+ if (pbrFill)
{
- if (!(pbrushFill->flAttrs & GDIBRUSH_IS_NULL))
+ if (!(pbrFill->flAttrs & GDIBRUSH_IS_NULL))
{
- BrushOrigin = *((PPOINTL)&pbrushFill->ptOrigin);
+ BrushOrigin = *((PPOINTL)&pbrFill->ptOrigin);
BrushOrigin.x += dc->ptlDCOrig.x;
BrushOrigin.y += dc->ptlDCOrig.y;
- EBRUSHOBJ_vInit(&eboFill, pbrushFill, dc->rosdc.XlateBrush);
ret = IntEngBitBlt(&psurf->SurfObj,
NULL,
NULL,
&DestRect,
NULL,
NULL,
- &eboFill.BrushObject,
+ &dc->eboFill.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
}
}
- EBRUSHOBJ_vInit(&eboLine, pbrushLine, dc->rosdc.XlatePen);
-
// Draw the rectangle with the current pen
ret = TRUE; // change default to success
- if (!(pbrushLine->flAttrs & GDIBRUSH_IS_NULL))
+ if (!(pbrLine->flAttrs & GDIBRUSH_IS_NULL))
{
Mix = ROP2_TO_MIX(pdcattr->jROP2);
ret = ret && IntEngLineTo(&psurf->SurfObj,
dc->rosdc.CombinedClip,
- &eboLine.BrushObject,
+ &dc->eboLine.BrushObject,
DestRect.left, DestRect.top, DestRect.right, DestRect.top,
&DestRect, // Bounding rectangle
Mix);
ret = ret && IntEngLineTo(&psurf->SurfObj,
dc->rosdc.CombinedClip,
- &eboLine.BrushObject,
+ &dc->eboLine.BrushObject,
DestRect.right, DestRect.top, DestRect.right, DestRect.bottom,
&DestRect, // Bounding rectangle
Mix);
ret = ret && IntEngLineTo(&psurf->SurfObj,
dc->rosdc.CombinedClip,
- &eboLine.BrushObject,
+ &dc->eboLine.BrushObject,
DestRect.right, DestRect.bottom, DestRect.left, DestRect.bottom,
&DestRect, // Bounding rectangle
Mix);
ret = ret && IntEngLineTo(&psurf->SurfObj,
dc->rosdc.CombinedClip,
- &eboLine.BrushObject,
+ &dc->eboLine.BrushObject,
DestRect.left, DestRect.bottom, DestRect.left, DestRect.top,
&DestRect, // Bounding rectangle
Mix);
}
cleanup:
- if (pbrushFill)
- BRUSH_UnlockBrush(pbrushFill);
-
- if (pbrushLine)
- PEN_UnlockPen(pbrushLine);
-
- if (psurf)
- SURFACE_UnlockSurface(psurf);
+ DC_vFinishBlit(dc, NULL);
/* Move current position in DC?
MSDN: The current position is neither used nor updated by Rectangle. */
return TRUE;
}
- ret = IntRectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
- DC_UnlockDc ( dc );
+ /* Do we rotate or shear? */
+ if (!(dc->dclevel.mxWorldToDevice.flAccel & MX_SCALE))
+ {
+ POINTL DestCoords[4];
+ ULONG PolyCounts = 4;
+
+ DestCoords[0].x = DestCoords[3].x = LeftRect;
+ DestCoords[0].y = DestCoords[1].y = TopRect;
+ DestCoords[1].x = DestCoords[2].x = RightRect;
+ DestCoords[2].y = DestCoords[3].y = BottomRect;
+ // Use IntGdiPolyPolygon so to support PATH.
+ ret = IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1);
+ }
+ else
+ {
+ ret = IntRectangle(dc, LeftRect, TopRect, RightRect, BottomRect );
+ }
+
+ DC_UnlockDc(dc);
return ret;
}
pdcattr = dc->pdcattr;
- if (pdcattr->ulDirty_ & DC_BRUSH_DIRTY)
- IntGdiSelectBrush(dc,pdcattr->hbrush);
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
- if (pdcattr->ulDirty_ & DC_PEN_DIRTY)
- IntGdiSelectPen(dc,pdcattr->hpen);
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
pbrushLine = PEN_LockPen(pdcattr->hpen);
if (!pbrushLine)
}
if (!PenWidth) PenWidth = 1;
- pbrushLine->ptPenWidth.x = PenWidth;
+ pbrushLine->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.top = Top;
RectBounds.bottom += dc->ptlDCOrig.y;
pbrushFill = BRUSH_LockBrush(pdcattr->hbrush);
- if (NULL == pbrushFill)
+ if (NULL == pbrushFill)
{
DPRINT1("FillRound Fail\n");
SetLastWin32Error(ERROR_INTERNAL_ERROR);
ret = FALSE;
- }
+ }
else
{
RtlCopyMemory(&brushTemp, pbrushFill, sizeof(brushTemp));
return ret;
}
-BOOL FASTCALL
-IntGdiGradientFill(
- DC *dc,
+BOOL
+NTAPI
+GreGradientFill(
+ HDC hdc,
PTRIVERTEX pVertex,
- ULONG uVertex,
+ ULONG nVertex,
PVOID pMesh,
- ULONG uMesh,
+ ULONG nMesh,
ULONG ulMode)
{
+ PDC pdc;
SURFACE *psurf;
- PPALGDI PalDestGDI;
- XLATEOBJ *XlateObj;
- RECTL Extent;
- POINTL DitherOrg;
- ULONG Mode, i;
- BOOL Ret;
- HPALETTE hDestPalette;
-
- ASSERT(dc);
- ASSERT(pVertex);
- ASSERT(uVertex);
- ASSERT(pMesh);
- ASSERT(uMesh);
+ EXLATEOBJ exlo;
+ RECTL rclExtent;
+ POINTL ptlDitherOrg;
+ ULONG i;
+ BOOL bRet;
/* check parameters */
if (ulMode & GRADIENT_FILL_TRIANGLE)
{
- PGRADIENT_TRIANGLE tr = (PGRADIENT_TRIANGLE)pMesh;
+ PGRADIENT_TRIANGLE pTriangle = (PGRADIENT_TRIANGLE)pMesh;
- for (i = 0; i < uMesh; i++, tr++)
+ for (i = 0; i < nMesh; i++, pTriangle++)
{
- if (tr->Vertex1 >= uVertex ||
- tr->Vertex2 >= uVertex ||
- tr->Vertex3 >= uVertex)
+ if (pTriangle->Vertex1 >= nVertex ||
+ pTriangle->Vertex2 >= nVertex ||
+ pTriangle->Vertex3 >= nVertex)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
else
{
- PGRADIENT_RECT rc = (PGRADIENT_RECT)pMesh;
- for (i = 0; i < uMesh; i++, rc++)
+ PGRADIENT_RECT pRect = (PGRADIENT_RECT)pMesh;
+ for (i = 0; i < nMesh; i++, pRect++)
{
- if (rc->UpperLeft >= uVertex || rc->LowerRight >= uVertex)
+ if (pRect->UpperLeft >= nVertex || pRect->LowerRight >= nVertex)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
}
- /* calculate extent */
- Extent.left = Extent.right = pVertex->x;
- Extent.top = Extent.bottom = pVertex->y;
- for (i = 0; i < uVertex; i++)
+ /* Lock the output DC */
+ pdc = DC_LockDc(hdc);
+ if(!pdc)
{
- 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);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
}
- DitherOrg.x = dc->ptlDCOrig.x;
- DitherOrg.y = dc->ptlDCOrig.y;
- Extent.left += DitherOrg.x;
- Extent.right += DitherOrg.x;
- Extent.top += DitherOrg.y;
- Extent.bottom += DitherOrg.y;
-
- psurf = SURFACE_LockSurface(dc->rosdc.hBitmap);
- /* FIXME - psurf can be NULL!!! Don't assert but handle this case gracefully! */
- ASSERT(psurf);
+ if(pdc->dctype == DC_TYPE_INFO)
+ {
+ DC_UnlockDc(pdc);
+ /* Yes, Windows really returns TRUE in this case */
+ return TRUE;
+ }
- hDestPalette = psurf->hDIBPalette;
- if (!hDestPalette) hDestPalette = pPrimarySurface->DevInfo.hpalDefault;
+ psurf = pdc->dclevel.pSurface;
+ if(!psurf)
+ {
+ /* Memory DC with no surface selected */
+ DC_UnlockDc(pdc);
+ return TRUE; //CHECKME
+ }
- PalDestGDI = PALETTE_LockPalette(hDestPalette);
- if (PalDestGDI)
+ /* calculate extent */
+ rclExtent.left = rclExtent.right = pVertex->x;
+ rclExtent.top = rclExtent.bottom = pVertex->y;
+ for (i = 0; i < nVertex; i++)
{
- Mode = PalDestGDI->Mode;
- PALETTE_UnlockPalette(PalDestGDI);
+ rclExtent.left = min(rclExtent.left, (pVertex + i)->x);
+ rclExtent.right = max(rclExtent.right, (pVertex + i)->x);
+ rclExtent.top = min(rclExtent.top, (pVertex + i)->y);
+ rclExtent.bottom = max(rclExtent.bottom, (pVertex + i)->y);
}
- else
- Mode = PAL_RGB;
+ IntLPtoDP(pdc, (LPPOINT)&rclExtent, 2);
+
+ rclExtent.left += pdc->ptlDCOrig.x;
+ rclExtent.right += pdc->ptlDCOrig.x;
+ rclExtent.top += pdc->ptlDCOrig.y;
+ rclExtent.bottom += pdc->ptlDCOrig.y;
+
+ ptlDitherOrg.x = ptlDitherOrg.y = 0;
+ IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1);
+
+ ptlDitherOrg.x += pdc->ptlDCOrig.x;
+ ptlDitherOrg.y += pdc->ptlDCOrig.y;
+
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0, 0);
- XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, hDestPalette, NULL);
- ASSERT(XlateObj);
+ ASSERT(pdc->rosdc.CombinedClip);
- Ret = IntEngGradientFill(&psurf->SurfObj,
- dc->rosdc.CombinedClip,
- XlateObj,
+ DC_vPrepareDCsForBlit(pdc, rclExtent, NULL, rclExtent);
+
+ bRet = IntEngGradientFill(&psurf->SurfObj,
+ pdc->rosdc.CombinedClip,
+ &exlo.xlo,
pVertex,
- uVertex,
+ nVertex,
pMesh,
- uMesh,
- &Extent,
- &DitherOrg,
+ nMesh,
+ &rclExtent,
+ &ptlDitherOrg,
ulMode);
- SURFACE_UnlockSurface(psurf);
- EngDeleteXlate(XlateObj);
+ EXLATEOBJ_vCleanup(&exlo);
+ DC_vFinishBlit(pdc, NULL);
+ DC_UnlockDc(pdc);
- return Ret;
+ return bRet;
}
BOOL
NtGdiGradientFill(
HDC hdc,
PTRIVERTEX pVertex,
- ULONG uVertex,
+ ULONG nVertex,
PVOID pMesh,
- ULONG uMesh,
+ ULONG nMesh,
ULONG ulMode)
{
- DC *dc;
- BOOL Ret;
+ BOOL bRet;
PTRIVERTEX SafeVertex;
PVOID SafeMesh;
- ULONG SizeMesh;
- NTSTATUS Status = STATUS_SUCCESS;
+ ULONG cbVertex, cbMesh;
- dc = DC_LockDc(hdc);
- if (!dc)
- {
- SetLastWin32Error(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- if (dc->dctype == DC_TYPE_INFO)
- {
- DC_UnlockDc(dc);
- /* Yes, Windows really returns TRUE in this case */
- return TRUE;
- }
- if (!pVertex || !uVertex || !pMesh || !uMesh)
+ /* Validate parameters */
+ if (!pVertex || !nVertex || !pMesh || !nMesh)
{
- DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
{
case GRADIENT_FILL_RECT_H:
case GRADIENT_FILL_RECT_V:
- SizeMesh = uMesh * sizeof(GRADIENT_RECT);
+ cbMesh = nMesh * sizeof(GRADIENT_RECT);
break;
case GRADIENT_FILL_TRIANGLE:
- SizeMesh = uMesh * sizeof(TRIVERTEX);
+ cbMesh = nMesh * sizeof(GRADIENT_TRIANGLE);
break;
default:
- DC_UnlockDc(dc);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
- _SEH2_TRY
- {
- ProbeForRead(pVertex,
- uVertex * sizeof(TRIVERTEX),
- 1);
- ProbeForRead(pMesh,
- SizeMesh,
- 1);
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
-
- if (!NT_SUCCESS(Status))
+ cbVertex = nVertex * sizeof(TRIVERTEX) ;
+ if(cbVertex + cbMesh <= cbVertex)
{
- DC_UnlockDc(dc);
- SetLastWin32Error(Status);
- return FALSE;
+ /* Overflow */
+ return FALSE ;
}
- if (!(SafeVertex = ExAllocatePoolWithTag(PagedPool, (uVertex * sizeof(TRIVERTEX)) + SizeMesh, TAG_SHAPE)))
+ /* Allocate a kernel mode buffer */
+ SafeVertex = ExAllocatePoolWithTag(PagedPool, cbVertex + cbMesh, TAG_SHAPE);
+ if(!SafeVertex)
{
- DC_UnlockDc(dc);
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
- SafeMesh = (PTRIVERTEX)(SafeVertex + uVertex);
+ SafeMesh = (PVOID)((ULONG_PTR)SafeVertex + cbVertex);
+ /* Copy the parameters to kernel mode */
_SEH2_TRY
{
- /* pointers were already probed! */
- RtlCopyMemory(SafeVertex,
- pVertex,
- uVertex * sizeof(TRIVERTEX));
- RtlCopyMemory(SafeMesh,
- pMesh,
- SizeMesh);
+ ProbeForRead(pVertex, cbVertex, 1);
+ ProbeForRead(pMesh, cbMesh, 1);
+ RtlCopyMemory(SafeVertex, pVertex, cbVertex);
+ RtlCopyMemory(SafeMesh, pMesh, cbMesh);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END;
-
- if (!NT_SUCCESS(Status))
- {
- DC_UnlockDc(dc);
ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
- SetLastNtError(Status);
- return FALSE;
+ SetLastNtError(_SEH2_GetExceptionCode());
+ _SEH2_YIELD(return FALSE;)
}
+ _SEH2_END;
- Ret = IntGdiGradientFill(dc, SafeVertex, uVertex, SafeMesh, uMesh, ulMode);
+ /* Call the internal function */
+ bRet = GreGradientFill(hdc, SafeVertex, nVertex, SafeMesh, nMesh, ulMode);
- DC_UnlockDc(dc);
- ExFreePool(SafeVertex);
- return Ret;
+ /* Cleanup and return result */
+ ExFreePoolWithTag(SafeVertex, TAG_SHAPE);
+ return bRet;
}
BOOL APIENTRY
UINT FillType)
{
PDC dc;
- PDC_ATTR pdcattr;
- SURFACE *psurf = NULL;
- PBRUSH pbrushFill = NULL;
- EBRUSHOBJ eboFill;
+ PDC_ATTR pdcattr;
+ SURFACE *psurf = NULL;
+ EXLATEOBJ exlo;
BOOL Ret = FALSE;
RECTL DestRect;
POINTL Pt;
- POINTL BrushOrigin;
-
- DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
+ ULONG ConvColor;
dc = DC_LockDc(hDC);
if (!dc)
pdcattr = dc->pdcattr;
- if (pdcattr->ulDirty_ & DC_PEN_DIRTY)
- IntGdiSelectPen(dc,pdcattr->hpen);
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
- if (pdcattr->ulDirty_ & DC_BRUSH_DIRTY)
- IntGdiSelectBrush(dc,pdcattr->hbrush);
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
Pt.x = XStart;
Pt.y = YStart;
else
goto cleanup;
- pbrushFill = BRUSH_LockBrush(pdcattr->hbrush);
- if (!pbrushFill)
- {
- Ret = FALSE;
- goto cleanup;
- }
- psurf = SURFACE_LockSurface(dc->rosdc.hBitmap);
+ psurf = dc->dclevel.pSurface;
if (!psurf)
{
Ret = FALSE;
goto cleanup;
}
- if ( pbrushFill && (FillType == FLOODFILLBORDER))
- {
- if (!(pbrushFill->flAttrs & GDIBRUSH_IS_NULL))
- {
- pbrushFill->BrushAttr.lbColor = Color;
- BrushOrigin = *((PPOINTL)&pbrushFill->ptOrigin);
- BrushOrigin.x += dc->ptlDCOrig.x;
- BrushOrigin.y += dc->ptlDCOrig.y;
- EBRUSHOBJ_vInit(&eboFill, pbrushFill, dc->rosdc.XlateBrush);
- Ret = IntEngBitBlt(&psurf->SurfObj, NULL, NULL,
- dc->rosdc.CombinedClip, NULL,
- &DestRect, NULL, NULL,
- &eboFill.BrushObject,
- &BrushOrigin,
- ROP3_TO_ROP4(PATCOPY));
- }
- }
- else
- {
- }
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, psurf->ppal, 0, 0xffffff, 0);
-cleanup:
- if (pbrushFill)
- BRUSH_UnlockBrush(pbrushFill);
+ /* Only solid fills supported for now
+ * How to support pattern brushes and non standard surfaces (not offering dib functions):
+ * Version a (most likely slow): call DrvPatBlt for every pixel
+ * Version b: create a flood mask and let MaskBlt blit a masked brush */
+ ConvColor = XLATEOBJ_iXlate(&exlo.xlo, Color);
+ Ret = DIB_XXBPP_FloodFillSolid(&psurf->SurfObj, &dc->eboFill.BrushObject, &DestRect, &Pt, ConvColor, FillType);
- if (psurf)
- SURFACE_UnlockSurface(psurf);
+ EXLATEOBJ_vCleanup(&exlo);
+cleanup:
DC_UnlockDc(dc);
return Ret;
}