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
29static void
30fbZeroLine(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
57static void
58fbZeroSegment(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
75void
76fbFixCoordModePrevious(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
90void
91fbPolyLine(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
122void
123fbPolySegment(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