#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 "scrnintstr.h"
#include "pixmapstr.h"
#include "regionstr.h"
#include "maskbits.h"
#if defined(NO_3_60_CG4) && defined(FASTPUTBITS) && defined(FASTGETBITS)
#define FASTCHARS
#endif
#if (BITMAP_BIT_ORDER == MSBFirst) && (GLYPHPADBYTES != 4)
#if GLYPHPADBYTES == 1
#define ShiftAmnt 24
#else
#define ShiftAmnt 16
#endif
#if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
#define GetBits4 c = (*char1++ << ShiftAmnt) | \
SCRRIGHT (*char2++ << ShiftAmnt, xoff2) | \
SCRRIGHT (*char3++ << ShiftAmnt, xoff3) | \
SCRRIGHT (*char4++ << ShiftAmnt, xoff4);
#else
#define GetBits4 c = (*char1++ << ShiftAmnt) | \
SCRRIGHT (*char2 << ShiftAmnt, xoff2) | \
SCRRIGHT (*char3 << ShiftAmnt, xoff3) | \
SCRRIGHT (*char4 << ShiftAmnt, xoff4); \
char2++; char3++; char4++;
#endif
#else
#if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
#define GetBits4 c = *char1++ | \
SCRRIGHT (*char2++, xoff2) | \
SCRRIGHT (*char3++, xoff3) | \
SCRRIGHT (*char4++, xoff4);
#else
#define GetBits4 c = *char1++ | \
SCRRIGHT (*char2, xoff2) | \
SCRRIGHT (*char3, xoff3) | \
SCRRIGHT (*char4, xoff4); \
char2++; char3++; char4++;
#endif
#endif
#if GLYPHPADBYTES == 1
typedef unsigned char *glyphPointer;
#define USE_LEFTBITS
#endif
#if GLYPHPADBYTES == 2
typedef unsigned short *glyphPointer;
#define USE_LEFTBITS
#endif
#if GLYPHPADBYTES == 4
typedef unsigned int *glyphPointer;
#endif
#ifdef USE_LEFTBITS
#define GetBits1 getleftbits (char1, widthGlyph, c); \
c &= glyphMask; \
char1 = (glyphPointer) (((char *) char1) + glyphBytes);
#else
#define GetBits1 c = *char1++;
#endif
void
MFBTEGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
DrawablePtr pDrawable;
GC *pGC;
int x, y;
unsigned int nglyph;
CharInfoPtr *ppci;
pointer pglyphBase;
{
FontPtr pfont = pGC->font;
int widthDst;
PixelType *pdstBase;
int h;
register int xpos;
int ypos;
int widthGlyph;
int hTmp;
register PixelType startmask, endmask;
int nfirst;
BoxRec bbox;
int widthGlyphs;
register PixelType *dst;
register PixelType c;
register int xoff1, xoff2, xoff3, xoff4;
register glyphPointer char1, char2, char3, char4;
#ifdef USE_LEFTBITS
register PixelType glyphMask;
register PixelType tmpSrc;
register int glyphBytes;
#endif
if (!(pGC->planemask & 1))
return;
mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
xpos = x + pDrawable->x;
ypos = y + pDrawable->y;
widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
h = FONTASCENT(pfont) + FONTDESCENT(pfont);
xpos += FONTMAXBOUNDS(pfont,leftSideBearing);
ypos -= FONTASCENT(pfont);
bbox.x1 = xpos;
bbox.x2 = xpos + (widthGlyph * nglyph);
bbox.y1 = ypos;
bbox.y2 = ypos + h;
switch (RECT_IN_REGION(pGC->pScreen, pGC->pCompositeClip, &bbox))
{
case rgnPART:
CLIPTETEXT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
case rgnOUT:
return;
}
pdstBase = mfbScanlineDeltaNoBankSwitch(pdstBase, ypos, widthDst);
widthGlyphs = widthGlyph * PGSZB;
#ifdef USE_LEFTBITS
glyphMask = endtab[widthGlyph];
glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci);
#endif
if (nglyph >= PGSZB && widthGlyphs <= PPW)
{
while (nglyph >= PGSZB)
{
nglyph -= PGSZB;
xoff1 = xpos & PIM;
xoff2 = widthGlyph;
xoff3 = xoff2 + widthGlyph;
xoff4 = xoff3 + widthGlyph;
char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
char2 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
char3 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
char4 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
hTmp = h;
dst = mfbScanlineOffset(pdstBase, (xpos >> PWSH));
#ifndef FASTCHARS
if (xoff1 + widthGlyphs <= PPW)
{
maskpartialbits (xoff1, widthGlyphs, startmask);
#endif
while (hTmp--)
{
GetBits4
#ifdef FASTCHARS
# if BITMAP_BIT_ORDER == MSBFirst
c >>= PPW - widthGlyphs;
# endif
FASTPUTBITS(OP(c), xoff1, widthGlyphs, dst);
#else
*(dst) = ((*dst) & ~startmask) | (OP(SCRRIGHT(c, xoff1)) & startmask);
#endif
mfbScanlineInc(dst, widthDst);
}
#ifndef FASTCHARS
}
else
{
maskPPWbits (xoff1, widthGlyphs, startmask, endmask);
nfirst = PPW - xoff1;
while (hTmp--)
{
GetBits4
dst[0] = (dst[0] & ~startmask) |
(OP(SCRRIGHT(c,xoff1)) & startmask);
dst[1] = (dst[1] & ~endmask) |
(OP(SCRLEFT(c,nfirst)) & endmask);
mfbScanlineInc(dst, widthDst);
}
}
#endif
xpos += widthGlyphs;
}
}
while(nglyph--)
{
xoff1 = xpos & PIM;
char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
hTmp = h;
dst = mfbScanlineOffset(pdstBase, (xpos >> PWSH));
#ifndef FASTCHARS
if (xoff1 + widthGlyph <= PPW)
{
maskpartialbits (xoff1, widthGlyph, startmask);
#endif
while (hTmp--)
{
#ifdef FASTCHARS
#ifdef USE_LEFTBITS
FASTGETBITS (char1,0,widthGlyph,c);
char1 = (glyphPointer) (((char *) char1) + glyphBytes);
#else
c = *char1++;
#if BITMAP_BIT_ORDER == MSBFirst
c >>= PPW - widthGlyph;
#endif
#endif
FASTPUTBITS (OP(c),xoff1,widthGlyph,dst);
#else
GetBits1
(*dst) = ((*dst) & ~startmask) | (OP(SCRRIGHT(c, xoff1)) & startmask);
#endif
mfbScanlineInc(dst, widthDst);
}
#ifndef FASTCHARS
}
else
{
maskPPWbits (xoff1, widthGlyph, startmask, endmask);
nfirst = PPW - xoff1;
while (hTmp--)
{
GetBits1
dst[0] = (dst[0] & ~startmask) |
(OP(SCRRIGHT(c,xoff1)) & startmask);
dst[1] = (dst[1] & ~endmask) |
(OP(SCRLEFT(c,nfirst)) & endmask);
mfbScanlineInc(dst, widthDst);
}
}
#endif
xpos += widthGlyph;
}
}