105b261ecSmrg/***********************************************************
205b261ecSmrg
305b261ecSmrgCopyright 1987, 1998  The Open Group
405b261ecSmrg
505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its
605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that
705b261ecSmrgthe above copyright notice appear in all copies and that both that
805b261ecSmrgcopyright notice and this permission notice appear in supporting
905b261ecSmrgdocumentation.
1005b261ecSmrg
1105b261ecSmrgThe above copyright notice and this permission notice shall be included in
1205b261ecSmrgall copies or substantial portions of the Software.
1305b261ecSmrg
1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2005b261ecSmrg
2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be
2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings
2305b261ecSmrgin this Software without prior written authorization from The Open Group.
2405b261ecSmrg
2505b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
2605b261ecSmrg
2705b261ecSmrg                        All Rights Reserved
2805b261ecSmrg
2935c4bbdfSmrgPermission to use, copy, modify, and distribute this software and its
3035c4bbdfSmrgdocumentation for any purpose and without fee is hereby granted,
3105b261ecSmrgprovided that the above copyright notice appear in all copies and that
3235c4bbdfSmrgboth that copyright notice and this permission notice appear in
3305b261ecSmrgsupporting documentation, and that the name of Digital not be
3405b261ecSmrgused in advertising or publicity pertaining to distribution of the
3535c4bbdfSmrgsoftware without specific, written prior permission.
3605b261ecSmrg
3705b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
3905b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
4305b261ecSmrgSOFTWARE.
4405b261ecSmrg
4505b261ecSmrg******************************************************************/
4605b261ecSmrg
4705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H
4805b261ecSmrg#include <dix-config.h>
4905b261ecSmrg#endif
5005b261ecSmrg
5105b261ecSmrg#include	<X11/X.h>
5205b261ecSmrg#include	<X11/Xmd.h>
5305b261ecSmrg#include	<X11/Xproto.h>
5405b261ecSmrg#include	"misc.h"
5505b261ecSmrg#include	<X11/fonts/fontstruct.h>
561b5d61b8Smrg#include        <X11/fonts/libxfont2.h>
5705b261ecSmrg#include	"dixfontstr.h"
5805b261ecSmrg#include	"gcstruct.h"
5905b261ecSmrg#include	"windowstr.h"
6005b261ecSmrg#include	"scrnintstr.h"
6105b261ecSmrg#include	"pixmap.h"
6205b261ecSmrg#include	"servermd.h"
6305b261ecSmrg#include        "mi.h"
6405b261ecSmrg
6505b261ecSmrg/*
6605b261ecSmrg    machine-independent glyph blt.
6705b261ecSmrg    assumes that glyph bits in snf are written in bytes,
6805b261ecSmrghave same bit order as the server's bitmap format,
6905b261ecSmrgand are byte padded.  this corresponds to the snf distributed
7005b261ecSmrgwith the sample server.
7105b261ecSmrg
7205b261ecSmrg    get a scratch GC.
7305b261ecSmrg    in the scratch GC set alu = GXcopy, fg = 1, bg = 0
7405b261ecSmrg    allocate a bitmap big enough to hold the largest glyph in the font
7505b261ecSmrg    validate the scratch gc with the bitmap
7605b261ecSmrg    for each glyph
7705b261ecSmrg	carefully put the bits of the glyph in a buffer,
7805b261ecSmrg	    padded to the server pixmap scanline padding rules
7905b261ecSmrg	fake a call to PutImage from the buffer into the bitmap
8005b261ecSmrg	use the bitmap in a call to PushPixels
8105b261ecSmrg*/
8205b261ecSmrg
836747b715Smrgvoid
8435c4bbdfSmrgmiPolyGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci,  /* array of character info */
8535c4bbdfSmrg               void *pglyphBase       /* start of array of glyphs */
864642e01fSmrg    )
8705b261ecSmrg{
8805b261ecSmrg    int width, height;
8905b261ecSmrg    PixmapPtr pPixmap;
9035c4bbdfSmrg    int nbyLine;                /* bytes per line of padded pixmap */
9105b261ecSmrg    FontPtr pfont;
9205b261ecSmrg    GCPtr pGCtmp;
9305b261ecSmrg    int i;
9405b261ecSmrg    int j;
9535c4bbdfSmrg    unsigned char *pbits;       /* buffer for PutImage */
9635c4bbdfSmrg    unsigned char *pb;          /* temp pointer into buffer */
97ed6184dfSmrg    CharInfoPtr pci;            /* current char info */
9835c4bbdfSmrg    unsigned char *pglyph;      /* pointer bits in glyph */
9935c4bbdfSmrg    int gWidth, gHeight;        /* width and height of glyph */
10035c4bbdfSmrg    int nbyGlyphWidth;          /* bytes per scanline of glyph */
10135c4bbdfSmrg    int nbyPadGlyph;            /* server padded line of glyph */
10205b261ecSmrg
1036747b715Smrg    ChangeGCVal gcvals[3];
10405b261ecSmrg
10535c4bbdfSmrg    if (pGC->miTranslate) {
10635c4bbdfSmrg        x += pDrawable->x;
10735c4bbdfSmrg        y += pDrawable->y;
10805b261ecSmrg    }
10905b261ecSmrg
11005b261ecSmrg    pfont = pGC->font;
11135c4bbdfSmrg    width = FONTMAXBOUNDS(pfont, rightSideBearing) -
11235c4bbdfSmrg        FONTMINBOUNDS(pfont, leftSideBearing);
11335c4bbdfSmrg    height = FONTMAXBOUNDS(pfont, ascent) + FONTMAXBOUNDS(pfont, descent);
11435c4bbdfSmrg
11535c4bbdfSmrg    pPixmap = (*pDrawable->pScreen->CreatePixmap) (pDrawable->pScreen,
11635c4bbdfSmrg                                                   width, height, 1,
11735c4bbdfSmrg                                                   CREATE_PIXMAP_USAGE_SCRATCH);
11805b261ecSmrg    if (!pPixmap)
11935c4bbdfSmrg        return;
12005b261ecSmrg
12105b261ecSmrg    pGCtmp = GetScratchGC(1, pDrawable->pScreen);
12235c4bbdfSmrg    if (!pGCtmp) {
12335c4bbdfSmrg        (*pDrawable->pScreen->DestroyPixmap) (pPixmap);
12435c4bbdfSmrg        return;
12505b261ecSmrg    }
12605b261ecSmrg
1276747b715Smrg    gcvals[0].val = GXcopy;
1286747b715Smrg    gcvals[1].val = 1;
1296747b715Smrg    gcvals[2].val = 0;
13005b261ecSmrg
13135c4bbdfSmrg    ChangeGC(NullClient, pGCtmp, GCFunction | GCForeground | GCBackground,
13235c4bbdfSmrg             gcvals);
13305b261ecSmrg
13405b261ecSmrg    nbyLine = BitmapBytePad(width);
13535c4bbdfSmrg    pbits = xallocarray(height, nbyLine);
13635c4bbdfSmrg    if (!pbits) {
13735c4bbdfSmrg        (*pDrawable->pScreen->DestroyPixmap) (pPixmap);
13835c4bbdfSmrg        FreeScratchGC(pGCtmp);
13905b261ecSmrg        return;
14005b261ecSmrg    }
14135c4bbdfSmrg    while (nglyph--) {
14235c4bbdfSmrg        pci = *ppci++;
14335c4bbdfSmrg        pglyph = FONTGLYPHBITS(pglyphBase, pci);
14435c4bbdfSmrg        gWidth = GLYPHWIDTHPIXELS(pci);
14535c4bbdfSmrg        gHeight = GLYPHHEIGHTPIXELS(pci);
14635c4bbdfSmrg        if (gWidth && gHeight) {
14735c4bbdfSmrg            nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
14835c4bbdfSmrg            nbyPadGlyph = BitmapBytePad(gWidth);
14935c4bbdfSmrg
15035c4bbdfSmrg            if (nbyGlyphWidth == nbyPadGlyph
15105b261ecSmrg#if GLYPHPADBYTES != 4
15235c4bbdfSmrg                && (((int) pglyph) & 3) == 0
15305b261ecSmrg#endif
15435c4bbdfSmrg                ) {
15535c4bbdfSmrg                pb = pglyph;
15635c4bbdfSmrg            }
15735c4bbdfSmrg            else {
15835c4bbdfSmrg                for (i = 0, pb = pbits; i < gHeight;
15935c4bbdfSmrg                     i++, pb = pbits + (i * nbyPadGlyph))
16035c4bbdfSmrg                    for (j = 0; j < nbyGlyphWidth; j++)
16135c4bbdfSmrg                        *pb++ = *pglyph++;
16235c4bbdfSmrg                pb = pbits;
16335c4bbdfSmrg            }
16435c4bbdfSmrg
16535c4bbdfSmrg            if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber))
16635c4bbdfSmrg                ValidateGC((DrawablePtr) pPixmap, pGCtmp);
16735c4bbdfSmrg            (*pGCtmp->ops->PutImage) ((DrawablePtr) pPixmap, pGCtmp,
16835c4bbdfSmrg                                      pPixmap->drawable.depth,
16935c4bbdfSmrg                                      0, 0, gWidth, gHeight,
17035c4bbdfSmrg                                      0, XYBitmap, (char *) pb);
17135c4bbdfSmrg
17235c4bbdfSmrg            (*pGC->ops->PushPixels) (pGC, pPixmap, pDrawable,
17335c4bbdfSmrg                                     gWidth, gHeight,
17435c4bbdfSmrg                                     x + pci->metrics.leftSideBearing,
17535c4bbdfSmrg                                     y - pci->metrics.ascent);
17635c4bbdfSmrg        }
17735c4bbdfSmrg        x += pci->metrics.characterWidth;
17805b261ecSmrg    }
17935c4bbdfSmrg    (*pDrawable->pScreen->DestroyPixmap) (pPixmap);
1806747b715Smrg    free(pbits);
18105b261ecSmrg    FreeScratchGC(pGCtmp);
18205b261ecSmrg}
18305b261ecSmrg
1846747b715Smrgvoid
18535c4bbdfSmrgmiImageGlyphBlt(DrawablePtr pDrawable, GC * pGC, int x, int y, unsigned int nglyph, CharInfoPtr * ppci, /* array of character info */
18635c4bbdfSmrg                void *pglyphBase      /* start of array of glyphs */
1874642e01fSmrg    )
18805b261ecSmrg{
1891b5d61b8Smrg    ExtentInfoRec info;         /* used by xfont2_query_glyph_extents() */
1906747b715Smrg    ChangeGCVal gcvals[3];
19105b261ecSmrg    int oldAlu, oldFS;
19235c4bbdfSmrg    unsigned long oldFG;
19305b261ecSmrg    xRectangle backrect;
19405b261ecSmrg
1951b5d61b8Smrg    xfont2_query_glyph_extents(pGC->font, ppci, (unsigned long) nglyph, &info);
19605b261ecSmrg
19735c4bbdfSmrg    if (info.overallWidth >= 0) {
19835c4bbdfSmrg        backrect.x = x;
19935c4bbdfSmrg        backrect.width = info.overallWidth;
20005b261ecSmrg    }
20135c4bbdfSmrg    else {
20235c4bbdfSmrg        backrect.x = x + info.overallWidth;
20335c4bbdfSmrg        backrect.width = -info.overallWidth;
20405b261ecSmrg    }
20505b261ecSmrg    backrect.y = y - FONTASCENT(pGC->font);
20605b261ecSmrg    backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
20705b261ecSmrg
20805b261ecSmrg    oldAlu = pGC->alu;
20905b261ecSmrg    oldFG = pGC->fgPixel;
21005b261ecSmrg    oldFS = pGC->fillStyle;
21105b261ecSmrg
21205b261ecSmrg    /* fill in the background */
2136747b715Smrg    gcvals[0].val = GXcopy;
2146747b715Smrg    gcvals[1].val = pGC->bgPixel;
2156747b715Smrg    gcvals[2].val = FillSolid;
21635c4bbdfSmrg    ChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFillStyle, gcvals);
21705b261ecSmrg    ValidateGC(pDrawable, pGC);
21835c4bbdfSmrg    (*pGC->ops->PolyFillRect) (pDrawable, pGC, 1, &backrect);
21905b261ecSmrg
22005b261ecSmrg    /* put down the glyphs */
2216747b715Smrg    gcvals[0].val = oldFG;
2226747b715Smrg    ChangeGC(NullClient, pGC, GCForeground, gcvals);
22305b261ecSmrg    ValidateGC(pDrawable, pGC);
22435c4bbdfSmrg    (*pGC->ops->PolyGlyphBlt) (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
22505b261ecSmrg
22605b261ecSmrg    /* put all the toys away when done playing */
2276747b715Smrg    gcvals[0].val = oldAlu;
2286747b715Smrg    gcvals[1].val = oldFG;
2296747b715Smrg    gcvals[2].val = oldFS;
23035c4bbdfSmrg    ChangeGC(NullClient, pGC, GCFunction | GCForeground | GCFillStyle, gcvals);
23105b261ecSmrg    ValidateGC(pDrawable, pGC);
23205b261ecSmrg
23305b261ecSmrg}
234