2 * DIBDRV implementation of GDI driver graphics functions
4 * Copyright 2009 Massimo Del Fedele
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(dibdrv
);
28 static inline void OrderInt(int *i1
, int *i2
)
44 /* clips a line segment by a rectangular window */
45 static inline BYTE
outCodes(const POINT
*p
, const RECT
*r
)
51 else if(p
->y
>= r
->bottom
)
55 else if(p
->x
< r
->left
)
60 static BOOL
ClipLine(const POINT
*p1
, const POINT
*p2
, const RECT
*r
, POINT
*pc1
, POINT
*pc2
)
62 BYTE outCode1
,outCode2
;
66 pc1
->x
= p1
->x
; pc1
->y
= p1
->y
;
67 pc2
->x
= p2
->x
; pc2
->y
= p2
->y
;
70 outCode1
= outCodes(pc1
, r
);
71 outCode2
= outCodes(pc2
, r
);
72 if(outCode1
& outCode2
)
74 if(!outCode1
&& !outCode2
)
78 tmp
= pc1
->x
; pc1
->x
= pc2
->x
; pc2
->x
= tmp
;
79 tmp
= pc1
->y
; pc1
->y
= pc2
->y
; pc2
->y
= tmp
;
80 tmpCode
= outCode1
; outCode1
= outCode2
; outCode2
= tmpCode
;
82 if(outCode1
& TOP_SIDE
)
84 pc1
->x
+= MulDiv(pc2
->x
- pc1
->x
, r
->top
- pc1
->y
, pc2
->y
- pc1
->y
);
87 else if(outCode1
& BOTTOM_SIDE
)
89 pc1
->x
+= MulDiv(pc2
->x
- pc1
->x
, r
->bottom
- 1 - pc1
->y
, pc2
->y
- pc1
->y
);
90 pc1
->y
= r
->bottom
- 1;
92 else if(outCode1
& RIGHT_SIDE
)
94 pc1
->y
+= MulDiv(pc2
->y
- pc1
->y
, r
->right
- 1 - pc1
->x
, pc2
->x
- pc1
->x
);
95 pc1
->x
= r
->right
- 1;
97 else if(outCode1
& LEFT_SIDE
)
99 pc1
->y
+= MulDiv(pc2
->y
- pc1
->y
, r
->left
- pc1
->x
, pc2
->x
- pc1
->x
);
105 /* Clips a polygon by an horizontal/vertical line
106 which indicates the side :
108 static inline BOOL
PointInside(const POINT
*p
, const RECT
*r
, BYTE side
)
113 return p
->x
>= r
->left
;
115 return p
->y
>= r
->top
;
117 return p
->x
< r
->right
;
119 return p
->y
< r
->bottom
;
125 static inline void SideIntersect(const POINT
*p1
, const POINT
*p2
, const RECT
*r
, BYTE side
, POINT
*inters
)
129 case LEFT_SIDE
: /* left */
131 inters
->y
= MulDiv(p2
->y
- p1
->y
, r
->left
- p1
->x
, p2
->x
- p1
->x
) + p1
->y
;
133 case TOP_SIDE
: /* top */
134 inters
->x
= MulDiv(p2
->x
- p1
->x
, r
->top
- p1
->y
, p2
->y
- p1
->y
) + p1
->x
;
137 case RIGHT_SIDE
: /* right */
138 inters
->x
= r
->right
- 1;
139 inters
->y
= MulDiv(p2
->y
- p1
->y
, r
->right
- 1 - p1
->x
, p2
->x
- p1
->x
) + p1
->y
;
141 case BOTTOM_SIDE
: /* bottom */
142 inters
->x
= MulDiv(p2
->x
- p1
->x
, r
->bottom
- 1 - p1
->y
, p2
->y
- p1
->y
) + p1
->x
;
143 inters
->y
= r
->bottom
- 1;
151 static BOOL
ClipPolygonBySide(const POINT
*pt
, int count
, const RECT
*r
, BYTE side
, POINT
**clipped
, int *clippedCount
)
154 const POINT
*p1
, *p2
;
157 if(!(*clipped
= HeapAlloc(GetProcessHeap(), 0, sizeof(POINT
) * count
* 2)))
164 for(iPoint
= 0 ; iPoint
< count
; iPoint
++)
166 if(PointInside(p2
, r
, side
))
168 /* point p is "inside" */
169 if(!PointInside(p1
, r
, side
))
171 /* p is "inside" and s is "outside" */
172 SideIntersect(p2
, p1
, r
, side
, pOut
++);
180 else if(PointInside( p1
, r
, side
))
182 /* s is "inside" and p is "outside" */
183 SideIntersect(p1
, p2
, r
, side
, pOut
++);
188 return *clippedCount
;
192 /* Clips a polygon by a rectangular window - returns a new polygon */
193 static BOOL
ClipPolygon(const POINT
* pt
, int count
, const RECT
*r
, POINT
**newPt
, int *newCount
)
199 if(!ClipPolygonBySide(pt
, count
, r
, LEFT_SIDE
, &pc1
, &count1
))
201 res
= ClipPolygonBySide(pc1
, count1
, r
, TOP_SIDE
, &pc2
, &count2
);
202 HeapFree(GetProcessHeap(), 0, pc1
);
205 res
= ClipPolygonBySide(pc2
, count2
, r
, RIGHT_SIDE
, &pc1
, &count1
);
206 HeapFree(GetProcessHeap(), 0, pc2
);
209 res
= ClipPolygonBySide(pc1
, count1
, r
, BOTTOM_SIDE
, &pc2
, &count2
);
210 HeapFree(GetProcessHeap(), 0, pc1
);
219 /* Intersects a line given by 2 points with an horizontal scan line at height y */
220 static BOOL
ScanLine(const POINT
*p1
, const POINT
*p2
, int ys
, POINT
*pRes
)
225 /* if line lies completely over or under scan line, no intersection */
226 if((p1
->y
< ys
&& p2
->y
< ys
) || (p1
->y
>= ys
&& p2
->y
>= ys
))
229 /* if line is parallel to x axis, we consider it not intersecting */
233 pRes
->x
= MulDiv(p2
->x
- p1
->x
, ys
- p1
->y
, p2
->y
- p1
->y
) + p1
->x
;
238 /* Gets an x-ordered list of intersection points of a scanline at position y
239 with a polygon/polyline */
240 static BOOL
ScanPolygon(const POINT
*pt
, int count
, int ys
, POINT
**scans
, int *scanCount
)
242 const POINT
*p1
, *p2
;
248 /* if not at least 2 points, nothing to return */
252 /* intersections count is AT MOST 'count'; we don't care to
253 allocate exact memory needed */
254 *scans
= HeapAlloc(GetProcessHeap(), 0, sizeof(POINT
)*count
);
258 /* builds unordered intersections */
262 for(iPoint
= 0; iPoint
< count
-1; iPoint
++)
266 if(ScanLine(p1
, p2
, ys
, pDest
))
274 if(ScanLine(p1
, p2
, ys
, pDest
))
280 /* now we sort the list -- duped point are left into
281 as they're needed for the scanline fill algorithm */
282 for(i
= 0, ps1
= *scans
; i
< *scanCount
-1; i
++, ps1
++)
283 for(j
= i
+1, ps2
= ps1
+1; j
< *scanCount
; j
++, ps2
++)
297 /* gets bounding box of a polygon */
298 static void PolygonBoundingBox(const POINT
*pt
, int count
, RECT
*bBox
)
303 bBox
->left
= MAXLONG
; bBox
->right
= -MAXLONG
;
304 bBox
->top
= MAXLONG
; bBox
->bottom
= -MAXLONG
;
305 for(p
= pt
, iPoint
= 0; iPoint
< count
; iPoint
++, p
++)
307 if(p
->x
< bBox
->left
) bBox
->left
= p
->x
;
308 if(p
->x
> bBox
->right
) bBox
->right
= p
->x
;
309 if(p
->y
< bBox
->top
) bBox
->top
= p
->y
;
310 if(p
->y
> bBox
->bottom
) bBox
->bottom
= p
->y
;
314 /* intersect 2 rectangles (just to not use USER32 one...)
315 bottom and tight sides are considered OUTSIDE */
316 BOOL
_DIBDRV_IntersectRect(RECT
*d
, const RECT
*s1
, const RECT
*s2
)
318 if(s1
->right
<= s2
->left
||
319 s2
->right
<= s1
->left
||
320 s1
->bottom
<= s2
->top
||
321 s2
->bottom
<= s1
->top
324 d
->left
= s1
->left
> s2
->left
? s1
->left
: s2
->left
;
325 d
->top
= s1
->top
> s2
->top
? s1
->top
: s2
->top
;
326 d
->right
= s1
->right
< s2
->right
? s1
->right
: s2
->right
;
327 d
->bottom
= s1
->bottom
< s2
->bottom
? s1
->bottom
: s2
->bottom
;
331 /* converts a rectangle form Word space to Device space */
332 void _DIBDRV_Rect_ws2ds(DIBDRVPHYSDEV
*physDev
, const RECT
*src
, RECT
*dst
)
335 pts
[0].x
= src
->left
;
337 pts
[1].x
= src
->right
;
338 pts
[1].y
= src
->bottom
;
339 LPtoDP(physDev
->hdc
, pts
, 2);
340 dst
->left
= pts
[0].x
;
342 dst
->right
= pts
[1].x
;
343 dst
->bottom
= pts
[1].y
;
346 /* converts positions from Word space to Device space */
347 void _DIBDRV_Position_ws2ds(DIBDRVPHYSDEV
*physDev
, int *x
, int *y
)
352 LPtoDP(physDev
->hdc
, &p
, 1);
357 void _DIBDRV_Positions_ws2ds(DIBDRVPHYSDEV
*physDev
, int *x1
, int *y1
, int *x2
, int *y2
)
364 LPtoDP(physDev
->hdc
, pts
, 2);
371 /* converts sizes from Word space to Device space */
372 void _DIBDRV_Sizes_ws2ds(DIBDRVPHYSDEV
*physDev
, int *w
, int *h
)
379 LPtoDP(physDev
->hdc
, pts
, 2);
380 *w
= pts
[1].x
- pts
[0].x
;
381 *h
= pts
[1].y
- pts
[0].y
;
384 /* converts positions from Device space to World space */
385 void _DIBDRV_Position_ds2ws(DIBDRVPHYSDEV
*physDev
, int *x
, int *y
)
390 DPtoLP(physDev
->hdc
, &p
, 1);
395 void _DIBDRV_Positions_ds2ws(DIBDRVPHYSDEV
*physDev
, int *x1
, int *y1
, int *x2
, int *y2
)
402 DPtoLP(physDev
->hdc
, pts
, 2);
409 /* converts sizes from Device space to World space */
410 void _DIBDRV_Sizes_ds2ws(DIBDRVPHYSDEV
*physDev
, int *w
, int *h
)
417 DPtoLP(physDev
->hdc
, pts
, 2);
418 *w
= pts
[1].x
- pts
[0].x
;
419 *h
= pts
[1].y
- pts
[0].y
;
422 /***********************************************************************
425 BOOL
DIBDRV_Arc( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
,
426 int xstart
, int ystart
, int xend
, int yend
)
430 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
431 physDev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
435 /* DIB section selected in, use DIB Engine */
436 ONCE(FIXME("STUB\n"));
441 /* DDB selected in, use X11 driver */
442 res
= _DIBDRV_GetDisplayDriver()->pArc(physDev
->X11PhysDev
, left
, top
, right
, bottom
,
443 xstart
, ystart
, xend
, yend
);
448 /***********************************************************************
451 BOOL
DIBDRV_Chord( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
,
452 int xstart
, int ystart
, int xend
, int yend
)
456 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
457 physDev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
461 /* DIB section selected in, use DIB Engine */
462 ONCE(FIXME("STUB\n"));
467 /* DDB selected in, use X11 driver */
468 res
= _DIBDRV_GetDisplayDriver()->pChord(physDev
->X11PhysDev
, left
, top
, right
, bottom
,
469 xstart
, ystart
, xend
, yend
);
474 /***********************************************************************
477 BOOL
DIBDRV_Ellipse( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
)
481 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n",
482 physDev
, left
, top
, right
, bottom
));
486 /* DIB section selected in, use DIB Engine */
487 ONCE(FIXME("STUB\n"));
492 /* DDB selected in, use X11 driver */
493 res
= _DIBDRV_GetDisplayDriver()->pEllipse(physDev
->X11PhysDev
, left
, top
, right
, bottom
);
498 /**********************************************************************
499 * DIBDRV_ExtFloodFill
501 BOOL
DIBDRV_ExtFloodFill( DIBDRVPHYSDEV
*physDev
, int x
, int y
, COLORREF color
,
506 MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n",
507 physDev
, x
, y
, color
, fillType
));
511 /* DIB section selected in, use DIB Engine */
512 ONCE(FIXME("STUB\n"));
517 /* DDB selected in, use X11 driver */
518 res
= _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev
->X11PhysDev
, x
, y
, color
, fillType
);
523 /***********************************************************************
526 BOOL
DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV
*physDev
, LPPOINT lpp
)
530 MAYBE(TRACE("physDev:%p, lpp:%p\n", physDev
, lpp
));
534 /* DIB section selected in, use DIB Engine */
535 ONCE(FIXME("STUB\n"));
540 /* DDB selected in, use X11 driver */
541 res
= _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev
->X11PhysDev
, lpp
);
546 /***********************************************************************
549 COLORREF
DIBDRV_GetPixel( DIBDRVPHYSDEV
*physDev
, int x
, int y
)
553 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev
, x
, y
));
557 _DIBDRV_Position_ws2ds(physDev
, &x
, &y
);
558 res
= physDev
->physBitmap
->funcs
->GetPixel(physDev
->physBitmap
, x
, y
);
562 /* DDB selected in, use X11 driver */
563 res
= _DIBDRV_GetDisplayDriver()->pGetPixel(physDev
->X11PhysDev
, x
, y
);
568 /***********************************************************************
571 BOOL
DIBDRV_LineTo( DIBDRVPHYSDEV
*physDev
, int x
, int y
)
577 POINT p1
, p2
, pc1
, pc2
;
579 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev
, x
, y
));
584 GetCurrentPositionEx(physDev
->hdc
, &curPos
);
586 /* converts position to device space */
587 p1
.x
= curPos
.x
; p1
.y
= curPos
.y
;
589 LPtoDP(physDev
->hdc
, &p1
, 1);
590 LPtoDP(physDev
->hdc
, &p2
, 1);
592 /* cycle on all current clipping rectangles */
593 r
= physDev
->regionRects
;
594 for(iRec
= 0; iRec
< physDev
->regionRectCount
; iRec
++, r
++)
596 _DIBDRV_ResetDashOrigin(physDev
);
598 /* clipe line on current region area */
599 if(ClipLine(&p1
, &p2
, r
, &pc1
, &pc2
))
602 physDev
->penHLine(physDev
, pc1
.x
, pc2
.x
, pc1
.y
);
603 else if(pc1
.x
== pc2
.x
)
604 physDev
->penVLine(physDev
, pc1
.x
, pc1
.y
, pc2
.y
);
606 physDev
->penLine(physDev
, pc1
.x
, pc1
.y
, pc2
.x
, pc2
.y
);
611 /* moves current position to next point */
612 MoveToEx(physDev
->hdc
, x
, y
, NULL
);
616 /* DDB selected in, use X11 driver */
617 res
= _DIBDRV_GetDisplayDriver()->pLineTo(physDev
->X11PhysDev
, x
, y
);
622 /***********************************************************************
625 BOOL
DIBDRV_Rectangle( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
);
626 BOOL
DIBDRV_PaintRgn( DIBDRVPHYSDEV
*physDev
, HRGN hrgn
)
634 MAYBE(TRACE("physDev:%p, hrgn:%p\n", physDev
, hrgn
));
638 /* gets needed region data size */
639 if(!(size
= GetRegionData(hrgn
, 0, NULL
)))
642 /* allocates buffer and gets actual region data */
643 if(!(data
= HeapAlloc(GetProcessHeap(), 0, size
)))
645 if(!GetRegionData(hrgn
, size
, data
))
647 HeapFree(GetProcessHeap(), 0, data
);
651 /* paints the filled rectangles */
652 rect
= (RECT
*)data
->Buffer
;
653 for(i
= 0; i
< data
->rdh
.nCount
; i
++)
655 DIBDRV_Rectangle( physDev
, rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
658 HeapFree( GetProcessHeap(), 0, data
);
665 /* DDB selected in, use X11 driver */
666 res
= _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev
->X11PhysDev
, hrgn
);
671 /***********************************************************************
674 BOOL
DIBDRV_Pie( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
,
675 int xstart
, int ystart
, int xend
, int yend
)
679 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
680 physDev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
684 /* DIB section selected in, use DIB Engine */
685 ONCE(FIXME("STUB\n"));
690 /* DDB selected in, use X11 driver */
691 res
= _DIBDRV_GetDisplayDriver()->pPie(physDev
->X11PhysDev
, left
, top
, right
, bottom
,
692 xstart
, ystart
, xend
, yend
);
697 /**********************************************************************
700 BOOL
DIBDRV_Polygon( DIBDRVPHYSDEV
*physDev
, const POINT
* ptw
, int count
)
711 int scanCount
, iScan
;
712 const POINT
*p1
, *p2
;
716 MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev
, ptw
, count
));
720 /* DIB section selected in, use DIB Engine */
724 /* first converts all points to device coords */
725 if(!(pt
= HeapAlloc(GetProcessHeap(), 0, sizeof(POINT
) * count
)))
727 memcpy(pt
, ptw
, sizeof(POINT
) * count
);
728 LPtoDP(physDev
->hdc
, pt
, count
);
730 /* cycle on all current clipping rectangles */
731 r
= physDev
->regionRects
;
732 for(iRec
= 0; iRec
< physDev
->regionRectCount
; iRec
++, r
++)
735 if(ClipPolygon(pt
, count
, r
, &clipped
, &clippedCount
))
737 /* gets polygon bounding box -- for ytop and ybottom */
738 PolygonBoundingBox(clipped
, clippedCount
, &bBox
);
740 /* gets all ordered intersections of polygon with
742 for(ys
= bBox
.top
; ys
< bBox
.bottom
; ys
++)
744 if(ScanPolygon(clipped
, clippedCount
, ys
, &scans
, &scanCount
))
752 while(iScan
< scanCount
- 1)
754 physDev
->brushHLine(physDev
, p1
->x
, p2
->x
, ys
);
760 HeapFree(GetProcessHeap(), 0, scans
);
763 HeapFree(GetProcessHeap(), 0, clipped
);
766 /* perimeter -- don't use PolyLine for speed */
768 for(iPoint
= 0; iPoint
< count
-1; iPoint
++)
771 if(ClipLine(p1
, p2
, r
, &pc1
, &pc2
))
774 physDev
->penLine(physDev
, pc1
.x
, pc1
.y
, pc2
.x
, pc2
.y
);
779 if(ClipLine(p1
, p2
, r
, &pc1
, &pc2
))
782 physDev
->penLine(physDev
, pc1
.x
, pc1
.y
, pc2
.x
, pc2
.y
);
786 HeapFree(GetProcessHeap(), 0, pt
);
791 /* DDB selected in, use X11 driver */
792 res
= _DIBDRV_GetDisplayDriver()->pPolygon(physDev
->X11PhysDev
, ptw
, count
);
798 /**********************************************************************
801 BOOL
DIBDRV_Polyline( DIBDRVPHYSDEV
*physDev
, const POINT
* ptw
, int count
)
805 MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev
, ptw
, count
));
809 /* DIB section selected in, use DIB Engine */
819 /* first converts all points to device coords */
820 if(!(pt
= HeapAlloc(GetProcessHeap(), 0, sizeof(POINT
) * count
)))
822 memcpy(pt
, ptw
, sizeof(POINT
) * count
);
823 LPtoDP(physDev
->hdc
, pt
, count
);
825 r
= physDev
->regionRects
;
826 for(iRec
= 0; iRec
< physDev
->regionRectCount
; iRec
++)
828 const POINT
*p2
= pt
, *p1
;
829 for(iPoint
= 0; iPoint
< count
-1; iPoint
++)
832 if(ClipLine(p1
, p2
, r
, &pc1
, &pc2
))
835 physDev
->penLine(physDev
, pc1
.x
, pc1
.y
, pc2
.x
, pc2
.y
);
841 HeapFree(GetProcessHeap(), 0, pt
);
847 /* DDB selected in, use X11 driver */
848 res
= _DIBDRV_GetDisplayDriver()->pPolyline(physDev
->X11PhysDev
, ptw
, count
);
853 /**********************************************************************
856 BOOL
DIBDRV_PolyPolygon( DIBDRVPHYSDEV
*physDev
, const POINT
* pt
, const int* counts
, UINT polygons
)
860 MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev
, pt
, counts
, polygons
));
864 /* DIB section selected in, use DIB Engine */
865 ONCE(FIXME("STUB\n"));
870 /* DDB selected in, use X11 driver */
871 res
= _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev
->X11PhysDev
, pt
, counts
, polygons
);
876 /**********************************************************************
877 * DIBDRV_PolyPolyline
879 BOOL
DIBDRV_PolyPolyline( DIBDRVPHYSDEV
*physDev
, const POINT
* pt
, const DWORD
* counts
,
884 MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev
, pt
, counts
, polylines
));
888 /* DIB section selected in, use DIB Engine */
889 ONCE(FIXME("STUB\n"));
894 /* DDB selected in, use X11 driver */
895 res
= _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev
->X11PhysDev
, pt
, counts
, polylines
);
900 /***********************************************************************
903 BOOL
DIBDRV_Rectangle( DIBDRVPHYSDEV
*physDev
, int x1
, int y1
, int x2
, int y2
)
907 RECT rWorld
, rDevice
, rClipped
;
911 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", physDev
, x1
, y1
, x2
, y2
));
920 /* converts to device space */
921 rWorld
.left
= x1
; rWorld
.top
= y1
; rWorld
.right
= x2
; rWorld
.bottom
= y2
;
922 _DIBDRV_Rect_ws2ds(physDev
, &rWorld
, &rDevice
);
924 /* loop on all clip region rectangles */
925 r
= physDev
->regionRects
;
926 for(iRec
= 0; iRec
< physDev
->regionRectCount
; iRec
++, r
++)
928 /* clips rectangle to current region */
929 if(_DIBDRV_IntersectRect(&rClipped
, &rDevice
, r
))
931 x1
= rClipped
.left
; y1
= rClipped
.top
;
932 x2
= rClipped
.right
; y2
= rClipped
.bottom
;
934 _DIBDRV_ResetDashOrigin(physDev
);
936 /* fill the inside, if not null brush */
937 if(physDev
->brushStyle
!= BS_NULL
)
940 for (i
= y1
; i
< y2
; i
++)
941 physDev
->brushHLine(physDev
, x1
, x2
, i
);
944 /* draw perimeter, if not null pen */
945 if(physDev
->penStyle
!= PS_NULL
)
948 /* particular case where the rectangle
949 degenerates to a line or a point */
951 physDev
->penVLine(physDev
, x1
, y1
, y2
);
952 else if (y1
>= y2
-1)
953 physDev
->penHLine(physDev
, x1
, x2
, y1
);
956 /* Draw the perimeter */
957 physDev
->penHLine(physDev
, x1
, x2
, y1
);
958 physDev
->penHLine(physDev
, x1
, x2
, y2
- 1);
959 physDev
->penVLine(physDev
, x1
, y1
+ 1, y2
- 1);
960 physDev
->penVLine(physDev
, x2
- 1, y1
+ 1, y2
- 1);
969 /* DDB selected in, use X11 driver */
970 res
= _DIBDRV_GetDisplayDriver()->pRectangle(physDev
->X11PhysDev
, x1
, y1
, x2
, y2
);
975 /***********************************************************************
978 BOOL
DIBDRV_RoundRect( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
,
979 int bottom
, int ell_width
, int ell_height
)
983 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, ell_width:%d, ell_height:%d\n",
984 physDev
, left
, top
, right
, bottom
, ell_width
, ell_height
));
988 /* DIB section selected in, use DIB Engine */
989 ONCE(FIXME("STUB\n"));
994 /* DDB selected in, use X11 driver */
995 res
= _DIBDRV_GetDisplayDriver()->pRoundRect(physDev
->X11PhysDev
, left
, top
, right
, bottom
,
996 ell_width
, ell_height
);
1001 /***********************************************************************
1004 COLORREF
DIBDRV_SetPixel( DIBDRVPHYSDEV
*physDev
, int x
, int y
, COLORREF color
)
1009 MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev
, x
, y
, color
));
1013 /* get real colorref */
1014 color
= _DIBDRV_MapColor(physDev
, color
);
1016 /* map to pixel color / palette index */
1017 color
= physDev
->physBitmap
->funcs
->ColorToPixel(physDev
->physBitmap
, color
);
1019 _DIBDRV_Position_ws2ds(physDev
, &x
, &y
);
1021 /* gets previous pixel */
1022 res
= physDev
->physBitmap
->funcs
->GetPixel(physDev
->physBitmap
, x
, y
);
1024 /* calculates AND and XOR from color */
1025 _DIBDRV_CalcAndXorMasks(GetROP2(physDev
->hdc
), color
, &and, &xor);
1027 /* sets the pixel */
1028 physDev
->physBitmap
->funcs
->SetPixel(physDev
->physBitmap
, x
, y
, and, xor);
1032 /* DDB selected in, use X11 driver */
1033 res
= _DIBDRV_GetDisplayDriver()->pSetPixel(physDev
->X11PhysDev
, x
, y
, color
);
1038 /***********************************************************************
1041 DWORD
DIBDRV_SetDCOrg( DIBDRVPHYSDEV
*physDev
, int x
, int y
)
1045 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev
, x
, y
));
1049 /* DIB section selected in, use DIB Engine */
1050 ONCE(FIXME("STUB\n"));
1055 /* DDB selected in, use X11 driver */
1056 res
= _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev
->X11PhysDev
, x
, y
);