103b705cfSriastradh/*
203b705cfSriastradh * Copyright © 1998 Keith Packard
303b705cfSriastradh * Copyright © 2012 Intel Corporation
403b705cfSriastradh *
503b705cfSriastradh * Permission to use, copy, modify, distribute, and sell this software and its
603b705cfSriastradh * documentation for any purpose is hereby granted without fee, provided that
703b705cfSriastradh * the above copyright notice appear in all copies and that both that
803b705cfSriastradh * copyright notice and this permission notice appear in supporting
903b705cfSriastradh * documentation, and that the name of Keith Packard not be used in
1003b705cfSriastradh * advertising or publicity pertaining to distribution of the software without
1103b705cfSriastradh * specific, written prior permission.  Keith Packard makes no
1203b705cfSriastradh * representations about the suitability of this software for any purpose.  It
1303b705cfSriastradh * is provided "as is" without express or implied warranty.
1403b705cfSriastradh *
1503b705cfSriastradh * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
1603b705cfSriastradh * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
1703b705cfSriastradh * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
1803b705cfSriastradh * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
1903b705cfSriastradh * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
2003b705cfSriastradh * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
2103b705cfSriastradh * PERFORMANCE OF THIS SOFTWARE.
2203b705cfSriastradh */
2303b705cfSriastradh
2403b705cfSriastradh#define isClipped(c,ul,lr)  (((c) | ((c) - (ul)) | ((lr) - (c))) & 0x80008000)
2503b705cfSriastradh#define RROP(b,a,x)	WRITE((b), FbDoRRop (READ(b), (a), (x)))
2603b705cfSriastradh
2703b705cfSriastradhstatic void
2803b705cfSriastradhBRESSOLID(DrawablePtr drawable, GCPtr gc, int dashOffset,
2903b705cfSriastradh	  int sdx, int sdy, int axis,
3003b705cfSriastradh	  int x1, int y1, int e, int e1, int e3, int len)
3103b705cfSriastradh{
3203b705cfSriastradh	FbBits *dst;
3303b705cfSriastradh	FbStride stride;
3403b705cfSriastradh	int bpp, dx, dy;
3503b705cfSriastradh	BITS *bits;
3603b705cfSriastradh	FbStride major, minor;
3703b705cfSriastradh	BITS xor = fb_gc(gc)->xor;
3803b705cfSriastradh
3903b705cfSriastradh	fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
4003b705cfSriastradh	bits = (BITS *)(dst + (y1 + dy) * stride) + (x1 + dx);
4103b705cfSriastradh	stride = stride * (sizeof(FbBits) / sizeof(BITS));
4203b705cfSriastradh	if (sdy < 0)
4303b705cfSriastradh		stride = -stride;
4403b705cfSriastradh	if (axis == X_AXIS) {
4503b705cfSriastradh		major = sdx;
4603b705cfSriastradh		minor = stride;
4703b705cfSriastradh	} else {
4803b705cfSriastradh		major = stride;
4903b705cfSriastradh		minor = sdx;
5003b705cfSriastradh	}
5103b705cfSriastradh	while (len--) {
5203b705cfSriastradh		WRITE(bits, xor);
5303b705cfSriastradh		bits += major;
5403b705cfSriastradh		e += e1;
5503b705cfSriastradh		if (e >= 0) {
5603b705cfSriastradh			bits += minor;
5703b705cfSriastradh			e += e3;
5803b705cfSriastradh		}
5903b705cfSriastradh	}
6003b705cfSriastradh}
6103b705cfSriastradh
6203b705cfSriastradhstatic void
6303b705cfSriastradhBRESSOLIDR(DrawablePtr drawable, GCPtr gc, int dashOffset,
6403b705cfSriastradh	   int sdx, int sdy, int axis,
6503b705cfSriastradh	   int x1, int y1, int e, int e1, int e3, int len)
6603b705cfSriastradh{
6703b705cfSriastradh	FbBits *dst;
6803b705cfSriastradh	FbStride stride;
6903b705cfSriastradh	int bpp, dx, dy;
7003b705cfSriastradh	BITS *bits;
7103b705cfSriastradh	FbStride major, minor;
7203b705cfSriastradh	BITS and = fb_gc(gc)->and;
7303b705cfSriastradh	BITS xor = fb_gc(gc)->xor;
7403b705cfSriastradh
7503b705cfSriastradh	fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
7603b705cfSriastradh	bits = (BITS *)(dst + (y1 + dy) * stride) + (x1 + dx);
7703b705cfSriastradh	stride = stride * (sizeof(FbBits) / sizeof(BITS));
7803b705cfSriastradh	if (sdy < 0)
7903b705cfSriastradh		stride = -stride;
8003b705cfSriastradh	if (axis == X_AXIS) {
8103b705cfSriastradh		major = sdx;
8203b705cfSriastradh		minor = stride;
8303b705cfSriastradh	} else {
8403b705cfSriastradh		major = stride;
8503b705cfSriastradh		minor = sdx;
8603b705cfSriastradh	}
8703b705cfSriastradh	while (len--) {
8803b705cfSriastradh		RROP(bits, and, xor);
8903b705cfSriastradh		bits += major;
9003b705cfSriastradh		e += e1;
9103b705cfSriastradh		if (e >= 0) {
9203b705cfSriastradh			bits += minor;
9303b705cfSriastradh			e += e3;
9403b705cfSriastradh		}
9503b705cfSriastradh	}
9603b705cfSriastradh}
9703b705cfSriastradh
9803b705cfSriastradhstatic void
9903b705cfSriastradhBRESDASH(DrawablePtr drawable, GCPtr gc, int dashOffset,
10003b705cfSriastradh	 int sdx, int sdy, int axis,
10103b705cfSriastradh	 int x1, int y1, int e, int e1, int e3, int len)
10203b705cfSriastradh{
10303b705cfSriastradh	FbBits *dst;
10403b705cfSriastradh	FbStride stride;
10503b705cfSriastradh	int bpp, dx, dy;
10603b705cfSriastradh	BITS *bits;
10703b705cfSriastradh	FbStride major, minor;
10803b705cfSriastradh
10903b705cfSriastradh	FbDashDeclare;
11003b705cfSriastradh	int dashlen;
11103b705cfSriastradh	bool even;
11203b705cfSriastradh	bool doOdd = gc->lineStyle == LineDoubleDash;
11303b705cfSriastradh	BITS xorfg = fb_gc(gc)->xor;
11403b705cfSriastradh	BITS xorbg = fb_gc(gc)->bgxor;
11503b705cfSriastradh
11603b705cfSriastradh	fbGetDrawable(drawable, dst, stride, bpp, dx, dy);
11703b705cfSriastradh
11803b705cfSriastradh	FbDashInit(gc, fb_gc(gc), dashOffset, dashlen, even);
11903b705cfSriastradh
12003b705cfSriastradh	bits = ((BITS *) (dst + ((y1 + dy) * stride))) + (x1 + dx);
12103b705cfSriastradh	stride = stride * (sizeof(FbBits) / sizeof(BITS));
12203b705cfSriastradh	if (sdy < 0)
12303b705cfSriastradh		stride = -stride;
12403b705cfSriastradh	if (axis == X_AXIS) {
12503b705cfSriastradh		major = sdx;
12603b705cfSriastradh		minor = stride;
12703b705cfSriastradh	} else {
12803b705cfSriastradh		major = stride;
12903b705cfSriastradh		minor = sdx;
13003b705cfSriastradh	}
13103b705cfSriastradh	if (dashlen >= len)
13203b705cfSriastradh		dashlen = len;
13303b705cfSriastradh	if (doOdd) {
13403b705cfSriastradh		if (!even)
13503b705cfSriastradh			goto doubleOdd;
13603b705cfSriastradh		for (;;) {
13703b705cfSriastradh			len -= dashlen;
13803b705cfSriastradh			while (dashlen--) {
13903b705cfSriastradh				WRITE(bits, xorfg);
14003b705cfSriastradh				bits += major;
14103b705cfSriastradh				if ((e += e1) >= 0) {
14203b705cfSriastradh					e += e3;
14303b705cfSriastradh					bits += minor;
14403b705cfSriastradh				}
14503b705cfSriastradh			}
14603b705cfSriastradh			if (!len)
14703b705cfSriastradh				break;
14803b705cfSriastradh
14903b705cfSriastradh			FbDashNextEven(dashlen);
15003b705cfSriastradh
15103b705cfSriastradh			if (dashlen >= len)
15203b705cfSriastradh				dashlen = len;
15303b705cfSriastradhdoubleOdd:
15403b705cfSriastradh			len -= dashlen;
15503b705cfSriastradh			while (dashlen--) {
15603b705cfSriastradh				WRITE(bits, xorbg);
15703b705cfSriastradh				bits += major;
15803b705cfSriastradh				if ((e += e1) >= 0) {
15903b705cfSriastradh					e += e3;
16003b705cfSriastradh					bits += minor;
16103b705cfSriastradh				}
16203b705cfSriastradh			}
16303b705cfSriastradh			if (!len)
16403b705cfSriastradh				break;
16503b705cfSriastradh
16603b705cfSriastradh			FbDashNextOdd(dashlen);
16703b705cfSriastradh
16803b705cfSriastradh			if (dashlen >= len)
16903b705cfSriastradh				dashlen = len;
17003b705cfSriastradh		}
17103b705cfSriastradh	} else {
17203b705cfSriastradh		if (!even)
17303b705cfSriastradh			goto onOffOdd;
17403b705cfSriastradh		for (;;) {
17503b705cfSriastradh			len -= dashlen;
17603b705cfSriastradh			while (dashlen--) {
17703b705cfSriastradh				WRITE(bits, xorfg);
17803b705cfSriastradh				bits += major;
17903b705cfSriastradh				if ((e += e1) >= 0) {
18003b705cfSriastradh					e += e3;
18103b705cfSriastradh					bits += minor;
18203b705cfSriastradh				}
18303b705cfSriastradh			}
18403b705cfSriastradh			if (!len)
18503b705cfSriastradh				break;
18603b705cfSriastradh
18703b705cfSriastradh			FbDashNextEven(dashlen);
18803b705cfSriastradh
18903b705cfSriastradh			if (dashlen >= len)
19003b705cfSriastradh				dashlen = len;
19103b705cfSriastradhonOffOdd:
19203b705cfSriastradh			len -= dashlen;
19303b705cfSriastradh			while (dashlen--) {
19403b705cfSriastradh				bits += major;
19503b705cfSriastradh				if ((e += e1) >= 0) {
19603b705cfSriastradh					e += e3;
19703b705cfSriastradh					bits += minor;
19803b705cfSriastradh				}
19903b705cfSriastradh			}
20003b705cfSriastradh			if (!len)
20103b705cfSriastradh				break;
20203b705cfSriastradh
20303b705cfSriastradh			FbDashNextOdd(dashlen);
20403b705cfSriastradh
20503b705cfSriastradh			if (dashlen >= len)
20603b705cfSriastradh				dashlen = len;
20703b705cfSriastradh		}
20803b705cfSriastradh	}
20903b705cfSriastradh}
21003b705cfSriastradh
21103b705cfSriastradh#undef RROP
21203b705cfSriastradh#undef isClipped
213