1/* 2 * Copyright © 1998 Keith Packard 3 * Copyright © 2012 Intel Corporation 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the name of Keith Packard not be used in 10 * advertising or publicity pertaining to distribution of the software without 11 * specific, written prior permission. Keith Packard makes no 12 * representations about the suitability of this software for any purpose. It 13 * is provided "as is" without express or implied warranty. 14 * 15 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 16 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 17 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR 18 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 19 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 20 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 21 * PERFORMANCE OF THIS SOFTWARE. 22 */ 23 24#include "fb.h" 25#include "fbclip.h" 26 27static void 28fbPushPattern(DrawablePtr drawable, GCPtr gc, 29 FbStip *src, FbStride srcStride, int srcX, 30 int x, int y, int width, int height) 31{ 32 FbStip *s, bitsMask, bitsMask0, bits; 33 int xspan; 34 int w; 35 int lenspan; 36 37 src += srcX >> FB_STIP_SHIFT; 38 srcX &= FB_STIP_MASK; 39 40 bitsMask0 = FbStipMask(srcX, 1); 41 42 while (height--) { 43 bitsMask = bitsMask0; 44 w = width; 45 s = src; 46 src += srcStride; 47 bits = READ(s++); 48 xspan = x; 49 while (w) { 50 if (bits & bitsMask) { 51 lenspan = 0; 52 do { 53 if (++lenspan == w) 54 break; 55 56 bitsMask = FbStipRight(bitsMask, 1); 57 if (!bitsMask) { 58 bits = READ(s++); 59 bitsMask = FbBitsMask(0, 1); 60 } 61 } while (bits & bitsMask); 62 fbFill(drawable, gc, xspan, y, lenspan, 1); 63 xspan += lenspan; 64 w -= lenspan; 65 } else { 66 do { 67 xspan++; 68 if (!--w) 69 break; 70 71 bitsMask = FbStipRight(bitsMask, 1); 72 if (!bitsMask) { 73 bits = READ(s++); 74 bitsMask = FbBitsMask(0, 1); 75 } 76 } while (!(bits & bitsMask)); 77 } 78 } 79 y++; 80 } 81} 82 83static void 84fbPushFill(DrawablePtr drawable, GCPtr gc, 85 FbStip *src, FbStride srcStride, int srcX, 86 int x, int y, int width, int height) 87{ 88 FbGCPrivPtr pgc = fb_gc(gc); 89 90 if (gc->fillStyle == FillSolid) { 91 FbBits *dst; 92 FbStride dstStride; 93 int dstBpp; 94 int dstXoff, dstYoff; 95 int dstX; 96 int dstWidth; 97 98 fbGetDrawable(drawable, dst, 99 dstStride, dstBpp, dstXoff, dstYoff); 100 dst = dst + (y + dstYoff) * dstStride; 101 dstX = (x + dstXoff) * dstBpp; 102 dstWidth = width * dstBpp; 103 if (dstBpp == 1) { 104 fbBltStip(src, srcStride, srcX, 105 (FbStip *)dst, dstStride, dstX, 106 dstWidth, height, 107 FbStipple1Rop(gc->alu, gc->fgPixel), pgc->pm, dstBpp); 108 } else { 109 fbBltOne(src, srcStride, srcX, 110 dst, dstStride, dstX, dstBpp, 111 dstWidth, height, 112 pgc->and, pgc->xor, 113 fbAnd(GXnoop, (FbBits) 0, FB_ALLONES), 114 fbXor(GXnoop, (FbBits) 0, FB_ALLONES)); 115 } 116 } else 117 fbPushPattern(drawable, gc, src, srcStride, srcX, 118 x, y, width, height); 119} 120 121struct fbPushImage { 122 FbStip *src; 123 FbStride stride; 124 int x0, y0; 125}; 126 127inline static void 128_fbPushImage(DrawablePtr drawable, GCPtr gc, const BoxRec *b, void *_data) 129{ 130 struct fbPushImage *data = _data; 131 132 fbPushFill(drawable, gc, 133 data->src + (b->y1 - data->y0) * data->stride, data->stride, 134 b->x1 - data->x0, 135 b->x1, b->y1, 136 b->x2 - b->x1, b->y2 - b->y1); 137} 138 139void 140fbPushImage(DrawablePtr drawable, GCPtr gc, 141 FbStip *src, FbStride stride, int dx, 142 int x, int y, int width, int height) 143{ 144 struct fbPushImage data; 145 BoxRec box; 146 147 DBG(("%s (%d, %d)x(%d, %d)\n", __FUNCTION__, x, y, width, height)); 148 149 data.src = src; 150 data.stride = stride; 151 data.y0 = y; 152 data.x0 = x - dx; 153 154 box.x1 = x; 155 box.y1 = y; 156 box.x2 = x + width; 157 box.y2 = y + height; 158 fbDrawableRun(drawable, gc, &box, _fbPushImage, &data); 159} 160 161void 162fbPushPixels(GCPtr gc, PixmapPtr bitmap, DrawablePtr drawable, 163 int dx, int dy, int xOrg, int yOrg) 164{ 165 FbStip *stip; 166 FbStride stipStride; 167 int stipBpp; 168 _X_UNUSED int stipXoff, stipYoff; 169 170 DBG(("%s bitmap=%x%d\n", __FUNCTION__, 171 bitmap->drawable.width, bitmap->drawable.height)); 172 173 fbGetStipDrawable(&bitmap->drawable, stip, 174 stipStride, stipBpp, stipXoff, stipYoff); 175 176 fbPushImage(drawable, gc, stip, stipStride, 0, xOrg, yOrg, dx, dy); 177} 178