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