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 "fbclip.h" 2603b705cfSriastradh 2703b705cfSriastradhstatic void 2803b705cfSriastradhfbSolid(FbBits * dst, 2903b705cfSriastradh FbStride dstStride, 3003b705cfSriastradh int dstX, int bpp, int width, int height, FbBits and, FbBits xor) 3103b705cfSriastradh{ 3203b705cfSriastradh FbBits startmask, endmask; 3303b705cfSriastradh int n, nmiddle; 3403b705cfSriastradh int startbyte, endbyte; 3503b705cfSriastradh 3603b705cfSriastradh dst += dstX >> FB_SHIFT; 3703b705cfSriastradh dstX &= FB_MASK; 3803b705cfSriastradh FbMaskBitsBytes(dstX, width, and == 0, startmask, startbyte, 3903b705cfSriastradh nmiddle, endmask, endbyte); 4003b705cfSriastradh if (startmask) 4103b705cfSriastradh dstStride--; 4203b705cfSriastradh dstStride -= nmiddle; 4303b705cfSriastradh while (height--) { 4403b705cfSriastradh if (startmask) { 4503b705cfSriastradh FbDoLeftMaskByteRRop(dst, startbyte, startmask, and, xor); 4603b705cfSriastradh dst++; 4703b705cfSriastradh } 4803b705cfSriastradh n = nmiddle; 4903b705cfSriastradh if (!and) 5003b705cfSriastradh while (n--) 5103b705cfSriastradh WRITE(dst++, xor); 5203b705cfSriastradh else 5303b705cfSriastradh while (n--) { 5403b705cfSriastradh WRITE(dst, FbDoRRop(READ(dst), and, xor)); 5503b705cfSriastradh dst++; 5603b705cfSriastradh } 5703b705cfSriastradh if (endmask) 5803b705cfSriastradh FbDoRightMaskByteRRop(dst, endbyte, endmask, and, xor); 5903b705cfSriastradh dst += dstStride; 6003b705cfSriastradh } 6103b705cfSriastradh} 6203b705cfSriastradh 6303b705cfSriastradhvoid 6403b705cfSriastradhfbFill(DrawablePtr drawable, GCPtr gc, int x, int y, int width, int height) 6503b705cfSriastradh{ 6603b705cfSriastradh FbBits *dst; 6703b705cfSriastradh FbStride dstStride; 6803b705cfSriastradh int dstBpp; 6903b705cfSriastradh int dstXoff, dstYoff; 7003b705cfSriastradh FbGCPrivPtr pgc = fb_gc(gc); 7103b705cfSriastradh 7203b705cfSriastradh DBG(("%s (%d, %d)x(%d, %d), style=%d\n", 7303b705cfSriastradh __FUNCTION__, x, y, width, height, gc->fillStyle)); 7403b705cfSriastradh 7503b705cfSriastradh fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 7603b705cfSriastradh 7703b705cfSriastradh switch (gc->fillStyle) { 7803b705cfSriastradh case FillSolid: 7903b705cfSriastradh if (pgc->and || 8003b705cfSriastradh !pixman_fill((uint32_t *) dst, dstStride, dstBpp, 8103b705cfSriastradh x + dstXoff, y + dstYoff, 8203b705cfSriastradh width, height, pgc->xor)) 8303b705cfSriastradh fbSolid(dst + (y + dstYoff) * dstStride, 8403b705cfSriastradh dstStride, 8503b705cfSriastradh (x + dstXoff) * dstBpp, 8603b705cfSriastradh dstBpp, width * dstBpp, height, pgc->and, pgc->xor); 8703b705cfSriastradh break; 8803b705cfSriastradh 8903b705cfSriastradh case FillStippled: 9003b705cfSriastradh case FillOpaqueStippled: 9103b705cfSriastradh { 9203b705cfSriastradh PixmapPtr pStip = gc->stipple; 9303b705cfSriastradh int stipWidth = pStip->drawable.width; 9403b705cfSriastradh int stipHeight = pStip->drawable.height; 9503b705cfSriastradh 9603b705cfSriastradh if (dstBpp == 1) { 9703b705cfSriastradh int alu; 9803b705cfSriastradh FbBits *stip; 9903b705cfSriastradh FbStride stipStride; 10003b705cfSriastradh int stipBpp; 10103b705cfSriastradh _X_UNUSED int stipXoff, stipYoff; 10203b705cfSriastradh 10303b705cfSriastradh if (gc->fillStyle == FillStippled) 10403b705cfSriastradh alu = FbStipple1Rop(gc->alu, gc->fgPixel); 10503b705cfSriastradh else 10603b705cfSriastradh alu = FbOpaqueStipple1Rop(gc->alu, gc->fgPixel, gc->bgPixel); 10703b705cfSriastradh fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff, 10803b705cfSriastradh stipYoff); 10903b705cfSriastradh fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff, 11003b705cfSriastradh width, height, stip, stipStride, stipWidth, stipHeight, alu, 11103b705cfSriastradh pgc->pm, dstBpp, (gc->patOrg.x + drawable->x + dstXoff), 11203b705cfSriastradh gc->patOrg.y + drawable->y - y); 11303b705cfSriastradh } else { 11403b705cfSriastradh FbStip *stip; 11503b705cfSriastradh FbStride stipStride; 11603b705cfSriastradh int stipBpp; 11703b705cfSriastradh _X_UNUSED int stipXoff, stipYoff; 11803b705cfSriastradh FbBits fgand, fgxor, bgand, bgxor; 11903b705cfSriastradh 12003b705cfSriastradh fgand = pgc->and; 12103b705cfSriastradh fgxor = pgc->xor; 12203b705cfSriastradh if (gc->fillStyle == FillStippled) { 12303b705cfSriastradh bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); 12403b705cfSriastradh bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); 12503b705cfSriastradh } else { 12603b705cfSriastradh bgand = pgc->bgand; 12703b705cfSriastradh bgxor = pgc->bgxor; 12803b705cfSriastradh } 12903b705cfSriastradh 13003b705cfSriastradh fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp, 13103b705cfSriastradh stipXoff, stipYoff); 13203b705cfSriastradh fbStipple(dst + (y + dstYoff) * dstStride, dstStride, 13303b705cfSriastradh (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, 13403b705cfSriastradh stip, stipStride, stipWidth, stipHeight, 13503b705cfSriastradh pgc->evenStipple, fgand, fgxor, bgand, bgxor, 13603b705cfSriastradh gc->patOrg.x + drawable->x + dstXoff, 13703b705cfSriastradh gc->patOrg.y + drawable->y - y); 13803b705cfSriastradh } 13903b705cfSriastradh break; 14003b705cfSriastradh } 14103b705cfSriastradh 14203b705cfSriastradh case FillTiled: 14303b705cfSriastradh { 14403b705cfSriastradh PixmapPtr tile = gc->tile.pixmap; 14503b705cfSriastradh 14603b705cfSriastradh fbTile(dst + (y + dstYoff) * dstStride, dstStride, 14703b705cfSriastradh (x + dstXoff) * dstBpp, width * dstBpp, height, 14803b705cfSriastradh tile->devPrivate.ptr, tile->devKind / sizeof(FbBits), 14903b705cfSriastradh tile->drawable.width * tile->drawable.bitsPerPixel, 15003b705cfSriastradh tile->drawable.height, 15103b705cfSriastradh gc->alu, pgc->pm, dstBpp, 15203b705cfSriastradh (gc->patOrg.x + drawable->x + dstXoff) * dstBpp, 15303b705cfSriastradh gc->patOrg.y + drawable->y - y); 15403b705cfSriastradh break; 15503b705cfSriastradh } 15603b705cfSriastradh } 15703b705cfSriastradh} 15803b705cfSriastradh 15903b705cfSriastradhstatic void 16003b705cfSriastradh_fbSolidBox(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) 16103b705cfSriastradh{ 16203b705cfSriastradh FbBits *dst; 16303b705cfSriastradh FbStride stride; 16403b705cfSriastradh int dx, dy, bpp; 16503b705cfSriastradh FbBits and = fbAnd(GXcopy, fb_gc(gc)->bg, fb_gc(gc)->pm); 16603b705cfSriastradh FbBits xor = fbXor(GXcopy, fb_gc(gc)->bg, fb_gc(gc)->pm); 16703b705cfSriastradh 16803b705cfSriastradh fbGetDrawable(drawable, dst, stride, bpp, dx, dy); 16903b705cfSriastradh 17003b705cfSriastradh if (and || 17103b705cfSriastradh !pixman_fill((uint32_t *) dst, stride, bpp, 17203b705cfSriastradh b->x1 + dx, b->y1 + dy, 17303b705cfSriastradh (b->x2 - b->x1), (b->y2 - b->y1), xor)) 17403b705cfSriastradh fbSolid(dst + (b->y1 + dy) * stride, stride, 17503b705cfSriastradh (b->x1 + dx) * bpp, bpp, 17603b705cfSriastradh (b->x2 - b->x1) * bpp, (b->y2 - b->y1), 17703b705cfSriastradh and, xor); 17803b705cfSriastradh} 17903b705cfSriastradh 18003b705cfSriastradhvoid 18103b705cfSriastradhfbSolidBoxClipped(DrawablePtr drawable, GCPtr gc, 18203b705cfSriastradh int x1, int y1, int x2, int y2) 18303b705cfSriastradh{ 18403b705cfSriastradh BoxRec box; 18503b705cfSriastradh 18603b705cfSriastradh box.x1 = x1; 18703b705cfSriastradh box.y1 = y1; 18803b705cfSriastradh box.x2 = x2; 18903b705cfSriastradh box.y2 = y2; 19003b705cfSriastradh 19103b705cfSriastradh fbDrawableRun(drawable, gc, &box, _fbSolidBox, NULL); 19203b705cfSriastradh} 19303b705cfSriastradh 19403b705cfSriastradhinline static void 19503b705cfSriastradhfbFillBox(DrawablePtr drawable, GCPtr gc, const BoxRec *box, void *data) 19603b705cfSriastradh{ 19703b705cfSriastradh DBG(("%s box=(%d, %d), (%d, %d)\n", __FUNCTION__, 19803b705cfSriastradh box->x1, box->y1, box->x2, box->y2)); 19903b705cfSriastradh fbFill(drawable, gc, 20003b705cfSriastradh box->x1, box->y1, 20103b705cfSriastradh box->x2 - box->x1, box->y2 - box->y1); 20203b705cfSriastradh} 20303b705cfSriastradh 20403b705cfSriastradhvoid 20503b705cfSriastradhfbPolyFillRect(DrawablePtr drawable, GCPtr gc, int n, xRectangle *r) 20603b705cfSriastradh{ 20703b705cfSriastradh DBG(("%s x %d\n", __FUNCTION__, n)); 20803b705cfSriastradh while (n--) { 20903b705cfSriastradh BoxRec b; 21003b705cfSriastradh 21103b705cfSriastradh b.x1 = r->x + drawable->x; 21203b705cfSriastradh b.y1 = r->y + drawable->y; 21303b705cfSriastradh b.x2 = fbBound(b.x1, r->width); 21403b705cfSriastradh b.y2 = fbBound(b.y1, r->height); 21503b705cfSriastradh r++; 21603b705cfSriastradh 21703b705cfSriastradh DBG(("%s: rectangle (%d, %d), (%d, %d)\n", 21803b705cfSriastradh __FUNCTION__, b.x1, b.y1, b.x2, b.y2)); 21903b705cfSriastradh fbDrawableRun(drawable, gc, &b, fbFillBox, NULL); 22003b705cfSriastradh } 22103b705cfSriastradh} 222