home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / x / xibm.zip / ppc / ppcBitmap.c < prev    next >
C/C++ Source or Header  |  1991-12-12  |  8KB  |  318 lines

  1. /*
  2.  * Copyright IBM Corporation 1987,1988,1989
  3.  *
  4.  * All Rights Reserved
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software and its
  7.  * documentation for any purpose and without fee is hereby granted,
  8.  * provided that the above copyright notice appear in all copies and that 
  9.  * both that copyright notice and this permission notice appear in
  10.  * supporting documentation, and that the name of IBM not be
  11.  * used in advertising or publicity pertaining to distribution of the
  12.  * software without specific, written prior permission.
  13.  *
  14.  * IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  15.  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  16.  * IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  17.  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  18.  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  19.  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  20.  * SOFTWARE.
  21.  *
  22. */
  23.  
  24. #include "X.h"
  25. #include "pixmap.h"
  26. #include "pixmapstr.h"
  27.  
  28. #include "mfb.h"
  29. #include "maskbits.h"
  30.  
  31. #include "OScompiler.h"
  32.  
  33. /* ppcQuickBlt -- a quick and dirty bitblit routine
  34.  * copies from psrcBase(xSrc, ySrc) to pdstBase(xDst, yDst) an array of bits
  35.  * w wide by h high.  It is assumed that psrcBase and pdstBase point at 
  36.  * things reasonable to bitblt between. It is assumed that all clipping has
  37.  * been done.  It is also assumed that the rectangle fits on the destination
  38.  * (that is, that (pdstBase + (yDst * h) + w) is a bit in the destination).
  39.  * This routine does no error-checking of any type, CAVEAT HACKER 
  40.  */
  41. void
  42. ppcQuickBlt(psrcBase, pdstBase, xSrc, ySrc, xDst, yDst, w, h, wSrc, wDst)
  43.     int *psrcBase, *pdstBase,    /* first bits in pixmaps */
  44.          xSrc, ySrc,        /* origin of source */
  45.      xDst, yDst,        /* origin for destination */
  46.      w,            /* width to blt  */
  47.      h,            /* height to blt */
  48.      wSrc, wDst;        /* width of pixmaps */
  49. {
  50.  
  51.     int *psrcLine, *pdstLine;
  52.     int xdir, ydir;
  53.     int nl, startmask, endmask, nlMiddle, *psrc, *pdst, tmpSrc;
  54.  
  55.     if (psrcBase + wSrc * h < pdstBase ||
  56.        pdstBase + wDst * h < psrcBase)
  57.     {
  58.     /* the areas don't overlap  right and down is fine */
  59.     xdir = ydir = 1;
  60.     }
  61.     else if (ySrc < yDst) /* move right and up */
  62.     {
  63.     xdir = 1;
  64.     ydir = -1;
  65.     }
  66.     else if (ySrc > yDst) /* move right and down */
  67.     {
  68.     xdir = 1;
  69.     ydir = 1;
  70.     }
  71.     else if (xSrc < xDst) /* move left and down */
  72.     {
  73.     xdir = -1;
  74.     ydir = 1;
  75.     }
  76.     else /* if xSrc <= xDst */ /* move right and down */
  77.     {
  78.     xdir = 1;
  79.     ydir = 1;
  80.     }
  81.  
  82.     if (ydir == -1) /* start at last scanline of rectangle */
  83.     {
  84.     psrcLine = psrcBase + (((ySrc + h) -1) * wSrc);
  85.     pdstLine = pdstBase + (((yDst + h) -1) * wDst);
  86.     wSrc = -wSrc;
  87.     wDst = -wDst;
  88.     }
  89.     else /* start at first scanline */
  90.     {
  91.     psrcLine = psrcBase + (ySrc * wSrc);
  92.     pdstLine = pdstBase + (yDst * wDst);
  93.     }
  94.  
  95.     /* x direction doesn't matter for < 1 longword */
  96.     if (w <= 32)
  97.     {
  98.     int srcBit, dstBit;    /* bit offset of src and dst */
  99.  
  100.     pdstLine += (xDst >> 5);
  101.     psrcLine += (xSrc >> 5);
  102.     psrc = psrcLine;
  103.     pdst = pdstLine;
  104.  
  105.     srcBit = xSrc & 0x1f;
  106.     dstBit = xDst & 0x1f;
  107.  
  108.     while ( h-- )
  109.     {
  110.         getbits(psrc, srcBit, w, tmpSrc);
  111.         putbits(tmpSrc, dstBit, w, pdst);
  112.         psrc += wSrc;
  113.         pdst += wDst;
  114.     }
  115.     }
  116.     else
  117.     {
  118.     register int xoffSrc;    /* offset (>= 0, < 32) from which to
  119.                    fetch whole longwords fetched 
  120.                    in src */
  121.     int nstart;        /* number of ragged bits 
  122.                    at start of dst */
  123.     int nend;        /* number of ragged bits at end 
  124.                    of dst */
  125.     int srcStartOver;    /* pulling nstart bits from src
  126.                    overflows into the next word? */
  127.  
  128.     maskbits(xDst, w, startmask, endmask, nlMiddle);
  129.     if (startmask)
  130.         nstart = 32 - (xDst & 0x1f);
  131.     else
  132.         nstart = 0;
  133.     if (endmask)
  134.         nend = (xDst + w)  & 0x1f;
  135.     else
  136.         nend = 0;
  137.  
  138.     xoffSrc = ((xSrc & 0x1f) + nstart) & 0x1f;
  139.     srcStartOver = ((xSrc & 0x1f) + nstart) > 31;
  140.  
  141.     if (xdir == 1) /* move left to right */
  142.     {
  143.         pdstLine += (xDst >> 5);
  144.         psrcLine += (xSrc >> 5);
  145.  
  146.         while (h--)
  147.         {
  148.         psrc = psrcLine;
  149.         pdst = pdstLine;
  150.  
  151.         if (startmask)
  152.         {
  153.             getbits(psrc, (xSrc & 0x1f), nstart, tmpSrc);
  154.             putbits(tmpSrc, (xDst & 0x1f), nstart, pdst);
  155.             pdst++;
  156.             if (srcStartOver)
  157.             psrc++;
  158.         }
  159.  
  160.         nl = nlMiddle;
  161.         while (nl--)
  162.         {
  163.             getbits(psrc, xoffSrc, 32, tmpSrc);
  164.             *pdst++ = tmpSrc;
  165.             psrc++;
  166.         }
  167.  
  168.         if (endmask)
  169.         {
  170.             getbits(psrc, xoffSrc, nend, tmpSrc);
  171.             {
  172.             int tmpmask ;
  173.             maskpartialbits( 0, nend, tmpmask ) ;
  174.             *pdst = ( *pdst & ~tmpmask ) | ( tmpSrc & tmpmask ) ;
  175.             }
  176.         }
  177.  
  178.         psrcLine += wSrc;
  179.         pdstLine += wDst;
  180.         }
  181.     }
  182.     else /* move right to left */
  183.     {
  184.         pdstLine += ((xDst + w) >> 5);
  185.         psrcLine += (xSrc + w >> 5);
  186.         /* if fetch of last partial bits from source crosses
  187.            a longword boundary, start at the previous longword
  188.         */
  189.         if (xoffSrc + nend >= 32)
  190.         --psrcLine;
  191.  
  192.         while (h--)
  193.         {
  194.         psrc = psrcLine;
  195.         pdst = pdstLine;
  196.  
  197.         if (endmask)
  198.         {
  199.             getbits(psrc, xoffSrc, nend, tmpSrc)
  200.             {
  201.             int tmpmask ;
  202.             maskpartialbits( 0, nend, tmpmask ) ;
  203.             *pdst = ( *pdst & ~tmpmask ) | ( tmpSrc & tmpmask ) ;
  204.             }
  205.         }
  206.  
  207.         nl = nlMiddle;
  208.         while (nl--)
  209.         {
  210.             --psrc;
  211.             getbits(psrc, xoffSrc, 32, tmpSrc)
  212.             *--pdst = tmpSrc;
  213.         }
  214.  
  215.         if (startmask)
  216.         {
  217.             if (srcStartOver)
  218.             --psrc;
  219.             --pdst;
  220.             getbits(psrc, (xSrc & 0x1f), nstart, tmpSrc)
  221.             putbits(tmpSrc, (xDst & 0x1f), nstart, pdst)
  222.         }
  223.  
  224.         pdstLine += wDst;
  225.         psrcLine += wSrc;
  226.         }
  227.     } /* move right to left */
  228.     }
  229.     return ;
  230. }
  231.  
  232. /* Rotates pixmap pPix by w pixels to the right on the screen. Assumes that
  233.  * words are 32 bits wide, and that the least significant bit appears on the
  234.  * left.
  235.  */
  236. void
  237. ppcRotBitmapRight(pPix, rw)
  238.     register PixmapPtr    pPix;
  239.     register int rw;
  240. {
  241.     register long    *pw, *pwFinal, *pwNew;
  242.     register unsigned long    t;
  243.     int            size;
  244.  
  245.     if ( (pPix == NullPixmap) || ( rw == 0 ) )
  246.         return;
  247.  
  248.     pw = (long *)pPix->devPrivate.ptr;
  249.     rw %= pPix->drawable.width;
  250.     if (rw < 0)
  251.     rw += pPix->drawable.width;
  252.     if ( pPix->drawable.width == 32 )
  253.     {
  254.         pwFinal = pw + pPix->drawable.height;
  255.     while ( pw < pwFinal )
  256.     {
  257.         t = *pw;
  258.         *pw++ = SCRRIGHT(t, rw) | 
  259.             (SCRLEFT(t, (32-rw)) & endtab[rw]);
  260.     }
  261.     }
  262.     else
  263.     {
  264.     int sz = pPix->drawable.height * pPix->devKind;
  265.     pwNew = (long *) ALLOCATE_LOCAL( sz );
  266.     if ( !pwNew )
  267.         return;
  268.  
  269.     /* o.k., divide pw (the pixmap) in two vertically at (w - rw)
  270.      * pick up the part on the left and make it the right of the new
  271.      * pixmap.  then pick up the part on the right and make it the left
  272.      * of the new pixmap.
  273.      * now hook in the new part and throw away the old. All done.
  274.      */
  275.     size = PixmapWidthInPadUnits(pPix->drawable.width, 1) ;
  276.         ppcQuickBlt(pw, pwNew, 0, 0, rw, 0, pPix->drawable.width - rw, pPix->drawable.height,
  277.             size, size);
  278.         ppcQuickBlt(pw, pwNew, pPix->drawable.width - rw, 0, 0, 0, rw, pPix->drawable.height,
  279.                 size, size);
  280.     MOVE( pwNew, pPix->devPrivate.ptr, sz );
  281.     DEALLOCATE_LOCAL( pwNew );
  282.  
  283.     }
  284.     return ;
  285. }
  286.  
  287. void
  288. ppcRotBitmapDown(pPix, rh)
  289.     register PixmapPtr    pPix;
  290.     register int    rh;
  291. {
  292.     int nbyDown;    /* bytes to move down to row 0; also offset of
  293.                row rh */
  294.     int nbyUp;        /* bytes to move up to line rh; also
  295.                offset of first line moved down to 0 */
  296.     register char *pbase;
  297.     register char *ptmp;
  298.  
  299.     if (pPix == NullPixmap)
  300.     return;
  301.     rh %= pPix->drawable.height;
  302.     if (rh < 0)
  303.     rh += pPix->drawable.height;
  304.  
  305.     nbyDown = rh * pPix->devKind;
  306.     nbyUp = (pPix->devKind * pPix->drawable.height) - nbyDown;
  307.     if ( !( ptmp = (char *) ALLOCATE_LOCAL( nbyUp ) ) )
  308.     return;
  309.  
  310.     pbase = (char *) pPix->devPrivate.ptr;
  311.  
  312.     MOVE(pbase, ptmp, nbyUp);        /* save the low rows */
  313.     MOVE(pbase+nbyUp, pbase, nbyDown);    /* slide the top rows down */
  314.     MOVE(ptmp, pbase+nbyDown, nbyUp);    /* move lower rows up to row rh */
  315.     DEALLOCATE_LOCAL(ptmp);
  316.     return ;
  317. }
  318.