Back to index

lightning-sunbird  0.9+nobinonly
icblt.c
Go to the documentation of this file.
00001 /*
00002  * Id: $
00003  *
00004  * Copyright © 1998 Keith Packard
00005  *
00006  * Permission to use, copy, modify, distribute, and sell this software and its
00007  * documentation for any purpose is hereby granted without fee, provided that
00008  * the above copyright notice appear in all copies and that both that
00009  * copyright notice and this permission notice appear in supporting
00010  * documentation, and that the name of Keith Packard not be used in
00011  * advertising or publicity pertaining to distribution of the software without
00012  * specific, written prior permission.  Keith Packard makes no
00013  * representations about the suitability of this software for any purpose.  It
00014  * is provided "as is" without express or implied warranty.
00015  *
00016  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
00017  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
00018  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
00019  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
00020  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
00021  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00022  * PERFORMANCE OF THIS SOFTWARE.
00023  */
00024 
00025 #include "pixman-xserver-compat.h"
00026 
00027 #define InitializeShifts(sx,dx,ls,rs) { \
00028     if (sx != dx) { \
00029        if (sx > dx) { \
00030            ls = sx - dx; \
00031            rs = FB_UNIT - ls; \
00032        } else { \
00033            rs = dx - sx; \
00034            ls = FB_UNIT - rs; \
00035        } \
00036     } \
00037 }
00038 
00039 void
00040 fbBlt (FbBits   *srcLine,
00041        FbStride      srcStride,
00042        int    srcX,
00043        
00044        FbBits   *dstLine,
00045        FbStride dstStride,
00046        int    dstX,
00047        
00048        int    width, 
00049        int    height,
00050        
00051        int    alu,
00052        FbBits pm,
00053        int    bpp,
00054        
00055        Bool   reverse,
00056        Bool   upsidedown)
00057 {
00058     FbBits  *src, *dst;
00059     int           leftShift, rightShift;
00060     FbBits  startmask, endmask;
00061     FbBits  bits, bits1;
00062     int           n, nmiddle;
00063     Bool    destInvarient;
00064     int           startbyte, endbyte;
00065     FbDeclareMergeRop ();
00066  
00067     /* are we just copying multiples of 8 bits?  if so, run, forrest, run!
00068        the memcpy()'s should be pluggable ala mplayer|xine - perhaps we can get
00069        one of the above to give up their code for us.
00070      */
00071     if((pm==FB_ALLONES) && (alu==GXcopy) && !reverse && (srcX&7)==0 && (dstX&7)==0 && (width&7)==0)
00072     {
00073               CARD8 *isrc=(CARD8 *)srcLine;
00074               CARD8 *idst=(CARD8 *)dstLine;
00075               int sstride=srcStride*sizeof(FbBits);
00076               int dstride=dstStride*sizeof(FbBits);
00077               int j;
00078               width>>=3;
00079               isrc+=(srcX>>3);
00080               idst+=(dstX>>3);
00081               if(!upsidedown)
00082                      for(j=0;j<height;j++)
00083                             memcpy(idst+j*dstride, isrc+j*sstride, width);
00084               else
00085                      for(j=(height-1);j>=0;j--)
00086                             memcpy(idst+j*dstride, isrc+j*sstride, width);
00087        
00088               return;
00089     }
00090     
00091 #ifdef FB_24BIT
00092     if (bpp == 24 && !FbCheck24Pix (pm))
00093     {
00094        fbBlt24 (srcLine, srcStride, srcX, dstLine, dstStride, dstX,
00095                width, height, alu, pm, reverse, upsidedown);
00096        return;
00097     }
00098 #endif
00099     FbInitializeMergeRop(alu, pm);
00100     destInvarient = FbDestInvarientMergeRop();
00101     if (upsidedown)
00102     {
00103        srcLine += (height - 1) * (srcStride);
00104        dstLine += (height - 1) * (dstStride);
00105        srcStride = -srcStride;
00106        dstStride = -dstStride;
00107     }
00108     FbMaskBitsBytes (dstX, width, destInvarient, startmask, startbyte,
00109                    nmiddle, endmask, endbyte);
00110     if (reverse)
00111     {
00112        srcLine += ((srcX + width - 1) >> FB_SHIFT) + 1;
00113        dstLine += ((dstX + width - 1) >> FB_SHIFT) + 1;
00114        srcX = (srcX + width - 1) & FB_MASK;
00115        dstX = (dstX + width - 1) & FB_MASK;
00116     }
00117     else
00118     {
00119        srcLine += srcX >> FB_SHIFT;
00120        dstLine += dstX >> FB_SHIFT;
00121        srcX &= FB_MASK;
00122        dstX &= FB_MASK;
00123     }
00124     if (srcX == dstX)
00125     {
00126        while (height--)
00127        {
00128            src = srcLine;
00129            srcLine += srcStride;
00130            dst = dstLine;
00131            dstLine += dstStride;
00132            if (reverse)
00133            {
00134               if (endmask)
00135               {
00136                   bits = *--src;
00137                   --dst;
00138                   FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
00139               }
00140               n = nmiddle;
00141               if (destInvarient)
00142               {
00143                   while (n--)
00144                      *--dst = FbDoDestInvarientMergeRop(*--src);
00145               }
00146               else
00147               {
00148                   while (n--)
00149                   {
00150                      bits = *--src;
00151                      --dst;
00152                      *dst = FbDoMergeRop (bits, *dst);
00153                   }
00154               }
00155               if (startmask)
00156               {
00157                   bits = *--src;
00158                   --dst;
00159                   FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
00160               }
00161            }
00162            else
00163            {
00164               if (startmask)
00165               {
00166                   bits = *src++;
00167                   FbDoLeftMaskByteMergeRop(dst, bits, startbyte, startmask);
00168                   dst++;
00169               }
00170               n = nmiddle;
00171               if (destInvarient)
00172               {
00173 #if 0
00174                   /*
00175                    * This provides some speedup on screen->screen blts
00176                    * over the PCI bus, usually about 10%.  But fb
00177                    * isn't usually used for this operation...
00178                    */
00179                   if (_ca2 + 1 == 0 && _cx2 == 0)
00180                   {
00181                      FbBits t1, t2, t3, t4;
00182                      while (n >= 4)
00183                      {
00184                          t1 = *src++;
00185                          t2 = *src++;
00186                          t3 = *src++;
00187                          t4 = *src++;
00188                          *dst++ = t1;
00189                          *dst++ = t2;
00190                          *dst++ = t3;
00191                          *dst++ = t4;
00192                          n -= 4;
00193                      }
00194                   }
00195 #endif
00196                   while (n--)
00197                      *dst++ = FbDoDestInvarientMergeRop(*src++);
00198               }
00199               else
00200               {
00201                   while (n--)
00202                   {
00203                      bits = *src++;
00204                      *dst = FbDoMergeRop (bits, *dst);
00205                      dst++;
00206                   }
00207               }
00208               if (endmask)
00209               {
00210                   bits = *src;
00211                   FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
00212               }
00213            }
00214        }
00215     }
00216     else
00217     {
00218        if (srcX > dstX)
00219        {
00220            leftShift = srcX - dstX;
00221            rightShift = FB_UNIT - leftShift;
00222        }
00223        else
00224        {
00225            rightShift = dstX - srcX;
00226            leftShift = FB_UNIT - rightShift;
00227        }
00228        while (height--)
00229        {
00230            src = srcLine;
00231            srcLine += srcStride;
00232            dst = dstLine;
00233            dstLine += dstStride;
00234            
00235            bits1 = 0;
00236            if (reverse)
00237            {
00238               if (srcX < dstX)
00239                   bits1 = *--src;
00240               if (endmask)
00241               {
00242                   bits = FbScrRight(bits1, rightShift); 
00243                   if (FbScrRight(endmask, leftShift))
00244                   {
00245                      bits1 = *--src;
00246                      bits |= FbScrLeft(bits1, leftShift);
00247                   }
00248                   --dst;
00249                   FbDoRightMaskByteMergeRop(dst, bits, endbyte, endmask);
00250               }
00251               n = nmiddle;
00252               if (destInvarient)
00253               {
00254                   while (n--)
00255                   {
00256                      bits = FbScrRight(bits1, rightShift); 
00257                      bits1 = *--src;
00258                      bits |= FbScrLeft(bits1, leftShift);
00259                      --dst;
00260                      *dst = FbDoDestInvarientMergeRop(bits);
00261                   }
00262               }
00263               else
00264               {
00265                   while (n--)
00266                   {
00267                      bits = FbScrRight(bits1, rightShift); 
00268                      bits1 = *--src;
00269                      bits |= FbScrLeft(bits1, leftShift);
00270                      --dst;
00271                      *dst = FbDoMergeRop(bits, *dst);
00272                   }
00273               }
00274               if (startmask)
00275               {
00276                   bits = FbScrRight(bits1, rightShift); 
00277                   if (FbScrRight(startmask, leftShift))
00278                   {
00279                      bits1 = *--src;
00280                      bits |= FbScrLeft(bits1, leftShift);
00281                   }
00282                   --dst;
00283                   FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
00284               }
00285            }
00286            else
00287            {
00288               if (srcX > dstX)
00289                   bits1 = *src++;
00290               if (startmask)
00291               {
00292                   bits = FbScrLeft(bits1, leftShift); 
00293                   bits1 = *src++;
00294                   bits |= FbScrRight(bits1, rightShift);
00295                   FbDoLeftMaskByteMergeRop (dst, bits, startbyte, startmask);
00296                   dst++;
00297               }
00298               n = nmiddle;
00299               if (destInvarient)
00300               {
00301                   while (n--)
00302                   {
00303                      bits = FbScrLeft(bits1, leftShift); 
00304                      bits1 = *src++;
00305                      bits |= FbScrRight(bits1, rightShift);
00306                      *dst = FbDoDestInvarientMergeRop(bits);
00307                      dst++;
00308                   }
00309               }
00310               else
00311               {
00312                   while (n--)
00313                   {
00314                      bits = FbScrLeft(bits1, leftShift); 
00315                      bits1 = *src++;
00316                      bits |= FbScrRight(bits1, rightShift);
00317                      *dst = FbDoMergeRop(bits, *dst);
00318                      dst++;
00319                   }
00320               }
00321               if (endmask)
00322               {
00323                   bits = FbScrLeft(bits1, leftShift); 
00324                   if (FbScrLeft(endmask, rightShift))
00325                   {
00326                      bits1 = *src;
00327                      bits |= FbScrRight(bits1, rightShift);
00328                   }
00329                   FbDoRightMaskByteMergeRop (dst, bits, endbyte, endmask);
00330               }
00331            }
00332        }
00333     }
00334 }
00335 
00336 #ifdef FB_24BIT
00337 
00338 #undef DEBUG_BLT24
00339 #ifdef DEBUG_BLT24
00340 
00341 static unsigned long
00342 getPixel (char *src, int x)
00343 {
00344     unsigned long   l;
00345 
00346     l = 0;
00347     memcpy (&l, src + x * 3, 3);
00348     return l;
00349 }
00350 #endif
00351 
00352 static void
00353 fbBlt24Line (FbBits      *src,
00354             int          srcX,
00355 
00356             FbBits       *dst,
00357             int          dstX,
00358 
00359             int          width,
00360 
00361             int          alu,
00362             FbBits       pm,
00363         
00364             Bool         reverse)
00365 {
00366 #ifdef DEBUG_BLT24
00367     char    *origDst = (char *) dst;
00368     FbBits  *origLine = dst + ((dstX >> FB_SHIFT) - 1);
00369     int           origNlw = ((width + FB_MASK) >> FB_SHIFT) + 3;
00370     int           origX = dstX / 24;
00371 #endif
00372     
00373     int           leftShift, rightShift;
00374     FbBits  startmask, endmask;
00375     int           n;
00376     
00377     FbBits  bits, bits1;
00378     FbBits  mask;
00379 
00380     int           rot;
00381     FbDeclareMergeRop ();
00382     
00383     FbInitializeMergeRop (alu, FB_ALLONES);
00384     FbMaskBits(dstX, width, startmask, n, endmask);
00385 #ifdef DEBUG_BLT24
00386     ErrorF ("dstX %d width %d reverse %d\n", dstX, width, reverse);
00387 #endif
00388     if (reverse)
00389     {
00390        src += ((srcX + width - 1) >> FB_SHIFT) + 1;
00391        dst += ((dstX + width - 1) >> FB_SHIFT) + 1;
00392        rot = FbFirst24Rot (((dstX + width - 8) & FB_MASK));
00393        rot = FbPrev24Rot(rot);
00394 #ifdef DEBUG_BLT24
00395        ErrorF ("dstX + width - 8: %d rot: %d\n", (dstX + width - 8) & FB_MASK, rot);
00396 #endif
00397        srcX = (srcX + width - 1) & FB_MASK;
00398        dstX = (dstX + width - 1) & FB_MASK;
00399     }
00400     else
00401     {
00402        src += srcX >> FB_SHIFT;
00403        dst += dstX >> FB_SHIFT;
00404        srcX &= FB_MASK;
00405        dstX &= FB_MASK;
00406        rot = FbFirst24Rot (dstX);
00407 #ifdef DEBUG_BLT24
00408        ErrorF ("dstX: %d rot: %d\n", dstX, rot);
00409 #endif
00410     }
00411     mask = FbRot24(pm,rot);
00412 #ifdef DEBUG_BLT24
00413     ErrorF ("pm 0x%x mask 0x%x\n", pm, mask);
00414 #endif
00415     if (srcX == dstX)
00416     {
00417        if (reverse)
00418        {
00419            if (endmask)
00420            {
00421               bits = *--src;
00422               --dst;
00423               *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
00424               mask = FbPrev24Pix (mask);
00425            }
00426            while (n--)
00427            {
00428               bits = *--src;
00429               --dst;
00430               *dst = FbDoMaskMergeRop (bits, *dst, mask);
00431               mask = FbPrev24Pix (mask);
00432            }
00433            if (startmask)
00434            {
00435               bits = *--src;
00436               --dst;
00437               *dst = FbDoMaskMergeRop(bits, *dst, mask & startmask);
00438            }
00439        }
00440        else
00441        {
00442            if (startmask)
00443            {
00444               bits = *src++;
00445               *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
00446               dst++;
00447               mask = FbNext24Pix(mask);
00448            }
00449            while (n--)
00450            {
00451               bits = *src++;
00452               *dst = FbDoMaskMergeRop (bits, *dst, mask);
00453               dst++;
00454               mask = FbNext24Pix(mask);
00455            }
00456            if (endmask)
00457            {
00458               bits = *src;
00459               *dst = FbDoMaskMergeRop(bits, *dst, mask & endmask);
00460            }
00461        }
00462     }
00463     else
00464     {
00465        if (srcX > dstX)
00466        {
00467            leftShift = srcX - dstX;
00468            rightShift = FB_UNIT - leftShift;
00469        }
00470        else
00471        {
00472            rightShift = dstX - srcX;
00473            leftShift = FB_UNIT - rightShift;
00474        }
00475        
00476        bits1 = 0;
00477        if (reverse)
00478        {
00479            if (srcX < dstX)
00480               bits1 = *--src;
00481            if (endmask)
00482            {
00483               bits = FbScrRight(bits1, rightShift); 
00484               if (FbScrRight(endmask, leftShift))
00485               {
00486                   bits1 = *--src;
00487                   bits |= FbScrLeft(bits1, leftShift);
00488               }
00489               --dst;
00490               *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
00491               mask = FbPrev24Pix(mask);
00492            }
00493            while (n--)
00494            {
00495               bits = FbScrRight(bits1, rightShift); 
00496               bits1 = *--src;
00497               bits |= FbScrLeft(bits1, leftShift);
00498               --dst;
00499               *dst = FbDoMaskMergeRop(bits, *dst, mask);
00500               mask = FbPrev24Pix(mask);
00501            }
00502            if (startmask)
00503            {
00504               bits = FbScrRight(bits1, rightShift); 
00505               if (FbScrRight(startmask, leftShift))
00506               {
00507                   bits1 = *--src;
00508                   bits |= FbScrLeft(bits1, leftShift);
00509               }
00510               --dst;
00511               *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
00512            }
00513        }
00514        else
00515        {
00516            if (srcX > dstX)
00517               bits1 = *src++;
00518            if (startmask)
00519            {
00520               bits = FbScrLeft(bits1, leftShift); 
00521               bits1 = *src++;
00522               bits |= FbScrRight(bits1, rightShift);
00523               *dst = FbDoMaskMergeRop (bits, *dst, mask & startmask);
00524               dst++;
00525               mask = FbNext24Pix(mask);
00526            }
00527            while (n--)
00528            {
00529               bits = FbScrLeft(bits1, leftShift); 
00530               bits1 = *src++;
00531               bits |= FbScrRight(bits1, rightShift);
00532               *dst = FbDoMaskMergeRop(bits, *dst, mask);
00533               dst++;
00534               mask = FbNext24Pix(mask);
00535            }
00536            if (endmask)
00537            {
00538               bits = FbScrLeft(bits1, leftShift); 
00539               if (FbScrLeft(endmask, rightShift))
00540               {
00541                   bits1 = *src;
00542                   bits |= FbScrRight(bits1, rightShift);
00543               }
00544               *dst = FbDoMaskMergeRop (bits, *dst, mask & endmask);
00545            }
00546        }
00547     }
00548 #ifdef DEBUG_BLT24
00549     {
00550        int firstx, lastx, x;
00551 
00552        firstx = origX;
00553        if (firstx)
00554            firstx--;
00555        lastx = origX + width/24 + 1;
00556        for (x = firstx; x <= lastx; x++)
00557            ErrorF ("%06x ", getPixel (origDst, x));
00558        ErrorF ("\n");
00559        while (origNlw--)
00560            ErrorF ("%08x ", *origLine++);
00561        ErrorF ("\n");
00562     }
00563 #endif
00564 }
00565 
00566 void
00567 fbBlt24 (FbBits          *srcLine,
00568         FbStride   srcStride,
00569         int       srcX,
00570 
00571         FbBits           *dstLine,
00572         FbStride   dstStride,
00573         int       dstX,
00574 
00575         int       width, 
00576         int       height,
00577 
00578         int       alu,
00579         FbBits           pm,
00580 
00581         Bool      reverse,
00582         Bool      upsidedown)
00583 {
00584     if (upsidedown)
00585     {
00586        srcLine += (height-1) * srcStride;
00587        dstLine += (height-1) * dstStride;
00588        srcStride = -srcStride;
00589        dstStride = -dstStride;
00590     }
00591     while (height--)
00592     {
00593        fbBlt24Line (srcLine, srcX, dstLine, dstX, width, alu, pm, reverse);
00594        srcLine += srcStride;
00595        dstLine += dstStride;
00596     }
00597 #ifdef DEBUG_BLT24
00598     ErrorF ("\n");
00599 #endif
00600 }
00601 #endif /* FB_24BIT */
00602 
00603 #if FB_SHIFT == FB_STIP_SHIFT + 1
00604 
00605 /*
00606  * Could be generalized to FB_SHIFT > FB_STIP_SHIFT + 1 by
00607  * creating an ring of values stepped through for each line
00608  */
00609 
00610 void
00611 fbBltOdd (FbBits    *srcLine,
00612          FbStride  srcStrideEven,
00613          FbStride  srcStrideOdd,
00614          int      srcXEven,
00615          int      srcXOdd,
00616 
00617          FbBits    *dstLine,
00618          FbStride  dstStrideEven,
00619          FbStride  dstStrideOdd,
00620          int      dstXEven,
00621          int      dstXOdd,
00622 
00623          int      width,
00624          int      height,
00625 
00626          int      alu,
00627          FbBits    pm,
00628          int      bpp)
00629 {
00630     FbBits  *src;
00631     int           leftShiftEven, rightShiftEven;
00632     FbBits  startmaskEven, endmaskEven;
00633     int           nmiddleEven;
00634     
00635     FbBits  *dst;
00636     int           leftShiftOdd, rightShiftOdd;
00637     FbBits  startmaskOdd, endmaskOdd;
00638     int           nmiddleOdd;
00639 
00640     int           leftShift, rightShift;
00641     FbBits  startmask, endmask;
00642     int           nmiddle;
00643     
00644     int           srcX, dstX;
00645     
00646     FbBits  bits, bits1;
00647     int           n;
00648     
00649     Bool    destInvarient;
00650     Bool    even;
00651     FbDeclareMergeRop ();
00652 
00653     FbInitializeMergeRop (alu, pm);
00654     destInvarient = FbDestInvarientMergeRop();
00655 
00656     srcLine += srcXEven >> FB_SHIFT;
00657     dstLine += dstXEven >> FB_SHIFT;
00658     srcXEven &= FB_MASK;
00659     dstXEven &= FB_MASK;
00660     srcXOdd &= FB_MASK;
00661     dstXOdd &= FB_MASK;
00662 
00663     FbMaskBits(dstXEven, width, startmaskEven, nmiddleEven, endmaskEven);
00664     FbMaskBits(dstXOdd, width, startmaskOdd, nmiddleOdd, endmaskOdd);
00665     
00666     even = TRUE;
00667     InitializeShifts(srcXEven, dstXEven, leftShiftEven, rightShiftEven);
00668     InitializeShifts(srcXOdd, dstXOdd, leftShiftOdd, rightShiftOdd);
00669     while (height--)
00670     {
00671        src = srcLine;
00672        dst = dstLine;
00673        if (even)
00674        {
00675            srcX = srcXEven;
00676            dstX = dstXEven;
00677            startmask = startmaskEven;
00678            endmask = endmaskEven;
00679            nmiddle = nmiddleEven;
00680            leftShift = leftShiftEven;
00681            rightShift = rightShiftEven;
00682            srcLine += srcStrideEven;
00683            dstLine += dstStrideEven;
00684            even = FALSE;
00685        }
00686        else
00687        {
00688            srcX = srcXOdd;
00689            dstX = dstXOdd;
00690            startmask = startmaskOdd;
00691            endmask = endmaskOdd;
00692            nmiddle = nmiddleOdd;
00693            leftShift = leftShiftOdd;
00694            rightShift = rightShiftOdd;
00695            srcLine += srcStrideOdd;
00696            dstLine += dstStrideOdd;
00697            even = TRUE;
00698        }
00699        if (srcX == dstX)
00700        {
00701            if (startmask)
00702            {
00703               bits = *src++;
00704               *dst = FbDoMaskMergeRop (bits, *dst, startmask);
00705               dst++;
00706            }
00707            n = nmiddle;
00708            if (destInvarient)
00709            {
00710               while (n--)
00711               {
00712                   bits = *src++;
00713                   *dst = FbDoDestInvarientMergeRop(bits);
00714                   dst++;
00715               }
00716            }
00717            else
00718            {
00719               while (n--)
00720               {
00721                   bits = *src++;
00722                   *dst = FbDoMergeRop (bits, *dst);
00723                   dst++;
00724               }
00725            }
00726            if (endmask)
00727            {
00728               bits = *src;
00729               *dst = FbDoMaskMergeRop(bits, *dst, endmask);
00730            }
00731        }
00732        else
00733        {
00734            bits = 0;
00735            if (srcX > dstX)
00736               bits = *src++;
00737            if (startmask)
00738            {
00739               bits1 = FbScrLeft(bits, leftShift);
00740               bits = *src++;
00741               bits1 |= FbScrRight(bits, rightShift);
00742               *dst = FbDoMaskMergeRop (bits1, *dst, startmask);
00743               dst++;
00744            }
00745            n = nmiddle;
00746            if (destInvarient)
00747            {
00748               while (n--)
00749               {
00750                   bits1 = FbScrLeft(bits, leftShift);
00751                   bits = *src++;
00752                   bits1 |= FbScrRight(bits, rightShift);
00753                   *dst = FbDoDestInvarientMergeRop(bits1);
00754                   dst++;
00755               }
00756            }
00757            else
00758            {
00759               while (n--)
00760               {
00761                   bits1 = FbScrLeft(bits, leftShift);
00762                   bits = *src++;
00763                   bits1 |= FbScrRight(bits, rightShift);
00764                   *dst = FbDoMergeRop(bits1, *dst);
00765                   dst++;
00766               }
00767            }
00768            if (endmask)
00769            {
00770               bits1 = FbScrLeft(bits, leftShift);
00771               if (FbScrLeft(endmask, rightShift))
00772               {
00773                   bits = *src;
00774                   bits1 |= FbScrRight(bits, rightShift);
00775               }
00776               *dst = FbDoMaskMergeRop (bits1, *dst, endmask);
00777            }
00778        }
00779     }
00780 }
00781 
00782 #ifdef FB_24BIT
00783 void
00784 fbBltOdd24 (FbBits   *srcLine,
00785            FbStride  srcStrideEven,
00786            FbStride  srcStrideOdd,
00787            int              srcXEven,
00788            int              srcXOdd,
00789 
00790            FbBits    *dstLine,
00791            FbStride  dstStrideEven,
00792            FbStride  dstStrideOdd,
00793            int              dstXEven,
00794            int              dstXOdd,
00795 
00796            int              width,
00797            int              height,
00798 
00799            int              alu,
00800            FbBits    pm)
00801 {
00802     Bool    even = TRUE;
00803     
00804     while (height--)
00805     {
00806        if (even)
00807        {
00808            fbBlt24Line (srcLine, srcXEven, dstLine, dstXEven,
00809                       width, alu, pm, FALSE);
00810            srcLine += srcStrideEven;
00811            dstLine += dstStrideEven;
00812            even = FALSE;
00813        }
00814        else
00815        {
00816            fbBlt24Line (srcLine, srcXOdd, dstLine, dstXOdd,
00817                       width, alu, pm, FALSE);
00818            srcLine += srcStrideOdd;
00819            dstLine += dstStrideOdd;
00820            even = TRUE;
00821        }
00822     }
00823 #if 0
00824     fprintf (stderr, "\n");
00825 #endif
00826 }
00827 #endif
00828 
00829 #endif
00830 
00831 #if FB_STIP_SHIFT != FB_SHIFT
00832 void
00833 fbSetBltOdd (FbStip  *stip,
00834             FbStride stipStride,
00835             int      srcX,
00836             FbBits   **bits,
00837             FbStride *strideEven,
00838             FbStride *strideOdd,
00839             int      *srcXEven,
00840             int      *srcXOdd)
00841 {
00842     int           srcAdjust;
00843     int           strideAdjust;
00844 
00845     /*
00846      * bytes needed to align source
00847      */
00848     srcAdjust = (((int) stip) & (FB_MASK >> 3));
00849     /*
00850      * FbStip units needed to align stride
00851      */
00852     strideAdjust = stipStride & (FB_MASK >> FB_STIP_SHIFT);
00853 
00854     *bits = (FbBits *) ((char *) stip - srcAdjust);
00855     if (srcAdjust)
00856     {
00857        *strideEven = FbStipStrideToBitsStride (stipStride + 1);
00858        *strideOdd = FbStipStrideToBitsStride (stipStride);
00859 
00860        *srcXEven = srcX + (srcAdjust << 3);
00861        *srcXOdd = srcX + (srcAdjust << 3) - (strideAdjust << FB_STIP_SHIFT);
00862     }
00863     else
00864     {
00865        *strideEven = FbStipStrideToBitsStride (stipStride);
00866        *strideOdd = FbStipStrideToBitsStride (stipStride + 1);
00867        
00868        *srcXEven = srcX;
00869        *srcXOdd = srcX + (strideAdjust << FB_STIP_SHIFT);
00870     }
00871 }
00872 #endif
00873 
00874 void
00875 fbBltStip (FbStip   *src,
00876           FbStride srcStride,          /* in FbStip units, not FbBits units */
00877           int     srcX,
00878           
00879           FbStip   *dst,
00880           FbStride dstStride,          /* in FbStip units, not FbBits units */
00881           int     dstX,
00882 
00883           int     width, 
00884           int     height,
00885 
00886           int     alu,
00887           FbBits   pm,
00888           int     bpp)
00889 {
00890 #if FB_STIP_SHIFT != FB_SHIFT
00891     if (FB_STIP_ODDSTRIDE(srcStride) || FB_STIP_ODDPTR(src) ||
00892        FB_STIP_ODDSTRIDE(dstStride) || FB_STIP_ODDPTR(dst))
00893     {
00894        FbStride    srcStrideEven, srcStrideOdd;
00895        FbStride    dstStrideEven, dstStrideOdd;
00896        int        srcXEven, srcXOdd;
00897        int        dstXEven, dstXOdd;
00898        FbBits     *s, *d;
00899        int        sx, dx;
00900        
00901        src += srcX >> FB_STIP_SHIFT;
00902        srcX &= FB_STIP_MASK;
00903        dst += dstX >> FB_STIP_SHIFT;
00904        dstX &= FB_STIP_MASK;
00905        
00906        fbSetBltOdd (src, srcStride, srcX,
00907                    &s,
00908                    &srcStrideEven, &srcStrideOdd,
00909                    &srcXEven, &srcXOdd);
00910                    
00911        fbSetBltOdd (dst, dstStride, dstX,
00912                    &d,
00913                    &dstStrideEven, &dstStrideOdd,
00914                    &dstXEven, &dstXOdd);
00915                    
00916 #ifdef FB_24BIT
00917        if (bpp == 24 && !FbCheck24Pix (pm))
00918        {
00919            fbBltOdd24  (s, srcStrideEven, srcStrideOdd,
00920                       srcXEven, srcXOdd,
00921 
00922                       d, dstStrideEven, dstStrideOdd,
00923                       dstXEven, dstXOdd,
00924 
00925                       width, height, alu, pm);
00926        }
00927        else
00928 #endif
00929        {
00930            fbBltOdd (s, srcStrideEven, srcStrideOdd,
00931                     srcXEven, srcXOdd,
00932     
00933                     d, dstStrideEven, dstStrideOdd,
00934                     dstXEven, dstXOdd,
00935     
00936                     width, height, alu, pm, bpp);
00937        }
00938     }
00939     else
00940 #endif
00941     {
00942        fbBlt ((FbBits *) src, FbStipStrideToBitsStride (srcStride), 
00943               srcX, 
00944               (FbBits *) dst, FbStipStrideToBitsStride (dstStride), 
00945               dstX, 
00946               width, height,
00947               alu, pm, bpp, FALSE, FALSE);
00948     }
00949 }