#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
#include <X11/X.h>
#include <X11/Xmd.h>
#include <X11/Xproto.h>
#include "mfb.h"
#include <X11/fonts/fontstruct.h>
#include "dixfontstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "pixmapstr.h"
#include "scrnintstr.h"
#include "regionstr.h"
#include "maskbits.h"
#include "miscstruct.h"
void
MFBPOLYGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
DrawablePtr pDrawable;
GCPtr pGC;
int x, y;
unsigned int nglyph;
CharInfoPtr *ppci;
pointer pglyphBase;
{
ExtentInfoRec info;
BoxRec bbox;
CharInfoPtr pci;
int xorg, yorg;
int widthDst;
PixelType *pdstBase;
int xchar;
register int xoff;
register PixelType *pdst;
int w;
int h;
int widthGlyph;
register unsigned char *pglyph;
register PixelType tmpSrc;
register PixelType startmask;
register PixelType endmask;
register int nFirst;
if (!(pGC->planemask & 1))
return;
xorg = pDrawable->x;
yorg = pDrawable->y;
mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
x += xorg;
y += yorg;
QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
bbox.x1 = x + info.overallLeft;
bbox.x2 = x + info.overallRight;
bbox.y1 = y - info.overallAscent;
bbox.y2 = y + info.overallDescent;
switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox))
{
case rgnOUT:
break;
case rgnIN:
pdstBase = mfbScanlineNoBankSwitch(pdstBase, x, y, widthDst);
xchar = x & PIM;
while(nglyph--)
{
pci = *ppci;
pglyph = FONTGLYPHBITS(pglyphBase, pci);
w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
h = pci->metrics.ascent + pci->metrics.descent;
widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
pdst = pdstBase;
xoff = xchar + pci->metrics.leftSideBearing;
if (xoff > PLST)
{
pdst++;
xoff &= PIM;
}
else if (xoff < 0)
{
xoff += PPW;
pdst--;
}
pdst = mfbScanlineDelta(pdst, -pci->metrics.ascent, widthDst);
if ((xoff + w) <= PPW)
{
maskpartialbits(xoff, w, startmask);
while (h--)
{
getleftbits(pglyph, w, tmpSrc);
*pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
pglyph += widthGlyph;
mfbScanlineInc(pdst, widthDst);
}
}
else
{
maskPPWbits(xoff, w, startmask, endmask);
nFirst = PPW - xoff;
while (h--)
{
getleftbits(pglyph, w, tmpSrc);
*pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
*(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
pglyph += widthGlyph;
mfbScanlineInc(pdst, widthDst);
}
}
x += pci->metrics.characterWidth;
xchar += pci->metrics.characterWidth;
if (xchar > PLST)
{
xchar -= PPW;
pdstBase++;
}
else if (xchar < 0)
{
xchar += PPW;
pdstBase--;
}
ppci++;
}
break;
case rgnPART:
{
TEXTPOS *ppos;
RegionPtr cclip;
int nbox;
BoxPtr pbox;
int xpos;
int i;
BoxRec clip;
int leftEdge, rightEdge;
int topEdge, bottomEdge;
int glyphRow;
int glyphCol;
#if GETLEFTBITS_ALIGNMENT > 1
int getWidth;
#endif
if(!(ppos = (TEXTPOS *)ALLOCATE_LOCAL(nglyph * sizeof(TEXTPOS))))
return;
pdstBase = mfbScanlineNoBankSwitch(pdstBase, x, y, widthDst);
xpos = x;
xchar = xpos & PIM;
for (i=0; i<nglyph; i++)
{
pci = ppci[i];
ppos[i].xpos = xpos;
ppos[i].xchar = xchar;
ppos[i].leftEdge = xpos + pci->metrics.leftSideBearing;
ppos[i].rightEdge = xpos + pci->metrics.rightSideBearing;
ppos[i].topEdge = y - pci->metrics.ascent;
ppos[i].bottomEdge = y + pci->metrics.descent;
ppos[i].pdstBase = pdstBase;
ppos[i].widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
xpos += pci->metrics.characterWidth;
xchar += pci->metrics.characterWidth;
if (xchar > PLST)
{
xchar &= PIM;
pdstBase++;
}
else if (xchar < 0)
{
xchar += PPW;
pdstBase--;
}
}
cclip = pGC->pCompositeClip;
pbox = REGION_RECTS(cclip);
nbox = REGION_NUM_RECTS(cclip);
for (; --nbox >= 0; pbox++)
{
clip.x1 = max(bbox.x1, pbox->x1);
clip.y1 = max(bbox.y1, pbox->y1);
clip.x2 = min(bbox.x2, pbox->x2);
clip.y2 = min(bbox.y2, pbox->y2);
if ((clip.x2<=clip.x1) || (clip.y2<=clip.y1))
continue;
for(i=0; i<nglyph; i++)
{
pci = ppci[i];
xchar = ppos[i].xchar;
if (ppos[i].leftEdge < clip.x1)
leftEdge = clip.x1;
else
leftEdge = ppos[i].leftEdge;
if (ppos[i].rightEdge > clip.x2)
rightEdge = clip.x2;
else
rightEdge = ppos[i].rightEdge;
w = rightEdge - leftEdge;
if (w <= 0)
continue;
if (ppos[i].topEdge < clip.y1)
topEdge = clip.y1;
else
topEdge = ppos[i].topEdge;
if (ppos[i].bottomEdge > clip.y2)
bottomEdge = clip.y2;
else
bottomEdge = ppos[i].bottomEdge;
h = bottomEdge - topEdge;
if (h <= 0)
continue;
glyphRow = (topEdge - y) + pci->metrics.ascent;
widthGlyph = ppos[i].widthGlyph;
pglyph = FONTGLYPHBITS(pglyphBase, pci);
pglyph += (glyphRow * widthGlyph);
pdst = ppos[i].pdstBase;
glyphCol = (leftEdge - ppos[i].xpos) -
(pci->metrics.leftSideBearing);
#if GETLEFTBITS_ALIGNMENT > 1
getWidth = w + glyphCol;
#endif
xoff = xchar + (leftEdge - ppos[i].xpos);
if (xoff > PLST)
{
xoff &= PIM;
pdst++;
}
else if (xoff < 0)
{
xoff += PPW;
pdst--;
}
pdst = mfbScanlineDelta(pdst, -(y-topEdge), widthDst);
if ((xoff + w) <= PPW)
{
maskpartialbits(xoff, w, startmask);
while (h--)
{
getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
*pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
pglyph += widthGlyph;
mfbScanlineInc(pdst, widthDst);
}
}
else
{
maskPPWbits(xoff, w, startmask, endmask);
nFirst = PPW - xoff;
while (h--)
{
getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
*pdst OPEQ (SCRRIGHT(tmpSrc, xoff) & startmask);
*(pdst+1) OPEQ (SCRLEFT(tmpSrc, nFirst) & endmask);
pglyph += widthGlyph;
mfbScanlineInc(pdst, widthDst);
}
}
}
}
DEALLOCATE_LOCAL(ppos);
break;
}
default:
break;
}
}