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