fbfill.c revision 35c4bbdf
105b261ecSmrg/* 205b261ecSmrg * Copyright © 1998 Keith Packard 305b261ecSmrg * 405b261ecSmrg * Permission to use, copy, modify, distribute, and sell this software and its 505b261ecSmrg * documentation for any purpose is hereby granted without fee, provided that 605b261ecSmrg * the above copyright notice appear in all copies and that both that 705b261ecSmrg * copyright notice and this permission notice appear in supporting 805b261ecSmrg * documentation, and that the name of Keith Packard not be used in 905b261ecSmrg * advertising or publicity pertaining to distribution of the software without 1005b261ecSmrg * specific, written prior permission. Keith Packard makes no 1105b261ecSmrg * representations about the suitability of this software for any purpose. It 1205b261ecSmrg * is provided "as is" without express or implied warranty. 1305b261ecSmrg * 1405b261ecSmrg * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 1505b261ecSmrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 1605b261ecSmrg * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 1705b261ecSmrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 1805b261ecSmrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 1905b261ecSmrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 2005b261ecSmrg * PERFORMANCE OF THIS SOFTWARE. 2105b261ecSmrg */ 2205b261ecSmrg 2305b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 2405b261ecSmrg#include <dix-config.h> 2505b261ecSmrg#endif 2605b261ecSmrg 2705b261ecSmrg#include "fb.h" 2805b261ecSmrg 2935c4bbdfSmrgstatic void 3035c4bbdfSmrgfbTile(FbBits * dst, FbStride dstStride, int dstX, int width, int height, 3135c4bbdfSmrg FbBits * tile, FbStride tileStride, int tileWidth, int tileHeight, 3235c4bbdfSmrg int alu, FbBits pm, int bpp, int xRot, int yRot) 3335c4bbdfSmrg{ 3435c4bbdfSmrg int tileX, tileY; 3535c4bbdfSmrg int widthTmp; 3635c4bbdfSmrg int h, w; 3735c4bbdfSmrg int x, y; 3835c4bbdfSmrg 3935c4bbdfSmrg modulus(-yRot, tileHeight, tileY); 4035c4bbdfSmrg y = 0; 4135c4bbdfSmrg while (height) { 4235c4bbdfSmrg h = tileHeight - tileY; 4335c4bbdfSmrg if (h > height) 4435c4bbdfSmrg h = height; 4535c4bbdfSmrg height -= h; 4635c4bbdfSmrg widthTmp = width; 4735c4bbdfSmrg x = dstX; 4835c4bbdfSmrg modulus(dstX - xRot, tileWidth, tileX); 4935c4bbdfSmrg while (widthTmp) { 5035c4bbdfSmrg w = tileWidth - tileX; 5135c4bbdfSmrg if (w > widthTmp) 5235c4bbdfSmrg w = widthTmp; 5335c4bbdfSmrg widthTmp -= w; 5435c4bbdfSmrg fbBlt(tile + tileY * tileStride, 5535c4bbdfSmrg tileStride, 5635c4bbdfSmrg tileX, 5735c4bbdfSmrg dst + y * dstStride, 5835c4bbdfSmrg dstStride, x, w, h, alu, pm, bpp, FALSE, FALSE); 5935c4bbdfSmrg x += w; 6035c4bbdfSmrg tileX = 0; 6135c4bbdfSmrg } 6235c4bbdfSmrg y += h; 6335c4bbdfSmrg tileY = 0; 6435c4bbdfSmrg } 6535c4bbdfSmrg} 6635c4bbdfSmrg 6735c4bbdfSmrgstatic void 6835c4bbdfSmrgfbStipple(FbBits * dst, FbStride dstStride, 6935c4bbdfSmrg int dstX, int dstBpp, 7035c4bbdfSmrg int width, int height, 7135c4bbdfSmrg FbStip * stip, FbStride stipStride, 7235c4bbdfSmrg int stipWidth, int stipHeight, 7335c4bbdfSmrg FbBits fgand, FbBits fgxor, 7435c4bbdfSmrg FbBits bgand, FbBits bgxor, 7535c4bbdfSmrg int xRot, int yRot) 7635c4bbdfSmrg{ 7735c4bbdfSmrg int stipX, stipY, sx; 7835c4bbdfSmrg int widthTmp; 7935c4bbdfSmrg int h, w; 8035c4bbdfSmrg int x, y; 8135c4bbdfSmrg 8235c4bbdfSmrg modulus(-yRot, stipHeight, stipY); 8335c4bbdfSmrg modulus(dstX / dstBpp - xRot, stipWidth, stipX); 8435c4bbdfSmrg y = 0; 8535c4bbdfSmrg while (height) { 8635c4bbdfSmrg h = stipHeight - stipY; 8735c4bbdfSmrg if (h > height) 8835c4bbdfSmrg h = height; 8935c4bbdfSmrg height -= h; 9035c4bbdfSmrg widthTmp = width; 9135c4bbdfSmrg x = dstX; 9235c4bbdfSmrg sx = stipX; 9335c4bbdfSmrg while (widthTmp) { 9435c4bbdfSmrg w = (stipWidth - sx) * dstBpp; 9535c4bbdfSmrg if (w > widthTmp) 9635c4bbdfSmrg w = widthTmp; 9735c4bbdfSmrg widthTmp -= w; 9835c4bbdfSmrg fbBltOne(stip + stipY * stipStride, 9935c4bbdfSmrg stipStride, 10035c4bbdfSmrg sx, 10135c4bbdfSmrg dst + y * dstStride, 10235c4bbdfSmrg dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor); 10335c4bbdfSmrg x += w; 10435c4bbdfSmrg sx = 0; 10535c4bbdfSmrg } 10635c4bbdfSmrg y += h; 10735c4bbdfSmrg stipY = 0; 10835c4bbdfSmrg } 10935c4bbdfSmrg} 11035c4bbdfSmrg 11105b261ecSmrgvoid 11235c4bbdfSmrgfbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height) 11305b261ecSmrg{ 11435c4bbdfSmrg FbBits *dst; 11535c4bbdfSmrg FbStride dstStride; 11635c4bbdfSmrg int dstBpp; 11735c4bbdfSmrg int dstXoff, dstYoff; 11835c4bbdfSmrg FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 11935c4bbdfSmrg 12035c4bbdfSmrg fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 12105b261ecSmrg 12205b261ecSmrg switch (pGC->fillStyle) { 12305b261ecSmrg case FillSolid: 12405b261ecSmrg#ifndef FB_ACCESS_WRAPPER 12535c4bbdfSmrg if (pPriv->and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp, 12635c4bbdfSmrg x + dstXoff, y + dstYoff, 12735c4bbdfSmrg width, height, pPriv->xor)) 12835c4bbdfSmrg#endif 12935c4bbdfSmrg fbSolid(dst + (y + dstYoff) * dstStride, 13035c4bbdfSmrg dstStride, 13135c4bbdfSmrg (x + dstXoff) * dstBpp, 13235c4bbdfSmrg dstBpp, width * dstBpp, height, pPriv->and, pPriv->xor); 13335c4bbdfSmrg break; 13405b261ecSmrg case FillStippled: 13535c4bbdfSmrg case FillOpaqueStippled:{ 13635c4bbdfSmrg PixmapPtr pStip = pGC->stipple; 13735c4bbdfSmrg int stipWidth = pStip->drawable.width; 13835c4bbdfSmrg int stipHeight = pStip->drawable.height; 13935c4bbdfSmrg 14035c4bbdfSmrg if (dstBpp == 1) { 14135c4bbdfSmrg int alu; 14235c4bbdfSmrg FbBits *stip; 14335c4bbdfSmrg FbStride stipStride; 14435c4bbdfSmrg int stipBpp; 14535c4bbdfSmrg _X_UNUSED int stipXoff, stipYoff; 14635c4bbdfSmrg 14735c4bbdfSmrg if (pGC->fillStyle == FillStippled) 14835c4bbdfSmrg alu = FbStipple1Rop(pGC->alu, pGC->fgPixel); 14935c4bbdfSmrg else 15035c4bbdfSmrg alu = FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel, pGC->bgPixel); 15135c4bbdfSmrg fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff, 15235c4bbdfSmrg stipYoff); 15335c4bbdfSmrg fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff, 15435c4bbdfSmrg width, height, stip, stipStride, stipWidth, stipHeight, alu, 15535c4bbdfSmrg pPriv->pm, dstBpp, (pGC->patOrg.x + pDrawable->x + dstXoff), 15635c4bbdfSmrg pGC->patOrg.y + pDrawable->y - y); 15735c4bbdfSmrg fbFinishAccess(&pStip->drawable); 15835c4bbdfSmrg } 15935c4bbdfSmrg else { 16035c4bbdfSmrg FbStip *stip; 16135c4bbdfSmrg FbStride stipStride; 16235c4bbdfSmrg int stipBpp; 16335c4bbdfSmrg _X_UNUSED int stipXoff, stipYoff; 16435c4bbdfSmrg FbBits fgand, fgxor, bgand, bgxor; 16535c4bbdfSmrg 16635c4bbdfSmrg fgand = pPriv->and; 16735c4bbdfSmrg fgxor = pPriv->xor; 16835c4bbdfSmrg if (pGC->fillStyle == FillStippled) { 16935c4bbdfSmrg bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES); 17035c4bbdfSmrg bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES); 17135c4bbdfSmrg } 17235c4bbdfSmrg else { 17335c4bbdfSmrg bgand = pPriv->bgand; 17435c4bbdfSmrg bgxor = pPriv->bgxor; 17535c4bbdfSmrg } 17635c4bbdfSmrg 17735c4bbdfSmrg fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp, 17835c4bbdfSmrg stipXoff, stipYoff); 17935c4bbdfSmrg fbStipple(dst + (y + dstYoff) * dstStride, dstStride, 18035c4bbdfSmrg (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height, 18135c4bbdfSmrg stip, stipStride, stipWidth, stipHeight, 18235c4bbdfSmrg fgand, fgxor, bgand, bgxor, 18335c4bbdfSmrg pGC->patOrg.x + pDrawable->x + dstXoff, 18435c4bbdfSmrg pGC->patOrg.y + pDrawable->y - y); 18535c4bbdfSmrg fbFinishAccess(&pStip->drawable); 18635c4bbdfSmrg } 18735c4bbdfSmrg break; 18805b261ecSmrg } 18935c4bbdfSmrg case FillTiled:{ 19035c4bbdfSmrg PixmapPtr pTile = pGC->tile.pixmap; 19135c4bbdfSmrg FbBits *tile; 19235c4bbdfSmrg FbStride tileStride; 19335c4bbdfSmrg int tileBpp; 19435c4bbdfSmrg int tileWidth; 19535c4bbdfSmrg int tileHeight; 19635c4bbdfSmrg _X_UNUSED int tileXoff, tileYoff; 19735c4bbdfSmrg 19835c4bbdfSmrg fbGetDrawable(&pTile->drawable, tile, tileStride, tileBpp, tileXoff, 19935c4bbdfSmrg tileYoff); 20035c4bbdfSmrg tileWidth = pTile->drawable.width; 20135c4bbdfSmrg tileHeight = pTile->drawable.height; 20235c4bbdfSmrg fbTile(dst + (y + dstYoff) * dstStride, 20335c4bbdfSmrg dstStride, 20435c4bbdfSmrg (x + dstXoff) * dstBpp, 20535c4bbdfSmrg width * dstBpp, height, 20635c4bbdfSmrg tile, 20735c4bbdfSmrg tileStride, 20835c4bbdfSmrg tileWidth * tileBpp, 20935c4bbdfSmrg tileHeight, 21035c4bbdfSmrg pGC->alu, 21135c4bbdfSmrg pPriv->pm, 21235c4bbdfSmrg dstBpp, 21335c4bbdfSmrg (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp, 21435c4bbdfSmrg pGC->patOrg.y + pDrawable->y - y); 21535c4bbdfSmrg fbFinishAccess(&pTile->drawable); 21635c4bbdfSmrg break; 21705b261ecSmrg } 21805b261ecSmrg } 21935c4bbdfSmrg fbValidateDrawable(pDrawable); 22035c4bbdfSmrg fbFinishAccess(pDrawable); 22105b261ecSmrg} 22205b261ecSmrg 22305b261ecSmrgvoid 22435c4bbdfSmrgfbSolidBoxClipped(DrawablePtr pDrawable, 22535c4bbdfSmrg RegionPtr pClip, 22635c4bbdfSmrg int x1, int y1, int x2, int y2, FbBits and, FbBits xor) 22705b261ecSmrg{ 22835c4bbdfSmrg FbBits *dst; 22935c4bbdfSmrg FbStride dstStride; 23035c4bbdfSmrg int dstBpp; 23135c4bbdfSmrg int dstXoff, dstYoff; 23235c4bbdfSmrg BoxPtr pbox; 23335c4bbdfSmrg int nbox; 23435c4bbdfSmrg int partX1, partX2, partY1, partY2; 23535c4bbdfSmrg 23635c4bbdfSmrg fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 23735c4bbdfSmrg 2386747b715Smrg for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); 23935c4bbdfSmrg nbox--; pbox++) { 24035c4bbdfSmrg partX1 = pbox->x1; 24135c4bbdfSmrg if (partX1 < x1) 24235c4bbdfSmrg partX1 = x1; 24335c4bbdfSmrg 24435c4bbdfSmrg partX2 = pbox->x2; 24535c4bbdfSmrg if (partX2 > x2) 24635c4bbdfSmrg partX2 = x2; 24735c4bbdfSmrg 24835c4bbdfSmrg if (partX2 <= partX1) 24935c4bbdfSmrg continue; 25035c4bbdfSmrg 25135c4bbdfSmrg partY1 = pbox->y1; 25235c4bbdfSmrg if (partY1 < y1) 25335c4bbdfSmrg partY1 = y1; 25435c4bbdfSmrg 25535c4bbdfSmrg partY2 = pbox->y2; 25635c4bbdfSmrg if (partY2 > y2) 25735c4bbdfSmrg partY2 = y2; 25835c4bbdfSmrg 25935c4bbdfSmrg if (partY2 <= partY1) 26035c4bbdfSmrg continue; 26105b261ecSmrg 26205b261ecSmrg#ifndef FB_ACCESS_WRAPPER 26335c4bbdfSmrg if (and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp, 26435c4bbdfSmrg partX1 + dstXoff, partY1 + dstYoff, 26535c4bbdfSmrg (partX2 - partX1), (partY2 - partY1), xor)) 26605b261ecSmrg#endif 26735c4bbdfSmrg fbSolid(dst + (partY1 + dstYoff) * dstStride, 26835c4bbdfSmrg dstStride, 26935c4bbdfSmrg (partX1 + dstXoff) * dstBpp, 27035c4bbdfSmrg dstBpp, 27135c4bbdfSmrg (partX2 - partX1) * dstBpp, (partY2 - partY1), and, xor); 27205b261ecSmrg } 27335c4bbdfSmrg fbFinishAccess(pDrawable); 27405b261ecSmrg} 275