187 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			187 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C
		
	
	
	
| /*
 | |
|  * Copyright © 1998 Keith Packard
 | |
|  *
 | |
|  * Permission to use, copy, modify, distribute, and sell this software and its
 | |
|  * documentation for any purpose is hereby granted without fee, provided that
 | |
|  * the above copyright notice appear in all copies and that both that
 | |
|  * copyright notice and this permission notice appear in supporting
 | |
|  * documentation, and that the name of Keith Packard not be used in
 | |
|  * advertising or publicity pertaining to distribution of the software without
 | |
|  * specific, written prior permission.  Keith Packard makes no
 | |
|  * representations about the suitability of this software for any purpose.  It
 | |
|  * is provided "as is" without express or implied warranty.
 | |
|  *
 | |
|  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | |
|  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | |
|  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | |
|  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | |
|  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | |
|  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | |
|  * PERFORMANCE OF THIS SOFTWARE.
 | |
|  */
 | |
| 
 | |
| #include <dix-config.h>
 | |
| 
 | |
| #include "fb.h"
 | |
| 
 | |
| static void
 | |
| fbPushPattern(DrawablePtr pDrawable,
 | |
|               GCPtr pGC,
 | |
|               FbStip * src,
 | |
|               FbStride srcStride, int srcX, int x, int y, int width, int height)
 | |
| {
 | |
|     FbStip *s, bitsMask, bitsMask0, bits;
 | |
|     int xspan;
 | |
|     int w;
 | |
|     int lenspan;
 | |
| 
 | |
|     src += srcX >> FB_STIP_SHIFT;
 | |
|     srcX &= FB_STIP_MASK;
 | |
| 
 | |
|     bitsMask0 = FbStipMask(srcX, 1);
 | |
| 
 | |
|     while (height--) {
 | |
|         bitsMask = bitsMask0;
 | |
|         w = width;
 | |
|         s = src;
 | |
|         src += srcStride;
 | |
|         bits = READ(s++);
 | |
|         xspan = x;
 | |
|         while (w) {
 | |
|             if (bits & bitsMask) {
 | |
|                 lenspan = 0;
 | |
|                 do {
 | |
|                     lenspan++;
 | |
|                     if (lenspan == w)
 | |
|                         break;
 | |
|                     bitsMask = FbStipRight(bitsMask, 1);
 | |
|                     if (!bitsMask) {
 | |
|                         bits = READ(s++);
 | |
|                         bitsMask = FbBitsMask(0, 1);
 | |
|                     }
 | |
|                 } while (bits & bitsMask);
 | |
|                 fbFill(pDrawable, pGC, xspan, y, lenspan, 1);
 | |
|                 xspan += lenspan;
 | |
|                 w -= lenspan;
 | |
|             }
 | |
|             else {
 | |
|                 do {
 | |
|                     w--;
 | |
|                     xspan++;
 | |
|                     if (!w)
 | |
|                         break;
 | |
|                     bitsMask = FbStipRight(bitsMask, 1);
 | |
|                     if (!bitsMask) {
 | |
|                         bits = READ(s++);
 | |
|                         bitsMask = FbBitsMask(0, 1);
 | |
|                     }
 | |
|                 } while (!(bits & bitsMask));
 | |
|             }
 | |
|         }
 | |
|         y++;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static void
 | |
| fbPushFill(DrawablePtr pDrawable,
 | |
|            GCPtr pGC,
 | |
|            FbStip * src,
 | |
|            FbStride srcStride, int srcX, int x, int y, int width, int height)
 | |
| {
 | |
|     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
 | |
| 
 | |
|     if (pGC->fillStyle == FillSolid) {
 | |
|         FbBits *dst;
 | |
|         FbStride dstStride;
 | |
|         int dstBpp;
 | |
|         int dstXoff, dstYoff;
 | |
|         int dstX;
 | |
|         int dstWidth;
 | |
| 
 | |
|         fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 | |
|         dst = dst + (y + dstYoff) * dstStride;
 | |
|         dstX = (x + dstXoff) * dstBpp;
 | |
|         dstWidth = width * dstBpp;
 | |
|         if (dstBpp == 1) {
 | |
|             fbBltStip(src,
 | |
|                       srcStride,
 | |
|                       srcX,
 | |
|                       (FbStip *) dst,
 | |
|                       FbBitsStrideToStipStride(dstStride),
 | |
|                       dstX,
 | |
|                       dstWidth,
 | |
|                       height,
 | |
|                       FbStipple1Rop(pGC->alu, pGC->fgPixel), pPriv->pm, dstBpp);
 | |
|         }
 | |
|         else {
 | |
|             fbBltOne(src,
 | |
|                      srcStride,
 | |
|                      srcX,
 | |
|                      dst,
 | |
|                      dstStride,
 | |
|                      dstX,
 | |
|                      dstBpp,
 | |
|                      dstWidth,
 | |
|                      height,
 | |
|                      pPriv->and, pPriv->xor,
 | |
|                      fbAnd(GXnoop, (FbBits) 0, FB_ALLONES),
 | |
|                      fbXor(GXnoop, (FbBits) 0, FB_ALLONES));
 | |
|         }
 | |
|         fbFinishAccess(pDrawable);
 | |
|     }
 | |
|     else {
 | |
|         fbPushPattern(pDrawable, pGC, src, srcStride, srcX,
 | |
|                       x, y, width, height);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbPushImage(DrawablePtr pDrawable,
 | |
|             GCPtr pGC,
 | |
|             FbStip * src,
 | |
|             FbStride srcStride, int srcX, int x, int y, int width, int height)
 | |
| {
 | |
|     RegionPtr pClip = fbGetCompositeClip(pGC);
 | |
|     int nbox;
 | |
|     BoxPtr pbox;
 | |
|     int x1, y1, x2, y2;
 | |
| 
 | |
|     for (nbox = RegionNumRects(pClip),
 | |
|          pbox = RegionRects(pClip); nbox--; pbox++) {
 | |
|         x1 = x;
 | |
|         y1 = y;
 | |
|         x2 = x + width;
 | |
|         y2 = y + height;
 | |
|         if (x1 < pbox->x1)
 | |
|             x1 = pbox->x1;
 | |
|         if (y1 < pbox->y1)
 | |
|             y1 = pbox->y1;
 | |
|         if (x2 > pbox->x2)
 | |
|             x2 = pbox->x2;
 | |
|         if (y2 > pbox->y2)
 | |
|             y2 = pbox->y2;
 | |
|         if (x1 >= x2 || y1 >= y2)
 | |
|             continue;
 | |
|         fbPushFill(pDrawable,
 | |
|                    pGC,
 | |
|                    src + (y1 - y) * srcStride,
 | |
|                    srcStride, srcX + (x1 - x), x1, y1, x2 - x1, y2 - y1);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void
 | |
| fbPushPixels(GCPtr pGC,
 | |
|              PixmapPtr pBitmap,
 | |
|              DrawablePtr pDrawable, int dx, int dy, int xOrg, int yOrg)
 | |
| {
 | |
|     FbStip *stip;
 | |
|     FbStride stipStride;
 | |
|     int stipBpp;
 | |
|     _X_UNUSED int stipXoff, stipYoff;
 | |
| 
 | |
|     fbGetStipDrawable(&pBitmap->drawable, stip, stipStride, stipBpp, stipXoff,
 | |
|                       stipYoff);
 | |
| 
 | |
|     fbPushImage(pDrawable, pGC, stip, stipStride, 0, xOrg, yOrg, dx, dy);
 | |
| }
 |