home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / X / mit / server / ddx / dec / qdss / qdpushpxl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-07-19  |  10.4 KB  |  351 lines

  1. /***********************************************************
  2. Copyright 1987, 1988 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. /***********************************************************
  26. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  27. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  28.  
  29.                         All Rights Reserved
  30.  
  31. Permission to use, copy, modify, and distribute this software and its 
  32. documentation for any purpose and without fee is hereby granted, 
  33. provided that the above copyright notice appear in all copies and that
  34. both that copyright notice and this permission notice appear in 
  35. supporting documentation, and that the names of Digital or MIT not be
  36. used in advertising or publicity pertaining to distribution of the
  37. software without specific, written prior permission.  
  38.  
  39. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  40. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  41. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  42. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  43. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  44. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  45. SOFTWARE.
  46.  
  47. ******************************************************************/
  48.  
  49. #include "X.h"
  50. #include "Xmd.h"
  51. #include "gcstruct.h"
  52. #include "screenint.h"
  53. #include "scrnintstr.h"
  54. #include "windowstr.h"
  55. #include "pixmapstr.h"
  56. #include "regionstr.h"
  57.  
  58. #include "../../mfb/maskbits.h"
  59.  
  60. #include "qd.h"
  61. #include "qdgc.h"
  62.  
  63. /* PushPixels to absolete screen coordinates */
  64.  
  65. static void
  66. qdPushPixelsToScreen(pGC, pBitMap, dx, dy, xOrg, yOrg)
  67.     GCPtr        pGC;
  68.     QDPixPtr        pBitMap;
  69.     int            dx, dy, xOrg, yOrg;
  70. {
  71.     xOrg += pGC->lastWinOrg.x;
  72.     yOrg += pGC->lastWinOrg.y;
  73.     if (QDPIX_Y(pBitMap) != NOTOFFSCREEN) {
  74.     tlPlaneTile(pGC, xOrg, yOrg, dx, dy,
  75.                QDPIX_X(pBitMap),
  76.                QDPIX_Y(pBitMap),
  77.                pBitMap->planes);
  78.     } else {
  79.     /* fillStyle must be FillSolid */
  80.     RegionPtr pcl = QDGC_COMPOSITE_CLIP(pGC);
  81.     register BoxPtr    rects = REGION_RECTS(pcl);
  82.     int ic;
  83.     for (ic = REGION_NUM_RECTS(pcl); --ic >= 0; rects++)
  84.         {
  85.         BoxRec    cb;
  86.  
  87.         cb.x1 = max( rects->x1, xOrg);
  88.         cb.y1 = max( rects->y1, yOrg);
  89.         cb.x2 = min( rects->x2, xOrg+dx);
  90.         cb.y2 = min( rects->y2, yOrg+dy);
  91.  
  92.         if (cb.x1 < cb.x2 && cb.y1 < cb.y2)
  93.             tlBitmapStipple(pGC, pBitMap, pGC->fgPixel, pGC->bgPixel,
  94.                     xOrg, yOrg, &cb);
  95.         }
  96.     }
  97. }
  98.  
  99. /*
  100.  * xxPushPixels
  101.  * pBitMap is a stencil (dx by dy of it is used, it may
  102.  * be bigger) which is placed on the drawable at xOrg, yOrg.  Where a 1 bit
  103.  * is set in the bitmap, the foreground pattern is put onto the drawable using
  104.  * the GC's logical function. The drawable is not changed where the bitmap
  105.  * has a zero bit or outside the area covered by the stencil.
  106. */
  107. void
  108. qdPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
  109.     GCPtr        pGC;
  110.     PixmapPtr        pBitMap;
  111.     DrawablePtr     pDrawable;
  112.     int            dx, dy, xOrg, yOrg;
  113. {
  114.  
  115.     /*
  116.      * If pDrawable is not the screen
  117.      */
  118.     if ( pDrawable->type == UNDRAWABLE_WINDOW)
  119.     return;
  120.     if (pGC->fillStyle != FillSolid && !tlConfirmPixmap(pBitMap)) {
  121.     qdUnnaturalPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
  122.     return;
  123.     }
  124.  
  125.     if ( pDrawable->type == DRAWABLE_PIXMAP)
  126.     {
  127.     CHECK_MOVED(pGC, pDrawable);
  128.     if (QD_PIX_DATA((PixmapPtr)pDrawable) == NULL) {
  129.         SETUP_PIXMAP_AS_WINDOW(pDrawable, pGC);
  130.         qdPushPixelsToScreen(pGC, pBitMap, dx, dy, xOrg, yOrg);
  131.         CLEANUP_PIXMAP_AS_WINDOW(pGC);
  132.         }
  133. #if NPLANES<24
  134.     else if (pDrawable->depth > 1 && pGC->fillStyle == FillSolid) {
  135.         extern unsigned int Allplanes;
  136.         int ix, iy;
  137.         RegionPtr pGCclip = QDGC_COMPOSITE_CLIP(pGC);
  138.         BoxPtr pclip = REGION_RECTS(pGCclip);
  139.         int    nclip = REGION_NUM_RECTS(pGCclip);    /* number of clips */
  140.         int fast =
  141.           pGC->alu == GXcopy && (pGC->planemask & Allplanes) == Allplanes;
  142.         tlCancelPixmap(pBitMap);
  143.         for ( ; --nclip >= 0; pclip++) { /* for each clip rectangle */
  144.             unsigned char *maskStart = QD_PIX_DATA(pBitMap);
  145.         unsigned char *pdst = QD_PIX_DATA((PixmapPtr)pDrawable)
  146.           + xOrg + yOrg *  QDPIX_WIDTH((PixmapPtr)pDrawable);
  147.         int skip; /* used for clipping calculations */
  148.         int x1 = 0, x2 = dx; /* coordinates relative to pBitMap */
  149.         int height = dy;
  150.         /* do x clipping */
  151.         skip = xOrg + dx - pclip->x2;
  152.         if (skip > 0) x2 -= skip;
  153.         skip = pclip->x1 - xOrg;
  154.         if (skip > 0) {
  155.             pdst += skip;
  156.             x1 += skip;
  157.         }
  158.         /* do y clipping */
  159.         skip = yOrg + dy - pclip->y2;
  160.         if (skip > 0) height -= skip;
  161.         skip = pclip->y1 - yOrg;
  162.         if (skip > 0) {
  163.             pdst += skip * QDPIX_WIDTH((PixmapPtr)pDrawable);
  164.             maskStart += skip * pBitMap->devKind;
  165.             height -= skip;
  166.         }
  167.         skip = x1 - x2; /* -(effective width) */
  168.         if (skip >= 0) continue;
  169.         skip += QDPIX_WIDTH((PixmapPtr)pDrawable);
  170.         for (iy = 0; iy < height; iy++) {
  171.             if (fast)
  172.                 for (ix = x1; ix < x2; ix++, pdst++) {
  173.                 if (maskStart[ix >> 3] & (1 << (ix&7))) {
  174.                     *pdst = pGC->fgPixel;
  175.                 }
  176.                     }
  177.             else
  178.                 for (ix = x1; ix < x2; ix++, pdst++) {
  179.                 if (maskStart[ix >> 3] & (1 << (ix&7))) {
  180.                     qddopixel(&pGC->fgPixel, pdst, pGC);
  181.                     }
  182.                     }
  183.             maskStart += pBitMap->devKind;
  184.             pdst += skip;
  185.             } /* for each scanline */
  186.         } /* for each clip rectangle */
  187.         }
  188. #endif
  189.     else {
  190.         /* Otherwise, miPushPixels violates qdGetSpans convention */
  191.         tlCancelPixmap(pBitMap);
  192.  
  193.         miPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
  194.     }
  195.     return;
  196.     }
  197.  
  198.     /*
  199.      * now do the real work
  200.      */
  201.     qdPushPixelsToScreen(pGC, pBitMap, dx, dy, xOrg, yOrg);
  202. }
  203.  
  204. qdUnnaturalPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
  205.     GCPtr        pGC;
  206.     PixmapPtr        pBitMap;
  207.     DrawablePtr     pDrawable;
  208.     int            dx, dy, xOrg, yOrg;
  209. {
  210. /*
  211.  * We cannot call miPushPixels if pBitMap is in offscreen memory,
  212.  * since it fails to adjust coordinates by pBitMap->drawable.{x,y},
  213.  * thus violating the (new) qdGetSpans interface.
  214.  */
  215.     tlCancelPixmap(pBitMap);
  216.     miPushPixels( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg);
  217. }
  218.  
  219. #if 0
  220. /*
  221.  * This should be faster than miPushPixels to a Pixmap, because this
  222.  * routine can take advantage of knowledge of the dragon-specific
  223.  * pixmap representation.
  224.  *    DON'T NEED SPEED YET, SO THIS IS NOT CALLED    XXX
  225.  */
  226. #define MAX3( a, b, c)    ( (a)>(b)&&(a)>(c) ? (a) : (((b)>(c))?(b):(c)))
  227. #define MIN3( a, b, c)    ( (a)<(b)&&(a)<(c) ? (a) : (((b)<(c))?(b):(c)))
  228.  
  229. extern    int    Nplanes;
  230. extern    int    Nentries;
  231. extern    int    Nchannels;
  232.  
  233. static void
  234. qdPPpixmap( pGC, pBitMap, pDrawable, dx, dy, xOrg, yOrg)
  235.     GCPtr        pGC;
  236.     PixmapPtr        pBitMap;
  237.     PixmapPtr         pDrawable;
  238.     int            dx, dy, xOrg, yOrg;
  239. {
  240.     PixmapPtr        pDp = (PixmapPtr) pDrawable; /* destination Pixmap */
  241.     int            ch;    /* channel index */
  242.     int            ic;    /* clip box index */
  243.  
  244.     /*
  245.      * for each channel in destination pixmap
  246.      */
  247.     for ( ch=0; ch<Nchannels; ch++)
  248.     {
  249.     RegionPtr        pcl;
  250.     register BoxPtr    p1box;
  251.     unsigned char *pd =
  252.         QD_PIX_DATA(pDp) + ch * QDPIX_WIDTH(pDp) * QDPIX_HEIGHT(pDp);
  253.      
  254.     /*
  255.      * for each clipping rectangle
  256.      */
  257.     pcl = QDGC_COMPOSITE_CLIP(pGC);
  258.     p1box = REGION_RECTS(pcl);
  259.     for (ic = REGION_NUM_RECTS(pcl); --ic >= 0; p1box++)
  260.     {
  261.  
  262.         qdPPPix1chan( pGC, pBitMap, pDrawable, ch, 
  263.             MAX3( 0, xOrg, p1box->x1),
  264.             MAX3( 0, yOrg, p1box->y1),
  265.             MIN3( pDrawable->width, xOrg+dx, p1box->x2),
  266.             MIN3( pDrawable->height, yOrg+dy, p1box->y2),
  267.             xOrg, yOrg);
  268.     }
  269.     }
  270. }
  271.  
  272.  
  273. #define FATAL(x)    \
  274.     { fprintf(stderr, "fatal error in qdspans, %s\n", x); exit(1) }
  275. #define PIXDEPTH(x) ((x->drawable).depth)
  276.  
  277. /*
  278.  * box clipped by caller
  279.  * bitmap could be clipped too
  280.  */
  281. static
  282. qdPPPix1chan( pGC, pBitMap, pPixmap, ch, x1, y1, x2, y2, xOrg, yOrg)
  283.     GCPtr        pGC;        /* note that clipping is already done */
  284.     PixmapPtr        pBitMap;
  285.     PixmapPtr        pPixmap;
  286.     int            ch;        /* which group of 8 planes? */
  287.     int            x1, y1, x2, y2;    /* clipping rectangle in pixmap coords*/
  288.     int                 xOrg, yOrg;     /* origin of bitmap within pixmap */
  289. {
  290. #ifdef undef
  291.     int            mask[];
  292.  
  293.     register int    chmask = 0xff << (ch*8);
  294.     u_char *        destorig = QD_PIX_DATA(pPixmap)
  295.                     [ nch * pPixmap->width * pPixmap->height]; 
  296.     int            swlongs = 
  297.         pBitMap->devKind>>2;    /* width of source bitmap in longs */
  298.     unsigned *        psr;        /* pointer to bitmap source row */
  299.     int            sr;        /* bitmap source row */
  300.     int            sc;        /* bitmap source column */
  301.     int            dr;        /* destination row */
  302.     int            dc;        /* destination column */
  303.     int            bit;        /* effectively, a boolean */
  304.     char        bytetab[256];
  305.  
  306.  
  307.     switch (pGC->fillStyle) {
  308.       case FillOpaqueStippled:
  309.       case FillStippled:
  310.       case FillSolid:
  311.         {
  312.     initializeLookup( bytetab, pGC);/*accounts for output state in the GC*/
  313.  
  314.     /*
  315.      * for each row in source bitmap
  316.      */
  317.     for (    sr = y1-yOrg, psr = (unsigned *)pBitmap->devPrivate+swlongs*sr;
  318.         sr < y2-yOrg;
  319.         sr++, psr += swlongs)
  320.         /*
  321.          * for each column in source bitmap
  322.          */
  323.         for ( sc=x1-xOrg; sc < x2-xOrg; sc++)
  324.         {
  325.         /*
  326.          * examine each bit.  "mask" is from maskbits.c
  327.          */
  328.         bit = psr[ sc>>5] & mask[ sc&0x1f] ? 1 : 0;
  329.         /*
  330.          * apply alu function and write result
  331.          */
  332.         pdr[ dc] = bytetab[ pdr[ dc]] [ bit];
  333.         }
  334.     }
  335.     break;
  336.       case FillTiled:
  337.     break;
  338.     }
  339. #endif
  340. }
  341.  
  342.  
  343. static
  344. initializeLookup( bytetab, pGC)
  345.     char    bytetab[];
  346.     GCPtr               pGC;
  347.  
  348. {
  349. }
  350. #endif
  351.