miglblt.c revision 4642e01f
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 2505b261ecSmrg 2605b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 2705b261ecSmrg 2805b261ecSmrg All Rights Reserved 2905b261ecSmrg 3005b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3105b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3205b261ecSmrgprovided that the above copyright notice appear in all copies and that 3305b261ecSmrgboth that copyright notice and this permission notice appear in 3405b261ecSmrgsupporting documentation, and that the name of Digital not be 3505b261ecSmrgused in advertising or publicity pertaining to distribution of the 3605b261ecSmrgsoftware without specific, written prior permission. 3705b261ecSmrg 3805b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3905b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 4005b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4105b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4205b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4305b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4405b261ecSmrgSOFTWARE. 4505b261ecSmrg 4605b261ecSmrg******************************************************************/ 4705b261ecSmrg 4805b261ecSmrg 4905b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 5005b261ecSmrg#include <dix-config.h> 5105b261ecSmrg#endif 5205b261ecSmrg 5305b261ecSmrg#include <X11/X.h> 5405b261ecSmrg#include <X11/Xmd.h> 5505b261ecSmrg#include <X11/Xproto.h> 5605b261ecSmrg#include "misc.h" 5705b261ecSmrg#include <X11/fonts/fontstruct.h> 5805b261ecSmrg#include "dixfontstr.h" 5905b261ecSmrg#include "gcstruct.h" 6005b261ecSmrg#include "windowstr.h" 6105b261ecSmrg#include "scrnintstr.h" 6205b261ecSmrg#include "pixmap.h" 6305b261ecSmrg#include "servermd.h" 6405b261ecSmrg#include "mi.h" 6505b261ecSmrg 6605b261ecSmrg/* 6705b261ecSmrg machine-independent glyph blt. 6805b261ecSmrg assumes that glyph bits in snf are written in bytes, 6905b261ecSmrghave same bit order as the server's bitmap format, 7005b261ecSmrgand are byte padded. this corresponds to the snf distributed 7105b261ecSmrgwith the sample server. 7205b261ecSmrg 7305b261ecSmrg get a scratch GC. 7405b261ecSmrg in the scratch GC set alu = GXcopy, fg = 1, bg = 0 7505b261ecSmrg allocate a bitmap big enough to hold the largest glyph in the font 7605b261ecSmrg validate the scratch gc with the bitmap 7705b261ecSmrg for each glyph 7805b261ecSmrg carefully put the bits of the glyph in a buffer, 7905b261ecSmrg padded to the server pixmap scanline padding rules 8005b261ecSmrg fake a call to PutImage from the buffer into the bitmap 8105b261ecSmrg use the bitmap in a call to PushPixels 8205b261ecSmrg*/ 8305b261ecSmrg 8405b261ecSmrg_X_EXPORT void 854642e01fSmrgmiPolyGlyphBlt( 864642e01fSmrg DrawablePtr pDrawable, 874642e01fSmrg GC *pGC, 884642e01fSmrg int x, 894642e01fSmrg int y, 904642e01fSmrg unsigned int nglyph, 914642e01fSmrg CharInfoPtr *ppci, /* array of character info */ 924642e01fSmrg pointer pglyphBase /* start of array of glyphs */ 934642e01fSmrg ) 9405b261ecSmrg{ 9505b261ecSmrg int width, height; 9605b261ecSmrg PixmapPtr pPixmap; 9705b261ecSmrg int nbyLine; /* bytes per line of padded pixmap */ 9805b261ecSmrg FontPtr pfont; 9905b261ecSmrg GCPtr pGCtmp; 10005b261ecSmrg int i; 10105b261ecSmrg int j; 10205b261ecSmrg unsigned char *pbits; /* buffer for PutImage */ 10305b261ecSmrg unsigned char *pb; /* temp pointer into buffer */ 10405b261ecSmrg CharInfoPtr pci; /* currect char info */ 10505b261ecSmrg unsigned char *pglyph; /* pointer bits in glyph */ 10605b261ecSmrg int gWidth, gHeight; /* width and height of glyph */ 10705b261ecSmrg int nbyGlyphWidth; /* bytes per scanline of glyph */ 10805b261ecSmrg int nbyPadGlyph; /* server padded line of glyph */ 10905b261ecSmrg 11005b261ecSmrg XID gcvals[3]; 11105b261ecSmrg 11205b261ecSmrg if (pGC->miTranslate) 11305b261ecSmrg { 11405b261ecSmrg x += pDrawable->x; 11505b261ecSmrg y += pDrawable->y; 11605b261ecSmrg } 11705b261ecSmrg 11805b261ecSmrg pfont = pGC->font; 11905b261ecSmrg width = FONTMAXBOUNDS(pfont,rightSideBearing) - 12005b261ecSmrg FONTMINBOUNDS(pfont,leftSideBearing); 12105b261ecSmrg height = FONTMAXBOUNDS(pfont,ascent) + 12205b261ecSmrg FONTMAXBOUNDS(pfont,descent); 12305b261ecSmrg 12405b261ecSmrg pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen, 1254642e01fSmrg width, height, 1, 1264642e01fSmrg CREATE_PIXMAP_USAGE_SCRATCH); 12705b261ecSmrg if (!pPixmap) 12805b261ecSmrg return; 12905b261ecSmrg 13005b261ecSmrg pGCtmp = GetScratchGC(1, pDrawable->pScreen); 13105b261ecSmrg if (!pGCtmp) 13205b261ecSmrg { 13305b261ecSmrg (*pDrawable->pScreen->DestroyPixmap)(pPixmap); 13405b261ecSmrg return; 13505b261ecSmrg } 13605b261ecSmrg 13705b261ecSmrg gcvals[0] = GXcopy; 13805b261ecSmrg gcvals[1] = 1; 13905b261ecSmrg gcvals[2] = 0; 14005b261ecSmrg 14105b261ecSmrg DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0); 14205b261ecSmrg 14305b261ecSmrg nbyLine = BitmapBytePad(width); 1444642e01fSmrg pbits = (unsigned char *)xalloc(height*nbyLine); 14505b261ecSmrg if (!pbits) 14605b261ecSmrg { 14705b261ecSmrg (*pDrawable->pScreen->DestroyPixmap)(pPixmap); 14805b261ecSmrg FreeScratchGC(pGCtmp); 14905b261ecSmrg return; 15005b261ecSmrg } 15105b261ecSmrg while(nglyph--) 15205b261ecSmrg { 15305b261ecSmrg pci = *ppci++; 15405b261ecSmrg pglyph = FONTGLYPHBITS(pglyphBase, pci); 15505b261ecSmrg gWidth = GLYPHWIDTHPIXELS(pci); 15605b261ecSmrg gHeight = GLYPHHEIGHTPIXELS(pci); 15705b261ecSmrg if (gWidth && gHeight) 15805b261ecSmrg { 15905b261ecSmrg nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci); 16005b261ecSmrg nbyPadGlyph = BitmapBytePad(gWidth); 16105b261ecSmrg 16205b261ecSmrg if (nbyGlyphWidth == nbyPadGlyph 16305b261ecSmrg#if GLYPHPADBYTES != 4 16405b261ecSmrg && (((int) pglyph) & 3) == 0 16505b261ecSmrg#endif 16605b261ecSmrg ) 16705b261ecSmrg { 16805b261ecSmrg pb = pglyph; 16905b261ecSmrg } 17005b261ecSmrg else 17105b261ecSmrg { 17205b261ecSmrg for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph)) 17305b261ecSmrg for (j = 0; j < nbyGlyphWidth; j++) 17405b261ecSmrg *pb++ = *pglyph++; 17505b261ecSmrg pb = pbits; 17605b261ecSmrg } 17705b261ecSmrg 17805b261ecSmrg if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber)) 17905b261ecSmrg ValidateGC((DrawablePtr)pPixmap, pGCtmp); 18005b261ecSmrg (*pGCtmp->ops->PutImage)((DrawablePtr)pPixmap, pGCtmp, 18105b261ecSmrg pPixmap->drawable.depth, 18205b261ecSmrg 0, 0, gWidth, gHeight, 18305b261ecSmrg 0, XYBitmap, (char *)pb); 18405b261ecSmrg 18505b261ecSmrg if ((pGC->serialNumber) != (pDrawable->serialNumber)) 18605b261ecSmrg ValidateGC(pDrawable, pGC); 18705b261ecSmrg (*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable, 18805b261ecSmrg gWidth, gHeight, 18905b261ecSmrg x + pci->metrics.leftSideBearing, 19005b261ecSmrg y - pci->metrics.ascent); 19105b261ecSmrg } 19205b261ecSmrg x += pci->metrics.characterWidth; 19305b261ecSmrg } 19405b261ecSmrg (*pDrawable->pScreen->DestroyPixmap)(pPixmap); 1954642e01fSmrg xfree(pbits); 19605b261ecSmrg FreeScratchGC(pGCtmp); 19705b261ecSmrg} 19805b261ecSmrg 19905b261ecSmrg 20005b261ecSmrg_X_EXPORT void 2014642e01fSmrgmiImageGlyphBlt( 2024642e01fSmrg DrawablePtr pDrawable, 2034642e01fSmrg GC *pGC, 2044642e01fSmrg int x, 2054642e01fSmrg int y, 2064642e01fSmrg unsigned int nglyph, 2074642e01fSmrg CharInfoPtr *ppci, /* array of character info */ 2084642e01fSmrg pointer pglyphBase /* start of array of glyphs */ 2094642e01fSmrg ) 21005b261ecSmrg{ 21105b261ecSmrg ExtentInfoRec info; /* used by QueryGlyphExtents() */ 21205b261ecSmrg XID gcvals[3]; 21305b261ecSmrg int oldAlu, oldFS; 21405b261ecSmrg unsigned long oldFG; 21505b261ecSmrg xRectangle backrect; 21605b261ecSmrg 21705b261ecSmrg QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info); 21805b261ecSmrg 21905b261ecSmrg if (info.overallWidth >= 0) 22005b261ecSmrg { 22105b261ecSmrg backrect.x = x; 22205b261ecSmrg backrect.width = info.overallWidth; 22305b261ecSmrg } 22405b261ecSmrg else 22505b261ecSmrg { 22605b261ecSmrg backrect.x = x + info.overallWidth; 22705b261ecSmrg backrect.width = -info.overallWidth; 22805b261ecSmrg } 22905b261ecSmrg backrect.y = y - FONTASCENT(pGC->font); 23005b261ecSmrg backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font); 23105b261ecSmrg 23205b261ecSmrg oldAlu = pGC->alu; 23305b261ecSmrg oldFG = pGC->fgPixel; 23405b261ecSmrg oldFS = pGC->fillStyle; 23505b261ecSmrg 23605b261ecSmrg /* fill in the background */ 23705b261ecSmrg gcvals[0] = GXcopy; 23805b261ecSmrg gcvals[1] = pGC->bgPixel; 23905b261ecSmrg gcvals[2] = FillSolid; 24005b261ecSmrg DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0); 24105b261ecSmrg ValidateGC(pDrawable, pGC); 24205b261ecSmrg (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &backrect); 24305b261ecSmrg 24405b261ecSmrg /* put down the glyphs */ 24505b261ecSmrg gcvals[0] = oldFG; 24605b261ecSmrg DoChangeGC(pGC, GCForeground, gcvals, 0); 24705b261ecSmrg ValidateGC(pDrawable, pGC); 24805b261ecSmrg (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci, 24905b261ecSmrg pglyphBase); 25005b261ecSmrg 25105b261ecSmrg /* put all the toys away when done playing */ 25205b261ecSmrg gcvals[0] = oldAlu; 25305b261ecSmrg gcvals[1] = oldFG; 25405b261ecSmrg gcvals[2] = oldFS; 25505b261ecSmrg DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0); 25605b261ecSmrg ValidateGC(pDrawable, pGC); 25705b261ecSmrg 25805b261ecSmrg} 259