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>
21 extern int COLOR_ToPhysical( DC
*dc
, COLORREF color
);
23 /***********************************************************************
26 BOOL
LineTo( HDC hdc
, short x
, short y
)
28 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
31 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
32 if (!dc
) return FALSE
;
33 MF_MetaParam2(dc
, META_LINETO
, x
, y
);
37 if (DC_SetupGCForPen( dc
))
38 XDrawLine(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
39 dc
->w
.DCOrgX
+ XLPTODP( dc
, dc
->w
.CursPosX
),
40 dc
->w
.DCOrgY
+ YLPTODP( dc
, dc
->w
.CursPosY
),
41 dc
->w
.DCOrgX
+ XLPTODP( dc
, x
),
42 dc
->w
.DCOrgY
+ YLPTODP( dc
, y
) );
49 /***********************************************************************
52 DWORD
MoveTo( HDC hdc
, short x
, short y
)
55 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
58 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
59 if (!dc
) return FALSE
;
60 MF_MetaParam2(dc
, META_MOVETO
, x
, y
);
64 oldx
= dc
->w
.CursPosX
;
65 oldy
= dc
->w
.CursPosY
;
68 return oldx
| (oldy
<< 16);
72 /***********************************************************************
75 BOOL
MoveToEx( HDC hdc
, short x
, short y
, LPPOINT pt
)
77 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
78 if (!dc
) return FALSE
;
81 pt
->x
= dc
->w
.CursPosX
;
82 pt
->y
= dc
->w
.CursPosY
;
90 /***********************************************************************
93 * Helper functions for Arc(), Chord() and Pie().
94 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
96 BOOL
GRAPH_DrawArc( HDC hdc
, int left
, int top
, int right
, int bottom
,
97 int xstart
, int ystart
, int xend
, int yend
, int lines
)
100 double start_angle
, end_angle
, diff_angle
;
102 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
105 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
106 if (!dc
) return FALSE
;
110 MF_MetaParam8(dc
, META_ARC
, left
, top
, right
, bottom
,
111 xstart
, ystart
, xend
, yend
);
115 MF_MetaParam8(dc
, META_CHORD
, left
, top
, right
, bottom
,
116 xstart
, ystart
, xend
, yend
);
120 MF_MetaParam8(dc
, META_PIE
, left
, top
, right
, bottom
,
121 xstart
, ystart
, xend
, yend
);
127 left
= XLPTODP( dc
, left
);
128 top
= YLPTODP( dc
, top
);
129 right
= XLPTODP( dc
, right
);
130 bottom
= YLPTODP( dc
, bottom
);
131 xstart
= XLPTODP( dc
, xstart
);
132 ystart
= YLPTODP( dc
, ystart
);
133 xend
= XLPTODP( dc
, xend
);
134 yend
= YLPTODP( dc
, yend
);
135 if ((left
== right
) || (top
== bottom
)) return FALSE
;
137 if (!DC_SetupGCForPen( dc
)) return TRUE
;
139 xcenter
= (right
+ left
) / 2;
140 ycenter
= (bottom
+ top
) / 2;
141 start_angle
= atan2( (double)(ycenter
-ystart
)*(right
-left
),
142 (double)(xstart
-xcenter
)*(bottom
-top
) );
143 end_angle
= atan2( (double)(ycenter
-yend
)*(right
-left
),
144 (double)(xend
-xcenter
)*(bottom
-top
) );
145 diff_angle
= end_angle
- start_angle
;
146 if (diff_angle
< 0.0) diff_angle
+= 2*PI
;
148 XDrawArc( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
149 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
150 right
-left
-1, bottom
-top
-1,
151 (int)(start_angle
* 180 * 64 / PI
),
152 (int)(diff_angle
* 180 * 64 / PI
) );
153 if (!lines
) return TRUE
;
155 points
[0].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(start_angle
) * (right
-left
) / 2);
156 points
[0].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(start_angle
) * (bottom
-top
) / 2);
157 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(end_angle
) * (right
-left
) / 2);
158 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(end_angle
) * (bottom
-top
) / 2);
161 points
[2] = points
[1];
162 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
;
163 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
;
165 XDrawLines( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
166 points
, lines
+1, CoordModeOrigin
);
171 /***********************************************************************
174 BOOL
Arc( HDC hdc
, int left
, int top
, int right
, int bottom
,
175 int xstart
, int ystart
, int xend
, int yend
)
177 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
178 xstart
, ystart
, xend
, yend
, 0 );
182 /***********************************************************************
185 BOOL
Pie( HDC hdc
, int left
, int top
, int right
, int bottom
,
186 int xstart
, int ystart
, int xend
, int yend
)
188 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
189 xstart
, ystart
, xend
, yend
, 2 );
193 /***********************************************************************
196 BOOL
Chord( HDC hdc
, int left
, int top
, int right
, int bottom
,
197 int xstart
, int ystart
, int xend
, int yend
)
199 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
200 xstart
, ystart
, xend
, yend
, 1 );
204 /***********************************************************************
207 BOOL
Ellipse( HDC hdc
, int left
, int top
, int right
, int bottom
)
209 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
212 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
213 if (!dc
) return FALSE
;
214 MF_MetaParam4(dc
, META_ELLIPSE
, left
, top
, right
, bottom
);
218 left
= XLPTODP( dc
, left
);
219 top
= YLPTODP( dc
, top
);
220 right
= XLPTODP( dc
, right
);
221 bottom
= YLPTODP( dc
, bottom
);
222 if ((left
== right
) || (top
== bottom
)) return FALSE
;
224 if (DC_SetupGCForBrush( dc
))
225 XFillArc( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
226 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
227 right
-left
-1, bottom
-top
-1, 0, 360*64 );
228 if (DC_SetupGCForPen( dc
))
229 XDrawArc( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
230 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
231 right
-left
-1, bottom
-top
-1, 0, 360*64 );
236 /***********************************************************************
239 BOOL
Rectangle( HDC hdc
, int left
, int top
, int right
, int bottom
)
241 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
244 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
245 if (!dc
) return FALSE
;
246 MF_MetaParam4(dc
, META_RECTANGLE
, left
, top
, right
, bottom
);
250 left
= XLPTODP( dc
, left
);
251 top
= YLPTODP( dc
, top
);
252 right
= XLPTODP( dc
, right
);
253 bottom
= YLPTODP( dc
, bottom
);
255 if (DC_SetupGCForBrush( dc
))
256 XFillRectangle( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
257 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
258 right
-left
-1, bottom
-top
-1 );
259 if (DC_SetupGCForPen( dc
))
260 XDrawRectangle( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
261 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
262 right
-left
-1, bottom
-top
-1 );
267 /***********************************************************************
270 BOOL
RoundRect( HDC hDC
, short left
, short top
, short right
, short bottom
,
271 short ell_width
, short ell_height
)
274 DC
* dc
= (DC
*) GDI_GetObjPtr(hDC
, DC_MAGIC
);
277 dc
= (DC
*)GDI_GetObjPtr(hDC
, METAFILE_DC_MAGIC
);
278 if (!dc
) return FALSE
;
279 MF_MetaParam6(dc
, META_ROUNDRECT
, left
, top
, right
, bottom
,
280 ell_width
, ell_height
);
284 printf("RoundRect(%d %d %d %d %d %d\n",
285 left, top, right, bottom, ell_width, ell_height);
287 x1
= XLPTODP(dc
, left
);
288 y1
= YLPTODP(dc
, top
);
289 x2
= XLPTODP(dc
, right
- ell_width
);
290 y2
= YLPTODP(dc
, bottom
- ell_height
);
291 if (DC_SetupGCForBrush(dc
)) {
292 XFillArc(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
293 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y1
,
294 ell_width
, ell_height
, 90 * 64, 90 * 64);
295 XFillArc(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
296 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y2
,
297 ell_width
, ell_height
, 180 * 64, 90 * 64);
298 XFillArc(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
299 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y2
,
300 ell_width
, ell_height
, 270 * 64, 90 * 64);
301 XFillArc(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
302 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y1
,
303 ell_width
, ell_height
, 0, 90 * 64);
304 ell_width
/= 2; ell_height
/= 2;
305 XFillRectangle(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
306 dc
->w
.DCOrgX
+ left
+ ell_width
, dc
->w
.DCOrgY
+ top
,
307 right
- left
- 2 * ell_width
, bottom
- top
);
308 XFillRectangle(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
309 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
+ ell_height
,
310 ell_width
, bottom
- top
- 2 * ell_height
);
311 XFillRectangle(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
312 dc
->w
.DCOrgX
+ right
- ell_width
, dc
->w
.DCOrgY
+ top
+ ell_height
,
313 ell_width
, bottom
- top
- 2 * ell_height
);
314 ell_width
*= 2; ell_height
*= 2;
316 if (DC_SetupGCForPen(dc
)) {
317 XDrawArc(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
318 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y1
,
319 ell_width
, ell_height
, 90 * 64, 90 * 64);
320 XDrawArc(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
321 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y2
,
322 ell_width
, ell_height
, 180 * 64, 90 * 64);
323 XDrawArc(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
324 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y2
,
325 ell_width
, ell_height
, 270 * 64, 90 * 64);
326 XDrawArc(XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
327 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y1
,
328 ell_width
, ell_height
, 0, 90 * 64);
330 ell_width
/= 2; ell_height
/= 2;
331 MoveTo(hDC
, left
, top
+ ell_height
);
332 LineTo(hDC
, left
, bottom
- ell_height
);
333 MoveTo(hDC
, left
+ ell_width
, bottom
);
334 LineTo(hDC
, right
- ell_width
, bottom
);
335 MoveTo(hDC
, right
, bottom
- ell_height
);
336 LineTo(hDC
, right
, top
+ ell_height
);
337 MoveTo(hDC
, right
- ell_width
, top
);
338 LineTo(hDC
, left
+ ell_width
, top
);
343 /***********************************************************************
346 int FillRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
350 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return 0;
351 if (!(prevBrush
= SelectObject( hdc
, hbrush
))) return 0;
352 PatBlt( hdc
, rect
->left
, rect
->top
,
353 rect
->right
- rect
->left
, rect
->bottom
- rect
->top
, PATCOPY
);
354 SelectObject( hdc
, prevBrush
);
359 /***********************************************************************
360 * InvertRect (USER.82)
362 void InvertRect( HDC hdc
, LPRECT rect
)
364 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return;
365 PatBlt( hdc
, rect
->left
, rect
->top
,
366 rect
->right
- rect
->left
, rect
->bottom
- rect
->top
, DSTINVERT
);
370 /***********************************************************************
371 * FrameRect (USER.83)
373 int FrameRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
376 int left
, top
, right
, bottom
;
378 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
379 if (!dc
) return FALSE
;
381 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return 0;
382 if (!(prevBrush
= SelectObject( hdc
, hbrush
))) return 0;
384 left
= XLPTODP( dc
, rect
->left
);
385 top
= YLPTODP( dc
, rect
->top
);
386 right
= XLPTODP( dc
, rect
->right
);
387 bottom
= YLPTODP( dc
, rect
->bottom
);
389 if (DC_SetupGCForBrush( dc
)) {
390 PatBlt( hdc
, rect
->left
, rect
->top
, 1,
391 rect
->bottom
- rect
->top
, PATCOPY
);
392 PatBlt( hdc
, rect
->right
- 1, rect
->top
, 1,
393 rect
->bottom
- rect
->top
, PATCOPY
);
394 PatBlt( hdc
, rect
->left
, rect
->top
,
395 rect
->right
- rect
->left
, 1, PATCOPY
);
396 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
397 rect
->right
- rect
->left
, 1, PATCOPY
);
399 SelectObject( hdc
, prevBrush
);
404 /***********************************************************************
407 COLORREF
SetPixel( HDC hdc
, short x
, short y
, COLORREF color
)
412 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
415 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
417 MF_MetaParam4(dc
, META_SETPIXEL
, x
, y
, HIWORD(color
), LOWORD(color
));
421 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
422 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
423 pixel
= COLOR_ToPhysical( dc
, color
);
424 GetPaletteEntries( dc
->w
.hPalette
, pixel
, 1, &entry
);
426 XSetForeground( XT_display
, dc
->u
.x
.gc
, pixel
);
427 XSetFunction( XT_display
, dc
->u
.x
.gc
, GXcopy
);
428 XDrawPoint( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, x
, y
);
430 return RGB( entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
434 /***********************************************************************
437 COLORREF
GetPixel( HDC hdc
, short x
, short y
)
442 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
445 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
446 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
447 if ((x
< 0) || (y
< 0)) return 0;
449 if (!(dc
->w
.flags
& DC_MEMORY
))
451 XWindowAttributes win_attr
;
453 if (!XGetWindowAttributes( XT_display
, dc
->u
.x
.drawable
, &win_attr
))
455 if (win_attr
.map_state
!= IsViewable
) return 0;
456 if ((x
>= win_attr
.width
) || (y
>= win_attr
.height
)) return 0;
459 image
= XGetImage( XT_display
, dc
->u
.x
.drawable
, x
, y
,
460 1, 1, AllPlanes
, ZPixmap
);
461 GetPaletteEntries( dc
->w
.hPalette
, XGetPixel( image
, 0, 0 ), 1, &entry
);
462 XDestroyImage( image
);
463 return RGB( entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
467 /***********************************************************************
470 BOOL
PaintRgn( HDC hdc
, HRGN hrgn
)
473 HRGN tmpVisRgn
, prevVisRgn
;
474 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
475 if (!dc
) return FALSE
;
477 /* Modify visible region */
479 prevVisRgn
= SaveVisRgn( hdc
);
482 if (!(tmpVisRgn
= CreateRectRgn( 0, 0, 0, 0 )))
484 RestoreVisRgn( hdc
);
487 CombineRgn( tmpVisRgn
, prevVisRgn
, hrgn
, RGN_AND
);
488 SelectVisRgn( hdc
, tmpVisRgn
);
489 DeleteObject( tmpVisRgn
);
491 else SelectVisRgn( hdc
, hrgn
);
493 /* Fill the region */
495 GetClipBox( hdc
, &box
);
496 if (DC_SetupGCForBrush( dc
))
497 XFillRectangle( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
498 dc
->w
.DCOrgX
+ box
.left
, dc
->w
.DCOrgY
+ box
.top
,
499 box
.right
-box
.left
, box
.bottom
-box
.top
);
501 /* Restore the visible region */
503 if (prevVisRgn
) RestoreVisRgn( hdc
);
504 else SelectVisRgn( hdc
, 0 );
509 /***********************************************************************
512 BOOL
FillRgn( HDC hdc
, HRGN hrgn
, HBRUSH hbrush
)
515 HBRUSH prevBrush
= SelectObject( hdc
, hbrush
);
516 if (!prevBrush
) return FALSE
;
517 retval
= PaintRgn( hdc
, hrgn
);
518 SelectObject( hdc
, prevBrush
);
523 /***********************************************************************
524 * DrawFocusRect (USER.466)
526 void DrawFocusRect( HDC hdc
, LPRECT rc
)
529 int oldDrawMode
, oldBkMode
;
530 int left
, top
, right
, bottom
;
531 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
534 left
= XLPTODP( dc
, rc
->left
);
535 top
= YLPTODP( dc
, rc
->top
);
536 right
= XLPTODP( dc
, rc
->right
);
537 bottom
= YLPTODP( dc
, rc
->bottom
);
539 hOldPen
= (HPEN
)SelectObject(hdc
, sysColorObjects
.hpenWindowText
);
540 oldDrawMode
= SetROP2(hdc
, R2_XORPEN
);
541 oldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
543 if (DC_SetupGCForPen( dc
))
544 XDrawRectangle( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
545 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
546 right
-left
-1, bottom
-top
-1 );
548 SetBkMode(hdc
, oldBkMode
);
549 SetROP2(hdc
, oldDrawMode
);
550 SelectObject(hdc
, (HANDLE
)hOldPen
);
554 /**********************************************************************
555 * DrawReliefRect (Not a MSWin Call)
557 void DrawReliefRect( HDC hdc
, RECT rect
, int thickness
, BOOL pressed
)
562 hbrushOld
= SelectObject( hdc
, pressed
? sysColorObjects
.hbrushBtnShadow
:
563 sysColorObjects
.hbrushBtnHighlight
);
564 for (i
= 0; i
< thickness
; i
++)
566 PatBlt( hdc
, rect
.left
+ i
, rect
.top
,
567 1, rect
.bottom
- rect
.top
- i
, PATCOPY
);
568 PatBlt( hdc
, rect
.left
, rect
.top
+ i
,
569 rect
.right
- rect
.left
- i
, 1, PATCOPY
);
572 SelectObject( hdc
, pressed
? sysColorObjects
.hbrushBtnHighlight
:
573 sysColorObjects
.hbrushBtnShadow
);
574 for (i
= 0; i
< thickness
; i
++)
576 PatBlt( hdc
, rect
.right
- i
- 1, rect
.top
+ i
,
577 1, rect
.bottom
- rect
.top
- i
, PATCOPY
);
578 PatBlt( hdc
, rect
.left
+ i
, rect
.bottom
- i
- 1,
579 rect
.right
- rect
.left
- i
, 1, PATCOPY
);
582 SelectObject( hdc
, hbrushOld
);
586 /**********************************************************************
589 BOOL
Polyline (HDC hdc
, LPPOINT pt
, int count
)
592 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
595 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
596 if (!dc
) return FALSE
;
597 MF_MetaPoly(dc
, META_POLYLINE
, pt
, count
);
601 if (DC_SetupGCForPen( dc
))
603 for (i
= 0; i
< count
-1; i
++)
604 XDrawLine (XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
605 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
].x
),
606 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
].y
),
607 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
+1].x
),
608 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
+1].y
));
609 XDrawLine (XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
610 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[count
-1].x
),
611 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[count
-1].y
),
612 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[0].x
),
613 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[0].y
));
620 /**********************************************************************
623 BOOL
Polygon (HDC hdc
, LPPOINT pt
, int count
)
626 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
627 XPoint
*points
= (XPoint
*) malloc (sizeof (XPoint
) * count
+1);
631 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
632 if (!dc
) return FALSE
;
633 MF_MetaPoly(dc
, META_POLYGON
, pt
, count
);
637 if (DC_SetupGCForBrush( dc
))
640 for (i
= 0; i
< count
; i
++)
642 points
[i
].x
= dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
].x
);
643 points
[i
].y
= dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
].y
);
645 points
[count
] = points
[0];
647 XFillPolygon( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
648 points
, count
, Complex
, CoordModeOrigin
);
650 if (DC_SetupGCForPen ( dc
))
652 XDrawLines( XT_display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
653 points
, count
, CoordModeOrigin
);
656 free ((void *) points
);
660 /**********************************************************************
661 * FloodFill_rec -- FloodFill helper function
663 * Just does a recursive flood fill:
664 * this is /not/ efficent -- a better way would be to draw
665 * an entire line at a time, but this will do for now.
667 static BOOL
FloodFill_rec(XImage
*image
, int x
, int y
,
668 int orgx
, int orgy
, int endx
, int endy
,
669 Pixel borderp
, Pixel fillp
)
673 if (x
> endx
|| x
< orgx
|| y
> endy
|| y
< orgy
)
675 XPutPixel(image
, x
, y
, fillp
);
677 testp
= XGetPixel(image
, x
+1, y
+1);
678 if (testp
!= borderp
&& testp
!= fillp
)
679 FloodFill_rec(image
, x
+1, y
+1, orgx
, orgy
,
680 endx
, endy
, borderp
, fillp
);
682 testp
= XGetPixel(image
, x
+1, y
-1);
683 if (testp
!= borderp
&& testp
!= fillp
)
684 FloodFill_rec(image
, x
+1, y
-1, orgx
, orgy
,
685 endx
, endy
, borderp
, fillp
);
686 testp
= XGetPixel(image
, x
-1, y
+1);
687 if (testp
!= borderp
&& testp
!= fillp
)
688 FloodFill_rec(image
, x
-1, y
+1, orgx
, orgy
,
689 endx
, endy
, borderp
, fillp
);
690 testp
= XGetPixel(image
, x
-1, y
-1);
691 if (testp
!= borderp
&& testp
!= fillp
)
692 FloodFill_rec(image
, x
-1, y
-1, orgx
, orgy
,
693 endx
, endy
, borderp
, fillp
);
698 /**********************************************************************
701 BOOL
FloodFill(HDC hdc
, short x
, short y
, DWORD crColor
)
708 #ifdef DEBUG_GRAPHICS
709 printf("FloodFill %x %d,%d %x\n", hdc
, x
, y
, crColor
);
711 dc
= (DC
*) GDI_GetObjPtr(hdc
, DC_MAGIC
);
714 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
715 if (!dc
) return FALSE
;
716 MF_MetaParam4(dc
, META_FLOODFILL
, x
, y
, HIWORD(crColor
),
721 x
= dc
->w
.DCOrgX
+ XLPTODP(dc
, x
);
722 y
= dc
->w
.DCOrgY
+ YLPTODP(dc
, y
);
724 if (x
< dc
->w
.DCOrgX
|| x
> dc
->w
.DCOrgX
+ dc
->w
.DCSizeX
||
725 y
< dc
->w
.DCOrgY
|| y
> dc
->w
.DCOrgY
+ dc
->w
.DCSizeY
)
728 if (!DC_SetupGCForBrush(dc
))
731 boundrypixel
= GetNearestPaletteIndex( dc
->w
.hPalette
, crColor
);
733 image
= XGetImage(display
, dc
->u
.x
.drawable
,
734 dc
->w
.DCOrgX
, dc
->w
.DCOrgY
,
735 dc
->w
.DCSizeX
, dc
->w
.DCSizeY
, AllPlanes
, ZPixmap
);
736 if (XGetPixel(image
, x
, y
) == boundrypixel
)
738 if (!FloodFill_rec(image
, x
, y
,
740 dc
->w
.DCOrgX
+ dc
->w
.DCSizeX
,
741 dc
->w
.DCOrgY
+ dc
->w
.DCSizeY
,
742 boundrypixel
, dc
->u
.x
.brush
.pixel
)) {
743 XDestroyImage(image
);
747 XPutImage(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, image
,
749 dc
->w
.DCOrgX
, dc
->w
.DCOrgY
,
750 dc
->w
.DCSizeX
, dc
->w
.DCSizeY
);
751 XDestroyImage(image
);