home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / cfb / cfbfillsp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-18  |  25.1 KB  |  927 lines

  1. /************************************************************
  2. Copyright 1987 by Sun Microsystems, Inc. Mountain View, CA.
  3.  
  4.                     All Rights Reserved
  5.  
  6. Permission  to  use,  copy,  modify,  and  distribute   this
  7. software  and  its documentation for any purpose and without
  8. fee is hereby granted, provided that the above copyright no-
  9. tice  appear  in all copies and that both that copyright no-
  10. tice and this permission notice appear in  supporting  docu-
  11. mentation,  and  that the names of Sun or MIT not be used in
  12. advertising or publicity pertaining to distribution  of  the
  13. software  without specific prior written permission. Sun and
  14. M.I.T. make no representations about the suitability of this
  15. software for any purpose. It is provided "as is" without any
  16. express or implied warranty.
  17.  
  18. SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
  19. INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
  20. NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
  21. ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  22. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
  23. PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
  24. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
  25. THE USE OR PERFORMANCE OF THIS SOFTWARE.
  26.  
  27. ********************************************************/
  28.  
  29. /***********************************************************
  30. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  31. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  32.  
  33.                         All Rights Reserved
  34.  
  35. Permission to use, copy, modify, and distribute this software and its 
  36. documentation for any purpose and without fee is hereby granted, 
  37. provided that the above copyright notice appear in all copies and that
  38. both that copyright notice and this permission notice appear in 
  39. supporting documentation, and that the names of Digital or MIT not be
  40. used in advertising or publicity pertaining to distribution of the
  41. software without specific, written prior permission.  
  42.  
  43. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  44. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  45. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  46. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  47. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  48. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  49. SOFTWARE.
  50.  
  51. ******************************************************************/
  52.  
  53. /* $XConsortium: cfbfillsp.c,v 5.17 91/07/18 23:31:04 keith Exp $ */
  54.  
  55. #include "X.h"
  56. #include "Xmd.h"
  57. #include "servermd.h"
  58. #include "gcstruct.h"
  59. #include "window.h"
  60. #include "pixmapstr.h"
  61. #include "scrnintstr.h"
  62. #include "windowstr.h"
  63.  
  64. #include "cfb.h"
  65. #include "cfbmskbits.h"
  66.  
  67. #include "mergerop.h"
  68.  
  69. #if PPW == 4
  70. #include "cfb8bit.h"
  71. #endif
  72.  
  73. extern void mfbInvertSolidFS(), mfbBlackSolidFS(), mfbWhiteSolidFS();
  74.  
  75. /* scanline filling for color frame buffer
  76.    written by drewry, oct 1986 modified by smarks
  77.    changes for compatibility with Little-endian systems Jul 1987; MIT:yba.
  78.  
  79.    these routines all clip.  they assume that anything that has called
  80. them has already translated the points (i.e. pGC->miTranslate is
  81. non-zero, which is howit gets set in cfbCreateGC().)
  82.  
  83.    the number of new scnalines created by clipping ==
  84. MaxRectsPerBand * nSpans.
  85.  
  86.     FillSolid is overloaded to be used for OpaqueStipple as well,
  87. if fgPixel == bgPixel.  
  88. Note that for solids, PrivGC.rop == PrivGC.ropOpStip
  89.  
  90.  
  91.     FillTiled is overloaded to be used for OpaqueStipple, if
  92. fgPixel != bgPixel.  based on the fill style, it uses
  93. {RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip}
  94. */
  95.  
  96. #ifdef    notdef
  97. #include    <stdio.h>
  98. static
  99. dumpspans(n, ppt, pwidth)
  100.     int    n;
  101.     DDXPointPtr ppt;
  102.     int *pwidth;
  103. {
  104.     fprintf(stderr,"%d spans\n", n);
  105.     while (n--) {
  106.     fprintf(stderr, "[%d,%d] %d\n", ppt->x, ppt->y, *pwidth);
  107.     ppt++;
  108.     pwidth++;
  109.     }
  110.     fprintf(stderr, "\n");
  111. }
  112. #endif
  113.  
  114. /* Fill spans with tiles that aren't 32 bits wide */
  115. void
  116. cfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  117. DrawablePtr pDrawable;
  118. GC        *pGC;
  119. int        nInit;        /* number of spans to fill */
  120. DDXPointPtr pptInit;        /* pointer to list of start points */
  121. int *pwidthInit;        /* pointer to list of n widths */
  122. int fSorted;
  123. {
  124.     int n;            /* number of spans to fill */
  125.     register DDXPointPtr ppt;    /* pointer to list of start points */
  126.     register int *pwidth;    /* pointer to list of n widths */
  127.     void    (*fill)();
  128.     extern void    cfbFillSpanTileOddCopy ();
  129.     extern void    cfbFillSpanTileOddGeneral ();
  130.     extern void    cfbFillSpanTile32sCopy ();
  131.     extern void cfbFillSpanTile32sGeneral ();
  132.     int    xrot, yrot;
  133.  
  134.     if (!(pGC->planemask))
  135.     return;
  136.  
  137.     if (pGC->tile.pixmap->drawable.width & PIM)
  138.     {
  139.         fill = cfbFillSpanTileOddGeneral;
  140.         if ((pGC->planemask & PMSK) == PMSK)
  141.         {
  142.         if (pGC->alu == GXcopy)
  143.             fill = cfbFillSpanTileOddCopy;
  144.         }
  145.     }
  146.     else
  147.     {
  148.     fill = cfbFillSpanTile32sGeneral;
  149.         if ((pGC->planemask & PMSK) == PMSK)
  150.         {
  151.         if (pGC->alu == GXcopy)
  152.         fill = cfbFillSpanTile32sCopy;
  153.     }
  154.     }
  155.     n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip);
  156.     pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  157.     ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  158.     if(!ppt || !pwidth)
  159.     {
  160.     if (ppt) DEALLOCATE_LOCAL(ppt);
  161.     if (pwidth) DEALLOCATE_LOCAL(pwidth);
  162.     return;
  163.     }
  164.     n = miClipSpans(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip,
  165.              pptInit, pwidthInit, nInit, 
  166.              ppt, pwidth, fSorted);
  167.  
  168.     xrot = pDrawable->x + pGC->patOrg.x;
  169.     yrot = pDrawable->y + pGC->patOrg.y;
  170.  
  171.     (*fill) (pDrawable, n, ppt, pwidth, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
  172.  
  173.     DEALLOCATE_LOCAL(ppt);
  174.     DEALLOCATE_LOCAL(pwidth);
  175. }
  176.  
  177. #if PPW == 4
  178.  
  179. void
  180. cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  181. DrawablePtr pDrawable;
  182. GC        *pGC;
  183. int        nInit;        /* number of spans to fill */
  184. DDXPointPtr pptInit;        /* pointer to list of start points */
  185. int *pwidthInit;        /* pointer to list of n widths */
  186. int fSorted;
  187. {
  188.                 /* next three parameters are post-clip */
  189.     int            n;        /* number of spans to fill */
  190.     DDXPointPtr        ppt;    /* pointer to list of start points */
  191.     int            *pwidth;    /* pointer to list of n widths */
  192.     int            *pwidthFree;/* copies of the pointers to free */
  193.     DDXPointPtr        pptFree;
  194.     unsigned long   *pdstBase;    /* pointer to start of bitmap */
  195.     int            nlwDst;    /* width in longwords of bitmap */
  196.     register unsigned long    *pdst;    /* pointer to current word in bitmap */
  197.     PixmapPtr        pStipple;    /* pointer to stipple we want to fill with */
  198.     int            nlw;
  199.     int            x, y, w, xrem, xSrc, ySrc;
  200.     int            stwidth, stippleWidth;
  201.     int            stippleHeight;
  202.     register unsigned long  bits, inputBits;
  203.     register int    partBitsLeft;
  204.     int            nextPartBits;
  205.     int            bitsLeft, bitsWhole;
  206.     unsigned long   *srcTemp, *srcStart;
  207.     unsigned long   *psrcBase;
  208.     unsigned long   startmask, endmask;
  209.  
  210.     if (pGC->fillStyle == FillStippled)
  211.     cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
  212.     else
  213.     cfb8CheckOpaqueStipple (pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
  214.  
  215.     if (cfb8StippleRRop == GXnoop)
  216.     return;
  217.  
  218.     n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip);
  219.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  220.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  221.     if(!pptFree || !pwidthFree)
  222.     {
  223.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  224.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  225.     return;
  226.     }
  227.  
  228.     pwidth = pwidthFree;
  229.     ppt = pptFree;
  230.     n = miClipSpans(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip,
  231.              pptInit, pwidthInit, nInit, 
  232.              ppt, pwidth, fSorted);
  233.  
  234.     /*
  235.      *  OK,  so what's going on here?  We have two Drawables:
  236.      *
  237.      *  The Stipple:
  238.      *        Depth = 1
  239.      *        Width = stippleWidth
  240.      *        Words per scanline = stwidth
  241.      *        Pointer to pixels = pStipple->devPrivate.ptr
  242.      */
  243.  
  244.     pStipple = pGC->stipple;
  245.  
  246.     stwidth = pStipple->devKind >> 2;
  247.     stippleWidth = pStipple->drawable.width;
  248.     stippleHeight = pStipple->drawable.height;
  249.     psrcBase = (unsigned long *) pStipple->devPrivate.ptr;
  250.  
  251.     /*
  252.      *    The Target:
  253.      *        Depth = PSZ
  254.      *        Width = determined from *pwidth
  255.      *        Words per scanline = nlwDst
  256.      *        Pointer to pixels = addrlBase
  257.      */
  258.  
  259.     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pdstBase)
  260.  
  261.     /* this replaces rotating the stipple. Instead we just adjust the offset
  262.      * at which we start grabbing bits from the stipple.
  263.      * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
  264.      * so that iline and xrem always stay within the stipple bounds.
  265.      */
  266.  
  267.     modulus (pGC->patOrg.x, stippleWidth, xSrc);
  268.     xSrc += pDrawable->x - stippleWidth;
  269.     modulus (pGC->patOrg.y, stippleHeight, ySrc);
  270.     ySrc += pDrawable->y - stippleHeight;
  271.  
  272.     bitsWhole = stippleWidth;
  273.  
  274.     while (n--)
  275.     {
  276.     x = ppt->x;
  277.     y = ppt->y;
  278.     ppt++;
  279.     w = *pwidth++;
  280.     pdst = pdstBase + y * nlwDst + (x >> PWSH);
  281.     y = (y - ySrc) % stippleHeight;
  282.     srcStart = psrcBase + y * stwidth;
  283.     xrem = ((x & ~3) - xSrc) % stippleWidth;
  284.     srcTemp = srcStart + (xrem >> 5);
  285.     bitsLeft = stippleWidth - (xrem & ~0x1f);
  286.     xrem &= 0x1f;
  287.     NextUnnaturalStippleWord
  288.     if (partBitsLeft < xrem)
  289.         FatalError ("cfbUnnaturalStippleFS bad partBitsLeft %d xrem %d",
  290.             partBitsLeft, xrem);
  291.     NextSomeBits (inputBits, xrem);
  292.     partBitsLeft -= xrem;
  293.     if (((x & PIM) + w) <= PPW)
  294.     {
  295.         maskpartialbits (x, w, startmask)
  296.         NextUnnaturalStippleBits
  297.         *pdst = MaskRRopPixels(*pdst,bits,startmask);
  298.     }
  299.     else
  300.     {
  301.         maskbits (x, w, startmask, endmask, nlw);
  302.         nextPartBits = (x & 0x3) + w;
  303.         if (nextPartBits < partBitsLeft)
  304.         {
  305.         if (startmask)
  306.         {
  307.             MaskRRopFourBits(pdst,GetFourBits(inputBits),startmask)
  308.             pdst++;
  309.             NextFourBits (inputBits);
  310.         }
  311.         while (nlw--)
  312.         {
  313.             RRopFourBits (pdst, GetFourBits (inputBits));
  314.             pdst++;
  315.             NextFourBits (inputBits);
  316.         }
  317.         if (endmask)
  318.         {
  319.             MaskRRopFourBits(pdst,GetFourBits(inputBits),endmask)
  320.         }
  321.         }
  322.         else if (bitsLeft != bitsWhole && nextPartBits < partBitsLeft + bitsLeft)
  323.         {
  324.             NextUnnaturalStippleBitsFast
  325.             if (startmask)
  326.             {
  327.             *pdst = MaskRRopPixels(*pdst,bits,startmask);
  328.             pdst++;
  329.                 NextUnnaturalStippleBitsFast
  330.             }
  331.             while (nlw--)
  332.             {
  333.             *pdst = RRopPixels(*pdst,bits);
  334.             pdst++;
  335.                 NextUnnaturalStippleBitsFast
  336.             }
  337.             if (endmask)
  338.             *pdst = MaskRRopPixels (*pdst,bits,endmask);
  339.         }
  340.         else
  341.         {
  342.             NextUnnaturalStippleBits
  343.             if (startmask)
  344.             {
  345.             *pdst = MaskRRopPixels(*pdst,bits,startmask);
  346.             pdst++;
  347.                 NextUnnaturalStippleBits
  348.             }
  349.             while (nlw--)
  350.             {
  351.             *pdst = RRopPixels(*pdst,bits);
  352.             pdst++;
  353.                 NextUnnaturalStippleBits
  354.             }
  355.             if (endmask)
  356.             *pdst = MaskRRopPixels(*pdst,bits,endmask);
  357.         }
  358.     }
  359.     }
  360.     DEALLOCATE_LOCAL(pptFree);
  361.     DEALLOCATE_LOCAL(pwidthFree);
  362. }
  363.  
  364. #else
  365.  
  366. /* Fill spans with stipples that aren't 32 bits wide */
  367. void
  368. cfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  369. DrawablePtr pDrawable;
  370. GC        *pGC;
  371. int        nInit;        /* number of spans to fill */
  372. DDXPointPtr pptInit;        /* pointer to list of start points */
  373. int *pwidthInit;        /* pointer to list of n widths */
  374. int fSorted;
  375. {
  376.                 /* next three parameters are post-clip */
  377.     int                n;        /* number of spans to fill */
  378.     register DDXPointPtr    ppt;    /* pointer to list of start points */
  379.     register unsigned long  *pwidth;    /* pointer to list of n widths */
  380.     int                iline;    /* first line of tile to use */
  381.     unsigned long        *addrlBase;    /* pointer to start of bitmap */
  382.     int                nlwidth;    /* width in longwords of bitmap */
  383.     register unsigned long  *pdst;    /* pointer to current word in bitmap */
  384.     PixmapPtr            pStipple;    /* pointer to stipple we want to fill with */
  385.     register int        w;
  386.     int                width,  x, xrem, xSrc, ySrc;
  387.     unsigned long        tmpSrc, tmpDst1, tmpDst2;
  388.     int                stwidth, stippleWidth;
  389.     unsigned long        *psrcS;
  390.     int                rop, stiprop;
  391.     int                stippleHeight;
  392.     int                *pwidthFree;    /* copies of the pointers to free */
  393.     DDXPointPtr            pptFree;
  394.     unsigned long        fgfill, bgfill;
  395.  
  396.     if (!(pGC->planemask))
  397.     return;
  398.  
  399.     n = nInit * miFindMaxBand(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip);
  400.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  401.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  402.     if(!pptFree || !pwidthFree)
  403.     {
  404.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  405.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  406.     return;
  407.     }
  408.     pwidth = pwidthFree;
  409.     ppt = pptFree;
  410.     n = miClipSpans(((cfbPrivGC *)(pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip,
  411.              pptInit, pwidthInit, nInit, 
  412.              ppt, pwidth, fSorted);
  413.     rop = pGC->alu;
  414.     if (pGC->fillStyle == FillStippled) {
  415.     switch (rop) {
  416.         case GXand:
  417.         case GXcopy:
  418.         case GXnoop:
  419.         case GXor:
  420.         stiprop = rop;
  421.         break;
  422.         default:
  423.         stiprop = rop;
  424.         rop = GXcopy;
  425.     }
  426.     }
  427.     fgfill = PFILL(pGC->fgPixel);
  428.     bgfill = PFILL(pGC->bgPixel);
  429.  
  430.     /*
  431.      *  OK,  so what's going on here?  We have two Drawables:
  432.      *
  433.      *  The Stipple:
  434.      *        Depth = 1
  435.      *        Width = stippleWidth
  436.      *        Words per scanline = stwidth
  437.      *        Pointer to pixels = pStipple->devPrivate.ptr
  438.      */
  439.     pStipple = pGC->stipple;
  440.  
  441.     stwidth = pStipple->devKind >> 2;
  442.     stippleWidth = pStipple->drawable.width;
  443.     stippleHeight = pStipple->drawable.height;
  444.  
  445.     /*
  446.      *    The Target:
  447.      *        Depth = PSZ
  448.      *        Width = determined from *pwidth
  449.      *        Words per scanline = nlwidth
  450.      *        Pointer to pixels = addrlBase
  451.      */
  452.  
  453.     cfbGetLongWidthAndPointer (pDrawable, nlwidth, addrlBase)
  454.  
  455.     /* this replaces rotating the stipple. Instead we just adjust the offset
  456.      * at which we start grabbing bits from the stipple.
  457.      * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
  458.      * so that iline and xrem always stay within the stipple bounds.
  459.      */
  460.     modulus (pGC->patOrg.x, stippleWidth, xSrc);
  461.     xSrc += pDrawable->x - stippleWidth;
  462.     modulus (pGC->patOrg.y, stippleHeight, ySrc);
  463.     ySrc += pDrawable->y - stippleHeight;
  464.  
  465.     while (n--)
  466.     {
  467.     iline = (ppt->y - ySrc) % stippleHeight;
  468.     x = ppt->x;
  469.     pdst = addrlBase + (ppt->y * nlwidth);
  470.         psrcS = (int *) pStipple->devPrivate.ptr + (iline * stwidth);
  471.  
  472.     if (*pwidth)
  473.     {
  474.         width = *pwidth;
  475.         while(width > 0)
  476.         {
  477.             int xtemp, tmpx;
  478.         register unsigned int *ptemp;
  479.         register int *pdsttmp;
  480.         /*
  481.          *  Do a stripe through the stipple & destination w pixels
  482.          *  wide.  w is not more than:
  483.          *    -    the width of the destination
  484.          *    -    the width of the stipple
  485.          *    -    the distance between x and the next word 
  486.          *        boundary in the destination
  487.          *    -    the distance between x and the next word
  488.          *        boundary in the stipple
  489.          */
  490.  
  491.         /* width of dest/stipple */
  492.                 xrem = (x - xSrc) % stippleWidth;
  493.             w = min((stippleWidth - xrem), width);
  494.         /* dist to word bound in dest */
  495.         w = min(w, PPW - (x & PIM));
  496.         /* dist to word bound in stip */
  497.         w = min(w, 32 - (x & 0x1f));
  498.  
  499.             xtemp = (xrem & 0x1f);
  500.             ptemp = (unsigned int *)(psrcS + (xrem >> 5));
  501.         tmpx = x & PIM;
  502.         pdsttmp = pdst + (x>>PWSH);
  503.         switch ( pGC->fillStyle ) {
  504.             case FillOpaqueStippled:
  505.             getstipplepixels(ptemp, xtemp, w, 0, &bgfill, &tmpDst1);
  506.             getstipplepixels(ptemp, xtemp, w, 1, &fgfill, &tmpDst2);
  507.             break;
  508.             case FillStippled:
  509.             /* Fill tmpSrc with the source pixels */
  510.             getbits(pdsttmp, tmpx, w, tmpSrc);
  511.             getstipplepixels(ptemp, xtemp, w, 0, &tmpSrc, &tmpDst1);
  512.             if (rop != stiprop) {
  513.                 putbitsrop(fgfill, 0, w, &tmpSrc, pGC->planemask, stiprop);
  514.             } else {
  515.                 tmpSrc = fgfill;
  516.             }
  517.             getstipplepixels(ptemp, xtemp, w, 1, &tmpSrc, &tmpDst2);
  518.             break;
  519.         }
  520.         tmpDst2 |= tmpDst1;
  521.         putbitsrop(tmpDst2, tmpx, w, pdsttmp, pGC->planemask, rop);
  522.         x += w;
  523.         width -= w;
  524.         }
  525.     }
  526.     ppt++;
  527.     pwidth++;
  528.     }
  529.     DEALLOCATE_LOCAL(pptFree);
  530.     DEALLOCATE_LOCAL(pwidthFree);
  531. }
  532.  
  533. #endif /* PPW == 4 */
  534.  
  535. #if PPW == 4
  536.  
  537. void
  538. cfb8Stipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  539.     DrawablePtr pDrawable;
  540.     GCPtr    pGC;
  541.     int        nInit;            /* number of spans to fill */
  542.     DDXPointPtr pptInit;        /* pointer to list of start points */
  543.     int        *pwidthInit;        /* pointer to list of n widths */
  544.     int     fSorted;
  545. {
  546.                 /* next three parameters are post-clip */
  547.     int            n;            /* number of spans to fill */
  548.     DDXPointPtr        ppt;        /* pointer to list of start points */
  549.     int            *pwidth;        /* pointer to list of n widths */
  550.     unsigned long   *src;        /* pointer to bits in stipple, if needed */
  551.     int            stippleHeight;    /* height of the stipple */
  552.     PixmapPtr        stipple;
  553.  
  554.     int            nlwDst;        /* width in longwords of the dest pixmap */
  555.     int            x,y,w;        /* current span */
  556.     unsigned long   startmask;
  557.     unsigned long   endmask;
  558.     register unsigned long *dst;    /* pointer to bits we're writing */
  559.     register int    nlw;
  560.     unsigned long   *dstTmp;
  561.     int            nlwTmp;
  562.  
  563.     unsigned long   *pbits;        /* pointer to start of pixmap */
  564.     register unsigned long  xor;
  565.     register unsigned long  mask;
  566.     register unsigned long  bits;    /* bits from stipple */
  567.     int            wEnd;
  568.  
  569.     int            *pwidthFree;    /* copies of the pointers to free */
  570.     DDXPointPtr        pptFree;
  571.     cfbPrivGCPtr    devPriv;
  572.  
  573.     devPriv = (cfbPrivGCPtr) pGC->devPrivates[cfbGCPrivateIndex].ptr;
  574.     cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
  575.     n = nInit * miFindMaxBand(devPriv->pCompositeClip);
  576.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  577.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  578.     if(!pptFree || !pwidthFree)
  579.     {
  580.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  581.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  582.     return;
  583.     }
  584.     pwidth = pwidthFree;
  585.     ppt = pptFree;
  586.     n = miClipSpans(devPriv->pCompositeClip,
  587.              pptInit, pwidthInit, nInit,
  588.              ppt, pwidth, fSorted);
  589.  
  590.     stipple = devPriv->pRotatedPixmap;
  591.     src = (unsigned long *)stipple->devPrivate.ptr;
  592.     stippleHeight = stipple->drawable.height;
  593.  
  594.     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
  595.  
  596.     while (n--)
  597.     {
  598.         w = *pwidth++;
  599.     x = ppt->x;
  600.         y = ppt->y;
  601.     ppt++;
  602.         dst = pbits + (y * nlwDst) + (x >> PWSH);
  603.     if (((x & PIM) + w) <= PPW)
  604.     {
  605.         maskpartialbits(x, w, startmask);
  606.         endmask = 0;
  607.         nlw = 0;
  608.     }
  609.     else
  610.     {
  611.         maskbits (x, w, startmask, endmask, nlw);
  612.     }
  613.     bits = src[y % stippleHeight];
  614.     RotBitsLeft (bits, (x & (31 & ~3)));
  615.     if (cfb8StippleRRop == GXcopy)
  616.     {
  617.         xor = devPriv->xor;
  618.         if (w < 64)
  619.         {
  620.         if (startmask)
  621.         {
  622.             mask = cfb8PixelMasks[GetFourBits(bits)];
  623.             *dst = (*dst & ~(mask & startmask)) |
  624.                (xor & (mask & startmask));
  625.             dst++;
  626.             RotBitsLeft (bits, 4);
  627.         }
  628.         while (nlw--)
  629.         {
  630.             WriteFourBits (dst,xor,GetFourBits(bits))
  631.             dst++;
  632.             RotBitsLeft (bits, 4);
  633.         }
  634.         if (endmask)
  635.         {
  636.             mask = cfb8PixelMasks[GetFourBits(bits)];
  637.             *dst = (*dst & ~(mask & endmask)) |
  638.                (xor & (mask & endmask));
  639.         }
  640.         }
  641.         else
  642.         {
  643.         wEnd = 7 - (nlw & 7);
  644.         nlw = (nlw >> 3) + 1;
  645.         dstTmp = dst;
  646.         nlwTmp = nlw;
  647.         if (startmask)
  648.         {
  649.             mask = cfb8PixelMasks[GetFourBits(bits)];
  650.             *dstTmp = (*dstTmp & ~(mask & startmask)) |
  651.                (xor & (mask & startmask));
  652.             dstTmp++;
  653.             RotBitsLeft (bits, 4);
  654.         }
  655.         w = 7 - wEnd;
  656.         while (w--)
  657.         {
  658.             dst = dstTmp;
  659.             dstTmp++;
  660.             nlw = nlwTmp;
  661. #if defined(__GNUC__) && defined(mc68020)
  662.             mask = cfb8PixelMasks[GetFourBits(bits)];
  663.             xor = xor & mask;
  664.             mask = ~mask;
  665.             while (nlw--)
  666.             {
  667.             *dst = (*dst & mask) | xor;
  668.             dst += 8;
  669.             }
  670.             xor = devPriv->xor;
  671. #else
  672. #define SwitchBitsLoop(body) \
  673.     while (nlw--)    \
  674.     {        \
  675.     body    \
  676.     dst += 8;    \
  677.     }
  678.             SwitchFourBits(dst, xor, GetFourBits(bits));
  679. #undef SwitchBitsLoop
  680. #endif
  681.             NextFourBits (bits);
  682.         }
  683.         nlwTmp--;
  684.         w = wEnd + 1;
  685.         if (endmask)
  686.         {
  687.             mask = cfb8PixelMasks[GetFourBits(bits)];
  688.             dst = dstTmp + (nlwTmp << 3);
  689.             *dst = (*dst & ~(mask & endmask)) |
  690.                (xor &  (mask & endmask));
  691.         }
  692.         while (w--)
  693.         {
  694.             nlw = nlwTmp;
  695.             dst = dstTmp;
  696.             dstTmp++;
  697. #if defined(__GNUC__) && defined(mc68020)
  698.             mask = cfb8PixelMasks[GetFourBits(bits)];
  699.             xor = xor & mask;
  700.             mask = ~mask;
  701.             while (nlw--)
  702.             {
  703.             *dst = (*dst & mask) | xor;
  704.             dst += 8;
  705.             }
  706.             xor = devPriv->xor;
  707. #else
  708. #define SwitchBitsLoop(body) \
  709.     while (nlw--)    \
  710.     {        \
  711.         body    \
  712.         dst += 8;    \
  713.     }
  714.             SwitchFourBits(dst, xor, GetFourBits(bits));
  715. #undef SwitchBitsLoop
  716. #endif
  717.             NextFourBits (bits);
  718.         }
  719.         }
  720.     }
  721.     else
  722.     {
  723.         if (startmask)
  724.         {
  725.         xor = GetFourBits(bits);
  726.         *dst = MaskRRopPixels(*dst, xor, startmask);
  727.         dst++;
  728.         RotBitsLeft (bits, 4);
  729.         }
  730.         while (nlw--)
  731.         {
  732.         RRopFourBits(dst, GetFourBits(bits));
  733.         dst++;
  734.         RotBitsLeft (bits, 4);
  735.         }
  736.         if (endmask)
  737.         {
  738.         xor = GetFourBits(bits);
  739.         *dst = MaskRRopPixels(*dst, xor, endmask);
  740.         }
  741.     }
  742.     }
  743.     DEALLOCATE_LOCAL(pptFree);
  744.     DEALLOCATE_LOCAL(pwidthFree);
  745. }
  746.  
  747. void
  748. cfb8OpaqueStipple32FS (pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  749.     DrawablePtr pDrawable;
  750.     GCPtr    pGC;
  751.     int        nInit;            /* number of spans to fill */
  752.     DDXPointPtr pptInit;        /* pointer to list of start points */
  753.     int        *pwidthInit;        /* pointer to list of n widths */
  754.     int     fSorted;
  755. {
  756.                 /* next three parameters are post-clip */
  757.     int            n;            /* number of spans to fill */
  758.     DDXPointPtr        ppt;        /* pointer to list of start points */
  759.     int            *pwidth;        /* pointer to list of n widths */
  760.     unsigned long   *src;        /* pointer to bits in stipple, if needed */
  761.     int            stippleHeight;    /* height of the stipple */
  762.     PixmapPtr        stipple;
  763.  
  764.     int            nlwDst;        /* width in longwords of the dest pixmap */
  765.     int            x,y,w;        /* current span */
  766.     unsigned long   startmask;
  767.     unsigned long   endmask;
  768.     register unsigned long *dst;    /* pointer to bits we're writing */
  769.     register int    nlw;
  770.     unsigned long   *dstTmp;
  771.     int            nlwTmp;
  772.  
  773.     unsigned long   *pbits;        /* pointer to start of pixmap */
  774.     register unsigned long  xor;
  775.     register unsigned long  mask;
  776.     register unsigned long  bits;    /* bits from stipple */
  777.     int            wEnd;
  778.  
  779.     int            *pwidthFree;    /* copies of the pointers to free */
  780.     DDXPointPtr        pptFree;
  781.     cfbPrivGCPtr    devPriv;
  782.  
  783.     devPriv = (cfbPrivGCPtr) pGC->devPrivates[cfbGCPrivateIndex].ptr;
  784.  
  785.     cfb8CheckOpaqueStipple(pGC->alu, pGC->fgPixel, pGC->bgPixel, pGC->planemask);
  786.  
  787.     n = nInit * miFindMaxBand(devPriv->pCompositeClip);
  788.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  789.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  790.     if(!pptFree || !pwidthFree)
  791.     {
  792.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  793.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  794.     return;
  795.     }
  796.     pwidth = pwidthFree;
  797.     ppt = pptFree;
  798.     n = miClipSpans(devPriv->pCompositeClip,
  799.              pptInit, pwidthInit, nInit,
  800.              ppt, pwidth, fSorted);
  801.  
  802.     stipple = devPriv->pRotatedPixmap;
  803.     src = (unsigned long *)stipple->devPrivate.ptr;
  804.     stippleHeight = stipple->drawable.height;
  805.  
  806.     cfbGetLongWidthAndPointer (pDrawable, nlwDst, pbits)
  807.  
  808.     while (n--)
  809.     {
  810.         w = *pwidth++;
  811.     x = ppt->x;
  812.         y = ppt->y;
  813.     ppt++;
  814.         dst = pbits + (y * nlwDst) + (x >> PWSH);
  815.     if (((x & PIM) + w) <= PPW)
  816.     {
  817.         maskpartialbits(x, w, startmask);
  818.         endmask = 0;
  819.         nlw = 0;
  820.     }
  821.     else
  822.     {
  823.         maskbits (x, w, startmask, endmask, nlw);
  824.     }
  825.     bits = src[y % stippleHeight];
  826.     RotBitsLeft (bits, (x & (31 & ~3)));
  827.     if (cfb8StippleRRop == GXcopy)
  828.     {
  829.         xor = devPriv->xor;
  830.         if (w < 64)
  831.         {
  832.         if (startmask)
  833.         {
  834.             *dst = *dst & ~startmask |
  835.                 GetFourPixels (bits) & startmask;
  836.             dst++;
  837.             RotBitsLeft (bits, 4);
  838.         }
  839.         while (nlw--)
  840.         {
  841.             *dst++ = GetFourPixels(bits);
  842.             RotBitsLeft (bits, 4);
  843.         }
  844.         if (endmask)
  845.         {
  846.             *dst = *dst & ~endmask |
  847.               GetFourPixels (bits) & endmask;
  848.         }
  849.         }
  850.         else
  851.         {
  852.         wEnd = 7 - (nlw & 7);
  853.         nlw = (nlw >> 3) + 1;
  854.         dstTmp = dst;
  855.         nlwTmp = nlw;
  856.         if (startmask)
  857.         {
  858.             *dstTmp = *dstTmp & ~startmask |
  859.                GetFourPixels (bits) & startmask;
  860.             dstTmp++;
  861.             RotBitsLeft (bits, 4);
  862.         }
  863.         w = 7 - wEnd;
  864.         while (w--)
  865.         {
  866.             nlw = nlwTmp;
  867.             dst = dstTmp;
  868.             dstTmp++;
  869.             xor = GetFourPixels (bits);
  870.             while (nlw--)
  871.             {
  872.             *dst = xor;
  873.             dst += 8;
  874.             }
  875.             NextFourBits (bits);
  876.         }
  877.         nlwTmp--;
  878.         w = wEnd + 1;
  879.         if (endmask)
  880.         {
  881.             dst = dstTmp + (nlwTmp << 3);
  882.             *dst = (*dst & ~endmask) |
  883.                GetFourPixels (bits) & endmask;
  884.         }
  885.         while (w--)
  886.         {
  887.             nlw = nlwTmp;
  888.             dst = dstTmp;
  889.             dstTmp++;
  890.             xor = GetFourPixels (bits);
  891.             while (nlw--)
  892.             {
  893.             *dst = xor;
  894.             dst += 8;
  895.             }
  896.             NextFourBits (bits);
  897.         }
  898.         }
  899.     }
  900.     else
  901.     {
  902.         if (startmask)
  903.         {
  904.         xor = GetFourBits(bits);
  905.         *dst = MaskRRopPixels(*dst, xor, startmask);
  906.         dst++;
  907.         RotBitsLeft (bits, 4);
  908.         }
  909.         while (nlw--)
  910.         {
  911.         RRopFourBits(dst, GetFourBits(bits));
  912.         dst++;
  913.         RotBitsLeft (bits, 4);
  914.         }
  915.         if (endmask)
  916.         {
  917.         xor = GetFourBits(bits);
  918.         *dst = MaskRRopPixels(*dst, xor, endmask);
  919.         }
  920.     }
  921.     }
  922.     DEALLOCATE_LOCAL(pptFree);
  923.     DEALLOCATE_LOCAL(pwidthFree);
  924. }
  925.  
  926. #endif
  927.