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 30fbPushPattern (DrawablePtr pDrawable, 31 GCPtr pGC, 32 33 FbStip *src, 34 FbStride srcStride, 35 int srcX, 36 37 int x, 38 int y, 39 40 int width, 41 int height) 42{ 43 FbStip *s, bitsMask, bitsMask0, bits; 44 int xspan; 45 int w; 46 int lenspan; 47 48 src += srcX >> FB_STIP_SHIFT; 49 srcX &= FB_STIP_MASK; 50 51 bitsMask0 = FbStipMask (srcX, 1); 52 53 while (height--) 54 { 55 bitsMask = bitsMask0; 56 w = width; 57 s = src; 58 src += srcStride; 59 bits = READ(s++); 60 xspan = x; 61 while (w) 62 { 63 if (bits & bitsMask) 64 { 65 lenspan = 0; 66 do 67 { 68 lenspan++; 69 if (lenspan == w) 70 break; 71 bitsMask = FbStipRight (bitsMask, 1); 72 if (!bitsMask) 73 { 74 bits = READ(s++); 75 bitsMask = FbBitsMask(0,1); 76 } 77 } while (bits & bitsMask); 78 fbFill (pDrawable, pGC, xspan, y, lenspan, 1); 79 xspan += lenspan; 80 w -= lenspan; 81 } 82 else 83 { 84 do 85 { 86 w--; 87 xspan++; 88 if (!w) 89 break; 90 bitsMask = FbStipRight (bitsMask, 1); 91 if (!bitsMask) 92 { 93 bits = READ(s++); 94 bitsMask = FbBitsMask(0,1); 95 } 96 } while (!(bits & bitsMask)); 97 } 98 } 99 y++; 100 } 101} 102 103void 104fbPushFill (DrawablePtr pDrawable, 105 GCPtr pGC, 106 107 FbStip *src, 108 FbStride srcStride, 109 int srcX, 110 111 int x, 112 int y, 113 int width, 114 int height) 115{ 116 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 117 118 if (pGC->fillStyle == FillSolid) 119 { 120 FbBits *dst; 121 FbStride dstStride; 122 int dstBpp; 123 int dstXoff, dstYoff; 124 int dstX; 125 int dstWidth; 126 127 fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 128 dst = dst + (y + dstYoff) * dstStride; 129 dstX = (x + dstXoff) * dstBpp; 130 dstWidth = width * dstBpp; 131 if (dstBpp == 1) 132 { 133 fbBltStip (src, 134 srcStride, 135 srcX, 136 137 (FbStip *) dst, 138 FbBitsStrideToStipStride (dstStride), 139 dstX, 140 141 dstWidth, 142 height, 143 144 FbStipple1Rop(pGC->alu,pGC->fgPixel), 145 pPriv->pm, 146 dstBpp); 147 } 148 else 149 { 150 fbBltOne (src, 151 srcStride, 152 srcX, 153 154 dst, 155 dstStride, 156 dstX, 157 dstBpp, 158 159 dstWidth, 160 height, 161 162 pPriv->and, pPriv->xor, 163 fbAnd(GXnoop,(FbBits) 0,FB_ALLONES), 164 fbXor(GXnoop,(FbBits) 0,FB_ALLONES)); 165 } 166 fbFinishAccess (pDrawable); 167 } 168 else 169 { 170 fbPushPattern (pDrawable, pGC, src, srcStride, srcX, 171 x, y, width, height); 172 } 173} 174 175void 176fbPushImage (DrawablePtr pDrawable, 177 GCPtr pGC, 178 179 FbStip *src, 180 FbStride srcStride, 181 int srcX, 182 183 int x, 184 int y, 185 int width, 186 int height) 187{ 188 RegionPtr pClip = fbGetCompositeClip (pGC); 189 int nbox; 190 BoxPtr pbox; 191 int x1, y1, x2, y2; 192 193 for (nbox = RegionNumRects (pClip), 194 pbox = RegionRects(pClip); 195 nbox--; 196 pbox++) 197 { 198 x1 = x; 199 y1 = y; 200 x2 = x + width; 201 y2 = y + height; 202 if (x1 < pbox->x1) 203 x1 = pbox->x1; 204 if (y1 < pbox->y1) 205 y1 = pbox->y1; 206 if (x2 > pbox->x2) 207 x2 = pbox->x2; 208 if (y2 > pbox->y2) 209 y2 = pbox->y2; 210 if (x1 >= x2 || y1 >= y2) 211 continue; 212 fbPushFill (pDrawable, 213 pGC, 214 215 src + (y1 - y) * srcStride, 216 srcStride, 217 srcX + (x1 - x), 218 219 x1, 220 y1, 221 x2 - x1, 222 y2 - y1); 223 } 224} 225 226void 227fbPushPixels (GCPtr pGC, 228 PixmapPtr pBitmap, 229 DrawablePtr pDrawable, 230 int dx, 231 int dy, 232 int xOrg, 233 int yOrg) 234{ 235 FbStip *stip; 236 FbStride stipStride; 237 int stipBpp; 238 int stipXoff, stipYoff; /* Assumed to be zero */ 239 240 fbGetStipDrawable (&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, stipYoff); 241 242 fbPushImage (pDrawable, pGC, 243 stip, stipStride, 0, 244 xOrg, yOrg, dx, dy); 245} 246