Author: jimtabor
Date: Mon Mar 16 06:21:00 2009
New Revision: 40051
URL:
http://svn.reactos.org/svn/reactos?rev=40051&view=rev
Log:
- Patch by Evgeniy Boltik: Fix Rectangle, Ellipse, RoundRect and Polygon.
Modified:
trunk/reactos/subsystems/win32/win32k/include/paint.h
trunk/reactos/subsystems/win32/win32k/objects/drawing.c
trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
trunk/reactos/subsystems/win32/win32k/objects/polyfill.c
Modified: trunk/reactos/subsystems/win32/win32k/include/paint.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/paint.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/paint.h [iso-8859-1] Mon Mar 16 06:21:00
2009
@@ -3,5 +3,7 @@
BOOL APIENTRY FillSolid (SURFOBJ* Surface, RECTL* Dimensions, ULONG iColor);
BOOL APIENTRY FillPolygon ( DC* dc, SURFACE* pSurface, BRUSHOBJ* BrushObj, MIX RopMode,
CONST PPOINT Points, INT Count, RECTL BoundRect );
+BOOL FASTCALL IntFillPolygon(PDC dc, SURFACE *psurf, BRUSHOBJ *BrushObj,
+ CONST PPOINT Points, int Count, RECTL DestRect, POINTL *BrushOrigin);
#endif /* _WIN32K_PAINT_H */
Modified: trunk/reactos/subsystems/win32/win32k/objects/drawing.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/drawing.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/drawing.c [iso-8859-1] Mon Mar 16
06:21:00 2009
@@ -1337,26 +1337,10 @@
INT XLeft,
INT YLeft,
INT Width,
- INT Height)
-{
- BOOL ret;
- PDC_ATTR Dc_Attr;
- PGDIBRUSHOBJ FillBrushObj;
-
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
- FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
- if (NULL == FillBrushObj)
- {
- DPRINT1("FillEllipse Fail\n");
- SetLastWin32Error(ERROR_INTERNAL_ERROR);
- return FALSE;
- }
- ret = (BOOL)app_fill_ellipse(dc, rect( XLeft, YLeft, Width, Height), FillBrushObj);
-
- BRUSHOBJ_UnlockBrush(FillBrushObj);
- return ret;
+ INT Height,
+ PGDIBRUSHOBJ FillBrushObj)
+{
+ return (BOOL)app_fill_ellipse(dc, rect( XLeft, YLeft, Width, Height), FillBrushObj);
}
BOOL
@@ -1367,23 +1351,12 @@
INT Right,
INT Bottom,
INT Wellipse,
- INT Hellipse)
-{
- PDC_ATTR Dc_Attr;
- PGDIBRUSHOBJ FillBrushObj;
+ INT Hellipse,
+ PGDIBRUSHOBJ FillBrushObj)
+{
Rect r;
int rx, ry; /* radius in x and y directions */
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
- FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
- if (NULL == FillBrushObj)
- {
- DPRINT1("FillEllipse Fail\n");
- SetLastWin32Error(ERROR_INTERNAL_ERROR);
- return FALSE;
- }
// x y Width Height
r = rect( Left, Top, abs(Right-Left), abs(Bottom-Top));
rx = Wellipse/2;
@@ -1432,7 +1405,6 @@
app_fill_rect(dc, rect(r.x, r.y+ry+1, r.width, r.height-ry-ry), FillBrushObj,
FALSE);
}
- BRUSHOBJ_UnlockBrush(FillBrushObj);
return TRUE;
}
Modified: trunk/reactos/subsystems/win32/win32k/objects/fillshap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/fillshap.c [iso-8859-1] Mon Mar 16
06:21:00 2009
@@ -44,9 +44,9 @@
#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 IntFillEllipse( PDC dc, INT XLeft, INT YLeft, INT Width, INT Height,
PGDIBRUSHOBJ FillBrushObj);
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 IntFillRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT
Wellipse, INT Hellipse, PGDIBRUSHOBJ FillBrushObj);
BOOL FASTCALL IntDrawRoundRect( PDC dc, INT Left, INT Top, INT Right, INT Bottom, INT
Wellipse, INT Hellipse, PGDIBRUSHOBJ PenBrushObj);
BOOL FASTCALL
@@ -61,7 +61,10 @@
RECTL DestRect;
int CurrentPoint;
PDC_ATTR Dc_Attr;
-
+ POINTL BrushOrigin;
+// int Left;
+// int Top;
+
ASSERT(dc); // caller's responsibility to pass a valid dc
if (!Points || Count < 2 )
@@ -69,6 +72,16 @@
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return FALSE;
}
+
+/*
+ //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);
+ }
+*/
Dc_Attr = dc->pDc_Attr;
if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
@@ -111,8 +124,12 @@
/* Now fill the polygon with the current brush. */
if (FillBrushObj && !(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
{
+ BrushOrigin = *((PPOINTL)&FillBrushObj->ptOrigin);
+ BrushOrigin.x += dc->ptlDCOrig.x;
+ BrushOrigin.y += dc->ptlDCOrig.y;
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj,
dc->XlateBrush);
- ret = FillPolygon ( dc, psurf, &FillBrushInst.BrushObject,
ROP2_TO_MIX(Dc_Attr->jROP2), Points, Count, DestRect );
+ ret = IntFillPolygon (dc, psurf, &FillBrushInst.BrushObject, Points,
Count,
+ DestRect, &BrushOrigin);
}
if (FillBrushObj)
BRUSHOBJ_UnlockBrush(FillBrushObj);
@@ -213,6 +230,8 @@
BOOL ret = TRUE;
LONG PenWidth, PenOrigWidth;
LONG RadiusX, RadiusY, CenterX, CenterY;
+ PGDIBRUSHOBJ pFillBrushObj;
+ GDIBRUSHOBJ tmpFillBrushObj;
if ((Left == Right) || (Top == Bottom)) return TRUE;
@@ -303,11 +322,29 @@
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 = BRUSHOBJ_LockBrush(Dc_Attr->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);
+ BRUSHOBJ_UnlockBrush(pFillBrushObj);
+ }
+
if (ret)
ret = IntDrawEllipse( dc,
CenterX - RadiusX,
@@ -512,6 +549,7 @@
RECTL DestRect;
MIX Mix;
PDC_ATTR Dc_Attr;
+ POINTL BrushOrigin;
ASSERT ( dc ); // caller's responsibility to set this up
@@ -581,6 +619,9 @@
{
if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
{
+ BrushOrigin = *((PPOINTL)&FillBrushObj->ptOrigin);
+ BrushOrigin.x += dc->ptlDCOrig.x;
+ BrushOrigin.y += dc->ptlDCOrig.y;
IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj,
dc->XlateBrush);
ret = IntEngBitBlt(&psurf->SurfObj,
NULL,
@@ -591,7 +632,7 @@
NULL,
NULL,
&FillBrushInst.BrushObject,
- NULL,
+ &BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
}
}
@@ -697,6 +738,8 @@
RECTL RectBounds;
LONG PenWidth, PenOrigWidth;
BOOL ret = TRUE; // default to success
+ PGDIBRUSHOBJ pFillBrushObj;
+ GDIBRUSHOBJ tmpFillBrushObj;
ASSERT ( dc ); // caller's responsibility to set this up
@@ -763,13 +806,29 @@
RectBounds.right += dc->ptlDCOrig.x;
RectBounds.bottom += dc->ptlDCOrig.y;
- ret = IntFillRoundRect( dc,
- RectBounds.left,
- RectBounds.top,
- RectBounds.right,
- RectBounds.bottom,
- xCurveDiameter,
- yCurveDiameter);
+ pFillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
+ if (NULL == pFillBrushObj)
+ {
+ DPRINT1("FillRound 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;
+ ret = IntFillRoundRect( dc,
+ RectBounds.left,
+ RectBounds.top,
+ RectBounds.right,
+ RectBounds.bottom,
+ xCurveDiameter,
+ yCurveDiameter,
+ &tmpFillBrushObj);
+ BRUSHOBJ_UnlockBrush(pFillBrushObj);
+ }
+
if (ret)
ret = IntDrawRoundRect( dc,
RectBounds.left,
@@ -1048,95 +1107,93 @@
COLORREF Color,
UINT FillType)
{
- PDC dc;
- PDC_ATTR Dc_Attr;
- SURFACE *psurf = NULL;
- PGDIBRUSHOBJ FillBrushObj = NULL;
- GDIBRUSHINST FillBrushInst;
- BOOL Ret = FALSE;
- RECTL DestRect;
- POINTL Pt;
-// MIX Mix;
-
- DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
-
- 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;
- }
-
- Dc_Attr = dc->pDc_Attr;
- if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
-
- if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY)
- IntGdiSelectPen(dc,Dc_Attr->hpen);
-
- if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY)
- IntGdiSelectBrush(dc,Dc_Attr->hbrush);
-
- Pt.x = XStart;
- Pt.y = YStart;
- IntLPtoDP(dc, (LPPOINT)&Pt, 1);
-
- Ret = NtGdiPtInRegion(dc->w.hGCClipRgn, Pt.x, Pt.y);
- if (Ret)
- IntGdiGetRgnBox(dc->w.hGCClipRgn,(LPRECT)&DestRect);
- else
- goto cleanup;
-
- FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
- if (!FillBrushObj)
- {
- Ret = FALSE;
- goto cleanup;
- }
- psurf = SURFACE_LockSurface(dc->w.hBitmap);
- if (!psurf)
- {
- Ret = FALSE;
- goto cleanup;
- }
-
- if ( FillBrushObj && (FillType == FLOODFILLBORDER))
- {
- if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
- {
- FillBrushObj->BrushAttr.lbColor = Color;
- IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj, dc->XlateBrush);
- Ret = IntEngBitBlt(&psurf->SurfObj,
- NULL,
- NULL,
- dc->CombinedClip,
- NULL,
- &DestRect,
- NULL,
- NULL,
+ PDC dc;
+ PDC_ATTR Dc_Attr;
+ SURFACE *psurf = NULL;
+ PGDIBRUSHOBJ FillBrushObj = NULL;
+ GDIBRUSHINST FillBrushInst;
+ BOOL Ret = FALSE;
+ RECTL DestRect;
+ POINTL Pt;
+ POINTL BrushOrigin;
+
+ DPRINT1("FIXME: NtGdiExtFloodFill is UNIMPLEMENTED\n");
+
+ 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;
+ }
+
+ Dc_Attr = dc->pDc_Attr;
+ if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+
+ if (Dc_Attr->ulDirty_ & DC_PEN_DIRTY)
+ IntGdiSelectPen(dc,Dc_Attr->hpen);
+
+ if (Dc_Attr->ulDirty_ & DC_BRUSH_DIRTY)
+ IntGdiSelectBrush(dc,Dc_Attr->hbrush);
+
+ Pt.x = XStart;
+ Pt.y = YStart;
+ IntLPtoDP(dc, (LPPOINT)&Pt, 1);
+
+ Ret = NtGdiPtInRegion(dc->w.hGCClipRgn, Pt.x, Pt.y);
+ if (Ret)
+ IntGdiGetRgnBox(dc->w.hGCClipRgn,(LPRECT)&DestRect);
+ else
+ goto cleanup;
+
+ FillBrushObj = BRUSHOBJ_LockBrush(Dc_Attr->hbrush);
+ if (!FillBrushObj)
+ {
+ Ret = FALSE;
+ goto cleanup;
+ }
+ psurf = SURFACE_LockSurface(dc->w.hBitmap);
+ if (!psurf)
+ {
+ Ret = FALSE;
+ goto cleanup;
+ }
+
+ if ( FillBrushObj && (FillType == FLOODFILLBORDER))
+ {
+ if (!(FillBrushObj->flAttrs & GDIBRUSH_IS_NULL))
+ {
+ FillBrushObj->BrushAttr.lbColor = Color;
+ BrushOrigin = *((PPOINTL)&FillBrushObj->ptOrigin);
+ BrushOrigin.x += dc->ptlDCOrig.x;
+ BrushOrigin.y += dc->ptlDCOrig.y;
+ IntGdiInitBrushInstance(&FillBrushInst, FillBrushObj,
dc->XlateBrush);
+ Ret = IntEngBitBlt(&psurf->SurfObj, NULL, NULL,
+ dc->CombinedClip, NULL,
+ &DestRect, NULL, NULL,
&FillBrushInst.BrushObject,
- NULL,
+ &BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
- }
- }
- else
- {
- }
+ }
+ }
+ else
+ {
+ }
cleanup:
- if (FillBrushObj)
- BRUSHOBJ_UnlockBrush(FillBrushObj);
-
- if (psurf)
- SURFACE_UnlockSurface(psurf);
-
- DC_UnlockDc(dc);
- return Ret;
+ if (FillBrushObj)
+ BRUSHOBJ_UnlockBrush(FillBrushObj);
+
+ if (psurf)
+ SURFACE_UnlockSurface(psurf);
+
+ DC_UnlockDc(dc);
+ return Ret;
}
/* EOF */
Modified: trunk/reactos/subsystems/win32/win32k/objects/polyfill.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/polyfill.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/polyfill.c [iso-8859-1] Mon Mar 16
06:21:00 2009
@@ -600,4 +600,76 @@
return TRUE;
}
+
+BOOL FASTCALL
+IntFillPolygon(
+ PDC dc,
+ SURFACE *psurf,
+ BRUSHOBJ *BrushObj,
+ CONST PPOINT Points,
+ int Count,
+ RECTL DestRect,
+ POINTL *BrushOrigin)
+{
+ FILL_EDGE_LIST *list = 0;
+ FILL_EDGE *ActiveHead = 0;
+ FILL_EDGE *pLeft, *pRight;
+ int ScanLine;
+
+ //DPRINT("IntFillPolygon\n");
+
+ /* Create Edge List. */
+ list = POLYGONFILL_MakeEdgeList(Points, Count);
+ /* DEBUG_PRINT_EDGELIST(list); */
+ if (NULL == list)
+ return FALSE;
+
+ /* For each Scanline from DestRect.top to DestRect.bottom, determine line segments to
draw */
+ for ( ScanLine = DestRect.top; ScanLine < DestRect.bottom; ++ScanLine )
+ {
+ POLYGONFILL_BuildActiveList(ScanLine, list, &ActiveHead);
+ //DEBUG_PRINT_ACTIVE_EDGELIST(ActiveHead);
+
+ if ( !ActiveHead )
+ return FALSE;
+
+ pLeft = ActiveHead;
+ pRight = pLeft->pNext;
+ ASSERT(pRight);
+
+ while ( NULL != pRight )
+ {
+ int x1 = pLeft->XIntercept[0];
+ int x2 = pRight->XIntercept[1];
+ if ( x2 > x1 )
+ {
+ RECTL LineRect;
+ LineRect.top = ScanLine;
+ LineRect.bottom = ScanLine + 1;
+ LineRect.left = x1;
+ LineRect.right = x2;
+
+ IntEngBitBlt(&psurf->SurfObj,
+ NULL,
+ NULL,
+ dc->CombinedClip,
+ NULL,
+ &LineRect,
+ NULL,
+ NULL,
+ BrushObj,
+ BrushOrigin,
+ ROP3_TO_ROP4(PATCOPY));
+ }
+ pLeft = pRight->pNext;
+ pRight = pLeft ? pLeft->pNext : NULL;
+ }
+ }
+
+ /* Free Edge List. If any are left. */
+ POLYGONFILL_DestroyEdgeList(list);
+
+ return TRUE;
+}
+
/* EOF */