void miImageGlyphBlt( DrawablePtr pDrawable, GC *pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, /* array of character info */ pointer pglyphBase /* start of array of glyphs */ ) { ExtentInfoRec info; /* used by QueryGlyphExtents() */ ChangeGCVal gcvals[3]; int oldAlu, oldFS; unsigned long oldFG; xRectangle backrect; QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info); if (info.overallWidth >= 0) { backrect.x = x; backrect.width = info.overallWidth; } else { backrect.x = x + info.overallWidth; backrect.width = -info.overallWidth; } backrect.y = y - FONTASCENT(pGC->font); backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); oldAlu = pGC->alu; oldFG = pGC->fgPixel; oldFS = pGC->fillStyle; /* fill in the background */ gcvals[0].val = GXcopy; gcvals[1].val = pGC->bgPixel; gcvals[2].val = FillSolid; ChangeGC(NullClient, pGC, GCFunction|GCForeground|GCFillStyle, gcvals); ValidateGC(pDrawable, pGC); (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &backrect); /* put down the glyphs */ gcvals[0].val = oldFG; ChangeGC(NullClient, pGC, GCForeground, gcvals); ValidateGC(pDrawable, pGC); (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); /* put all the toys away when done playing */ gcvals[0].val = oldAlu; gcvals[1].val = oldFG; gcvals[2].val = oldFS; ChangeGC(NullClient, pGC, GCFunction|GCForeground|GCFillStyle, gcvals); ValidateGC(pDrawable, pGC); }
void XAAValidateImageGlyphBlt( GCPtr pGC, unsigned long changes, DrawablePtr pDraw ) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); Bool BigFont = FALSE; pGC->ops->ImageText8 = XAAFallbackOps.ImageText8; pGC->ops->ImageText16 = XAAFallbackOps.ImageText16; pGC->ops->ImageGlyphBlt = XAAFallbackOps.ImageGlyphBlt; if(!pGC->font) return; if((FONTMAXBOUNDS(pGC->font, rightSideBearing) - FONTMINBOUNDS(pGC->font, leftSideBearing) > 32)) BigFont = TRUE; /* no funny business */ if((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) || ((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0)) return; /* Check for TE Fonts */ if(!TERMINALFONT(pGC->font) || BigFont || (pGC->depth == 32)) { if(infoRec->ImageGlyphBltNonTE && CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltNonTEFlags) && CHECK_FG(pGC,infoRec->ImageGlyphBltNonTEFlags) && infoRec->SetupForSolidFill && CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) && CHECK_BG(pGC,infoRec->SolidFillFlags)) { pGC->ops->ImageText8 = infoRec->ImageText8NonTE; pGC->ops->ImageText16 = infoRec->ImageText16NonTE; pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltNonTE; } } else if(infoRec->ImageGlyphBltTE && CHECK_PLANEMASK(pGC,infoRec->ImageGlyphBltTEFlags)){ if(!(infoRec->ImageGlyphBltTEFlags & TRANSPARENCY_ONLY) && CHECK_COLORS(pGC,infoRec->ImageGlyphBltTEFlags)) { pGC->ops->ImageText8 = infoRec->ImageText8TE; pGC->ops->ImageText16 = infoRec->ImageText16TE; pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE; } else { if(CHECK_FG(pGC,infoRec->ImageGlyphBltTEFlags) && infoRec->SetupForSolidFill && CHECK_PLANEMASK(pGC,infoRec->SolidFillFlags) && CHECK_BG(pGC,infoRec->SolidFillFlags)) { pGC->ops->ImageText8 = infoRec->ImageText8TE; pGC->ops->ImageText16 = infoRec->ImageText16TE; pGC->ops->ImageGlyphBlt = infoRec->ImageGlyphBltTE; } } } }
void GetTextBoundingBox(DrawablePtr pDrawable, FontPtr font, int x, int y, int n, BoxPtr pbox) { int maxAscent; int maxDescent; int maxCharWidth; if (FONTASCENT(font) > FONTMAXBOUNDS(font, ascent)) { maxAscent = FONTASCENT(font); } else { maxAscent = FONTMAXBOUNDS(font, ascent); } if (FONTDESCENT(font) > FONTMAXBOUNDS(font, descent)) { maxDescent = FONTDESCENT(font); } else { maxDescent = FONTMAXBOUNDS(font, descent); } if (FONTMAXBOUNDS(font, rightSideBearing) > FONTMAXBOUNDS(font, characterWidth)) { maxCharWidth = FONTMAXBOUNDS(font, rightSideBearing); } else { maxCharWidth = FONTMAXBOUNDS(font, characterWidth); } pbox->x1 = pDrawable->x + x; pbox->y1 = pDrawable->y + y - maxAscent; pbox->x2 = pbox->x1 + maxCharWidth * n; pbox->y2 = pbox->y1 + maxAscent + maxDescent; if (FONTMINBOUNDS(font, leftSideBearing) < 0) { pbox->x1 += FONTMINBOUNDS(font, leftSideBearing); } }
void XAAValidatePolyGlyphBlt(GCPtr pGC, unsigned long changes, DrawablePtr pDraw) { XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_GC(pGC); Bool BigFont = FALSE; pGC->ops->PolyText8 = XAAFallbackOps.PolyText8; pGC->ops->PolyText16 = XAAFallbackOps.PolyText16; pGC->ops->PolyGlyphBlt = XAAFallbackOps.PolyGlyphBlt; if (!pGC->font) return; if (pGC->fillStyle != FillSolid) return; if ((FONTMAXBOUNDS(pGC->font, rightSideBearing) - FONTMINBOUNDS(pGC->font, leftSideBearing) > 32)) BigFont = TRUE; /* no funny business */ if ((FONTMINBOUNDS(pGC->font, characterWidth) <= 0) || ((FONTASCENT(pGC->font) + FONTDESCENT(pGC->font)) <= 0)) return; /* Check for TE Fonts */ if (!TERMINALFONT(pGC->font) || BigFont) { if (infoRec->PolyGlyphBltNonTE && CHECK_PLANEMASK(pGC, infoRec->PolyGlyphBltNonTEFlags) && CHECK_ROP(pGC, infoRec->PolyGlyphBltNonTEFlags) && CHECK_ROPSRC(pGC, infoRec->PolyGlyphBltNonTEFlags) && CHECK_FG(pGC, infoRec->PolyGlyphBltNonTEFlags) && (!(infoRec->PolyGlyphBltNonTEFlags & TRANSPARENCY_GXCOPY_ONLY) || (pGC->alu == GXcopy)) ) { pGC->ops->PolyText8 = infoRec->PolyText8NonTE; pGC->ops->PolyText16 = infoRec->PolyText16NonTE; pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltNonTE; } } else { if (infoRec->PolyGlyphBltTE && CHECK_PLANEMASK(pGC, infoRec->PolyGlyphBltTEFlags) && CHECK_ROP(pGC, infoRec->PolyGlyphBltTEFlags) && CHECK_ROPSRC(pGC, infoRec->PolyGlyphBltNonTEFlags) && CHECK_FG(pGC, infoRec->PolyGlyphBltTEFlags) && (!(infoRec->PolyGlyphBltTEFlags & TRANSPARENCY_GXCOPY_ONLY) || (pGC->alu == GXcopy)) ) { pGC->ops->PolyText8 = infoRec->PolyText8TE; pGC->ops->PolyText16 = infoRec->PolyText16TE; pGC->ops->PolyGlyphBlt = infoRec->PolyGlyphBltTE; } } }
void fbImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppciInit, pointer pglyphBase) { FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); CharInfoPtr *ppci; CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ Bool opaque; int n; int gx, gy; void (*glyph) (FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; glyph = 0; if (pPriv->and == 0) { fbGetDrawable(pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); switch (dstBpp) { case 8: glyph = fbGlyph8; break; case 16: glyph = fbGlyph16; break; case 24: glyph = fbGlyph24; break; case 32: glyph = fbGlyph32; break; } } x += pDrawable->x; y += pDrawable->y; if (TERMINALFONT(pGC->font) && !glyph ) { opaque = TRUE; } else { int xBack, widthBack; int yBack, heightBack; ppci = ppciInit; n = nglyph; widthBack = 0; while (n--) widthBack += (*ppci++)->metrics.characterWidth; xBack = x; if (widthBack < 0) { xBack += widthBack; widthBack = -widthBack; } yBack = y - FONTASCENT(pGC->font); heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); fbSolidBoxClipped(pDrawable, fbGetCompositeClip(pGC), xBack, yBack, xBack + widthBack, yBack + heightBack, fbAnd(GXcopy, pPriv->bg, pPriv->pm), fbXor(GXcopy, pPriv->bg, pPriv->pm)); opaque = FALSE; } ppci = ppciInit; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(pglyphBase, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (glyph && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) { (*glyph) (dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pPriv->fg, gx + dstXoff, gHeight); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPutXYImage(pDrawable, fbGetCompositeClip(pGC), pPriv->fg, pPriv->bg, pPriv->pm, GXcopy, opaque, gx, gy, gWidth, gHeight, (FbStip *) pglyph, gStride, 0); } } x += pci->metrics.characterWidth; } }
void LeoTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pGlyphBase) { LeoPtr pLeo = LeoGetScreenPrivate (pGC->pScreen); LeoCommand0 *lc0 = pLeo->lc0; LeoDraw *ld0 = pLeo->ld0; RegionPtr clip; int h, hTmp; int widthGlyph, widthGlyphs; BoxRec bbox; FontPtr pfont = pGC->font; int curw = -1; unsigned int *fbf; unsigned char *fb; int height, width; widthGlyph = FONTMAXBOUNDS(pfont,characterWidth); h = FONTASCENT(pfont) + FONTDESCENT(pfont); clip = cfbGetCompositeClip(pGC); bbox.x1 = x + pDrawable->x; bbox.x2 = bbox.x1 + (widthGlyph * nglyph); bbox.y1 = y + pDrawable->y - FONTASCENT(pfont); bbox.y2 = bbox.y1 + h; /* If fully out of range, and we have no chance of getting back * in range, no work to do. */ y = y + pDrawable->y - FONTASCENT(pfont); x += pDrawable->x; height = pLeo->height; width = pLeo->width; if (x >= width) return; switch (RECT_IN_REGION(pGC->pScreen, clip, &bbox)) { case rgnPART: if (REGION_NUM_RECTS(clip) == 1) { ld0->vclipmin = (clip->extents.y1 << 16) | clip->extents.x1; ld0->vclipmax = ((clip->extents.y2 - 1) << 16) | (clip->extents.x2 - 1); break; } x -= pDrawable->x; y = y - pDrawable->y + FONTASCENT(pfont); if (pGlyphBase) cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, NULL); else miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pGlyphBase); case rgnOUT: return; default: clip = NULL; break; } lc0->addrspace = LEO_ADDRSPC_FONT_OBGR; ld0->fg = pGC->fgPixel; if (pGC->alu != GXcopy) ld0->rop = leoRopTable[pGC->alu]; if (pGC->planemask != 0xffffff) ld0->planemask = pGC->planemask; fb = (unsigned char *)pLeo->fb; if(pGlyphBase) lc0->fontt = 1; else { lc0->fontt = 0; ld0->bg = pGC->bgPixel; } #define LoopIt(count, w, loadup, fetch) \ if (w != curw) { \ curw = w; \ lc0->fontmsk = 0xffffffff << (32 - w); \ } \ while (nglyph >= count) { \ loadup \ nglyph -= count; \ fbf = (unsigned *)(fb + (y << 13) + (x << 2)); \ hTmp = h; \ if (y + h <= height) \ while (hTmp--) { \ *fbf = fetch; \ fbf += 2048; \ } \ else \ for (hTmp = 0; hTmp < h && y + hTmp < height; hTmp++) { \ *fbf = fetch; \ fbf += 2048; \ } \ x += w; \ if(x >= width) \ goto out; \ } if (widthGlyph <= 8) { widthGlyphs = widthGlyph << 2; LoopIt(4, widthGlyphs, unsigned int *char1 = (unsigned int *) (*ppci++)->bits; unsigned int *char2 = (unsigned int *) (*ppci++)->bits; unsigned int *char3 = (unsigned int *) (*ppci++)->bits; unsigned int *char4 = (unsigned int *) (*ppci++)->bits;,
void xf4bppImageGlyphBlt(DrawablePtr pDrawable, GC *pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase) { ExtentInfoRec info; /* used by QueryGlyphExtents() */ xRectangle backrect;/* backing rectangle to paint. in the general case, NOT necessarily the same as the string's bounding box */ /* GJA -- I agree, this ALL should be moved to GC validation. */ if ( (pDrawable->type != DRAWABLE_WINDOW) || (pGC->alu != GXcopy) || !xf86Screens[pDrawable->pScreen->myNum]->vtSema || ((pGC->font) && (FONTMAXBOUNDS(pGC->font,rightSideBearing) - FONTMINBOUNDS(pGC->font,leftSideBearing) > 32 || FONTMINBOUNDS(pGC->font,characterWidth) < 0)) ) { miImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); } else { ppcPrivGC *pPrivGC; int oldfillStyle, oldfg, oldalu; if (!(pGC->planemask & 0x0F)) return; QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info); backrect.x = x; backrect.y = y - FONTASCENT(pGC->font); backrect.width = info.overallWidth; backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); pPrivGC = pGC->devPrivates[mfbGCPrivateIndex].ptr; oldfillStyle = pPrivGC->colorRrop.fillStyle; /* GJA */ oldfg = pPrivGC->colorRrop.fgPixel; /* GJA */ oldalu = pPrivGC->colorRrop.alu; /* GJA */ pPrivGC->colorRrop.fillStyle = FillSolid; /* GJA */ pPrivGC->colorRrop.fgPixel = pGC->bgPixel; /* GJA */ pGC->fgPixel = pGC->bgPixel; pPrivGC->colorRrop.alu = GXcopy; /* GJA */ pGC->alu = GXcopy; /* Required fields: * colorRrop.alu, colorRrop.planemask, colorRrop.fgPixel */ xf4bppPolyFillRect(pDrawable, pGC, 1, &backrect); pPrivGC->colorRrop.fgPixel = oldfg; /* GJA */ pGC->fgPixel = oldfg; /* the faint-hearted can open their eyes now */ DO_WM3(pGC,doImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase,&info)) pPrivGC->colorRrop.fillStyle = oldfillStyle; /* GJA */ pPrivGC->colorRrop.alu = oldalu; /* GJA */ pGC->alu = oldalu; } }
void fbImageGlyphBlt(DrawablePtr drawable, GCPtr gc, int x, int y, unsigned int nglyph, CharInfoPtr * ppciInit, pointer glyphs) { FbGCPrivPtr pgc = fb_gc(gc); CharInfoPtr *ppci; CharInfoPtr pci; unsigned char *pglyph; /* pointer bits in glyph */ int gWidth, gHeight; /* width and height of glyph */ FbStride gStride; /* stride of glyph */ bool opaque; int n; int gx, gy; void (*raster)(FbBits *, FbStride, int, FbStip *, FbBits, int, int); FbBits *dst = 0; FbStride dstStride = 0; int dstBpp = 0; int dstXoff = 0, dstYoff = 0; DBG(("%s x %d\n", __FUNCTION__, nglyph)); raster = 0; if (pgc->and == 0) { dstBpp = drawable->bitsPerPixel; switch (dstBpp) { case 8: raster = fbGlyph8; break; case 16: raster = fbGlyph16; break; case 32: raster = fbGlyph32; break; } } x += drawable->x; y += drawable->y; if (TERMINALFONT(gc->font) && !raster) { opaque = TRUE; } else { int xBack, widthBack; int yBack, heightBack; ppci = ppciInit; n = nglyph; widthBack = 0; while (n--) widthBack += (*ppci++)->metrics.characterWidth; xBack = x; if (widthBack < 0) { xBack += widthBack; widthBack = -widthBack; } yBack = y - FONTASCENT(gc->font); heightBack = FONTASCENT(gc->font) + FONTDESCENT(gc->font); fbSolidBoxClipped(drawable, gc, xBack, yBack, xBack + widthBack, yBack + heightBack); opaque = FALSE; } ppci = ppciInit; while (nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(glyphs, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { gx = x + pci->metrics.leftSideBearing; gy = y - pci->metrics.ascent; if (raster && gWidth <= sizeof(FbStip) * 8 && fbGlyphIn(gc, gx, gy, gWidth, gHeight)) { fbGetDrawable(drawable, dst, dstStride, dstBpp, dstXoff, dstYoff); raster(dst + (gy + dstYoff) * dstStride, dstStride, dstBpp, (FbStip *) pglyph, pgc->fg, gx + dstXoff, gHeight); } else { gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof(FbStip); fbPutXYImage(drawable, gc, pgc->fg, pgc->bg, pgc->pm, GXcopy, opaque, gx, gy, gWidth, gHeight, (FbStip *) pglyph, gStride, 0); } } x += pci->metrics.characterWidth; } }