2 #undef WIN32_LEAN_AND_MEAN
5 #include <win32k/fillshap.h>
7 #include <win32k/pen.h>
8 #include <include/object.h>
9 #include <include/inteng.h>
12 #include <win32k/debug1.h>
55 //ALTERNATE Selects alternate mode (fills the area between odd-numbered and even-numbered
56 //polygon sides on each scan line).
57 //When the fill mode is ALTERNATE, GDI fills the area between odd-numbered and
58 //even-numbered polygon sides on each scan line. That is, GDI fills the area between the
59 //first and second side, between the third and fourth side, and so on.
60 extern BOOL FillPolygon_ALTERNATE(SURFOBJ *SurfObj,
70 //WINDING Selects winding mode (fills any region with a nonzero winding value).
71 //When the fill mode is WINDING, GDI fills any region that has a nonzero winding value.
72 //This value is defined as the number of times a pen used to draw the polygon would go around the region.
73 //The direction of each edge of the polygon is important.
74 extern BOOL FillPolygon_WINDING(SURFOBJ *SurfObj,
75 PBRUSHOBJ BrushObj,MIX RopMode,
82 //This implementation is blatantly ripped off from W32kRectangle
89 DC *dc = DC_HandleToPtr(hDC);
90 SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
91 PBRUSHOBJ OutBrushObj, FillBrushObj;
98 DPRINT("In W32kPolygon()\n");
109 RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
110 //ei not yet implemented ASSERT(RectBounds);
112 DestRect.bottom = Points[0].y + dc->w.DCOrgY + 1;
113 DestRect.top = Points[0].y + dc->w.DCOrgY;
114 DestRect.right = Points[0].y + dc->w.DCOrgX;
115 DestRect.left = Points[0].y + dc->w.DCOrgX + 1;
119 if(PATH_IsPathOpen(dc->w.path))
121 ret = PATH_Polygon(hDC, Points, Count);
125 //Get the current pen.
126 pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
128 OutBrushObj = (PBRUSHOBJ)PenToBrushObj(dc, pen);
129 GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC );
131 // Draw the Polygon Edges with the current pen
132 for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint)
134 DestRect.bottom = MAX(DestRect.bottom, Points[CurrentPoint].y + dc->w.DCOrgY);
135 DestRect.top = MIN(DestRect.top, Points[CurrentPoint].y + dc->w.DCOrgY);
136 DestRect.right = MAX(DestRect.right, Points[CurrentPoint].y + dc->w.DCOrgX);
137 DestRect.left = MIN(DestRect.left, Points[CurrentPoint].y + dc->w.DCOrgX);
140 //Now fill the polygon with the current brush.
141 FillBrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
142 // determine the fill mode to fill the polygon.
143 if (dc->w.polyFillMode == WINDING)
144 ret = FillPolygon_WINDING(SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect, dc->w.DCOrgX, dc->w.DCOrgY);
146 ret = FillPolygon_ALTERNATE(SurfObj, FillBrushObj, dc->w.ROPmode, Points, Count, DestRect, dc->w.DCOrgX, dc->w.DCOrgY);
147 // Draw the Polygon Edges with the current pen
148 for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint)
151 //Let CurrentPoint be i
152 //if i+1 > Count, Draw a line from Points[i] to Points[0]
153 //Draw a line from Points[i] to Points[i+1]
154 if (CurrentPoint + 1 >= Count)
156 To = Points[CurrentPoint];
161 From = Points[CurrentPoint];
162 To = Points[CurrentPoint + 1];
164 DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y );
165 ret = EngLineTo(SurfObj,
168 From.x + dc->w.DCOrgX,
169 From.y + dc->w.DCOrgY,
172 RectBounds, // Bounding rectangle
173 dc->w.ROPmode); // MIX
176 GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC );
179 GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
180 DC_ReleasePtr( hDC );
187 W32kPolyPolygon(HDC hDC,
188 CONST LPPOINT Points,
189 CONST LPINT PolyCounts,
197 W32kRectangle(HDC hDC,
203 DC *dc = DC_HandleToPtr(hDC);
204 SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
214 RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
215 //ei not yet implemented ASSERT(RectBounds);
217 if(PATH_IsPathOpen(dc->w.path)) {
218 ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
220 // Draw the rectangle with the current pen
221 pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
223 BrushObj = (PBRUSHOBJ)PenToBrushObj(dc, pen);
224 GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC );
226 LeftRect += dc->w.DCOrgX;
227 RightRect += dc->w.DCOrgX;
228 TopRect += dc->w.DCOrgY;
229 BottomRect += dc->w.DCOrgY;
231 ret = IntEngLineTo(SurfObj,
234 LeftRect, TopRect, RightRect, TopRect,
235 RectBounds, // Bounding rectangle
236 dc->w.ROPmode); // MIX
238 ret = IntEngLineTo(SurfObj,
241 RightRect, TopRect, RightRect, BottomRect,
242 RectBounds, // Bounding rectangle
243 dc->w.ROPmode); // MIX
245 ret = IntEngLineTo(SurfObj,
248 LeftRect, BottomRect, RightRect, BottomRect,
249 RectBounds, // Bounding rectangle
250 dc->w.ROPmode); // MIX
252 ret = IntEngLineTo(SurfObj,
255 LeftRect, TopRect, LeftRect, BottomRect,
256 RectBounds, // Bounding rectangle
257 dc->w.ROPmode); // MIX */
259 // FIXME: BrushObj is obtained above; decide which one is correct
260 BrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
264 if (BrushObj->logbrush.lbStyle != BS_NULL)
266 DestRect.left = LeftRect + 1;
267 DestRect.right = RightRect - 1;
268 DestRect.top = TopRect + 1;
269 DestRect.bottom = BottomRect - 1;
270 ret = EngBitBlt(SurfObj,
283 GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC );
286 // FIXME: Move current position in DC?
287 GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
288 DC_ReleasePtr( hDC );
294 W32kRoundRect(HDC hDC,