fbfill.c revision 05b261ec
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 2905b261ecSmrgvoid 3005b261ecSmrgfbFill (DrawablePtr pDrawable, 3105b261ecSmrg GCPtr pGC, 3205b261ecSmrg int x, 3305b261ecSmrg int y, 3405b261ecSmrg int width, 3505b261ecSmrg int height) 3605b261ecSmrg{ 3705b261ecSmrg FbBits *dst; 3805b261ecSmrg FbStride dstStride; 3905b261ecSmrg int dstBpp; 4005b261ecSmrg int dstXoff, dstYoff; 4105b261ecSmrg FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 4205b261ecSmrg 4305b261ecSmrg fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 4405b261ecSmrg 4505b261ecSmrg switch (pGC->fillStyle) { 4605b261ecSmrg case FillSolid: 4705b261ecSmrg#ifndef FB_ACCESS_WRAPPER 4805b261ecSmrg if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp, 4905b261ecSmrg x + dstXoff, y + dstYoff, 5005b261ecSmrg width, height, 5105b261ecSmrg pPriv->xor)) 5205b261ecSmrg#endif 5305b261ecSmrg fbSolid (dst + (y + dstYoff) * dstStride, 5405b261ecSmrg dstStride, 5505b261ecSmrg (x + dstXoff) * dstBpp, 5605b261ecSmrg dstBpp, 5705b261ecSmrg width * dstBpp, height, 5805b261ecSmrg pPriv->and, pPriv->xor); 5905b261ecSmrg break; 6005b261ecSmrg case FillStippled: 6105b261ecSmrg case FillOpaqueStippled: { 6205b261ecSmrg PixmapPtr pStip = pGC->stipple; 6305b261ecSmrg int stipWidth = pStip->drawable.width; 6405b261ecSmrg int stipHeight = pStip->drawable.height; 6505b261ecSmrg 6605b261ecSmrg if (dstBpp == 1) 6705b261ecSmrg { 6805b261ecSmrg int alu; 6905b261ecSmrg FbBits *stip; 7005b261ecSmrg FbStride stipStride; 7105b261ecSmrg int stipBpp; 7205b261ecSmrg int stipXoff, stipYoff; /* XXX assumed to be zero */ 7305b261ecSmrg 7405b261ecSmrg if (pGC->fillStyle == FillStippled) 7505b261ecSmrg alu = FbStipple1Rop(pGC->alu,pGC->fgPixel); 7605b261ecSmrg else 7705b261ecSmrg alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel); 7805b261ecSmrg fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); 7905b261ecSmrg fbTile (dst + (y + dstYoff) * dstStride, 8005b261ecSmrg dstStride, 8105b261ecSmrg x + dstXoff, 8205b261ecSmrg width, height, 8305b261ecSmrg stip, 8405b261ecSmrg stipStride, 8505b261ecSmrg stipWidth, 8605b261ecSmrg stipHeight, 8705b261ecSmrg alu, 8805b261ecSmrg pPriv->pm, 8905b261ecSmrg dstBpp, 9005b261ecSmrg 9105b261ecSmrg (pGC->patOrg.x + pDrawable->x + dstXoff), 9205b261ecSmrg pGC->patOrg.y + pDrawable->y - y); 9305b261ecSmrg fbFinishAccess (&pStip->drawable); 9405b261ecSmrg } 9505b261ecSmrg else 9605b261ecSmrg { 9705b261ecSmrg FbStip *stip; 9805b261ecSmrg FbStride stipStride; 9905b261ecSmrg int stipBpp; 10005b261ecSmrg int stipXoff, stipYoff; /* XXX assumed to be zero */ 10105b261ecSmrg FbBits fgand, fgxor, bgand, bgxor; 10205b261ecSmrg 10305b261ecSmrg fgand = pPriv->and; 10405b261ecSmrg fgxor = pPriv->xor; 10505b261ecSmrg if (pGC->fillStyle == FillStippled) 10605b261ecSmrg { 10705b261ecSmrg bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES); 10805b261ecSmrg bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES); 10905b261ecSmrg } 11005b261ecSmrg else 11105b261ecSmrg { 11205b261ecSmrg bgand = pPriv->bgand; 11305b261ecSmrg bgxor = pPriv->bgxor; 11405b261ecSmrg } 11505b261ecSmrg 11605b261ecSmrg fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); 11705b261ecSmrg fbStipple (dst + (y + dstYoff) * dstStride, 11805b261ecSmrg dstStride, 11905b261ecSmrg (x + dstXoff) * dstBpp, 12005b261ecSmrg dstBpp, 12105b261ecSmrg width * dstBpp, height, 12205b261ecSmrg stip, 12305b261ecSmrg stipStride, 12405b261ecSmrg stipWidth, 12505b261ecSmrg stipHeight, 12605b261ecSmrg pPriv->evenStipple, 12705b261ecSmrg fgand, fgxor, 12805b261ecSmrg bgand, bgxor, 12905b261ecSmrg pGC->patOrg.x + pDrawable->x + dstXoff, 13005b261ecSmrg pGC->patOrg.y + pDrawable->y - y); 13105b261ecSmrg fbFinishAccess (&pStip->drawable); 13205b261ecSmrg } 13305b261ecSmrg break; 13405b261ecSmrg } 13505b261ecSmrg case FillTiled: { 13605b261ecSmrg PixmapPtr pTile = pGC->tile.pixmap; 13705b261ecSmrg FbBits *tile; 13805b261ecSmrg FbStride tileStride; 13905b261ecSmrg int tileBpp; 14005b261ecSmrg int tileWidth; 14105b261ecSmrg int tileHeight; 14205b261ecSmrg int tileXoff, tileYoff; /* XXX assumed to be zero */ 14305b261ecSmrg 14405b261ecSmrg fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff); 14505b261ecSmrg tileWidth = pTile->drawable.width; 14605b261ecSmrg tileHeight = pTile->drawable.height; 14705b261ecSmrg fbTile (dst + (y + dstYoff) * dstStride, 14805b261ecSmrg dstStride, 14905b261ecSmrg (x + dstXoff) * dstBpp, 15005b261ecSmrg width * dstBpp, height, 15105b261ecSmrg tile, 15205b261ecSmrg tileStride, 15305b261ecSmrg tileWidth * tileBpp, 15405b261ecSmrg tileHeight, 15505b261ecSmrg pGC->alu, 15605b261ecSmrg pPriv->pm, 15705b261ecSmrg dstBpp, 15805b261ecSmrg (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp, 15905b261ecSmrg pGC->patOrg.y + pDrawable->y - y); 16005b261ecSmrg fbFinishAccess (&pTile->drawable); 16105b261ecSmrg break; 16205b261ecSmrg } 16305b261ecSmrg } 16405b261ecSmrg fbValidateDrawable (pDrawable); 16505b261ecSmrg fbFinishAccess (pDrawable); 16605b261ecSmrg} 16705b261ecSmrg 16805b261ecSmrgvoid 16905b261ecSmrgfbSolidBoxClipped (DrawablePtr pDrawable, 17005b261ecSmrg RegionPtr pClip, 17105b261ecSmrg int x1, 17205b261ecSmrg int y1, 17305b261ecSmrg int x2, 17405b261ecSmrg int y2, 17505b261ecSmrg FbBits and, 17605b261ecSmrg FbBits xor) 17705b261ecSmrg{ 17805b261ecSmrg FbBits *dst; 17905b261ecSmrg FbStride dstStride; 18005b261ecSmrg int dstBpp; 18105b261ecSmrg int dstXoff, dstYoff; 18205b261ecSmrg BoxPtr pbox; 18305b261ecSmrg int nbox; 18405b261ecSmrg int partX1, partX2, partY1, partY2; 18505b261ecSmrg 18605b261ecSmrg fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 18705b261ecSmrg 18805b261ecSmrg for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); 18905b261ecSmrg nbox--; 19005b261ecSmrg pbox++) 19105b261ecSmrg { 19205b261ecSmrg partX1 = pbox->x1; 19305b261ecSmrg if (partX1 < x1) 19405b261ecSmrg partX1 = x1; 19505b261ecSmrg 19605b261ecSmrg partX2 = pbox->x2; 19705b261ecSmrg if (partX2 > x2) 19805b261ecSmrg partX2 = x2; 19905b261ecSmrg 20005b261ecSmrg if (partX2 <= partX1) 20105b261ecSmrg continue; 20205b261ecSmrg 20305b261ecSmrg partY1 = pbox->y1; 20405b261ecSmrg if (partY1 < y1) 20505b261ecSmrg partY1 = y1; 20605b261ecSmrg 20705b261ecSmrg partY2 = pbox->y2; 20805b261ecSmrg if (partY2 > y2) 20905b261ecSmrg partY2 = y2; 21005b261ecSmrg 21105b261ecSmrg if (partY2 <= partY1) 21205b261ecSmrg continue; 21305b261ecSmrg 21405b261ecSmrg#ifndef FB_ACCESS_WRAPPER 21505b261ecSmrg if (and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp, 21605b261ecSmrg partX1 + dstXoff, partY1 + dstYoff, 21705b261ecSmrg (partX2 - partX1), (partY2 - partY1), 21805b261ecSmrg xor)) 21905b261ecSmrg#endif 22005b261ecSmrg fbSolid (dst + (partY1 + dstYoff) * dstStride, 22105b261ecSmrg dstStride, 22205b261ecSmrg (partX1 + dstXoff) * dstBpp, 22305b261ecSmrg dstBpp, 22405b261ecSmrg 22505b261ecSmrg (partX2 - partX1) * dstBpp, 22605b261ecSmrg (partY2 - partY1), 22705b261ecSmrg and, xor); 22805b261ecSmrg } 22905b261ecSmrg fbFinishAccess (pDrawable); 23005b261ecSmrg} 231