1428d7b3dSmrg/*
2428d7b3dSmrg * Copyright © 1998 Keith Packard
3428d7b3dSmrg * Copyright © 2012 Intel Corporation
4428d7b3dSmrg *
5428d7b3dSmrg * Permission to use, copy, modify, distribute, and sell this software and its
6428d7b3dSmrg * documentation for any purpose is hereby granted without fee, provided that
7428d7b3dSmrg * the above copyright notice appear in all copies and that both that
8428d7b3dSmrg * copyright notice and this permission notice appear in supporting
9428d7b3dSmrg * documentation, and that the name of Keith Packard not be used in
10428d7b3dSmrg * advertising or publicity pertaining to distribution of the software without
11428d7b3dSmrg * specific, written prior permission.  Keith Packard makes no
12428d7b3dSmrg * representations about the suitability of this software for any purpose.  It
13428d7b3dSmrg * is provided "as is" without express or implied warranty.
14428d7b3dSmrg *
15428d7b3dSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16428d7b3dSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17428d7b3dSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18428d7b3dSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19428d7b3dSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20428d7b3dSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
21428d7b3dSmrg * PERFORMANCE OF THIS SOFTWARE.
22428d7b3dSmrg */
23428d7b3dSmrg
24428d7b3dSmrg#include "fb.h"
25428d7b3dSmrg#include <mi.h>
26428d7b3dSmrg#include <micoord.h>
27428d7b3dSmrg#include <miline.h>
28428d7b3dSmrg#include <scrnintstr.h>
29428d7b3dSmrg
30428d7b3dSmrg#define POLYLINE    fbPolyline8
31428d7b3dSmrg#define POLYSEGMENT fbPolySegment8
32428d7b3dSmrg#define BITS	    BYTE
33428d7b3dSmrg#define BITS2	    CARD16
34428d7b3dSmrg#define BITS4	    CARD32
35428d7b3dSmrg#include "fblinebits.h"
36428d7b3dSmrg#undef BITS
37428d7b3dSmrg#undef BITS2
38428d7b3dSmrg#undef BITS4
39428d7b3dSmrg#undef POLYSEGMENT
40428d7b3dSmrg#undef POLYLINE
41428d7b3dSmrg
42428d7b3dSmrg#define POLYLINE    fbPolyline16
43428d7b3dSmrg#define POLYSEGMENT fbPolySegment16
44428d7b3dSmrg#define BITS	    CARD16
45428d7b3dSmrg#define BITS2	    CARD32
46428d7b3dSmrg#include "fblinebits.h"
47428d7b3dSmrg#undef BITS
48428d7b3dSmrg#undef BITS2
49428d7b3dSmrg#undef POLYSEGMENT
50428d7b3dSmrg#undef POLYLINE
51428d7b3dSmrg
52428d7b3dSmrg#define POLYLINE    fbPolyline32
53428d7b3dSmrg#define POLYSEGMENT fbPolySegment32
54428d7b3dSmrg#define BITS	    CARD32
55428d7b3dSmrg#include "fblinebits.h"
56428d7b3dSmrg#undef BITS
57428d7b3dSmrg#undef POLYSEGMENT
58428d7b3dSmrg#undef POLYLINE
59428d7b3dSmrg
60428d7b3dSmrgstatic void
61428d7b3dSmrgfbZeroLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt)
62428d7b3dSmrg{
63428d7b3dSmrg	int x1, y1, x2, y2;
64428d7b3dSmrg	int x, y;
65428d7b3dSmrg	int dashOffset;
66428d7b3dSmrg
67428d7b3dSmrg	x = drawable->x;
68428d7b3dSmrg	y = drawable->y;
69428d7b3dSmrg	x1 = pt->x;
70428d7b3dSmrg	y1 = pt->y;
71428d7b3dSmrg	dashOffset = gc->dashOffset;
72428d7b3dSmrg	while (--n) {
73428d7b3dSmrg		++pt;
74428d7b3dSmrg		x2 = pt->x;
75428d7b3dSmrg		y2 = pt->y;
76428d7b3dSmrg		if (mode == CoordModePrevious) {
77428d7b3dSmrg			x2 += x1;
78428d7b3dSmrg			y2 += y1;
79428d7b3dSmrg		}
80428d7b3dSmrg		fbSegment(drawable, gc,
81428d7b3dSmrg			  x1 + x, y1 + y,
82428d7b3dSmrg			  x2 + x, y2 + y,
83428d7b3dSmrg			  n == 1 && gc->capStyle != CapNotLast, &dashOffset);
84428d7b3dSmrg		x1 = x2;
85428d7b3dSmrg		y1 = y2;
86428d7b3dSmrg	}
87428d7b3dSmrg}
88428d7b3dSmrg
89428d7b3dSmrgstatic void
90428d7b3dSmrgfbZeroSegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
91428d7b3dSmrg{
92428d7b3dSmrg	int dashOffset;
93428d7b3dSmrg	int16_t x, y;
94428d7b3dSmrg	Bool drawLast = gc->capStyle != CapNotLast;
95428d7b3dSmrg
96428d7b3dSmrg	x = drawable->x;
97428d7b3dSmrg	y = drawable->y;
98428d7b3dSmrg	while (n--) {
99428d7b3dSmrg		dashOffset = gc->dashOffset;
100428d7b3dSmrg		fbSegment(drawable, gc,
101428d7b3dSmrg			  seg->x1 + x, seg->y1 + y,
102428d7b3dSmrg			  seg->x2 + x, seg->y2 + y,
103428d7b3dSmrg			  drawLast, &dashOffset);
104428d7b3dSmrg		seg++;
105428d7b3dSmrg	}
106428d7b3dSmrg}
107428d7b3dSmrg
108428d7b3dSmrgvoid
109428d7b3dSmrgfbFixCoordModePrevious(int n, DDXPointPtr pt)
110428d7b3dSmrg{
111428d7b3dSmrg	int16_t x = pt->x;
112428d7b3dSmrg	int16_t y = pt->y;
113428d7b3dSmrg	while (--n) {
114428d7b3dSmrg		pt++;
115428d7b3dSmrg		x = (pt->x += x);
116428d7b3dSmrg		y = (pt->y += y);
117428d7b3dSmrg	}
118428d7b3dSmrg}
119428d7b3dSmrg
120428d7b3dSmrgvoid
121428d7b3dSmrgfbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt)
122428d7b3dSmrg{
123428d7b3dSmrg	void (*raster)(DrawablePtr, GCPtr, int mode, int n, DDXPointPtr pt);
124428d7b3dSmrg
125428d7b3dSmrg	DBG(("%s x %d, width=%d, fill=%d [solid? %d], line=%d [solid? %d], bpp=%d\n",
126428d7b3dSmrg	     __FUNCTION__, n, gc->lineWidth,
127428d7b3dSmrg	     gc->fillStyle, gc->fillStyle == FillSolid,
128428d7b3dSmrg	     gc->lineStyle, gc->lineStyle == LineSolid,
129428d7b3dSmrg	     drawable->bitsPerPixel));
130428d7b3dSmrg
131428d7b3dSmrg	if (gc->lineWidth == 0) {
132428d7b3dSmrg		raster = fbZeroLine;
133428d7b3dSmrg		if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) {
134428d7b3dSmrg			switch (drawable->bitsPerPixel) {
135428d7b3dSmrg			case 8:
136428d7b3dSmrg				raster = fbPolyline8;
137428d7b3dSmrg				break;
138428d7b3dSmrg			case 16:
139428d7b3dSmrg				raster = fbPolyline16;
140428d7b3dSmrg				break;
141428d7b3dSmrg			case 32:
142428d7b3dSmrg				raster = fbPolyline32;
143428d7b3dSmrg				break;
144428d7b3dSmrg			}
145428d7b3dSmrg		}
146428d7b3dSmrg	} else {
147428d7b3dSmrg		if (gc->lineStyle != LineSolid)
148428d7b3dSmrg			raster = miWideDash;
149428d7b3dSmrg		else
150428d7b3dSmrg			raster = miWideLine;
151428d7b3dSmrg	}
152428d7b3dSmrg	raster(drawable, gc, mode, n, pt);
153428d7b3dSmrg}
154428d7b3dSmrg
155428d7b3dSmrgvoid
156428d7b3dSmrgfbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
157428d7b3dSmrg{
158428d7b3dSmrg	void (*raster)(DrawablePtr drawable, GCPtr gc, int n, xSegment * seg);
159428d7b3dSmrg
160428d7b3dSmrg	DBG(("%s x %d, width=%d, fill=%d [solid? %d], line=%d [solid? %d], bpp=%d\n",
161428d7b3dSmrg	     __FUNCTION__, n, gc->lineWidth,
162428d7b3dSmrg	     gc->fillStyle, gc->fillStyle == FillSolid,
163428d7b3dSmrg	     gc->lineStyle, gc->lineStyle == LineSolid,
164428d7b3dSmrg	     drawable->bitsPerPixel));
165428d7b3dSmrg
166428d7b3dSmrg	if (gc->lineWidth == 0) {
167428d7b3dSmrg		raster = fbZeroSegment;
168428d7b3dSmrg		if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) {
169428d7b3dSmrg			switch (drawable->bitsPerPixel) {
170428d7b3dSmrg			case 8:
171428d7b3dSmrg				raster = fbPolySegment8;
172428d7b3dSmrg				break;
173428d7b3dSmrg			case 16:
174428d7b3dSmrg				raster = fbPolySegment16;
175428d7b3dSmrg				break;
176428d7b3dSmrg			case 32:
177428d7b3dSmrg				raster = fbPolySegment32;
178428d7b3dSmrg				break;
179428d7b3dSmrg			}
180428d7b3dSmrg		}
181428d7b3dSmrg	} else
182428d7b3dSmrg		raster = miPolySegment;
183428d7b3dSmrg
184428d7b3dSmrg	raster(drawable, gc, n, seg);
185428d7b3dSmrg}
186