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); }
Bool QueryTextExtents(FontPtr pFont, unsigned long count, unsigned char *chars, ExtentInfoRec *info) { xCharInfo **charinfo; unsigned long n; FontEncoding encoding; int cm; int i; unsigned long t; xCharInfo *defaultChar = 0; unsigned char defc[2]; int firstReal; charinfo = (xCharInfo **) xalloc(count * sizeof(xCharInfo *)); if (!charinfo) return FALSE; encoding = TwoD16Bit; if (pFont->info.lastRow == 0) encoding = Linear16Bit; (*pFont->get_metrics) (pFont, count, chars, encoding, &n, charinfo); /* Do default character substitution as get_metrics doesn't */ #define IsNonExistentChar(ci) (!(ci) || \ ((ci)->ascent == 0 && \ (ci)->descent == 0 && \ (ci)->leftSideBearing == 0 && \ (ci)->rightSideBearing == 0 && \ (ci)->characterWidth == 0)) firstReal = n; defc[0] = pFont->info.defaultCh >> 8; defc[1] = pFont->info.defaultCh; (*pFont->get_metrics) (pFont, 1, defc, encoding, &t, &defaultChar); if ((IsNonExistentChar (defaultChar))) defaultChar = 0; for (i = 0; i < n; i++) { if ((IsNonExistentChar (charinfo[i]))) { if (!defaultChar) continue; charinfo[i] = defaultChar; } if (firstReal == n) firstReal = i; } cm = pFont->info.constantMetrics; pFont->info.constantMetrics = FALSE; QueryGlyphExtents(pFont, (CharInfoPtr*) charinfo + firstReal, n - firstReal, info); pFont->info.constantMetrics = cm; xfree(charinfo); return TRUE; }
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; } }