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

📄 mfbgc.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
    new_fill = FALSE;    mask = changes;    while (mask)    {	index = lowbit (mask);	mask &= ~index;	/* this switch acculmulates a list of which procedures	   might have to change due to changes in the GC.  in	   some cases (e.g. changing one 16 bit tile for another)	   we might not really need a change, but the code is	   being paranoid.	   this sort of batching wins if, for example, the alu	   and the font have been changed, or any other pair	   of items that both change the same thing.	*/	switch (index)	{	  case GCFunction:	  case GCForeground:	    new_rrop = TRUE;	    break;	  case GCPlaneMask:	    break;	  case GCBackground:	    new_rrop = TRUE;	/* for opaque stipples */	    break;	  case GCLineStyle:	  case GCLineWidth:	  case GCJoinStyle:	    new_line = TRUE;	    break;	  case GCCapStyle:	    break;	  case GCFillStyle:	    new_fill = TRUE;	    break;	  case GCFillRule:	    break;	  case GCTile:	    if(pGC->tileIsPixel)		break;	    new_rotate = TRUE;	    new_fill = TRUE;	    break;	  case GCStipple:	    if(pGC->stipple == (PixmapPtr)NULL)		break;	    new_rotate = TRUE;	    new_fill = TRUE;	    break;	  case GCTileStipXOrigin:	    new_rotate = TRUE;	    break;	  case GCTileStipYOrigin:	    new_rotate = TRUE;	    break;	  case GCFont:	    new_text = TRUE;	    break;	  case GCSubwindowMode:	    break;	  case GCGraphicsExposures:	    break;	  case GCClipXOrigin:	    break;	  case GCClipYOrigin:	    break;	  case GCClipMask:	    break;	  case GCDashOffset:	    break;	  case GCDashList:	    break;	  case GCArcMode:	    break;	  default:	    break;	}    }    /* deal with the changes we've collected .       new_rrop must be done first because subsequent things       depend on it.    */    if(new_rotate || new_fill)    {	Bool new_pix = FALSE;	/* figure out how much to rotate */	xrot = pGC->patOrg.x;	yrot = pGC->patOrg.y;	xrot += pDrawable->x;	yrot += pDrawable->y;	switch (pGC->fillStyle)	{	case FillTiled:	    /* copy current tile and stipple */	    if (!pGC->tileIsPixel && (pGC->tile.pixmap->drawable.width <= 32) &&	    	!(pGC->tile.pixmap->drawable.width & (pGC->tile.pixmap->drawable.width - 1)))	    {		mfbCopyRotatePixmap(pGC->tile.pixmap,				    &devPriv->pRotatedPixmap, xrot, yrot);		new_pix = TRUE;	    }	    break;	case FillStippled:	case FillOpaqueStippled:	    if (pGC->stipple && (pGC->stipple->drawable.width <= 32) &&	    	!(pGC->stipple->drawable.width & (pGC->stipple->drawable.width - 1)))	    {	    	if (pGC->stipple == pGC->pScreen->PixmapPerDepth[0])	    	{		    if (pGC->stipple->drawable.width != 32)			mfbPadPixmap(pGC->stipple);		    if (devPriv->pRotatedPixmap)			mfbDestroyPixmap(devPriv->pRotatedPixmap);		    devPriv->pRotatedPixmap = pGC->stipple;		    ++devPriv->pRotatedPixmap->refcnt;	    	}	    	else	    	{		    mfbCopyRotatePixmap(pGC->stipple,					&devPriv->pRotatedPixmap, xrot, yrot);	    	}		new_pix = TRUE;	    }	}	/* destroy any previously rotated tile or stipple */	if (!new_pix && devPriv->pRotatedPixmap)	{	    mfbDestroyPixmap(devPriv->pRotatedPixmap);	    devPriv->pRotatedPixmap = (PixmapPtr)NULL;	}    }    /*     * duck out here when the GC is unchanged     */    if (!changes)	return;    if (new_rrop || new_fill)    {	rrop = mfbReduceRop(pGC->alu, pGC->fgPixel);	devPriv->rop = rrop;	new_fill = TRUE;	/* FillArea raster op is GC's for tile filling,	   and the reduced rop for solid and stipple	*/	if (pGC->fillStyle == FillTiled)	    devPriv->ropFillArea = pGC->alu;	else	    devPriv->ropFillArea = rrop;	/* opaque stipples:	   fg	bg	ropOpStip	fill style	   1	0	alu		tile	   0	1	inverseAlu	tile	   1	1	rrop(fg, alu)	solid	   0	0	rrop(fg, alu)	solid	Note that rrop(fg, alu) == mfbPrivGC.rop, so we don't really need to	compute it.	*/        if (pGC->fillStyle == FillOpaqueStippled)        {	    if ((pGC->fgPixel & 1) != (pGC->bgPixel & 1))	    {	        if (pGC->fgPixel & 1)		    devPriv->ropOpStip = pGC->alu;	        else		    devPriv->ropOpStip = InverseAlu[pGC->alu];	    }	    else	        devPriv->ropOpStip = rrop;	    devPriv->ropFillArea = devPriv->ropOpStip;        }    }    else	rrop = devPriv->rop;    if (new_line || new_fill || new_text)    {	GCOps	*newops;	if (newops = matchCommon (pGC)) 	{	    if (pGC->ops->devPrivate.val)		mfbDestroyOps (pGC->ops);	    pGC->ops = newops;	    new_line = new_fill = new_text = 0;	} 	else 	{	    if (!pGC->ops->devPrivate.val) 	    {		pGC->ops = mfbCreateOps (pGC->ops);		pGC->ops->devPrivate.val = 1;	    }	}    }    if (new_line || new_fill)    {	if (pGC->lineWidth == 0)	{	    if ((pGC->lineStyle == LineSolid) && (pGC->fillStyle == FillSolid)		&& ((rrop == RROP_WHITE) || (rrop == RROP_BLACK)))		pGC->ops->PolyArc = mfbZeroPolyArcSS;	    else		pGC->ops->PolyArc = miZeroPolyArc;	}	else	    pGC->ops->PolyArc = miPolyArc;	if (pGC->lineStyle == LineSolid)	{	    if(pGC->lineWidth == 0)	    {	        if (pGC->fillStyle == FillSolid)		{		    pGC->ops->PolySegment = mfbSegmentSS;		    pGC->ops->Polylines = mfbLineSS;	        } 		else		{		    pGC->ops->PolySegment = miPolySegment;		    pGC->ops->Polylines = miZeroLine;		}	    }	    else	    {		pGC->ops->PolySegment = miPolySegment;		pGC->ops->Polylines = miWideLine;	    }	}	else	{	    if(pGC->lineWidth == 0 && pGC->fillStyle == FillSolid)	    {	        pGC->ops->Polylines = mfbLineSD;		pGC->ops->PolySegment = mfbSegmentSD;	    }	    else	    {	        pGC->ops->Polylines = miWideDash;		pGC->ops->PolySegment = miPolySegment;	    }	}    }    if (new_text || new_fill)    {	if ((pGC->font) &&	    (FONTMAXBOUNDS(pGC->font,rightSideBearing) -	     FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 ||	     FONTMINBOUNDS(pGC->font,characterWidth) < 0))	{	    pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;	    pGC->ops->ImageGlyphBlt = miImageGlyphBlt;	}	else	{	    /* special case ImageGlyphBlt for terminal emulator fonts */	    if ((pGC->font) &&		TERMINALFONT(pGC->font) &&		((pGC->fgPixel & 1) != (pGC->bgPixel & 1)))	    {		/* pcc bug makes this not compile...		pGC->ops->ImageGlyphBlt = (pGC->fgPixel & 1) ? mfbTEGlyphBltWhite :						      mfbTEGlyphBltBlack;		*/		if (pGC->fgPixel & 1)		    pGC->ops->ImageGlyphBlt = mfbTEGlyphBltWhite;		else		    pGC->ops->ImageGlyphBlt = mfbTEGlyphBltBlack;	    }	    else	    {	        if (pGC->fgPixel & 1)		    pGC->ops->ImageGlyphBlt = mfbImageGlyphBltWhite;	        else		    pGC->ops->ImageGlyphBlt = mfbImageGlyphBltBlack;	    }	    /* now do PolyGlyphBlt */	    if (pGC->fillStyle == FillSolid ||		(pGC->fillStyle == FillOpaqueStippled &&		 (pGC->fgPixel & 1) == (pGC->bgPixel & 1)		)	       )	    {		if (rrop == RROP_WHITE)		    pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltWhite;		else if (rrop == RROP_BLACK)		    pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltBlack;		else if (rrop == RROP_INVERT)		    pGC->ops->PolyGlyphBlt = mfbPolyGlyphBltInvert;		else		    pGC->ops->PolyGlyphBlt = NoopDDA;	    }	    else	    {		pGC->ops->PolyGlyphBlt = miPolyGlyphBlt;	    }	}    }    if (new_fill)    {	/* install a suitable fillspans and pushpixels */	pGC->ops->PushPixels = mfbPushPixels;	if ((pGC->fillStyle == FillSolid) ||	    ((pGC->fillStyle == FillOpaqueStippled) &&	     ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))))	{	    pGC->ops->PushPixels = mfbSolidPP;	    switch(devPriv->rop)	    {	      case RROP_WHITE:		pGC->ops->FillSpans = mfbWhiteSolidFS;		break;	      case RROP_BLACK:		pGC->ops->FillSpans = mfbBlackSolidFS;		break;	      case RROP_INVERT:		pGC->ops->FillSpans = mfbInvertSolidFS;		break;	      case RROP_NOP:		pGC->ops->FillSpans = NoopDDA;		break;	    }	}	/* beyond this point, opaqueStippled ==> fg != bg */	else if (((pGC->fillStyle == FillTiled) ||		  (pGC->fillStyle == FillOpaqueStippled)) &&		 !devPriv->pRotatedPixmap)	{	    pGC->ops->FillSpans = mfbUnnaturalTileFS;	}	else if ((pGC->fillStyle == FillStippled) && !devPriv->pRotatedPixmap)	{	    pGC->ops->FillSpans = mfbUnnaturalStippleFS;	}	else if (pGC->fillStyle == FillStippled)	{	    switch(devPriv->rop)	    {	      case RROP_WHITE:		pGC->ops->FillSpans = mfbWhiteStippleFS;		break;	      case RROP_BLACK:		pGC->ops->FillSpans = mfbBlackStippleFS;		break;	      case RROP_INVERT:		pGC->ops->FillSpans = mfbInvertStippleFS;		break;	      case RROP_NOP:		pGC->ops->FillSpans = NoopDDA;		break;	    }	}	else /* overload tiles to do parti-colored opaque stipples */	{	    pGC->ops->FillSpans = mfbTileFS;	}	if (pGC->fillStyle == FillSolid)	    pGC->ops->PolyFillArc = mfbPolyFillArcSolid;	else	    pGC->ops->PolyFillArc = miPolyFillArc;	/* the rectangle code doesn't deal with opaque stipples that	   are two colors -- we can fool it for fg==bg, though	 */	if ((((pGC->fillStyle == FillTiled) ||	      (pGC->fillStyle == FillStippled)) &&	     !devPriv->pRotatedPixmap) ||	    ((pGC->fillStyle == FillOpaqueStippled) &&	     ((pGC->fgPixel & 1) != (pGC->bgPixel & 1)))	   )	{	    pGC->ops->PolyFillRect = miPolyFillRect;	}	else /* deal with solids and natural stipples and tiles */	{	    pGC->ops->PolyFillRect = mfbPolyFillRect;	    if ((pGC->fillStyle == FillSolid) ||		((pGC->fillStyle == FillOpaqueStippled) &&		 ((pGC->fgPixel & 1) == (pGC->bgPixel & 1))))	    {		switch(devPriv->rop)		{		  case RROP_WHITE:		    devPriv->FillArea = mfbSolidWhiteArea;		    break;		  case RROP_BLACK:		    devPriv->FillArea = mfbSolidBlackArea;		    break;		  case RROP_INVERT:		    devPriv->FillArea = mfbSolidInvertArea;		    break;		  case RROP_NOP:		    devPriv->FillArea = NoopDDA;		    break;		}	    }	    else if (pGC->fillStyle == FillStippled)	    {		switch(devPriv->rop)		{		  case RROP_WHITE:		    devPriv->FillArea = mfbStippleWhiteArea;		    break;		  case RROP_BLACK:		    devPriv->FillArea = mfbStippleBlackArea;		    break;		  case RROP_INVERT:		    devPriv->FillArea = mfbStippleInvertArea;		    break;		  case RROP_NOP:		    devPriv->FillArea = NoopDDA;		    break;		}	    }	    else /* deal with tiles */	    {		extern void mfbTileArea32Copy(), mfbTileArea32General();		switch (pGC->alu)		{		  case GXcopy:		    devPriv->FillArea = mfbTileArea32Copy;		    break;		  default:		    devPriv->FillArea = mfbTileArea32General;		    break;		}	    }	} /* end of natural rectangles */    } /* end of new_fill */}/* table to map alu(src, dst) to alu(~src, dst) */int InverseAlu[16] = {	GXclear,	GXandInverted,	GXnor,	GXcopyInverted,	GXand,	GXnoop,	GXequiv,	GXorInverted,	GXandReverse,	GXxor,	GXinvert,	GXnand,	GXcopy,	GXor,	GXorReverse,	GXset};intmfbReduceRop(alu, src)    register unsigned char alu;    register Pixel src;{    int rop;    if ((src & 1) == 0)	/* src is black */    {	switch(alu)	{	  case GXclear:	    rop = RROP_BLACK;	    break;	  case GXand:	    rop = RROP_BLACK;	    break;	  case GXandReverse:	    rop = RROP_BLACK;	    break;	  case GXcopy:	    rop = RROP_BLACK;	    break;	  case GXandInverted:	    rop = RROP_NOP;	    break;	  case GXnoop:	    rop = RROP_NOP;	    break;	  case GXxor:	    rop = RROP_NOP;	    break;	  case GXor:	    rop = RROP_NOP;	    break;	  case GXnor:	    rop = RROP_INVERT;	    break;	  case GXequiv:	    rop = RROP_INVERT;	    break;	  case GXinvert:	    rop = RROP_INVERT;	    break;	  case GXorReverse:	    rop = RROP_INVERT;	    break;	  case GXcopyInverted:	    rop = RROP_WHITE;	    break;	  case GXorInverted:	    rop = RROP_WHITE;	    break;	  case GXnand:	    rop = RROP_WHITE;	    break;	  case GXset:	    rop = RROP_WHITE;	    break;	}    }    else /* src is white */    {	switch(alu)	{	  case GXclear:	    rop = RROP_BLACK;	    break;	  case GXand:	    rop = RROP_NOP;	    break;	  case GXandReverse:	    rop = RROP_INVERT;	    break;	  case GXcopy:	    rop = RROP_WHITE;	    break;	  case GXandInverted:	    rop = RROP_BLACK;	    break;	  case GXnoop:	    rop = RROP_NOP;	    break;	  case GXxor:	    rop = RROP_INVERT;	    break;	  case GXor:	    rop = RROP_WHITE;	    break;	  case GXnor:	    rop = RROP_BLACK;	    break;	  case GXequiv:	    rop = RROP_NOP;	    break;	  case GXinvert:	    rop = RROP_INVERT;	    break;	  case GXorReverse:	    rop = RROP_WHITE;	    break;	  case GXcopyInverted:	    rop = RROP_BLACK;	    break;	  case GXorInverted:	    rop = RROP_NOP;	    break;	  case GXnand:	    rop = RROP_INVERT;	    break;	  case GXset:	    rop = RROP_WHITE;	    break;	}    }    return rop;}voidmfbDestroyClip(pGC)    GCPtr	pGC;{    if(pGC->clientClipType == CT_NONE)	return;    else if (pGC->clientClipType == CT_PIXMAP)    {	mfbDestroyPixmap((PixmapPtr)(pGC->clientClip));    }    else    {	/* we know we'll never have a list of rectangles, since	   ChangeClip immediately turns them into a region 	*/        (*pGC->pScreen->RegionDestroy)(pGC->clientClip);    }    pGC->clientClip = NULL;    pGC->clientClipType = CT_NONE;}voidmfbChangeClip(pGC, type, pvalue, nrects)    GCPtr	    pGC;    unsigned int    type;    pointer	    pvalue;    int		    nrects;{    mfbDestroyClip(pGC);    if(type == CT_PIXMAP)    {	/* convert the pixmap to a region */	pGC->clientClip = (pointer) (*pGC->pScreen->BitmapToRegion)((PixmapPtr)pvalue);	/* you wouldn't do this if you were leaving the pixmap in	   rather than converting it.	*/	(*pGC->pScreen->DestroyPixmap)(pvalue);    }    else if (type == CT_REGION)    {	/* stuff the region in the GC */	pGC->clientClip = pvalue;    }    else if (type != CT_NONE)    {	pGC->clientClip = (pointer) (*pGC->pScreen->RectsToRegion)(nrects,						    (xRectangle *)pvalue,						    type);	xfree(pvalue);    }    pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION :        CT_NONE;    pGC->stateChanges |= GCClipMask;}voidmfbCopyClip (pgcDst, pgcSrc)    GCPtr pgcDst, pgcSrc;{    RegionPtr prgnNew;    switch(pgcSrc->clientClipType)    {      case CT_PIXMAP:	((PixmapPtr) pgcSrc->clientClip)->refcnt++;	/* Fall through !! */      case CT_NONE:	mfbChangeClip(pgcDst, pgcSrc->clientClipType, pgcSrc->clientClip, 0);	break;      case CT_REGION:	prgnNew = (*pgcSrc->pScreen->RegionCreate)(NULL, 1);	(*pgcSrc->pScreen->RegionCopy)(prgnNew,				       (RegionPtr)(pgcSrc->clientClip));	mfbChangeClip(pgcDst, CT_REGION, (pointer)prgnNew, 0);	break;    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -