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 
29 static void
fbZeroLine(DrawablePtr pDrawable,GCPtr pGC,int mode,int npt,DDXPointPtr ppt)30 fbZeroLine(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
31 {
32     int x1, y1, x2, y2;
33     int x, y;
34     int dashOffset;
35 
36     x = pDrawable->x;
37     y = pDrawable->y;
38     x1 = ppt->x;
39     y1 = ppt->y;
40     dashOffset = pGC->dashOffset;
41     while (--npt) {
42         ++ppt;
43         x2 = ppt->x;
44         y2 = ppt->y;
45         if (mode == CoordModePrevious) {
46             x2 += x1;
47             y2 += y1;
48         }
49         fbSegment(pDrawable, pGC, x1 + x, y1 + y,
50                   x2 + x, y2 + y,
51                   npt == 1 && pGC->capStyle != CapNotLast, &dashOffset);
52         x1 = x2;
53         y1 = y2;
54     }
55 }
56 
57 static void
fbZeroSegment(DrawablePtr pDrawable,GCPtr pGC,int nseg,xSegment * pSegs)58 fbZeroSegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pSegs)
59 {
60     int dashOffset;
61     int x, y;
62     Bool drawLast = pGC->capStyle != CapNotLast;
63 
64     x = pDrawable->x;
65     y = pDrawable->y;
66     while (nseg--) {
67         dashOffset = pGC->dashOffset;
68         fbSegment(pDrawable, pGC,
69                   pSegs->x1 + x, pSegs->y1 + y,
70                   pSegs->x2 + x, pSegs->y2 + y, drawLast, &dashOffset);
71         pSegs++;
72     }
73 }
74 
75 void
fbFixCoordModePrevious(int npt,DDXPointPtr ppt)76 fbFixCoordModePrevious(int npt, DDXPointPtr ppt)
77 {
78     int x, y;
79 
80     x = ppt->x;
81     y = ppt->y;
82     npt--;
83     while (npt--) {
84         ppt++;
85         x = (ppt->x += x);
86         y = (ppt->y += y);
87     }
88 }
89 
90 void
fbPolyLine(DrawablePtr pDrawable,GCPtr pGC,int mode,int npt,DDXPointPtr ppt)91 fbPolyLine(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, DDXPointPtr ppt)
92 {
93     void (*line) (DrawablePtr, GCPtr, int mode, int npt, DDXPointPtr ppt);
94 
95     if (pGC->lineWidth == 0) {
96         line = fbZeroLine;
97         if (pGC->fillStyle == FillSolid &&
98             pGC->lineStyle == LineSolid &&
99             RegionNumRects(fbGetCompositeClip(pGC)) == 1) {
100             switch (pDrawable->bitsPerPixel) {
101             case 8:
102                 line = fbPolyline8;
103                 break;
104             case 16:
105                 line = fbPolyline16;
106                 break;
107             case 32:
108                 line = fbPolyline32;
109                 break;
110             }
111         }
112     }
113     else {
114         if (pGC->lineStyle != LineSolid)
115             line = miWideDash;
116         else
117             line = miWideLine;
118     }
119     (*line) (pDrawable, pGC, mode, npt, ppt);
120 }
121 
122 void
fbPolySegment(DrawablePtr pDrawable,GCPtr pGC,int nseg,xSegment * pseg)123 fbPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg)
124 {
125     void (*seg) (DrawablePtr pDrawable, GCPtr pGC, int nseg, xSegment * pseg);
126 
127     if (pGC->lineWidth == 0) {
128         seg = fbZeroSegment;
129         if (pGC->fillStyle == FillSolid &&
130             pGC->lineStyle == LineSolid &&
131             RegionNumRects(fbGetCompositeClip(pGC)) == 1) {
132             switch (pDrawable->bitsPerPixel) {
133             case 8:
134                 seg = fbPolySegment8;
135                 break;
136             case 16:
137                 seg = fbPolySegment16;
138                 break;
139             case 32:
140                 seg = fbPolySegment32;
141                 break;
142             }
143         }
144     }
145     else {
146         seg = miPolySegment;
147     }
148     (*seg) (pDrawable, pGC, nseg, pseg);
149 }
150