fbfillrect.c revision 706f2543
1/*
2 * Copyright © 1998 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission.  Keith Packard makes no
11 * representations about the suitability of this software for any purpose.  It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_DIX_CONFIG_H
24#include <dix-config.h>
25#endif
26
27#include "fb.h"
28
29void
30fbPolyFillRect(DrawablePtr  pDrawable,
31	       GCPtr	    pGC,
32	       int	    nrect,
33	       xRectangle   *prect)
34{
35    RegionPtr	    pClip = fbGetCompositeClip(pGC);
36    register BoxPtr pbox;
37    BoxPtr	    pextent;
38    int		    extentX1, extentX2, extentY1, extentY2;
39    int		    fullX1, fullX2, fullY1, fullY2;
40    int		    partX1, partX2, partY1, partY2;
41    int		    xorg, yorg;
42    int		    n;
43
44    xorg = pDrawable->x;
45    yorg = pDrawable->y;
46
47    pextent = RegionExtents(pClip);
48    extentX1 = pextent->x1;
49    extentY1 = pextent->y1;
50    extentX2 = pextent->x2;
51    extentY2 = pextent->y2;
52    while (nrect--)
53    {
54	fullX1 = prect->x + xorg;
55	fullY1 = prect->y + yorg;
56	fullX2 = fullX1 + (int) prect->width;
57	fullY2 = fullY1 + (int) prect->height;
58	prect++;
59
60	if (fullX1 < extentX1)
61	    fullX1 = extentX1;
62
63	if (fullY1 < extentY1)
64	    fullY1 = extentY1;
65
66	if (fullX2 > extentX2)
67	    fullX2 = extentX2;
68
69	if (fullY2 > extentY2)
70	    fullY2 = extentY2;
71
72	if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
73	    continue;
74	n = RegionNumRects (pClip);
75	if (n == 1)
76	{
77	    fbFill (pDrawable,
78		    pGC,
79		    fullX1, fullY1, fullX2-fullX1, fullY2-fullY1);
80	}
81	else
82	{
83	    pbox = RegionRects(pClip);
84	    /*
85	     * clip the rectangle to each box in the clip region
86	     * this is logically equivalent to calling Intersect()
87	     */
88	    while(n--)
89	    {
90		partX1 = pbox->x1;
91		if (partX1 < fullX1)
92		    partX1 = fullX1;
93		partY1 = pbox->y1;
94		if (partY1 < fullY1)
95		    partY1 = fullY1;
96		partX2 = pbox->x2;
97		if (partX2 > fullX2)
98		    partX2 = fullX2;
99		partY2 = pbox->y2;
100		if (partY2 > fullY2)
101		    partY2 = fullY2;
102
103		pbox++;
104
105		if (partX1 < partX2 && partY1 < partY2)
106		    fbFill (pDrawable, pGC,
107			    partX1, partY1,
108			    partX2 - partX1, partY2 - partY1);
109	    }
110	}
111    }
112}
113