📄 misprite.c
字号:
extents.overallAscent = FONTASCENT(font); else extents.overallAscent = FONTMAXBOUNDS(font, ascent); if (imageblt && FONTDESCENT(font) > FONTMAXBOUNDS(font,descent)) extents.overallDescent = FONTDESCENT(font); else extents.overallDescent = FONTMAXBOUNDS(font,descent); if (!BOX_OVERLAP(cursorBox, x + extents.overallLeft, y - extents.overallAscent, x + extents.overallRight, y + extents.overallDescent)) return FALSE; else if (imageblt && w) return TRUE; /* if it does overlap, fall through and compute exactly, because * taking down the cursor is expensive enough to make this worth it */ } QueryGlyphExtents(font, charinfo, n, &extents); if (imageblt) { if (extents.overallWidth > extents.overallRight) extents.overallRight = extents.overallWidth; if (extents.overallWidth < extents.overallLeft) extents.overallLeft = extents.overallWidth; if (extents.overallLeft > 0) extents.overallLeft = 0; if (extents.fontAscent > extents.overallAscent) extents.overallAscent = extents.fontAscent; if (extents.fontDescent > extents.overallDescent) extents.overallDescent = extents.fontDescent; } return (BOX_OVERLAP(cursorBox, x + extents.overallLeft, y - extents.overallAscent, x + extents.overallRight, y + extents.overallDescent));}/* * values for textType: */#define TT_POLY8 0#define TT_IMAGE8 1#define TT_POLY16 2#define TT_IMAGE16 3static int miSpriteText (pDraw, pGC, x, y, count, chars, fontEncoding, textType, cursorBox) DrawablePtr pDraw; GCPtr pGC; int x, y; unsigned long count; char *chars; FontEncoding fontEncoding; Bool textType; BoxPtr cursorBox;{ CharInfoPtr *charinfo; register CharInfoPtr *info; unsigned long i; unsigned int n; int w; void (*drawFunc)(); Bool imageblt; imageblt = (textType == TT_IMAGE8) || (textType == TT_IMAGE16); charinfo = (CharInfoPtr *) ALLOCATE_LOCAL(count * sizeof(CharInfoPtr)); if (!charinfo) return x; GetGlyphs(pGC->font, count, (unsigned char *)chars, fontEncoding, &i, charinfo); n = (unsigned int)i; w = 0; if (!imageblt) for (info = charinfo; i--; info++) w += (*info)->metrics.characterWidth; if (n != 0) { if (miSpriteTextOverlap(pDraw, pGC->font, x, y, n, charinfo, imageblt, w, cursorBox)) miSpriteRemoveCursor(pDraw->pScreen);#ifdef AVOID_GLYPHBLT /* * On displays like Apollos, which do not optimize the GlyphBlt functions because they * convert fonts to their internal form in RealizeFont and optimize text directly, we * want to invoke the text functions here, not the GlyphBlt functions. */ switch (textType) { case TT_POLY8: drawFunc = (void (*)())pGC->ops->PolyText8; break; case TT_IMAGE8: drawFunc = pGC->ops->ImageText8; break; case TT_POLY16: drawFunc = (void (*)())pGC->ops->PolyText16; break; case TT_IMAGE16: drawFunc = pGC->ops->ImageText16; break; } (*drawFunc) (pDraw, pGC, x, y, (int) count, chars);#else /* don't AVOID_GLYPHBLT */ /* * On the other hand, if the device does use GlyphBlt ultimately to do text, we * don't want to slow it down by invoking the text functions and having them call * GetGlyphs all over again, so we go directly to the GlyphBlt functions here. */ drawFunc = imageblt ? pGC->ops->ImageGlyphBlt : pGC->ops->PolyGlyphBlt; (*drawFunc) (pDraw, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font));#endif /* AVOID_GLYPHBLT */ } DEALLOCATE_LOCAL(charinfo); return x + w;}static intmiSpritePolyText8(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; char *chars;{ int ret; GC_SETUP (pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable)) ret = miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars, Linear8Bit, TT_POLY8, &pScreenPriv->saved); else ret = (*pGC->ops->PolyText8) (pDrawable, pGC, x, y, count, chars); GC_OP_EPILOGUE (pGC); return ret;}static intmiSpritePolyText16(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; unsigned short *chars;{ int ret; GC_SETUP(pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable)) ret = miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, (char *)chars, FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, TT_POLY16, &pScreenPriv->saved); else ret = (*pGC->ops->PolyText16) (pDrawable, pGC, x, y, count, chars); GC_OP_EPILOGUE (pGC); return ret;}static voidmiSpriteImageText8(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; char *chars;{ GC_SETUP(pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable)) (void) miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, chars, Linear8Bit, TT_IMAGE8, &pScreenPriv->saved); else (*pGC->ops->ImageText8) (pDrawable, pGC, x, y, count, chars); GC_OP_EPILOGUE (pGC);}static voidmiSpriteImageText16(pDrawable, pGC, x, y, count, chars) DrawablePtr pDrawable; GCPtr pGC; int x, y; int count; unsigned short *chars;{ GC_SETUP(pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable)) (void) miSpriteText (pDrawable, pGC, x, y, (unsigned long)count, (char *)chars, FONTLASTROW(pGC->font) == 0 ? Linear16Bit : TwoD16Bit, TT_IMAGE16, &pScreenPriv->saved); else (*pGC->ops->ImageText16) (pDrawable, pGC, x, y, count, chars); GC_OP_EPILOGUE (pGC);}static voidmiSpriteImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) DrawablePtr pDrawable; GCPtr pGC; int x, y; unsigned int nglyph; CharInfoPtr *ppci; /* array of character info */ pointer pglyphBase; /* start of array of glyphs */{ GC_SETUP(pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable) && miSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, TRUE, 0, &pScreenPriv->saved)) { miSpriteRemoveCursor(pDrawable->pScreen); } (*pGC->ops->ImageGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); GC_OP_EPILOGUE (pGC);}static voidmiSpritePolyGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase) DrawablePtr pDrawable; GCPtr pGC; int x, y; unsigned int nglyph; CharInfoPtr *ppci; /* array of character info */ pointer pglyphBase; /* start of array of glyphs */{ GC_SETUP (pDrawable, pGC); GC_OP_PROLOGUE (pGC); if (GC_CHECK((WindowPtr) pDrawable) && miSpriteTextOverlap (pDrawable, pGC->font, x, y, nglyph, ppci, FALSE, 0, &pScreenPriv->saved)) { miSpriteRemoveCursor(pDrawable->pScreen); } (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); GC_OP_EPILOGUE (pGC);}static voidmiSpritePushPixels(pGC, pBitMap, pDrawable, w, h, x, y) GCPtr pGC; PixmapPtr pBitMap; DrawablePtr pDrawable; int w, h, x, y;{ GC_SETUP(pDrawable, pGC); if (GC_CHECK((WindowPtr) pDrawable) && ORG_OVERLAP(&pScreenPriv->saved,pDrawable->x,pDrawable->y,x,y,w,h)) { miSpriteRemoveCursor (pDrawable->pScreen); } GC_OP_PROLOGUE (pGC); (*pGC->ops->PushPixels) (pGC, pBitMap, pDrawable, w, h, x, y); GC_OP_EPILOGUE (pGC);}#ifdef NEED_LINEHELPER/* * I don't expect this routine will ever be called, as the GC * will have been unwrapped for the line drawing */static voidmiSpriteLineHelper(){ FatalError("miSpriteLineHelper called\n");}#endif/* * miPointer interface routines */#define SPRITE_PAD 8static BoolmiSpriteRealizeCursor (pScreen, pCursor) ScreenPtr pScreen; CursorPtr pCursor;{ miSpriteScreenPtr pScreenPriv; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; if (pCursor == pScreenPriv->pCursor) pScreenPriv->checkPixels = TRUE; return (*pScreenPriv->funcs->RealizeCursor) (pScreen, pCursor);}static BoolmiSpriteUnrealizeCursor (pScreen, pCursor) ScreenPtr pScreen; CursorPtr pCursor;{ miSpriteScreenPtr pScreenPriv; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; return (*pScreenPriv->funcs->UnrealizeCursor) (pScreen, pCursor);}static voidmiSpriteSetCursor (pScreen, pCursor, x, y) ScreenPtr pScreen; CursorPtr pCursor;{ miSpriteScreenPtr pScreenPriv; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv->shouldBeUp = TRUE; if (pScreenPriv->x == x && pScreenPriv->y == y && pScreenPriv->pCursor == pCursor && !pScreenPriv->checkPixels) { return; } if (!pCursor) { pScreenPriv->shouldBeUp = FALSE; if (pScreenPriv->isUp) miSpriteRemoveCursor (pScreen); pScreenPriv->pCursor = 0; return; } pScreenPriv->x = x; pScreenPriv->y = y; pScreenPriv->pCacheWin = NullWindow; if (pScreenPriv->checkPixels || pScreenPriv->pCursor != pCursor) { pScreenPriv->pCursor = pCursor; miSpriteFindColors (pScreen); } if (pScreenPriv->isUp) { int sx, sy; /* * check to see if the old saved region * encloses the new sprite, in which case we use * the flicker-free MoveCursor primitive. */ sx = pScreenPriv->x - (int)pCursor->bits->xhot; sy = pScreenPriv->y - (int)pCursor->bits->yhot; if (sx + (int) pCursor->bits->width >= pScreenPriv->saved.x1 && sx < pScreenPriv->saved.x2 && sy + (int) pCursor->bits->height >= pScreenPriv->saved.y1 && sy < pScreenPriv->saved.y2 && (int) pCursor->bits->width + (2 * SPRITE_PAD) == pScreenPriv->saved.x2 - pScreenPriv->saved.x1 && (int) pCursor->bits->height + (2 * SPRITE_PAD) == pScreenPriv->saved.y2 - pScreenPriv->saved.y1 ) { pScreenPriv->isUp = FALSE; if (!(sx >= pScreenPriv->saved.x1 && sx + (int)pCursor->bits->width < pScreenPriv->saved.x2 && sy >= pScreenPriv->saved.y1 && sy + (int)pCursor->bits->height < pScreenPriv->saved.y2)) { int oldx1, oldy1, dx, dy; oldx1 = pScreenPriv->saved.x1; oldy1 = pScreenPriv->saved.y1; dx = oldx1 - (sx - SPRITE_PAD); dy = oldy1 - (sy - SPRITE_PAD); pScreenPriv->saved.x1 -= dx; pScreenPriv->saved.y1 -= dy; pScreenPriv->saved.x2 -= dx; pScreenPriv->saved.y2 -= dy; (void) (*pScreenPriv->funcs->ChangeSave) (pScreen, pScreenPriv->saved.x1, pScreenPriv->saved.y1, pScreenPriv->saved.x2 - pScreenPriv->saved.x1, pScreenPriv->saved.y2 - pScreenPriv->saved.y1, dx, dy); } (void) (*pScreenPriv->funcs->MoveCursor) (pScreen, pCursor, pScreenPriv->saved.x1, pScreenPriv->saved.y1, pScreenPriv->saved.x2 - pScreenPriv->saved.x1, pScreenPriv->saved.y2 - pScreenPriv->saved.y1, sx - pScreenPriv->saved.x1, sy - pScreenPriv->saved.y1, pScreenPriv->colors[SOURCE_COLOR].pixel, pScreenPriv->colors[MASK_COLOR].pixel); pScreenPriv->isUp = TRUE; } else { miSpriteRemoveCursor (pScreen); } } if (!pScreenPriv->isUp && pScreenPriv->pCursor) miSpriteRestoreCursor (pScreen);}static voidmiSpriteMoveCursor (pScreen, x, y) ScreenPtr pScreen; int x, y;{ miSpriteScreenPtr pScreenPriv; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; miSpriteSetCursor (pScreen, pScreenPriv->pCursor, x, y);}/* * undraw/draw cursor */static voidmiSpriteRemoveCursor (pScreen) ScreenPtr pScreen;{ miSpriteScreenPtr pScreenPriv; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pScreenPriv->isUp = FALSE; pScreenPriv->pCacheWin = NullWindow; if (!(*pScreenPriv->funcs->RestoreUnderCursor) (pScreen, pScreenPriv->saved.x1, pScreenPriv->saved.y1, pScreenPriv->saved.x2 - pScreenPriv->saved.x1, pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) { pScreenPriv->isUp = TRUE; }}/* * Called from the block handler, restores the cursor * before waiting for something to do. */static voidmiSpriteRestoreCursor (pScreen) ScreenPtr pScreen;{ miSpriteScreenPtr pScreenPriv; int x, y; CursorPtr pCursor; miSpriteComputeSaved (pScreen); pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pCursor = pScreenPriv->pCursor; x = pScreenPriv->x - (int)pCursor->bits->xhot; y = pScreenPriv->y - (int)pCursor->bits->yhot; if ((*pScreenPriv->funcs->SaveUnderCursor) (pScreen, pScreenPriv->saved.x1, pScreenPriv->saved.y1, pScreenPriv->saved.x2 - pScreenPriv->saved.x1, pScreenPriv->saved.y2 - pScreenPriv->saved.y1)) { if (pScreenPriv->checkPixels) miSpriteFindColors (pScreen); if ((*pScreenPriv->funcs->PutUpCursor) (pScreen, pCursor, x, y, pScreenPriv->colors[SOURCE_COLOR].pixel, pScreenPriv->colors[MASK_COLOR].pixel)) pScreenPriv->isUp = TRUE; }}/* * compute the desired area of the screen to save */static voidmiSpriteComputeSaved (pScreen) ScreenPtr pScreen;{ miSpriteScreenPtr pScreenPriv; int x, y, w, h; int wpad, hpad; CursorPtr pCursor; pScreenPriv = (miSpriteScreenPtr) pScreen->devPrivates[miSpriteScreenIndex].ptr; pCursor = pScreenPriv->pCursor; x = pScreenPriv->x - (int)pCursor->bits->xhot; y = pScreenPriv->y - (int)pCursor->bits->yhot; w = pCursor->bits->width; h = pCursor->bits->height; wpad = SPRITE_PAD; hpad = SPRITE_PAD; pScreenPriv->saved.x1 = x - wpad; pScreenPriv->saved.y1 = y - hpad; pScreenPriv->saved.x2 = pScreenPriv->saved.x1 + w + wpad * 2; pScreenPriv->saved.y2 = pScreenPriv->saved.y1 + h + hpad * 2;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -