1/*
2 * Copyright © 1998 Keith Packard
3 * Copyright © 2012 Intel Corporation
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and its
6 * documentation for any purpose is hereby granted without fee, provided that
7 * the above copyright notice appear in all copies and that both that
8 * copyright notice and this permission notice appear in supporting
9 * documentation, and that the name of Keith Packard not be used in
10 * advertising or publicity pertaining to distribution of the software without
11 * specific, written prior permission.  Keith Packard makes no
12 * representations about the suitability of this software for any purpose.  It
13 * is provided "as is" without express or implied warranty.
14 *
15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21 * PERFORMANCE OF THIS SOFTWARE.
22 */
23
24#include "fb.h"
25#include <mi.h>
26#include <micoord.h>
27#include <miline.h>
28#include <scrnintstr.h>
29
30#define POLYLINE    fbPolyline8
31#define POLYSEGMENT fbPolySegment8
32#define BITS	    BYTE
33#define BITS2	    CARD16
34#define BITS4	    CARD32
35#include "fblinebits.h"
36#undef BITS
37#undef BITS2
38#undef BITS4
39#undef POLYSEGMENT
40#undef POLYLINE
41
42#define POLYLINE    fbPolyline16
43#define POLYSEGMENT fbPolySegment16
44#define BITS	    CARD16
45#define BITS2	    CARD32
46#include "fblinebits.h"
47#undef BITS
48#undef BITS2
49#undef POLYSEGMENT
50#undef POLYLINE
51
52#define POLYLINE    fbPolyline32
53#define POLYSEGMENT fbPolySegment32
54#define BITS	    CARD32
55#include "fblinebits.h"
56#undef BITS
57#undef POLYSEGMENT
58#undef POLYLINE
59
60static void
61fbZeroLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt)
62{
63	int x1, y1, x2, y2;
64	int x, y;
65	int dashOffset;
66
67	x = drawable->x;
68	y = drawable->y;
69	x1 = pt->x;
70	y1 = pt->y;
71	dashOffset = gc->dashOffset;
72	while (--n) {
73		++pt;
74		x2 = pt->x;
75		y2 = pt->y;
76		if (mode == CoordModePrevious) {
77			x2 += x1;
78			y2 += y1;
79		}
80		fbSegment(drawable, gc,
81			  x1 + x, y1 + y,
82			  x2 + x, y2 + y,
83			  n == 1 && gc->capStyle != CapNotLast, &dashOffset);
84		x1 = x2;
85		y1 = y2;
86	}
87}
88
89static void
90fbZeroSegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
91{
92	int dashOffset;
93	int16_t x, y;
94	Bool drawLast = gc->capStyle != CapNotLast;
95
96	x = drawable->x;
97	y = drawable->y;
98	while (n--) {
99		dashOffset = gc->dashOffset;
100		fbSegment(drawable, gc,
101			  seg->x1 + x, seg->y1 + y,
102			  seg->x2 + x, seg->y2 + y,
103			  drawLast, &dashOffset);
104		seg++;
105	}
106}
107
108void
109fbFixCoordModePrevious(int n, DDXPointPtr pt)
110{
111	int16_t x = pt->x;
112	int16_t y = pt->y;
113	while (--n) {
114		pt++;
115		x = (pt->x += x);
116		y = (pt->y += y);
117	}
118}
119
120void
121fbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt)
122{
123	void (*raster)(DrawablePtr, GCPtr, int mode, int n, DDXPointPtr pt);
124
125	DBG(("%s x %d, width=%d, fill=%d [solid? %d], line=%d [solid? %d], bpp=%d\n",
126	     __FUNCTION__, n, gc->lineWidth,
127	     gc->fillStyle, gc->fillStyle == FillSolid,
128	     gc->lineStyle, gc->lineStyle == LineSolid,
129	     drawable->bitsPerPixel));
130
131	if (gc->lineWidth == 0) {
132		raster = fbZeroLine;
133		if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) {
134			switch (drawable->bitsPerPixel) {
135			case 8:
136				raster = fbPolyline8;
137				break;
138			case 16:
139				raster = fbPolyline16;
140				break;
141			case 32:
142				raster = fbPolyline32;
143				break;
144			}
145		}
146	} else {
147		if (gc->lineStyle != LineSolid)
148			raster = miWideDash;
149		else
150			raster = miWideLine;
151	}
152	raster(drawable, gc, mode, n, pt);
153}
154
155void
156fbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
157{
158	void (*raster)(DrawablePtr drawable, GCPtr gc, int n, xSegment * seg);
159
160	DBG(("%s x %d, width=%d, fill=%d [solid? %d], line=%d [solid? %d], bpp=%d\n",
161	     __FUNCTION__, n, gc->lineWidth,
162	     gc->fillStyle, gc->fillStyle == FillSolid,
163	     gc->lineStyle, gc->lineStyle == LineSolid,
164	     drawable->bitsPerPixel));
165
166	if (gc->lineWidth == 0) {
167		raster = fbZeroSegment;
168		if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) {
169			switch (drawable->bitsPerPixel) {
170			case 8:
171				raster = fbPolySegment8;
172				break;
173			case 16:
174				raster = fbPolySegment16;
175				break;
176			case 32:
177				raster = fbPolySegment32;
178				break;
179			}
180		}
181	} else
182		raster = miPolySegment;
183
184	raster(drawable, gc, n, seg);
185}
186