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 static inline swap_int(int *a
, int *b
)
32 /***********************************************************************
35 BOOL
LineTo( HDC hdc
, short x
, short y
)
37 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
40 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
41 if (!dc
) return FALSE
;
42 MF_MetaParam2(dc
, META_LINETO
, x
, y
);
46 if (DC_SetupGCForPen( dc
))
47 XDrawLine(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
48 dc
->w
.DCOrgX
+ XLPTODP( dc
, dc
->w
.CursPosX
),
49 dc
->w
.DCOrgY
+ YLPTODP( dc
, dc
->w
.CursPosY
),
50 dc
->w
.DCOrgX
+ XLPTODP( dc
, x
),
51 dc
->w
.DCOrgY
+ YLPTODP( dc
, y
) );
58 /***********************************************************************
61 DWORD
MoveTo( HDC hdc
, short x
, short y
)
64 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
67 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
68 if (!dc
) return FALSE
;
69 MF_MetaParam2(dc
, META_MOVETO
, x
, y
);
73 oldx
= dc
->w
.CursPosX
;
74 oldy
= dc
->w
.CursPosY
;
77 return oldx
| (oldy
<< 16);
81 /***********************************************************************
84 BOOL
MoveToEx( HDC hdc
, short x
, short y
, LPPOINT pt
)
86 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
87 if (!dc
) return FALSE
;
90 pt
->x
= dc
->w
.CursPosX
;
91 pt
->y
= dc
->w
.CursPosY
;
99 /***********************************************************************
102 * Helper functions for Arc(), Chord() and Pie().
103 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
105 BOOL
GRAPH_DrawArc( HDC hdc
, int left
, int top
, int right
, int bottom
,
106 int xstart
, int ystart
, int xend
, int yend
, int lines
)
108 int xcenter
, ycenter
, istart_angle
, idiff_angle
;
109 double start_angle
, end_angle
;
111 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
114 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
115 if (!dc
) return FALSE
;
119 MF_MetaParam8(dc
, META_ARC
, left
, top
, right
, bottom
,
120 xstart
, ystart
, xend
, yend
);
124 MF_MetaParam8(dc
, META_CHORD
, left
, top
, right
, bottom
,
125 xstart
, ystart
, xend
, yend
);
129 MF_MetaParam8(dc
, META_PIE
, left
, top
, right
, bottom
,
130 xstart
, ystart
, xend
, yend
);
136 left
= XLPTODP( dc
, left
);
137 top
= YLPTODP( dc
, top
);
138 right
= XLPTODP( dc
, right
);
139 bottom
= YLPTODP( dc
, bottom
);
140 xstart
= XLPTODP( dc
, xstart
);
141 ystart
= YLPTODP( dc
, ystart
);
142 xend
= XLPTODP( dc
, xend
);
143 yend
= YLPTODP( dc
, yend
);
144 if ((left
== right
) || (top
== bottom
)) return FALSE
;
146 if (!DC_SetupGCForPen( dc
)) return TRUE
;
148 xcenter
= (right
+ left
) / 2;
149 ycenter
= (bottom
+ top
) / 2;
150 start_angle
= atan2( (double)(ycenter
-ystart
)*(right
-left
),
151 (double)(xstart
-xcenter
)*(bottom
-top
) );
152 end_angle
= atan2( (double)(ycenter
-yend
)*(right
-left
),
153 (double)(xend
-xcenter
)*(bottom
-top
) );
154 istart_angle
= (int)(start_angle
* 180 * 64 / PI
);
155 idiff_angle
= (int)((end_angle
- start_angle
) * 180 * 64 / PI
);
156 if (idiff_angle
<= 0) idiff_angle
+= 360 * 64;
157 if (left
> right
) swap_int( &left
, &right
);
158 if (top
> bottom
) swap_int( &top
, &bottom
);
160 XDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
161 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
162 right
-left
-1, bottom
-top
-1, istart_angle
, idiff_angle
);
163 if (!lines
) return TRUE
;
165 points
[0].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(start_angle
) * (right
-left
) / 2);
166 points
[0].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(start_angle
) * (bottom
-top
) / 2);
167 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(end_angle
) * (right
-left
) / 2);
168 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(end_angle
) * (bottom
-top
) / 2);
171 points
[2] = points
[1];
172 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
;
173 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
;
175 XDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
176 points
, lines
+1, CoordModeOrigin
);
181 /***********************************************************************
184 BOOL
Arc( HDC hdc
, int left
, int top
, int right
, int bottom
,
185 int xstart
, int ystart
, int xend
, int yend
)
187 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
188 xstart
, ystart
, xend
, yend
, 0 );
192 /***********************************************************************
195 BOOL
Pie( HDC hdc
, int left
, int top
, int right
, int bottom
,
196 int xstart
, int ystart
, int xend
, int yend
)
198 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
199 xstart
, ystart
, xend
, yend
, 2 );
203 /***********************************************************************
206 BOOL
Chord( HDC hdc
, int left
, int top
, int right
, int bottom
,
207 int xstart
, int ystart
, int xend
, int yend
)
209 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
210 xstart
, ystart
, xend
, yend
, 1 );
214 /***********************************************************************
217 BOOL
Ellipse( HDC hdc
, int left
, int top
, int right
, int bottom
)
219 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
222 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
223 if (!dc
) return FALSE
;
224 MF_MetaParam4(dc
, META_ELLIPSE
, left
, top
, right
, bottom
);
228 left
= XLPTODP( dc
, left
);
229 top
= YLPTODP( dc
, top
);
230 right
= XLPTODP( dc
, right
);
231 bottom
= YLPTODP( dc
, bottom
);
232 if ((left
== right
) || (top
== bottom
)) return FALSE
;
235 swap_int(&right
, &left
);
238 swap_int(&bottom
, &top
);
240 if (DC_SetupGCForBrush( dc
))
241 XFillArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
242 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
243 right
-left
-1, bottom
-top
-1, 0, 360*64 );
244 if (DC_SetupGCForPen( dc
))
245 XDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
246 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
247 right
-left
-1, bottom
-top
-1, 0, 360*64 );
252 /***********************************************************************
255 BOOL
Rectangle( HDC hdc
, int left
, int top
, int right
, int bottom
)
257 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
260 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
261 if (!dc
) return FALSE
;
262 MF_MetaParam4(dc
, META_RECTANGLE
, left
, top
, right
, bottom
);
265 left
= XLPTODP( dc
, left
);
266 top
= YLPTODP( dc
, top
);
267 right
= XLPTODP( dc
, right
);
268 bottom
= YLPTODP( dc
, bottom
);
271 swap_int(&right
, &left
);
274 swap_int(&bottom
, &top
);
276 if ((left
== right
) || (top
== bottom
)) {
277 if (DC_SetupGCForPen( dc
))
278 XDrawLine(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
281 dc
->w
.DCOrgX
+ right
,
282 dc
->w
.DCOrgY
+ bottom
);
286 if (DC_SetupGCForBrush( dc
))
287 XFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
288 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
289 right
-left
, bottom
-top
);
290 if (DC_SetupGCForPen( dc
))
291 XDrawRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
292 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
293 right
-left
-1, bottom
-top
-1 );
298 /***********************************************************************
301 BOOL
RoundRect( HDC hDC
, short left
, short top
, short right
, short bottom
,
302 short ell_width
, short ell_height
)
305 DC
* dc
= (DC
*) GDI_GetObjPtr(hDC
, DC_MAGIC
);
308 dc
= (DC
*)GDI_GetObjPtr(hDC
, METAFILE_DC_MAGIC
);
309 if (!dc
) return FALSE
;
310 MF_MetaParam6(dc
, META_ROUNDRECT
, left
, top
, right
, bottom
,
311 ell_width
, ell_height
);
315 printf("RoundRect(%d %d %d %d %d %d\n",
316 left, top, right, bottom, ell_width, ell_height);
318 x1
= XLPTODP(dc
, left
);
319 y1
= YLPTODP(dc
, top
);
320 x2
= XLPTODP(dc
, right
- ell_width
);
321 y2
= YLPTODP(dc
, bottom
- ell_height
);
322 if (DC_SetupGCForBrush(dc
)) {
323 XFillArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
324 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y1
,
325 ell_width
, ell_height
, 90 * 64, 90 * 64);
326 XFillArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
327 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y2
,
328 ell_width
, ell_height
, 180 * 64, 90 * 64);
329 XFillArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
330 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y2
,
331 ell_width
, ell_height
, 270 * 64, 90 * 64);
332 XFillArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
333 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y1
,
334 ell_width
, ell_height
, 0, 90 * 64);
335 ell_width
/= 2; ell_height
/= 2;
336 XFillRectangle(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
337 dc
->w
.DCOrgX
+ left
+ ell_width
, dc
->w
.DCOrgY
+ top
,
338 right
- left
- 2 * ell_width
, bottom
- top
);
339 XFillRectangle(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
340 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
+ ell_height
,
341 ell_width
, bottom
- top
- 2 * ell_height
);
342 XFillRectangle(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
343 dc
->w
.DCOrgX
+ right
- ell_width
, dc
->w
.DCOrgY
+ top
+ ell_height
,
344 ell_width
, bottom
- top
- 2 * ell_height
);
345 ell_width
*= 2; ell_height
*= 2;
347 if (DC_SetupGCForPen(dc
)) {
348 XDrawArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
349 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y1
,
350 ell_width
, ell_height
, 90 * 64, 90 * 64);
351 XDrawArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
352 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y2
,
353 ell_width
, ell_height
, 180 * 64, 90 * 64);
354 XDrawArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
355 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y2
,
356 ell_width
, ell_height
, 270 * 64, 90 * 64);
357 XDrawArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
358 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y1
,
359 ell_width
, ell_height
, 0, 90 * 64);
361 ell_width
/= 2; ell_height
/= 2;
362 MoveTo(hDC
, left
, top
+ ell_height
);
363 LineTo(hDC
, left
, bottom
- ell_height
);
364 MoveTo(hDC
, left
+ ell_width
, bottom
);
365 LineTo(hDC
, right
- ell_width
, bottom
);
366 MoveTo(hDC
, right
, bottom
- ell_height
);
367 LineTo(hDC
, right
, top
+ ell_height
);
368 MoveTo(hDC
, right
- ell_width
, top
);
369 LineTo(hDC
, left
+ ell_width
, top
);
374 /***********************************************************************
377 int FillRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
381 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return 0;
382 if (!(prevBrush
= SelectObject( hdc
, hbrush
))) return 0;
383 PatBlt( hdc
, rect
->left
, rect
->top
,
384 rect
->right
- rect
->left
, rect
->bottom
- rect
->top
, PATCOPY
);
385 SelectObject( hdc
, prevBrush
);
390 /***********************************************************************
391 * InvertRect (USER.82)
393 void InvertRect( HDC hdc
, LPRECT rect
)
395 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return;
396 PatBlt( hdc
, rect
->left
, rect
->top
,
397 rect
->right
- rect
->left
, rect
->bottom
- rect
->top
, DSTINVERT
);
401 /***********************************************************************
402 * FrameRect (USER.83)
404 int FrameRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
407 int left
, top
, right
, bottom
;
409 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
410 if (!dc
) return FALSE
;
412 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return 0;
413 if (!(prevBrush
= SelectObject( hdc
, hbrush
))) return 0;
415 left
= XLPTODP( dc
, rect
->left
);
416 top
= YLPTODP( dc
, rect
->top
);
417 right
= XLPTODP( dc
, rect
->right
);
418 bottom
= YLPTODP( dc
, rect
->bottom
);
420 if (DC_SetupGCForBrush( dc
)) {
421 PatBlt( hdc
, rect
->left
, rect
->top
, 1,
422 rect
->bottom
- rect
->top
, PATCOPY
);
423 PatBlt( hdc
, rect
->right
- 1, rect
->top
, 1,
424 rect
->bottom
- rect
->top
, PATCOPY
);
425 PatBlt( hdc
, rect
->left
, rect
->top
,
426 rect
->right
- rect
->left
, 1, PATCOPY
);
427 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
428 rect
->right
- rect
->left
, 1, PATCOPY
);
430 SelectObject( hdc
, prevBrush
);
435 /***********************************************************************
438 COLORREF
SetPixel( HDC hdc
, short x
, short y
, COLORREF color
)
443 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
446 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
448 MF_MetaParam4(dc
, META_SETPIXEL
, x
, y
, HIWORD(color
), LOWORD(color
));
452 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
453 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
454 pixel
= COLOR_ToPhysical( dc
, color
);
455 GetPaletteEntries( dc
->w
.hPalette
, pixel
, 1, &entry
);
457 XSetForeground( display
, dc
->u
.x
.gc
, pixel
);
458 XSetFunction( display
, dc
->u
.x
.gc
, GXcopy
);
459 XDrawPoint( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, x
, y
);
461 return RGB( entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
465 /***********************************************************************
468 COLORREF
GetPixel( HDC hdc
, short x
, short y
)
473 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
476 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
477 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
478 if ((x
< 0) || (y
< 0)) return 0;
480 if (!(dc
->w
.flags
& DC_MEMORY
))
482 XWindowAttributes win_attr
;
484 if (!XGetWindowAttributes( display
, dc
->u
.x
.drawable
, &win_attr
))
486 if (win_attr
.map_state
!= IsViewable
) return 0;
487 if ((x
>= win_attr
.width
) || (y
>= win_attr
.height
)) return 0;
490 image
= XGetImage( display
, dc
->u
.x
.drawable
, x
, y
,
491 1, 1, AllPlanes
, ZPixmap
);
492 GetPaletteEntries( dc
->w
.hPalette
, XGetPixel( image
, 0, 0 ), 1, &entry
);
493 XDestroyImage( image
);
494 return RGB( entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
498 /***********************************************************************
501 BOOL
PaintRgn( HDC hdc
, HRGN hrgn
)
504 HRGN tmpVisRgn
, prevVisRgn
;
505 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
506 if (!dc
) return FALSE
;
508 /* Modify visible region */
510 prevVisRgn
= SaveVisRgn( hdc
);
513 if (!(tmpVisRgn
= CreateRectRgn( 0, 0, 0, 0 )))
515 RestoreVisRgn( hdc
);
518 CombineRgn( tmpVisRgn
, prevVisRgn
, hrgn
, RGN_AND
);
519 SelectVisRgn( hdc
, tmpVisRgn
);
520 DeleteObject( tmpVisRgn
);
522 else SelectVisRgn( hdc
, hrgn
);
524 /* Fill the region */
526 GetClipBox( hdc
, &box
);
527 if (DC_SetupGCForBrush( dc
))
528 XFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
529 dc
->w
.DCOrgX
+ box
.left
, dc
->w
.DCOrgY
+ box
.top
,
530 box
.right
-box
.left
, box
.bottom
-box
.top
);
532 /* Restore the visible region */
534 if (prevVisRgn
) RestoreVisRgn( hdc
);
535 else SelectVisRgn( hdc
, 0 );
540 /***********************************************************************
543 BOOL
FillRgn( HDC hdc
, HRGN hrgn
, HBRUSH hbrush
)
546 HBRUSH prevBrush
= SelectObject( hdc
, hbrush
);
547 if (!prevBrush
) return FALSE
;
548 retval
= PaintRgn( hdc
, hrgn
);
549 SelectObject( hdc
, prevBrush
);
554 /***********************************************************************
555 * DrawFocusRect (USER.466)
557 void DrawFocusRect( HDC hdc
, LPRECT rc
)
560 int oldDrawMode
, oldBkMode
;
561 int left
, top
, right
, bottom
;
562 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
565 left
= XLPTODP( dc
, rc
->left
);
566 top
= YLPTODP( dc
, rc
->top
);
567 right
= XLPTODP( dc
, rc
->right
);
568 bottom
= YLPTODP( dc
, rc
->bottom
);
570 hOldPen
= (HPEN
)SelectObject(hdc
, sysColorObjects
.hpenWindowText
);
571 oldDrawMode
= SetROP2(hdc
, R2_XORPEN
);
572 oldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
574 if (DC_SetupGCForPen( dc
))
575 XDrawRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
576 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
577 right
-left
-1, bottom
-top
-1 );
579 SetBkMode(hdc
, oldBkMode
);
580 SetROP2(hdc
, oldDrawMode
);
581 SelectObject(hdc
, (HANDLE
)hOldPen
);
585 /**********************************************************************
586 * DrawReliefRect (Not a MSWin Call)
588 void DrawReliefRect( HDC hdc
, RECT rect
, int thickness
, BOOL pressed
)
593 hbrushOld
= SelectObject( hdc
, pressed
? sysColorObjects
.hbrushBtnShadow
:
594 sysColorObjects
.hbrushBtnHighlight
);
595 for (i
= 0; i
< thickness
; i
++)
597 PatBlt( hdc
, rect
.left
+ i
, rect
.top
,
598 1, rect
.bottom
- rect
.top
- i
, PATCOPY
);
599 PatBlt( hdc
, rect
.left
, rect
.top
+ i
,
600 rect
.right
- rect
.left
- i
, 1, PATCOPY
);
603 SelectObject( hdc
, pressed
? sysColorObjects
.hbrushBtnHighlight
:
604 sysColorObjects
.hbrushBtnShadow
);
605 for (i
= 0; i
< thickness
; i
++)
607 PatBlt( hdc
, rect
.right
- i
- 1, rect
.top
+ i
,
608 1, rect
.bottom
- rect
.top
- i
, PATCOPY
);
609 PatBlt( hdc
, rect
.left
+ i
, rect
.bottom
- i
- 1,
610 rect
.right
- rect
.left
- i
, 1, PATCOPY
);
613 SelectObject( hdc
, hbrushOld
);
617 /**********************************************************************
620 BOOL
Polyline (HDC hdc
, LPPOINT pt
, int count
)
623 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
626 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
627 if (!dc
) return FALSE
;
628 MF_MetaPoly(dc
, META_POLYLINE
, pt
, count
);
632 if (DC_SetupGCForPen( dc
))
634 for (i
= 0; i
< count
-1; i
++)
635 XDrawLine (display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
636 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
].x
),
637 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
].y
),
638 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
+1].x
),
639 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
+1].y
));
640 XDrawLine (display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
641 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[count
-1].x
),
642 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[count
-1].y
),
643 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[0].x
),
644 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[0].y
));
651 /**********************************************************************
654 BOOL
Polygon (HDC hdc
, LPPOINT pt
, int count
)
657 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
658 XPoint
*points
= (XPoint
*) malloc (sizeof (XPoint
) * (count
+1));
662 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
663 if (!dc
) return FALSE
;
664 MF_MetaPoly(dc
, META_POLYGON
, pt
, count
);
668 for (i
= 0; i
< count
; i
++)
670 points
[i
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
[i
].x
);
671 points
[i
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
[i
].y
);
673 points
[count
] = points
[0];
675 if (DC_SetupGCForBrush( dc
))
676 XFillPolygon( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
677 points
, count
+1, Complex
, CoordModeOrigin
);
679 if (DC_SetupGCForPen ( dc
))
680 XDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
681 points
, count
+1, CoordModeOrigin
);
688 /**********************************************************************
689 * PolyPolygon (GDI.450)
691 BOOL
PolyPolygon( HDC hdc
, LPPOINT pt
, LPINT counts
, WORD polygons
)
695 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
699 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
700 if (!dc
) return FALSE
;
701 /* MF_MetaPoly(dc, META_POLYGON, pt, count); */
704 /* The points should be converted to device coords before */
705 /* creating the region. But as CreatePolyPolygonRgn is not */
706 /* really correct either, it doesn't matter much... */
707 /* At least the outline will be correct :-) */
708 hrgn
= CreatePolyPolygonRgn( pt
, counts
, polygons
, dc
->w
.polyFillMode
);
709 PaintRgn( hdc
, hrgn
);
710 DeleteObject( hrgn
);
712 /* Draw the outline of the polygons */
714 if (DC_SetupGCForPen ( dc
))
719 for (i
= 0; i
< polygons
; i
++) if (counts
[i
] > max
) max
= counts
[i
];
720 points
= (XPoint
*) malloc( sizeof(XPoint
) * (max
+1) );
722 for (i
= 0; i
< polygons
; i
++)
724 for (j
= 0; j
< counts
[i
]; j
++)
726 points
[j
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
->x
);
727 points
[j
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
->y
);
730 points
[j
] = points
[0];
731 XDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
732 points
, j
+ 1, CoordModeOrigin
);
740 /**********************************************************************
741 * FloodFill_rec -- FloodFill helper function
743 * Just does a recursive flood fill:
744 * this is /not/ efficent -- a better way would be to draw
745 * an entire line at a time, but this will do for now.
747 static BOOL
FloodFill_rec(XImage
*image
, int x
, int y
,
748 int orgx
, int orgy
, int endx
, int endy
,
749 Pixel borderp
, Pixel fillp
)
753 if (x
> endx
|| x
< orgx
|| y
> endy
|| y
< orgy
)
755 XPutPixel(image
, x
, y
, fillp
);
757 if ((x
+1 <= endx
) && (y
+1 <= endy
)) {
758 testp
= XGetPixel(image
, x
+1, y
+1);
759 if (testp
!= borderp
&& testp
!= fillp
)
760 FloodFill_rec(image
, x
+1, y
+1, orgx
, orgy
,
761 endx
, endy
, borderp
, fillp
);
763 if ((x
+1 <= endx
) && (y
-1 >= orgy
)) {
764 testp
= XGetPixel(image
, x
+1, y
-1);
765 if (testp
!= borderp
&& testp
!= fillp
)
766 FloodFill_rec(image
, x
+1, y
-1, orgx
, orgy
,
767 endx
, endy
, borderp
, fillp
);
769 if ((x
-1 >= orgx
) && (y
+1 <= endy
)) {
770 testp
= XGetPixel(image
, x
-1, y
+1);
771 if (testp
!= borderp
&& testp
!= fillp
)
772 FloodFill_rec(image
, x
-1, y
+1, orgx
, orgy
,
773 endx
, endy
, borderp
, fillp
);
775 if ((x
-1 >= orgx
) && (y
-1 >= orgy
)) {
776 testp
= XGetPixel(image
, x
-1, y
-1);
777 if (testp
!= borderp
&& testp
!= fillp
)
778 FloodFill_rec(image
, x
-1, y
-1, orgx
, orgy
,
779 endx
, endy
, borderp
, fillp
);
785 /**********************************************************************
788 BOOL
FloodFill(HDC hdc
, short x
, short y
, DWORD crColor
)
795 #ifdef DEBUG_GRAPHICS
796 printf("FloodFill %x %d,%d %x\n", hdc
, x
, y
, crColor
);
798 dc
= (DC
*) GDI_GetObjPtr(hdc
, DC_MAGIC
);
801 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
802 if (!dc
) return FALSE
;
803 MF_MetaParam4(dc
, META_FLOODFILL
, x
, y
, HIWORD(crColor
),
808 x
= dc
->w
.DCOrgX
+ XLPTODP(dc
, x
);
809 y
= dc
->w
.DCOrgY
+ YLPTODP(dc
, y
);
811 if (x
< dc
->w
.DCOrgX
|| x
> dc
->w
.DCOrgX
+ dc
->w
.DCSizeX
||
812 y
< dc
->w
.DCOrgY
|| y
> dc
->w
.DCOrgY
+ dc
->w
.DCSizeY
)
815 if (!DC_SetupGCForBrush(dc
))
818 boundrypixel
= GetNearestPaletteIndex( dc
->w
.hPalette
, crColor
);
820 image
= XGetImage(display
, dc
->u
.x
.drawable
,
821 dc
->w
.DCOrgX
, dc
->w
.DCOrgY
,
822 dc
->w
.DCSizeX
, dc
->w
.DCSizeY
, AllPlanes
, ZPixmap
);
823 if (XGetPixel(image
, x
, y
) == boundrypixel
)
825 if (!FloodFill_rec(image
, x
, y
,
829 boundrypixel
, dc
->u
.x
.brush
.pixel
)) {
830 XDestroyImage(image
);
834 XPutImage(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, image
,
836 dc
->w
.DCOrgX
, dc
->w
.DCOrgY
,
837 dc
->w
.DCSizeX
, dc
->w
.DCSizeY
);
838 XDestroyImage(image
);