update for HEAD-2003050101
[reactos.git] / 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 }