📄 hpcopyarea.c
字号:
* (if included window is source and parent is dest) */ if (pDstDrawable->type == DRAWABLE_WINDOW) lowlife = 1; if (pSrcDrawable == pDstDrawable && pGC->clientClipType == CT_NONE) { scl = REGION_RECTS(((cfbPrivGC *) pGC->devPrivates[cfbGCPrivateIndex].ptr)->pCompositeClip); sboxes = REGION_NUM_RECTS(((cfbPrivGC *) pGC->devPrivates[cfbGCPrivateIndex].ptr)->pCompositeClip); } else /* gotta create a new clip list */ { sHitList = NotClippedByChildren((WindowPtr)pSrcDrawable); scl = REGION_RECTS(sHitList); sboxes = REGION_NUM_RECTS(sHitList); } } else { scl = REGION_RECTS(&((WindowPtr)pSrcDrawable)->clipList); sboxes = REGION_NUM_RECTS(&((WindowPtr)pSrcDrawable)->clipList); } } /* lookup the dest clip list and any translation */ dcl = REGION_RECTS(((cfbPrivGC *) pGC->devPrivates[cfbGCPrivateIndex].ptr)->pCompositeClip); dboxes = REGION_NUM_RECTS(((cfbPrivGC *) pGC->devPrivates[cfbGCPrivateIndex].ptr)->pCompositeClip); dtx = dty = 0; if (pDstDrawable->type == DRAWABLE_PIXMAP) { if (DEVKIND(pDstDrawable) == PIXMAP_FRAME_BUFFER) { dtx = PIXER(pDstDrawable)->pChunk->x; dty = PIXER(pDstDrawable)->pChunk->y; } /* else dest is in main mem & composite clip is OK */ } else /* dest is a window */ { if (pGC->miTranslate) /* translate window to screen coordinates */ { dstx += pDstDrawable->x; dsty += pDstDrawable->y; } } /* figure out who to call to actually do the copy area */ if (pDstDrawable->type == DRAWABLE_PIXMAP && DEVKIND(pDstDrawable) == PIXMAP_HOST_MEMORY) /* MTOM */ { if (pSrcDrawable->depth==1) /* can only handle some bitmaps */ { if ((pSrcDrawable!=pDstDrawable || !lapdog(srcx,srcy, width,height, dstx,dsty, sboxes+dboxes)) && srcx==0 && srcy==0 && dstx==0 && dsty==0 && (width % 8)==0) { width /= 8; goto mtom; } /* let mfb handle most of the bit maps */ return mfbCopyArea(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut); } /* can't handle overlapping moves unless overlap don't matter */ if (pSrcDrawable==pDstDrawable && lapdog(srcx,srcy,width,height,dstx,dsty,sboxes+dboxes) && (SWEAT_PLANES_MASK(pSrcDrawable,pGC->planemask) || (pGC->alu!=GXclear && pGC->alu!=GXset && pGC->alu!=GXnoop)) ) { return hpfbCopyArea(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut); } mtom: MemToMem(pSrcDrawable,pDstDrawable,pGC, srcx,srcy,width,height, dstx,dsty, scl,sboxes, dcl,dboxes); } else if (pSrcDrawable->type == DRAWABLE_PIXMAP && DEVKIND(pSrcDrawable) == PIXMAP_HOST_MEMORY) /* MTOS */ MemToScreen(pSrcDrawable,pDstDrawable,pGC, srcx,srcy,width,height, dstx,dsty, dboxes,dcl, dtx,dty); else /* STOS */ if ( (pSrcDrawable==pDstDrawable || lowlife) && (sboxes +dboxes >2) && lapdog(srcx,srcy, width,height, dstx,dsty, sboxes+dboxes) && (srcy<dsty || srcx<dstx) ) /* overlap */ { BoxRec *sl, *dl; int j; /* allocate new clip lists */ sl = (BoxRec *)xalloc((unsigned long) ((sboxes+dboxes)*sizeof(BoxRec))); dl = &sl[sboxes]; for (j=0; j<sboxes; j++) sl[j] = scl[j]; for (j=0; j<dboxes; j++) dl[j] = dcl[j]; /* reverse vertical & horizontal banding */ if (srcy<dsty || (srcy<dsty && srcx<dstx)) { spud(sl,sboxes); spud(dl,dboxes); } else /* reverse horizontal banding */ { spudd(sl,sboxes); spudd(dl,dboxes); } ScreenToScreen(pSrcDrawable, pGC, srcx,srcy, width,height, dstx,dsty, sl,sboxes, dl,dboxes, stx,sty, dtx,dty); xfree((char *)sl); } else ScreenToScreen(pSrcDrawable, pGC, srcx,srcy, width,height, dstx,dsty, scl,sboxes, dcl,dboxes, stx,sty, dtx,dty); /* let miHandleExposures() handle all the exposure stuff 'cause * it knows lots more than I do. It also sends noExpose * events if needbe. * Note: Other CopyAreas use (cfbPrivGC *)(pGC->devPriv))->fExpose * instead of pGC->graphicsExposures. This is because * mfbPutImage is brain damaged and since HP don't use it, I * can use graphicsExposures. */ if (pGC->graphicsExposures) prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut,0); if (sHitList) (*pGC->pScreen->RegionDestroy)(sHitList); return prgnExposed;}/* HPFBCOPYAREA -- "public" entry for the CopyArea request * For requests operating within a single topcat frame buffer. * For each rectangle in the source region * move rectangle using topcat pixel mover hardware */static RegionPtrhpfbCopyArea(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut) register DrawablePtr pSrcDrawable; register DrawablePtr pDstDrawable; GCPtr pGC; int xIn, yIn; int widthSrc, heightSrc; int xOut, yOut;{ DDXPointPtr ppt, pptFirst; unsigned int *pwidthFirst, *pwidth, *pbits; BoxRec srcBox, *prect; /* may be a new region, or just a copy */ RegionPtr prgnSrcClip, prgnDstClip; /* non-0 if we've created a src clip */ int realSrcClip = 0, useOrdering = 0; int srcx, srcy, dstx, dsty, i, j, y, width, height, xMin, xMax, yMin, yMax; unsigned int *ordering; RegionPtr prgnExposed; int numRects; BoxPtr boxes; /* clip the left and top edges of the source */ if (xIn < 0) { widthSrc += xIn; srcx = pSrcDrawable->x; } else srcx = xIn + pSrcDrawable->x; if (yIn < 0) { heightSrc += yIn; srcy = pSrcDrawable->y; } else srcy = yIn + pSrcDrawable->y; /* If the destination isn't realized, this is easy */ if ((pDstDrawable->type == DRAWABLE_WINDOW) && (!((WindowPtr)pDstDrawable)->realized)) return (RegionPtr)NULL; /* clip the source */ if (pSrcDrawable->type == DRAWABLE_PIXMAP) { BoxRec box; box.x1 = pSrcDrawable->x; box.y1 = pSrcDrawable->y; box.x2 = pSrcDrawable->x + (int) pSrcDrawable->width; box.y2 = pSrcDrawable->y + (int) pSrcDrawable->height; prgnSrcClip = (*pGC->pScreen->RegionCreate)(&box, 1); realSrcClip = 1; } else prgnSrcClip = &((WindowPtr)pSrcDrawable)->clipList; srcBox.x1 = srcx; srcBox.y1 = srcy; srcBox.x2 = srcx + widthSrc; srcBox.y2 = srcy + heightSrc; dstx = xOut; dsty = yOut; if (pGC->miTranslate) { dstx += pDstDrawable->x; dsty += pDstDrawable->y; } prgnDstClip = ((cfbPrivGC *) (pGC->devPrivates[cfbGCPrivateIndex].ptr))->pCompositeClip; numRects = REGION_NUM_RECTS(prgnSrcClip); boxes = REGION_RECTS(prgnSrcClip); ordering = (unsigned int *) ALLOCATE_LOCAL(numRects * sizeof(unsigned int)); if (!ordering) return (RegionPtr)NULL; /* If not the same drawable then order of move doesn't matter. Following assumes that boxes are sorted from top to bottom and left to right. */ if (pSrcDrawable != pDstDrawable) for (i=0; i < numRects; i++) ordering[i] = i; else { /* within same drawable, must sequence moves carefully! */ useOrdering = 1; /* must pay attention to this ordering later! */ if (dsty <= srcBox.y1) { /* Scroll up or stationary vertical. Vertical order OK */ if (dstx <= srcBox.x1) /* Scroll left or stationary horizontal. Horizontal order OK as well */ for (i=0; i < numRects; i++) ordering[i] = i; else { /* scroll right. must reverse horizontal banding of rects. */ for (i=0, j=1, xMax=0; i < numRects; j=i+1, xMax=i) { /* find extent of current horizontal band */ y=boxes[i].y1; /* band has this y coordinate */ while ((j < numRects) && (boxes[j].y1 == y)) j++; /* reverse the horizontal band in the output ordering */ for (j-- ; j >= xMax; j--, i++) ordering[i] = j; } } } else { /* Scroll down. Must reverse vertical banding. */ if (dstx < srcBox.x1) { /* Scroll left. Horizontal order OK. */ for (i=numRects-1, j=i-1, yMin=i, yMax=0; i >= 0; j=i-1, yMin=i) { /* find extent of current horizontal band */ y=boxes[i].y1; /* band has this y coordinate */ while ((j >= 0) && (boxes[j].y1 == y)) j--; /* reverse the horizontal band in the output ordering */ for (j++ ; j <= yMin; j++, i--, yMax++) ordering[yMax] = j; } } else /* Scroll right or horizontal stationary. Reverse horizontal order as well (if stationary, horizontal order can be swapped without penalty and this is faster to compute). */ for (i=0, j=numRects-1; i < numRects; i++, j--) ordering[i] = j; } } if ((pSrcDrawable->pScreen == pDstDrawable->pScreen) && (((pSrcDrawable->type == DRAWABLE_PIXMAP) && (((PixmapPtr)pSrcDrawable)->devKind == PIXMAP_FRAME_BUFFER)) || (pSrcDrawable->type == DRAWABLE_WINDOW)) && (((pDstDrawable->type == DRAWABLE_PIXMAP) && (((PixmapPtr)pDstDrawable)->devKind == PIXMAP_FRAME_BUFFER)) || (pDstDrawable->type == DRAWABLE_WINDOW)) ) { /* Copy area within portions of a single screens frame buffer. * For each visible portion of source, move into visible * portions of destination utilizing area mover. */ BoxRec dstBox, *prect2; int sxMin, sxMax, syMin, syMax, /* source for actual move */ dxMin, dxMax, dyMin, dyMax; /* dest for actual move */ register hpPrivScreenPtr pPrivScreen; void (*bitMover)(), (*maskConfig)(); pPrivScreen = getPrivScreenPtr(pGC->pScreen); bitMover = pPrivScreen->MoveBits; maskConfig = pPrivScreen->MaskConfig; if (pSrcDrawable->type == DRAWABLE_PIXMAP) { /* make screen relative */ register hpChunk *pixChunk = ((hpPrivPixmapPtr) (((PixmapPtr)pSrcDrawable)->devPrivate.ptr))->pChunk; boxes[0].x1 += pixChunk->x; boxes[0].y1 += pixChunk->y; boxes[0].x2 += pixChunk->x; boxes[0].y2 += pixChunk->y; srcBox.x1 += pixChunk->x; srcBox.y1 += pixChunk->y; srcBox.x2 += pixChunk->x; srcBox.y2 += pixChunk->y; srcx += pixChunk->x; srcy += pixChunk->y; } if (pDstDrawable->type == DRAWABLE_PIXMAP) { /* make screen relative */ register hpChunk *pixChunk = (hpChunk *) ((hpPrivPixmapPtr) (((PixmapPtr)pDstDrawable)->devPrivate.ptr))->pChunk; REGION_RECTS(prgnDstClip)[0].x1 += pixChunk->x; REGION_RECTS(prgnDstClip)[0].y1 += pixChunk->y; REGION_RECTS(prgnDstClip)[0].x2 += pixChunk->x; REGION_RECTS(prgnDstClip)[0].y2 += pixChunk->y; dstx += pixChunk->x; dsty += pixChunk->y; } for (i = 0; i < numRects; i++) { prect = &boxes[ordering[i]]; /* find portion of move contained in this visible portion of window */ xMin = max(prect->x1, srcBox.x1); xMax = min(prect->x2, srcBox.x2); yMin = max(prect->y1, srcBox.y1); yMax = min(prect->y2, srcBox.y2); /* exit loop unless there is something visible */ if (xMax <= xMin || yMax <= yMin) continue; /* destination box for visible portion of source */ dstBox.x1 = xMin - (srcx - dstx); dstBox.y1 = yMin - (srcy - dsty); dstBox.x2 = dstBox.x1 + xMax - xMin; dstBox.y2 = dstBox.y1 + yMax - yMin; /* find visible portions of destination */ prect2 = REGION_RECTS(prgnDstClip); for (j = 0; j < REGION_NUM_RECTS(prgnDstClip); j++) { if (useOrdering) prect2 = ®ION_RECTS(prgnDstClip)[ordering[j]]; else prect2 = ®ION_RECTS(prgnDstClip)[j]; dxMin = max(prect2->x1, dstBox.x1); dxMax = min(prect2->x2, dstBox.x2); dyMin = max(prect2->y1, dstBox.y1); dyMax = min(prect2->y2, dstBox.y2); /* any portion of destination visible in this area? */ if (dxMax <= dxMin || dyMax <= dyMin) continue; /* will further clip source if destination was also clipped */ sxMin = xMin + max((prect2->x1 - dstBox.x1), 0); syMin = yMin + max((prect2->y1 - dstBox.y1), 0); sxMax = xMax + min((prect2->x2 - dstBox.x2), 0); syMax = yMax + min((prect2->y2 - dstBox.y2), 0); (*bitMover)(pGC->pScreen, pGC->planemask, pGC->alu, sxMin, syMin, dxMin, dyMin, (sxMax - sxMin), (syMax - syMin)); } } } else { /* no place for hardware assist */ pptFirst = ppt = (DDXPointPtr) ALLOCATE_LOCAL(heightSrc * sizeof(DDXPointRec)); pwidthFirst = pwidth = (unsigned int *) ALLOCATE_LOCAL(heightSrc * sizeof(unsigned int)); if (!pptFirst || !pwidthFirst) { DEALLOCATE_LOCAL(ordering); if (pptFirst) DEALLOCATE_LOCAL(pptFirst); if (pwidthFirst) DEALLOCATE_LOCAL(pwidthFirst); return (RegionPtr)NULL; } for (i = 0; i < numRects; i++) { prect = &boxes[ordering[i]]; xMin = max(prect->x1, srcBox.x1); xMax = min(prect->x2, srcBox.x2); yMin = max(prect->y1, srcBox.y1); yMax = min(prect->y2, srcBox.y2); /* is there anything visible here? */ if (xMax <= xMin || yMax <= yMin) continue; ppt = pptFirst; pwidth = pwidthFirst; y = yMin; height = yMax - yMin; width = xMax - xMin; for (j = 0; j < height; j++) { ppt->x = xMin; ppt++->y = y++; *pwidth++ = width; } pbits = (unsigned int *)xalloc(height * PixmapBytePad(width, pSrcDrawable->depth)); if (pbits) { (*pSrcDrawable->pScreen->GetSpans)(pSrcDrawable, width, pptFirst, pwidthFirst, height, pbits); ppt = pptFirst; pwidth = pwidthFirst; xMin -= (srcx - dstx); y = yMin - (srcy - dsty); for (j = 0; j < height; j++) { ppt->x = xMin; ppt++->y = y++; *pwidth++ = width; } (*pGC->ops->SetSpans)(pDstDrawable, pGC, pbits, pptFirst, pwidthFirst, height, TRUE); xfree(pbits); } } DEALLOCATE_LOCAL(pptFirst); DEALLOCATE_LOCAL(pwidthFirst); } DEALLOCATE_LOCAL(ordering); prgnExposed = miHandleExposures(pSrcDrawable, pDstDrawable, pGC, xIn, yIn, widthSrc, heightSrc, xOut, yOut, (unsigned long)0); if (realSrcClip) (*pGC->pScreen->RegionDestroy)(prgnSrcClip); return prgnExposed;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -