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#include "fb.h"
2503b705cfSriastradh#include <mi.h>
2603b705cfSriastradh#include <micoord.h>
2703b705cfSriastradh#include <miline.h>
2803b705cfSriastradh#include <scrnintstr.h>
2903b705cfSriastradh
3003b705cfSriastradh#define POLYLINE    fbPolyline8
3103b705cfSriastradh#define POLYSEGMENT fbPolySegment8
3203b705cfSriastradh#define BITS	    BYTE
3303b705cfSriastradh#define BITS2	    CARD16
3403b705cfSriastradh#define BITS4	    CARD32
3503b705cfSriastradh#include "fblinebits.h"
3603b705cfSriastradh#undef BITS
3703b705cfSriastradh#undef BITS2
3803b705cfSriastradh#undef BITS4
3903b705cfSriastradh#undef POLYSEGMENT
4003b705cfSriastradh#undef POLYLINE
4103b705cfSriastradh
4203b705cfSriastradh#define POLYLINE    fbPolyline16
4303b705cfSriastradh#define POLYSEGMENT fbPolySegment16
4403b705cfSriastradh#define BITS	    CARD16
4503b705cfSriastradh#define BITS2	    CARD32
4603b705cfSriastradh#include "fblinebits.h"
4703b705cfSriastradh#undef BITS
4803b705cfSriastradh#undef BITS2
4903b705cfSriastradh#undef POLYSEGMENT
5003b705cfSriastradh#undef POLYLINE
5103b705cfSriastradh
5203b705cfSriastradh#define POLYLINE    fbPolyline32
5303b705cfSriastradh#define POLYSEGMENT fbPolySegment32
5403b705cfSriastradh#define BITS	    CARD32
5503b705cfSriastradh#include "fblinebits.h"
5603b705cfSriastradh#undef BITS
5703b705cfSriastradh#undef POLYSEGMENT
5803b705cfSriastradh#undef POLYLINE
5903b705cfSriastradh
6003b705cfSriastradhstatic void
6103b705cfSriastradhfbZeroLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt)
6203b705cfSriastradh{
6303b705cfSriastradh	int x1, y1, x2, y2;
6403b705cfSriastradh	int x, y;
6503b705cfSriastradh	int dashOffset;
6603b705cfSriastradh
6703b705cfSriastradh	x = drawable->x;
6803b705cfSriastradh	y = drawable->y;
6903b705cfSriastradh	x1 = pt->x;
7003b705cfSriastradh	y1 = pt->y;
7103b705cfSriastradh	dashOffset = gc->dashOffset;
7203b705cfSriastradh	while (--n) {
7303b705cfSriastradh		++pt;
7403b705cfSriastradh		x2 = pt->x;
7503b705cfSriastradh		y2 = pt->y;
7603b705cfSriastradh		if (mode == CoordModePrevious) {
7703b705cfSriastradh			x2 += x1;
7803b705cfSriastradh			y2 += y1;
7903b705cfSriastradh		}
8003b705cfSriastradh		fbSegment(drawable, gc,
8103b705cfSriastradh			  x1 + x, y1 + y,
8203b705cfSriastradh			  x2 + x, y2 + y,
8303b705cfSriastradh			  n == 1 && gc->capStyle != CapNotLast, &dashOffset);
8403b705cfSriastradh		x1 = x2;
8503b705cfSriastradh		y1 = y2;
8603b705cfSriastradh	}
8703b705cfSriastradh}
8803b705cfSriastradh
8903b705cfSriastradhstatic void
9003b705cfSriastradhfbZeroSegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
9103b705cfSriastradh{
9203b705cfSriastradh	int dashOffset;
9303b705cfSriastradh	int16_t x, y;
9403b705cfSriastradh	Bool drawLast = gc->capStyle != CapNotLast;
9503b705cfSriastradh
9603b705cfSriastradh	x = drawable->x;
9703b705cfSriastradh	y = drawable->y;
9803b705cfSriastradh	while (n--) {
9903b705cfSriastradh		dashOffset = gc->dashOffset;
10003b705cfSriastradh		fbSegment(drawable, gc,
10103b705cfSriastradh			  seg->x1 + x, seg->y1 + y,
10203b705cfSriastradh			  seg->x2 + x, seg->y2 + y,
10303b705cfSriastradh			  drawLast, &dashOffset);
10403b705cfSriastradh		seg++;
10503b705cfSriastradh	}
10603b705cfSriastradh}
10703b705cfSriastradh
10803b705cfSriastradhvoid
10903b705cfSriastradhfbFixCoordModePrevious(int n, DDXPointPtr pt)
11003b705cfSriastradh{
11103b705cfSriastradh	int16_t x = pt->x;
11203b705cfSriastradh	int16_t y = pt->y;
11303b705cfSriastradh	while (--n) {
11403b705cfSriastradh		pt++;
11503b705cfSriastradh		x = (pt->x += x);
11603b705cfSriastradh		y = (pt->y += y);
11703b705cfSriastradh	}
11803b705cfSriastradh}
11903b705cfSriastradh
12003b705cfSriastradhvoid
12103b705cfSriastradhfbPolyLine(DrawablePtr drawable, GCPtr gc, int mode, int n, DDXPointPtr pt)
12203b705cfSriastradh{
12303b705cfSriastradh	void (*raster)(DrawablePtr, GCPtr, int mode, int n, DDXPointPtr pt);
12403b705cfSriastradh
12542542f5fSchristos	DBG(("%s x %d, width=%d, fill=%d [solid? %d], line=%d [solid? %d], bpp=%d\n",
12642542f5fSchristos	     __FUNCTION__, n, gc->lineWidth,
12742542f5fSchristos	     gc->fillStyle, gc->fillStyle == FillSolid,
12842542f5fSchristos	     gc->lineStyle, gc->lineStyle == LineSolid,
12942542f5fSchristos	     drawable->bitsPerPixel));
13003b705cfSriastradh
13103b705cfSriastradh	if (gc->lineWidth == 0) {
13203b705cfSriastradh		raster = fbZeroLine;
13303b705cfSriastradh		if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) {
13403b705cfSriastradh			switch (drawable->bitsPerPixel) {
13503b705cfSriastradh			case 8:
13603b705cfSriastradh				raster = fbPolyline8;
13703b705cfSriastradh				break;
13803b705cfSriastradh			case 16:
13903b705cfSriastradh				raster = fbPolyline16;
14003b705cfSriastradh				break;
14103b705cfSriastradh			case 32:
14203b705cfSriastradh				raster = fbPolyline32;
14303b705cfSriastradh				break;
14403b705cfSriastradh			}
14503b705cfSriastradh		}
14603b705cfSriastradh	} else {
14703b705cfSriastradh		if (gc->lineStyle != LineSolid)
14803b705cfSriastradh			raster = miWideDash;
14903b705cfSriastradh		else
15003b705cfSriastradh			raster = miWideLine;
15103b705cfSriastradh	}
15203b705cfSriastradh	raster(drawable, gc, mode, n, pt);
15303b705cfSriastradh}
15403b705cfSriastradh
15503b705cfSriastradhvoid
15603b705cfSriastradhfbPolySegment(DrawablePtr drawable, GCPtr gc, int n, xSegment *seg)
15703b705cfSriastradh{
15803b705cfSriastradh	void (*raster)(DrawablePtr drawable, GCPtr gc, int n, xSegment * seg);
15903b705cfSriastradh
16042542f5fSchristos	DBG(("%s x %d, width=%d, fill=%d [solid? %d], line=%d [solid? %d], bpp=%d\n",
16142542f5fSchristos	     __FUNCTION__, n, gc->lineWidth,
16242542f5fSchristos	     gc->fillStyle, gc->fillStyle == FillSolid,
16342542f5fSchristos	     gc->lineStyle, gc->lineStyle == LineSolid,
16442542f5fSchristos	     drawable->bitsPerPixel));
16503b705cfSriastradh
16603b705cfSriastradh	if (gc->lineWidth == 0) {
16703b705cfSriastradh		raster = fbZeroSegment;
16803b705cfSriastradh		if (gc->fillStyle == FillSolid && gc->lineStyle == LineSolid) {
16903b705cfSriastradh			switch (drawable->bitsPerPixel) {
17003b705cfSriastradh			case 8:
17103b705cfSriastradh				raster = fbPolySegment8;
17203b705cfSriastradh				break;
17303b705cfSriastradh			case 16:
17403b705cfSriastradh				raster = fbPolySegment16;
17503b705cfSriastradh				break;
17603b705cfSriastradh			case 32:
17703b705cfSriastradh				raster = fbPolySegment32;
17803b705cfSriastradh				break;
17903b705cfSriastradh			}
18003b705cfSriastradh		}
18103b705cfSriastradh	} else
18203b705cfSriastradh		raster = miPolySegment;
18303b705cfSriastradh
18403b705cfSriastradh	raster(drawable, gc, n, seg);
18503b705cfSriastradh}
186