Release 970914
[wine.git] / graphics / painting.c
blob5fef3304a858ce9fa8ef5a8b7a724af008c348cc
1 /*
2 * Misc. graphics operations
4 * Copyright 1993, 1994 Alexandre Julliard
5 */
7 #include <math.h>
8 #include <stdlib.h>
9 #include <X11/Xlib.h>
10 #include <X11/Xutil.h>
11 #include <X11/Intrinsic.h>
12 #ifndef PI
13 #define PI M_PI
14 #endif
15 #include "gdi.h"
16 #include "dc.h"
17 #include "bitmap.h"
18 #include "callback.h"
19 #include "metafile.h"
20 #include "syscolor.h"
21 #include "palette.h"
22 #include "color.h"
23 #include "region.h"
24 #include "stddebug.h"
25 #include "debug.h"
26 #include "xmalloc.h"
28 BOOL32 DrawDiagEdge32(HDC32 hdc, RECT32 *rect, UINT32 edge, UINT32 flags);
29 BOOL32 DrawRectEdge32(HDC32 hdc, RECT32 *rect, UINT32 edge, UINT32 flags);
30 BOOL32 DrawFrameButton32(HDC32 hdc, LPRECT32 rc, UINT32 uState);
31 BOOL32 DrawFrameCaption32(HDC32 hdc, LPRECT32 rc, UINT32 uState);
32 BOOL32 DrawFrameMenu32(HDC32 hdc, LPRECT32 rc, UINT32 uState);
33 BOOL32 DrawFrameScroll32(HDC32 hdc, LPRECT32 rc, UINT32 uState);
35 /***********************************************************************
36 * LineTo16 (GDI.19)
38 BOOL16 WINAPI LineTo16( HDC16 hdc, INT16 x, INT16 y )
40 return LineTo32( hdc, x, y );
44 /***********************************************************************
45 * LineTo32 (GDI32.249)
47 BOOL32 WINAPI LineTo32( HDC32 hdc, INT32 x, INT32 y )
49 DC * dc = DC_GetDCPtr( hdc );
51 return dc && dc->funcs->pLineTo &&
52 dc->funcs->pLineTo(dc,x,y);
56 /***********************************************************************
57 * MoveTo (GDI.20)
59 DWORD WINAPI MoveTo( HDC16 hdc, INT16 x, INT16 y )
61 POINT16 pt;
63 if (!MoveToEx16(hdc,x,y,&pt))
64 return 0;
65 return MAKELONG(pt.x,pt.y);
69 /***********************************************************************
70 * MoveToEx16 (GDI.483)
72 BOOL16 WINAPI MoveToEx16( HDC16 hdc, INT16 x, INT16 y, LPPOINT16 pt )
74 POINT32 pt32;
76 if (!MoveToEx32( (HDC32)hdc, (INT32)x, (INT32)y, &pt32 )) return FALSE;
77 if (pt) CONV_POINT32TO16( &pt32, pt );
78 return TRUE;
83 /***********************************************************************
84 * MoveToEx32 (GDI32.254)
86 BOOL32 WINAPI MoveToEx32( HDC32 hdc, INT32 x, INT32 y, LPPOINT32 pt )
88 DC * dc = DC_GetDCPtr( hdc );
90 return dc && dc->funcs->pMoveToEx &&
91 dc->funcs->pMoveToEx(dc,x,y,pt);
95 /***********************************************************************
96 * Arc16 (GDI.23)
98 BOOL16 WINAPI Arc16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
99 INT16 bottom, INT16 xstart, INT16 ystart,
100 INT16 xend, INT16 yend )
102 return Arc32( (HDC32)hdc, (INT32)left, (INT32)top, (INT32)right,
103 (INT32)bottom, (INT32)xstart, (INT32)ystart, (INT32)xend,
104 (INT32)yend );
108 /***********************************************************************
109 * Arc32 (GDI32.7)
111 BOOL32 WINAPI Arc32( HDC32 hdc, INT32 left, INT32 top, INT32 right,
112 INT32 bottom, INT32 xstart, INT32 ystart,
113 INT32 xend, INT32 yend )
115 DC * dc = DC_GetDCPtr( hdc );
117 return dc && dc->funcs->pArc &&
118 dc->funcs->pArc(dc,left,top,right,bottom,xstart,ystart,xend,yend);
122 /***********************************************************************
123 * Pie16 (GDI.26)
125 BOOL16 WINAPI Pie16( HDC16 hdc, INT16 left, INT16 top,
126 INT16 right, INT16 bottom, INT16 xstart, INT16 ystart,
127 INT16 xend, INT16 yend )
129 return Pie32( (HDC32)hdc, (INT32)left, (INT32)top, (INT32)right,
130 (INT32)bottom, (INT32)xstart, (INT32)ystart, (INT32)xend,
131 (INT32)yend );
135 /***********************************************************************
136 * Pie32 (GDI32.262)
138 BOOL32 WINAPI Pie32( HDC32 hdc, INT32 left, INT32 top,
139 INT32 right, INT32 bottom, INT32 xstart, INT32 ystart,
140 INT32 xend, INT32 yend )
142 DC * dc = DC_GetDCPtr( hdc );
144 return dc && dc->funcs->pPie &&
145 dc->funcs->pPie(dc,left,top,right,bottom,xstart,ystart,xend,yend);
149 /***********************************************************************
150 * Chord16 (GDI.348)
152 BOOL16 WINAPI Chord16( HDC16 hdc, INT16 left, INT16 top,
153 INT16 right, INT16 bottom, INT16 xstart, INT16 ystart,
154 INT16 xend, INT16 yend )
156 return Chord32( hdc, left, top, right, bottom, xstart, ystart, xend, yend );
160 /***********************************************************************
161 * Chord32 (GDI32.14)
163 BOOL32 WINAPI Chord32( HDC32 hdc, INT32 left, INT32 top,
164 INT32 right, INT32 bottom, INT32 xstart, INT32 ystart,
165 INT32 xend, INT32 yend )
167 DC * dc = DC_GetDCPtr( hdc );
169 return dc && dc->funcs->pChord &&
170 dc->funcs->pChord(dc,left,top,right,bottom,xstart,ystart,xend,yend);
174 /***********************************************************************
175 * Ellipse16 (GDI.24)
177 BOOL16 WINAPI Ellipse16( HDC16 hdc, INT16 left, INT16 top,
178 INT16 right, INT16 bottom )
180 return Ellipse32( hdc, left, top, right, bottom );
184 /***********************************************************************
185 * Ellipse32 (GDI32.75)
187 BOOL32 WINAPI Ellipse32( HDC32 hdc, INT32 left, INT32 top,
188 INT32 right, INT32 bottom )
190 DC * dc = DC_GetDCPtr( hdc );
192 return dc && dc->funcs->pEllipse &&
193 dc->funcs->pEllipse(dc,left,top,right,bottom);
197 /***********************************************************************
198 * Rectangle16 (GDI.27)
200 BOOL16 WINAPI Rectangle16( HDC16 hdc, INT16 left, INT16 top,
201 INT16 right, INT16 bottom )
203 return Rectangle32( hdc, left, top, right, bottom );
207 /***********************************************************************
208 * Rectangle32 (GDI32.283)
210 BOOL32 WINAPI Rectangle32( HDC32 hdc, INT32 left, INT32 top,
211 INT32 right, INT32 bottom )
213 DC * dc = DC_GetDCPtr( hdc );
215 return dc && dc->funcs->pRectangle &&
216 dc->funcs->pRectangle(dc,left,top,right,bottom);
220 /***********************************************************************
221 * RoundRect16 (GDI.28)
223 BOOL16 WINAPI RoundRect16( HDC16 hdc, INT16 left, INT16 top, INT16 right,
224 INT16 bottom, INT16 ell_width, INT16 ell_height )
226 return RoundRect32( hdc, left, top, right, bottom, ell_width, ell_height );
230 /***********************************************************************
231 * RoundRect32 (GDI32.291)
233 BOOL32 WINAPI RoundRect32( HDC32 hdc, INT32 left, INT32 top, INT32 right,
234 INT32 bottom, INT32 ell_width, INT32 ell_height )
236 DC * dc = DC_GetDCPtr( hdc );
238 return dc && dc->funcs->pRoundRect &&
239 dc->funcs->pRoundRect(dc,left,top,right,bottom,ell_width,ell_height);
243 /***********************************************************************
244 * FillRect16 (USER.81)
246 INT16 WINAPI FillRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
248 HBRUSH16 prevBrush;
250 /* coordinates are logical so we cannot fast-check 'rect',
251 * it will be done later in the PatBlt().
254 if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
255 PatBlt32( hdc, rect->left, rect->top,
256 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
257 SelectObject16( hdc, prevBrush );
258 return 1;
262 /***********************************************************************
263 * FillRect32 (USER32.196)
265 INT32 WINAPI FillRect32( HDC32 hdc, const RECT32 *rect, HBRUSH32 hbrush )
267 HBRUSH32 prevBrush;
269 if (!(prevBrush = SelectObject32( hdc, hbrush ))) return 0;
270 PatBlt32( hdc, rect->left, rect->top,
271 rect->right - rect->left, rect->bottom - rect->top, PATCOPY );
272 SelectObject32( hdc, prevBrush );
273 return 1;
277 /***********************************************************************
278 * InvertRect16 (USER.82)
280 void WINAPI InvertRect16( HDC16 hdc, const RECT16 *rect )
282 PatBlt32( hdc, rect->left, rect->top,
283 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
287 /***********************************************************************
288 * InvertRect32 (USER32.329)
290 void WINAPI InvertRect32( HDC32 hdc, const RECT32 *rect )
292 PatBlt32( hdc, rect->left, rect->top,
293 rect->right - rect->left, rect->bottom - rect->top, DSTINVERT );
297 /***********************************************************************
298 * FrameRect16 (USER.83)
300 INT16 WINAPI FrameRect16( HDC16 hdc, const RECT16 *rect, HBRUSH16 hbrush )
302 HBRUSH16 prevBrush;
303 int left, top, right, bottom;
305 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
306 if (!dc) return FALSE;
308 left = XLPTODP( dc, rect->left );
309 top = YLPTODP( dc, rect->top );
310 right = XLPTODP( dc, rect->right );
311 bottom = YLPTODP( dc, rect->bottom );
313 if ( (right <= left) || (bottom <= top) ) return 0;
314 if (!(prevBrush = SelectObject16( hdc, hbrush ))) return 0;
316 if (DC_SetupGCForBrush( dc ))
318 PatBlt32( hdc, rect->left, rect->top, 1,
319 rect->bottom - rect->top, PATCOPY );
320 PatBlt32( hdc, rect->right - 1, rect->top, 1,
321 rect->bottom - rect->top, PATCOPY );
322 PatBlt32( hdc, rect->left, rect->top,
323 rect->right - rect->left, 1, PATCOPY );
324 PatBlt32( hdc, rect->left, rect->bottom - 1,
325 rect->right - rect->left, 1, PATCOPY );
327 SelectObject16( hdc, prevBrush );
328 return 1;
332 /***********************************************************************
333 * FrameRect32 (USER32.202)
335 INT32 WINAPI FrameRect32( HDC32 hdc, const RECT32 *rect, HBRUSH32 hbrush )
337 RECT16 rect16;
338 CONV_RECT32TO16( rect, &rect16 );
339 return FrameRect16( (HDC16)hdc, &rect16, (HBRUSH16)hbrush );
343 /***********************************************************************
344 * SetPixel16 (GDI.31)
346 COLORREF WINAPI SetPixel16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
348 return SetPixel32( hdc, x, y, color );
352 /***********************************************************************
353 * SetPixel32 (GDI32.327)
355 COLORREF WINAPI SetPixel32( HDC32 hdc, INT32 x, INT32 y, COLORREF color )
357 DC * dc = DC_GetDCPtr( hdc );
359 if (!dc || !dc->funcs->pSetPixel) return 0;
360 return dc->funcs->pSetPixel(dc,x,y,color);
364 /***********************************************************************
365 * GetPixel16 (GDI.83)
367 COLORREF WINAPI GetPixel16( HDC16 hdc, INT16 x, INT16 y )
369 return GetPixel32( hdc, x, y );
373 /***********************************************************************
374 * GetPixel32 (GDI32.211)
376 COLORREF WINAPI GetPixel32( HDC32 hdc, INT32 x, INT32 y )
378 DC * dc = DC_GetDCPtr( hdc );
380 if (!dc) return 0;
381 #ifdef SOLITAIRE_SPEED_HACK
382 return 0;
383 #endif
385 /* FIXME: should this be in the graphics driver? */
386 if (!PtVisible32( hdc, x, y )) return 0;
387 if (!dc || !dc->funcs->pGetPixel) return 0;
388 return dc->funcs->pGetPixel(dc,x,y);
392 /***********************************************************************
393 * PaintRgn16 (GDI.43)
395 BOOL16 WINAPI PaintRgn16( HDC16 hdc, HRGN16 hrgn )
397 return PaintRgn32( hdc, hrgn );
401 /***********************************************************************
402 * PaintRgn32 (GDI32.259)
404 BOOL32 WINAPI PaintRgn32( HDC32 hdc, HRGN32 hrgn )
406 DC * dc = DC_GetDCPtr( hdc );
408 return dc && dc->funcs->pPaintRgn &&
409 dc->funcs->pPaintRgn(dc,hrgn);
413 /***********************************************************************
414 * FillRgn16 (GDI.40)
416 BOOL16 WINAPI FillRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush )
418 return FillRgn32( hdc, hrgn, hbrush );
422 /***********************************************************************
423 * FillRgn32 (GDI32.101)
425 BOOL32 WINAPI FillRgn32( HDC32 hdc, HRGN32 hrgn, HBRUSH32 hbrush )
427 BOOL32 retval;
428 HBRUSH32 prevBrush = SelectObject32( hdc, hbrush );
429 if (!prevBrush) return FALSE;
430 retval = PaintRgn32( hdc, hrgn );
431 SelectObject32( hdc, prevBrush );
432 return retval;
436 /***********************************************************************
437 * FrameRgn16 (GDI.41)
439 BOOL16 WINAPI FrameRgn16( HDC16 hdc, HRGN16 hrgn, HBRUSH16 hbrush,
440 INT16 nWidth, INT16 nHeight )
442 return FrameRgn32( hdc, hrgn, hbrush, nWidth, nHeight );
446 /***********************************************************************
447 * FrameRgn32 (GDI32.105)
449 BOOL32 WINAPI FrameRgn32( HDC32 hdc, HRGN32 hrgn, HBRUSH32 hbrush,
450 INT32 nWidth, INT32 nHeight )
452 HRGN32 tmp = CreateRectRgn32( 0, 0, 0, 0 );
453 if(!REGION_FrameRgn( tmp, hrgn, nWidth, nHeight )) return FALSE;
454 FillRgn32( hdc, tmp, hbrush );
455 DeleteObject32( tmp );
456 return TRUE;
460 /***********************************************************************
461 * InvertRgn16 (GDI.42)
463 BOOL16 WINAPI InvertRgn16( HDC16 hdc, HRGN16 hrgn )
465 return InvertRgn32( hdc, hrgn );
469 /***********************************************************************
470 * InvertRgn32 (GDI32.246)
472 BOOL32 WINAPI InvertRgn32( HDC32 hdc, HRGN32 hrgn )
474 HBRUSH32 prevBrush = SelectObject32( hdc, GetStockObject32(BLACK_BRUSH) );
475 INT32 prevROP = SetROP232( hdc, R2_NOT );
476 BOOL32 retval = PaintRgn32( hdc, hrgn );
477 SelectObject32( hdc, prevBrush );
478 SetROP232( hdc, prevROP );
479 return retval;
483 /***********************************************************************
484 * DrawFocusRect16 (USER.466)
486 void WINAPI DrawFocusRect16( HDC16 hdc, const RECT16* rc )
488 RECT32 rect32;
489 CONV_RECT16TO32( rc, &rect32 );
490 DrawFocusRect32( hdc, &rect32 );
494 /***********************************************************************
495 * DrawFocusRect32 (USER32.155)
497 * FIXME: PatBlt(PATINVERT) with background brush.
499 void WINAPI DrawFocusRect32( HDC32 hdc, const RECT32* rc )
501 HPEN32 hOldPen;
502 INT32 oldDrawMode, oldBkMode;
503 INT32 left, top, right, bottom;
505 DC * dc = (DC *) GDI_GetObjPtr( hdc, DC_MAGIC );
506 if (!dc) return;
508 left = XLPTODP( dc, rc->left );
509 top = YLPTODP( dc, rc->top );
510 right = XLPTODP( dc, rc->right );
511 bottom = YLPTODP( dc, rc->bottom );
513 hOldPen = SelectObject32( hdc, sysColorObjects.hpenWindowText );
514 oldDrawMode = SetROP232(hdc, R2_XORPEN);
515 oldBkMode = SetBkMode32(hdc, TRANSPARENT);
517 /* Hack: make sure the XORPEN operation has an effect */
518 dc->u.x.pen.pixel = (1 << screenDepth) - 1;
520 if (DC_SetupGCForPen( dc ))
521 XDrawRectangle( display, dc->u.x.drawable, dc->u.x.gc,
522 dc->w.DCOrgX + left, dc->w.DCOrgY + top,
523 right-left-1, bottom-top-1 );
525 SetBkMode32(hdc, oldBkMode);
526 SetROP232(hdc, oldDrawMode);
527 SelectObject32(hdc, hOldPen);
531 /**********************************************************************
532 * Polyline16 (GDI.37)
534 BOOL16 WINAPI Polyline16( HDC16 hdc, LPPOINT16 pt, INT16 count )
536 register int i;
537 LPPOINT32 pt32 = (LPPOINT32)xmalloc(count*sizeof(POINT32));
538 BOOL16 ret;
540 for (i=count;i--;) CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
541 ret = Polyline32(hdc,pt32,count);
542 free(pt32);
543 return ret;
547 /**********************************************************************
548 * Polyline32 (GDI32.276)
550 BOOL32 WINAPI Polyline32( HDC32 hdc, const LPPOINT32 pt, INT32 count )
552 DC * dc = DC_GetDCPtr( hdc );
554 return dc && dc->funcs->pPolyline &&
555 dc->funcs->pPolyline(dc,pt,count);
559 /**********************************************************************
560 * Polygon16 (GDI.36)
562 BOOL16 WINAPI Polygon16( HDC16 hdc, LPPOINT16 pt, INT16 count )
564 register int i;
565 LPPOINT32 pt32 = (LPPOINT32)xmalloc(count*sizeof(POINT32));
566 BOOL32 ret;
569 for (i=count;i--;) CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
570 ret = Polygon32(hdc,pt32,count);
571 free(pt32);
572 return ret;
576 /**********************************************************************
577 * Polygon32 (GDI32.275)
579 BOOL32 WINAPI Polygon32( HDC32 hdc, LPPOINT32 pt, INT32 count )
581 DC * dc = DC_GetDCPtr( hdc );
583 return dc && dc->funcs->pPolygon &&
584 dc->funcs->pPolygon(dc,pt,count);
588 /**********************************************************************
589 * PolyPolygon16 (GDI.450)
591 BOOL16 WINAPI PolyPolygon16( HDC16 hdc, LPPOINT16 pt, LPINT16 counts,
592 UINT16 polygons )
594 int i,nrpts;
595 LPPOINT32 pt32;
596 LPINT32 counts32;
597 BOOL16 ret;
599 nrpts=0;
600 for (i=polygons;i--;)
601 nrpts+=counts[i];
602 pt32 = (LPPOINT32)xmalloc(sizeof(POINT32)*nrpts);
603 for (i=nrpts;i--;)
604 CONV_POINT16TO32(&(pt[i]),&(pt32[i]));
605 counts32 = (LPINT32)xmalloc(polygons*sizeof(INT32));
606 for (i=polygons;i--;) counts32[i]=counts[i];
608 ret = PolyPolygon32(hdc,pt32,counts32,polygons);
609 free(counts32);
610 free(pt32);
611 return ret;
614 /**********************************************************************
615 * PolyPolygon32 (GDI.450)
617 BOOL32 WINAPI PolyPolygon32( HDC32 hdc, LPPOINT32 pt, LPINT32 counts,
618 UINT32 polygons )
620 DC * dc = DC_GetDCPtr( hdc );
622 return dc && dc->funcs->pPolyPolygon &&
623 dc->funcs->pPolyPolygon(dc,pt,counts,polygons);
626 /**********************************************************************
627 * ExtFloodFill16 (GDI.372)
629 BOOL16 WINAPI ExtFloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color,
630 UINT16 fillType )
632 return ExtFloodFill32( hdc, x, y, color, fillType );
636 /**********************************************************************
637 * ExtFloodFill32 (GDI32.96)
639 BOOL32 WINAPI ExtFloodFill32( HDC32 hdc, INT32 x, INT32 y, COLORREF color,
640 UINT32 fillType )
642 DC *dc = DC_GetDCPtr( hdc );
644 return dc && dc->funcs->pExtFloodFill &&
645 dc->funcs->pExtFloodFill(dc,x,y,color,fillType);
649 /**********************************************************************
650 * FloodFill16 (GDI.25)
652 BOOL16 WINAPI FloodFill16( HDC16 hdc, INT16 x, INT16 y, COLORREF color )
654 return ExtFloodFill32( hdc, x, y, color, FLOODFILLBORDER );
658 /**********************************************************************
659 * FloodFill32 (GDI32.104)
661 BOOL32 WINAPI FloodFill32( HDC32 hdc, INT32 x, INT32 y, COLORREF color )
663 return ExtFloodFill32( hdc, x, y, color, FLOODFILLBORDER );
667 /**********************************************************************
668 * DrawFrameControl32 (USER32.152)
670 BOOL32 WINAPI DrawAnimatedRects32( HWND32 hwnd, int idAni,
671 const LPRECT32 lprcFrom,
672 const LPRECT32 lprcTo )
674 fprintf( stdnimp,"DrawAnimatedRects32(%x,%d,%p,%p), empty stub!\n",
675 hwnd, idAni, lprcFrom, lprcTo );
676 return TRUE;
679 BOOL32 WINAPI DrawState32A(
680 HDC32 hdc,HBRUSH32 hbrush,DRAWSTATEPROC drawstateproc,
681 LPARAM lparam,WPARAM32 wparam,INT32 x,INT32 y,INT32 z,INT32 a,UINT32 b
683 fprintf(stderr,"DrawStateA(%x,%x,%p,0x%08lx,0x%08x,%d,%d,%d,%d,%d),stub\n",
684 hdc,hbrush,drawstateproc,lparam,wparam,x,y,z,a,b
686 return TRUE;