⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hpcopyarea.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	     *  (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 = &REGION_RECTS(prgnDstClip)[ordering[j]];		else		    prect2 = &REGION_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 + -