Commit | Line | Data |
---|---|---|
a09e091a JB |
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 | #include "mizerarc.h" | |
29 | #include <limits.h> | |
30 | ||
31 | typedef void (*FbArc) (FbBits * dst, | |
32 | FbStride dstStride, | |
33 | int dstBpp, | |
34 | xArc * arc, int dx, int dy, FbBits and, FbBits xor); | |
35 | ||
36 | void | |
37 | fbPolyArc(DrawablePtr pDrawable, GCPtr pGC, int narcs, xArc * parcs) | |
38 | { | |
39 | FbArc arc; | |
40 | ||
41 | if (pGC->lineWidth == 0) { | |
42 | arc = 0; | |
43 | if (pGC->lineStyle == LineSolid && pGC->fillStyle == FillSolid) { | |
44 | switch (pDrawable->bitsPerPixel) { | |
45 | case 8: | |
46 | arc = fbArc8; | |
47 | break; | |
48 | case 16: | |
49 | arc = fbArc16; | |
50 | break; | |
51 | case 24: | |
52 | arc = fbArc24; | |
53 | break; | |
54 | case 32: | |
55 | arc = fbArc32; | |
56 | break; | |
57 | } | |
58 | } | |
59 | if (arc) { | |
60 | FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); | |
61 | FbBits *dst; | |
62 | FbStride dstStride; | |
63 | int dstBpp; | |
64 | int dstXoff, dstYoff; | |
65 | BoxRec box; | |
66 | int x2, y2; | |
67 | RegionPtr cclip; | |
68 | ||
69 | #ifdef FB_ACCESS_WRAPPER | |
70 | int wrapped = 1; | |
71 | #endif | |
72 | ||
73 | cclip = fbGetCompositeClip(pGC); | |
74 | fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); | |
75 | while (narcs--) { | |
76 | if (miCanZeroArc(parcs)) { | |
77 | box.x1 = parcs->x + pDrawable->x; | |
78 | box.y1 = parcs->y + pDrawable->y; | |
79 | /* | |
80 | * Because box.x2 and box.y2 get truncated to 16 bits, and the | |
81 | * RECT_IN_REGION test treats the resulting number as a signed | |
82 | * integer, the RECT_IN_REGION test alone can go the wrong way. | |
83 | * This can result in a server crash because the rendering | |
84 | * routines in this file deal directly with cpu addresses | |
85 | * of pixels to be stored, and do not clip or otherwise check | |
86 | * that all such addresses are within their respective pixmaps. | |
87 | * So we only allow the RECT_IN_REGION test to be used for | |
88 | * values that can be expressed correctly in a signed short. | |
89 | */ | |
90 | x2 = box.x1 + (int) parcs->width + 1; | |
91 | box.x2 = x2; | |
92 | y2 = box.y1 + (int) parcs->height + 1; | |
93 | box.y2 = y2; | |
94 | if ((x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) && | |
95 | (RegionContainsRect(cclip, &box) == rgnIN)) { | |
96 | #ifdef FB_ACCESS_WRAPPER | |
97 | if (!wrapped) { | |
98 | fbPrepareAccess(pDrawable); | |
99 | wrapped = 1; | |
100 | } | |
101 | #endif | |
102 | (*arc) (dst, dstStride, dstBpp, | |
103 | parcs, pDrawable->x + dstXoff, | |
104 | pDrawable->y + dstYoff, pPriv->and, pPriv->xor); | |
105 | } | |
106 | else { | |
107 | #ifdef FB_ACCESS_WRAPPER | |
108 | if (wrapped) { | |
109 | fbFinishAccess(pDrawable); | |
110 | wrapped = 0; | |
111 | } | |
112 | #endif | |
113 | miZeroPolyArc(pDrawable, pGC, 1, parcs); | |
114 | } | |
115 | } | |
116 | else { | |
117 | #ifdef FB_ACCESS_WRAPPER | |
118 | if (wrapped) { | |
119 | fbFinishAccess(pDrawable); | |
120 | wrapped = 0; | |
121 | } | |
122 | #endif | |
123 | miPolyArc(pDrawable, pGC, 1, parcs); | |
124 | } | |
125 | parcs++; | |
126 | } | |
127 | #ifdef FB_ACCESS_WRAPPER | |
128 | if (wrapped) { | |
129 | fbFinishAccess(pDrawable); | |
130 | wrapped = 0; | |
131 | } | |
132 | #endif | |
133 | } | |
134 | else | |
135 | miZeroPolyArc(pDrawable, pGC, narcs, parcs); | |
136 | } | |
137 | else | |
138 | miPolyArc(pDrawable, pGC, narcs, parcs); | |
139 | } |