xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

fbfill.c (8808B)


      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 
     29 static void
     30 fbTile(FbBits * dst, FbStride dstStride, int dstX, int width, int height,
     31        FbBits * tile, FbStride tileStride, int tileWidth, int tileHeight,
     32        int alu, FbBits pm, int bpp, int xRot, int yRot)
     33 {
     34     int tileX, tileY;
     35     int widthTmp;
     36     int h, w;
     37     int x, y;
     38 
     39     modulus(-yRot, tileHeight, tileY);
     40     y = 0;
     41     while (height) {
     42         h = tileHeight - tileY;
     43         if (h > height)
     44             h = height;
     45         height -= h;
     46         widthTmp = width;
     47         x = dstX;
     48         modulus(dstX - xRot, tileWidth, tileX);
     49         while (widthTmp) {
     50             w = tileWidth - tileX;
     51             if (w > widthTmp)
     52                 w = widthTmp;
     53             widthTmp -= w;
     54             fbBlt(tile + tileY * tileStride,
     55                   tileStride,
     56                   tileX,
     57                   dst + y * dstStride,
     58                   dstStride, x, w, h, alu, pm, bpp, FALSE, FALSE);
     59             x += w;
     60             tileX = 0;
     61         }
     62         y += h;
     63         tileY = 0;
     64     }
     65 }
     66 
     67 static void
     68 fbStipple(FbBits * dst, FbStride dstStride,
     69           int dstX, int dstBpp,
     70           int width, int height,
     71           FbStip * stip, FbStride stipStride,
     72           int stipWidth, int stipHeight,
     73           FbBits fgand, FbBits fgxor,
     74           FbBits bgand, FbBits bgxor,
     75           int xRot, int yRot)
     76 {
     77     int stipX, stipY, sx;
     78     int widthTmp;
     79     int h, w;
     80     int x, y;
     81 
     82     modulus(-yRot, stipHeight, stipY);
     83     modulus(dstX / dstBpp - xRot, stipWidth, stipX);
     84     y = 0;
     85     while (height) {
     86         h = stipHeight - stipY;
     87         if (h > height)
     88             h = height;
     89         height -= h;
     90         widthTmp = width;
     91         x = dstX;
     92         sx = stipX;
     93         while (widthTmp) {
     94             w = (stipWidth - sx) * dstBpp;
     95             if (w > widthTmp)
     96                 w = widthTmp;
     97             widthTmp -= w;
     98             fbBltOne(stip + stipY * stipStride,
     99                      stipStride,
    100                      sx,
    101                      dst + y * dstStride,
    102                      dstStride, x, dstBpp, w, h, fgand, fgxor, bgand, bgxor);
    103             x += w;
    104             sx = 0;
    105         }
    106         y += h;
    107         stipY = 0;
    108     }
    109 }
    110 
    111 void
    112 fbFill(DrawablePtr pDrawable, GCPtr pGC, int x, int y, int width, int height)
    113 {
    114     FbBits *dst;
    115     FbStride dstStride;
    116     int dstBpp;
    117     int dstXoff, dstYoff;
    118     FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
    119 
    120     fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    121 
    122     switch (pGC->fillStyle) {
    123     case FillSolid:
    124 #ifndef FB_ACCESS_WRAPPER
    125         if (pPriv->and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp,
    126                                        x + dstXoff, y + dstYoff,
    127                                        width, height, pPriv->xor))
    128 #endif
    129             fbSolid(dst + (y + dstYoff) * dstStride,
    130                     dstStride,
    131                     (x + dstXoff) * dstBpp,
    132                     dstBpp, width * dstBpp, height, pPriv->and, pPriv->xor);
    133         break;
    134     case FillStippled:
    135     case FillOpaqueStippled:{
    136         PixmapPtr pStip = pGC->stipple;
    137         int stipWidth = pStip->drawable.width;
    138         int stipHeight = pStip->drawable.height;
    139 
    140         if (dstBpp == 1) {
    141             int alu;
    142             FbBits *stip;
    143             FbStride stipStride;
    144             int stipBpp;
    145             _X_UNUSED int stipXoff, stipYoff;
    146 
    147             if (pGC->fillStyle == FillStippled)
    148                 alu = FbStipple1Rop(pGC->alu, pGC->fgPixel);
    149             else
    150                 alu = FbOpaqueStipple1Rop(pGC->alu, pGC->fgPixel, pGC->bgPixel);
    151             fbGetDrawable(&pStip->drawable, stip, stipStride, stipBpp, stipXoff,
    152                           stipYoff);
    153             fbTile(dst + (y + dstYoff) * dstStride, dstStride, x + dstXoff,
    154                    width, height, stip, stipStride, stipWidth, stipHeight, alu,
    155                    pPriv->pm, dstBpp, (pGC->patOrg.x + pDrawable->x + dstXoff),
    156                    pGC->patOrg.y + pDrawable->y - y);
    157             fbFinishAccess(&pStip->drawable);
    158         }
    159         else {
    160             FbStip *stip;
    161             FbStride stipStride;
    162             int stipBpp;
    163             _X_UNUSED int stipXoff, stipYoff;
    164             FbBits fgand, fgxor, bgand, bgxor;
    165 
    166             fgand = pPriv->and;
    167             fgxor = pPriv->xor;
    168             if (pGC->fillStyle == FillStippled) {
    169                 bgand = fbAnd(GXnoop, (FbBits) 0, FB_ALLONES);
    170                 bgxor = fbXor(GXnoop, (FbBits) 0, FB_ALLONES);
    171             }
    172             else {
    173                 bgand = pPriv->bgand;
    174                 bgxor = pPriv->bgxor;
    175             }
    176 
    177             fbGetStipDrawable(&pStip->drawable, stip, stipStride, stipBpp,
    178                               stipXoff, stipYoff);
    179             fbStipple(dst + (y + dstYoff) * dstStride, dstStride,
    180                       (x + dstXoff) * dstBpp, dstBpp, width * dstBpp, height,
    181                       stip, stipStride, stipWidth, stipHeight,
    182                       fgand, fgxor, bgand, bgxor,
    183                       pGC->patOrg.x + pDrawable->x + dstXoff,
    184                       pGC->patOrg.y + pDrawable->y - y);
    185             fbFinishAccess(&pStip->drawable);
    186         }
    187         break;
    188     }
    189     case FillTiled:{
    190         PixmapPtr pTile = pGC->tile.pixmap;
    191         FbBits *tile;
    192         FbStride tileStride;
    193         int tileBpp;
    194         int tileWidth;
    195         int tileHeight;
    196         _X_UNUSED int tileXoff, tileYoff;
    197 
    198         fbGetDrawable(&pTile->drawable, tile, tileStride, tileBpp, tileXoff,
    199                       tileYoff);
    200         tileWidth = pTile->drawable.width;
    201         tileHeight = pTile->drawable.height;
    202         fbTile(dst + (y + dstYoff) * dstStride,
    203                dstStride,
    204                (x + dstXoff) * dstBpp,
    205                width * dstBpp, height,
    206                tile,
    207                tileStride,
    208                tileWidth * tileBpp,
    209                tileHeight,
    210                pGC->alu,
    211                pPriv->pm,
    212                dstBpp,
    213                (pGC->patOrg.x + pDrawable->x + dstXoff) * dstBpp,
    214                pGC->patOrg.y + pDrawable->y - y);
    215         fbFinishAccess(&pTile->drawable);
    216         break;
    217     }
    218     }
    219     fbValidateDrawable(pDrawable);
    220     fbFinishAccess(pDrawable);
    221 }
    222 
    223 void
    224 fbSolidBoxClipped(DrawablePtr pDrawable,
    225                   RegionPtr pClip,
    226                   int x1, int y1, int x2, int y2, FbBits and, FbBits xor)
    227 {
    228     FbBits *dst;
    229     FbStride dstStride;
    230     int dstBpp;
    231     int dstXoff, dstYoff;
    232     BoxPtr pbox;
    233     int nbox;
    234     int partX1, partX2, partY1, partY2;
    235 
    236     fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
    237 
    238     for (nbox = RegionNumRects(pClip), pbox = RegionRects(pClip);
    239          nbox--; pbox++) {
    240         partX1 = pbox->x1;
    241         if (partX1 < x1)
    242             partX1 = x1;
    243 
    244         partX2 = pbox->x2;
    245         if (partX2 > x2)
    246             partX2 = x2;
    247 
    248         if (partX2 <= partX1)
    249             continue;
    250 
    251         partY1 = pbox->y1;
    252         if (partY1 < y1)
    253             partY1 = y1;
    254 
    255         partY2 = pbox->y2;
    256         if (partY2 > y2)
    257             partY2 = y2;
    258 
    259         if (partY2 <= partY1)
    260             continue;
    261 
    262 #ifndef FB_ACCESS_WRAPPER
    263         if (and || !pixman_fill((uint32_t *) dst, dstStride, dstBpp,
    264                                 partX1 + dstXoff, partY1 + dstYoff,
    265                                 (partX2 - partX1), (partY2 - partY1), xor))
    266 #endif
    267             fbSolid(dst + (partY1 + dstYoff) * dstStride,
    268                     dstStride,
    269                     (partX1 + dstXoff) * dstBpp,
    270                     dstBpp,
    271                     (partX2 - partX1) * dstBpp, (partY2 - partY1), and, xor);
    272     }
    273     fbFinishAccess(pDrawable);
    274 }