📄 mfbgc.c
字号:
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 <= PPW) && !(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 <= PPW) && !(pGC->stipple->drawable.width & (pGC->stipple->drawable.width - 1))) { mfbCopyRotatePixmap(pGC->stipple, &devPriv->pRotatedPixmap, xrot, yrot); new_pix = TRUE; } } /* destroy any previously rotated tile or stipple */ if (!new_pix && devPriv->pRotatedPixmap) { (*pDrawable->pScreen->DestroyPixmap)(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) miDestroyGCOps (pGC->ops); pGC->ops = newops; new_line = new_fill = new_text = 0; } else { if (!pGC->ops->devPrivate.val) { pGC->ops = miCreateGCOps (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 = (void (*)())NoopDDA; } else { pGC->ops->PolyGlyphBlt = miPolyGlyphBlt; } } } if (new_fill) { /* install a suitable fillspans and pushpixels */ pGC->ops->PushPixels = mfbPushPixels; pGC->ops->FillPolygon = miFillPolygon; 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; pGC->ops->FillPolygon = mfbFillPolyWhite; break; case RROP_BLACK: pGC->ops->FillSpans = mfbBlackSolidFS; pGC->ops->FillPolygon = mfbFillPolyBlack; break; case RROP_INVERT: pGC->ops->FillSpans = mfbInvertSolidFS; pGC->ops->FillPolygon = mfbFillPolyInvert; break; case RROP_NOP: pGC->ops->FillSpans = (void (*)())NoopDDA; pGC->ops->FillPolygon = (void (*)())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 = (void (*)())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 = (void (*)())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 = (void (*)())NoopDDA; break; } } else /* deal with tiles */ { switch (pGC->alu) { case GXcopy: devPriv->FillArea = mfbTileAreaPPWCopy; break; default: devPriv->FillArea = mfbTileAreaPPWGeneral; 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 int 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;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -