📄 gc.c
字号:
pgcDst->arcMode = pgcSrc->arcMode; break; default: clientErrorValue = maskQ; error = BadValue; break; } } if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel) { if (!CreateDefaultTile (pgcDst)) { pgcDst->fillStyle = FillSolid; error = BadAlloc; } } (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst); return error;}/***************** * FreeGC * does the diX part of freeing the characteristics in the GC ***************//*ARGSUSED*/intFreeGC(value, gid) pointer value; /* must conform to DeleteType */ XID gid;{ GCPtr pGC = (GCPtr)value; CloseFont(pGC->font, (Font)0); (* pGC->funcs->DestroyClip)(pGC); if (!pGC->tileIsPixel) (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap); if (pGC->stipple) (* pGC->pScreen->DestroyPixmap)(pGC->stipple); (*pGC->funcs->DestroyGC) (pGC); if (pGC->dash != DefaultDash) xfree(pGC->dash); xfree(pGC); return(Success);}voidSetGCMask(pGC, selectMask, newDataMask) GCPtr pGC; Mask selectMask; Mask newDataMask;{ pGC->stateChanges = (~selectMask & pGC->stateChanges) | (selectMask & newDataMask); if (selectMask & newDataMask) pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; }/* CreateScratchGC(pScreen, depth) like CreateGC, but doesn't do the default tile or stipple,since we can't create them without already having a GC. any codeusing the tile or stipple has to set them explicitly anyway,since the state of the scratch gc is unknown. This is OKbecause ChangeGC() has to be able to deal with NULL tiles andstipples anyway (in case the CreateGC() call has provided a value for them -- we can't set the default tile until theclient-supplied attributes are installed, since the fgPixelis what fills the default tile. (maybe this comment shouldgo with CreateGC() or ChangeGC().)*/GCPtrCreateScratchGC(pScreen, depth) ScreenPtr pScreen; unsigned depth;{ register GCPtr pGC; pGC = AllocateGC(pScreen); if (!pGC) return (GCPtr)NULL; pGC->pScreen = pScreen; pGC->depth = depth; pGC->alu = GXcopy; /* dst <- src */ pGC->planemask = ~0; pGC->serialNumber = 0; pGC->fgPixel = 0; pGC->bgPixel = 1; pGC->lineWidth = 0; pGC->lineStyle = LineSolid; pGC->capStyle = CapButt; pGC->joinStyle = JoinMiter; pGC->fillStyle = FillSolid; pGC->fillRule = EvenOddRule; pGC->arcMode = ArcPieSlice; pGC->font = defaultFont; if ( pGC->font) /* necessary, because open of default font could fail */ pGC->font->refcnt++; pGC->tileIsPixel = TRUE; pGC->tile.pixel = 0; pGC->stipple = NullPixmap; pGC->patOrg.x = 0; pGC->patOrg.y = 0; pGC->subWindowMode = ClipByChildren; pGC->graphicsExposures = TRUE; pGC->clipOrg.x = 0; pGC->clipOrg.y = 0; pGC->clientClipType = CT_NONE; pGC->dashOffset = 0; pGC->numInDashList = 2; pGC->dash = DefaultDash; pGC->lastWinOrg.x = 0; pGC->lastWinOrg.y = 0; pGC->stateChanges = (1 << (GCLastBit+1)) - 1; if (!(*pScreen->CreateGC)(pGC)) { FreeGC(pGC, (XID)0); pGC = (GCPtr)NULL; } return pGC;}voidFreeGCperDepth(screenNum) int screenNum;{ register int i; register ScreenPtr pScreen; GCPtr *ppGC; pScreen = screenInfo.screens[screenNum]; ppGC = pScreen->GCperDepth; for (i = 0; i <= pScreen->numDepths; i++) (void)FreeGC(ppGC[i], (XID)0); pScreen->rgf = ~0L;}BoolCreateGCperDepth(screenNum) int screenNum;{ register int i; register ScreenPtr pScreen; DepthPtr pDepth; GCPtr *ppGC; pScreen = screenInfo.screens[screenNum]; pScreen->rgf = 0; ppGC = pScreen->GCperDepth; /* do depth 1 separately because it's not included in list */ if (!(ppGC[0] = CreateScratchGC(pScreen, 1))) return FALSE; ppGC[0]->graphicsExposures = FALSE; pDepth = pScreen->allowedDepths; for (i=0; i<pScreen->numDepths; i++, pDepth++) { if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth))) { for (; i >= 0; i--) (void)FreeGC(ppGC[i], (XID)0); return FALSE; } ppGC[i+1]->graphicsExposures = FALSE; } return TRUE;}BoolCreateDefaultStipple(screenNum) int screenNum;{ register ScreenPtr pScreen; XID tmpval[3]; xRectangle rect; CARD16 w, h; GCPtr pgcScratch; pScreen = screenInfo.screens[screenNum]; w = 16; h = 16; (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen); if (!(pScreen->PixmapPerDepth[0] = (*pScreen->CreatePixmap)(pScreen, w, h, 1))) return FALSE; /* fill stipple with 1 */ tmpval[0] = GXcopy; tmpval[1] = 1; tmpval[2] = FillSolid; pgcScratch = GetScratchGC(1, pScreen); if (!pgcScratch) { (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]); return FALSE; } (void)ChangeGC(pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval); ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch); rect.x = 0; rect.y = 0; rect.width = w; rect.height = h; (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch, 1, &rect); FreeScratchGC(pgcScratch); return TRUE;}voidFreeDefaultStipple(screenNum) int screenNum;{ ScreenPtr pScreen = screenInfo.screens[screenNum]; (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);}intSetDashes(pGC, offset, ndash, pdash)register GCPtr pGC;unsigned offset;register unsigned ndash;register unsigned char *pdash;{ register long i; register unsigned char *p, *indash; BITS32 maskQ = 0; i = ndash; p = pdash; while (i--) { if (!*p++) { /* dash segment must be > 0 */ clientErrorValue = 0; return BadValue; } } if (ndash & 1) p = (unsigned char *)xalloc(2 * ndash * sizeof(unsigned char)); else p = (unsigned char *)xalloc(ndash * sizeof(unsigned char)); if (!p) return BadAlloc; pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; if (offset != pGC->dashOffset) { pGC->dashOffset = offset; pGC->stateChanges |= GCDashOffset; maskQ |= GCDashOffset; } if (pGC->dash != DefaultDash) xfree(pGC->dash); pGC->numInDashList = ndash; pGC->dash = p; if (ndash & 1) { pGC->numInDashList += ndash; indash = pdash; i = ndash; while (i--) *p++ = *indash++; } while(ndash--) *p++ = *pdash++; pGC->stateChanges |= GCDashList; maskQ |= GCDashList; if (pGC->funcs->ChangeGC) (*pGC->funcs->ChangeGC) (pGC, maskQ); return Success;}intVerifyRectOrder(nrects, prects, ordering) int nrects; xRectangle *prects; int ordering;{ register xRectangle *prectP, *prectN; register int i; switch(ordering) { case Unsorted: return CT_UNSORTED; case YSorted: if(nrects > 1) { for(i = 1, prectP = prects, prectN = prects + 1; i < nrects; i++, prectP++, prectN++) if(prectN->y < prectP->y) return -1; } return CT_YSORTED; case YXSorted: if(nrects > 1) { for(i = 1, prectP = prects, prectN = prects + 1; i < nrects; i++, prectP++, prectN++) if((prectN->y < prectP->y) || ( (prectN->y == prectP->y) && (prectN->x < prectP->x) ) ) return -1; } return CT_YXSORTED; case YXBanded: if(nrects > 1) { for(i = 1, prectP = prects, prectN = prects + 1; i < nrects; i++, prectP++, prectN++) if((prectN->y != prectP->y && prectN->y < prectP->y + (int) prectP->height) || ((prectN->y == prectP->y) && (prectN->height != prectP->height || prectN->x < prectP->x + (int) prectP->width))) return -1; } return CT_YXBANDED; } return -1;}intSetClipRects(pGC, xOrigin, yOrigin, nrects, prects, ordering) GCPtr pGC; int xOrigin, yOrigin; int nrects; xRectangle *prects; int ordering;{ int newct, size; xRectangle *prectsNew; newct = VerifyRectOrder(nrects, prects, ordering); if (newct < 0) return(BadMatch); size = nrects * sizeof(xRectangle); prectsNew = (xRectangle *) xalloc(size); if (!prectsNew && size) return BadAlloc; pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; pGC->clipOrg.x = xOrigin; pGC->stateChanges |= GCClipXOrigin; pGC->clipOrg.y = yOrigin; pGC->stateChanges |= GCClipYOrigin; if (size) memmove((char *)prectsNew, (char *)prects, size); (*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects); if (pGC->funcs->ChangeGC) (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask); return Success;}/* sets reasonable defaults if we can get a pre-allocated one, use it and mark it as used. if we can't, create one out of whole cloth (The Velveteen GC -- if you use it often enough it will become real.)*/GCPtrGetScratchGC(depth, pScreen) register unsigned depth; register ScreenPtr pScreen;{ register int i; register GCPtr pGC; for (i=0; i<=pScreen->numDepths; i++) if ( pScreen->GCperDepth[i]->depth == depth && !(pScreen->rgf & (1L << (i+1))) ) { pScreen->rgf |= (1L << (i+1)); pGC = (pScreen->GCperDepth[i]); pGC->alu = GXcopy; pGC->planemask = ~0; pGC->serialNumber = 0; pGC->fgPixel = 0; pGC->bgPixel = 1; pGC->lineWidth = 0; pGC->lineStyle = LineSolid; pGC->capStyle = CapButt; pGC->joinStyle = JoinMiter; pGC->fillStyle = FillSolid; pGC->fillRule = EvenOddRule; pGC->arcMode = ArcChord; pGC->patOrg.x = 0; pGC->patOrg.y = 0; pGC->subWindowMode = ClipByChildren; pGC->graphicsExposures = FALSE; pGC->clipOrg.x = 0; pGC->clipOrg.y = 0; if (pGC->clientClipType != CT_NONE) (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0); pGC->stateChanges = (1 << (GCLastBit+1)) - 1; return pGC; } /* if we make it this far, need to roll our own */ pGC = CreateScratchGC(pScreen, depth); if (pGC) pGC->graphicsExposures = FALSE; return pGC;}/* if the gc to free is in the table of pre-existing ones,mark it as available. if not, free it for real*/voidFreeScratchGC(pGC) register GCPtr pGC;{ register ScreenPtr pScreen = pGC->pScreen; register int i; for (i=0; i<=pScreen->numDepths; i++) { if ( pScreen->GCperDepth[i] == pGC) { pScreen->rgf &= ~(1L << (i+1)); return; } } (void)FreeGC(pGC, (GContext)0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -