#include "X.h"
#include "Xmd.h"
#include "Xproto.h"
#include "ilbm.h"
#include "fontstruct.h"
#include "dixfontstr.h"
#include "gcstruct.h"
#include "windowstr.h"
#include "scrnintstr.h"
#include "pixmapstr.h"
#include "regionstr.h"
#include "maskbits.h"
void
ilbmImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
DrawablePtr pDrawable;
GC *pGC;
int x, y;
unsigned int nglyph;
CharInfoPtr *ppci;
pointer pglyphBase;
{
ExtentInfoRec info;
BoxRec bbox;
xRectangle backrect;
CharInfoPtr pci;
int xorg, yorg;
int widthDst;
PixelType *pdstBase;
int xchar;
register int xoff;
register PixelType *pdst;
register int d;
int depthDst;
int auxDst;
int hSave;
int w;
int h;
int widthGlyph;
unsigned char rrops[AFB_MAX_DEPTH];
register unsigned char *pglyph;
unsigned char *pglyphSave;
register PixelType tmpSrc;
register PixelType startmask;
register PixelType endmask;
register int nFirst;
PixelType *pdstSave;
int oldFill;
ilbmPrivGC *pPriv = (ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr);
xorg = pDrawable->x;
yorg = pDrawable->y;
ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, widthDst, auxDst, depthDst,
pdstBase);
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);
x += xorg;
y += yorg;
bbox.x1 = x + info.overallLeft;
bbox.x2 = x + info.overallRight;
bbox.y1 = y - info.overallAscent;
bbox.y2 = y + info.overallDescent;
oldFill = pGC->fillStyle;
pGC->fillStyle = FillSolid;
ilbmReduceRop (pGC->alu, pGC->bgPixel, pGC->planemask, pGC->depth,
pPriv->rrops);
ilbmPolyFillRect(pDrawable, pGC, 1, &backrect);
pGC->fillStyle = oldFill;
ilbmReduceRop (pGC->alu, pGC->fgPixel, pGC->planemask, pGC->depth,
pPriv->rrops);
ilbmReduceRop (GXcopy, pGC->fgPixel, pGC->planemask, pGC->depth, rrops);
switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox)) {
case rgnOUT:
break;
case rgnIN:
pdstBase = ilbmScanlineNoBankSwitch(pdstBase, x, y, auxDst);
xchar = x & PIM;
while (nglyph--) {
pci = *ppci;
pglyphSave = FONTGLYPHBITS(pglyphBase, pci);
w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
hSave = pci->metrics.ascent + pci->metrics.descent;
widthGlyph = GLYPHWIDTHBYTESPADDED(pci);
pdstSave = ilbmScanlineDelta(pdstBase, -pci->metrics.ascent,
auxDst);
xoff = xchar + pci->metrics.leftSideBearing;
if (xoff > PLST) {
pdstSave++;
xoff &= PIM;
} else if (xoff < 0) {
xoff += PPW;
pdstSave--;
}
for (d = 0; d < depthDst; d++) {
h = hSave;
pdst = pdstSave;
pdstSave += widthDst;
pglyph = pglyphSave;
if ((xoff + w) <= PPW) {
maskpartialbits(xoff, w, startmask);
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
getleftbits(pglyph, w, tmpSrc);
*pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
pglyph += widthGlyph;
ilbmScanlineInc(pdst, auxDst);
}
break;
case RROP_WHITE:
while (h--) {
getleftbits(pglyph, w, tmpSrc);
*pdst |= SCRRIGHT(tmpSrc, xoff) & startmask;
pglyph += widthGlyph;
ilbmScanlineInc(pdst, auxDst);
}
break;
case RROP_NOP:
break;
}
} else {
maskPPWbits(xoff, w, startmask, endmask);
nFirst = PPW - xoff;
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
getleftbits(pglyph, w, tmpSrc);
*pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
*(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask);
pglyph += widthGlyph;
ilbmScanlineInc(pdst, auxDst);
}
break;
case RROP_WHITE:
while (h--) {
getleftbits(pglyph, w, tmpSrc);
*pdst |= SCRRIGHT(tmpSrc, xoff) & startmask;
*(pdst+1) |= SCRLEFT(tmpSrc, nFirst) & endmask;
pglyph += widthGlyph;
ilbmScanlineInc(pdst, auxDst);
}
break;
case RROP_NOP:
break;
}
}
}
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:
{
ilbmTEXTPOS *ppos;
int nbox;
BoxPtr pbox;
RegionPtr cclip;
int xpos;
int i;
BoxRec clip;
int leftEdge, rightEdge;
int topEdge, bottomEdge;
int glyphRow;
int glyphCol;
int getWidth;
if (!(ppos = (ilbmTEXTPOS *)ALLOCATE_LOCAL(nglyph *
sizeof(ilbmTEXTPOS))))
return;
pdstBase = ilbmScanlineNoBankSwitch(pdstBase, x, y, auxDst);
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);
pbox--;
while (nbox--) {
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;
hSave = bottomEdge - topEdge;
if (hSave <= 0)
continue;
glyphRow = (topEdge - y) + pci->metrics.ascent;
widthGlyph = ppos[i].widthGlyph;
pglyphSave = FONTGLYPHBITS(pglyphBase, pci);
pglyphSave += (glyphRow * widthGlyph);
glyphCol = (leftEdge - ppos[i].xpos) -
(pci->metrics.leftSideBearing);
getWidth = w + glyphCol;
pdstSave = ilbmScanlineDelta(ppos[i].pdstBase, -(y-topEdge),
auxDst);
xoff = xchar + (leftEdge - ppos[i].xpos);
if (xoff > PLST) {
xoff &= PIM;
pdstSave++;
} else if (xoff < 0) {
xoff += PPW;
pdstSave--;
}
for (d = 0; d < depthDst; d++) {
h = hSave;
pdst = pdstSave;
pdstSave += widthDst;
pglyph = pglyphSave;
if ((xoff + w) <= PPW) {
maskpartialbits(xoff, w, startmask);
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
*pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
pglyph += widthGlyph;
ilbmScanlineInc(pdst, auxDst);
}
break;
case RROP_WHITE:
while (h--) {
getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
*pdst |= SCRRIGHT(tmpSrc, xoff) & startmask;
pglyph += widthGlyph;
ilbmScanlineInc(pdst, auxDst);
}
break;
case RROP_NOP:
break;
}
} else {
maskPPWbits(xoff, w, startmask, endmask);
nFirst = PPW - xoff;
switch (rrops[d]) {
case RROP_BLACK:
while (h--) {
getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
*pdst &= ~(SCRRIGHT(tmpSrc, xoff) & startmask);
*(pdst+1) &= ~(SCRLEFT(tmpSrc, nFirst) & endmask);
pglyph += widthGlyph;
ilbmScanlineInc(pdst, auxDst);
}
break;
case RROP_WHITE:
while (h--) {
getshiftedleftbits(pglyph, glyphCol, getWidth, tmpSrc);
*pdst |= SCRRIGHT(tmpSrc, xoff) & startmask;
*(pdst+1) |= SCRLEFT(tmpSrc, nFirst) & endmask;
pglyph += widthGlyph;
ilbmScanlineInc(pdst, auxDst);
}
break;
case RROP_NOP:
break;
}
}
}
}
}
DEALLOCATE_LOCAL(ppos);
break;
}
default:
break;
}
}