DIB Engine: implement most engine functions
[wine/hacks.git] / dlls / winedib.drv / graphics.c
blob8dda082eac06b76258fea203444239b51b1d4225
1 /*
2 * DIBDRV implementation of GDI driver graphics functions
4 * Copyright 2009 Massimo Del Fedele
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include "dibdrv.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv);
28 static inline void OrderInt(int *i1, int *i2)
30 if(*i1 > *i2)
32 int tmp;
33 tmp = *i1;
34 *i1 = *i2;
35 *i2 = tmp;
39 /***********************************************************************
40 * DIBDRV_Arc
42 BOOL DIBDRV_Arc( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
43 int xstart, int ystart, int xend, int yend )
45 BOOL res;
47 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
48 physDev, left, top, right, bottom, xstart, ystart, xend, yend));
50 if(physDev->hasDIB)
52 /* DIB section selected in, use DIB Engine */
53 ONCE(FIXME("STUB\n"));
54 res = TRUE;
56 else
58 /* DDB selected in, use X11 driver */
59 res = _DIBDRV_GetDisplayDriver()->pArc(physDev->X11PhysDev, left, top, right, bottom,
60 xstart, ystart, xend, yend);
62 return res;
65 /***********************************************************************
66 * DIBDRV_Chord
68 BOOL DIBDRV_Chord( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
69 int xstart, int ystart, int xend, int yend )
71 BOOL res;
73 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
74 physDev, left, top, right, bottom, xstart, ystart, xend, yend));
76 if(physDev->hasDIB)
78 /* DIB section selected in, use DIB Engine */
79 ONCE(FIXME("STUB\n"));
80 res = TRUE;
82 else
84 /* DDB selected in, use X11 driver */
85 res = _DIBDRV_GetDisplayDriver()->pChord(physDev->X11PhysDev, left, top, right, bottom,
86 xstart, ystart, xend, yend);
88 return res;
91 /***********************************************************************
92 * DIBDRV_Ellipse
94 BOOL DIBDRV_Ellipse( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom )
96 BOOL res;
98 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n",
99 physDev, left, top, right, bottom));
101 if(physDev->hasDIB)
103 /* DIB section selected in, use DIB Engine */
104 ONCE(FIXME("STUB\n"));
105 res = TRUE;
107 else
109 /* DDB selected in, use X11 driver */
110 res = _DIBDRV_GetDisplayDriver()->pEllipse(physDev->X11PhysDev, left, top, right, bottom);
112 return res;
115 /**********************************************************************
116 * DIBDRV_ExtFloodFill
118 BOOL DIBDRV_ExtFloodFill( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color,
119 UINT fillType )
121 BOOL res;
123 MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n",
124 physDev, x, y, color, fillType));
126 if(physDev->hasDIB)
128 /* DIB section selected in, use DIB Engine */
129 ONCE(FIXME("STUB\n"));
130 res = TRUE;
132 else
134 /* DDB selected in, use X11 driver */
135 res = _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev->X11PhysDev, x, y, color, fillType);
137 return res;
140 /***********************************************************************
141 * DIBDRV_GetDCOrgEx
143 BOOL DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV *physDev, LPPOINT lpp )
145 BOOL res;
147 MAYBE(TRACE("physDev:%p, lpp:%p\n", physDev, lpp));
149 if(physDev->hasDIB)
151 /* DIB section selected in, use DIB Engine */
152 ONCE(FIXME("STUB\n"));
153 res = TRUE;
155 else
157 /* DDB selected in, use X11 driver */
158 res = _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev->X11PhysDev, lpp);
160 return res;
163 /***********************************************************************
164 * DIBDRV_GetPixel
166 COLORREF DIBDRV_GetPixel( DIBDRVPHYSDEV *physDev, int x, int y )
168 COLORREF res;
170 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
172 if(physDev->hasDIB)
174 res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y);
176 else
178 /* DDB selected in, use X11 driver */
179 res = _DIBDRV_GetDisplayDriver()->pGetPixel(physDev->X11PhysDev, x, y);
181 return res;
184 /***********************************************************************
185 * DIBDRV_LineTo
187 BOOL DIBDRV_LineTo( DIBDRVPHYSDEV *physDev, int x, int y )
189 BOOL res;
190 POINT curPos;
192 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
194 if(physDev->hasDIB)
196 GetCurrentPositionEx(physDev->hdc, &curPos);
198 _DIBDRV_ResetDashOrigin(physDev);
200 if(curPos.y == y)
201 physDev->penHLine(physDev, curPos.x, x, y);
202 else if(curPos.x == x)
203 physDev->penVLine(physDev, x, curPos.y, y);
204 else
205 physDev->penLine(physDev, curPos.x, curPos.y, x, y);
206 res = TRUE;
208 else
210 /* DDB selected in, use X11 driver */
211 res = _DIBDRV_GetDisplayDriver()->pLineTo(physDev->X11PhysDev, x, y);
213 return res;
216 /***********************************************************************
217 * DIBDRV_PaintRgn
219 BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom);
220 BOOL DIBDRV_PaintRgn( DIBDRVPHYSDEV *physDev, HRGN hrgn )
222 BOOL res = FALSE;
223 int i;
224 RECT *rect;
225 RGNDATA *data;
226 int size;
228 MAYBE(TRACE("physDev:%p, hrgn:%p\n", physDev, hrgn));
230 if(physDev->hasDIB)
232 /* gets needed region data size */
233 if(!(size = GetRegionData(hrgn, 0, NULL)))
234 goto fin;
236 /* allocates buffer and gets actual region data */
237 if(!(data = HeapAlloc(GetProcessHeap(), 0, size)))
238 goto fin;
239 if(!GetRegionData(hrgn, size, data))
241 HeapFree(GetProcessHeap(), 0, data);
242 goto fin;
245 /* paints the filled rectangles */
246 rect = (RECT *)data->Buffer;
247 for(i = 0; i < data->rdh.nCount; i++)
249 DIBDRV_Rectangle( physDev, rect->left, rect->top, rect->right, rect->bottom);
250 rect++;
252 HeapFree( GetProcessHeap(), 0, data );
253 res = TRUE;
254 fin:
257 else
259 /* DDB selected in, use X11 driver */
260 res = _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev->X11PhysDev, hrgn);
262 return res;
265 /***********************************************************************
266 * DIBDRV_Pie
268 BOOL DIBDRV_Pie( DIBDRVPHYSDEV *physDev, int left, int top, int right, int bottom,
269 int xstart, int ystart, int xend, int yend )
271 BOOL res;
273 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
274 physDev, left, top, right, bottom, xstart, ystart, xend, yend));
276 if(physDev->hasDIB)
278 /* DIB section selected in, use DIB Engine */
279 ONCE(FIXME("STUB\n"));
280 res = TRUE;
282 else
284 /* DDB selected in, use X11 driver */
285 res = _DIBDRV_GetDisplayDriver()->pPie(physDev->X11PhysDev, left, top, right, bottom,
286 xstart, ystart, xend, yend);
288 return res;
291 /**********************************************************************
292 * DIBDRV_Polygon
294 BOOL DIBDRV_Polygon( DIBDRVPHYSDEV *physDev, const POINT* pt, int count )
296 BOOL res;
298 MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count));
300 if(physDev->hasDIB)
302 /* DIB section selected in, use DIB Engine */
303 ONCE(FIXME("STUB\n"));
304 res = TRUE;
306 else
308 /* DDB selected in, use X11 driver */
309 res = _DIBDRV_GetDisplayDriver()->pPolygon(physDev->X11PhysDev, pt, count);
311 return res;
314 /**********************************************************************
315 * DIBDRV_Polyline
317 BOOL DIBDRV_Polyline( DIBDRVPHYSDEV *physDev, const POINT* pt, int count )
319 BOOL res;
321 MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev, pt, count));
323 if(physDev->hasDIB)
325 /* DIB section selected in, use DIB Engine */
326 ONCE(FIXME("STUB\n"));
327 res = TRUE;
329 else
331 /* DDB selected in, use X11 driver */
332 res = _DIBDRV_GetDisplayDriver()->pPolyline(physDev->X11PhysDev, pt, count);
334 return res;
337 /**********************************************************************
338 * DIBDRV_PolyPolygon
340 BOOL DIBDRV_PolyPolygon( DIBDRVPHYSDEV *physDev, const POINT* pt, const int* counts, UINT polygons)
342 BOOL res;
344 MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev, pt, counts, polygons));
346 if(physDev->hasDIB)
348 /* DIB section selected in, use DIB Engine */
349 ONCE(FIXME("STUB\n"));
350 res = TRUE;
352 else
354 /* DDB selected in, use X11 driver */
355 res = _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev->X11PhysDev, pt, counts, polygons);
357 return res;
360 /**********************************************************************
361 * DIBDRV_PolyPolyline
363 BOOL DIBDRV_PolyPolyline( DIBDRVPHYSDEV *physDev, const POINT* pt, const DWORD* counts,
364 DWORD polylines )
366 BOOL res;
368 MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev, pt, counts, polylines));
370 if(physDev->hasDIB)
372 /* DIB section selected in, use DIB Engine */
373 ONCE(FIXME("STUB\n"));
374 res = TRUE;
376 else
378 /* DDB selected in, use X11 driver */
379 res = _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev->X11PhysDev, pt, counts, polylines);
381 return res;
384 /***********************************************************************
385 * DIBDRV_Rectangle
387 BOOL DIBDRV_Rectangle( DIBDRVPHYSDEV *physDev, int x1, int y1, int x2, int y2)
389 BOOL res = TRUE;
390 int i;
391 DIBDRVBITMAP *bmp = &physDev->physBitmap;
393 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", physDev, x1, y1, x2, y2));
395 if(physDev->hasDIB)
397 OrderInt(&x1, &x2);
398 OrderInt(&y1, &y2);
400 /* temporary fix.... should be done by clipping */
401 if(x1 < 0) x1 = 0;
402 if(x2 < 0) x2 = 0;
403 if(y1 < 0) y1 = 0;
404 if(y2 < 0) y2 = 0;
405 if(x1 >= bmp->width) x1 = bmp->width - 1;
406 if(y1 >= bmp->height) y1 = bmp->height - 1;
407 if(x2 > bmp->width) x2 = bmp->width;
408 if(y2 > bmp->height) y2 = bmp->height ;
409 if(x1 >= x2 || y1 >= y2)
410 goto fin;
412 _DIBDRV_ResetDashOrigin(physDev);
414 /* particular case where the rectangle
415 degenerates to a line or a point */
416 if(x1 >= x2 - 1)
418 physDev->penVLine(physDev, x1, y1, y2);
419 goto fin;
421 else if (y1 >= y2 -1)
423 physDev->penHLine(physDev, x1, x2, y1);
424 goto fin;
427 /* Draw the perimeter */
428 physDev->penHLine(physDev, x1 , x2 , y1 );
429 physDev->penHLine(physDev, x1 , x2 , y2 - 1);
430 physDev->penVLine(physDev, x1 , y1 + 1, y2 - 1);
431 physDev->penVLine(physDev, x2 - 1, y1 + 1, y2 - 1);
433 /* fill the inside */
434 if(x2 >= x1 + 2)
435 for (i = y1 + 1; i < y2 - 1; i++)
436 physDev->brushHLine(physDev, x1 + 1, x2 - 1, i);
438 res = TRUE;
439 fin:
442 else
444 /* DDB selected in, use X11 driver */
445 res = _DIBDRV_GetDisplayDriver()->pRectangle(physDev->X11PhysDev, x1, y1, x2, y2);
447 return res;
450 /***********************************************************************
451 * DIBDRV_RoundRect
453 BOOL DIBDRV_RoundRect( DIBDRVPHYSDEV *physDev, int left, int top, int right,
454 int bottom, int ell_width, int ell_height )
456 BOOL res;
458 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, ell_width:%d, ell_height:%d\n",
459 physDev, left, top, right, bottom, ell_width, ell_height));
461 if(physDev->hasDIB)
463 /* DIB section selected in, use DIB Engine */
464 ONCE(FIXME("STUB\n"));
465 res = TRUE;
467 else
469 /* DDB selected in, use X11 driver */
470 res = _DIBDRV_GetDisplayDriver()->pRoundRect(physDev->X11PhysDev, left, top, right, bottom,
471 ell_width, ell_height);
473 return res;
476 /***********************************************************************
477 * DIBDRV_SetPixel
479 COLORREF DIBDRV_SetPixel( DIBDRVPHYSDEV *physDev, int x, int y, COLORREF color )
481 COLORREF res;
482 DWORD and, xor;
484 MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev, x, y, color));
486 if(physDev->hasDIB)
488 /* gets previous pixel */
489 res = physDev->physBitmap.funcs->GetPixel(&physDev->physBitmap, x, y);
491 /* calculates AND and XOR from color */
492 _DIBDRV_CalcAndXorMasks(GetROP2(physDev->hdc), color, &and, &xor);
494 /* sets the pixel */
495 physDev->physBitmap.funcs->SetPixel(&physDev->physBitmap, x, y, and, xor);
497 else
499 /* DDB selected in, use X11 driver */
500 res = _DIBDRV_GetDisplayDriver()->pSetPixel(physDev->X11PhysDev, x, y, color);
502 return res;
505 /***********************************************************************
506 * DIBDRV_SetDCOrg
508 DWORD DIBDRV_SetDCOrg( DIBDRVPHYSDEV *physDev, int x, int y )
510 DWORD res;
512 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev, x, y));
514 if(physDev->hasDIB)
516 /* DIB section selected in, use DIB Engine */
517 ONCE(FIXME("STUB\n"));
518 res = 0;
520 else
522 /* DDB selected in, use X11 driver */
523 res = _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev->X11PhysDev, x, y);
525 return res;