d387975e7cbfb9d6ccb6ee56f354d6760b63701e
[reactos.git] / reactos / subsys / win32k / objects / fillshap.c
1
2 #undef WIN32_LEAN_AND_MEAN
3 #include <windows.h>
4 #include <ddk/ntddk.h>
5 #include <win32k/fillshap.h>
6 #include <win32k/dc.h>
7 #include <win32k/pen.h>
8 #include <include/object.h>
9 #include <include/inteng.h>
10
11 #define NDEBUG
12 #include <win32k/debug1.h>
13
14 BOOL
15 STDCALL
16 W32kChord(HDC hDC,
17 int LeftRect,
18 int TopRect,
19 int RightRect,
20 int BottomRect,
21 int XRadial1,
22 int YRadial1,
23 int XRadial2,
24 int YRadial2)
25 {
26 UNIMPLEMENTED;
27 }
28
29 BOOL
30 STDCALL
31 W32kEllipse(HDC hDC,
32 int LeftRect,
33 int TopRect,
34 int RightRect,
35 int BottomRect)
36 {
37 UNIMPLEMENTED;
38 }
39
40 BOOL
41 STDCALL
42 W32kPie(HDC hDC,
43 int LeftRect,
44 int TopRect,
45 int RightRect,
46 int BottomRect,
47 int XRadial1,
48 int YRadial1,
49 int XRadial2,
50 int YRadial2)
51 {
52 UNIMPLEMENTED;
53 }
54
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,
61 PBRUSHOBJ BrushObj,
62 MIX RopMode,
63 CONST PPOINT Points,
64 int Count,
65 RECTL BoundRect,
66 int OrigX,
67 int OrigY);
68
69
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,
76 CONST PPOINT Points,
77 int Count,
78 RECTL BoundRect,
79 int OrigX,
80 int OrigY);
81
82 //This implementation is blatantly ripped off from W32kRectangle
83 BOOL
84 STDCALL
85 W32kPolygon(HDC hDC,
86 CONST PPOINT Points,
87 int Count)
88 {
89 DC *dc = DC_HandleToPtr(hDC);
90 SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
91 PBRUSHOBJ OutBrushObj, FillBrushObj;
92 BOOL ret;
93 PRECTL RectBounds;
94 PENOBJ *pen;
95 RECTL DestRect;
96 int CurrentPoint;
97
98 DPRINT("In W32kPolygon()\n");
99
100 if(0 == dc)
101 return FALSE;
102
103 if(0 == Points)
104 return FALSE;
105
106 if (2 > Count)
107 return FALSE;
108
109 RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
110 //ei not yet implemented ASSERT(RectBounds);
111
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;
116
117
118
119 if(PATH_IsPathOpen(dc->w.path))
120 {
121 ret = PATH_Polygon(hDC, Points, Count);
122 }
123 else
124 {
125 //Get the current pen.
126 pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
127 ASSERT(pen);
128 OutBrushObj = (PBRUSHOBJ)PenToBrushObj(dc, pen);
129 GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC );
130
131 // Draw the Polygon Edges with the current pen
132 for (CurrentPoint = 0; CurrentPoint < Count; ++CurrentPoint)
133 {
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);
138 }//for
139
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);
145 else//default
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)
149 {
150 POINT To,From;
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)
155 {
156 To = Points[CurrentPoint];
157 From = Points[0];
158 }
159 else
160 {
161 From = Points[CurrentPoint];
162 To = Points[CurrentPoint + 1];
163 }
164 DPRINT("Polygon Making line from (%d,%d) to (%d,%d)\n", From.x, From.y, To.x, To.y );
165 ret = EngLineTo(SurfObj,
166 NULL, // ClipObj,
167 OutBrushObj,
168 From.x + dc->w.DCOrgX,
169 From.y + dc->w.DCOrgY,
170 To.x + dc->w.DCOrgX,
171 To.y + dc->w.DCOrgY,
172 RectBounds, // Bounding rectangle
173 dc->w.ROPmode); // MIX
174
175 }//for
176 GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC );
177 }// else
178
179 GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
180 DC_ReleasePtr( hDC );
181 return ret;
182 }
183
184
185 BOOL
186 STDCALL
187 W32kPolyPolygon(HDC hDC,
188 CONST LPPOINT Points,
189 CONST LPINT PolyCounts,
190 int Count)
191 {
192 UNIMPLEMENTED;
193 }
194
195 BOOL
196 STDCALL
197 W32kRectangle(HDC hDC,
198 int LeftRect,
199 int TopRect,
200 int RightRect,
201 int BottomRect)
202 {
203 DC *dc = DC_HandleToPtr(hDC);
204 SURFOBJ *SurfObj = (SURFOBJ*)AccessUserObject((ULONG)dc->Surface);
205 PBRUSHOBJ BrushObj;
206 BOOL ret;
207 PRECTL RectBounds;
208 PENOBJ * pen;
209 RECTL DestRect;
210
211 if(!dc)
212 return FALSE;
213
214 RectBounds = GDIOBJ_LockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
215 //ei not yet implemented ASSERT(RectBounds);
216
217 if(PATH_IsPathOpen(dc->w.path)) {
218 ret = PATH_Rectangle(hDC, LeftRect, TopRect, RightRect, BottomRect);
219 } else {
220 // Draw the rectangle with the current pen
221 pen = (PENOBJ*) GDIOBJ_LockObj(dc->w.hPen, GO_PEN_MAGIC);
222 ASSERT(pen);
223 BrushObj = (PBRUSHOBJ)PenToBrushObj(dc, pen);
224 GDIOBJ_UnlockObj( dc->w.hPen, GO_PEN_MAGIC );
225
226 LeftRect += dc->w.DCOrgX;
227 RightRect += dc->w.DCOrgX;
228 TopRect += dc->w.DCOrgY;
229 BottomRect += dc->w.DCOrgY;
230
231 ret = IntEngLineTo(SurfObj,
232 NULL, // ClipObj,
233 BrushObj,
234 LeftRect, TopRect, RightRect, TopRect,
235 RectBounds, // Bounding rectangle
236 dc->w.ROPmode); // MIX
237
238 ret = IntEngLineTo(SurfObj,
239 NULL, // ClipObj,
240 BrushObj,
241 RightRect, TopRect, RightRect, BottomRect,
242 RectBounds, // Bounding rectangle
243 dc->w.ROPmode); // MIX
244
245 ret = IntEngLineTo(SurfObj,
246 NULL, // ClipObj,
247 BrushObj,
248 LeftRect, BottomRect, RightRect, BottomRect,
249 RectBounds, // Bounding rectangle
250 dc->w.ROPmode); // MIX
251
252 ret = IntEngLineTo(SurfObj,
253 NULL, // ClipObj,
254 BrushObj,
255 LeftRect, TopRect, LeftRect, BottomRect,
256 RectBounds, // Bounding rectangle
257 dc->w.ROPmode); // MIX */
258
259 // FIXME: BrushObj is obtained above; decide which one is correct
260 BrushObj = (BRUSHOBJ*) GDIOBJ_LockObj(dc->w.hBrush, GO_BRUSH_MAGIC);
261
262 if (BrushObj)
263 {
264 if (BrushObj->logbrush.lbStyle != BS_NULL)
265 {
266 DestRect.left = LeftRect + 1;
267 DestRect.right = RightRect - 1;
268 DestRect.top = TopRect + 1;
269 DestRect.bottom = BottomRect - 1;
270 ret = EngBitBlt(SurfObj,
271 NULL,
272 NULL,
273 NULL,
274 NULL,
275 &DestRect,
276 NULL,
277 NULL,
278 BrushObj,
279 NULL,
280 PATCOPY);
281 }
282 }
283 GDIOBJ_UnlockObj( dc->w.hBrush, GO_BRUSH_MAGIC );
284 }
285
286 // FIXME: Move current position in DC?
287 GDIOBJ_UnlockObj(dc->w.hGCClipRgn, GO_REGION_MAGIC);
288 DC_ReleasePtr( hDC );
289 return TRUE;
290 }
291
292 BOOL
293 STDCALL
294 W32kRoundRect(HDC hDC,
295 int LeftRect,
296 int TopRect,
297 int RightRect,
298 int BottomRect,
299 int Width,
300 int Height)
301 {
302 UNIMPLEMENTED;
303 }