miglblt.c revision 4642e01f
1/***********************************************************
2
3Copyright 1987, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
21Except as contained in this notice, the name of The Open Group shall not be
22used in advertising or otherwise to promote the sale, use or other dealings
23in this Software without prior written authorization from The Open Group.
24
25
26Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
27
28                        All Rights Reserved
29
30Permission to use, copy, modify, and distribute this software and its
31documentation for any purpose and without fee is hereby granted,
32provided that the above copyright notice appear in all copies and that
33both that copyright notice and this permission notice appear in
34supporting documentation, and that the name of Digital not be
35used in advertising or publicity pertaining to distribution of the
36software without specific, written prior permission.
37
38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
44SOFTWARE.
45
46******************************************************************/
47
48
49#ifdef HAVE_DIX_CONFIG_H
50#include <dix-config.h>
51#endif
52
53#include	<X11/X.h>
54#include	<X11/Xmd.h>
55#include	<X11/Xproto.h>
56#include	"misc.h"
57#include	<X11/fonts/fontstruct.h>
58#include	"dixfontstr.h"
59#include	"gcstruct.h"
60#include	"windowstr.h"
61#include	"scrnintstr.h"
62#include	"pixmap.h"
63#include	"servermd.h"
64#include        "mi.h"
65
66/*
67    machine-independent glyph blt.
68    assumes that glyph bits in snf are written in bytes,
69have same bit order as the server's bitmap format,
70and are byte padded.  this corresponds to the snf distributed
71with the sample server.
72
73    get a scratch GC.
74    in the scratch GC set alu = GXcopy, fg = 1, bg = 0
75    allocate a bitmap big enough to hold the largest glyph in the font
76    validate the scratch gc with the bitmap
77    for each glyph
78	carefully put the bits of the glyph in a buffer,
79	    padded to the server pixmap scanline padding rules
80	fake a call to PutImage from the buffer into the bitmap
81	use the bitmap in a call to PushPixels
82*/
83
84_X_EXPORT void
85miPolyGlyphBlt(
86    DrawablePtr pDrawable,
87    GC		*pGC,
88    int		x,
89    int		y,
90    unsigned int nglyph,
91    CharInfoPtr *ppci,		/* array of character info */
92    pointer      pglyphBase	/* start of array of glyphs */
93    )
94{
95    int width, height;
96    PixmapPtr pPixmap;
97    int nbyLine;		/* bytes per line of padded pixmap */
98    FontPtr pfont;
99    GCPtr pGCtmp;
100    int i;
101    int j;
102    unsigned char *pbits;	/* buffer for PutImage */
103    unsigned char *pb;		/* temp pointer into buffer */
104    CharInfoPtr pci;		/* currect char info */
105    unsigned char *pglyph;	/* pointer bits in glyph */
106    int gWidth, gHeight;	/* width and height of glyph */
107    int nbyGlyphWidth;		/* bytes per scanline of glyph */
108    int nbyPadGlyph;		/* server padded line of glyph */
109
110    XID gcvals[3];
111
112    if (pGC->miTranslate)
113    {
114	x += pDrawable->x;
115	y += pDrawable->y;
116    }
117
118    pfont = pGC->font;
119    width = FONTMAXBOUNDS(pfont,rightSideBearing) -
120	    FONTMINBOUNDS(pfont,leftSideBearing);
121    height = FONTMAXBOUNDS(pfont,ascent) +
122	     FONTMAXBOUNDS(pfont,descent);
123
124    pPixmap = (*pDrawable->pScreen->CreatePixmap)(pDrawable->pScreen,
125						  width, height, 1,
126						  CREATE_PIXMAP_USAGE_SCRATCH);
127    if (!pPixmap)
128	return;
129
130    pGCtmp = GetScratchGC(1, pDrawable->pScreen);
131    if (!pGCtmp)
132    {
133	(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
134	return;
135    }
136
137    gcvals[0] = GXcopy;
138    gcvals[1] = 1;
139    gcvals[2] = 0;
140
141    DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0);
142
143    nbyLine = BitmapBytePad(width);
144    pbits = (unsigned char *)xalloc(height*nbyLine);
145    if (!pbits)
146    {
147	(*pDrawable->pScreen->DestroyPixmap)(pPixmap);
148	FreeScratchGC(pGCtmp);
149        return;
150    }
151    while(nglyph--)
152    {
153	pci = *ppci++;
154	pglyph = FONTGLYPHBITS(pglyphBase, pci);
155	gWidth = GLYPHWIDTHPIXELS(pci);
156	gHeight = GLYPHHEIGHTPIXELS(pci);
157	if (gWidth && gHeight)
158	{
159	    nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci);
160	    nbyPadGlyph = BitmapBytePad(gWidth);
161
162	    if (nbyGlyphWidth == nbyPadGlyph
163#if GLYPHPADBYTES != 4
164	        && (((int) pglyph) & 3) == 0
165#endif
166		)
167	    {
168		pb = pglyph;
169	    }
170	    else
171	    {
172		for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph))
173		    for (j = 0; j < nbyGlyphWidth; j++)
174			*pb++ = *pglyph++;
175		pb = pbits;
176	    }
177
178	    if ((pGCtmp->serialNumber) != (pPixmap->drawable.serialNumber))
179		ValidateGC((DrawablePtr)pPixmap, pGCtmp);
180	    (*pGCtmp->ops->PutImage)((DrawablePtr)pPixmap, pGCtmp,
181				pPixmap->drawable.depth,
182				0, 0, gWidth, gHeight,
183				0, XYBitmap, (char *)pb);
184
185	    if ((pGC->serialNumber) != (pDrawable->serialNumber))
186		ValidateGC(pDrawable, pGC);
187	    (*pGC->ops->PushPixels)(pGC, pPixmap, pDrawable,
188			       gWidth, gHeight,
189			       x + pci->metrics.leftSideBearing,
190			       y - pci->metrics.ascent);
191	}
192	x += pci->metrics.characterWidth;
193    }
194    (*pDrawable->pScreen->DestroyPixmap)(pPixmap);
195    xfree(pbits);
196    FreeScratchGC(pGCtmp);
197}
198
199
200_X_EXPORT void
201miImageGlyphBlt(
202    DrawablePtr pDrawable,
203    GC		*pGC,
204    int		 x,
205    int		 y,
206    unsigned int nglyph,
207    CharInfoPtr *ppci,		/* array of character info */
208    pointer      pglyphBase	/* start of array of glyphs */
209    )
210{
211    ExtentInfoRec info;		/* used by QueryGlyphExtents() */
212    XID gcvals[3];
213    int oldAlu, oldFS;
214    unsigned long	oldFG;
215    xRectangle backrect;
216
217    QueryGlyphExtents(pGC->font, ppci, (unsigned long)nglyph, &info);
218
219    if (info.overallWidth >= 0)
220    {
221    	backrect.x = x;
222    	backrect.width = info.overallWidth;
223    }
224    else
225    {
226	backrect.x = x + info.overallWidth;
227	backrect.width = -info.overallWidth;
228    }
229    backrect.y = y - FONTASCENT(pGC->font);
230    backrect.height = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
231
232    oldAlu = pGC->alu;
233    oldFG = pGC->fgPixel;
234    oldFS = pGC->fillStyle;
235
236    /* fill in the background */
237    gcvals[0] = GXcopy;
238    gcvals[1] = pGC->bgPixel;
239    gcvals[2] = FillSolid;
240    DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0);
241    ValidateGC(pDrawable, pGC);
242    (*pGC->ops->PolyFillRect)(pDrawable, pGC, 1, &backrect);
243
244    /* put down the glyphs */
245    gcvals[0] = oldFG;
246    DoChangeGC(pGC, GCForeground, gcvals, 0);
247    ValidateGC(pDrawable, pGC);
248    (*pGC->ops->PolyGlyphBlt)(pDrawable, pGC, x, y, nglyph, ppci,
249			      pglyphBase);
250
251    /* put all the toys away when done playing */
252    gcvals[0] = oldAlu;
253    gcvals[1] = oldFG;
254    gcvals[2] = oldFS;
255    DoChangeGC(pGC, GCFunction|GCForeground|GCFillStyle, gcvals, 0);
256    ValidateGC(pDrawable, pGC);
257
258}
259