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 /***********************************************************************
387 BOOL
DIBDRV_Arc( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
,
388 int xstart
, int ystart
, int xend
, int yend
)
392 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
393 physDev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
397 /* DIB section selected in, use DIB Engine */
398 ONCE(FIXME("STUB\n"));
403 /* DDB selected in, use X11 driver */
404 res
= _DIBDRV_GetDisplayDriver()->pArc(physDev
->X11PhysDev
, left
, top
, right
, bottom
,
405 xstart
, ystart
, xend
, yend
);
410 /***********************************************************************
413 BOOL
DIBDRV_Chord( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
,
414 int xstart
, int ystart
, int xend
, int yend
)
418 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
419 physDev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
423 /* DIB section selected in, use DIB Engine */
424 ONCE(FIXME("STUB\n"));
429 /* DDB selected in, use X11 driver */
430 res
= _DIBDRV_GetDisplayDriver()->pChord(physDev
->X11PhysDev
, left
, top
, right
, bottom
,
431 xstart
, ystart
, xend
, yend
);
436 /***********************************************************************
439 BOOL
DIBDRV_Ellipse( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
)
443 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n",
444 physDev
, left
, top
, right
, bottom
));
448 /* DIB section selected in, use DIB Engine */
449 ONCE(FIXME("STUB\n"));
454 /* DDB selected in, use X11 driver */
455 res
= _DIBDRV_GetDisplayDriver()->pEllipse(physDev
->X11PhysDev
, left
, top
, right
, bottom
);
460 /**********************************************************************
461 * DIBDRV_ExtFloodFill
463 BOOL
DIBDRV_ExtFloodFill( DIBDRVPHYSDEV
*physDev
, int x
, int y
, COLORREF color
,
468 MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x, fillType:%d\n",
469 physDev
, x
, y
, color
, fillType
));
473 /* DIB section selected in, use DIB Engine */
474 ONCE(FIXME("STUB\n"));
479 /* DDB selected in, use X11 driver */
480 res
= _DIBDRV_GetDisplayDriver()->pExtFloodFill(physDev
->X11PhysDev
, x
, y
, color
, fillType
);
485 /***********************************************************************
488 BOOL
DIBDRV_GetDCOrgEx( DIBDRVPHYSDEV
*physDev
, LPPOINT lpp
)
492 MAYBE(TRACE("physDev:%p, lpp:%p\n", physDev
, lpp
));
496 /* DIB section selected in, use DIB Engine */
497 ONCE(FIXME("STUB\n"));
502 /* DDB selected in, use X11 driver */
503 res
= _DIBDRV_GetDisplayDriver()->pGetDCOrgEx(physDev
->X11PhysDev
, lpp
);
508 /***********************************************************************
511 COLORREF
DIBDRV_GetPixel( DIBDRVPHYSDEV
*physDev
, int x
, int y
)
515 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev
, x
, y
));
519 _DIBDRV_Position_ws2ds(physDev
, &x
, &y
);
520 res
= physDev
->physBitmap
->funcs
->GetPixel(physDev
->physBitmap
, x
, y
);
524 /* DDB selected in, use X11 driver */
525 res
= _DIBDRV_GetDisplayDriver()->pGetPixel(physDev
->X11PhysDev
, x
, y
);
530 /***********************************************************************
533 BOOL
DIBDRV_LineTo( DIBDRVPHYSDEV
*physDev
, int x
, int y
)
539 POINT p1
, p2
, pc1
, pc2
;
541 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev
, x
, y
));
546 GetCurrentPositionEx(physDev
->hdc
, &curPos
);
548 /* converts position to device space */
549 p1
.x
= curPos
.x
; p1
.y
= curPos
.y
;
551 LPtoDP(physDev
->hdc
, &p1
, 1);
552 LPtoDP(physDev
->hdc
, &p2
, 1);
554 /* cycle on all current clipping rectangles */
555 r
= physDev
->regionRects
;
556 for(iRec
= 0; iRec
< physDev
->regionRectCount
; iRec
++, r
++)
558 _DIBDRV_ResetDashOrigin(physDev
);
560 /* clipe line on current region area */
561 if(ClipLine(&p1
, &p2
, r
, &pc1
, &pc2
))
564 physDev
->penHLine(physDev
, pc1
.x
, pc2
.x
, pc1
.y
);
565 else if(pc1
.x
== pc2
.x
)
566 physDev
->penVLine(physDev
, pc1
.x
, pc1
.y
, pc2
.y
);
568 physDev
->penLine(physDev
, pc1
.x
, pc1
.y
, pc2
.x
, pc2
.y
);
573 /* moves current position to next point */
574 MoveToEx(physDev
->hdc
, x
, y
, NULL
);
578 /* DDB selected in, use X11 driver */
579 res
= _DIBDRV_GetDisplayDriver()->pLineTo(physDev
->X11PhysDev
, x
, y
);
584 /***********************************************************************
587 BOOL
DIBDRV_Rectangle( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
);
588 BOOL
DIBDRV_PaintRgn( DIBDRVPHYSDEV
*physDev
, HRGN hrgn
)
596 MAYBE(TRACE("physDev:%p, hrgn:%p\n", physDev
, hrgn
));
600 /* gets needed region data size */
601 if(!(size
= GetRegionData(hrgn
, 0, NULL
)))
604 /* allocates buffer and gets actual region data */
605 if(!(data
= HeapAlloc(GetProcessHeap(), 0, size
)))
607 if(!GetRegionData(hrgn
, size
, data
))
609 HeapFree(GetProcessHeap(), 0, data
);
613 /* paints the filled rectangles */
614 rect
= (RECT
*)data
->Buffer
;
615 for(i
= 0; i
< data
->rdh
.nCount
; i
++)
617 DIBDRV_Rectangle( physDev
, rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
620 HeapFree( GetProcessHeap(), 0, data
);
627 /* DDB selected in, use X11 driver */
628 res
= _DIBDRV_GetDisplayDriver()->pPaintRgn(physDev
->X11PhysDev
, hrgn
);
633 /***********************************************************************
636 BOOL
DIBDRV_Pie( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
, int bottom
,
637 int xstart
, int ystart
, int xend
, int yend
)
641 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, xstart:%d, ystart:%d, xend:%d, yend:%d\n",
642 physDev
, left
, top
, right
, bottom
, xstart
, ystart
, xend
, yend
));
646 /* DIB section selected in, use DIB Engine */
647 ONCE(FIXME("STUB\n"));
652 /* DDB selected in, use X11 driver */
653 res
= _DIBDRV_GetDisplayDriver()->pPie(physDev
->X11PhysDev
, left
, top
, right
, bottom
,
654 xstart
, ystart
, xend
, yend
);
659 /**********************************************************************
662 BOOL
DIBDRV_Polygon( DIBDRVPHYSDEV
*physDev
, const POINT
* ptw
, int count
)
673 int scanCount
, iScan
;
674 const POINT
*p1
, *p2
;
678 MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev
, ptw
, count
));
682 /* DIB section selected in, use DIB Engine */
686 /* first converts all points to device coords */
687 if(!(pt
= HeapAlloc(GetProcessHeap(), 0, sizeof(POINT
) * count
)))
689 memcpy(pt
, ptw
, sizeof(POINT
) * count
);
690 LPtoDP(physDev
->hdc
, pt
, count
);
692 /* cycle on all current clipping rectangles */
693 r
= physDev
->regionRects
;
694 for(iRec
= 0; iRec
< physDev
->regionRectCount
; iRec
++, r
++)
697 if(ClipPolygon(pt
, count
, r
, &clipped
, &clippedCount
))
699 /* gets polygon bounding box -- for ytop and ybottom */
700 PolygonBoundingBox(clipped
, clippedCount
, &bBox
);
702 /* gets all ordered intersections of polygon with
704 for(ys
= bBox
.top
; ys
< bBox
.bottom
; ys
++)
706 if(ScanPolygon(clipped
, clippedCount
, ys
, &scans
, &scanCount
))
714 while(iScan
< scanCount
- 1)
716 physDev
->brushHLine(physDev
, p1
->x
, p2
->x
, ys
);
722 HeapFree(GetProcessHeap(), 0, scans
);
725 HeapFree(GetProcessHeap(), 0, clipped
);
728 /* perimeter -- don't use PolyLine for speed */
730 for(iPoint
= 0; iPoint
< count
-1; iPoint
++)
733 if(ClipLine(p1
, p2
, r
, &pc1
, &pc2
))
736 physDev
->penLine(physDev
, pc1
.x
, pc1
.y
, pc2
.x
, pc2
.y
);
741 if(ClipLine(p1
, p2
, r
, &pc1
, &pc2
))
744 physDev
->penLine(physDev
, pc1
.x
, pc1
.y
, pc2
.x
, pc2
.y
);
748 HeapFree(GetProcessHeap(), 0, pt
);
753 /* DDB selected in, use X11 driver */
754 res
= _DIBDRV_GetDisplayDriver()->pPolygon(physDev
->X11PhysDev
, ptw
, count
);
760 /**********************************************************************
763 BOOL
DIBDRV_Polyline( DIBDRVPHYSDEV
*physDev
, const POINT
* ptw
, int count
)
767 MAYBE(TRACE("physDev:%p, pt:%p, count:%d\n", physDev
, ptw
, count
));
771 /* DIB section selected in, use DIB Engine */
781 /* first converts all points to device coords */
782 if(!(pt
= HeapAlloc(GetProcessHeap(), 0, sizeof(POINT
) * count
)))
784 memcpy(pt
, ptw
, sizeof(POINT
) * count
);
785 LPtoDP(physDev
->hdc
, pt
, count
);
787 r
= physDev
->regionRects
;
788 for(iRec
= 0; iRec
< physDev
->regionRectCount
; iRec
++)
790 const POINT
*p2
= pt
, *p1
;
791 for(iPoint
= 0; iPoint
< count
-1; iPoint
++)
794 if(ClipLine(p1
, p2
, r
, &pc1
, &pc2
))
797 physDev
->penLine(physDev
, pc1
.x
, pc1
.y
, pc2
.x
, pc2
.y
);
803 HeapFree(GetProcessHeap(), 0, pt
);
809 /* DDB selected in, use X11 driver */
810 res
= _DIBDRV_GetDisplayDriver()->pPolyline(physDev
->X11PhysDev
, ptw
, count
);
815 /**********************************************************************
818 BOOL
DIBDRV_PolyPolygon( DIBDRVPHYSDEV
*physDev
, const POINT
* pt
, const int* counts
, UINT polygons
)
822 MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polygons:%d\n", physDev
, pt
, counts
, polygons
));
826 /* DIB section selected in, use DIB Engine */
827 ONCE(FIXME("STUB\n"));
832 /* DDB selected in, use X11 driver */
833 res
= _DIBDRV_GetDisplayDriver()->pPolyPolygon(physDev
->X11PhysDev
, pt
, counts
, polygons
);
838 /**********************************************************************
839 * DIBDRV_PolyPolyline
841 BOOL
DIBDRV_PolyPolyline( DIBDRVPHYSDEV
*physDev
, const POINT
* pt
, const DWORD
* counts
,
846 MAYBE(TRACE("physDev:%p, pt:%p, counts:%p, polylines:%d\n", physDev
, pt
, counts
, polylines
));
850 /* DIB section selected in, use DIB Engine */
851 ONCE(FIXME("STUB\n"));
856 /* DDB selected in, use X11 driver */
857 res
= _DIBDRV_GetDisplayDriver()->pPolyPolyline(physDev
->X11PhysDev
, pt
, counts
, polylines
);
862 /***********************************************************************
865 BOOL
DIBDRV_Rectangle( DIBDRVPHYSDEV
*physDev
, int x1
, int y1
, int x2
, int y2
)
869 RECT rWorld
, rDevice
, rClipped
;
873 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d\n", physDev
, x1
, y1
, x2
, y2
));
882 /* converts to device space */
883 rWorld
.left
= x1
; rWorld
.top
= y1
; rWorld
.right
= x2
; rWorld
.bottom
= y2
;
884 _DIBDRV_Rect_ws2ds(physDev
, &rWorld
, &rDevice
);
886 /* loop on all clip region rectangles */
887 r
= physDev
->regionRects
;
888 for(iRec
= 0; iRec
< physDev
->regionRectCount
; iRec
++, r
++)
890 /* clips rectangle to current region */
891 if(_DIBDRV_IntersectRect(&rClipped
, &rDevice
, r
))
893 x1
= rClipped
.left
; y1
= rClipped
.top
;
894 x2
= rClipped
.right
; y2
= rClipped
.bottom
;
896 _DIBDRV_ResetDashOrigin(physDev
);
898 /* fill the inside, if not null brush */
899 if(physDev
->brushStyle
!= BS_NULL
)
902 for (i
= y1
; i
< y2
; i
++)
903 physDev
->brushHLine(physDev
, x1
, x2
, i
);
906 /* draw perimeter, if not null pen */
907 if(physDev
->penStyle
!= PS_NULL
)
910 /* particular case where the rectangle
911 degenerates to a line or a point */
913 physDev
->penVLine(physDev
, x1
, y1
, y2
);
914 else if (y1
>= y2
-1)
915 physDev
->penHLine(physDev
, x1
, x2
, y1
);
918 /* Draw the perimeter */
919 physDev
->penHLine(physDev
, x1
, x2
, y1
);
920 physDev
->penHLine(physDev
, x1
, x2
, y2
- 1);
921 physDev
->penVLine(physDev
, x1
, y1
+ 1, y2
- 1);
922 physDev
->penVLine(physDev
, x2
- 1, y1
+ 1, y2
- 1);
931 /* DDB selected in, use X11 driver */
932 res
= _DIBDRV_GetDisplayDriver()->pRectangle(physDev
->X11PhysDev
, x1
, y1
, x2
, y2
);
937 /***********************************************************************
940 BOOL
DIBDRV_RoundRect( DIBDRVPHYSDEV
*physDev
, int left
, int top
, int right
,
941 int bottom
, int ell_width
, int ell_height
)
945 MAYBE(TRACE("physDev:%p, left:%d, top:%d, right:%d, bottom:%d, ell_width:%d, ell_height:%d\n",
946 physDev
, left
, top
, right
, bottom
, ell_width
, ell_height
));
950 /* DIB section selected in, use DIB Engine */
951 ONCE(FIXME("STUB\n"));
956 /* DDB selected in, use X11 driver */
957 res
= _DIBDRV_GetDisplayDriver()->pRoundRect(physDev
->X11PhysDev
, left
, top
, right
, bottom
,
958 ell_width
, ell_height
);
963 /***********************************************************************
966 COLORREF
DIBDRV_SetPixel( DIBDRVPHYSDEV
*physDev
, int x
, int y
, COLORREF color
)
971 MAYBE(TRACE("physDev:%p, x:%d, y:%d, color:%x\n", physDev
, x
, y
, color
));
975 /* get real colorref */
976 color
= _DIBDRV_MapColor(physDev
, color
);
978 /* map to pixel color / palette index */
979 color
= physDev
->physBitmap
->funcs
->ColorToPixel(physDev
->physBitmap
, color
);
981 _DIBDRV_Position_ws2ds(physDev
, &x
, &y
);
983 /* gets previous pixel */
984 res
= physDev
->physBitmap
->funcs
->GetPixel(physDev
->physBitmap
, x
, y
);
986 /* calculates AND and XOR from color */
987 _DIBDRV_CalcAndXorMasks(GetROP2(physDev
->hdc
), color
, &and, &xor);
990 physDev
->physBitmap
->funcs
->SetPixel(physDev
->physBitmap
, x
, y
, and, xor);
994 /* DDB selected in, use X11 driver */
995 res
= _DIBDRV_GetDisplayDriver()->pSetPixel(physDev
->X11PhysDev
, x
, y
, color
);
1000 /***********************************************************************
1003 DWORD
DIBDRV_SetDCOrg( DIBDRVPHYSDEV
*physDev
, int x
, int y
)
1007 MAYBE(TRACE("physDev:%p, x:%d, y:%d\n", physDev
, x
, y
));
1011 /* DIB section selected in, use DIB Engine */
1012 ONCE(FIXME("STUB\n"));
1017 /* DDB selected in, use X11 driver */
1018 res
= _DIBDRV_GetDisplayDriver()->pSetDCOrg(physDev
->X11PhysDev
, x
, y
);