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 const int DC_XROPfunction
[];
23 extern int COLOR_ToPhysical( DC
*dc
, COLORREF color
);
25 static inline swap_int(int *a
, int *b
)
34 /***********************************************************************
37 BOOL
LineTo( HDC hdc
, short x
, short y
)
39 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
42 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
43 if (!dc
) return FALSE
;
44 MF_MetaParam2(dc
, META_LINETO
, x
, y
);
48 if (DC_SetupGCForPen( dc
))
49 XDrawLine(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
50 dc
->w
.DCOrgX
+ XLPTODP( dc
, dc
->w
.CursPosX
),
51 dc
->w
.DCOrgY
+ YLPTODP( dc
, dc
->w
.CursPosY
),
52 dc
->w
.DCOrgX
+ XLPTODP( dc
, x
),
53 dc
->w
.DCOrgY
+ YLPTODP( dc
, y
) );
60 /***********************************************************************
63 DWORD
MoveTo( HDC hdc
, short x
, short y
)
66 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
69 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
70 if (!dc
) return FALSE
;
71 MF_MetaParam2(dc
, META_MOVETO
, x
, y
);
75 oldx
= dc
->w
.CursPosX
;
76 oldy
= dc
->w
.CursPosY
;
79 return oldx
| (oldy
<< 16);
83 /***********************************************************************
86 BOOL
MoveToEx( HDC hdc
, short x
, short y
, LPPOINT pt
)
88 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
89 if (!dc
) return FALSE
;
92 pt
->x
= dc
->w
.CursPosX
;
93 pt
->y
= dc
->w
.CursPosY
;
101 /***********************************************************************
104 * Helper functions for Arc(), Chord() and Pie().
105 * 'lines' is the number of lines to draw: 0 for Arc, 1 for Chord, 2 for Pie.
107 BOOL
GRAPH_DrawArc( HDC hdc
, int left
, int top
, int right
, int bottom
,
108 int xstart
, int ystart
, int xend
, int yend
, int lines
)
110 int xcenter
, ycenter
, istart_angle
, idiff_angle
;
111 double start_angle
, end_angle
;
113 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
116 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
117 if (!dc
) return FALSE
;
121 MF_MetaParam8(dc
, META_ARC
, left
, top
, right
, bottom
,
122 xstart
, ystart
, xend
, yend
);
126 MF_MetaParam8(dc
, META_CHORD
, left
, top
, right
, bottom
,
127 xstart
, ystart
, xend
, yend
);
131 MF_MetaParam8(dc
, META_PIE
, left
, top
, right
, bottom
,
132 xstart
, ystart
, xend
, yend
);
138 left
= XLPTODP( dc
, left
);
139 top
= YLPTODP( dc
, top
);
140 right
= XLPTODP( dc
, right
);
141 bottom
= YLPTODP( dc
, bottom
);
142 xstart
= XLPTODP( dc
, xstart
);
143 ystart
= YLPTODP( dc
, ystart
);
144 xend
= XLPTODP( dc
, xend
);
145 yend
= YLPTODP( dc
, yend
);
146 if ((left
== right
) || (top
== bottom
)) return FALSE
;
148 if (!DC_SetupGCForPen( dc
)) return TRUE
;
150 xcenter
= (right
+ left
) / 2;
151 ycenter
= (bottom
+ top
) / 2;
152 start_angle
= atan2( (double)(ycenter
-ystart
)*(right
-left
),
153 (double)(xstart
-xcenter
)*(bottom
-top
) );
154 end_angle
= atan2( (double)(ycenter
-yend
)*(right
-left
),
155 (double)(xend
-xcenter
)*(bottom
-top
) );
156 istart_angle
= (int)(start_angle
* 180 * 64 / PI
);
157 idiff_angle
= (int)((end_angle
- start_angle
) * 180 * 64 / PI
);
158 if (idiff_angle
<= 0) idiff_angle
+= 360 * 64;
159 if (left
> right
) swap_int( &left
, &right
);
160 if (top
> bottom
) swap_int( &top
, &bottom
);
162 XDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
163 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
164 right
-left
-1, bottom
-top
-1, istart_angle
, idiff_angle
);
165 if (!lines
) return TRUE
;
167 points
[0].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(start_angle
) * (right
-left
) / 2);
168 points
[0].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(start_angle
) * (bottom
-top
) / 2);
169 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
+ (int)(cos(end_angle
) * (right
-left
) / 2);
170 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
- (int)(sin(end_angle
) * (bottom
-top
) / 2);
173 points
[2] = points
[1];
174 points
[1].x
= dc
->w
.DCOrgX
+ xcenter
;
175 points
[1].y
= dc
->w
.DCOrgY
+ ycenter
;
177 XDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
178 points
, lines
+1, CoordModeOrigin
);
183 /***********************************************************************
186 BOOL
Arc( HDC hdc
, int left
, int top
, int right
, int bottom
,
187 int xstart
, int ystart
, int xend
, int yend
)
189 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
190 xstart
, ystart
, xend
, yend
, 0 );
194 /***********************************************************************
197 BOOL
Pie( HDC hdc
, int left
, int top
, int right
, int bottom
,
198 int xstart
, int ystart
, int xend
, int yend
)
200 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
201 xstart
, ystart
, xend
, yend
, 2 );
205 /***********************************************************************
208 BOOL
Chord( HDC hdc
, int left
, int top
, int right
, int bottom
,
209 int xstart
, int ystart
, int xend
, int yend
)
211 return GRAPH_DrawArc( hdc
, left
, top
, right
, bottom
,
212 xstart
, ystart
, xend
, yend
, 1 );
216 /***********************************************************************
219 BOOL
Ellipse( HDC hdc
, int left
, int top
, int right
, int bottom
)
221 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
224 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
225 if (!dc
) return FALSE
;
226 MF_MetaParam4(dc
, META_ELLIPSE
, left
, top
, right
, bottom
);
230 left
= XLPTODP( dc
, left
);
231 top
= YLPTODP( dc
, top
);
232 right
= XLPTODP( dc
, right
);
233 bottom
= YLPTODP( dc
, bottom
);
234 if ((left
== right
) || (top
== bottom
)) return FALSE
;
237 swap_int(&right
, &left
);
240 swap_int(&bottom
, &top
);
242 if (DC_SetupGCForBrush( dc
))
243 XFillArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
244 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
245 right
-left
-1, bottom
-top
-1, 0, 360*64 );
246 if (DC_SetupGCForPen( dc
))
247 XDrawArc( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
248 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
249 right
-left
-1, bottom
-top
-1, 0, 360*64 );
254 /***********************************************************************
257 BOOL
Rectangle( HDC hdc
, int left
, int top
, int right
, int bottom
)
259 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
262 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
263 if (!dc
) return FALSE
;
264 MF_MetaParam4(dc
, META_RECTANGLE
, left
, top
, right
, bottom
);
267 left
= XLPTODP( dc
, left
);
268 top
= YLPTODP( dc
, top
);
269 right
= XLPTODP( dc
, right
);
270 bottom
= YLPTODP( dc
, bottom
);
273 swap_int(&right
, &left
);
276 swap_int(&bottom
, &top
);
278 if ((left
== right
) || (top
== bottom
)) {
279 if (DC_SetupGCForPen( dc
))
280 XDrawLine(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
283 dc
->w
.DCOrgX
+ right
,
284 dc
->w
.DCOrgY
+ bottom
);
288 if (DC_SetupGCForBrush( dc
))
289 XFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
290 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
291 right
-left
, bottom
-top
);
292 if (DC_SetupGCForPen( dc
))
293 XDrawRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
294 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
295 right
-left
-1, bottom
-top
-1 );
300 /***********************************************************************
303 BOOL
RoundRect( HDC hDC
, short left
, short top
, short right
, short bottom
,
304 short ell_width
, short ell_height
)
307 DC
* dc
= (DC
*) GDI_GetObjPtr(hDC
, DC_MAGIC
);
310 dc
= (DC
*)GDI_GetObjPtr(hDC
, METAFILE_DC_MAGIC
);
311 if (!dc
) return FALSE
;
312 MF_MetaParam6(dc
, META_ROUNDRECT
, left
, top
, right
, bottom
,
313 ell_width
, ell_height
);
317 printf("RoundRect(%d %d %d %d %d %d\n",
318 left, top, right, bottom, ell_width, ell_height);
320 x1
= XLPTODP(dc
, left
);
321 y1
= YLPTODP(dc
, top
);
322 x2
= XLPTODP(dc
, right
- ell_width
);
323 y2
= YLPTODP(dc
, bottom
- ell_height
);
324 if (DC_SetupGCForBrush(dc
)) {
325 XFillArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
326 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y1
,
327 ell_width
, ell_height
, 90 * 64, 90 * 64);
328 XFillArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
329 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y2
,
330 ell_width
, ell_height
, 180 * 64, 90 * 64);
331 XFillArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
332 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y2
,
333 ell_width
, ell_height
, 270 * 64, 90 * 64);
334 XFillArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
335 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y1
,
336 ell_width
, ell_height
, 0, 90 * 64);
337 ell_width
/= 2; ell_height
/= 2;
338 XFillRectangle(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
339 dc
->w
.DCOrgX
+ left
+ ell_width
, dc
->w
.DCOrgY
+ top
,
340 right
- left
- 2 * ell_width
, bottom
- top
);
341 XFillRectangle(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
342 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
+ ell_height
,
343 ell_width
, bottom
- top
- 2 * ell_height
);
344 XFillRectangle(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
345 dc
->w
.DCOrgX
+ right
- ell_width
, dc
->w
.DCOrgY
+ top
+ ell_height
,
346 ell_width
, bottom
- top
- 2 * ell_height
);
347 ell_width
*= 2; ell_height
*= 2;
349 if (DC_SetupGCForPen(dc
)) {
350 XDrawArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
351 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y1
,
352 ell_width
, ell_height
, 90 * 64, 90 * 64);
353 XDrawArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
354 dc
->w
.DCOrgX
+ x1
, dc
->w
.DCOrgY
+ y2
,
355 ell_width
, ell_height
, 180 * 64, 90 * 64);
356 XDrawArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
357 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y2
,
358 ell_width
, ell_height
, 270 * 64, 90 * 64);
359 XDrawArc(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
360 dc
->w
.DCOrgX
+ x2
, dc
->w
.DCOrgY
+ y1
,
361 ell_width
, ell_height
, 0, 90 * 64);
363 ell_width
/= 2; ell_height
/= 2;
364 MoveTo(hDC
, left
, top
+ ell_height
);
365 LineTo(hDC
, left
, bottom
- ell_height
);
366 MoveTo(hDC
, left
+ ell_width
, bottom
);
367 LineTo(hDC
, right
- ell_width
, bottom
);
368 MoveTo(hDC
, right
, bottom
- ell_height
);
369 LineTo(hDC
, right
, top
+ ell_height
);
370 MoveTo(hDC
, right
- ell_width
, top
);
371 LineTo(hDC
, left
+ ell_width
, top
);
376 /***********************************************************************
379 int FillRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
383 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return 0;
384 if (!(prevBrush
= SelectObject( hdc
, hbrush
))) return 0;
385 PatBlt( hdc
, rect
->left
, rect
->top
,
386 rect
->right
- rect
->left
, rect
->bottom
- rect
->top
, PATCOPY
);
387 SelectObject( hdc
, prevBrush
);
392 /***********************************************************************
393 * InvertRect (USER.82)
395 void InvertRect( HDC hdc
, LPRECT rect
)
397 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return;
398 PatBlt( hdc
, rect
->left
, rect
->top
,
399 rect
->right
- rect
->left
, rect
->bottom
- rect
->top
, DSTINVERT
);
403 /***********************************************************************
404 * FrameRect (USER.83)
406 int FrameRect( HDC hdc
, LPRECT rect
, HBRUSH hbrush
)
409 int left
, top
, right
, bottom
;
411 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
412 if (!dc
) return FALSE
;
414 if ((rect
->right
<= rect
->left
) || (rect
->bottom
<= rect
->top
)) return 0;
415 if (!(prevBrush
= SelectObject( hdc
, hbrush
))) return 0;
417 left
= XLPTODP( dc
, rect
->left
);
418 top
= YLPTODP( dc
, rect
->top
);
419 right
= XLPTODP( dc
, rect
->right
);
420 bottom
= YLPTODP( dc
, rect
->bottom
);
422 if (DC_SetupGCForBrush( dc
)) {
423 PatBlt( hdc
, rect
->left
, rect
->top
, 1,
424 rect
->bottom
- rect
->top
, PATCOPY
);
425 PatBlt( hdc
, rect
->right
- 1, rect
->top
, 1,
426 rect
->bottom
- rect
->top
, PATCOPY
);
427 PatBlt( hdc
, rect
->left
, rect
->top
,
428 rect
->right
- rect
->left
, 1, PATCOPY
);
429 PatBlt( hdc
, rect
->left
, rect
->bottom
- 1,
430 rect
->right
- rect
->left
, 1, PATCOPY
);
432 SelectObject( hdc
, prevBrush
);
437 /***********************************************************************
440 COLORREF
SetPixel( HDC hdc
, short x
, short y
, COLORREF color
)
445 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
448 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
450 MF_MetaParam4(dc
, META_SETPIXEL
, x
, y
, HIWORD(color
), LOWORD(color
));
454 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
455 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
456 pixel
= COLOR_ToPhysical( dc
, color
);
457 GetPaletteEntries( dc
->w
.hPalette
, pixel
, 1, &entry
);
459 XSetForeground( display
, dc
->u
.x
.gc
, pixel
);
460 XSetFunction( display
, dc
->u
.x
.gc
, GXcopy
);
461 XDrawPoint( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, x
, y
);
463 return RGB( entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
467 /***********************************************************************
470 COLORREF
GetPixel( HDC hdc
, short x
, short y
)
475 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
478 #ifdef SOLITAIRE_SPEED_HACK
482 x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, x
);
483 y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, y
);
484 if ((x
< 0) || (y
< 0)) return 0;
486 if (!(dc
->w
.flags
& DC_MEMORY
))
488 XWindowAttributes win_attr
;
490 if (!XGetWindowAttributes( display
, dc
->u
.x
.drawable
, &win_attr
))
492 if (win_attr
.map_state
!= IsViewable
) return 0;
493 if ((x
>= win_attr
.width
) || (y
>= win_attr
.height
)) return 0;
496 image
= XGetImage( display
, dc
->u
.x
.drawable
, x
, y
,
497 1, 1, AllPlanes
, ZPixmap
);
498 GetPaletteEntries( dc
->w
.hPalette
, XGetPixel( image
, 0, 0 ), 1, &entry
);
499 XDestroyImage( image
);
500 return RGB( entry
.peRed
, entry
.peGreen
, entry
.peBlue
);
504 /***********************************************************************
507 BOOL
PaintRgn( HDC hdc
, HRGN hrgn
)
510 HRGN tmpVisRgn
, prevVisRgn
;
511 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
512 if (!dc
) return FALSE
;
514 /* Modify visible region */
516 prevVisRgn
= SaveVisRgn( hdc
);
519 if (!(tmpVisRgn
= CreateRectRgn( 0, 0, 0, 0 )))
521 RestoreVisRgn( hdc
);
524 CombineRgn( tmpVisRgn
, prevVisRgn
, hrgn
, RGN_AND
);
525 SelectVisRgn( hdc
, tmpVisRgn
);
526 DeleteObject( tmpVisRgn
);
528 else SelectVisRgn( hdc
, hrgn
);
530 /* Fill the region */
532 GetClipBox( hdc
, &box
);
533 if (DC_SetupGCForBrush( dc
))
534 XFillRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
535 dc
->w
.DCOrgX
+ box
.left
, dc
->w
.DCOrgY
+ box
.top
,
536 box
.right
-box
.left
, box
.bottom
-box
.top
);
538 /* Restore the visible region */
540 if (prevVisRgn
) RestoreVisRgn( hdc
);
541 else SelectVisRgn( hdc
, 0 );
546 /***********************************************************************
549 BOOL
FillRgn( HDC hdc
, HRGN hrgn
, HBRUSH hbrush
)
552 HBRUSH prevBrush
= SelectObject( hdc
, hbrush
);
553 if (!prevBrush
) return FALSE
;
554 retval
= PaintRgn( hdc
, hrgn
);
555 SelectObject( hdc
, prevBrush
);
560 /***********************************************************************
563 BOOL
InvertRgn( HDC hdc
, HRGN hrgn
)
565 HBRUSH prevBrush
= SelectObject( hdc
, GetStockObject(BLACK_BRUSH
) );
566 WORD prevROP
= SetROP2( hdc
, R2_NOT
);
567 BOOL retval
= PaintRgn( hdc
, hrgn
);
568 SelectObject( hdc
, prevBrush
);
569 SetROP2( hdc
, prevROP
);
574 /***********************************************************************
575 * DrawFocusRect (USER.466)
577 void DrawFocusRect( HDC hdc
, LPRECT rc
)
580 int oldDrawMode
, oldBkMode
;
581 int left
, top
, right
, bottom
;
582 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
585 left
= XLPTODP( dc
, rc
->left
);
586 top
= YLPTODP( dc
, rc
->top
);
587 right
= XLPTODP( dc
, rc
->right
);
588 bottom
= YLPTODP( dc
, rc
->bottom
);
590 hOldPen
= (HPEN
)SelectObject(hdc
, sysColorObjects
.hpenWindowText
);
591 oldDrawMode
= SetROP2(hdc
, R2_XORPEN
);
592 oldBkMode
= SetBkMode(hdc
, TRANSPARENT
);
594 if (DC_SetupGCForPen( dc
))
595 XDrawRectangle( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
596 dc
->w
.DCOrgX
+ left
, dc
->w
.DCOrgY
+ top
,
597 right
-left
-1, bottom
-top
-1 );
599 SetBkMode(hdc
, oldBkMode
);
600 SetROP2(hdc
, oldDrawMode
);
601 SelectObject(hdc
, (HANDLE
)hOldPen
);
605 /**********************************************************************
608 * Short-cut function to blit a bitmap into a device.
609 * Faster than CreateCompatibleDC() + SelectBitmap() + BitBlt() + DeleteDC().
611 BOOL
GRAPH_DrawBitmap( HDC hdc
, HBITMAP hbitmap
, int xdest
, int ydest
,
612 int xsrc
, int ysrc
, int width
, int height
, int rop
)
618 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return FALSE
;
619 if (!(bmp
= (BITMAPOBJ
*) GDI_GetObjPtr( hbitmap
, BITMAP_MAGIC
)))
621 val
.function
= DC_XROPfunction
[(rop
>> 16) & 0x0f];
622 val
.foreground
= dc
->w
.textPixel
;
623 val
.background
= dc
->w
.backgroundPixel
;
624 XChangeGC(display
, dc
->u
.x
.gc
, GCFunction
|GCForeground
|GCBackground
, &val
);
625 if (bmp
->bitmap
.bmBitsPixel
== 1)
627 XCopyPlane( display
, bmp
->pixmap
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
628 xsrc
, ysrc
, width
, height
,
629 dc
->w
.DCOrgX
+ xdest
, dc
->w
.DCOrgY
+ ydest
, 1 );
632 else if (bmp
->bitmap
.bmBitsPixel
== dc
->w
.bitsPerPixel
)
634 XCopyArea( display
, bmp
->pixmap
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
635 xsrc
, ysrc
, width
, height
,
636 dc
->w
.DCOrgX
+ xdest
, dc
->w
.DCOrgY
+ ydest
);
643 /**********************************************************************
644 * DrawReliefRect (Not a MSWin Call)
646 void DrawReliefRect( HDC hdc
, RECT rect
, int thickness
, BOOL pressed
)
651 hbrushOld
= SelectObject( hdc
, pressed
? sysColorObjects
.hbrushBtnShadow
:
652 sysColorObjects
.hbrushBtnHighlight
);
653 for (i
= 0; i
< thickness
; i
++)
655 PatBlt( hdc
, rect
.left
+ i
, rect
.top
,
656 1, rect
.bottom
- rect
.top
- i
, PATCOPY
);
657 PatBlt( hdc
, rect
.left
, rect
.top
+ i
,
658 rect
.right
- rect
.left
- i
, 1, PATCOPY
);
661 SelectObject( hdc
, pressed
? sysColorObjects
.hbrushBtnHighlight
:
662 sysColorObjects
.hbrushBtnShadow
);
663 for (i
= 0; i
< thickness
; i
++)
665 PatBlt( hdc
, rect
.right
- i
- 1, rect
.top
+ i
,
666 1, rect
.bottom
- rect
.top
- i
, PATCOPY
);
667 PatBlt( hdc
, rect
.left
+ i
, rect
.bottom
- i
- 1,
668 rect
.right
- rect
.left
- i
, 1, PATCOPY
);
671 SelectObject( hdc
, hbrushOld
);
675 /**********************************************************************
678 BOOL
Polyline (HDC hdc
, LPPOINT pt
, int count
)
681 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
684 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
685 if (!dc
) return FALSE
;
686 MF_MetaPoly(dc
, META_POLYLINE
, pt
, count
);
690 if (DC_SetupGCForPen( dc
))
692 for (i
= 0; i
< count
-1; i
++)
693 XDrawLine (display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
694 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
].x
),
695 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
].y
),
696 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[i
+1].x
),
697 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[i
+1].y
));
698 XDrawLine (display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
699 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[count
-1].x
),
700 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[count
-1].y
),
701 dc
->w
.DCOrgX
+ XLPTODP(dc
, pt
[0].x
),
702 dc
->w
.DCOrgY
+ YLPTODP(dc
, pt
[0].y
));
709 /**********************************************************************
712 BOOL
Polygon (HDC hdc
, LPPOINT pt
, int count
)
715 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
716 XPoint
*points
= (XPoint
*) malloc (sizeof (XPoint
) * (count
+1));
720 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
721 if (!dc
) return FALSE
;
722 MF_MetaPoly(dc
, META_POLYGON
, pt
, count
);
726 for (i
= 0; i
< count
; i
++)
728 points
[i
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
[i
].x
);
729 points
[i
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
[i
].y
);
731 points
[count
] = points
[0];
733 if (DC_SetupGCForBrush( dc
))
734 XFillPolygon( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
735 points
, count
+1, Complex
, CoordModeOrigin
);
737 if (DC_SetupGCForPen ( dc
))
738 XDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
739 points
, count
+1, CoordModeOrigin
);
746 /**********************************************************************
747 * PolyPolygon (GDI.450)
749 BOOL
PolyPolygon( HDC hdc
, LPPOINT pt
, LPINT counts
, WORD polygons
)
753 DC
* dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
);
757 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
758 if (!dc
) return FALSE
;
759 /* MF_MetaPoly(dc, META_POLYGON, pt, count); */
762 /* The points should be converted to device coords before */
763 /* creating the region. But as CreatePolyPolygonRgn is not */
764 /* really correct either, it doesn't matter much... */
765 /* At least the outline will be correct :-) */
766 hrgn
= CreatePolyPolygonRgn( pt
, counts
, polygons
, dc
->w
.polyFillMode
);
767 PaintRgn( hdc
, hrgn
);
768 DeleteObject( hrgn
);
770 /* Draw the outline of the polygons */
772 if (DC_SetupGCForPen ( dc
))
777 for (i
= 0; i
< polygons
; i
++) if (counts
[i
] > max
) max
= counts
[i
];
778 points
= (XPoint
*) malloc( sizeof(XPoint
) * (max
+1) );
780 for (i
= 0; i
< polygons
; i
++)
782 for (j
= 0; j
< counts
[i
]; j
++)
784 points
[j
].x
= dc
->w
.DCOrgX
+ XLPTODP( dc
, pt
->x
);
785 points
[j
].y
= dc
->w
.DCOrgY
+ YLPTODP( dc
, pt
->y
);
788 points
[j
] = points
[0];
789 XDrawLines( display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
,
790 points
, j
+ 1, CoordModeOrigin
);
798 /**********************************************************************
799 * FloodFill_rec -- FloodFill helper function
801 * Just does a recursive flood fill:
802 * this is /not/ efficent -- a better way would be to draw
803 * an entire line at a time, but this will do for now.
805 static BOOL
FloodFill_rec(XImage
*image
, int x
, int y
,
806 int orgx
, int orgy
, int endx
, int endy
,
807 Pixel borderp
, Pixel fillp
)
811 if (x
> endx
|| x
< orgx
|| y
> endy
|| y
< orgy
)
813 XPutPixel(image
, x
, y
, fillp
);
815 if ((x
+1 <= endx
) && (y
+1 <= endy
)) {
816 testp
= XGetPixel(image
, x
+1, y
+1);
817 if (testp
!= borderp
&& testp
!= fillp
)
818 FloodFill_rec(image
, x
+1, y
+1, orgx
, orgy
,
819 endx
, endy
, borderp
, fillp
);
821 if ((x
+1 <= endx
) && (y
-1 >= orgy
)) {
822 testp
= XGetPixel(image
, x
+1, y
-1);
823 if (testp
!= borderp
&& testp
!= fillp
)
824 FloodFill_rec(image
, x
+1, y
-1, orgx
, orgy
,
825 endx
, endy
, borderp
, fillp
);
827 if ((x
-1 >= orgx
) && (y
+1 <= endy
)) {
828 testp
= XGetPixel(image
, x
-1, y
+1);
829 if (testp
!= borderp
&& testp
!= fillp
)
830 FloodFill_rec(image
, x
-1, y
+1, orgx
, orgy
,
831 endx
, endy
, borderp
, fillp
);
833 if ((x
-1 >= orgx
) && (y
-1 >= orgy
)) {
834 testp
= XGetPixel(image
, x
-1, y
-1);
835 if (testp
!= borderp
&& testp
!= fillp
)
836 FloodFill_rec(image
, x
-1, y
-1, orgx
, orgy
,
837 endx
, endy
, borderp
, fillp
);
843 /**********************************************************************
846 BOOL
FloodFill(HDC hdc
, short x
, short y
, DWORD crColor
)
853 #ifdef DEBUG_GRAPHICS
854 printf("FloodFill %x %d,%d %x\n", hdc
, x
, y
, crColor
);
856 dc
= (DC
*) GDI_GetObjPtr(hdc
, DC_MAGIC
);
859 dc
= (DC
*)GDI_GetObjPtr(hdc
, METAFILE_DC_MAGIC
);
860 if (!dc
) return FALSE
;
861 MF_MetaParam4(dc
, META_FLOODFILL
, x
, y
, HIWORD(crColor
),
866 x
= dc
->w
.DCOrgX
+ XLPTODP(dc
, x
);
867 y
= dc
->w
.DCOrgY
+ YLPTODP(dc
, y
);
869 if (x
< dc
->w
.DCOrgX
|| x
> dc
->w
.DCOrgX
+ dc
->w
.DCSizeX
||
870 y
< dc
->w
.DCOrgY
|| y
> dc
->w
.DCOrgY
+ dc
->w
.DCSizeY
)
873 if (!DC_SetupGCForBrush(dc
))
876 boundrypixel
= GetNearestPaletteIndex( dc
->w
.hPalette
, crColor
);
878 image
= XGetImage(display
, dc
->u
.x
.drawable
,
879 dc
->w
.DCOrgX
, dc
->w
.DCOrgY
,
880 dc
->w
.DCSizeX
, dc
->w
.DCSizeY
, AllPlanes
, ZPixmap
);
881 if (XGetPixel(image
, x
, y
) == boundrypixel
)
883 if (!FloodFill_rec(image
, x
, y
,
887 boundrypixel
, dc
->u
.x
.brush
.pixel
)) {
888 XDestroyImage(image
);
892 XPutImage(display
, dc
->u
.x
.drawable
, dc
->u
.x
.gc
, image
,
894 dc
->w
.DCOrgX
, dc
->w
.DCOrgY
,
895 dc
->w
.DCSizeX
, dc
->w
.DCSizeY
);
896 XDestroyImage(image
);