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 / ppcSetSp.c < prev    next >
C/C++ Source or Header  |  1989-11-07  |  10KB  |  290 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. /***********************************************************
  25. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  26. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  27.  
  28.                         All Rights Reserved
  29.  
  30. Permission to use, copy, modify, and distribute this software and its 
  31. documentation for any purpose and without fee is hereby granted, 
  32. provided that the above copyright notice appear in all copies and that
  33. both that copyright notice and this permission notice appear in 
  34. supporting documentation, and that the names of Digital or MIT not be
  35. used in advertising or publicity pertaining to distribution of the
  36. software without specific, written prior permission.  
  37.  
  38. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  39. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  40. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  41. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  42. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  43. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  44. SOFTWARE.
  45.  
  46. ******************************************************************/
  47.  
  48. #include "X.h"
  49. #include "Xmd.h"
  50.  
  51. #include "servermd.h"
  52.  
  53. #include "misc.h"
  54. #include "regionstr.h"
  55. #include "gcstruct.h"
  56. #include "windowstr.h"
  57. #include "pixmapstr.h"
  58. #include "scrnintstr.h"
  59.  
  60. #include "OScompiler.h"
  61. #include "ppc.h"
  62. extern int mfbGCPrivateIndex ;
  63.  
  64. /* SetScanline -- copies the bits from psrc to the drawable starting at
  65.  * (xStart, y) and continuing to (xEnd, y).  xOrigin tells us where psrc 
  66.  * starts on the scanline. (I.e., if this scanline passes through multiple
  67.  * boxes, we may not want to start grabbing bits at psrc but at some offset
  68.  * further on.) 
  69.  */
  70. static void
  71. ppcSetScanline( pixCount, psrc, pdst, pm, alu )
  72.     register int        pixCount;    /* width of scanline in bits */
  73.     register unsigned char    *psrc;
  74.     register unsigned char    *pdst;        /* where to put the bits */
  75.     register const int        pm;        /* plane mask */
  76.     const int            alu;        /* raster op */
  77. {
  78. register const int npm = ~pm ;    /* inverted plane mask */
  79. register char tmpx ;
  80.  
  81. switch ( alu ) {
  82.     case GXclear:        /* 0x0 Zero 0 */
  83.         while ( pixCount-- )
  84.             *pdst++ &= npm ;
  85.         break ;
  86.     case GXand:        /* 0x1 src AND dst */
  87.         while ( pixCount-- )
  88.             *pdst++ &= *psrc++ | npm ;
  89.         break ;
  90.     case GXandReverse:    /* 0x2 src AND NOT dst */
  91.         for ( tmpx = *pdst ; pixCount-- ; pdst++, psrc++ )
  92.             *pdst = ( tmpx & npm ) | ( pm & *psrc & ~tmpx ) ;
  93.         break ;
  94.     case GXcopy:        /* 0x3 src */
  95.         for ( ; pixCount-- ; pdst++, psrc++ )
  96.             *pdst = ( *pdst & npm ) | ( pm & *psrc ) ;
  97.         break ;
  98.     case GXandInverted:    /* 0x4 NOT src AND dst */
  99.         while ( pixCount-- )
  100.             *pdst++ &= npm | ~*psrc++ ;
  101.         break ;
  102.     case GXnoop:        /* 0x5 dst */
  103.         break ;
  104.     case GXxor:        /* 0x6 src XOR dst */
  105.         while ( pixCount-- )
  106.             *pdst++ ^= pm & *psrc++ ;
  107.         break ;
  108.     case GXor:        /* 0x7 src OR dst */
  109.         while ( pixCount-- )
  110.             *pdst++ |= *psrc++ & pm ;
  111.         break ;
  112.     case GXnor:        /* 0x8 NOT src AND NOT dst */
  113.         for ( tmpx = *pdst ; pixCount-- ; pdst++, psrc++ )
  114.             *pdst = ( tmpx & npm ) | ( pm & ~( tmpx | *psrc ) ) ;
  115.         break ;
  116.     case GXequiv:        /* 0x9 NOT src XOR dst */
  117.         while ( pixCount-- )
  118.             *pdst++ ^= pm & ~ *psrc++ ;
  119.         break ;
  120.     case GXorReverse:    /* 0xb src OR NOT dst */
  121.         for ( tmpx = *pdst ; pixCount-- ; pdst++, psrc++ )
  122.             *pdst = ( tmpx & npm ) | ( pm & ( *psrc | ~tmpx ) ) ;
  123.         break ;
  124.     case GXinvert:        /* 0xa NOT dst */
  125.         while ( pixCount-- )
  126.             *pdst++ ^= pm ;
  127.         break ;
  128.     case GXcopyInverted:    /* 0xc NOT src */
  129.         for ( ; pixCount-- ; pdst++, psrc++ )
  130.             *pdst = ( *pdst & npm ) | ( pm & ~ *psrc ) ;
  131.         break ;
  132.     case GXorInverted:    /* 0xd NOT src OR dst */
  133.         while ( pixCount-- )
  134.             *pdst++ |= pm & ~ *psrc++ ;
  135.         break ;
  136.     case GXnand:        /* 0xe NOT src OR NOT dst */
  137.         for ( tmpx = *pdst ; pixCount-- ; pdst++, psrc++ )
  138.             *pdst = ( tmpx & npm ) | ( pm & ~( tmpx & *psrc ) ) ;
  139.         break ;
  140.     case GXset:        /* 0xf 1 */
  141.         while ( pixCount-- )
  142.             *pdst++ |= pm ;
  143.         break ;
  144.     default:
  145.         ErrorF( "ppcSetScanLine: bad alu value == 0x%02X\n", alu ) ;
  146.         break ;
  147. }
  148.  
  149. return ;
  150. }
  151.  
  152. /* SetSpans -- for each span copy pwidth[i] bits from psrc to pDrawable at
  153.  * ppt[i] using the raster op from the GC.  If fSorted is TRUE, the scanlines
  154.  * are in increasing Y order.
  155.  * Source bit lines are server scanline padded so that they always begin
  156.  * on a word boundary.
  157.  */ 
  158. void
  159. ppcSetSpans( pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted )
  160.     register const DrawablePtr    pDrawable ;
  161.     const GCPtr            pGC ;
  162.     unsigned char        *psrc ;
  163.     register DDXPointPtr    ppt ;
  164.     int                *pwidth ;
  165.     int                nspans ;
  166.     int                fSorted ;
  167. {
  168.     unsigned char    *pdstBase ;    /* start of dst bitmap */
  169.     int         widthDst ;    /* width of bitmap in words */
  170.     register BoxPtr     pbox, pboxLast, pboxTest ;
  171.     register DDXPointPtr pptLast ;
  172.     RegionPtr         prgnDst ;
  173.     register int    width ;
  174.     int            xStart, xEnd ;
  175.     int            yMax ;
  176.     int            alu ;
  177.     int            pm ;
  178.  
  179.     extern void mfbSetSpans() ;
  180.  
  181.     /* allow for 1-deep windows on nfb machines (eg apa8, aed) */
  182.     if ( ( pDrawable->depth == 1 ) && ( pDrawable->type == DRAWABLE_PIXMAP ) ) {
  183.     mfbSetSpans( pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted ) ;
  184.     return ;
  185.     }
  186.  
  187.     if ( !( pm = pGC->planemask & ~( (~0) << pDrawable->depth ) )
  188.       || ( ( alu = pGC->alu ) == GXnoop ) )
  189.     return ;
  190.  
  191.     prgnDst = ( (ppcPrivGC *) (pGC->devPrivates[mfbGCPrivateIndex].ptr) )->pCompositeClip ;
  192.  
  193.     if ( ! REGION_NUM_RECTS(prgnDst))
  194.     return ;
  195.  
  196.     pboxLast = ( pbox = REGION_RECTS(prgnDst) ) + REGION_NUM_RECTS(prgnDst);
  197.     pptLast = ppt + nspans ;
  198.  
  199.     if ( pDrawable->type == DRAWABLE_WINDOW ) {
  200.     yMax = (int) pDrawable->height + pDrawable->y ;
  201.     }
  202.     else {
  203.     pdstBase = (unsigned char *) ( (PixmapPtr) pDrawable )->devPrivate.ptr ;
  204.     widthDst = (int) ( (PixmapPtr) pDrawable )->devKind ;
  205.     yMax = pDrawable->height ;
  206.     }
  207.  
  208.     if ( fSorted ) {
  209.     /* scan lines sorted in ascending order. Because they are sorted, we
  210.      * don't have to check each scanline against each clip box.  We can be
  211.      * sure that this scanline only has to be clipped to boxes at or after the
  212.      * beginning of this y-band 
  213.      */
  214.     for ( pboxTest = pbox ;
  215.           ( ppt < pptLast ) && ( ppt->y < yMax ) ;
  216.           ppt++, pwidth++,
  217.           psrc += PixmapBytePad( width, pDrawable->depth ) ) {
  218.         width = *pwidth ;
  219.         for ( pbox = pboxTest ;
  220.               pbox < pboxLast ;
  221.           pbox++ ) {
  222.         if ( pbox->y2 <= ppt->y ) {
  223.             /* clip box is before scanline */
  224.             pboxTest = pbox + 1 ;
  225.         }
  226.         else if ( ( pbox->y1 > ppt->y )
  227.                || ( pbox->x1 > ppt->x + width ) )
  228.             break ; /* scanline before clip box or left of clip box */
  229.         else if ( pbox->x2 > ppt->x ) {
  230.             /* some of the scanline is in the current clip box */
  231.             xStart = MAX( pbox->x1, ppt->x ) ;
  232.             xEnd = MIN( ppt->x + width, pbox->x2 ) ;
  233.             if ( pDrawable->type == DRAWABLE_PIXMAP )
  234.                 ppcSetScanline( xEnd - xStart,
  235.                         psrc + ( xStart - ppt->x ),
  236.                         pdstBase + xStart
  237.                         + ( ppt->y * widthDst ),
  238.                             pm, alu ) ;
  239.             else
  240.                     ( *( ( (ppcScrnPriv *)
  241.               ( pDrawable->pScreen->devPrivate ) )->imageFill ) )
  242.                 ( xStart, ppt->y, xEnd - xStart, 1,
  243.                   psrc + ( xStart - ppt->x ), xEnd - xStart,
  244.                   alu, pm ) ;
  245.             if ( ppt->x + width <= pbox->x2 )
  246.                 break ; /* End of the line, as it were */
  247.         }
  248.         }
  249.         /* We've tried this line against every box ; it must be outside them
  250.          * all.  move on to the next point */
  251.     }
  252.     }
  253.     else {
  254.     /* scan lines not sorted. We must clip each line against all the boxes */
  255.     for ( ;
  256.           ppt < pptLast ;
  257.           ppt++, pwidth++,
  258.           psrc += PixmapBytePad( width, pDrawable->depth ) ) {
  259.         width = *pwidth ;
  260.         if ( ppt->y >= 0 && ppt->y < yMax ) {
  261.         for ( pbox = REGION_RECTS(prgnDst) ; pbox < pboxLast ; pbox++ ) {
  262.             if ( pbox->y1 > ppt->y )
  263.             break ; /* rest of clip region is above this scanline */
  264.             else if ( ( pbox->y2 > ppt->y )
  265.                && ( pbox->x1 <= ppt->x + width )
  266.                && ( pbox->x2 > ppt->x ) ) {
  267.             xStart = MAX( pbox->x1, ppt->x ) ;
  268.             xEnd = MIN( pbox->x2, ppt->x + width ) ;
  269.                 if ( pDrawable->type == DRAWABLE_PIXMAP )
  270.                 ppcSetScanline( xEnd - xStart,
  271.                         psrc + ( xStart - pbox->x1 ),
  272.                         ( ( pdstBase
  273.                          + ( ppt->y * widthDst ) )
  274.                          + xStart ),
  275.                         pm, alu ) ;
  276.                 else    /* pDrawable->type == DRAWABLE_WINDOW */
  277.                     ( *( ( (ppcScrnPriv *)
  278.             ( pDrawable->pScreen->devPrivate ) )->imageFill ) )
  279.                 ( xStart, ppt->y, xEnd - xStart, 1,
  280.                   psrc + ( xStart - pbox->x1 ), xEnd - xStart,
  281.                   alu, pm ) ;
  282.             }
  283.  
  284.         }
  285.         }
  286.     }
  287.     }
  288.     return ;
  289. }
  290.