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#define isClipped(c,ul,lr)  (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
25#define RROP(b,a,x)	WRITE((b), FbDoRRop (READ(b), (a), (x)))
26
27static void
28BRESSOLID(DrawablePtr drawable, GCPtr gc, int dashOffset,
29	  int sdx, int sdy, int axis,
30	  int x1, int y1, int e, int e1, int e3, int len)
31{
32	FbBits *dst;
33	FbStride stride;
34	int bpp, dx, dy;
35	BITS *bits;
36	FbStride major, minor;
37	BITS xor = fb_gc(gc)->xor;
38
39	fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
40	bits = (BITS *)(dst + (y1 + dy) * stride) + (x1 + dx);
41	stride = stride * (sizeof(FbBits) / sizeof(BITS));
42	if (sdy < 0)
43		stride = -stride;
44	if (axis == X_AXIS) {
45		major = sdx;
46		minor = stride;
47	} else {
48		major = stride;
49		minor = sdx;
50	}
51	while (len--) {
52		WRITE(bits, xor);
53		bits += major;
54		e += e1;
55		if (e >= 0) {
56			bits += minor;
57			e += e3;
58		}
59	}
60}
61
62static void
63BRESSOLIDR(DrawablePtr drawable, GCPtr gc, int dashOffset,
64	   int sdx, int sdy, int axis,
65	   int x1, int y1, int e, int e1, int e3, int len)
66{
67	FbBits *dst;
68	FbStride stride;
69	int bpp, dx, dy;
70	BITS *bits;
71	FbStride major, minor;
72	BITS and = fb_gc(gc)->and;
73	BITS xor = fb_gc(gc)->xor;
74
75	fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
76	bits = (BITS *)(dst + (y1 + dy) * stride) + (x1 + dx);
77	stride = stride * (sizeof(FbBits) / sizeof(BITS));
78	if (sdy < 0)
79		stride = -stride;
80	if (axis == X_AXIS) {
81		major = sdx;
82		minor = stride;
83	} else {
84		major = stride;
85		minor = sdx;
86	}
87	while (len--) {
88		RROP(bits, and, xor);
89		bits += major;
90		e += e1;
91		if (e >= 0) {
92			bits += minor;
93			e += e3;
94		}
95	}
96}
97
98static void
99BRESDASH(DrawablePtr drawable, GCPtr gc, int dashOffset,
100	 int sdx, int sdy, int axis,
101	 int x1, int y1, int e, int e1, int e3, int len)
102{
103	FbBits *dst;
104	FbStride stride;
105	int bpp, dx, dy;
106	BITS *bits;
107	FbStride major, minor;
108
109	FbDashDeclare;
110	int dashlen;
111	bool even;
112	bool doOdd = gc->lineStyle == LineDoubleDash;
113	BITS xorfg = fb_gc(gc)->xor;
114	BITS xorbg = fb_gc(gc)->bgxor;
115
116	fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
117
118	FbDashInit(gc, fb_gc(gc), dashOffset, dashlen, even);
119
120	bits = ((BITS *) (dst + ((y1 + dy) * stride))) + (x1 + dx);
121	stride = stride * (sizeof(FbBits) / sizeof(BITS));
122	if (sdy < 0)
123		stride = -stride;
124	if (axis == X_AXIS) {
125		major = sdx;
126		minor = stride;
127	} else {
128		major = stride;
129		minor = sdx;
130	}
131	if (dashlen >= len)
132		dashlen = len;
133	if (doOdd) {
134		if (!even)
135			goto doubleOdd;
136		for (;;) {
137			len -= dashlen;
138			while (dashlen--) {
139				WRITE(bits, xorfg);
140				bits += major;
141				if ((e += e1) >= 0) {
142					e += e3;
143					bits += minor;
144				}
145			}
146			if (!len)
147				break;
148
149			FbDashNextEven(dashlen);
150
151			if (dashlen >= len)
152				dashlen = len;
153doubleOdd:
154			len -= dashlen;
155			while (dashlen--) {
156				WRITE(bits, xorbg);
157				bits += major;
158				if ((e += e1) >= 0) {
159					e += e3;
160					bits += minor;
161				}
162			}
163			if (!len)
164				break;
165
166			FbDashNextOdd(dashlen);
167
168			if (dashlen >= len)
169				dashlen = len;
170		}
171	} else {
172		if (!even)
173			goto onOffOdd;
174		for (;;) {
175			len -= dashlen;
176			while (dashlen--) {
177				WRITE(bits, xorfg);
178				bits += major;
179				if ((e += e1) >= 0) {
180					e += e3;
181					bits += minor;
182				}
183			}
184			if (!len)
185				break;
186
187			FbDashNextEven(dashlen);
188
189			if (dashlen >= len)
190				dashlen = len;
191onOffOdd:
192			len -= dashlen;
193			while (dashlen--) {
194				bits += major;
195				if ((e += e1) >= 0) {
196					e += e3;
197					bits += minor;
198				}
199			}
200			if (!len)
201				break;
202
203			FbDashNextOdd(dashlen);
204
205			if (dashlen >= len)
206				dashlen = len;
207		}
208	}
209}
210
211#undef RROP
212#undef isClipped
213