home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / cfb / cfbfillrct.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-05-15  |  6.9 KB  |  293 lines

  1. /*
  2.  * Fill rectangles.
  3.  */
  4.  
  5. /*
  6. Copyright 1989 by the Massachusetts Institute of Technology
  7.  
  8. Permission to use, copy, modify, and distribute this software and its
  9. documentation for any purpose and without fee is hereby granted,
  10. provided that the above copyright notice appear in all copies and that
  11. both that copyright notice and this permission notice appear in
  12. supporting documentation, and that the name of M.I.T. not be used in
  13. advertising or publicity pertaining to distribution of the software
  14. without specific, written prior permission.  M.I.T. makes no
  15. representations about the suitability of this software for any
  16. purpose.  It is provided "as is" without express or implied warranty.
  17. */
  18.  
  19. /* $XConsortium: cfbfillrct.c,v 5.13 90/05/15 18:40:19 keith Exp $ */
  20.  
  21. #include "X.h"
  22. #include "Xmd.h"
  23. #include "servermd.h"
  24. #include "gcstruct.h"
  25. #include "window.h"
  26. #include "pixmapstr.h"
  27. #include "scrnintstr.h"
  28. #include "windowstr.h"
  29.  
  30. #include "cfb.h"
  31. #include "cfbmskbits.h"
  32. #include "mergerop.h"
  33.  
  34. #if PPW == 4
  35. extern void cfb8FillRectOpaqueStippled32();
  36. extern void cfb8FillRectTransparentStippled32();
  37. extern void cfb8FillRectStippledUnnatural();
  38. #endif
  39.  
  40. extern void cfbFillRectSolidCopy(), cfbFillRectSolidXor (), cfbFillRectSolidGeneral ();
  41.  
  42. extern void cfbFillRectTile32Copy (), cfbFillRectTile32General ();
  43.  
  44. extern void cfbFillBoxTileOddCopy ();
  45. extern void cfbFillBoxTileOddGeneral ();
  46. extern void cfbFillBoxTile32sCopy ();
  47. extern void cfbFillBoxTile32sGeneral ();
  48.  
  49. void
  50. cfbFillBoxTileOdd (pDrawable, n, rects, tile, xrot, yrot)
  51.     DrawablePtr    pDrawable;
  52.     int        n;
  53.     BoxPtr    rects;
  54.     PixmapPtr    tile;
  55.     int        xrot, yrot;
  56. {
  57.     if (tile->drawable.width & PIM)
  58.     cfbFillBoxTileOddCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0);
  59.     else
  60.     cfbFillBoxTile32sCopy (pDrawable, n, rects, tile, xrot, yrot, GXcopy, ~0);
  61. }
  62.  
  63. void
  64. cfbFillRectTileOdd (pDrawable, pGC, nBox, pBox)
  65.     DrawablePtr    pDrawable;
  66.     GCPtr    pGC;
  67.     int        nBox;
  68.     BoxPtr    pBox;
  69. {
  70.     int    xrot, yrot;
  71.     void    (*fill)();
  72.  
  73.     xrot = pDrawable->x + pGC->patOrg.x;
  74.     yrot = pDrawable->y + pGC->patOrg.y;
  75.     if (pGC->tile.pixmap->drawable.width & PIM)
  76.     {
  77.         fill = cfbFillBoxTileOddGeneral;
  78.         if ((pGC->planemask & PMSK) == PMSK)
  79.         {
  80.         if (pGC->alu == GXcopy)
  81.             fill = cfbFillBoxTileOddCopy;
  82.         }
  83.     }
  84.     else
  85.     {
  86.         fill = cfbFillBoxTile32sGeneral;
  87.         if ((pGC->planemask & PMSK) == PMSK)
  88.         {
  89.         if (pGC->alu == GXcopy)
  90.             fill = cfbFillBoxTile32sCopy;
  91.         }
  92.     }
  93.     (*fill) (pDrawable, nBox, pBox, pGC->tile.pixmap, xrot, yrot, pGC->alu, pGC->planemask);
  94. }
  95.  
  96. #define NUM_STACK_RECTS    1024
  97.  
  98. void
  99. cfbPolyFillRect(pDrawable, pGC, nrectFill, prectInit)
  100.     DrawablePtr pDrawable;
  101.     register GCPtr pGC;
  102.     int        nrectFill;     /* number of rectangles to fill */
  103.     xRectangle    *prectInit;      /* Pointer to first rectangle to fill */
  104. {
  105.     xRectangle        *prect;
  106.     RegionPtr        prgnClip;
  107.     register BoxPtr pbox;
  108.     register BoxPtr pboxClipped;
  109.     BoxPtr        pboxClippedBase;
  110.     BoxPtr        pextent;
  111.     BoxRec        stackRects[NUM_STACK_RECTS];
  112.     cfbPrivGC        *priv;
  113.     int            numRects;
  114.     void        (*BoxFill)();
  115.     int            n;
  116.     int            xorg, yorg;
  117.  
  118.     priv = (cfbPrivGC *) pGC->devPrivates[cfbGCPrivateIndex].ptr;
  119.     prgnClip = priv->pCompositeClip;
  120.  
  121.     BoxFill = 0;
  122.     switch (pGC->fillStyle)
  123.     {
  124.     case FillSolid:
  125.     switch (priv->rop) {
  126.     case GXcopy:
  127.         BoxFill = cfbFillRectSolidCopy;
  128.         break;
  129.     case GXxor:
  130.         BoxFill = cfbFillRectSolidXor;
  131.         break;
  132.     default:
  133.         BoxFill = cfbFillRectSolidGeneral;
  134.         break;
  135.     }
  136.     break;
  137.     case FillTiled:
  138.     if (!((cfbPrivGCPtr) pGC->devPrivates[cfbGCPrivateIndex].ptr)->
  139.                             pRotatedPixmap)
  140.         BoxFill = cfbFillRectTileOdd;
  141.     else
  142.     {
  143.         if (pGC->alu == GXcopy && (pGC->planemask & PMSK) == PMSK)
  144.         BoxFill = cfbFillRectTile32Copy;
  145.         else
  146.         BoxFill = cfbFillRectTile32General;
  147.     }
  148.     break;
  149. #if (PPW == 4)
  150.     case FillStippled:
  151.     if (!((cfbPrivGCPtr) pGC->devPrivates[cfbGCPrivateIndex].ptr)->
  152.                             pRotatedPixmap)
  153.         BoxFill = cfb8FillRectStippledUnnatural;
  154.     else
  155.         BoxFill = cfb8FillRectTransparentStippled32;
  156.     break;
  157.     case FillOpaqueStippled:
  158.     if (!((cfbPrivGCPtr) pGC->devPrivates[cfbGCPrivateIndex].ptr)->
  159.                             pRotatedPixmap)
  160.         BoxFill = cfb8FillRectStippledUnnatural;
  161.     else
  162.         BoxFill = cfb8FillRectOpaqueStippled32;
  163.     break;
  164. #endif
  165.     }
  166.     prect = prectInit;
  167.     xorg = pDrawable->x;
  168.     yorg = pDrawable->y;
  169.     if (xorg || yorg)
  170.     {
  171.     prect = prectInit;
  172.     n = nrectFill;
  173.     while(n--)
  174.     {
  175.         prect->x += xorg;
  176.         prect->y += yorg;
  177.         prect++;
  178.     }
  179.     }
  180.  
  181.     prect = prectInit;
  182.  
  183.     numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
  184.     if (numRects > NUM_STACK_RECTS)
  185.     {
  186.     pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
  187.     if (!pboxClippedBase)
  188.         return;
  189.     }
  190.     else
  191.     pboxClippedBase = stackRects;
  192.  
  193.     pboxClipped = pboxClippedBase;
  194.     
  195.     if (REGION_NUM_RECTS(prgnClip) == 1)
  196.     {
  197.     int x1, y1, x2, y2, bx2, by2;
  198.  
  199.     pextent = REGION_RECTS(prgnClip);
  200.     x1 = pextent->x1;
  201.     y1 = pextent->y1;
  202.     x2 = pextent->x2;
  203.     y2 = pextent->y2;
  204.         while (nrectFill--)
  205.         {
  206.         if ((pboxClipped->x1 = prect->x) < x1)
  207.         pboxClipped->x1 = x1;
  208.     
  209.         if ((pboxClipped->y1 = prect->y) < y1)
  210.         pboxClipped->y1 = y1;
  211.     
  212.         bx2 = (int) prect->x + (int) prect->width;
  213.         if (bx2 > x2)
  214.         bx2 = x2;
  215.         pboxClipped->x2 = bx2;
  216.     
  217.         by2 = (int) prect->y + (int) prect->height;
  218.         if (by2 > y2)
  219.         by2 = y2;
  220.         pboxClipped->y2 = by2;
  221.  
  222.         prect++;
  223.         if ((pboxClipped->x1 < pboxClipped->x2) &&
  224.         (pboxClipped->y1 < pboxClipped->y2))
  225.         {
  226.         pboxClipped++;
  227.         }
  228.         }
  229.     }
  230.     else
  231.     {
  232.     int x1, y1, x2, y2, bx2, by2;
  233.  
  234.     pextent = (*pGC->pScreen->RegionExtents)(prgnClip);
  235.     x1 = pextent->x1;
  236.     y1 = pextent->y1;
  237.     x2 = pextent->x2;
  238.     y2 = pextent->y2;
  239.         while (nrectFill--)
  240.         {
  241.         BoxRec box;
  242.     
  243.         if ((box.x1 = prect->x) < x1)
  244.         box.x1 = x1;
  245.     
  246.         if ((box.y1 = prect->y) < y1)
  247.         box.y1 = y1;
  248.     
  249.         bx2 = (int) prect->x + (int) prect->width;
  250.         if (bx2 > x2)
  251.         bx2 = x2;
  252.         box.x2 = bx2;
  253.     
  254.         by2 = (int) prect->y + (int) prect->height;
  255.         if (by2 > y2)
  256.         by2 = y2;
  257.         box.y2 = by2;
  258.     
  259.         prect++;
  260.     
  261.         if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
  262.             continue;
  263.     
  264.         n = REGION_NUM_RECTS (prgnClip);
  265.         pbox = REGION_RECTS(prgnClip);
  266.     
  267.         /* clip the rectangle to each box in the clip region
  268.            this is logically equivalent to calling Intersect()
  269.         */
  270.         while(n--)
  271.         {
  272.         pboxClipped->x1 = max(box.x1, pbox->x1);
  273.         pboxClipped->y1 = max(box.y1, pbox->y1);
  274.         pboxClipped->x2 = min(box.x2, pbox->x2);
  275.         pboxClipped->y2 = min(box.y2, pbox->y2);
  276.         pbox++;
  277.  
  278.         /* see if clipping left anything */
  279.         if(pboxClipped->x1 < pboxClipped->x2 && 
  280.            pboxClipped->y1 < pboxClipped->y2)
  281.         {
  282.             pboxClipped++;
  283.         }
  284.         }
  285.         }
  286.     }
  287.     if (pboxClipped != pboxClippedBase)
  288.     (*BoxFill) (pDrawable, pGC,
  289.             pboxClipped-pboxClippedBase, pboxClippedBase);
  290.     if (pboxClippedBase != stackRects)
  291.         DEALLOCATE_LOCAL(pboxClippedBase);
  292. }
  293.