Edit

IABSD.fr/xenocara/xserver/fb/fbfill.c

Branch :

  • Show log

    Commit

  • Author : matthieu
    Date : 2012-06-10 13:21:05
    Hash : e60da745
    Message : Update to xserver 1.12.2. tested by naddy@, krw@, mpi@.

  • xserver/fb/fbfill.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.
     */
    
    #ifdef HAVE_DIX_CONFIG_H
    #include <dix-config.h>
    #endif
    
    #include "fb.h"
    
    void
    fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height)
    {
        FbBits *dst;
        FbStride dstStride;
        int dstBpp;
        int dstXoff, dstYoff;
        FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    
        fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    
        switch (pGC->fillStyle) {
        case FillSolid:
    #ifndef FB_ACCESS_WRAPPER
            if (pPriv->and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp,
                                           x + dstXoff, y + dstYoff,
                                           width, height, pPriv->xor))
    #endif
                fbSolid(dst + (y + dstYoff) * dstStride,
                        dstStride,
                        (x + dstXoff) * dstBpp,
                        dstBpp, width * dstBpp, height, pPriv->and, pPriv->xor);
            break;
        case FillStippled:
        case FillOpaqueStippled:{
            PixmapPtr pStip = pGC->stipple;
            int stipWidth = pStip->drawable.width;
            int stipHeight = pStip->drawable.height;
    
            if (dstBpp == 1) {
                int alu;
                FbBits *stip;
                FbStride stipStride;
                int stipBpp;
                _X_UNUSED int stipXoff, stipYoff;
    
                if (pGC->fillStyle == FillStippled)
                    alu = FbStipple1Rop(pGC->alu, pGC->fgPixel);
                else
                    alu = FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel, pGC->bgPixel);
                fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff,
                              stipYoff);
                fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff,
                       width, height, stip, stipStride, stipWidth, stipHeight, alu,
                       pPriv->pm, dstBpp, (pGC->patOrg.x + pDrawable->x + dstXoff),
                       pGC->patOrg.y + pDrawable->y - y);
                fbFinishAccess(&pStip->drawable);
            }
            else {
                FbStip *stip;
                FbStride stipStride;
                int stipBpp;
                _X_UNUSED int stipXoff, stipYoff;
                FbBits fgand, fgxor, bgand, bgxor;
    
                fgand = pPriv->and;
                fgxor = pPriv->xor;
                if (pGC->fillStyle == FillStippled) {
                    bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
                    bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
                }
                else {
                    bgand = pPriv->bgand;
                    bgxor = pPriv->bgxor;
                }
    
                fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp,
                                  stipXoff, stipYoff);
                fbStipple(dst + (y + dstYoff) * dstStride, dstStride,
                          (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height,
                          stip, stipStride, stipWidth, stipHeight,
                          pPriv->evenStipple, fgand, fgxor, bgand, bgxor,
                          pGC->patOrg.x + pDrawable->x + dstXoff,
                          pGC->patOrg.y + pDrawable->y - y);
                fbFinishAccess(&pStip->drawable);
            }
            break;
        }
        case FillTiled:{
            PixmapPtr pTile = pGC->tile.pixmap;
            FbBits *tile;
            FbStride tileStride;
            int tileBpp;
            int tileWidth;
            int tileHeight;
            _X_UNUSED int tileXoff, tileYoff;
    
            fbGetDrawable(&pTile->drawable, tile, tileStride, tileBpp, tileXoff,
                          tileYoff);
            tileWidth = pTile->drawable.width;
            tileHeight = pTile->drawable.height;
            fbTile(dst + (y + dstYoff) * dstStride,
                   dstStride,
                   (x + dstXoff) * dstBpp,
                   width * dstBpp, height,
                   tile,
                   tileStride,
                   tileWidth * tileBpp,
                   tileHeight,
                   pGC->alu,
                   pPriv->pm,
                   dstBpp,
                   (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
                   pGC->patOrg.y + pDrawable->y - y);
            fbFinishAccess(&pTile->drawable);
            break;
        }
        }
        fbValidateDrawable(pDrawable);
        fbFinishAccess(pDrawable);
    }
    
    void
    fbSolidBoxClipped(DrawablePtr pDrawable,
                      RegionPtr pClip,
                      int x1, int y1, int x2, int y2, FbBits and, FbBits xor)
    {
        FbBits *dst;
        FbStride dstStride;
        int dstBpp;
        int dstXoff, dstYoff;
        BoxPtr pbox;
        int nbox;
        int partX1, partX2, partY1, partY2;
    
        fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    
        for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip);
             nbox--; pbox++) {
            partX1 = pbox->x1;
            if (partX1 < x1)
                partX1 = x1;
    
            partX2 = pbox->x2;
            if (partX2 > x2)
                partX2 = x2;
    
            if (partX2 <= partX1)
                continue;
    
            partY1 = pbox->y1;
            if (partY1 < y1)
                partY1 = y1;
    
            partY2 = pbox->y2;
            if (partY2 > y2)
                partY2 = y2;
    
            if (partY2 <= partY1)
                continue;
    
    #ifndef FB_ACCESS_WRAPPER
            if (and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp,
                                    partX1 + dstXoff, partY1 + dstYoff,
                                    (partX2 - partX1), (partY2 - partY1), xor))
    #endif
                fbSolid(dst + (partY1 + dstYoff) * dstStride,
                        dstStride,
                        (partX1 + dstXoff) * dstBpp,
                        dstBpp,
                        (partX2 - partX1) * dstBpp, (partY2 - partY1), and, xor);
        }
        fbFinishAccess(pDrawable);
    }