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 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; } } }
static GCOps * cfb32MatchCommon_Underlay( GCPtr pGC, cfbPrivGCPtr devPriv) { if (pGC->lineWidth != 0) return 0; if (pGC->lineStyle != LineSolid) return 0; if (pGC->fillStyle != FillSolid) return 0; if (devPriv->rop != GXcopy) return 0; if (pGC->font && FONTMAXBOUNDS(pGC->font,rightSideBearing) - FONTMINBOUNDS(pGC->font,leftSideBearing) <= 32 && FONTMINBOUNDS(pGC->font,characterWidth) >= 0) { if (TERMINALFONT(pGC->font) #ifdef FOUR_BIT_CODE && FONTMAXBOUNDS(pGC->font,characterWidth) >= PGSZB #endif ) #ifdef NO_ONE_RECT return &cfbTEOps1Rect; #else if (devPriv->oneRect) return &cfbTEOps1Rect; else return &cfbTEOps; #endif else #ifdef NO_ONE_RECT return &cfbNonTEOps1Rect; #else if (devPriv->oneRect) return &cfbNonTEOps1Rect; else return &cfbNonTEOps; #endif }
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 miPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase) { int width, height; PixmapPtr pPixmap; int nbyLine; /* bytes per line of padded pixmap */ FontPtr pfont; GCPtr pGCtmp; int i; int j; unsigned char *pbits; /* buffer for PutImage */ unsigned char *pb; /* temp pointer into buffer */ CharInfoPtr pci; /* currect char info */ unsigned char *pglyph; /* pointer bits in glyph */ int gWidth, gHeight; /* width and height of glyph */ int nbyGlyphWidth; /* bytes per scanline of glyph */ int nbyPadGlyph; /* server padded line of glyph */ XID gcvals[3]; if (pGC->miTranslate) { x += pDrawable->x; y += pDrawable->y; } pfont = pGC->font; width = FONTMAXBOUNDS(pfont,rightSideBearing) - FONTMINBOUNDS(pfont,leftSideBearing); height = FONTMAXBOUNDS(pfont,ascent) + FONTMAXBOUNDS(pfont,descent); pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen, width, height, 1); if (!pPixmap) return; pGCtmp = GetScratchGC(1, pDrawable->pScreen); if (!pGCtmp) { (*pDrawable->pScreen->DestroyPixmap)(pPixmap); return; } gcvals[0] = GXcopy; gcvals[1] = 1; gcvals[2] = 0; DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0); nbyLine = BitmapBytePad(width); pbits = (unsigned char *)ALLOCATE_LOCAL(height*nbyLine); if (!pbits) { (*pDrawable->pScreen->DestroyPixmap)(pPixmap); FreeScratchGC(pGCtmp); return; } while(nglyph--) { pci = *ppci++; pglyph = FONTGLYPHBITS(pglyphBase, pci); gWidth = GLYPHWIDTHPIXELS(pci); gHeight = GLYPHHEIGHTPIXELS(pci); if (gWidth && gHeight) { nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci); nbyPadGlyph = BitmapBytePad(gWidth); if (nbyGlyphWidth == nbyPadGlyph #if GLYPHPADBYTES != 4 && (((int) pglyph) & 3) == 0 #endif ) { pb = pglyph; } else { for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph)) for (j = 0; j < nbyGlyphWidth; j++) *pb++ = *pglyph++; pb = pbits; } if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber)) ValidateGC((DrawablePtr)pPixmap, pGCtmp); (*pGCtmp->ops->PutImage)((DrawablePtr)pPixmap, pGCtmp, pPixmap->drawable.depth, 0, 0, gWidth, gHeight, 0, XYBitmap, (char *)pb); if ((pGC->serialNumber) != (pDrawable->serialNumber)) ValidateGC(pDrawable, pGC); (*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable, gWidth, gHeight, x + pci->metrics.leftSideBearing, y - pci->metrics.ascent); } x += pci->metrics.characterWidth; } (*pDrawable->pScreen->DestroyPixmap)(pPixmap); DEALLOCATE_LOCAL(pbits); FreeScratchGC(pGCtmp); }
void LeoPolyGlyphBlt (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; CharInfoPtr pci; int w, h, x0, y0, i; unsigned int *bits; BoxRec box; int curw = -1; unsigned int *fbf; unsigned char *fb; int height, width; clip = cfbGetCompositeClip(pGC); /* compute an approximate (but covering) bounding box */ box.x1 = 0; if (ppci[0]->metrics.leftSideBearing < 0) box.x1 = ppci[0]->metrics.leftSideBearing; h = nglyph - 1; w = ppci[h]->metrics.rightSideBearing; while (--h >= 0) w += ppci[h]->metrics.characterWidth; box.x2 = w; box.y1 = -FONTMAXBOUNDS(pGC->font,ascent); box.y2 = FONTMAXBOUNDS(pGC->font,descent); box.x1 += pDrawable->x + x; box.x2 += pDrawable->x + x; box.y1 += pDrawable->y + y; box.y2 += pDrawable->y + y; switch (RECT_IN_REGION(pGC->pScreen, clip, &box)) { 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; } cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pGlyphBase); case rgnOUT: return; default: clip = NULL; break; } x += pDrawable->x; y += pDrawable->y; lc0->fontt = 1; 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; height = pLeo->height; width = pLeo->width; fb = (unsigned char *)pLeo->fb; while (nglyph--) { pci = *ppci++; w = GLYPHWIDTHPIXELS (pci); h = GLYPHHEIGHTPIXELS (pci); if (!w || !h) goto next_glyph; x0 = x + pci->metrics.leftSideBearing; y0 = y - pci->metrics.ascent; /* We're off the screen to the left, making our way * back onto the screen. */ if((x0 >> 31) == -1) goto next_glyph; /* We walked off the screen (to the right or downwards) * or we started there, we're never going to work our * way back so stop now. */ if(x0 >= width || y0 >= height) break; bits = (unsigned int *) pci->bits; if (w != curw) { curw = w; if (w) lc0->fontmsk = 0xffffffff << (32 - w); else lc0->fontmsk = 0; } fbf = (unsigned *)(fb + (y0 << 13) + (x0 << 2)); if (y0 + h <= height) for (i = 0; i < h; i++) { *fbf = *bits++; fbf += 2048; } else for (i = 0; i < h && y0 + i < height; i++) { *fbf = *bits++; fbf += 2048; } next_glyph: x += pci->metrics.characterWidth; } lc0->addrspace = LEO_ADDRSPC_OBGR; if (pGC->alu != GXcopy) ld0->rop = LEO_ATTR_RGBE_ENABLE|LEO_ROP_NEW; if (pGC->planemask != 0xffffff) ld0->planemask = 0xffffff; if (clip) { ld0->vclipmin = 0; ld0->vclipmax = pLeo->vclipmax; } }
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; } }