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

  1. /***********************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24. /***********************************************************
  25.               Copyright IBM Corporation 1987,1988
  26.  
  27.                       All Rights Reserved
  28.  
  29. Permission to use, copy, modify, and distribute this software and its
  30. documentation for any purpose and without fee is hereby granted,
  31. provided that the above copyright notice appear in all copies and that
  32. both that copyright notice and this permission notice appear in
  33. supporting documentation, and that the name of IBM not be
  34. used in advertising or publicity pertaining to distribution of the
  35. software without specific, written prior permission.
  36.  
  37. IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  38. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  39. IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  40. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  41. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  42. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  43. SOFTWARE.
  44.  
  45. ******************************************************************/
  46. /***********************************************************
  47. Copyright 1989 by the Massachusetts Institute of Technology
  48.  
  49.                      All rights reserved.
  50.  
  51. Permission to use, copy, modify, and distribute this software and its
  52. documentation for any purpose and without fee is hereby granted,
  53. provided that the above copyright notice appear in all copies and that
  54. both that copyright notice and this permission notice appear in
  55. supporting documentation, and that the name of the Massachusetts
  56. Institute of Technology (M.I.T.) not be used in advertising or publicity
  57. pertaining to distribution of the software without specific, written
  58. prior permission.
  59.  
  60. M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  61. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  62. M.I.T. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  63. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  64. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  65. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  66. SOFTWARE.
  67.  
  68. ******************************************************************/
  69. /* $XConsortium: apa16FlSp.c,v 1.2 90/03/05 13:53:30 swick Exp $ */
  70. #include "X.h"
  71. #include "Xmd.h"
  72. #include "gcstruct.h"
  73. #include "window.h"
  74. #include "pixmapstr.h"
  75. #include "scrnintstr.h"
  76. #include "windowstr.h"
  77. #include "mfb.h"
  78. #include "maskbits.h"
  79.  
  80. #include "servermd.h"
  81.  
  82. #include "OScompiler.h"
  83. #include "apa16Hdwr.h"
  84. #include "ibmTrace.h"
  85.  
  86. /* scanline filling for monochrome frame buffer
  87.    written by drewry, oct 1986
  88.    modified for apa16 by erik, may 1987
  89.    optimized by jfc, june 1991
  90.  
  91.    these routines all clip.  they assume that anything that has called
  92. them has already translated the points (i.e. pGC->miTranslate is
  93. non-zero, which is howit gets set in mfbCreateGC().)
  94.  
  95.    the number of new scnalines created by clipping ==
  96. MaxRectsPerBand * nSpans.
  97.  
  98.     FillSolid is overloaded to be used for OpaqueStipple as well,
  99. if fgPixel == bgPixel.  
  100.  
  101.  
  102.     FillTiled is overloaded to be used for OpaqueStipple, if
  103. fgPixel != bgPixel.  based on the fill style, it uses
  104. {RotatedPixmap, gc.alu} or {RotatedPixmap, PrivGC.ropOpStip}
  105. */
  106. void
  107. apa16SolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  108.     DrawablePtr pDrawable;
  109.     GCPtr    pGC;
  110.     int        nInit;            /* number of spans to fill */
  111.     DDXPointPtr pptInit;        /* pointer to list of start points */
  112.     int        *pwidthInit;        /* pointer to list of n widths */
  113.     int     fSorted;
  114. {
  115.                 /* next three parameters are post-clip */
  116.     int n;            /* number of spans to fill */
  117.     register DDXPointPtr ppt;    /* pointer to list of start points */
  118.     register int *pwidth;    /* pointer to list of n widths */
  119.     int rop;            /* reduced rasterop */
  120.     mfbPrivGC *gcpriv;
  121.  
  122.     if (!(pGC->planemask & 1) || nInit == 0) 
  123.     return;
  124.  
  125.     TRACE(("apa16SolidFS(pDrawable=%#x, pGC=%#x, n=%d, ppt=%#x {%d,%d}, pwidth=%#x (%d))\n",
  126.             pDrawable, pGC, nInit, pptInit, pptInit->x,
  127.             pptInit->y, pwidthInit, *pwidthInit));
  128.  
  129.     gcpriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
  130.     rop = gcpriv->rop;
  131.     if (rop==RROP_NOP)    return;
  132.  
  133.     if (pDrawable->type!=DRAWABLE_WINDOW) {
  134.     if (rop==RROP_WHITE)
  135.         mfbWhiteSolidFS(pDrawable,pGC,nInit,pptInit,pwidthInit,fSorted);
  136.     else if (rop==RROP_BLACK)
  137.         mfbBlackSolidFS(pDrawable,pGC,nInit,pptInit,pwidthInit,fSorted);
  138.     else if (rop==RROP_INVERT)
  139.         mfbInvertSolidFS(pDrawable,pGC,nInit,pptInit,pwidthInit,fSorted);
  140.     return;
  141.     }
  142.  
  143.     n = nInit * miFindMaxBand(gcpriv->pCompositeClip);
  144.     pwidth = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  145.     if (!pwidth)
  146.     return;
  147.     ppt = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  148.     if(!ppt)
  149.       {
  150.     DEALLOCATE_LOCAL(ppt);
  151.     return;
  152.       }
  153.     n = miClipSpans(gcpriv->pCompositeClip, pptInit, pwidthInit,
  154.             nInit, ppt, pwidth, fSorted);
  155.     if (n == 0)
  156.       return;
  157.  
  158.     if (rop == RROP_BLACK)
  159.       rop = STYPE_BLACK;
  160.     else if (rop == RROP_WHITE)
  161.       rop = STYPE_WHITE;
  162.     else /* rop == RROP_INVERT */
  163.       rop = STYPE_INVERT;
  164.  
  165.     apa16FastFS(pwidth, ppt, n, rop);
  166.     DEALLOCATE_LOCAL(ppt);
  167.     DEALLOCATE_LOCAL(pwidth);
  168.     return ;
  169. }
  170.  
  171. /* this works with tiles of width == 32 */
  172.  
  173. /* the "hard" way is used if writing neither 0 nor 1 to a bit can be
  174.    used as a noop. */
  175.  
  176. #define FILLSPAN32_HARD(ROP) \
  177.     while (--n >= 0) \
  178.     { register unsigned int *addrl; \
  179.     if (*pwidth) \
  180.     { \
  181.         addrl = ((unsigned int *)APA16_BASE) + (ppt->y * (APA16_WIDTH / 32)) + (ppt->x >> 5); \
  182.         src = psrc[ppt->y % tileHeight]; \
  183.         if ( ((ppt->x & 0x1f) + *pwidth) < 32) \
  184.         { \
  185.         maskpartialbits(ppt->x, *pwidth, startmask); \
  186.         *addrl = (*addrl & ~startmask) | (ROP(src, *addrl) & startmask); \
  187.         } \
  188.         else \
  189.         { \
  190.         maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
  191.         if (startmask) \
  192.         { \
  193.             *addrl = (*addrl & ~startmask) | \
  194.                  (ROP(src, *addrl) & startmask); \
  195.             addrl++; \
  196.         } \
  197.         while (nlmiddle--) \
  198.         { \
  199.             *addrl = ROP(src, *addrl); \
  200.             addrl++; \
  201.         } \
  202.         if (endmask) \
  203.             *addrl = (*addrl & ~endmask) | \
  204.                  (ROP(src, *addrl) & endmask); \
  205.         } \
  206.     } \
  207.     pwidth++; \
  208.     ppt++; \
  209.     }
  210.  
  211. /* This version is modified for the apa16: it assumes that
  212.    the mode register has been set and writing NOP has no
  213.    effect with the current setting. */
  214.  
  215. #define FILLSPAN32(NOP) \
  216.     while (--n >= 0) \
  217.     { register unsigned int *addrl; \
  218.     if (*pwidth) \
  219.     { \
  220.         addrl = ((unsigned int *)APA16_BASE) + (ppt->y * (APA16_WIDTH / 32)) + (ppt->x >> 5); \
  221.         src = psrc[ppt->y % tileHeight]; \
  222.         if ( ((ppt->x & 0x1f) + *pwidth) < 32) \
  223.         { \
  224.         maskpartialbits(ppt->x, *pwidth, startmask); \
  225.         *addrl = (NOP & ~startmask) | (src & startmask); \
  226.         } \
  227.         else \
  228.         { \
  229.         maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
  230.         if (startmask) \
  231.           *addrl++ = (src & startmask) | (NOP & ~startmask); \
  232.         while (nlmiddle--) \
  233.           *addrl++ = src; \
  234.         if (endmask) \
  235.           *addrl = (NOP & ~endmask) | (src & endmask); \
  236.         } \
  237.     } \
  238.     pwidth++; \
  239.     ppt++; \
  240.     }
  241.  
  242.  
  243.  
  244. void
  245. apa16TileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  246. DrawablePtr pDrawable;
  247. GC *pGC;
  248. int nInit;            /* number of spans to fill */
  249. DDXPointPtr pptInit;        /* pointer to list of start points */
  250. int *pwidthInit;        /* pointer to list of n widths */
  251. int fSorted;
  252. {
  253.                 /* next three parameters are post-clip */
  254.     int n;            /* number of spans to fill */
  255.     register DDXPointPtr ppt;    /* pointer to list of start points */
  256.     register int *pwidth;    /* pointer to list of n widths */
  257.     register int startmask;
  258.     register int endmask;
  259.     register int nlmiddle;
  260.     PixmapPtr pTile;
  261.     int *psrc;
  262.     register int src;
  263.     int tileHeight;
  264.     int rop;
  265.     int *pwidthFree;        /* copies of the pointers to free */
  266.     DDXPointPtr pptFree;
  267.     mfbPrivGC *gcpriv = (mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr);
  268.  
  269.     if (!(pGC->planemask & 1))
  270.     return;
  271.  
  272.     if (pDrawable->type != DRAWABLE_WINDOW)
  273.       {
  274.     mfbTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
  275.     return;
  276.       }
  277.  
  278.     n = nInit * miFindMaxBand(gcpriv->pCompositeClip);
  279.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  280.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  281.     if(!pptFree || !pwidthFree)
  282.     {
  283.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  284.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  285.     return;
  286.     }
  287.     pwidth = pwidthFree;
  288.     ppt = pptFree;
  289.     n = miClipSpans(gcpriv->pCompositeClip, pptInit, pwidthInit,
  290.             nInit, ppt, pwidth, fSorted);
  291.  
  292. #if FAST_TILE
  293.     if (!pGC->tileIsPixel)
  294.       {
  295.     pTile = pGC->tile.pixmap;
  296.     if (pTile->drawable.width >= 16)
  297.       {
  298.         apa16FastTileFS(pwidth, ppt, n, apa16_rop2stype[pGC->alu],
  299.                 pTile->devPrivate.ptr, pTile->drawable.width,
  300.                 pTile->drawable.height, pTile->devKind,
  301.                 pGC->patOrg.x + pDrawable->x,
  302.                 pGC->patOrg.y + pDrawable->y);
  303.         DEALLOCATE_LOCAL(pptFree);
  304.         DEALLOCATE_LOCAL(pwidthFree);
  305.         return;
  306.       }
  307.       }
  308. #endif
  309.  
  310.     SET_MERGE_MODE(MERGE_COPY);
  311.  
  312.     pTile = gcpriv->pRotatedPixmap;
  313.     tileHeight = pTile->drawable.height;
  314.     psrc = (int *)(pTile->devPrivate.ptr);
  315.     if (pGC->fillStyle == FillTiled)
  316.       rop = pGC->alu;
  317.     else
  318.       rop = gcpriv->ropOpStip;
  319.  
  320.     switch(rop)
  321.     {
  322.       case GXclear:
  323.     FILLSPAN32_HARD(fnCLEAR)
  324.     break;
  325.       case GXand:
  326.     MR = (MR_DEFAULT & MERGE_MODE_MASK) | MERGE_AND;
  327.     FILLSPAN32(~0)
  328.     MR = MR_DEFAULT;
  329.     break;
  330.       case GXandReverse:
  331.     MR = (MR_DEFAULT & MERGE_MODE_MASK) | MERGE_BLACK;
  332.     goto fs32_0;
  333.       case GXcopy:
  334.     FILLSPAN32_HARD(fnCOPY)
  335.     break;
  336.       case GXandInverted:
  337.     FILLSPAN32_HARD(fnANDINVERTED)
  338.     break;
  339.       case GXnoop:
  340.     break;
  341.       case GXxor:
  342.     FILLSPAN32_HARD(fnXOR)
  343.     break;
  344.       case GXor:
  345.     MR = (MR_DEFAULT & MERGE_MODE_MASK) | MERGE_WHITE;
  346.        fs32_0:
  347.     FILLSPAN32(0)
  348.     MR = MR_DEFAULT;
  349.     break;
  350.       case GXnor:
  351.     FILLSPAN32_HARD(fnNOR)
  352.     break;
  353.       case GXequiv:
  354.     FILLSPAN32_HARD(fnEQUIV)
  355.     break;
  356.       case GXinvert:
  357.     MR = (MR_DEFAULT & MERGE_MODE_MASK) | MERGE_INVERT;
  358.        goto fs32_0;
  359.       case GXorReverse:
  360.     FILLSPAN32_HARD(fnORREVERSE)
  361.     break;
  362.       case GXcopyInverted:
  363.     FILLSPAN32_HARD(fnCOPYINVERTED)
  364.     break;
  365.       case GXorInverted:
  366.     FILLSPAN32_HARD(fnORINVERTED)
  367.     break;
  368.       case GXnand:
  369.     FILLSPAN32_HARD(fnNAND)
  370.     break;
  371.       case GXset:
  372.     FILLSPAN32_HARD(fnSET)
  373.     break;
  374.     }
  375.     DEALLOCATE_LOCAL(pptFree);
  376.     DEALLOCATE_LOCAL(pwidthFree);
  377.     return ;
  378. }
  379.  
  380.  
  381.  
  382. /* Fill spans with tiles that aren't 32 bits wide */
  383. void
  384. apa16UnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  385. DrawablePtr pDrawable;
  386. GC        *pGC;
  387. int        nInit;        /* number of spans to fill */
  388. DDXPointPtr pptInit;        /* pointer to list of start points */
  389. int *pwidthInit;        /* pointer to list of n widths */
  390. int fSorted;
  391. {
  392.     int        iline;        /* first line of tile to use */
  393.                 /* next three parameters are post-clip */
  394.     int n;            /* number of spans to fill */
  395.     register DDXPointPtr ppt;    /* pointer to list of start points */
  396.     register int *pwidth;    /* pointer to list of n widths */
  397.     register unsigned int *pdst;/* pointer to current word in bitmap */
  398.     register unsigned int *psrc;/* pointer to current word in tile */
  399.     register unsigned int startmask;
  400.     register int nlMiddle;
  401.     PixmapPtr    pTile;        /* pointer to tile we want to fill with */
  402.     int        w, width, x, xSrc, ySrc, srcStartOver, nstart, nend;
  403.     int     tlwidth, rem, tileWidth, tileHeight, endinc, rop;
  404.     unsigned int      endmask, *psrcT;
  405.     int *pwidthFree;        /* copies of the pointers to free */
  406.     DDXPointPtr pptFree;
  407.  
  408.     if (!(pGC->planemask & 1))
  409.     return;
  410.  
  411.     if (pDrawable->type != DRAWABLE_WINDOW)
  412.       {
  413.     mfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
  414.     return;
  415.       }
  416.  
  417.     n = nInit *
  418.       miFindMaxBand(((mfbPrivGC *)
  419.              (pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip);
  420.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  421.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  422.     if(!pptFree || !pwidthFree)
  423.     {
  424.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  425.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  426.     return;
  427.     }
  428.     pwidth = pwidthFree;
  429.     ppt = pptFree;
  430.     n = miClipSpans(((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip,
  431.             pptInit, pwidthInit, nInit, 
  432.             ppt, pwidth, fSorted);
  433.  
  434.  
  435. #ifdef FAST_TILE
  436.     if (!pGC->tileIsPixel)
  437.       {
  438.     pTile = pGC->tile.pixmap;
  439.     if (pTile->drawable.width >= 16)
  440.       {
  441.         apa16FastTileFS(pwidth, ppt, n, apa16_rop2stype[pGC->alu],
  442.                 pTile->devPrivate.ptr, pTile->drawable.width,
  443.                 pTile->drawable.height, pTile->devKind,
  444.                 pGC->patOrg.x + pDrawable->x,
  445.                 pGC->patOrg.y + pDrawable->y);
  446.         DEALLOCATE_LOCAL(pptFree);
  447.         DEALLOCATE_LOCAL(pwidthFree);
  448.         return;
  449.       }
  450.       }
  451. #endif
  452.  
  453.     if (pGC->fillStyle == FillTiled)
  454.     {
  455.     pTile = pGC->tile.pixmap;
  456.     tlwidth = pTile->devKind >> 2;
  457.     rop = pGC->alu;
  458.     }
  459.     else
  460.     {
  461.     pTile = pGC->stipple;
  462.     tlwidth = pTile->devKind >> 2;
  463.     rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->ropOpStip;
  464.     }
  465.  
  466.     if (rop == GXnoop) {
  467.     DEALLOCATE_LOCAL(pptFree);
  468.     DEALLOCATE_LOCAL(pwidthFree);
  469.     return;
  470.       }
  471.  
  472.     xSrc = pDrawable->x;
  473.     ySrc = pDrawable->y;
  474.  
  475.     tileWidth = pTile->drawable.width;
  476.     tileHeight = pTile->drawable.height;
  477.  
  478.     /* this replaces rotating the tile. Instead we just adjust the offset
  479.      * at which we start grabbing bits from the tile.
  480.      * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
  481.      * so that iline and rem always stay within the tile bounds.
  482.      */
  483.     xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
  484.     ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
  485.  
  486.     QUEUE_WAIT();
  487.  
  488.     while (n--)
  489.     {
  490.     iline = (ppt->y - ySrc) % tileHeight;
  491.         pdst = (unsigned int *)APA16_BASE + (ppt->y * (APA16_WIDTH / 32)) + (ppt->x >> 5);
  492.         psrcT = (unsigned int *) pTile->devPrivate.ptr + (iline * tlwidth);
  493.     x = ppt->x;
  494.  
  495.     if (*pwidth)
  496.     {
  497.         width = *pwidth;
  498.         while(width > 0)
  499.         {
  500.         psrc = psrcT;
  501.             w = MIN(tileWidth, width);
  502.         if((rem = (x - xSrc)  % tileWidth) != 0)
  503.         {
  504.             /* if we're in the middle of the tile, get
  505.                as many bits as will finish the span, or
  506.                as many as will get to the left edge of the tile,
  507.                or a longword worth, starting at the appropriate
  508.                offset in the tile.
  509.             */
  510.             w = MIN(MIN(tileWidth - rem, width), BITMAP_SCANLINE_UNIT);
  511.             endinc = rem / BITMAP_SCANLINE_UNIT;
  512.             getandputrop((psrc+endinc), (rem&0x1f), (x & 0x1f), w, pdst, rop);
  513.             if((x & 0x1f) + w >= 0x20)
  514.             pdst++;
  515.         }
  516.         else if(((x & 0x1f) + w) < 32)
  517.         {
  518.             /* doing < 32 bits is easy, and worth special-casing */
  519.             putbitsrop(*psrc, x & 0x1f, w, pdst, rop);
  520.         }
  521.         else
  522.         {
  523.             /* start at the left edge of the tile,
  524.                and put down as much as we can
  525.             */
  526.             maskbits(x, w, startmask, endmask, nlMiddle);
  527.  
  528.                 if (startmask)
  529.                 nstart = 32 - (x & 0x1f);
  530.                 else
  531.                 nstart = 0;
  532.                 if (endmask)
  533.                     nend = (x + w)  & 0x1f;
  534.                 else
  535.                 nend = 0;
  536.  
  537.                 srcStartOver = nstart > 31;
  538.  
  539.             if(startmask)
  540.             {
  541.             putbitsrop(*psrc, (x & 0x1f), nstart, pdst, rop);
  542.             pdst++;
  543.             if(srcStartOver)
  544.                 psrc++;
  545.             }
  546.              
  547.             while(nlMiddle--)
  548.             {
  549.                 getandputrop0(psrc, nstart, 32, pdst, rop);
  550.                 pdst++;
  551.                 psrc++;
  552.             }
  553.             if(endmask)
  554.             {
  555.             getandputrop0(psrc, nstart, nend, pdst, rop);
  556.             }
  557.          }
  558.          x += w;
  559.          width -= w;
  560.         }
  561.     }
  562.     ppt++;
  563.     pwidth++;
  564.     }
  565.     DEALLOCATE_LOCAL(pptFree);
  566.     DEALLOCATE_LOCAL(pwidthFree);
  567. }
  568.  
  569.  
  570. /* Fill spans with stipples that aren't 32 bits wide */
  571. void
  572. apa16UnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
  573. DrawablePtr pDrawable;
  574. GC        *pGC;
  575. int        nInit;        /* number of spans to fill */
  576. DDXPointPtr pptInit;        /* pointer to list of start points */
  577. int *pwidthInit;        /* pointer to list of n widths */
  578. int fSorted;
  579. {
  580.                 /* next three parameters are post-clip */
  581.     int n;            /* number of spans to fill */
  582.     register DDXPointPtr ppt;    /* pointer to list of start points */
  583.     register int *pwidth;    /* pointer to list of n widths */
  584.     int        iline;        /* first line of tile to use */
  585.     register unsigned int *pdst;/* pointer to current word in bitmap */
  586.     register int *psrc;        /* pointer to current word in tile */
  587.     register int startmask;
  588.     register int nlMiddle;
  589.     PixmapPtr    pTile;        /* pointer to tile we want to fill with */
  590.     int        w, width,  x, xSrc, ySrc, srcStartOver, nstart, nend;
  591.     int     endmask, tlwidth, rem, tileWidth, *psrcT, endinc, rop;
  592.     int        tileHeight;
  593.     int *pwidthFree;        /* copies of the pointers to free */
  594.     DDXPointPtr pptFree;
  595.  
  596.     if (!(pGC->planemask & 1))
  597.     return;
  598.  
  599.     if (pDrawable->type != DRAWABLE_WINDOW)
  600.       {
  601.     mfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted);
  602.     return;
  603.       }
  604.  
  605.     n = nInit * miFindMaxBand(((mfbPrivGC *)
  606.                    (pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip);
  607.     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
  608.     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
  609.     if(!pptFree || !pwidthFree)
  610.     {
  611.     if (pptFree) DEALLOCATE_LOCAL(pptFree);
  612.     if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
  613.     return;
  614.     }
  615.     pwidth = pwidthFree;
  616.     ppt = pptFree;
  617.     n = miClipSpans(((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip,
  618.             pptInit, pwidthInit, nInit, 
  619.             ppt, pwidth, fSorted);
  620.  
  621.     pTile = pGC->stipple;
  622.     rop = ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->rop;
  623.     if (rop == GXnoop) 
  624.       {
  625.     DEALLOCATE_LOCAL(pptFree);
  626.     DEALLOCATE_LOCAL(pwidthFree);
  627.     return;
  628.       }
  629.     tlwidth = pTile->devKind >> 2;
  630.     xSrc = pDrawable->x;
  631.     ySrc = pDrawable->y;
  632.  
  633.     tileWidth = pTile->drawable.width;
  634.     tileHeight = pTile->drawable.height;
  635.  
  636.     /* this replaces rotating the stipple.  Instead, we just adjust the offset
  637.      * at which we start grabbing bits from the stipple.
  638.      * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
  639.      * so that iline and rem always stay within the tile bounds.
  640.      */
  641.     xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
  642.     ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
  643.  
  644.     QUEUE_WAIT();
  645.  
  646.     while (n--)
  647.     {
  648.     iline = (ppt->y - ySrc) % tileHeight;
  649.         pdst = (unsigned int *)APA16_BASE + (ppt->y * (APA16_WIDTH / 32)) + (ppt->x >> 5);
  650.         psrcT = (int *) pTile->devPrivate.ptr + (iline * tlwidth);
  651.     x = ppt->x;
  652.  
  653.     if (*pwidth)
  654.     {
  655.         width = *pwidth;
  656.         while(width > 0)
  657.         {
  658.         psrc = psrcT;
  659.             w = MIN(tileWidth, width);
  660.         if((rem = (x - xSrc) % tileWidth) != 0)
  661.         {
  662.             /* if we're in the middle of the tile, get
  663.                as many bits as will finish the span, or
  664.                as many as will get to the left edge of the tile,
  665.                or a longword worth, starting at the appropriate
  666.                offset in the tile.
  667.             */
  668.             w = MIN(MIN(tileWidth - rem, width), BITMAP_SCANLINE_UNIT);
  669.             endinc = rem / BITMAP_SCANLINE_UNIT;
  670.             getandputrrop((psrc + endinc), (rem & 0x1f), (x & 0x1f),
  671.                  w, pdst, rop)
  672.             if((x & 0x1f) + w >= 0x20)
  673.             pdst++;
  674.         }
  675.  
  676.         else if(((x & 0x1f) + w) < 32)
  677.         {
  678.             /* doing < 32 bits is easy, and worth special-casing */
  679.             putbitsrrop(*psrc, x & 0x1f, w, pdst, rop);
  680.         }
  681.         else
  682.         {
  683.             /* start at the left edge of the tile,
  684.                and put down as much as we can
  685.             */
  686.             maskbits(x, w, startmask, endmask, nlMiddle);
  687.  
  688.                 if (startmask)
  689.                 nstart = 32 - (x & 0x1f);
  690.                 else
  691.                 nstart = 0;
  692.                 if (endmask)
  693.                     nend = (x + w)  & 0x1f;
  694.                 else
  695.                 nend = 0;
  696.  
  697.                 srcStartOver = nstart > 31;
  698.  
  699.             if(startmask)
  700.             {
  701.             putbitsrrop(*psrc, (x & 0x1f), nstart, pdst, rop);
  702.             pdst++;
  703.             if(srcStartOver)
  704.                 psrc++;
  705.             }
  706.              
  707.             while(nlMiddle--)
  708.             {
  709.                 getandputrrop0(psrc, nstart, 32, pdst, rop);
  710.                 pdst++;
  711.                 psrc++;
  712.             }
  713.             if(endmask)
  714.             {
  715.             getandputrrop0(psrc, nstart, nend, pdst, rop);
  716.             }
  717.          }
  718.          x += w;
  719.          width -= w;
  720.         }
  721.     }
  722.     ppt++;
  723.     pwidth++;
  724.     }
  725.     DEALLOCATE_LOCAL(pptFree);
  726.     DEALLOCATE_LOCAL(pwidthFree);
  727. }
  728.