2 * GDI graphics operations
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
12 #include <X11/Xutil.h>
13 #include <X11/Intrinsic.h>
20 extern int COLOR_ToPhysical( DC
*dc
, COLORREF color
);
22 /***********************************************************************
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
) );
41 /***********************************************************************
44 DWORD
MoveTo( HDC hdc
, short x
, short y
)
47 if (MoveToEx( hdc
, x
, y
, &pt
)) return pt
.x
| (pt
.y
<< 16);
52 /***********************************************************************
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
;
61 pt
->x
= dc
->w
.CursPosX
;
62 pt
->y
= dc
->w
.CursPosY
;
70 /***********************************************************************
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
)
80 double start_angle
, end_angle
, diff_angle
;
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);
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
);
129 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 /***********************************************************************
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 );
188 /***********************************************************************
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 );
213 /***********************************************************************
216 BOOL
RoundRect( HDC hDC
, short left
, short top
, short right
, short bottom
,
217 short ell_width
, short ell_height
)
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
);
282 /***********************************************************************
285 int FillRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
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
);
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
)
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
);
343 /***********************************************************************
346 COLORREF
SetPixel( HDC hdc
, short x
, short y
, COLORREF color
)
351 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
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 /***********************************************************************
370 COLORREF
GetPixel( HDC hdc
, short x
, short y
)
375 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
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
))
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 /***********************************************************************
403 BOOL
PaintRgn( HDC hdc
, HRGN hrgn
)
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
);
415 if (!(tmpVisRgn
= CreateRectRgn( 0, 0, 0, 0 )))
417 RestoreVisRgn( hdc
);
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 );
442 /***********************************************************************
445 BOOL
FillRgn( HDC hdc
, HRGN hrgn
, HBRUSH hbrush
)
448 HBRUSH prevBrush
= SelectObject( hdc
, hbrush
);
449 if (!prevBrush
) return FALSE
;
450 retval
= PaintRgn( hdc
, hrgn
);
451 SelectObject( hdc
, prevBrush
);
456 /***********************************************************************
457 * DrawFocusRect (USER.466)
459 void DrawFocusRect( HDC hdc
, LPRECT rc
)
462 int oldDrawMode
, oldBkMode
;
463 int left
, top
, right
, bottom
;
464 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
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
;
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 /**********************************************************************
531 BOOL
Polyline (HDC hdc
, LPPOINT pt
, int count
)
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
));
555 /**********************************************************************
558 BOOL
Polygon (HDC hdc
, LPPOINT pt
, int count
)
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
);
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
)
600 if (x
> endx
|| x
< orgx
|| y
> endy
|| y
< orgy
)
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
);
625 /**********************************************************************
628 BOOL
FloodFill(HDC hdc
, short x
, short y
, DWORD crColor
)
635 #ifdef DEBUG_GRAPHICS
636 printf("FloodFill %x %d,%d %x\n", hdc
, x
, y
, crColor
);
638 dc
= (DC
*) GDI_GetObjPtr(hdc
, DC_MAGIC
);
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
)
649 if (!DC_SetupGCForBrush(dc
))
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
)
659 if (!FloodFill_rec(image
, x
, y
,
661 dc
->w
.DCOrgX
+ dc
->w
.DCSizeX
,
662 dc
->w
.DCOrgY
+ dc
->w
.DCSizeY
,
663 boundrypixel
, dc
->u
.x
.brush
.pixel
)) {
664 XDestroyImage(image
);
668 XPutImage(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, image
,
670 dc
->w
.DCOrgX
, dc
->w
.DCOrgY
,
671 dc
->w
.DCSizeX
, dc
->w
.DCSizeY
);
672 XDestroyImage(image
);