#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xmd.h>
#include <X11/Xproto.h>
#include "misc.h"
#include <X11/fonts/fontstruct.h>
#include "dixfontstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "scrnintstr.h"
#include "pixmap.h"
#include "servermd.h"
#include "mi.h"
void
miPolyGlyphBlt(
DrawablePtr pDrawable,
GC *pGC,
int x,
int y,
unsigned int nglyph,
CharInfoPtr *ppci,
pointer pglyphBase
)
{
int width, height;
PixmapPtr pPixmap;
int nbyLine;
FontPtr pfont;
GCPtr pGCtmp;
int i;
int j;
unsigned char *pbits;
unsigned char *pb;
CharInfoPtr pci;
unsigned char *pglyph;
int gWidth, gHeight;
int nbyGlyphWidth;
int nbyPadGlyph;
ChangeGCVal 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,
CREATE_PIXMAP_USAGE_SCRATCH);
if (!pPixmap)
return;
pGCtmp = GetScratchGC(1, pDrawable->pScreen);
if (!pGCtmp)
{
(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
return;
}
gcvals[0].val = GXcopy;
gcvals[1].val = 1;
gcvals[2].val = 0;
ChangeGC(NullClient, pGCtmp, GCFunction|GCForeground|GCBackground, gcvals);
nbyLine = BitmapBytePad(width);
pbits = malloc(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);
(*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable,
gWidth, gHeight,
x + pci->metrics.leftSideBearing,
y - pci->metrics.ascent);
}
x += pci->metrics.characterWidth;
}
(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
free(pbits);
FreeScratchGC(pGCtmp);
}
void
miImageGlyphBlt(
DrawablePtr pDrawable,
GC *pGC,
int x,
int y,
unsigned int nglyph,
CharInfoPtr *ppci,
pointer pglyphBase
)
{
ExtentInfoRec info;
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;
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);
gcvals[0].val = oldFG;
ChangeGC(NullClient, pGC, GCForeground, gcvals);
ValidateGC(pDrawable, pGC);
(*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
pglyphBase);
gcvals[0].val = oldAlu;
gcvals[1].val = oldFG;
gcvals[2].val = oldFS;
ChangeGC(NullClient, pGC, GCFunction|GCForeground|GCFillStyle, gcvals);
ValidateGC(pDrawable, pGC);
}