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 <mizerarc.h>
2703b705cfSriastradh#include <limits.h>
2803b705cfSriastradh
2903b705cfSriastradh#define ARC	    fbArc8
3003b705cfSriastradh#define BITS	    BYTE
3103b705cfSriastradh#define BITS2	    CARD16
3203b705cfSriastradh#define BITS4	    CARD32
3303b705cfSriastradh#include "fbarcbits.h"
3403b705cfSriastradh#undef BITS
3503b705cfSriastradh#undef BITS2
3603b705cfSriastradh#undef BITS4
3703b705cfSriastradh#undef ARC
3803b705cfSriastradh
3903b705cfSriastradh#define ARC	    fbArc16
4003b705cfSriastradh#define BITS	    CARD16
4103b705cfSriastradh#define BITS2	    CARD32
4203b705cfSriastradh#include "fbarcbits.h"
4303b705cfSriastradh#undef BITS
4403b705cfSriastradh#undef BITS2
4503b705cfSriastradh#undef ARC
4603b705cfSriastradh
4703b705cfSriastradh#define ARC	    fbArc32
4803b705cfSriastradh#define BITS	    CARD32
4903b705cfSriastradh#include "fbarcbits.h"
5003b705cfSriastradh#undef BITS
5103b705cfSriastradh#undef ARC
5203b705cfSriastradh
5303b705cfSriastradhvoid
5403b705cfSriastradhfbPolyArc(DrawablePtr drawable, GCPtr gc, int n, xArc *arc)
5503b705cfSriastradh{
5603b705cfSriastradh	DBG(("%s x %d, width=%d, fill=%d, line=%d\n",
5703b705cfSriastradh	     __FUNCTION__, n, gc->lineWidth, gc->lineStyle, gc->fillStyle));
5803b705cfSriastradh
5903b705cfSriastradh	if (gc->lineWidth == 0) {
6003b705cfSriastradh		void (*raster)(FbBits *dst, FbStride dstStride, int dstBpp,
6103b705cfSriastradh			       xArc *arc, int dx, int dy,
6203b705cfSriastradh			       FbBits and, FbBits xor);
6303b705cfSriastradh
6403b705cfSriastradh		raster = 0;
6503b705cfSriastradh		if (gc->lineStyle == LineSolid && gc->fillStyle == FillSolid) {
6603b705cfSriastradh			switch (drawable->bitsPerPixel) {
6703b705cfSriastradh			case 8:
6803b705cfSriastradh				raster = fbArc8;
6903b705cfSriastradh				break;
7003b705cfSriastradh			case 16:
7103b705cfSriastradh				raster = fbArc16;
7203b705cfSriastradh				break;
7303b705cfSriastradh			case 32:
7403b705cfSriastradh				raster = fbArc32;
7503b705cfSriastradh				break;
7603b705cfSriastradh			}
7703b705cfSriastradh		}
7803b705cfSriastradh		if (raster) {
7903b705cfSriastradh			FbGCPrivPtr pgc = fb_gc(gc);
8003b705cfSriastradh			FbBits *dst;
8103b705cfSriastradh			FbStride dstStride;
8203b705cfSriastradh			int dstBpp;
8303b705cfSriastradh			int dstXoff, dstYoff;
8403b705cfSriastradh			BoxRec box;
8503b705cfSriastradh			int x2, y2;
8603b705cfSriastradh
8703b705cfSriastradh			fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
8803b705cfSriastradh			while (n--) {
8903b705cfSriastradh				if (miCanZeroArc(arc)) {
9003b705cfSriastradh					box.x1 = arc->x + drawable->x;
9103b705cfSriastradh					box.y1 = arc->y + drawable->y;
9203b705cfSriastradh					/*
9303b705cfSriastradh					 * Because box.x2 and box.y2 get truncated to 16 bits, and the
9403b705cfSriastradh					 * RECT_IN_REGION test treats the resulting number as a signed
9503b705cfSriastradh					 * integer, the RECT_IN_REGION test alone can go the wrong way.
9603b705cfSriastradh					 * This can result in a server crash because the rendering
9703b705cfSriastradh					 * routines in this file deal directly with cpu addresses
9803b705cfSriastradh					 * of pixels to be stored, and do not clip or otherwise check
9903b705cfSriastradh					 * that all such addresses are within their respective pixmaps.
10003b705cfSriastradh					 * So we only allow the RECT_IN_REGION test to be used for
10103b705cfSriastradh					 * values that can be expressed correctly in a signed short.
10203b705cfSriastradh					 */
10303b705cfSriastradh					x2 = box.x1 + (int) arc->width + 1;
10403b705cfSriastradh					box.x2 = x2;
10503b705cfSriastradh					y2 = box.y1 + (int) arc->height + 1;
10603b705cfSriastradh					box.y2 = y2;
10703b705cfSriastradh					if ((x2 <= SHRT_MAX) && (y2 <= SHRT_MAX) &&
10803b705cfSriastradh					    (RegionContainsRect(gc->pCompositeClip, &box) == rgnIN)) {
10903b705cfSriastradh						raster(dst, dstStride, dstBpp,
11003b705cfSriastradh						       arc, drawable->x + dstXoff,
11103b705cfSriastradh							drawable->y + dstYoff, pgc->and, pgc->xor);
11203b705cfSriastradh					} else
11303b705cfSriastradh						miZeroPolyArc(drawable, gc, 1, arc);
11403b705cfSriastradh				} else
11503b705cfSriastradh					miPolyArc(drawable, gc, 1, arc);
11603b705cfSriastradh				arc++;
11703b705cfSriastradh			}
11803b705cfSriastradh		} else
11903b705cfSriastradh			miZeroPolyArc(drawable, gc, n, arc);
12003b705cfSriastradh	} else
12103b705cfSriastradh		miPolyArc(drawable, gc, n, arc);
12203b705cfSriastradh}
123