Release 940405
[wine/gsoc-2012-control.git] / windows / graphics.c
blobfb3e580d23a9e0907addaa687aebc381db477923
1 /*
2 * GDI graphics operations
4 * Copyright 1993 Alexandre Julliard
5 */
7 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
9 #include <math.h>
10 #include <stdlib.h>
11 #include <X11/Xlib.h>
12 #include <X11/Xutil.h>
13 #include <X11/Intrinsic.h>
14 #ifndef PI
15 #define PI M_PI
16 #endif
18 #include "gdi.h"
20 extern int COLOR_ToPhysical( DC *dc, COLORREF color );
22 /***********************************************************************
23 * LineTo (GDI.19)
25 BOOL LineTo( HDC hdc, short x, short y )
27 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
28 if (!dc) return FALSE;
29 if (DC_SetupGCForPen( dc ))
30 XDrawLine(XT_display, dc->u.x.drawable, dc->u.x.gc,
31 dc->w.DCOrgX + XLPTODP( dc, dc->w.CursPosX ),
32 dc->w.DCOrgY + YLPTODP( dc, dc->w.CursPosY ),
33 dc->w.DCOrgX + XLPTODP( dc, x ),
34 dc->w.DCOrgY + YLPTODP( dc, y ) );
35 dc->w.CursPosX = x;
36 dc->w.CursPosY = y;
37 return TRUE;
41 /***********************************************************************
42 * MoveTo (GDI.20)
44 DWORD MoveTo( HDC hdc, short x, short y )
46 POINT pt;
47 if (MoveToEx( hdc, x, y, &pt )) return pt.x | (pt.y << 16);
48 else return 0;
52 /***********************************************************************
53 * MoveToEx (GDI.483)
55 BOOL MoveToEx( HDC hdc, short x, short y, LPPOINT pt )
57 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
58 if (!dc) return FALSE;
59 if (pt)
61 pt->x = dc->w.CursPosX;
62 pt->y = dc->w.CursPosY;
64 dc->w.CursPosX = x;
65 dc->w.CursPosY = y;
66 return TRUE;
70 /***********************************************************************
71 * GRAPH_DrawArc
73 * Helper functions for Arc(), Chord() and Pie().
74 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
76 BOOL GRAPH_DrawArc( HDC hdc, int left, int top, int right, int bottom,
77 int xstart, int ystart, int xend, int yend, int lines )
79 int xcenter, ycenter;
80 double start_angle, end_angle, diff_angle;
81 XPoint points[3];
82 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
83 if (!dc) return FALSE;
85 left = XLPTODP( dc, left );
86 top = YLPTODP( dc, top );
87 right = XLPTODP( dc, right );
88 bottom = YLPTODP( dc, bottom );
89 xstart = XLPTODP( dc, xstart );
90 ystart = YLPTODP( dc, ystart );
91 xend = XLPTODP( dc, xend );
92 yend = YLPTODP( dc, yend );
93 if ((left == right) || (top == bottom)) return FALSE;
95 if (!DC_SetupGCForPen( dc )) return TRUE;
97 xcenter = (right + left) / 2;
98 ycenter = (bottom + top) / 2;
99 start_angle = atan2( (double)(ycenter-ystart)*(right-left),
100 (double)(xstart-xcenter)*(bottom-top) );
101 end_angle = atan2( (double)(ycenter-yend)*(right-left),
102 (double)(xend-xcenter)*(bottom-top) );
103 diff_angle = end_angle - start_angle;
104 if (diff_angle < 0.0) diff_angle += 2*PI;
106 XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
107 dc->w.DCOrgX + left, dc->w.DCOrgY + top,
108 right-left-1, bottom-top-1,
109 (int)(start_angle * 180 * 64 / PI),
110 (int)(diff_angle * 180 * 64 / PI) );
111 if (!lines) return TRUE;
113 points[0].x = dc->w.DCOrgX + xcenter + (int)(cos(start_angle) * (right-left) / 2);
114 points[0].y = dc->w.DCOrgY + ycenter - (int)(sin(start_angle) * (bottom-top) / 2);
115 points[1].x = dc->w.DCOrgX + xcenter + (int)(cos(end_angle) * (right-left) / 2);
116 points[1].y = dc->w.DCOrgY + ycenter - (int)(sin(end_angle) * (bottom-top) / 2);
117 if (lines == 2)
119 points[2] = points[1];
120 points[1].x = dc->w.DCOrgX + xcenter;
121 points[1].y = dc->w.DCOrgY + ycenter;
123 XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
124 points, lines+1, CoordModeOrigin );
125 return TRUE;
129 /***********************************************************************
130 * Arc (GDI.23)
132 BOOL Arc( HDC hdc, int left, int top, int right, int bottom,
133 int xstart, int ystart, int xend, int yend )
135 return GRAPH_DrawArc( hdc, left, top, right, bottom,
136 xstart, ystart, xend, yend, 0 );
140 /***********************************************************************
141 * Pie (GDI.26)
143 BOOL Pie( HDC hdc, int left, int top, int right, int bottom,
144 int xstart, int ystart, int xend, int yend )
146 return GRAPH_DrawArc( hdc, left, top, right, bottom,
147 xstart, ystart, xend, yend, 2 );
151 /***********************************************************************
152 * Chord (GDI.348)
154 BOOL Chord( HDC hdc, int left, int top, int right, int bottom,
155 int xstart, int ystart, int xend, int yend )
157 return GRAPH_DrawArc( hdc, left, top, right, bottom,
158 xstart, ystart, xend, yend, 1 );
162 /***********************************************************************
163 * Ellipse (GDI.24)
165 BOOL Ellipse( HDC hdc, int left, int top, int right, int bottom )
167 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
168 if (!dc) return FALSE;
170 left = XLPTODP( dc, left );
171 top = YLPTODP( dc, top );
172 right = XLPTODP( dc, right );
173 bottom = YLPTODP( dc, bottom );
174 if ((left == right) || (top == bottom)) return FALSE;
176 if (DC_SetupGCForBrush( dc ))
177 XFillArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
178 dc->w.DCOrgX + left, dc->w.DCOrgY + top,
179 right-left-1, bottom-top-1, 0, 360*64 );
180 if (DC_SetupGCForPen( dc ))
181 XDrawArc( XT_display, dc->u.x.drawable, dc->u.x.gc,
182 dc->w.DCOrgX + left, dc->w.DCOrgY + top,
183 right-left-1, bottom-top-1, 0, 360*64 );
184 return TRUE;
188 /***********************************************************************
189 * Rectangle (GDI.27)
191 BOOL Rectangle( HDC hdc, int left, int top, int right, int bottom )
193 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
194 if (!dc) return FALSE;
196 left = XLPTODP( dc, left );
197 top = YLPTODP( dc, top );
198 right = XLPTODP( dc, right );
199 bottom = YLPTODP( dc, bottom );
201 if (DC_SetupGCForBrush( dc ))
202 XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
203 dc->w.DCOrgX + left, dc->w.DCOrgY + top,
204 right-left-1, bottom-top-1 );
205 if (DC_SetupGCForPen( dc ))
206 XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
207 dc->w.DCOrgX + left, dc->w.DCOrgY + top,
208 right-left-1, bottom-top-1 );
209 return TRUE;
213 /***********************************************************************
214 * RoundRect (GDI.28)
216 BOOL RoundRect( HDC hDC, short left, short top, short right, short bottom,
217 short ell_width, short ell_height)
219 int x1, y1, x2, y2;
220 DC * dc = (DC *) GDI_GetObjPtr(hDC, DC_MAGIC);
221 if (!dc) return FALSE;
223 printf("RoundRect(%d %d %d %d %d %d\n",
224 left, top, right, bottom, ell_width, ell_height);
226 x1 = XLPTODP(dc, left);
227 y1 = YLPTODP(dc, top);
228 x2 = XLPTODP(dc, right - ell_width);
229 y2 = YLPTODP(dc, bottom - ell_height);
230 if (DC_SetupGCForBrush(dc)) {
231 XFillArc(XT_display, dc->u.x.drawable, dc->u.x.gc,
232 dc->w.DCOrgX + x1, dc->w.DCOrgY + y1,
233 ell_width, ell_height, 90 * 64, 90 * 64);
234 XFillArc(XT_display, dc->u.x.drawable, dc->u.x.gc,
235 dc->w.DCOrgX + x1, dc->w.DCOrgY + y2,
236 ell_width, ell_height, 180 * 64, 90 * 64);
237 XFillArc(XT_display, dc->u.x.drawable, dc->u.x.gc,
238 dc->w.DCOrgX + x2, dc->w.DCOrgY + y2,
239 ell_width, ell_height, 270 * 64, 90 * 64);
240 XFillArc(XT_display, dc->u.x.drawable, dc->u.x.gc,
241 dc->w.DCOrgX + x2, dc->w.DCOrgY + y1,
242 ell_width, ell_height, 0, 90 * 64);
243 ell_width /= 2; ell_height /= 2;
244 XFillRectangle(XT_display, dc->u.x.drawable, dc->u.x.gc,
245 dc->w.DCOrgX + left + ell_width, dc->w.DCOrgY + top,
246 right - left - 2 * ell_width, bottom - top);
247 XFillRectangle(XT_display, dc->u.x.drawable, dc->u.x.gc,
248 dc->w.DCOrgX + left, dc->w.DCOrgY + top + ell_height,
249 ell_width, bottom - top - 2 * ell_height);
250 XFillRectangle(XT_display, dc->u.x.drawable, dc->u.x.gc,
251 dc->w.DCOrgX + right - ell_width, dc->w.DCOrgY + top + ell_height,
252 ell_width, bottom - top - 2 * ell_height);
253 ell_width *= 2; ell_height *= 2;
255 if (DC_SetupGCForPen(dc)) {
256 XDrawArc(XT_display, dc->u.x.drawable, dc->u.x.gc,
257 dc->w.DCOrgX + x1, dc->w.DCOrgY + y1,
258 ell_width, ell_height, 90 * 64, 90 * 64);
259 XDrawArc(XT_display, dc->u.x.drawable, dc->u.x.gc,
260 dc->w.DCOrgX + x1, dc->w.DCOrgY + y2,
261 ell_width, ell_height, 180 * 64, 90 * 64);
262 XDrawArc(XT_display, dc->u.x.drawable, dc->u.x.gc,
263 dc->w.DCOrgX + x2, dc->w.DCOrgY + y2,
264 ell_width, ell_height, 270 * 64, 90 * 64);
265 XDrawArc(XT_display, dc->u.x.drawable, dc->u.x.gc,
266 dc->w.DCOrgX + x2, dc->w.DCOrgY + y1,
267 ell_width, ell_height, 0, 90 * 64);
269 ell_width /= 2; ell_height /= 2;
270 MoveTo(hDC, left, top + ell_height);
271 LineTo(hDC, left, bottom - ell_height);
272 MoveTo(hDC, left + ell_width, bottom);
273 LineTo(hDC, right - ell_width, bottom);
274 MoveTo(hDC, right, bottom - ell_height);
275 LineTo(hDC, right, top + ell_height);
276 MoveTo(hDC, right - ell_width, top);
277 LineTo(hDC, left + ell_width, top);
278 return TRUE;
282 /***********************************************************************
283 * FillRect (USER.81)
285 int FillRect( HDC hdc, LPRECT rect, HBRUSH hbrush )
287 HBRUSH prevBrush;
289 if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
290 if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
291 PatBlt( hdc, rect->left, rect->top,
292 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
293 SelectObject( hdc, prevBrush );
294 return 1;
298 /***********************************************************************
299 * InvertRect (USER.82)
301 void InvertRect( HDC hdc, LPRECT rect )
303 if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return;
304 PatBlt( hdc, rect->left, rect->top,
305 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
309 /***********************************************************************
310 * FrameRect (USER.83)
312 int FrameRect( HDC hdc, LPRECT rect, HBRUSH hbrush )
314 HBRUSH prevBrush;
315 int left, top, right, bottom;
317 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
318 if (!dc) return FALSE;
320 if ((rect->right <= rect->left) || (rect->bottom <= rect->top)) return 0;
321 if (!(prevBrush = SelectObject( hdc, hbrush ))) return 0;
323 left = XLPTODP( dc, rect->left );
324 top = YLPTODP( dc, rect->top );
325 right = XLPTODP( dc, rect->right );
326 bottom = YLPTODP( dc, rect->bottom );
328 if (DC_SetupGCForBrush( dc )) {
329 PatBlt( hdc, rect->left, rect->top, 1,
330 rect->bottom - rect->top, PATCOPY );
331 PatBlt( hdc, rect->right - 1, rect->top, 1,
332 rect->bottom - rect->top, PATCOPY );
333 PatBlt( hdc, rect->left, rect->top,
334 rect->right - rect->left, 1, PATCOPY );
335 PatBlt( hdc, rect->left, rect->bottom - 1,
336 rect->right - rect->left, 1, PATCOPY );
338 SelectObject( hdc, prevBrush );
339 return 1;
343 /***********************************************************************
344 * SetPixel (GDI.31)
346 COLORREF SetPixel( HDC hdc, short x, short y, COLORREF color )
348 int pixel;
349 PALETTEENTRY entry;
351 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
352 if (!dc) return 0;
354 x = dc->w.DCOrgX + XLPTODP( dc, x );
355 y = dc->w.DCOrgY + YLPTODP( dc, y );
356 pixel = COLOR_ToPhysical( dc, color );
357 GetPaletteEntries( dc->w.hPalette, pixel, 1, &entry );
359 XSetForeground( XT_display, dc->u.x.gc, pixel );
360 XSetFunction( XT_display, dc->u.x.gc, GXcopy );
361 XDrawPoint( XT_display, dc->u.x.drawable, dc->u.x.gc, x, y );
363 return RGB( entry.peRed, entry.peGreen, entry.peBlue );
367 /***********************************************************************
368 * GetPixel (GDI.83)
370 COLORREF GetPixel( HDC hdc, short x, short y )
372 PALETTEENTRY entry;
373 XImage * image;
375 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
376 if (!dc) return 0;
378 x = dc->w.DCOrgX + XLPTODP( dc, x );
379 y = dc->w.DCOrgY + YLPTODP( dc, y );
380 if ((x < 0) || (y < 0)) return 0;
382 if (!(dc->w.flags & DC_MEMORY))
384 XWindowAttributes win_attr;
386 if (!XGetWindowAttributes( XT_display, dc->u.x.drawable, &win_attr ))
387 return 0;
388 if (win_attr.map_state != IsViewable) return 0;
389 if ((x >= win_attr.width) || (y >= win_attr.height)) return 0;
392 image = XGetImage( XT_display, dc->u.x.drawable, x, y,
393 1, 1, AllPlanes, ZPixmap );
394 GetPaletteEntries( dc->w.hPalette, XGetPixel( image, 0, 0 ), 1, &entry );
395 XDestroyImage( image );
396 return RGB( entry.peRed, entry.peGreen, entry.peBlue );
400 /***********************************************************************
401 * PaintRgn (GDI.43)
403 BOOL PaintRgn( HDC hdc, HRGN hrgn )
405 RECT box;
406 HRGN tmpVisRgn, prevVisRgn;
407 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
408 if (!dc) return FALSE;
410 /* Modify visible region */
412 prevVisRgn = SaveVisRgn( hdc );
413 if (prevVisRgn)
415 if (!(tmpVisRgn = CreateRectRgn( 0, 0, 0, 0 )))
417 RestoreVisRgn( hdc );
418 return FALSE;
420 CombineRgn( tmpVisRgn, prevVisRgn, hrgn, RGN_AND );
421 SelectVisRgn( hdc, tmpVisRgn );
422 DeleteObject( tmpVisRgn );
424 else SelectVisRgn( hdc, hrgn );
426 /* Fill the region */
428 GetClipBox( hdc, &box );
429 if (DC_SetupGCForBrush( dc ))
430 XFillRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
431 dc->w.DCOrgX + box.left, dc->w.DCOrgY + box.top,
432 box.right-box.left, box.bottom-box.top );
434 /* Restore the visible region */
436 if (prevVisRgn) RestoreVisRgn( hdc );
437 else SelectVisRgn( hdc, 0 );
438 return TRUE;
442 /***********************************************************************
443 * FillRgn (GDI.40)
445 BOOL FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
447 BOOL retval;
448 HBRUSH prevBrush = SelectObject( hdc, hbrush );
449 if (!prevBrush) return FALSE;
450 retval = PaintRgn( hdc, hrgn );
451 SelectObject( hdc, prevBrush );
452 return retval;
456 /***********************************************************************
457 * DrawFocusRect (USER.466)
459 void DrawFocusRect( HDC hdc, LPRECT rc )
461 HPEN hPen, hOldPen;
462 int oldDrawMode, oldBkMode;
463 int left, top, right, bottom;
464 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
465 if (!dc) return;
467 left = XLPTODP( dc, rc->left );
468 top = YLPTODP( dc, rc->top );
469 right = XLPTODP( dc, rc->right );
470 bottom = YLPTODP( dc, rc->bottom );
472 hPen = CreatePen(PS_DOT, 1, GetSysColor(COLOR_WINDOWTEXT));
473 hOldPen = (HPEN)SelectObject(hdc, (HANDLE)hPen);
474 oldDrawMode = SetROP2(hdc, R2_XORPEN);
475 oldBkMode = SetBkMode(hdc, TRANSPARENT);
477 if (DC_SetupGCForPen( dc ))
478 XDrawRectangle( XT_display, dc->u.x.drawable, dc->u.x.gc,
479 dc->w.DCOrgX + left, dc->w.DCOrgY + top,
480 right-left-1, bottom-top-1 );
482 SetBkMode(hdc, oldBkMode);
483 SetROP2(hdc, oldDrawMode);
484 SelectObject(hdc, (HANDLE)hOldPen);
485 DeleteObject((HANDLE)hPen);
489 /**********************************************************************
490 * DrawReliefRect (Not a MSWin Call)
492 void DrawReliefRect( HDC hdc, RECT rect, int thickness, BOOL pressed )
494 HBRUSH hbrushOld, hbrushShadow, hbrushHighlight;
495 int i;
497 hbrushShadow = CreateSolidBrush( GetSysColor(COLOR_BTNSHADOW) );
498 hbrushHighlight = CreateSolidBrush( GetSysColor(COLOR_BTNHIGHLIGHT) );
500 if (pressed) hbrushOld = SelectObject( hdc, hbrushShadow );
501 else hbrushOld = SelectObject( hdc, hbrushHighlight );
503 for (i = 0; i < thickness; i++)
505 PatBlt( hdc, rect.left + i, rect.top,
506 1, rect.bottom - rect.top - i, PATCOPY );
507 PatBlt( hdc, rect.left, rect.top + i,
508 rect.right - rect.left - i, 1, PATCOPY );
511 if (pressed) hbrushOld = SelectObject( hdc, hbrushHighlight );
512 else hbrushOld = SelectObject( hdc, hbrushShadow );
514 for (i = 0; i < thickness; i++)
516 PatBlt( hdc, rect.right - i - 1, rect.top + i,
517 1, rect.bottom - rect.top - i, PATCOPY );
518 PatBlt( hdc, rect.left + i, rect.bottom - i - 1,
519 rect.right - rect.left - i, 1, PATCOPY );
522 SelectObject( hdc, hbrushOld );
523 DeleteObject( hbrushShadow );
524 DeleteObject( hbrushHighlight );
528 /**********************************************************************
529 * Polyline (GDI.37)
531 BOOL Polyline (HDC hdc, LPPOINT pt, int count)
533 register int i;
534 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
536 if (DC_SetupGCForPen( dc ))
538 for (i = 0; i < count-1; i ++)
539 XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc,
540 dc->w.DCOrgX + XLPTODP(dc, pt [i].x),
541 dc->w.DCOrgY + YLPTODP(dc, pt [i].y),
542 dc->w.DCOrgX + XLPTODP(dc, pt [i+1].x),
543 dc->w.DCOrgY + YLPTODP(dc, pt [i+1].y));
544 XDrawLine (XT_display, dc->u.x.drawable, dc->u.x.gc,
545 dc->w.DCOrgX + XLPTODP(dc, pt [count-1].x),
546 dc->w.DCOrgY + YLPTODP(dc, pt [count-1].y),
547 dc->w.DCOrgX + XLPTODP(dc, pt [0].x),
548 dc->w.DCOrgY + YLPTODP(dc, pt [0].y));
551 return (TRUE);
555 /**********************************************************************
556 * Polygon (GDI.36)
558 BOOL Polygon (HDC hdc, LPPOINT pt, int count)
560 register int i;
561 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
562 XPoint *points = (XPoint *) malloc (sizeof (XPoint) * count+1);
564 if (DC_SetupGCForBrush( dc ))
567 for (i = 0; i < count; i++)
569 points [i].x = dc->w.DCOrgX + XLPTODP(dc, pt [i].x);
570 points [i].y = dc->w.DCOrgY + YLPTODP(dc, pt [i].y);
572 points [count] = points [0];
574 XFillPolygon( XT_display, dc->u.x.drawable, dc->u.x.gc,
575 points, count, Complex, CoordModeOrigin);
577 if (DC_SetupGCForPen ( dc ))
579 XDrawLines( XT_display, dc->u.x.drawable, dc->u.x.gc,
580 points, count, CoordModeOrigin );
583 free ((void *) points);
584 return (TRUE);
587 /**********************************************************************
588 * FloodFill_rec -- FloodFill helper function
590 * Just does a recursive flood fill:
591 * this is /not/ efficent -- a better way would be to draw
592 * an entire line at a time, but this will do for now.
594 static BOOL FloodFill_rec(XImage *image, int x, int y,
595 int orgx, int orgy, int endx, int endy,
596 Pixel borderp, Pixel fillp)
598 Pixel testp;
600 if (x > endx || x < orgx || y > endy || y < orgy)
601 return FALSE;
602 XPutPixel(image, x, y, fillp);
604 testp = XGetPixel(image, x+1, y+1);
605 if (testp != borderp && testp != fillp)
606 FloodFill_rec(image, x+1, y+1, orgx, orgy,
607 endx, endy, borderp, fillp);
609 testp = XGetPixel(image, x+1, y-1);
610 if (testp != borderp && testp != fillp)
611 FloodFill_rec(image, x+1, y-1, orgx, orgy,
612 endx, endy, borderp, fillp);
613 testp = XGetPixel(image, x-1, y+1);
614 if (testp != borderp && testp != fillp)
615 FloodFill_rec(image, x-1, y+1, orgx, orgy,
616 endx, endy, borderp, fillp);
617 testp = XGetPixel(image, x-1, y-1);
618 if (testp != borderp && testp != fillp)
619 FloodFill_rec(image, x-1, y-1, orgx, orgy,
620 endx, endy, borderp, fillp);
621 return TRUE;
625 /**********************************************************************
626 * FloodFill (GDI.25)
628 BOOL FloodFill(HDC hdc, short x, short y, DWORD crColor)
630 Pixel boundrypixel;
631 int imagex, imagey;
632 XImage *image;
633 DC *dc;
635 #ifdef DEBUG_GRAPHICS
636 printf("FloodFill %x %d,%d %x\n", hdc, x, y, crColor);
637 #endif
638 dc = (DC *) GDI_GetObjPtr(hdc, DC_MAGIC);
640 if (!dc) return 0;
642 x = dc->w.DCOrgX + XLPTODP(dc, x);
643 y = dc->w.DCOrgY + YLPTODP(dc, y);
645 if (x < dc->w.DCOrgX || x > dc->w.DCOrgX + dc->w.DCSizeX ||
646 y < dc->w.DCOrgY || y > dc->w.DCOrgY + dc->w.DCSizeY)
647 return 0;
649 if (!DC_SetupGCForBrush(dc))
650 return FALSE;
652 boundrypixel = GetNearestPaletteIndex( dc->w.hPalette, crColor );
654 image = XGetImage(display, dc->u.x.drawable,
655 dc->w.DCOrgX, dc->w.DCOrgY,
656 dc->w.DCSizeX, dc->w.DCSizeY, AllPlanes, ZPixmap);
657 if (XGetPixel(image, x, y) == boundrypixel)
658 return FALSE;
659 if (!FloodFill_rec(image, x, y,
660 0,0,
661 dc->w.DCOrgX + dc->w.DCSizeX,
662 dc->w.DCOrgY + dc->w.DCSizeY,
663 boundrypixel, dc->u.x.brush.pixel)) {
664 XDestroyImage(image);
665 return 0;
668 XPutImage(display, dc->u.x.drawable, dc->u.x.gc, image,
669 0, 0,
670 dc->w.DCOrgX, dc->w.DCOrgY,
671 dc->w.DCSizeX, dc->w.DCSizeY);
672 XDestroyImage(image);
674 return TRUE;