* 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>
-/*
- * a couple macros to fill a single pixel or a line
- */
-#define PUTPIXEL(x,y,BrushInst) \
- ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
- dc->CombinedClip, \
- &BrushInst.BrushObject, \
- x, y, (x)+1, y, \
- &RectBounds, \
- ROP2_TO_MIX(Dc_Attr->jROP2));
-
-#define PUTLINE(x1,y1,x2,y2,BrushInst) \
- ret = ret && IntEngLineTo(&BitmapObj->SurfObj, \
- dc->CombinedClip, \
- &BrushInst.BrushObject, \
- x1, y1, x2, y2, \
- &RectBounds, \
- ROP2_TO_MIX(Dc_Attr->jROP2));
-
#define Rsin(d) ((d) == 0.0 ? 0.0 : ((d) == 90.0 ? 1.0 : sin(d*M_PI/180.0)))
#define Rcos(d) ((d) == 0.0 ? 1.0 : ((d) == 90.0 ? 0.0 : cos(d*M_PI/180.0)))
-BOOL FASTCALL IntFillEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height);
-BOOL FASTCALL IntDrawEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, PGDIBRUSHOBJ PenBrushObj);
-BOOL FASTCALL IntFillRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT Wellipse, INT Hellipse);
-BOOL FASTCALL IntDrawRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT Wellipse, INT Hellipse, PGDIBRUSHOBJ PenBrushObj);
+BOOL FASTCALL IntFillEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, PBRUSH pbrush);
+BOOL FASTCALL IntDrawEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height, PBRUSH pbrush);
+BOOL FASTCALL IntFillRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT Wellipse, INT Hellipse, PBRUSH pbrush);
+BOOL FASTCALL IntDrawRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT Wellipse, INT Hellipse, PBRUSH pbrush);
BOOL FASTCALL
IntGdiPolygon(PDC dc,
PPOINT Points,
int Count)
{
- BITMAPOBJ *BitmapObj;
- PGDIBRUSHOBJ PenBrushObj, FillBrushObj;
- GDIBRUSHINST PenBrushInst, FillBrushInst;
+ SURFACE *psurf;
+ PBRUSH pbrLine, pbrFill;
BOOL ret = FALSE; // default to failure
RECTL DestRect;
int CurrentPoint;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
+ POINTL BrushOrigin;
+// int Left;
+// int Top;
ASSERT(dc); // caller's responsibility to pass a valid dc
return FALSE;
}
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+/*
+ //Find start x, y
+ Left = Points[0].x;
+ Top = Points[0].y;
+ for (CurrentPoint = 1; CurrentPoint < Count; ++CurrentPoint) {
+ Left = min(Left, Points[CurrentPoint].x);
+ Top = min(Top, Points[CurrentPoint].y);
+ }
+*/
+
+ pdcattr = dc->pdcattr;
/* Convert to screen coordinates */
IntLPtoDP(dc, Points, Count);
DestRect.bottom = max(DestRect.bottom, Points[CurrentPoint].y);
}
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
/* Special locking order to avoid lock-ups */
- FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
- PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- /* FIXME - BitmapObj can be NULL!!!! don't assert but handle this case gracefully! */
- ASSERT(BitmapObj);
-
- /* Now fill the polygon with the current brush. */
- if (FillBrushObj && !(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
+ 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 fill brush. */
+ if (!(pbrFill->flAttrs & GDIBRUSH_IS_NULL))
{
- IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
- ret = FillPolygon ( dc, BitmapObj, &FillBrushInst.BrushObject, ROP2_TO_MIX(Dc_Attr->jROP2), Points, Count, DestRect );
+ BrushOrigin = *((PPOINTL)&pbrFill->ptOrigin);
+ BrushOrigin.x += dc->ptlDCOrig.x;
+ BrushOrigin.y += dc->ptlDCOrig.y;
+ ret = IntFillPolygon (dc,
+ psurf,
+ &dc->eboFill.BrushObject,
+ Points,
+ Count,
+ DestRect,
+ &BrushOrigin);
}
- if (FillBrushObj)
- BRUSHOBJ_UnlockBrush(FillBrushObj);
// Draw the Polygon Edges with the current pen ( if not a NULL pen )
- if (PenBrushObj && !(PenBrushObj->flAttrs & GDIBRUSH_IS_NULL))
+ if (!(pbrLine->flAttrs & GDIBRUSH_IS_NULL))
{
int i;
- IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
-
for (i = 0; i < Count-1; i++)
{
// Points[0].x, Points[0].y,
// Points[1].x, Points[1].y );
- ret = IntEngLineTo(&BitmapObj->SurfObj,
- dc->CombinedClip,
- &PenBrushInst.BrushObject,
+ ret = IntEngLineTo(&psurf->SurfObj,
+ dc->rosdc.CombinedClip,
+ &dc->eboLine.BrushObject,
Points[i].x, /* From */
Points[i].y,
Points[i+1].x, /* To */
Points[i+1].y,
&DestRect,
- ROP2_TO_MIX(Dc_Attr->jROP2)); /* MIX */
+ ROP2_TO_MIX(pdcattr->jROP2)); /* MIX */
if (!ret) break;
}
/* Close the polygon */
if (ret)
{
- ret = IntEngLineTo(&BitmapObj->SurfObj,
- dc->CombinedClip,
- &PenBrushInst.BrushObject,
+ ret = IntEngLineTo(&psurf->SurfObj,
+ dc->rosdc.CombinedClip,
+ &dc->eboLine.BrushObject,
Points[Count-1].x, /* From */
Points[Count-1].y,
Points[0].x, /* To */
Points[0].y,
&DestRect,
- ROP2_TO_MIX(Dc_Attr->jROP2)); /* MIX */
+ ROP2_TO_MIX(pdcattr->jROP2)); /* MIX */
}
}
- if (PenBrushObj)
- PENOBJ_UnlockPen(PenBrushObj);
}
- BITMAPOBJ_UnlockBitmap(BitmapObj);
return ret;
}
PULONG PolyCounts,
int Count)
{
- if (PATH_IsPathOpen(dc->DcLevel))
+ if (PATH_IsPathOpen(dc->dclevel))
return PATH_PolyPolygon ( dc, Points, (PINT)PolyCounts, Count);
while (--Count >=0)
*
*/
-BOOL STDCALL
+BOOL APIENTRY
NtGdiEllipse(
HDC hDC,
int Left,
int Bottom)
{
PDC dc;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
RECTL RectBounds;
- PGDIBRUSHOBJ PenBrushObj;
+ PBRUSH pbrush;
BOOL ret = TRUE;
LONG PenWidth, PenOrigWidth;
LONG RadiusX, RadiusY, CenterX, CenterY;
+ PBRUSH pFillBrushObj;
+ BRUSH tmpFillBrushObj;
if ((Left == Right) || (Top == Bottom)) return TRUE;
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- if (dc->DC_Type == DC_TYPE_INFO)
+ if (dc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
- if (PATH_IsPathOpen(dc->DcLevel))
+ if (PATH_IsPathOpen(dc->dclevel))
{
ret = PATH_Ellipse(dc, Left, Top, Right, Bottom);
DC_UnlockDc(dc);
INT tmp = Bottom; Bottom = Top; Top = tmp;
}
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+ pdcattr = dc->pdcattr;
+
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
- PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
- if (NULL == PenBrushObj)
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
+ pbrush = PEN_LockPen(pdcattr->hpen);
+ if (!pbrush)
{
DPRINT1("Ellipse Fail 1\n");
DC_UnlockDc(dc);
return FALSE;
}
- PenOrigWidth = PenWidth = PenBrushObj->ptPenWidth.x;
- if (PenBrushObj->ulPenStyle == PS_NULL) PenWidth = 0;
+ PenOrigWidth = PenWidth = pbrush->ptPenWidth.x;
+ if (pbrush->ulPenStyle == PS_NULL) PenWidth = 0;
- if (PenBrushObj->ulPenStyle == PS_INSIDEFRAME)
+ if (pbrush->ulPenStyle == PS_INSIDEFRAME)
{
if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
}
if (!PenWidth) PenWidth = 1;
- PenBrushObj->ptPenWidth.x = PenWidth;
+ pbrush->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.right = Right;
DPRINT("Ellipse 2: XLeft: %d, YLeft: %d, Width: %d, Height: %d\n",
CenterX - RadiusX, CenterY + RadiusY, RadiusX*2, RadiusY*2);
- ret = IntFillEllipse( dc,
- CenterX - RadiusX,
- CenterY - RadiusY,
- RadiusX*2, // Width
- RadiusY*2); // Height
+ pFillBrushObj = BRUSH_LockBrush(pdcattr->hbrush);
+ if (NULL == pFillBrushObj)
+ {
+ DPRINT1("FillEllipse Fail\n");
+ SetLastWin32Error(ERROR_INTERNAL_ERROR);
+ ret = FALSE;
+ }
+ else
+ {
+ RtlCopyMemory(&tmpFillBrushObj, pFillBrushObj, sizeof(tmpFillBrushObj));
+// tmpFillBrushObj.ptOrigin.x += RectBounds.left - Left;
+// tmpFillBrushObj.ptOrigin.y += RectBounds.top - Top;
+ tmpFillBrushObj.ptOrigin.x += dc->ptlDCOrig.x;
+ tmpFillBrushObj.ptOrigin.y += dc->ptlDCOrig.y;
+ ret = IntFillEllipse( dc,
+ CenterX - RadiusX,
+ CenterY - RadiusY,
+ RadiusX*2, // Width
+ RadiusY*2, // Height
+ &tmpFillBrushObj);
+ BRUSH_UnlockBrush(pFillBrushObj);
+ }
+
if (ret)
ret = IntDrawEllipse( dc,
CenterX - RadiusX,
CenterY - RadiusY,
RadiusX*2, // Width
RadiusY*2, // Height
- PenBrushObj);
+ pbrush);
- PenBrushObj->ptPenWidth.x = PenOrigWidth;
- PENOBJ_UnlockPen(PenBrushObj);
+ pbrush->ptPenWidth.x = PenOrigWidth;
+ PEN_UnlockPen(pbrush);
DC_UnlockDc(dc);
DPRINT("Ellipse Exit.\n");
return ret;
ULONG_PTR
-STDCALL
+APIENTRY
NtGdiPolyPolyDraw( IN HDC hDC,
IN PPOINT UnsafePoints,
IN PULONG UnsafeCounts,
return FALSE;
}
- _SEH_TRY
+ _SEH2_TRY
{
ProbeForRead(UnsafePoints, Count * sizeof(POINT), 1);
ProbeForRead(UnsafeCounts, Count * sizeof(ULONG), 1);
nMaxPoints = max(nMaxPoints, UnsafeCounts[i]);
}
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
if (!NT_SUCCESS(Status))
{
SafeCounts = pTemp;
SafePoints = (PVOID)(SafeCounts + Count);
- _SEH_TRY
+ _SEH2_TRY
{
/* Pointers already probed! */
RtlCopyMemory(SafeCounts, UnsafeCounts, Count * sizeof(ULONG));
RtlCopyMemory(SafePoints, UnsafePoints, nPoints * sizeof(POINT));
}
- _SEH_HANDLE
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- Status = _SEH_GetExceptionCode();
+ Status = _SEH2_GetExceptionCode();
}
- _SEH_END;
+ _SEH2_END;
if (!NT_SUCCESS(Status))
{
return FALSE;
}
- if (dc->DC_Type == DC_TYPE_INFO)
+ if (dc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(dc);
ExFreePool(pTemp);
int RightRect,
int BottomRect)
{
- BITMAPOBJ *BitmapObj = NULL;
- PGDIBRUSHOBJ PenBrushObj = NULL, FillBrushObj = NULL;
- GDIBRUSHINST PenBrushInst, FillBrushInst;
+ SURFACE *psurf = NULL;
+ PBRUSH pbrLine, pbrFill;
BOOL ret = FALSE; // default to failure
RECTL DestRect;
MIX Mix;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
+ POINTL BrushOrigin;
ASSERT ( dc ); // caller's responsibility to set this up
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
- if ( PATH_IsPathOpen(dc->DcLevel) )
- {
- return PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
- }
+ pdcattr = dc->pdcattr;
/* Do we rotate or shear? */
- if (!(dc->DcLevel.mxWorldToDevice.flAccel & MX_SCALE))
+ 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;
- return IntGdiPolygon(dc, DestCoords, 4);
+ // Use IntGdiPolyPolygon so to support PATH.
+ return IntGdiPolyPolygon(dc, DestCoords, &PolyCounts, 1);
+ }
+ // Rectangle Path only.
+ if ( PATH_IsPathOpen(dc->dclevel) )
+ {
+ return PATH_Rectangle ( dc, LeftRect, TopRect, RightRect, BottomRect );
}
DestRect.left = LeftRect;
DestRect.bottom += dc->ptlDCOrig.y;
/* In GM_COMPATIBLE, don't include bottom and right edges */
- if (IntGetGraphicsMode(dc) == GM_COMPATIBLE)
+ if (pdcattr->iGraphicsMode == GM_COMPATIBLE)
{
DestRect.right--;
DestRect.bottom--;
}
- /* Special locking order to avoid lock-ups! */
- FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
- PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
- if (!PenBrushObj)
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ 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;
}
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- if (!BitmapObj)
+ psurf = dc->dclevel.pSurface;
+ if (!psurf)
{
ret = FALSE;
goto cleanup;
}
- if ( FillBrushObj )
+ if (pbrFill)
{
- if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
+ if (!(pbrFill->flAttrs & GDIBRUSH_IS_NULL))
{
- IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
- ret = IntEngBitBlt(&BitmapObj->SurfObj,
+ BrushOrigin = *((PPOINTL)&pbrFill->ptOrigin);
+ BrushOrigin.x += dc->ptlDCOrig.x;
+ BrushOrigin.y += dc->ptlDCOrig.y;
+ ret = IntEngBitBlt(&psurf->SurfObj,
NULL,
NULL,
- dc->CombinedClip,
+ dc->rosdc.CombinedClip,
NULL,
&DestRect,
NULL,
NULL,
- &FillBrushInst.BrushObject,
- NULL,
+ &dc->eboFill.BrushObject,
+ &BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
}
}
- IntGdiInitBrushInstance(&PenBrushInst, PenBrushObj, dc->XlatePen);
-
// Draw the rectangle with the current pen
ret = TRUE; // change default to success
- if (!(PenBrushObj->flAttrs & GDIBRUSH_IS_NULL))
+ if (!(pbrLine->flAttrs & GDIBRUSH_IS_NULL))
{
- Mix = ROP2_TO_MIX(Dc_Attr->jROP2);
- ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
- dc->CombinedClip,
- &PenBrushInst.BrushObject,
+ Mix = ROP2_TO_MIX(pdcattr->jROP2);
+ ret = ret && IntEngLineTo(&psurf->SurfObj,
+ dc->rosdc.CombinedClip,
+ &dc->eboLine.BrushObject,
DestRect.left, DestRect.top, DestRect.right, DestRect.top,
&DestRect, // Bounding rectangle
Mix);
- ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
- dc->CombinedClip,
- &PenBrushInst.BrushObject,
+ ret = ret && IntEngLineTo(&psurf->SurfObj,
+ dc->rosdc.CombinedClip,
+ &dc->eboLine.BrushObject,
DestRect.right, DestRect.top, DestRect.right, DestRect.bottom,
&DestRect, // Bounding rectangle
Mix);
- ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
- dc->CombinedClip,
- &PenBrushInst.BrushObject,
+ ret = ret && IntEngLineTo(&psurf->SurfObj,
+ dc->rosdc.CombinedClip,
+ &dc->eboLine.BrushObject,
DestRect.right, DestRect.bottom, DestRect.left, DestRect.bottom,
&DestRect, // Bounding rectangle
Mix);
- ret = ret && IntEngLineTo(&BitmapObj->SurfObj,
- dc->CombinedClip,
- &PenBrushInst.BrushObject,
+ ret = ret && IntEngLineTo(&psurf->SurfObj,
+ dc->rosdc.CombinedClip,
+ &dc->eboLine.BrushObject,
DestRect.left, DestRect.bottom, DestRect.left, DestRect.top,
&DestRect, // Bounding rectangle
Mix);
}
cleanup:
- if (FillBrushObj)
- BRUSHOBJ_UnlockBrush(FillBrushObj);
-
- if (PenBrushObj)
- PENOBJ_UnlockPen(PenBrushObj);
-
- if (BitmapObj)
- BITMAPOBJ_UnlockBitmap(BitmapObj);
-
/* Move current position in DC?
MSDN: The current position is neither used nor updated by Rectangle. */
}
BOOL
-STDCALL
+APIENTRY
NtGdiRectangle(HDC hDC,
int LeftRect,
int TopRect,
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- if (dc->DC_Type == DC_TYPE_INFO)
+ if (dc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */
int xCurveDiameter,
int yCurveDiameter)
{
- PDC_ATTR Dc_Attr;
- PGDIBRUSHOBJ PenBrushObj;
+ PDC_ATTR pdcattr;
+ PBRUSH pbrushLine, pbrushFill;
RECTL RectBounds;
LONG PenWidth, PenOrigWidth;
BOOL ret = TRUE; // default to success
+ BRUSH brushTemp;
ASSERT ( dc ); // caller's responsibility to set this up
- if ( PATH_IsPathOpen(dc->DcLevel) )
+ if ( PATH_IsPathOpen(dc->dclevel) )
return PATH_RoundRect ( dc, Left, Top, Right, Bottom,
xCurveDiameter, yCurveDiameter );
INT tmp = Bottom; Bottom = Top; Top = tmp;
}
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+ pdcattr = dc->pdcattr;
+
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
- PenBrushObj = PENOBJ_LockPen(Dc_Attr->hpen);
- if (!PenBrushObj)
+ pbrushLine = PEN_LockPen(pdcattr->hpen);
+ if (!pbrushLine)
{
/* Nothing to do, as we don't have a bitmap */
SetLastWin32Error(ERROR_INTERNAL_ERROR);
return FALSE;
}
- PenOrigWidth = PenWidth = PenBrushObj->ptPenWidth.x;
- if (PenBrushObj->ulPenStyle == PS_NULL) PenWidth = 0;
+ PenOrigWidth = PenWidth = pbrushLine->ptPenWidth.x;
+ if (pbrushLine->ulPenStyle == PS_NULL) PenWidth = 0;
- if (PenBrushObj->ulPenStyle == PS_INSIDEFRAME)
+ if (pbrushLine->ulPenStyle == PS_INSIDEFRAME)
{
if (2*PenWidth > (Right - Left)) PenWidth = (Right -Left + 1)/2;
if (2*PenWidth > (Bottom - Top)) PenWidth = (Bottom -Top + 1)/2;
}
if (!PenWidth) PenWidth = 1;
- PenBrushObj->ptPenWidth.x = PenWidth;
+ pbrushLine->ptPenWidth.x = PenWidth;
RectBounds.left = Left;
RectBounds.top = Top;
RectBounds.right += dc->ptlDCOrig.x;
RectBounds.bottom += dc->ptlDCOrig.y;
- ret = IntFillRoundRect( dc,
- RectBounds.left,
- RectBounds.top,
- RectBounds.right,
- RectBounds.bottom,
- xCurveDiameter,
- yCurveDiameter);
+ pbrushFill = BRUSH_LockBrush(pdcattr->hbrush);
+ if (NULL == pbrushFill)
+ {
+ DPRINT1("FillRound Fail\n");
+ SetLastWin32Error(ERROR_INTERNAL_ERROR);
+ ret = FALSE;
+ }
+ else
+ {
+ RtlCopyMemory(&brushTemp, pbrushFill, sizeof(brushTemp));
+ brushTemp.ptOrigin.x += RectBounds.left - Left;
+ brushTemp.ptOrigin.y += RectBounds.top - Top;
+ ret = IntFillRoundRect( dc,
+ RectBounds.left,
+ RectBounds.top,
+ RectBounds.right,
+ RectBounds.bottom,
+ xCurveDiameter,
+ yCurveDiameter,
+ &brushTemp);
+ BRUSH_UnlockBrush(pbrushFill);
+ }
+
if (ret)
ret = IntDrawRoundRect( dc,
RectBounds.left,
RectBounds.bottom,
xCurveDiameter,
yCurveDiameter,
- PenBrushObj);
+ pbrushLine);
- PenBrushObj->ptPenWidth.x = PenOrigWidth;
- PENOBJ_UnlockPen(PenBrushObj);
+ pbrushLine->ptPenWidth.x = PenOrigWidth;
+ PEN_UnlockPen(pbrushLine);
return ret;
}
BOOL
-STDCALL
+APIENTRY
NtGdiRoundRect(
HDC hDC,
int LeftRect,
DPRINT1("NtGdiRoundRect() - hDC is invalid\n");
SetLastWin32Error(ERROR_INVALID_HANDLE);
}
- else if (dc->DC_Type == DC_TYPE_INFO)
+ else if (dc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */
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)
{
- BITMAPOBJ *BitmapObj;
- PPALGDI PalDestGDI;
- XLATEOBJ *XlateObj;
- RECTL Extent;
- POINTL DitherOrg;
- ULONG Mode, i;
- BOOL Ret;
+ PDC pdc;
+ SURFACE *psurf;
+ PPALETTE ppal;
+ EXLATEOBJ exlo;
+ RECTL rclExtent;
+ POINTL ptlDitherOrg;
+ ULONG i;
+ BOOL bRet;
HPALETTE hDestPalette;
- ASSERT(dc);
- ASSERT(pVertex);
- ASSERT(uVertex);
- ASSERT(pMesh);
- ASSERT(uMesh);
-
- /* check parameters */
- if (ulMode & GRADIENT_FILL_TRIANGLE)
+ /* 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;
-
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- /* FIXME - BitmapObj can be NULL!!! Don't assert but handle this case gracefully! */
- ASSERT(BitmapObj);
+ if (pdc->dctype == DC_TYPE_INFO)
+ {
+ DC_UnlockDc(pdc);
+ /* Yes, Windows really returns TRUE in this case */
+ return TRUE;
+ }
- hDestPalette = BitmapObj->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;
- XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, hDestPalette, NULL);
- ASSERT(XlateObj);
+ 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;
- Ret = IntEngGradientFill(&BitmapObj->SurfObj,
- dc->CombinedClip,
- XlateObj,
- pVertex,
- uVertex,
- pMesh,
- uMesh,
- &Extent,
- &DitherOrg,
- ulMode);
+ ptlDitherOrg.x = ptlDitherOrg.y = 0;
+ IntLPtoDP(pdc, (LPPOINT)&ptlDitherOrg, 1);
+ ptlDitherOrg.x += pdc->ptlDCOrig.x;
+ ptlDitherOrg.y += pdc->ptlDCOrig.y;
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- EngDeleteXlate(XlateObj);
+ hDestPalette = psurf->hDIBPalette;
+ if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
- return Ret;
+ ppal = PALETTE_LockPalette(hDestPalette);
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0, 0);
+
+ ASSERT(pdc->rosdc.CombinedClip);
+
+ bRet = IntEngGradientFill(&psurf->SurfObj,
+ pdc->rosdc.CombinedClip,
+ &exlo.xlo,
+ pVertex,
+ nVertex,
+ pMesh,
+ nMesh,
+ &rclExtent,
+ &ptlDitherOrg,
+ ulMode);
+
+ EXLATEOBJ_vCleanup(&exlo);
+
+ if (ppal)
+ PALETTE_UnlockPalette(ppal);
+
+ DC_UnlockDc(pdc);
+
+ return bRet;
}
BOOL
-STDCALL
+APIENTRY
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->DC_Type == 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;
}
- _SEH_TRY
- {
- ProbeForRead(pVertex,
- uVertex * sizeof(TRIVERTEX),
- 1);
- ProbeForRead(pMesh,
- SizeMesh,
- 1);
- }
- _SEH_HANDLE
- {
- Status = _SEH_GetExceptionCode();
- }
- _SEH_END;
-
- if (!NT_SUCCESS(Status))
+ cbVertex = nVertex * sizeof(TRIVERTEX);
+ if (cbVertex + cbMesh <= cbVertex)
{
- DC_UnlockDc(dc);
- SetLastWin32Error(Status);
+ /* 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);
- _SEH_TRY
- {
- /* pointers were already probed! */
- RtlCopyMemory(SafeVertex,
- pVertex,
- uVertex * sizeof(TRIVERTEX));
- RtlCopyMemory(SafeMesh,
- pMesh,
- SizeMesh);
- }
- _SEH_HANDLE
+ /* Copy the parameters to kernel mode */
+ _SEH2_TRY
{
- Status = _SEH_GetExceptionCode();
+ ProbeForRead(pVertex, cbVertex, 1);
+ ProbeForRead(pMesh, cbMesh, 1);
+ RtlCopyMemory(SafeVertex, pVertex, cbVertex);
+ RtlCopyMemory(SafeMesh, pMesh, cbMesh);
}
- _SEH_END;
-
- if (!NT_SUCCESS(Status))
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
- 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 STDCALL
+BOOL APIENTRY
NtGdiExtFloodFill(
HDC hDC,
INT XStart,
COLORREF Color,
UINT FillType)
{
- DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
+ PDC dc;
+ PDC_ATTR pdcattr;
+ SURFACE *psurf = NULL;
+ HPALETTE hpal;
+ PPALETTE ppal;
+ EXLATEOBJ exlo;
+ BOOL Ret = FALSE;
+ RECTL DestRect;
+ POINTL Pt;
+ ULONG ConvColor;
- /* lie and say we succeded */
- return TRUE;
+ 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;
+ }
+
+ pdcattr = dc->pdcattr;
+
+ if (pdcattr->ulDirty_ & (DIRTY_FILL | DC_BRUSH_DIRTY))
+ DC_vUpdateFillBrush(dc);
+
+ if (pdcattr->ulDirty_ & (DIRTY_LINE | DC_PEN_DIRTY))
+ DC_vUpdateLineBrush(dc);
+
+ Pt.x = XStart;
+ Pt.y = YStart;
+ IntLPtoDP(dc, (LPPOINT)&Pt, 1);
+
+ Ret = NtGdiPtInRegion(dc->rosdc.hGCClipRgn, Pt.x, Pt.y);
+ if (Ret)
+ IntGdiGetRgnBox(dc->rosdc.hGCClipRgn,(LPRECT)&DestRect);
+ else
+ goto cleanup;
+
+ psurf = dc->dclevel.pSurface;
+ if (!psurf)
+ {
+ Ret = FALSE;
+ goto cleanup;
+ }
+
+ hpal = dc->dclevel.pSurface->hDIBPalette;
+ if (!hpal) hpal = pPrimarySurface->devinfo.hpalDefault;
+ ppal = PALETTE_ShareLockPalette(hpal);
+
+ EXLATEOBJ_vInitialize(&exlo, &gpalRGB, ppal, 0, 0xffffff, 0);
+
+ /* 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);
+
+ EXLATEOBJ_vCleanup(&exlo);
+ PALETTE_ShareUnlockPalette(ppal);
+
+cleanup:
+ DC_UnlockDc(dc);
+ return Ret;
}
/* EOF */