REPOST: v04i089: R3 Sun Server Speedups, Part03/03
Dan Heller
argv at island.uu.net
Wed Aug 16 08:17:12 AEST 1989
Submitted-by: uunet!inf.rl.ac.uk!taw
Posting-number: Volume 4, Issue 89
Archive-name: ral.speedups/part03
[ No one seems to have gotten this, so I'm reposting. --argv ]
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 2 (of 3)."
# Contents: sunBW2.c.patch sunGC.c.patch sunbitblt.c.patch
# sunplygblt.c.patch sunpntarea.c.patch suntegblt.c.patch
# Wrapped by taw at box on Wed Aug 2 15:45:04 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'sunBW2.c.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sunBW2.c.patch'\"
else
echo shar: Extracting \"'sunBW2.c.patch'\" \(607 characters\)
sed "s/^X//" >'sunBW2.c.patch' <<'END_OF_FILE'
X*** sunBW2.c.slow Tue Apr 25 09:54:26 1989
X--- sunBW2.c Tue Apr 25 09:59:55 1989
X***************
X*** 234,243 ****
X--- 234,251 ----
X {
X ColormapPtr pColormap;
X
X+ #ifdef RAL
X+ /* Use RAL sunScreenInit */
X+ if (!psunScreenInit(index, pScreen,
X+ sunFbs[index].fb,
X+ sunFbs[index].info.fb_width,
X+ sunFbs[index].info.fb_height, 90, 90))
X+ #else original
X if (!mfbScreenInit(index, pScreen,
X sunFbs[index].fb,
X sunFbs[index].info.fb_width,
X sunFbs[index].info.fb_height, 90, 90))
X+ #endif
X return (FALSE);
X
X pScreen->SaveScreen = sunBW2SaveScreen;
END_OF_FILE
if test 607 -ne `wc -c <'sunBW2.c.patch'`; then
echo shar: \"'sunBW2.c.patch'\" unpacked with wrong size!
fi
# end of 'sunBW2.c.patch'
fi
if test -f 'sunGC.c.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sunGC.c.patch'\"
else
echo shar: Extracting \"'sunGC.c.patch'\" \(746 characters\)
sed "s/^X//" >'sunGC.c.patch' <<'END_OF_FILE'
X*** sunGC.c.slow Tue Apr 25 10:00:31 1989
X--- sunGC.c Wed Aug 2 09:10:20 1989
X***************
X*** 1531,1537 ****
X */
X Bool
X sunCreateGC (pGC)
X! GCPtr pGC; /* The GC to play with */
X {
X GCInterestPtr pGCI;
X register GCPtr pShadowGC;
X--- 1531,1537 ----
X */
X Bool
X sunCreateGC (pGC)
X! register GCPtr pGC; /* The GC to play with */
X {
X GCInterestPtr pGCI;
X register GCPtr pShadowGC;
X***************
X*** 1552,1557 ****
X--- 1552,1558 ----
X *pShadowGC = *pGC;
X pGC->devPriv = (pointer)pShadowGC;
X bcopy (sunGCFuncs, &pGC->FillSpans, sizeof (sunGCFuncs));
X+ ((mfbPrivGCPtr)(pShadowGC->devPriv))->FillArea = sunSolidInvertArea;
X
X pGCI = (GCInterestPtr) Xalloc (sizeof (GCInterestRec));
X if (!pGCI) {
END_OF_FILE
if test 746 -ne `wc -c <'sunGC.c.patch'`; then
echo shar: \"'sunGC.c.patch'\" unpacked with wrong size!
fi
# end of 'sunGC.c.patch'
fi
if test -f 'sunbitblt.c.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sunbitblt.c.patch'\"
else
echo shar: Extracting \"'sunbitblt.c.patch'\" \(19505 characters\)
sed "s/^X//" >'sunbitblt.c.patch' <<'END_OF_FILE'
X*** sunbitblt.c.slow Tue Aug 1 09:49:21 1989
X--- sunbitblt.c Mon May 15 09:45:28 1989
X***************
X*** 0 ****
X--- 1,654 ----
X+ /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
X+ #include "sun.h"
X+ #include "Xprotostr.h"
X+ #include "font.h"
X+ #include "fontstruct.h"
X+
X+ #include "maskbits.h"
X+
X+ char *malloc ();
X+
X+ /* CopyArea and CopyPlane for a monchrome sun frame buffer
X+
X+
X+ clip the source rectangle to the source's available bits. (this
X+ avoids copying unnecessary pieces that will just get exposed anyway.)
X+ this becomes the new shape of the destination.
X+ clip the destination region to the composite clip in the
X+ GC. this requires translating the destination region to (dstx, dsty).
X+ build a list of source points, one for each rectangle in the
X+ destination. this is a simple translation.
X+ go do the multiple rectangle copies
X+ do graphics exposures
X+ */
X+ /* #ifdef PURDUE!!!!
X+ ** Optimized for drawing pixmaps into windows, especially when drawing into
X+ ** unobscured windows. Calls to the general-purpose region code were
X+ ** replaced with rectangle-to-rectangle clipping comparisions. This is
X+ ** possible, since the pixmap is a single rectangle. In an unobscured
X+ ** window, the destination clip is also a single rectangle, and region
X+ ** code can be avoided entirely. This is a big savings, since the region
X+ ** code uses XAlloc() and makes many function calls.
X+ **
X+ ** In addition, if source is a pixmap, there is no need to call the
X+ ** expensive miHandleExposures() routine. Instead, we simply return NULL.
X+ **
X+ ** Previously, drawing a pixmap into an unobscured window executed at least
X+ ** 8 XAlloc()'s, 30 function calls, and hundreds of lines of code.
X+ **
X+ ** Now, the same operation requires no XAlloc()'s, no region function calls,
X+ ** and much less overhead. Nice for drawing lots of small pixmaps.
X+ */
X+
X+ static int sun_rop [] =
X+ {
X+ PIX_SRC & PIX_NOT (PIX_SRC),
X+ PIX_SRC & PIX_DST,
X+ PIX_SRC & PIX_NOT (PIX_DST),
X+ PIX_SRC,
X+ PIX_NOT (PIX_SRC) & PIX_DST,
X+ PIX_DST,
X+ PIX_SRC ^ PIX_DST,
X+ PIX_SRC | PIX_DST,
X+ PIX_NOT (PIX_SRC | PIX_DST),
X+ PIX_NOT (PIX_SRC ^ PIX_DST),
X+ PIX_NOT (PIX_DST),
X+ PIX_SRC | PIX_NOT (PIX_DST),
X+ PIX_NOT (PIX_SRC),
X+ PIX_NOT (PIX_SRC) | PIX_DST,
X+ PIX_SRC | PIX_NOT (PIX_DST),
X+ PIX_SRC | PIX_NOT (PIX_SRC),
X+ };
X+
X+ RegionPtr
X+ psunCopyArea(pSrcDrawable, pDstDrawable,
X+ pGC, srcx, srcy, width, height, dstx, dsty)
X+ register DrawablePtr pSrcDrawable;
X+ register DrawablePtr pDstDrawable;
X+ GC *pGC;
X+ int srcx, srcy;
X+ int width, height;
X+ int dstx, dsty;
X+ {
X+ #ifndef PURDUE
X+ BoxRec srcBox;
X+ #endif PURDUE
X+ RegionPtr prgnSrcClip; /* may be a new region, or just a copy */
X+ int realSrcClip = 0; /* non-0 if we've created a src clip */
X+
X+ RegionPtr prgnDst, prgnExposed;
X+ DDXPointPtr pptSrc;
X+ register DDXPointPtr ppt;
X+ register BoxPtr pbox;
X+ int i;
X+ register int dx;
X+ register int dy;
X+ xRectangle origSource;
X+ DDXPointRec origDest;
X+
X+ #ifdef PURDUE
X+ RegionRec fastRegion; /* special region for clipping to 1 box */
X+ BoxRec fastBox;
X+ int fastClip = 0; /* for fast clipping with pixmap source */
X+ int fastExpose = 0; /* for fast exposures with pixmap source */
X+ #endif PURDUE
X+
X+ origSource.x = srcx;
X+ origSource.y = srcy;
X+ origSource.width = width;
X+ origSource.height = height;
X+ origDest.x = dstx;
X+ origDest.y = dsty;
X+
X+ /* clip the source */
X+
X+ if (pSrcDrawable->type == DRAWABLE_PIXMAP)
X+ {
X+ if ((pSrcDrawable == pDstDrawable) &&
X+ (pGC->clientClipType == CT_NONE))
X+ {
X+ prgnSrcClip = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip;
X+ }
X+ else
X+ #ifndef PURDUE
X+ {
X+ BoxRec box;
X+
X+ box.x1 = 0;
X+ box.y1 = 0;
X+ box.x2 = ((PixmapPtr)pSrcDrawable)->width;
X+ box.y2 = ((PixmapPtr)pSrcDrawable)->height;
X+
X+ prgnSrcClip = (*pGC->pScreen->RegionCreate)(&box, 1);
X+ realSrcClip = 1;
X+ }
X+ #else PURDUE
X+ {
X+ /* Pixmap sources generate simple exposure events */
X+ fastExpose = 1;
X+
X+ /* Pixmap is just one clipping rectangle so we can avoid
X+ allocating a full-blown region. */
X+ fastClip = 1;
X+
X+ fastBox.x1 = srcx;
X+ fastBox.y1 = srcy;
X+ fastBox.x2 = srcx + width;
X+ fastBox.y2 = srcy + height;
X+
X+ /* Left and top are already clipped, so clip right and bottom */
X+ if (fastBox.x2 > ((PixmapPtr)pSrcDrawable)->width)
X+ fastBox.x2 = ((PixmapPtr)pSrcDrawable)->width;
X+ if (fastBox.y2 > ((PixmapPtr)pSrcDrawable)->height)
X+ fastBox.y2 = ((PixmapPtr)pSrcDrawable)->height;
X+
X+ /* Initialize the fast region */
X+ fastRegion.numRects = 1;
X+ fastRegion.rects = &fastBox;
X+ }
X+ #endif PURDUE
X+ }
X+ else
X+ {
X+ srcx += ((WindowPtr)pSrcDrawable)->absCorner.x;
X+ srcy += ((WindowPtr)pSrcDrawable)->absCorner.y;
X+ if (pGC->subWindowMode == IncludeInferiors)
X+ {
X+ if ((pSrcDrawable == pDstDrawable) &&
X+ (pGC->clientClipType == CT_NONE))
X+ {
X+ prgnSrcClip = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip;
X+ }
X+ else
X+ {
X+ prgnSrcClip = NotClippedByChildren((WindowPtr)pSrcDrawable);
X+ realSrcClip = 1;
X+ }
X+ }
X+ else
X+ {
X+ prgnSrcClip = ((WindowPtr)pSrcDrawable)->clipList;
X+ }
X+ }
X+
X+ #ifdef PURDUE
X+ /* Don't create a source region if we are doing a fast clip */
X+ if (!fastClip)
X+ #endif PURDUE
X+ {
X+ BoxRec srcBox;
X+
X+ srcBox.x1 = srcx;
X+ srcBox.y1 = srcy;
X+ srcBox.x2 = srcx + width;
X+ srcBox.y2 = srcy + height;
X+
X+ prgnDst = (*pGC->pScreen->RegionCreate)(&srcBox, 1);
X+ (*pGC->pScreen->Intersect)(prgnDst, prgnDst, prgnSrcClip);
X+ }
X+
X+ if (pDstDrawable->type == DRAWABLE_WINDOW)
X+ {
X+ if (!((WindowPtr)pDstDrawable)->realized)
X+ {
X+ #ifdef PURDUE
X+ if (!fastClip)
X+ #endif
X+ (*pGC->pScreen->RegionDestroy)(prgnDst);
X+ if (realSrcClip)
X+ (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
X+ return NULL;
X+ }
X+ dstx += ((WindowPtr)pDstDrawable)->absCorner.x;
X+ dsty += ((WindowPtr)pDstDrawable)->absCorner.y;
X+ }
X+
X+ dx = srcx - dstx;
X+ dy = srcy - dsty;
X+
X+ #ifndef PURDUE
X+ /* clip the shape of the dst to the destination composite clip */
X+ (*pGC->pScreen->TranslateRegion)(prgnDst, -dx, -dy);
X+ (*pGC->pScreen->Intersect)(prgnDst,
X+ prgnDst,
X+ ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
X+
X+ #else PURDUE
X+ /* Translate and clip the dst to the destination composite clip */
X+ if (fastClip)
X+ {
X+ /* Translate the region directly */
X+ fastBox.x1 -= dx;
X+ fastBox.x2 -= dx;
X+ fastBox.y1 -= dy;
X+ fastBox.y2 -= dy;
X+
X+ /* If the destination composite clip is one rectangle we can
X+ do the clip directly. Otherwise we have to create a full
X+ blown region and call intersect */
X+ if (((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->numRects == 1)
X+ {
X+ BoxPtr pBox = ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip->rects;
X+
X+ if (fastBox.x1 < pBox->x1) fastBox.x1 = pBox->x1;
X+ if (fastBox.x2 > pBox->x2) fastBox.x2 = pBox->x2;
X+ if (fastBox.y1 < pBox->y1) fastBox.y1 = pBox->y1;
X+ if (fastBox.y2 > pBox->y2) fastBox.y2 = pBox->y2;
X+
X+ /* Check to see if the region is empty */
X+ if (fastBox.x1 >= fastBox.x2 || fastBox.y1 >= fastBox.y2)
X+ fastRegion.numRects = 0;
X+
X+ /* Use the fast region for all future computation.
X+ The following code insures that RegionDestroy is not
X+ called on it. */
X+ prgnDst = &fastRegion;
X+ }
X+ else
X+ {
X+ /* We must turn off fastClip now, since we must create
X+ a full blown region. It is intersected with the
X+ composite clip below. */
X+ fastClip = 0;
X+ prgnDst = (*pGC->pScreen->RegionCreate)(&fastBox,1);
X+ }
X+ }
X+ else
X+ {
X+ (*pGC->pScreen->TranslateRegion)(prgnDst, -dx, -dy);
X+ }
X+
X+ if (!fastClip)
X+ {
X+ (*pGC->pScreen->Intersect)(prgnDst,
X+ prgnDst,
X+ ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
X+ }
X+ #endif PURDUE
X+ if (!prgnDst->numRects)
X+ {
X+ (*pGC->pScreen->RegionDestroy)(prgnDst);
X+ if (realSrcClip)
X+ (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
X+ return NULL;
X+ }
X+ if(!(pptSrc = (DDXPointPtr)ALLOCATE_LOCAL( prgnDst->numRects *
X+ sizeof(DDXPointRec))))
X+ {
X+ #ifdef PURDUE
X+ if (!fastClip)
X+ #endif PURDUE
X+ (*pGC->pScreen->RegionDestroy)(prgnDst);
X+ if (realSrcClip)
X+ (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
X+ return NULL;
X+ }
X+ pbox = prgnDst->rects;
X+ ppt = pptSrc;
X+ for (i=0; i<prgnDst->numRects; i++, pbox++, ppt++)
X+ {
X+ ppt->x = pbox->x1 + dx;
X+ ppt->y = pbox->y1 + dy;
X+ }
X+
X+ if (pGC->planemask & 1)
X+ sunDoBitblt(pSrcDrawable, pDstDrawable, pGC->alu, prgnDst, pptSrc);
X+
X+ prgnExposed = NULL;
X+ if (((mfbPrivGC *)(pGC->devPriv))->fExpose) {
X+ #ifdef PURDUE
X+ /* Pixmap sources generate a NoExposed (we return NULL to do this) */
X+ if (!fastExpose)
X+ #endif PURDUE
X+ prgnExposed =
X+ miHandleExposures(pSrcDrawable, pDstDrawable, pGC,
X+ origSource.x, origSource.y,
X+ origSource.width, origSource.height,
X+ origDest.x, origDest.y, 0);
X+ }
X+
X+ DEALLOCATE_LOCAL(pptSrc);
X+ #ifdef PURDUE
X+
X+ /* Destroy any created regions */
X+ if (!fastClip)
X+ #endif PURDUE
X+ (*pGC->pScreen->RegionDestroy)(prgnDst);
X+ if (realSrcClip)
X+ (*pGC->pScreen->RegionDestroy)(prgnSrcClip);
X+ return prgnExposed;
X+ }
X+
X+
X+ void PixrectFromPixmap (pSrcDrawable, source, srcmem)
X+ register DrawablePtr (pSrcDrawable);
X+ register struct pixrect *source;
X+ register struct mpr_data *srcmem;
X+ {
X+ register unsigned int *psrcBase; /* start bitmaps */
X+ register int widthSrc; /* add to get to same position in next line */
X+
X+ extern struct pixrectops mem_ops;
X+
X+ if (pSrcDrawable->type == DRAWABLE_WINDOW)
X+ {
X+ psrcBase = (unsigned int *)
X+ (((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devPrivate);
X+ widthSrc = (int)
X+ ((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->devKind
X+ >> 2;
X+ source->pr_size.x = (((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->width);
X+ source->pr_size.y = (((PixmapPtr)(pSrcDrawable->pScreen->devPrivate))->height);
X+ }
X+ else
X+ {
X+ psrcBase = (unsigned int *)(((PixmapPtr)pSrcDrawable)->devPrivate);
X+ widthSrc = (int)(((PixmapPtr)pSrcDrawable)->devKind) >> 2;
X+ source->pr_size.x = ((PixmapPtr)pSrcDrawable)->width;
X+ source->pr_size.y = ((PixmapPtr)pSrcDrawable)->height;
X+ }
X+
X+ source->pr_ops = &mem_ops;
X+ source->pr_depth = 1;
X+ source->pr_data = (char *) srcmem;
X+
X+ srcmem->md_linebytes = widthSrc << 2;
X+ srcmem->md_image = (short *) psrcBase;
X+ srcmem->md_offset.x = srcmem->md_offset.y = 0;
X+ srcmem->md_primary = 1;
X+ srcmem->md_flags = 0;
X+ }
X+
X+ /* DoBitblt() does multiple rectangle moves into the rectangles
X+ if src or dst is a window, the points have already been
X+ translated.
X+ */
X+
X+ sunDoBitblt(pSrcDrawable, pDstDrawable, alu, prgnDst, pptSrc)
X+ DrawablePtr pSrcDrawable;
X+ DrawablePtr pDstDrawable;
X+ int alu;
X+ RegionPtr prgnDst;
X+ DDXPointPtr pptSrc;
X+ {
X+ register BoxPtr pbox;
X+ int nbox;
X+
X+ BoxPtr pboxTmp, pboxNext, pboxBase, pboxNew1, pboxNew2;
X+ /* temporaries for shuffling rectangles */
X+ DDXPointPtr pptTmp, pptNew1, pptNew2;
X+ /* shuffling boxes entails shuffling the
X+ source points too */
X+ static struct pixrect source, destination;
X+ static struct mpr_data srcmem, dstmem;
X+ int careful;
X+
X+ PixrectFromPixmap (pSrcDrawable, &source, &srcmem);
X+ PixrectFromPixmap (pDstDrawable, &destination, &dstmem);
X+
X+ /* XXX we have to err on the side of safety when both are windows,
X+ * because we don't know if IncludeInferiors is being used.
X+ */
X+ careful = ((pSrcDrawable == pDstDrawable) ||
X+ ((pSrcDrawable->type == DRAWABLE_WINDOW) &&
X+ (pDstDrawable->type == DRAWABLE_WINDOW)));
X+
X+ pbox = prgnDst->rects;
X+ nbox = prgnDst->numRects;
X+
X+ pboxNew1 = NULL;
X+ pptNew1 = NULL;
X+ pboxNew2 = NULL;
X+ pptNew2 = NULL;
X+ if (careful && (pptSrc->y < pbox->y1))
X+ {
X+ /* walk source bottom to top */
X+ if (nbox > 1)
X+ {
X+ /* keep ordering in each band, reverse order of bands */
X+ pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
X+ if(!pboxNew1)
X+ return;
X+ pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
X+ if(!pptNew1)
X+ {
X+ DEALLOCATE_LOCAL(pboxNew1);
X+ return;
X+ }
X+ pboxBase = pboxNext = pbox+nbox-1;
X+ while (pboxBase >= pbox)
X+ {
X+ while ((pboxNext >= pbox) &&
X+ (pboxBase->y1 == pboxNext->y1))
X+ pboxNext--;
X+ pboxTmp = pboxNext+1;
X+ pptTmp = pptSrc + (pboxTmp - pbox);
X+ while (pboxTmp <= pboxBase)
X+ {
X+ *pboxNew1++ = *pboxTmp++;
X+ *pptNew1++ = *pptTmp++;
X+ }
X+ pboxBase = pboxNext;
X+ }
X+ pboxNew1 -= nbox;
X+ pbox = pboxNew1;
X+ pptNew1 -= nbox;
X+ pptSrc = pptNew1;
X+ }
X+ }
X+
X+ if (careful && (pptSrc->x < pbox->x1))
X+ {
X+ /* walk source right to left */
X+
X+ if (nbox > 1)
X+ {
X+ /* reverse order of rects in each band */
X+ pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec) * nbox);
X+ pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec) * nbox);
X+ if(!pboxNew2 || !pptNew2)
X+ {
X+ if (pptNew2) DEALLOCATE_LOCAL(pptNew2);
X+ if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2);
X+ if (pboxNew1)
X+ {
X+ DEALLOCATE_LOCAL(pptNew1);
X+ DEALLOCATE_LOCAL(pboxNew1);
X+ }
X+ return;
X+ }
X+ pboxBase = pboxNext = pbox;
X+ while (pboxBase < pbox+nbox)
X+ {
X+ while ((pboxNext < pbox+nbox) &&
X+ (pboxNext->y1 == pboxBase->y1))
X+ pboxNext++;
X+ pboxTmp = pboxNext;
X+ pptTmp = pptSrc + (pboxTmp - pbox);
X+ while (pboxTmp != pboxBase)
X+ {
X+ *pboxNew2++ = *--pboxTmp;
X+ *pptNew2++ = *--pptTmp;
X+ }
X+ pboxBase = pboxNext;
X+ }
X+ pboxNew2 -= nbox;
X+ pbox = pboxNew2;
X+ pptNew2 -= nbox;
X+ pptSrc = pptNew2;
X+ }
X+ }
X+
X+ while (nbox--)
X+ {
X+ if (pr_rop (&destination, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, sun_rop [alu], &source, pptSrc->x, pptSrc->y) == PIX_ERR)
X+ exit (3);
X+ pbox++;
X+ pptSrc++;
X+ }
X+
X+ /* free up stuff */
X+ if (pboxNew2)
X+ {
X+ DEALLOCATE_LOCAL(pptNew2);
X+ DEALLOCATE_LOCAL(pboxNew2);
X+ }
X+ if (pboxNew1)
X+ {
X+ DEALLOCATE_LOCAL(pptNew1);
X+ DEALLOCATE_LOCAL(pboxNew1);
X+ }
X+ }
X+
X+ int sunTileOrgX, sunTileOrgY;
X+
X+ void
X+ sunTileArea (pDrawable, nbox, pbox, alu, ppix)
X+ DrawablePtr pDrawable;
X+ int nbox;
X+ BoxPtr pbox;
X+ int alu;
X+ PixmapPtr ppix;
X+ {
X+ static struct pixrect tile, destination;
X+ static struct mpr_data tilemem, dstmem;
X+ int rop;
X+
X+ PixrectFromPixmap (pDrawable, &destination, &dstmem);
X+ PixrectFromPixmap (ppix, &tile, &tilemem);
X+ while (nbox--)
X+ {
X+ if (pr_replrop (&destination, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, sun_rop [alu], &tile, pbox->x1 - sunTileOrgX, pbox->y1 - sunTileOrgY) == PIX_ERR)
X+ exit (3);
X+ pbox++;
X+ }
X+ }
X+
X+ RegionPtr
X+ psunCopyPlane(pSrcDrawable, pDstDrawable,
X+ pGC, srcx, srcy, width, height, dstx, dsty, plane)
X+ DrawablePtr pSrcDrawable, pDstDrawable;
X+ register GC *pGC;
X+ int srcx, srcy;
X+ int width, height;
X+ int dstx, dsty;
X+ unsigned int plane;
X+ {
X+ int alu;
X+ RegionPtr prgnExposed;
X+
X+ /* XXX a deeper screen ought to wrap ValidateGC to get around this */
X+ if (pSrcDrawable->depth != 1)
X+ return miCopyPlane(pSrcDrawable, pDstDrawable,
X+ pGC, srcx, srcy, width, height, dstx, dsty, plane);
X+ if (plane != 1)
X+ return NULL;
X+
X+ if ((pGC->fgPixel == 1) && (pGC->bgPixel == 0))
X+ {
X+ prgnExposed = (*pGC->CopyArea)(pSrcDrawable, pDstDrawable,
X+ pGC, srcx, srcy, width, height, dstx, dsty);
X+ }
X+ else if (pGC->fgPixel == pGC->bgPixel)
X+ {
X+ alu = pGC->alu;
X+ pGC->alu = ReduceRop(pGC->alu, pGC->fgPixel);
X+ prgnExposed = (*pGC->CopyArea)(pSrcDrawable, pDstDrawable,
X+ pGC, srcx, srcy, width, height, dstx, dsty);
X+ pGC->alu = alu;
X+ }
X+ else /* need to invert the src */
X+ {
X+ alu = pGC->alu;
X+ pGC->alu = InverseAlu[alu];
X+ prgnExposed = psunCopyArea (pSrcDrawable, pDstDrawable,
X+ pGC, srcx, srcy, width, height, dstx, dsty);
X+ pGC->alu = alu;
X+ }
X+ return prgnExposed;
X+ }
X+
X+ extern WindowRec WindowTable[];
X+
X+ /* UNCLEAN!
X+ this code calls the bitblt helper code directly.
X+
X+ sunCopyWindow copies only the parts of the destination that are
X+ visible in the source.
X+ */
X+
X+ void
X+ psunCopyWindow(pWin, ptOldOrg, prgnSrc)
X+ WindowPtr pWin;
X+ DDXPointRec ptOldOrg;
X+ RegionPtr prgnSrc;
X+ {
X+ DDXPointPtr pptSrc;
X+ register DDXPointPtr ppt;
X+ RegionPtr prgnDst;
X+ register BoxPtr pbox;
X+ register int dx, dy;
X+ register int i, nbox;
X+ WindowPtr pwinRoot;
X+
X+ pwinRoot = &WindowTable[pWin->drawable.pScreen->myNum];
X+
X+ prgnDst = (* pWin->drawable.pScreen->RegionCreate)(NULL,
X+ pWin->borderClip->numRects);
X+
X+ dx = ptOldOrg.x - pWin->absCorner.x;
X+ dy = ptOldOrg.y - pWin->absCorner.y;
X+ (* pWin->drawable.pScreen->TranslateRegion)(prgnSrc, -dx, -dy);
X+ (* pWin->drawable.pScreen->Intersect)(prgnDst, pWin->borderClip, prgnSrc);
X+
X+ pbox = prgnDst->rects;
X+ nbox = prgnDst->numRects;
X+ if(!(pptSrc = (DDXPointPtr )ALLOCATE_LOCAL( prgnDst->numRects *
X+ sizeof(DDXPointRec))))
X+ return;
X+ ppt = pptSrc;
X+
X+ #ifndef PURDUE
X+ for (i=0; i<nbox; i++, ppt++, pbox++)
X+ {
X+ ppt->x = pbox->x1 + dx;
X+ ppt->y = pbox->y1 + dy;
X+ }
X+ #else
X+ i = nbox;
X+ Duff(i, ppt->x = pbox->x1 + dx; ppt->y = pbox->y1 + dy; ppt++; pbox++);
X+ #endif /* PURDUE */
X+
X+ sunDoBitblt(pwinRoot, pwinRoot, GXcopy, prgnDst, pptSrc);
X+ DEALLOCATE_LOCAL(pptSrc);
X+ (* pWin->drawable.pScreen->RegionDestroy)(prgnDst);
X+ }
X+
X+ void
X+ psunPushPixels (pGC, pBitMap, pDst, w, h, x, y)
X+ GCPtr pGC;
X+ PixmapPtr pBitMap;
X+ DrawablePtr pDst;
X+ int w, h, x, y;
X+ {
X+ static struct pixrect source, destination;
X+ static struct mpr_data srcmem, dstmem;
X+
X+ PixrectFromPixmap (pBitMap, &source, &srcmem);
X+ PixrectFromPixmap (pDst, &destination, &dstmem);
X+
X+ switch (((mfbPrivGC*)(pGC->devPriv))->rop) /* added cast - CMC */
X+ {
X+ case RROP_WHITE:
X+ pr_rop (&destination, x, y, w, h, PIX_DST | PIX_SRC, &source, 0, 0);
X+ break;
X+ case RROP_BLACK:
X+ pr_rop (&destination, x, y, w, h, PIX_DST & PIX_NOT (PIX_SRC), &source, 0, 0);
X+ break;
X+ case RROP_INVERT:
X+ pr_rop (&destination, x, y, w, h, PIX_DST ^ PIX_SRC, &source, 0, 0);
X+ break;
X+ case RROP_NOP:
X+ break;
X+ }
X+ }
END_OF_FILE
if test 19505 -ne `wc -c <'sunbitblt.c.patch'`; then
echo shar: \"'sunbitblt.c.patch'\" unpacked with wrong size!
fi
# end of 'sunbitblt.c.patch'
fi
if test -f 'sunplygblt.c.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sunplygblt.c.patch'\"
else
echo shar: Extracting \"'sunplygblt.c.patch'\" \(6917 characters\)
sed "s/^X//" >'sunplygblt.c.patch' <<'END_OF_FILE'
X*** sunplygblt.c.slow Tue Aug 1 09:49:21 1989
X--- sunplygblt.c Tue Apr 25 15:00:23 1989
X***************
X*** 0 ****
X--- 1,181 ----
X+ /* $Header: sunplygblt.c,v 1.1 87/09/11 07:48:45 toddb Exp $ */
X+ /***********************************************************
X+ Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
X+ and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
X+
X+ All Rights Reserved
X+
X+ Permission to use, copy, modify, and distribute this software and its
X+ documentation for any purpose and without fee is hereby granted,
X+ provided that the above copyright notice appear in all copies and that
X+ both that copyright notice and this permission notice appear in
X+ supporting documentation, and that the names of Digital or MIT not be
X+ used in advertising or publicity pertaining to distribution of the
X+ software without specific, written prior permission.
X+
X+ DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
X+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
X+ DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
X+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
X+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
X+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
X+ SOFTWARE.
X+
X+ ******************************************************************/
X+ #include "X.h"
X+ #include "Xmd.h"
X+ #include "Xproto.h"
X+ #include "fontstruct.h"
X+ #include "dixfontstr.h"
X+ #include "gcstruct.h"
X+ #include "windowstr.h"
X+ #include "scrnintstr.h"
X+ #include "pixmapstr.h"
X+ #include "regionstr.h"
X+ #include "sun.h"
X+ #include "maskbits.h"
X+ /*
X+ we should eventually special-case fixed-width fonts, although
X+ its more important for ImageText, which is meant for terminal
X+ emulators.
X+
X+ this works for fonts with glyphs <= 32 bits wide.
X+
X+ the clipping calculations are done for worst-case fonts.
X+ we make no assumptions about the heights, widths, or bearings
X+ of the glyphs. if we knew that the glyphs are all the same height,
X+ we could clip the tops and bottoms per clipping box, rather
X+ than per character per clipping box. if we knew that the glyphs'
X+ left and right bearings were well-behaved, we could clip a single
X+ character at the start, output until the last unclipped
X+ character, and then clip the last one. this is all straightforward
X+ to determine based on max-bounds and min-bounds from the font.
X+ there is some inefficiency introduced in the per-character
X+ clipping to make what's going on clearer.
X+
X+ (it is possible, for example, for a font to be defined in which the
X+ next-to-last character in a font would be clipped out, but the last
X+ one wouldn't. the code below deals with this.)
X+
X+ PolyText looks at the fg color and the rasterop; mfbValidateGC
X+ swaps in the right routine after looking at the reduced ratserop
X+ in the private field of the GC.
X+
X+ the register allocations are provisional; in particualr startmask and
X+ endmask might not be the right things. pglyph, xoff, pdst, and tmpSrc
X+ are fairly obvious, though.
X+
X+ to avoid source proliferation, this file is compiled
X+ three times:
X+ SUNPOLYGLYPHBLT OP
X+ sunPolyGlyphBltWhite PIX_DST|PIX_SRC
X+ sunPolyGlyphBltBlack PIX_DST&PIX_NOT(PIX_SRC)
X+ sunPolyGlyphBltInvert PIX_SRC^PIX_DST
X+ */
X+
X+ void
X+ SUNPOLYGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
X+ DrawablePtr pDrawable;
X+ GC *pGC;
X+ int x, y;
X+ register unsigned int nglyph;
X+ register CharInfoPtr *ppci; /* array of character info */
X+ register unsigned char *pglyphBase; /* start of array of glyphs */
X+ {
X+ register int i; /* moved decl and made a register -- CMC */
X+ ExtentInfoRec info; /* used by QueryGlyphExtents() */
X+
X+ register CharInfoPtr pci; /* made a register -- CMC */
X+ FontInfoPtr pfi = pGC->font->pFI;
X+ int xorg, yorg;
X+
X+ int w; /* width of glyph and char */
X+ int h; /* height of glyph and char */
X+ register int xpos; /* current x */
X+ register int ypos; /* current y */
X+
X+ BoxRec bbox; /* for clipping */
X+
X+ static struct pr_prpos *batch = NULL;
X+ static struct pixrect *prs = NULL;
X+ static struct mpr_data *pr_datas = NULL;
X+ static int batch_length = 0;
X+
X+ static struct pixrect destination;
X+ static struct mpr_data data;
X+
X+ extern struct pixrectops mem_ops;
X+
X+ if (pDrawable->type == DRAWABLE_WINDOW)
X+ {
X+ xorg = ((WindowPtr)pDrawable)->absCorner.x;
X+ yorg = ((WindowPtr)pDrawable)->absCorner.y;
X+ }
X+ else
X+ {
X+ xorg = 0;
X+ yorg = 0;
X+ }
X+
X+ xpos = x + xorg;
X+ ypos = y + yorg;
X+
X+
X+ QueryGlyphExtents(pGC->font, ppci, nglyph, &info);
X+ bbox.x1 = xpos + info.overallLeft;
X+ bbox.x2 = xpos + info.overallRight;
X+ bbox.y1 = ypos - info.overallAscent;
X+ bbox.y2 = ypos + info.overallDescent;
X+
X+ switch ((*pGC->pScreen->RectIn)(
X+ ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip, &bbox))
X+ {
X+ case rgnOUT:
X+ break;
X+ case rgnPART:
X+ CLIPPLTEXT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
X+ break;
X+ case rgnIN:
X+ if (nglyph == 0)
X+ return;
X+ PixrectFromPixmap (pDrawable, &destination, &data);
X+ if (batch_length < nglyph)
X+ {
X+ int i;
X+
X+ batch_length = nglyph;
X+ batch = (struct pr_prpos *) Xrealloc (batch, batch_length * sizeof (struct pr_prpos));
X+ prs = (struct pixrect *) Xrealloc (prs, batch_length * sizeof (struct pixrect));
X+ pr_datas = (struct mpr_data *) Xrealloc (pr_datas, batch_length * sizeof (struct mpr_data));
X+ for (i = 0; i < nglyph; i++)
X+ {
X+ pr_datas[i].md_linebytes = 4; /* bytes , ahem */
X+ pr_datas[i].md_offset.x = pr_datas[i].md_offset.y = 0;
X+ pr_datas[i].md_flags = 0;
X+ pr_datas[i].md_primary = 1;
X+ prs[i].pr_depth = 1;
X+ prs[i].pr_ops = &mem_ops;
X+ prs[i].pr_data = (char *) (pr_datas + i);
X+ batch[i].pr = prs + i;
X+ }
X+ }
X+ batch[0].pos.x = batch[0].pos.y = 0;
X+ for (i = 0; i < nglyph; i++)
X+ {
X+ pci = *ppci;
X+ prs[i].pr_size.x = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
X+ prs[i].pr_size.y = pci->metrics.ascent + pci->metrics.descent;
X+ batch[i].pos.x += pci->metrics.leftSideBearing;
X+ batch[i].pos.y -= pci->metrics.ascent;
X+ if(i<(nglyph-1)) {
X+ batch[i+1].pos.x = pci->metrics.characterWidth
X+ - pci->metrics.leftSideBearing;
X+ batch[i+1].pos.y = pci->metrics.ascent;
X+ }
X+ pr_datas[i].md_image = (short *) (pglyphBase + (*ppci++)->byteOffset);
X+ }
X+ pr_batchrop (&destination, xpos, ypos, OP, batch, nglyph);
X+ break;
X+ }
X+ }
X+
END_OF_FILE
if test 6917 -ne `wc -c <'sunplygblt.c.patch'`; then
echo shar: \"'sunplygblt.c.patch'\" unpacked with wrong size!
fi
# end of 'sunplygblt.c.patch'
fi
if test -f 'sunpntarea.c.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sunpntarea.c.patch'\"
else
echo shar: Extracting \"'sunpntarea.c.patch'\" \(3029 characters\)
sed "s/^X//" >'sunpntarea.c.patch' <<'END_OF_FILE'
X*** sunpntarea.c.slow Tue Aug 1 09:49:21 1989
X--- sunpntarea.c Tue Apr 25 10:17:49 1989
X***************
X*** 0 ****
X--- 1,104 ----
X+ #include "sun.h"
X+ #include "Xprotostr.h"
X+
X+ #include "maskbits.h"
X+
X+ static int sun_rop [] =
X+ {
X+ PIX_SRC & PIX_NOT (PIX_SRC),
X+ PIX_SRC & PIX_DST,
X+ PIX_SRC & PIX_NOT (PIX_DST),
X+ PIX_SRC,
X+ PIX_NOT (PIX_SRC) & PIX_DST,
X+ PIX_DST,
X+ PIX_SRC ^ PIX_DST,
X+ PIX_SRC | PIX_DST,
X+ PIX_NOT (PIX_SRC | PIX_DST),
X+ PIX_NOT (PIX_SRC ^ PIX_DST),
X+ PIX_NOT (PIX_DST),
X+ PIX_SRC | PIX_NOT (PIX_DST),
X+ PIX_NOT (PIX_SRC),
X+ PIX_NOT (PIX_SRC) | PIX_DST,
X+ PIX_SRC | PIX_NOT (PIX_DST),
X+ PIX_SRC | PIX_NOT (PIX_SRC),
X+ };
X+
X+
X+ char *malloc ();
X+ /*
X+ SUNSOLIDFILLAREA OPEQ EQWHOLEWORD
X+ sunSolidWhiteArea |= = ~0
X+ sunSolidBlackArea &=~ = 0
X+ sunSolidInvertArea ^= ^= ~0
X+
X+ EQWHOLEWORD is used to write whole longwords. it could use OPEQ,
X+ but *p++ |= ~0 on at least two compilers generates much
X+ worse code than *p++ = ~0. similarly for *p++ &= ~~0
X+ and *p++ = 0.
X+
X+ */
X+
X+
X+ void
X+ SUNSOLIDFILLAREA (pDrawable, nbox, pbox, alu, nop)
X+ DrawablePtr pDrawable;
X+ register int nbox;
X+ register BoxPtr pbox;
X+ int alu;
X+ PixmapPtr nop;
X+ {
X+ static struct pixrect destination;
X+ static struct mpr_data dstmem;
X+ register int rop, one = 1;
X+
X+ PixrectFromPixmap (pDrawable, &destination, &dstmem);
X+ switch (one EQWHOLEWORD)
X+ {
X+ case ~1: rop = PIX_NOT (PIX_DST); break;
X+ case ~0: rop = PIX_DST | PIX_NOT (PIX_DST); break;
X+ case 0: rop = PIX_DST & PIX_NOT (PIX_DST); break;
X+ }
X+ while (nbox--)
X+ {
X+ if (pr_rop (&destination, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, rop, &destination, pbox->x1, pbox->y1) == PIX_ERR)
X+ exit (3);
X+ pbox++;
X+ }
X+ }
X+
X+ int sunTileOrgX, sunTileOrgY;
X+ /* stipple a list of boxes
X+
X+ you can use the reduced rasterop for stipples. if rrop is
X+ black, AND the destination with (not stipple pattern). if rrop is
X+ white OR the destination with the stipple pattern. if rrop is invert,
X+ XOR the destination with the stipple pattern.
X+
X+ SUNSTIPPLEFILLAREA OPEQ
X+ sunStippleWhiteArea |=
X+ sunStippleBlackArea &=~
X+ sunStippleInvertArea ^=
X+ */
X+
X+
X+ void
X+ SUNSTIPPLEFILLAREA (pDrawable, nbox, pbox, alu, ppix)
X+ DrawablePtr pDrawable;
X+ register int nbox;
X+ register BoxPtr pbox;
X+ register int alu;
X+ PixmapPtr ppix;
X+ {
X+ static struct pixrect tile, destination;
X+ static struct mpr_data tilemem, dstmem;
X+ register int rop;
X+
X+ PixrectFromPixmap (pDrawable, &destination, &dstmem);
X+ PixrectFromPixmap (ppix, &tile, &tilemem);
X+ while (nbox--)
X+ {
X+ if (pr_replrop (&destination, pbox->x1, pbox->y1, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, sun_rop [alu], &tile, pbox->x1 - sunTileOrgX, pbox->y1 - sunTileOrgY) == PIX_ERR)
X+ exit (3);
X+ pbox++;
X+ }
X+ }
END_OF_FILE
if test 3029 -ne `wc -c <'sunpntarea.c.patch'`; then
echo shar: \"'sunpntarea.c.patch'\" unpacked with wrong size!
fi
# end of 'sunpntarea.c.patch'
fi
if test -f 'suntegblt.c.patch' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'suntegblt.c.patch'\"
else
echo shar: Extracting \"'suntegblt.c.patch'\" \(7196 characters\)
sed "s/^X//" >'suntegblt.c.patch' <<'END_OF_FILE'
X*** suntegblt.c.slow Tue Aug 1 09:49:21 1989
X--- suntegblt.c Mon May 15 09:59:41 1989
X***************
X*** 0 ****
X--- 1,199 ----
X+ /* $Header: suntegblt.c,v 1.1 87/09/11 07:48:45 toddb Exp $ */
X+ /***********************************************************
X+ Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
X+ and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
X+
X+ All Rights Reserved
X+
X+ Permission to use, copy, modify, and distribute this software and its
X+ documentation for any purpose and without fee is hereby granted,
X+ provided that the above copyright notice appear in all copies and that
X+ both that copyright notice and this permission notice appear in
X+ supporting documentation, and that the names of Digital or MIT not be
X+ used in advertising or publicity pertaining to distribution of the
X+ software without specific, written prior permission.
X+
X+ DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
X+ ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
X+ DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
X+ ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
X+ WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
X+ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
X+ SOFTWARE.
X+
X+ ******************************************************************/
X+ #include "X.h"
X+ #include "Xmd.h"
X+ #include "Xproto.h"
X+ #include "fontstruct.h"
X+ #include "dixfontstr.h"
X+ #include "gcstruct.h"
X+ #include "windowstr.h"
X+ #include "scrnintstr.h"
X+ #include "pixmapstr.h"
X+ #include "regionstr.h"
X+ #include "sun.h"
X+ #include "maskbits.h"
X+ /*
X+ this works for fonts with glyphs <= 32 bits wide.
X+
X+ This should be called only with a terminal-emulator font;
X+ this means that the FIXED_METRICS flag is set, and that
X+ glyphbounds == charbounds.
X+
X+ in theory, this goes faster; even if it doesn't, it reduces the
X+ flicker caused by writing a string over itself with image text (since
X+ the background gets repainted per character instead of per string.)
X+ this seems to be important for some converted X10 applications.
X+
X+ Image text looks at the bits in the glyph and the fg and bg in the
X+ GC. it paints a rectangle, as defined in the protocol dcoument,
X+ and the paints the characters.
X+
X+ to avoid source proliferation, this file is compiled
X+ two times:
X+ SUNTEGLYPHBLT OP
X+ sunTEGlyphBltWhite (white text, black bg )
X+ sunTEGlyphBltBlack ~ (black text, white bg )
X+
X+ */
X+
X+ void
X+ SUNTEGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
X+ DrawablePtr pDrawable;
X+ GC *pGC;
X+ int x, y;
X+ register unsigned int nglyph;
X+ register CharInfoPtr *ppci; /* array of character info */
X+ register unsigned char *pglyphBase; /* start of array of glyphs */
X+ {
X+ register int i;
X+ CharInfoPtr pci;
X+ FontInfoPtr pfi = pGC->font->pFI;
X+ int xorg, yorg;
X+ int widthDst;
X+ unsigned int *pdstBase; /* pointer to longword with top row
X+ of current glyph */
X+
X+ register int w; /* width of glyph and char */
X+ register int h; /* height of glyph and char */
X+ int xpos; /* current x%32 */
X+ int ypos; /* current y%32 */
X+ /*register unsigned char *pglyph;*/
X+ int widthGlyph;
X+
X+ /*register unsigned int *pdst;pointer to current longword in dst */
X+ int hTmp; /* counter for height */
X+ /*register int startmask, endmask;*/
X+ /*int nfirst; used if glyphs spans a longword boundary */
X+ BoxRec bbox; /* for clipping */
X+
X+ static struct pr_prpos *batch = NULL;
X+ static struct pixrect *prs = NULL;
X+ static struct mpr_data *pr_datas = NULL;
X+ static int batch_length = 0;
X+
X+ static struct pixrect destination;
X+ static struct mpr_data data;
X+
X+ extern struct pixrectops mem_ops;
X+
X+ if (pDrawable->type == DRAWABLE_WINDOW)
X+ {
X+ xorg = ((WindowPtr)pDrawable)->absCorner.x;
X+ yorg = ((WindowPtr)pDrawable)->absCorner.y;
X+ pdstBase = (unsigned int *)
X+ (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
X+ widthDst = (int)
X+ (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
X+ }
X+ else
X+ {
X+ xorg = 0;
X+ yorg = 0;
X+ pdstBase = (unsigned int *)(((PixmapPtr)pDrawable)->devPrivate);
X+ widthDst = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
X+ }
X+
X+ xpos = x + xorg;
X+ ypos = y + yorg;
X+
X+ pci = &pfi->maxbounds;
X+ w = pci->metrics.characterWidth;
X+ h = pfi->fontAscent + pfi->fontDescent;
X+ widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
X+
X+ xpos += pci->metrics.leftSideBearing;
X+ ypos -= pfi->fontAscent;
X+
X+ bbox.x1 = xpos;
X+ bbox.x2 = xpos + (w * nglyph);
X+ bbox.y1 = ypos;
X+ bbox.y2 = ypos + h;
X+
X+ switch ((*pGC->pScreen->RectIn)(
X+ ((mfbPrivGC *)(pGC->devPriv))->pCompositeClip, &bbox))
X+ {
X+ case rgnOUT:
X+ break;
X+ case rgnPART:
X+ /* this is the WRONG thing to do, but it works.
X+ calling the non-terminal text is easy, but slow, given
X+ what we know about the font.
X+
X+ the right thing to do is something like:
X+ for each clip rectangle
X+ compute at which row the glyph starts to be in it,
X+ and at which row the glyph ceases to be in it
X+ compute which is the first glyph inside the left
X+ edge, and the last one inside the right edge
X+ draw a fractional first glyph, using only
X+ the rows we know are in
X+ draw all the whole glyphs, using the appropriate rows
X+ draw any pieces of the last glyph, using the right rows
X+
X+ this way, the code would take advantage of knowing that
X+ all glyphs are the same height and don't overlap.
X+
X+ one day...
X+ */
X+ CLIPTETEXT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
X+ break;
X+ case rgnIN:
X+ if (nglyph == 0)
X+ return;
X+ PixrectFromPixmap (pDrawable, &destination, &data);
X+ if (batch_length < nglyph)
X+ {
X+ int i;
X+
X+ batch_length = nglyph;
X+ batch = (struct pr_prpos *) Xrealloc (batch, batch_length * sizeof (struct pr_prpos));
X+ prs = (struct pixrect *) Xrealloc (prs, batch_length * sizeof (struct pixrect));
X+ pr_datas = (struct mpr_data *) Xrealloc (pr_datas, batch_length * sizeof (struct mpr_data));
X+ for (i = 0; i < nglyph; i++)
X+ {
X+ pr_datas[i].md_linebytes = 4; /* bytes , ahem */
X+ pr_datas[i].md_offset.x = pr_datas[i].md_offset.y = 0;
X+ pr_datas[i].md_flags = 0;
X+ pr_datas[i].md_primary = 1;
X+ prs[i].pr_depth = 1;
X+ prs[i].pr_ops = &mem_ops;
X+ prs[i].pr_data = (char *) (pr_datas + i);
X+ batch[i].pr = prs + i;
X+ }
X+ }
X+ for (i = 0; i < nglyph; i++)
X+ {
X+ prs[i].pr_size.x = w;
X+ prs[i].pr_size.y = h;
X+ batch[i].pos.x = w;
X+ batch[i].pos.y = 0;
X+ pr_datas[i].md_image = (short *) (pglyphBase + (*ppci++)->byteOffset);
X+ }
X+ batch[0].pos.x = batch[0].pos.y = 0; /* not the first! */
X+ pr_batchrop (&destination, xpos, ypos, (OP(0) ? PIX_NOT (PIX_SRC) : PIX_SRC), batch, nglyph);
X+ break;
X+ }
X+ }
X+
END_OF_FILE
if test 7196 -ne `wc -c <'suntegblt.c.patch'`; then
echo shar: \"'suntegblt.c.patch'\" unpacked with wrong size!
fi
# end of 'suntegblt.c.patch'
fi
echo shar: End of archive 2 \(of 3\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 3 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 3 archives.
echo "Now read README.ral"
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
More information about the Comp.sources.x
mailing list