fbpush.c revision 35c4bbdf
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 29static void 30fbPushPattern(DrawablePtr pDrawable, 31 GCPtr pGC, 32 FbStip * src, 33 FbStride srcStride, int srcX, int x, int y, int width, int height) 34{ 35 FbStip *s, bitsMask, bitsMask0, bits; 36 int xspan; 37 int w; 38 int lenspan; 39 40 src += srcX >> FB_STIP_SHIFT; 41 srcX &= FB_STIP_MASK; 42 43 bitsMask0 = FbStipMask(srcX, 1); 44 45 while (height--) { 46 bitsMask = bitsMask0; 47 w = width; 48 s = src; 49 src += srcStride; 50 bits = READ(s++); 51 xspan = x; 52 while (w) { 53 if (bits & bitsMask) { 54 lenspan = 0; 55 do { 56 lenspan++; 57 if (lenspan == w) 58 break; 59 bitsMask = FbStipRight(bitsMask, 1); 60 if (!bitsMask) { 61 bits = READ(s++); 62 bitsMask = FbBitsMask(0, 1); 63 } 64 } while (bits & bitsMask); 65 fbFill(pDrawable, pGC, xspan, y, lenspan, 1); 66 xspan += lenspan; 67 w -= lenspan; 68 } 69 else { 70 do { 71 w--; 72 xspan++; 73 if (!w) 74 break; 75 bitsMask = FbStipRight(bitsMask, 1); 76 if (!bitsMask) { 77 bits = READ(s++); 78 bitsMask = FbBitsMask(0, 1); 79 } 80 } while (!(bits & bitsMask)); 81 } 82 } 83 y++; 84 } 85} 86 87static void 88fbPushFill(DrawablePtr pDrawable, 89 GCPtr pGC, 90 FbStip * src, 91 FbStride srcStride, int srcX, int x, int y, int width, int height) 92{ 93 FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); 94 95 if (pGC->fillStyle == FillSolid) { 96 FbBits *dst; 97 FbStride dstStride; 98 int dstBpp; 99 int dstXoff, dstYoff; 100 int dstX; 101 int dstWidth; 102 103 fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); 104 dst = dst + (y + dstYoff) * dstStride; 105 dstX = (x + dstXoff) * dstBpp; 106 dstWidth = width * dstBpp; 107 if (dstBpp == 1) { 108 fbBltStip(src, 109 srcStride, 110 srcX, 111 (FbStip *) dst, 112 FbBitsStrideToStipStride(dstStride), 113 dstX, 114 dstWidth, 115 height, 116 FbStipple1Rop(pGC->alu, pGC->fgPixel), pPriv->pm, dstBpp); 117 } 118 else { 119 fbBltOne(src, 120 srcStride, 121 srcX, 122 dst, 123 dstStride, 124 dstX, 125 dstBpp, 126 dstWidth, 127 height, 128 pPriv->and, pPriv->xor, 129 fbAnd(GXnoop, (FbBits) 0, FB_ALLONES), 130 fbXor(GXnoop, (FbBits) 0, FB_ALLONES)); 131 } 132 fbFinishAccess(pDrawable); 133 } 134 else { 135 fbPushPattern(pDrawable, pGC, src, srcStride, srcX, 136 x, y, width, height); 137 } 138} 139 140void 141fbPushImage(DrawablePtr pDrawable, 142 GCPtr pGC, 143 FbStip * src, 144 FbStride srcStride, int srcX, int x, int y, int width, int height) 145{ 146 RegionPtr pClip = fbGetCompositeClip(pGC); 147 int nbox; 148 BoxPtr pbox; 149 int x1, y1, x2, y2; 150 151 for (nbox = RegionNumRects(pClip), 152 pbox = RegionRects(pClip); nbox--; pbox++) { 153 x1 = x; 154 y1 = y; 155 x2 = x + width; 156 y2 = y + height; 157 if (x1 < pbox->x1) 158 x1 = pbox->x1; 159 if (y1 < pbox->y1) 160 y1 = pbox->y1; 161 if (x2 > pbox->x2) 162 x2 = pbox->x2; 163 if (y2 > pbox->y2) 164 y2 = pbox->y2; 165 if (x1 >= x2 || y1 >= y2) 166 continue; 167 fbPushFill(pDrawable, 168 pGC, 169 src + (y1 - y) * srcStride, 170 srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1); 171 } 172} 173 174void 175fbPushPixels(GCPtr pGC, 176 PixmapPtr pBitmap, 177 DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg) 178{ 179 FbStip *stip; 180 FbStride stipStride; 181 int stipBpp; 182 _X_UNUSED int stipXoff, stipYoff; 183 184 fbGetStipDrawable(&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff, 185 stipYoff); 186 187 fbPushImage(pDrawable, pGC, stip, stipStride, 0, xOrg, yOrg, dx, dy); 188} 189