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 / ppcPushPxl.c < prev    next >
C/C++ Source or Header  |  1989-11-07  |  10KB  |  337 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. /* ppc PushPixels */
  25.  
  26. #include "X.h"
  27. #include "misc.h"
  28. #include "gcstruct.h"
  29. #include "windowstr.h"
  30. #include "regionstr.h"
  31. #include "pixmapstr.h"
  32. #include "scrnintstr.h"
  33. #include "miscstruct.h"
  34.  
  35. #include "ppc.h"
  36. #include "ppcBitMacs.h"
  37.  
  38. #include "OScompiler.h"
  39. #include "ibmTrace.h"
  40.  
  41. extern int mfbGCPrivateIndex;
  42.  
  43. static void
  44. BitMapMerge( pDst, pSrc, pStp, xOffset, yOffset, srcInvert )
  45. PixmapPtr    pDst;
  46. PixmapPtr    pSrc ;
  47. PixmapPtr    pStp ;
  48. int        xOffset, yOffset ; /* Offset To Stipple Tmp bitmap */
  49. int        srcInvert ; /* used for opaqueness */
  50. {
  51. register unsigned long int    bits ;
  52. register unsigned long int    *bitptr ;
  53. register int            wordOffset ;
  54. register unsigned long int    *pDstPriv =
  55.             (unsigned long int *) pDst->devPrivate.ptr ;
  56. unsigned long int    *pSrcPriv =
  57.             (unsigned long int *) pSrc->devPrivate.ptr ;
  58. register int            j ;
  59. register int            i ;
  60. register unsigned long int    *pStipSrc ;
  61. unsigned long int    *pStpPriv = (unsigned long int *) pStp->devPrivate.ptr ;
  62. unsigned long int    stipOffset ;
  63. unsigned long int    stpWidth    = pStp->drawable.width ;
  64. unsigned long int    stpPaddedWidth    = pStp->devKind >> 2 ;
  65. unsigned long int    stpHeight    = pStp->drawable.height ;
  66. unsigned long int    dstHeight    = pDst->drawable.height ;
  67. unsigned long int    dstWidth    = pDst->devKind >> 2 ;
  68.  
  69. if ( ( xOffset %= stpWidth ) < 0 )
  70.     xOffset += stpWidth ;
  71. if ( ( yOffset %= stpHeight ) < 0 )
  72.     yOffset += stpHeight ;
  73.  
  74. if ( stpWidth > 32 ) {
  75.     /* **************************** */
  76.     /* Only Works if stpWidth >= 32 */
  77.     /* **************************** */
  78.     if ( srcInvert )
  79.         for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
  80.             pStipSrc = pStpPriv
  81.                 + ( ( ( yOffset + i ) % stpHeight ) * stpPaddedWidth ) ;
  82.             for ( j = dstWidth, stipOffset = xOffset ; j-- ; ) {
  83.                 wordOffset = stipOffset & 0x1F ;
  84.                 if ( stipOffset <= stpWidth - 32 ) {
  85.                     bitptr = pStipSrc + ( stipOffset >> 5 ) ;
  86.                   bits = SCRLEFT( bitptr[0], wordOffset )
  87.                      | SCRRIGHT( bitptr[1],
  88.                           ( 32 - wordOffset )) ;
  89.                 }
  90.                 else { /* stipOffset > stpWidth - 32 */
  91.                     bits = SCRLEFT(
  92.                        pStipSrc[ stipOffset >> 5 ],
  93.                         wordOffset )
  94.                      | SCRRIGHT( pStipSrc[0],
  95.                         ( 32 - wordOffset )) ;
  96.                     stipOffset -= stpWidth ;
  97.                 }
  98.                 *pDstPriv++ = *pSrcPriv++ & ~ bits ;
  99.             }
  100.         }
  101.     else
  102.         for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
  103.             pStipSrc = pStpPriv
  104.                 + ( ( ( yOffset + i ) % stpHeight ) * stpPaddedWidth ) ;
  105.             for ( j = dstWidth, stipOffset = xOffset ; j-- ; ) {
  106.                 wordOffset = stipOffset & 0x1F ;
  107.                 if ( stipOffset <= stpWidth - 32 ) {
  108.                     bitptr = pStipSrc + ( stipOffset >> 5 ) ;
  109.                     bits = SCRLEFT( bitptr[0], wordOffset )
  110.                          | SCRRIGHT( bitptr[1],
  111.                              ( 32 - wordOffset ) ) ;
  112.                 }
  113.                 else { /* stipOffset > stpWidth - 32 */
  114.                     bits = SCRLEFT(
  115.                         pStipSrc[ stipOffset >> 5 ],
  116.                         wordOffset )
  117.                          | SCRRIGHT( pStipSrc[0],
  118.                              ( 32 - wordOffset ) ) ;
  119.                     stipOffset -= stpWidth ;
  120.                 }
  121.                 *pDstPriv++ = *pSrcPriv++ & bits ;
  122.             }
  123.         }
  124. }
  125. else { /* stpWidth <= 32 */
  126.     for ( i = stpWidth ; i < 32 ; i <<= 1 ) ; /* Test For A Power Of 2 */
  127.     if ( i == 32 ) { /* Best Case - Started w/ Power Of 2 */
  128.        if (srcInvert) {
  129.         for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
  130.                 bits = pStpPriv[ ( yOffset + i ) % stpHeight ] ;
  131.             /* Pad Out The Bit Mask To A Full Word */
  132.             for ( j = stpWidth ; j != 32 ; j <<= 1 )
  133.                 bits |= SCRRIGHT( bits, j ) ;
  134.             /* If Needed Rotate The Mask */
  135.             if ( xOffset )
  136.                 bits = SCRLEFT( bits, xOffset )
  137.                      | SCRRIGHT( bits, 32 - xOffset ) ;
  138.             /* For Each Word In The Line */
  139.             for ( j = dstWidth ; j-- ; )
  140.                 *pDstPriv++ = *pSrcPriv++ & ~bits ;
  141.         }
  142.        } else {
  143.         for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
  144.                 bits = pStpPriv[ ( yOffset + i ) % stpHeight ] ;
  145.             /* Pad Out The Bit Mask To A Full Word */
  146.             for ( j = stpWidth ; j != 32 ; j <<= 1 )
  147.                 bits |= SCRRIGHT( bits, j ) ;
  148.             /* If Needed Rotate The Mask */
  149.             if ( xOffset )
  150.                 bits = SCRLEFT( bits, xOffset )
  151.                      | SCRRIGHT( bits, 32 - xOffset ) ;
  152.             /* For Each Word In The Line */
  153.             for ( j = dstWidth ; j-- ; )
  154.                 *pDstPriv++ = *pSrcPriv++ & bits ;
  155.         }
  156.        }
  157.     } else { /* Case - Didn't Start w/ Power Of 2 */
  158.         int goalWidth = i >> 1 ;
  159.        if (srcInvert) {
  160.  
  161.         for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
  162.                 bits = pStpPriv[ ( yOffset + i ) % stpHeight ] ;
  163.             /* Pad Out The Bit Mask To A Full Word */
  164.             for ( j = stpWidth ; j <= goalWidth ; j <<= 1 )
  165.                 bits |= SCRRIGHT( bits, j ) ;
  166.             /* If Needed Rotate The Mask */
  167.             if ( xOffset )
  168.                 bits = ~(SCRLEFT( bits, xOffset )
  169.                      | SCRRIGHT( bits, goalWidth - xOffset)) ;
  170.             /* For Each Word In The Line */
  171.             for ( j = dstWidth ; j-- ; ) {
  172.                 *pDstPriv++ = *pSrcPriv++ & bits ;
  173.                 bits = ~(SCRLEFT( bits, 32 - goalWidth )
  174.                      | SCRRIGHT( bits,
  175.                         ( goalWidth << 1 ) - 32 )) ;
  176.             }
  177.         }
  178.        } else {
  179.         for ( i = 0 ; i < dstHeight ; i++ ) { /* For Each Line */
  180.                 bits = pStpPriv[ ( yOffset + i ) % stpHeight ] ;
  181.             /* Pad Out The Bit Mask To A Full Word */
  182.             for ( j = stpWidth ; j <= goalWidth ; j <<= 1 )
  183.                 bits |= SCRRIGHT( bits, j ) ;
  184.             /* If Needed Rotate The Mask */
  185.             if ( xOffset )
  186.                 bits = SCRLEFT( bits, xOffset )
  187.                      | SCRRIGHT( bits, goalWidth - xOffset ) ;
  188.             /* For Each Word In The Line */
  189.             for ( j = dstWidth ; j-- ; ) {
  190.                 *pDstPriv++ = *pSrcPriv++ & bits ;
  191.                 bits = SCRLEFT( bits, 32 - goalWidth )
  192.                      | SCRRIGHT( bits,
  193.                         ( goalWidth << 1 ) - 32 ) ;
  194.             }
  195.         }
  196.        }
  197.     }
  198. }
  199.  
  200. return ;
  201. }
  202.  
  203. /* Note: pushPixels operates with the current Fill Style
  204.      thus the ppc's colorRrop is initially valid.
  205. */
  206.  
  207. void
  208. ppcPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg )
  209.     GCPtr    pGC ;
  210.     PixmapPtr    pBitMap ;
  211.     DrawablePtr pDrawable ;
  212.     int        dx, dy, xOrg, yOrg ;
  213. {
  214. ppcPrivGC        *gcPriv  = (ppcPrivGC *) ( pGC->devPrivates[mfbGCPrivateIndex].ptr ) ;
  215. ScreenPtr        pScrn ;
  216. ppcScrnPriv        *scrPriv ;
  217. RegionPtr        prgnDst ;
  218. int            alu ;
  219. int            fillStyle ;
  220. int            xSrc, ySrc ;
  221. BoxPtr            pbox ;
  222. unsigned int        nbox ;
  223.  
  224. if ( ( pDrawable->type != DRAWABLE_WINDOW )
  225.   || ( fillStyle = gcPriv->colorRrop.fillStyle ) == FillTiled ) {
  226.     miPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg ) ;
  227.     return ;
  228. }
  229. pScrn   = (ScreenPtr) pDrawable->pScreen ;
  230. scrPriv = (ppcScrnPriv *) ( pScrn->devPrivate ) ;
  231.  
  232. /* Note: pushPixels operates with the current Fill Style
  233.      thus the ppc's colorRrop is initially valid. */
  234. if ( ( alu = gcPriv->colorRrop.alu ) == GXnoop )
  235.     return ;
  236.  
  237. /* Find The Actual Regions To Fill
  238.  * by intersecting the destination's clip-region with
  239.  * the box defined by our arguments.
  240.  */
  241. {
  242.     BoxRec        dstBox ;
  243.  
  244.     dstBox.x2 = ( dstBox.x1 = xOrg ) + dx ;
  245.     dstBox.y2 = ( dstBox.y1 = yOrg ) + dy ;
  246.  
  247.     prgnDst = (* pScrn->RegionCreate )( &dstBox,
  248.                         REGION_NUM_RECTS(gcPriv->pCompositeClip));
  249.     (* pScrn->Intersect)( prgnDst, prgnDst, gcPriv->pCompositeClip ) ;
  250.     if ( !( nbox = REGION_NUM_RECTS(prgnDst))) {
  251.        (* pScrn->RegionDestroy)( prgnDst ) ;
  252.        return;
  253.         } 
  254.      pbox = REGION_RECTS(prgnDst);
  255. }
  256.  
  257. /* ASSUME ( pDrawable->type == DRAWABLE_WINDOW ) */
  258. xSrc = pGC->patOrg.x + pDrawable->x ;
  259. ySrc = pGC->patOrg.y + pDrawable->y ;
  260.  
  261. { /* Begin Sub-Block */
  262.     PixmapPtr        ptmpBitmap = (PixmapPtr) 0 ;
  263.                 /* Temp bitmap Make Sure It's Zero'ed Here */
  264.     int            BitmapIsCopy = FALSE ;
  265.     void            (*FillFunc)() = scrPriv->stipFill ;
  266.     unsigned long int    fg = gcPriv->colorRrop.fgPixel ;
  267.     unsigned long int    bg = gcPriv->colorRrop.bgPixel ;
  268.     unsigned long int    pm = gcPriv->colorRrop.planemask ;
  269.  
  270.     /* Now Do The Needed Fill */
  271.     switch ( fillStyle ) {
  272.  
  273.         case FillOpaqueStippled : { /* Create two (2) Tmp stipples */
  274.             /* Create The Scratch Bitmap */
  275.             ptmpBitmap = (* pScrn->CreatePixmap)( pScrn,
  276.                             pBitMap->drawable.width,
  277.                             pBitMap->drawable.height, 1 ) ;
  278.  
  279.             /* Now take the logical "AND-Not" of the pBitmap argument
  280.              * and the GC's stipple */
  281.             BitMapMerge( ptmpBitmap, pBitMap, pGC->stipple,
  282.                      ( xOrg - xSrc ), ( yOrg - ySrc ), TRUE ) ;
  283.             for ( nbox = REGION_NUM_RECTS(prgnDst), pbox = REGION_RECTS(prgnDst);
  284.                   nbox-- ;
  285.                   pbox++ ) {
  286.                 (* FillFunc)( ptmpBitmap, bg, alu, pm,
  287.                           pbox->x1,
  288.                           pbox->y1,
  289.                           pbox->x2 - pbox->x1,
  290.                           pbox->y2 - pbox->y1,
  291.                           xOrg, yOrg ) ;
  292.                 }
  293.             } /* Now Fall-Though To Do Foreground */
  294.         case FillStippled : /* Create Tmp stipple from pBitmap AND stipple */
  295.             if ( !ptmpBitmap ) {
  296.                 ptmpBitmap = (* pScrn->CreatePixmap)( pScrn,
  297.                                 pBitMap->drawable.width,
  298.                                 pBitMap->drawable.height, 1 ) ;
  299.             }
  300.             /* Now take the logical "AND" of the GC's stipple
  301.              * and the pBitmap argument */
  302.             BitMapMerge( ptmpBitmap, pBitMap, pGC->stipple,
  303.                      ( xOrg - xSrc ), ( yOrg - ySrc ), FALSE ) ;
  304.  
  305.             /* Now Fall-Though To REALLY Do Foreground */
  306.         case FillSolid : /* Easiest case -- Just Stipple it in ! */
  307.             if ( !ptmpBitmap ) {
  308.                 ptmpBitmap = pBitMap ;
  309.                 BitmapIsCopy = TRUE ;
  310.             }
  311.             for ( nbox = REGION_NUM_RECTS(prgnDst), pbox = REGION_RECTS(prgnDst);
  312.                   nbox-- ;
  313.                   pbox++ ) {
  314.                 (* FillFunc)( ptmpBitmap, fg, alu, pm,
  315.                           pbox->x1,
  316.                           pbox->y1,
  317.                           pbox->x2 - pbox->x1,
  318.                           pbox->y2 - pbox->y1,
  319.                           xOrg, yOrg ) ;
  320.                 }
  321.             if ( BitmapIsCopy == FALSE )
  322.                 (* pScrn->DestroyPixmap)( ptmpBitmap ) ;
  323.             break ;
  324.  
  325.         case FillTiled : /* Hardest case */
  326.             /* Not Yet Implimented Here -- Calls "mi" above */
  327.             break ;
  328.         default :
  329.             ErrorF( "ppcPushPixels: Unknown fill Style\n" ) ;
  330.             break ;
  331.     }
  332. } /* End Sub-Block */
  333. (* pScrn->RegionDestroy)( prgnDst ) ;
  334.  
  335. return ;
  336. }
  337.