From 5d8e1ad0cd01de0bd0b43dc916c1d39fd293e79d Mon Sep 17 00:00:00 2001 From: marha Date: Fri, 1 Apr 2011 07:17:02 +0000 Subject: libXext xserver libXmu libX11 libXdmcp xextproto libxtrans mesa git update 1 Apr 2011 --- xorg-server/fb/fbglyph.c | 940 +++++++++++++++++++++++------------------------ 1 file changed, 461 insertions(+), 479 deletions(-) (limited to 'xorg-server/fb/fbglyph.c') diff --git a/xorg-server/fb/fbglyph.c b/xorg-server/fb/fbglyph.c index 51a5ea0a4..643cf909f 100644 --- a/xorg-server/fb/fbglyph.c +++ b/xorg-server/fb/fbglyph.c @@ -1,479 +1,461 @@ -/* - * - * Copyright © 1998 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "fb.h" -#include -#include "dixfontstr.h" - -Bool -fbGlyphIn (RegionPtr pRegion, - int x, - int y, - int width, - int height) -{ - BoxRec box; - BoxPtr pExtents = RegionExtents(pRegion); - - /* - * Check extents by hand to avoid 16 bit overflows - */ - if (x < (int) pExtents->x1) - return FALSE; - if ((int) pExtents->x2 < x + width) - return FALSE; - if (y < (int) pExtents->y1) - return FALSE; - if ((int) pExtents->y2 < y + height) - return FALSE; - box.x1 = x; - box.x2 = x + width; - box.y1 = y; - box.y2 = y + height; - return RegionContainsRect(pRegion, &box) == rgnIN; -} - -#ifdef FB_24BIT -#ifndef FBNOPIXADDR - -#define WRITE1(d,n,fg) WRITE((d) + (n), (CARD8) fg) -#define WRITE2(d,n,fg) WRITE((CARD16 *) &(d[n]), (CARD16) fg) -#define WRITE4(d,n,fg) WRITE((CARD32 *) &(d[n]), (CARD32) fg) -#if FB_UNIT == 6 && IMAGE_BYTE_ORDER == LSBFirst -#define WRITE8(d) WRITE((FbBits *) &(d[0]), fg) -#else -#define WRITE8(d) WRITE4(d,0,_ABCA), WRITE4(d,4,_BCAB) -#endif - -/* - * This is a bit tricky, but it's brief. Write 12 bytes worth - * of dest, which is four pixels, at a time. This gives constant - * code for each pattern as they're always aligned the same - * - * a b c d a b c d a b c d bytes - * A B C A B C A B C A B C pixels - * - * f0 f1 f2 - * A B C A B C A B C A B C pixels LSB - * C A B C A B C A B C A B pixels MSB - * - * LSB MSB - * A f0 f1 - * B f1 f2 - * C f2 f0 - * A B f0 f2 - * B C f1 f0 - * C A f2 f1 - * A B C A f0 f1 - * B C A B f1 f2 - * C A B C f2 f0 - */ - -#undef _A -#undef _B -#undef _C -#undef _AB -#undef _BC -#undef _CA -#undef _ABCA -#undef _BCAB -#undef _CABC - -#if IMAGE_BYTE_ORDER == MSBFirst -#define _A f1 -#define _B f2 -#define _C f0 -#define _AB f2 -#define _BC f0 -#define _CA f1 -#define _ABCA f1 -#define _BCAB f2 -#define _CABC f0 -#define CASE(a,b,c,d) ((a << 3) | (b << 2) | (c << 1) | d) -#else -#define _A f0 -#define _B f1 -#define _C f2 -#define _AB f0 -#define _BC f1 -#define _CA f2 -#define _ABCA f0 -#define _BCAB f1 -#define _CABC f2 -#define CASE(a,b,c,d) (a | (b << 1) | (c << 2) | (d << 3)) -#endif - -void -fbGlyph24 (FbBits *dstBits, - FbStride dstStride, - int dstBpp, - FbStip *stipple, - FbBits fg, - int x, - int height) -{ - int lshift; - FbStip bits; - CARD8 *dstLine; - CARD8 *dst; - FbStip f0, f1, f2; - int n; - int shift; - - f0 = fg; - f1 = FbRot24(f0,16); - f2 = FbRot24(f0,8); - - dstLine = (CARD8 *) dstBits; - dstLine += (x & ~3) * 3; - dstStride *= (sizeof (FbBits) / sizeof (CARD8)); - shift = x & 3; - lshift = 4 - shift; - while (height--) - { - bits = READ(stipple++); - n = lshift; - dst = dstLine; - while (bits) - { - switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) { - case CASE(0,0,0,0): - break; - case CASE(1,0,0,0): - WRITE2(dst,0,_AB); - WRITE1(dst,2,_C); - break; - case CASE(0,1,0,0): - WRITE1(dst,3,_A); - WRITE2(dst,4,_BC); - break; - case CASE(1,1,0,0): - WRITE4(dst,0,_ABCA); - WRITE2(dst,4,_BC); - break; - case CASE(0,0,1,0): - WRITE2(dst,6,_AB); - WRITE1(dst,8,_C); - break; - case CASE(1,0,1,0): - WRITE2(dst,0,_AB); - WRITE1(dst,2,_C); - - WRITE2(dst,6,_AB); - WRITE1(dst,8,_C); - break; - case CASE(0,1,1,0): - WRITE1(dst,3,_A); - WRITE4(dst,4,_BCAB); - WRITE1(dst,8,_C); - break; - case CASE(1,1,1,0): - WRITE8(dst); - WRITE1(dst,8,_C); - break; - case CASE(0,0,0,1): - WRITE1(dst,9,_A); - WRITE2(dst,10,_BC); - break; - case CASE(1,0,0,1): - WRITE2(dst,0,_AB); - WRITE1(dst,2,_C); - - WRITE1(dst,9,_A); - WRITE2(dst,10,_BC); - break; - case CASE(0,1,0,1): - WRITE1(dst,3,_A); - WRITE2(dst,4,_BC); - - WRITE1(dst,9,_A); - WRITE2(dst,10,_BC); - break; - case CASE(1,1,0,1): - WRITE4(dst,0,_ABCA); - WRITE2(dst,4,_BC); - - WRITE1(dst,9,_A); - WRITE2(dst,10,_BC); - break; - case CASE(0,0,1,1): - WRITE2(dst,6,_AB); - WRITE4(dst,8,_CABC); - break; - case CASE(1,0,1,1): - WRITE2(dst,0,_AB); - WRITE1(dst,2,_C); - - WRITE2(dst,6,_AB); - WRITE4(dst,8,_CABC); - break; - case CASE(0,1,1,1): - WRITE1(dst,3,_A); - WRITE4(dst,4,_BCAB); - WRITE4(dst,8,_CABC); - break; - case CASE(1,1,1,1): - WRITE8(dst); - WRITE4(dst,8,_CABC); - break; - } - bits = FbStipLeft (bits, n); - n = 4; - dst += 12; - } - dstLine += dstStride; - } -} -#endif -#endif - -void -fbPolyGlyphBlt (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase) -{ - FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); - CharInfoPtr pci; - unsigned char *pglyph; /* pointer bits in glyph */ - int gx, gy; - int gWidth, gHeight; /* width and height of glyph */ - FbStride gStride; /* stride of glyph */ -#ifndef FBNOPIXADDR - void (*glyph) (FbBits *, - FbStride, - int, - FbStip *, - FbBits, - int, - int); - FbBits *dst = 0; - FbStride dstStride = 0; - int dstBpp = 0; - int dstXoff = 0, dstYoff = 0; - - glyph = 0; - if (pGC->fillStyle == FillSolid && pPriv->and == 0) - { - dstBpp = pDrawable->bitsPerPixel; - switch (dstBpp) { - case 8: glyph = fbGlyph8; break; - case 16: glyph = fbGlyph16; break; -#ifdef FB_24BIT - case 24: glyph = fbGlyph24; break; -#endif - case 32: glyph = fbGlyph32; break; - } - } -#endif - x += pDrawable->x; - y += pDrawable->y; - - while (nglyph--) - { - pci = *ppci++; - pglyph = FONTGLYPHBITS(pglyphBase, pci); - gWidth = GLYPHWIDTHPIXELS(pci); - gHeight = GLYPHHEIGHTPIXELS(pci); - if (gWidth && gHeight) - { - gx = x + pci->metrics.leftSideBearing; - gy = y - pci->metrics.ascent; -#ifndef FBNOPIXADDR - if (glyph && gWidth <= sizeof (FbStip) * 8 && - fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) - { - fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); - (*glyph) (dst + (gy + dstYoff) * dstStride, - dstStride, - dstBpp, - (FbStip *) pglyph, - pPriv->xor, - gx + dstXoff, - gHeight); - fbFinishAccess (pDrawable); - } - else -#endif - { - gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); - fbPushImage (pDrawable, - pGC, - - (FbStip *) pglyph, - gStride, - 0, - - gx, - gy, - gWidth, gHeight); - } - } - x += pci->metrics.characterWidth; - } -} - - -void -fbImageGlyphBlt (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppciInit, - pointer pglyphBase) -{ - FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); - CharInfoPtr *ppci; - CharInfoPtr pci; - unsigned char *pglyph; /* pointer bits in glyph */ - int gWidth, gHeight; /* width and height of glyph */ - FbStride gStride; /* stride of glyph */ - Bool opaque; - int n; - int gx, gy; -#ifndef FBNOPIXADDR - void (*glyph) (FbBits *, - FbStride, - int, - FbStip *, - FbBits, - int, - int); - FbBits *dst = 0; - FbStride dstStride = 0; - int dstBpp = 0; - int dstXoff = 0, dstYoff = 0; - - glyph = 0; - if (pPriv->and == 0) - { - dstBpp = pDrawable->bitsPerPixel; - switch (dstBpp) { - case 8: glyph = fbGlyph8; break; - case 16: glyph = fbGlyph16; break; -#ifdef FB_24BIT - case 24: glyph = fbGlyph24; break; -#endif - case 32: glyph = fbGlyph32; break; - } - } -#endif - - x += pDrawable->x; - y += pDrawable->y; - - if (TERMINALFONT (pGC->font) -#ifndef FBNOPIXADDR - && !glyph -#endif - ) - { - opaque = TRUE; - } - else - { - int xBack, widthBack; - int yBack, heightBack; - - ppci = ppciInit; - n = nglyph; - widthBack = 0; - while (n--) - widthBack += (*ppci++)->metrics.characterWidth; - - xBack = x; - if (widthBack < 0) - { - xBack += widthBack; - widthBack = -widthBack; - } - yBack = y - FONTASCENT(pGC->font); - heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); - fbSolidBoxClipped (pDrawable, - fbGetCompositeClip(pGC), - xBack, - yBack, - xBack + widthBack, - yBack + heightBack, - fbAnd(GXcopy,pPriv->bg,pPriv->pm), - fbXor(GXcopy,pPriv->bg,pPriv->pm)); - opaque = FALSE; - } - - ppci = ppciInit; - while (nglyph--) - { - pci = *ppci++; - pglyph = FONTGLYPHBITS(pglyphBase, pci); - gWidth = GLYPHWIDTHPIXELS(pci); - gHeight = GLYPHHEIGHTPIXELS(pci); - if (gWidth && gHeight) - { - gx = x + pci->metrics.leftSideBearing; - gy = y - pci->metrics.ascent; -#ifndef FBNOPIXADDR - if (glyph && gWidth <= sizeof (FbStip) * 8 && - fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) - { - fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); - (*glyph) (dst + (gy + dstYoff) * dstStride, - dstStride, - dstBpp, - (FbStip *) pglyph, - pPriv->fg, - gx + dstXoff, - gHeight); - fbFinishAccess (pDrawable); - } - else -#endif - { - gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); - fbPutXYImage (pDrawable, - fbGetCompositeClip(pGC), - pPriv->fg, - pPriv->bg, - pPriv->pm, - GXcopy, - opaque, - - gx, - gy, - gWidth, gHeight, - - (FbStip *) pglyph, - gStride, - 0); - } - } - x += pci->metrics.characterWidth; - } -} +/* + * + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "fb.h" +#include +#include "dixfontstr.h" + +Bool +fbGlyphIn (RegionPtr pRegion, + int x, + int y, + int width, + int height) +{ + BoxRec box; + BoxPtr pExtents = RegionExtents(pRegion); + + /* + * Check extents by hand to avoid 16 bit overflows + */ + if (x < (int) pExtents->x1) + return FALSE; + if ((int) pExtents->x2 < x + width) + return FALSE; + if (y < (int) pExtents->y1) + return FALSE; + if ((int) pExtents->y2 < y + height) + return FALSE; + box.x1 = x; + box.x2 = x + width; + box.y1 = y; + box.y2 = y + height; + return RegionContainsRect(pRegion, &box) == rgnIN; +} + + +#define WRITE1(d,n,fg) WRITE((d) + (n), (CARD8) fg) +#define WRITE2(d,n,fg) WRITE((CARD16 *) &(d[n]), (CARD16) fg) +#define WRITE4(d,n,fg) WRITE((CARD32 *) &(d[n]), (CARD32) fg) +#if FB_UNIT == 6 && IMAGE_BYTE_ORDER == LSBFirst +#define WRITE8(d) WRITE((FbBits *) &(d[0]), fg) +#else +#define WRITE8(d) WRITE4(d,0,_ABCA), WRITE4(d,4,_BCAB) +#endif + +/* + * This is a bit tricky, but it's brief. Write 12 bytes worth + * of dest, which is four pixels, at a time. This gives constant + * code for each pattern as they're always aligned the same + * + * a b c d a b c d a b c d bytes + * A B C A B C A B C A B C pixels + * + * f0 f1 f2 + * A B C A B C A B C A B C pixels LSB + * C A B C A B C A B C A B pixels MSB + * + * LSB MSB + * A f0 f1 + * B f1 f2 + * C f2 f0 + * A B f0 f2 + * B C f1 f0 + * C A f2 f1 + * A B C A f0 f1 + * B C A B f1 f2 + * C A B C f2 f0 + */ + +#undef _A +#undef _B +#undef _C +#undef _AB +#undef _BC +#undef _CA +#undef _ABCA +#undef _BCAB +#undef _CABC + +#if IMAGE_BYTE_ORDER == MSBFirst +#define _A f1 +#define _B f2 +#define _C f0 +#define _AB f2 +#define _BC f0 +#define _CA f1 +#define _ABCA f1 +#define _BCAB f2 +#define _CABC f0 +#define CASE(a,b,c,d) ((a << 3) | (b << 2) | (c << 1) | d) +#else +#define _A f0 +#define _B f1 +#define _C f2 +#define _AB f0 +#define _BC f1 +#define _CA f2 +#define _ABCA f0 +#define _BCAB f1 +#define _CABC f2 +#define CASE(a,b,c,d) (a | (b << 1) | (c << 2) | (d << 3)) +#endif + +void +fbGlyph24 (FbBits *dstBits, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int x, + int height) +{ + int lshift; + FbStip bits; + CARD8 *dstLine; + CARD8 *dst; + FbStip f0, f1, f2; + int n; + int shift; + + f0 = fg; + f1 = FbRot24(f0,16); + f2 = FbRot24(f0,8); + + dstLine = (CARD8 *) dstBits; + dstLine += (x & ~3) * 3; + dstStride *= (sizeof (FbBits) / sizeof (CARD8)); + shift = x & 3; + lshift = 4 - shift; + while (height--) + { + bits = READ(stipple++); + n = lshift; + dst = dstLine; + while (bits) + { + switch (FbStipMoveLsb (FbLeftStipBits (bits, n), 4, n)) { + case CASE(0,0,0,0): + break; + case CASE(1,0,0,0): + WRITE2(dst,0,_AB); + WRITE1(dst,2,_C); + break; + case CASE(0,1,0,0): + WRITE1(dst,3,_A); + WRITE2(dst,4,_BC); + break; + case CASE(1,1,0,0): + WRITE4(dst,0,_ABCA); + WRITE2(dst,4,_BC); + break; + case CASE(0,0,1,0): + WRITE2(dst,6,_AB); + WRITE1(dst,8,_C); + break; + case CASE(1,0,1,0): + WRITE2(dst,0,_AB); + WRITE1(dst,2,_C); + + WRITE2(dst,6,_AB); + WRITE1(dst,8,_C); + break; + case CASE(0,1,1,0): + WRITE1(dst,3,_A); + WRITE4(dst,4,_BCAB); + WRITE1(dst,8,_C); + break; + case CASE(1,1,1,0): + WRITE8(dst); + WRITE1(dst,8,_C); + break; + case CASE(0,0,0,1): + WRITE1(dst,9,_A); + WRITE2(dst,10,_BC); + break; + case CASE(1,0,0,1): + WRITE2(dst,0,_AB); + WRITE1(dst,2,_C); + + WRITE1(dst,9,_A); + WRITE2(dst,10,_BC); + break; + case CASE(0,1,0,1): + WRITE1(dst,3,_A); + WRITE2(dst,4,_BC); + + WRITE1(dst,9,_A); + WRITE2(dst,10,_BC); + break; + case CASE(1,1,0,1): + WRITE4(dst,0,_ABCA); + WRITE2(dst,4,_BC); + + WRITE1(dst,9,_A); + WRITE2(dst,10,_BC); + break; + case CASE(0,0,1,1): + WRITE2(dst,6,_AB); + WRITE4(dst,8,_CABC); + break; + case CASE(1,0,1,1): + WRITE2(dst,0,_AB); + WRITE1(dst,2,_C); + + WRITE2(dst,6,_AB); + WRITE4(dst,8,_CABC); + break; + case CASE(0,1,1,1): + WRITE1(dst,3,_A); + WRITE4(dst,4,_BCAB); + WRITE4(dst,8,_CABC); + break; + case CASE(1,1,1,1): + WRITE8(dst); + WRITE4(dst,8,_CABC); + break; + } + bits = FbStipLeft (bits, n); + n = 4; + dst += 12; + } + dstLine += dstStride; + } +} + +void +fbPolyGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + pointer pglyphBase) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + CharInfoPtr pci; + unsigned char *pglyph; /* pointer bits in glyph */ + int gx, gy; + int gWidth, gHeight; /* width and height of glyph */ + FbStride gStride; /* stride of glyph */ + void (*glyph) (FbBits *, + FbStride, + int, + FbStip *, + FbBits, + int, + int); + FbBits *dst = 0; + FbStride dstStride = 0; + int dstBpp = 0; + int dstXoff = 0, dstYoff = 0; + + glyph = 0; + if (pGC->fillStyle == FillSolid && pPriv->and == 0) + { + dstBpp = pDrawable->bitsPerPixel; + switch (dstBpp) { + case 8: glyph = fbGlyph8; break; + case 16: glyph = fbGlyph16; break; + case 24: glyph = fbGlyph24; break; + case 32: glyph = fbGlyph32; break; + } + } + x += pDrawable->x; + y += pDrawable->y; + + while (nglyph--) + { + pci = *ppci++; + pglyph = FONTGLYPHBITS(pglyphBase, pci); + gWidth = GLYPHWIDTHPIXELS(pci); + gHeight = GLYPHHEIGHTPIXELS(pci); + if (gWidth && gHeight) + { + gx = x + pci->metrics.leftSideBearing; + gy = y - pci->metrics.ascent; + if (glyph && gWidth <= sizeof (FbStip) * 8 && + fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) + { + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + (*glyph) (dst + (gy + dstYoff) * dstStride, + dstStride, + dstBpp, + (FbStip *) pglyph, + pPriv->xor, + gx + dstXoff, + gHeight); + fbFinishAccess (pDrawable); + } + else + { + gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); + fbPushImage (pDrawable, + pGC, + + (FbStip *) pglyph, + gStride, + 0, + + gx, + gy, + gWidth, gHeight); + } + } + x += pci->metrics.characterWidth; + } +} + + +void +fbImageGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppciInit, + pointer pglyphBase) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + CharInfoPtr *ppci; + CharInfoPtr pci; + unsigned char *pglyph; /* pointer bits in glyph */ + int gWidth, gHeight; /* width and height of glyph */ + FbStride gStride; /* stride of glyph */ + Bool opaque; + int n; + int gx, gy; + void (*glyph) (FbBits *, + FbStride, + int, + FbStip *, + FbBits, + int, + int); + FbBits *dst = 0; + FbStride dstStride = 0; + int dstBpp = 0; + int dstXoff = 0, dstYoff = 0; + + glyph = 0; + if (pPriv->and == 0) + { + dstBpp = pDrawable->bitsPerPixel; + switch (dstBpp) { + case 8: glyph = fbGlyph8; break; + case 16: glyph = fbGlyph16; break; + case 24: glyph = fbGlyph24; break; + case 32: glyph = fbGlyph32; break; + } + } + + x += pDrawable->x; + y += pDrawable->y; + + if (TERMINALFONT (pGC->font) + && !glyph + ) + { + opaque = TRUE; + } + else + { + int xBack, widthBack; + int yBack, heightBack; + + ppci = ppciInit; + n = nglyph; + widthBack = 0; + while (n--) + widthBack += (*ppci++)->metrics.characterWidth; + + xBack = x; + if (widthBack < 0) + { + xBack += widthBack; + widthBack = -widthBack; + } + yBack = y - FONTASCENT(pGC->font); + heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); + fbSolidBoxClipped (pDrawable, + fbGetCompositeClip(pGC), + xBack, + yBack, + xBack + widthBack, + yBack + heightBack, + fbAnd(GXcopy,pPriv->bg,pPriv->pm), + fbXor(GXcopy,pPriv->bg,pPriv->pm)); + opaque = FALSE; + } + + ppci = ppciInit; + while (nglyph--) + { + pci = *ppci++; + pglyph = FONTGLYPHBITS(pglyphBase, pci); + gWidth = GLYPHWIDTHPIXELS(pci); + gHeight = GLYPHHEIGHTPIXELS(pci); + if (gWidth && gHeight) + { + gx = x + pci->metrics.leftSideBearing; + gy = y - pci->metrics.ascent; + if (glyph && gWidth <= sizeof (FbStip) * 8 && + fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight)) + { + fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff); + (*glyph) (dst + (gy + dstYoff) * dstStride, + dstStride, + dstBpp, + (FbStip *) pglyph, + pPriv->fg, + gx + dstXoff, + gHeight); + fbFinishAccess (pDrawable); + } + else + { + gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip); + fbPutXYImage (pDrawable, + fbGetCompositeClip(pGC), + pPriv->fg, + pPriv->bg, + pPriv->pm, + GXcopy, + opaque, + + gx, + gy, + gWidth, gHeight, + + (FbStip *) pglyph, + gStride, + 0); + } + } + x += pci->metrics.characterWidth; + } +} -- cgit v1.2.3