fbfill.c revision 706f2543
1/* 2 * Copyright © 1998 Keith Packard 3 * 4 * Permission to use, copy, modify, distribute, and sell this software and its 5 * documentation for any purpose is hereby granted without fee, provided that 6 * the above copyright notice appear in all copies and that both that 7 * copyright notice and this permission notice appear in supporting 8 * documentation, and that the name of Keith Packard not be used in 9 * advertising or publicity pertaining to distribution of the software without 10 * specific, written prior permission. Keith Packard makes no 11 * representations about the suitability of this software for any purpose. It 12 * is provided "as is" without express or implied warranty. 13 * 14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 20 * PERFORMANCE OF THIS SOFTWARE. 21 */ 22 23#ifdef HAVE_DIX_CONFIG_H 24#include <dix-config.h> 25#endif 26 27#include "fb.h" 28 29void 30fbFill (DrawablePtr pDrawable, 31 GCPtr pGC, 32 int x, 33 int y, 34 int width, 35 int height) 36{ 37 FbBits *dst; 38 FbStride dstStride; 39 int dstBpp; 40 int dstXoff, dstYoff; 41 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 42 43 fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 44 45 switch (pGC->fillStyle) { 46 case FillSolid: 47#ifndef FB_ACCESS_WRAPPER 48 if (pPriv->and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp, 49 x + dstXoff, y + dstYoff, 50 width, height, 51 pPriv->xor)) 52#endif 53 fbSolid (dst + (y + dstYoff) * dstStride, 54 dstStride, 55 (x + dstXoff) * dstBpp, 56 dstBpp, 57 width * dstBpp, height, 58 pPriv->and, pPriv->xor); 59 break; 60 case FillStippled: 61 case FillOpaqueStippled: { 62 PixmapPtr pStip = pGC->stipple; 63 int stipWidth = pStip->drawable.width; 64 int stipHeight = pStip->drawable.height; 65 66 if (dstBpp == 1) 67 { 68 int alu; 69 FbBits *stip; 70 FbStride stipStride; 71 int stipBpp; 72 int stipXoff, stipYoff; /* XXX assumed to be zero */ 73 74 if (pGC->fillStyle == FillStippled) 75 alu = FbStipple1Rop(pGC->alu,pGC->fgPixel); 76 else 77 alu = FbOpaqueStipple1Rop(pGC->alu,pGC->fgPixel,pGC->bgPixel); 78 fbGetDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); 79 fbTile (dst + (y + dstYoff) * dstStride, 80 dstStride, 81 x + dstXoff, 82 width, height, 83 stip, 84 stipStride, 85 stipWidth, 86 stipHeight, 87 alu, 88 pPriv->pm, 89 dstBpp, 90 91 (pGC->patOrg.x + pDrawable->x + dstXoff), 92 pGC->patOrg.y + pDrawable->y - y); 93 fbFinishAccess (&pStip->drawable); 94 } 95 else 96 { 97 FbStip *stip; 98 FbStride stipStride; 99 int stipBpp; 100 int stipXoff, stipYoff; /* XXX assumed to be zero */ 101 FbBits fgand, fgxor, bgand, bgxor; 102 103 fgand = pPriv->and; 104 fgxor = pPriv->xor; 105 if (pGC->fillStyle == FillStippled) 106 { 107 bgand = fbAnd(GXnoop,(FbBits) 0,FB_ALLONES); 108 bgxor = fbXor(GXnoop,(FbBits) 0,FB_ALLONES); 109 } 110 else 111 { 112 bgand = pPriv->bgand; 113 bgxor = pPriv->bgxor; 114 } 115 116 fbGetStipDrawable (&pStip->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); 117 fbStipple (dst + (y + dstYoff) * dstStride, 118 dstStride, 119 (x + dstXoff) * dstBpp, 120 dstBpp, 121 width * dstBpp, height, 122 stip, 123 stipStride, 124 stipWidth, 125 stipHeight, 126 pPriv->evenStipple, 127 fgand, fgxor, 128 bgand, bgxor, 129 pGC->patOrg.x + pDrawable->x + dstXoff, 130 pGC->patOrg.y + pDrawable->y - y); 131 fbFinishAccess (&pStip->drawable); 132 } 133 break; 134 } 135 case FillTiled: { 136 PixmapPtr pTile = pGC->tile.pixmap; 137 FbBits *tile; 138 FbStride tileStride; 139 int tileBpp; 140 int tileWidth; 141 int tileHeight; 142 int tileXoff, tileYoff; /* XXX assumed to be zero */ 143 144 fbGetDrawable (&pTile->drawable, tile, tileStride, tileBpp, tileXoff, tileYoff); 145 tileWidth = pTile->drawable.width; 146 tileHeight = pTile->drawable.height; 147 fbTile (dst + (y + dstYoff) * dstStride, 148 dstStride, 149 (x + dstXoff) * dstBpp, 150 width * dstBpp, height, 151 tile, 152 tileStride, 153 tileWidth * tileBpp, 154 tileHeight, 155 pGC->alu, 156 pPriv->pm, 157 dstBpp, 158 (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp, 159 pGC->patOrg.y + pDrawable->y - y); 160 fbFinishAccess (&pTile->drawable); 161 break; 162 } 163 } 164 fbValidateDrawable (pDrawable); 165 fbFinishAccess (pDrawable); 166} 167 168void 169fbSolidBoxClipped (DrawablePtr pDrawable, 170 RegionPtr pClip, 171 int x1, 172 int y1, 173 int x2, 174 int y2, 175 FbBits and, 176 FbBits xor) 177{ 178 FbBits *dst; 179 FbStride dstStride; 180 int dstBpp; 181 int dstXoff, dstYoff; 182 BoxPtr pbox; 183 int nbox; 184 int partX1, partX2, partY1, partY2; 185 186 fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 187 188 for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip); 189 nbox--; 190 pbox++) 191 { 192 partX1 = pbox->x1; 193 if (partX1 < x1) 194 partX1 = x1; 195 196 partX2 = pbox->x2; 197 if (partX2 > x2) 198 partX2 = x2; 199 200 if (partX2 <= partX1) 201 continue; 202 203 partY1 = pbox->y1; 204 if (partY1 < y1) 205 partY1 = y1; 206 207 partY2 = pbox->y2; 208 if (partY2 > y2) 209 partY2 = y2; 210 211 if (partY2 <= partY1) 212 continue; 213 214#ifndef FB_ACCESS_WRAPPER 215 if (and || !pixman_fill ((uint32_t *)dst, dstStride, dstBpp, 216 partX1 + dstXoff, partY1 + dstYoff, 217 (partX2 - partX1), (partY2 - partY1), 218 xor)) 219#endif 220 fbSolid (dst + (partY1 + dstYoff) * dstStride, 221 dstStride, 222 (partX1 + dstXoff) * dstBpp, 223 dstBpp, 224 225 (partX2 - partX1) * dstBpp, 226 (partY2 - partY1), 227 and, xor); 228 } 229 fbFinishAccess (pDrawable); 230} 231