1 /* $XConsortium: mfbtegblt.c,v 5.14 94/04/17 20:28:35 dpw Exp $ */
2 /* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
3 /***********************************************************
5 Copyright (c) 1987 X Consortium
7 Permission is hereby granted, free of charge, to any person obtaining a copy
8 of this software and associated documentation files (the "Software"), to deal
9 in the Software without restriction, including without limitation the rights
10 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 copies of the Software, and to permit persons to whom the Software is
12 furnished to do so, subject to the following conditions:
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 Except as contained in this notice, the name of the X Consortium shall not be
25 used in advertising or otherwise to promote the sale, use or other dealings
26 in this Software without prior written authorization from the X Consortium.
29 Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
33 Permission to use, copy, modify, and distribute this software and its
34 documentation for any purpose and without fee is hereby granted,
35 provided that the above copyright notice appear in all copies and that
36 both that copyright notice and this permission notice appear in
37 supporting documentation, and that the name of Digital not be
38 used in advertising or publicity pertaining to distribution of the
39 software without specific, written prior permission.
41 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
43 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
44 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
45 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
46 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
49 ******************************************************************/
54 #include "fontstruct.h"
55 #include "dixfontstr.h"
57 #include "windowstr.h"
58 #include "scrnintstr.h"
59 #include "pixmapstr.h"
60 #include "regionstr.h"
64 this works for fonts with glyphs <= PPW bits wide.
66 This should be called only with a terminal-emulator font;
67 this means that the FIXED_METRICS flag is set, and that
68 glyphbounds == charbounds.
70 in theory, this goes faster; even if it doesn't, it reduces the
71 flicker caused by writing a string over itself with image text (since
72 the background gets repainted per character instead of per string.)
73 this seems to be important for some converted X10 applications.
75 Image text looks at the bits in the glyph and the fg and bg in the
76 GC. it paints a rectangle, as defined in the protocol dcoument,
77 and the paints the characters.
79 to avoid source proliferation, this file is compiled
82 mfbTEGlyphBltWhite (white text, black bg )
83 mfbTEGlyphBltBlack ~ (black text, white bg )
87 #if defined(NO_3_60_CG4) && defined(FASTPUTBITS) && defined(FASTGETBITS)
92 * this macro "knows" that only characters <= 8 bits wide will
93 * fit this case (which is why it is independent of GLYPHPADBYTES)
96 #if (BITMAP_BIT_ORDER == MSBFirst) && (GLYPHPADBYTES != 4)
97 #if GLYPHPADBYTES == 1
104 * Note: for BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER, SCRRIGHT() evaluates its
105 * first argument more than once. Thus the imbedded char++ have to be moved.
108 #if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
110 #define GetBits4 c = (*char1++ << ShiftAmnt) | \
111 SCRRIGHT (*char2++ << ShiftAmnt, xoff2) | \
112 SCRRIGHT (*char3++ << ShiftAmnt, xoff3) | \
113 SCRRIGHT (*char4++ << ShiftAmnt, xoff4);
115 #define GetBits4 c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 ) | \
116 (SCRRIGHT (*char2++ << ShiftAmnt, xoff2) << 32 ) | \
117 (SCRRIGHT (*char3++ << ShiftAmnt, xoff3) << 32 ) | \
118 (SCRRIGHT (*char4++ << ShiftAmnt, xoff4) << 32 ) | \
119 (*char5++ << ShiftAmnt) | \
120 SCRRIGHT (*char6++ << ShiftAmnt, xoff6) | \
121 SCRRIGHT (*char7++ << ShiftAmnt, xoff7) | \
122 SCRRIGHT (*char8++ << ShiftAmnt, xoff8);
124 #else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */
126 #define GetBits4 c = (*char1++ << ShiftAmnt) | \
127 SCRRIGHT (*char2 << ShiftAmnt, xoff2) | \
128 SCRRIGHT (*char3 << ShiftAmnt, xoff3) | \
129 SCRRIGHT (*char4 << ShiftAmnt, xoff4); \
130 char2++; char3++; char4++;
131 #else /* PPW == 64 */
132 #define GetBits4 c = ((unsigned long)(*char1++ << ShiftAmnt) << 32 ) | \
133 (SCRRIGHT (*char2 << ShiftAmnt, xoff2) << 32 ) | \
134 (SCRRIGHT (*char3 << ShiftAmnt, xoff3) << 32 ) | \
135 (SCRRIGHT (*char4 << ShiftAmnt, xoff4) << 32 ) | \
136 (*char5++ << ShiftAmnt) | \
137 SCRRIGHT (*char6 << ShiftAmnt, xoff6) | \
138 SCRRIGHT (*char7 << ShiftAmnt, xoff7) | \
139 SCRRIGHT (*char8 << ShiftAmnt, xoff8); \
140 char2++; char3++; char4++; char6++; char7++; char8++;
142 #endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */
144 #else /* (BITMAP_BIT_ORDER != MSBFirst) || (GLYPHPADBYTES == 4) */
146 #if BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER
148 #define GetBits4 c = *char1++ | \
149 SCRRIGHT (*char2++, xoff2) | \
150 SCRRIGHT (*char3++, xoff3) | \
151 SCRRIGHT (*char4++, xoff4);
152 #else /* PPW == 64 */
153 #define GetBits4 c = (unsigned long)(((*char1++) << 64 ) | \
154 (SCRRIGHT (*char2++, xoff2) << 64 ) | \
155 (SCRRIGHT (*char3++, xoff3) << 64 ) | \
156 (SCRRIGHT (*char4++, xoff4) << 64 ) | \
157 SCRRIGHT (*char5++, xoff5) | \
158 SCRRIGHT (*char6++, xoff6) | \
159 SCRRIGHT (*char7++, xoff7) | \
160 SCRRIGHT (*char8++, xoff8));
162 #else /* BITMAP_BIT_ORDER != IMAGE_BYTE_ORDER */
164 #define GetBits4 c = *char1++ | \
165 SCRRIGHT (*char2, xoff2) | \
166 SCRRIGHT (*char3, xoff3) | \
167 SCRRIGHT (*char4, xoff4); \
168 char2++; char3++; char4++;
169 #else /* PPW == 64 */
170 #define GetBits4 c = (unsigned long)(((*char1++) << 64 ) | \
171 (SCRRIGHT (*char2, xoff2) << 64 ) | \
172 (SCRRIGHT (*char3, xoff3) << 64 ) | \
173 (SCRRIGHT (*char4, xoff4) << 64 ) | \
174 SCRRIGHT (*char5, xoff5) | \
175 SCRRIGHT (*char6, xoff6) | \
176 SCRRIGHT (*char7, xoff7) | \
177 SCRRIGHT (*char8, xoff8)); \
178 char2++; char3++; char4++; \
179 char5++; char6++; char7++; char8++;
181 #endif /* BITMAP_BIT_ORDER == IMAGE_BYTE_ORDER */
183 #endif /* BITMAP_BIT_ORDER && GLYPHPADBYTES */
186 #if GLYPHPADBYTES == 1
187 typedef unsigned char *glyphPointer;
191 #if GLYPHPADBYTES == 2
192 typedef unsigned short *glyphPointer;
196 #if GLYPHPADBYTES == 4
197 typedef unsigned int *glyphPointer;
201 #define GetBits1 getleftbits (char1, widthGlyph, c); \
203 char1 = (glyphPointer) (((char *) char1) + glyphBytes);
205 #define GetBits1 c = *char1++;
209 MFBTEGLYPHBLT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
210 DrawablePtr pDrawable;
214 CharInfoPtr *ppci; /* array of character info */
215 pointer pglyphBase; /* start of array of glyphs */
217 FontPtr pfont = pGC->font;
219 PixelType *pdstBase; /* pointer to longword with top row
222 int h; /* height of glyph and char */
223 register int xpos; /* current x */
224 int ypos; /* current y */
227 int hTmp; /* counter for height */
228 register PixelType startmask, endmask;
229 int nfirst; /* used if glyphs spans a longword boundary */
230 BoxRec bbox; /* for clipping */
232 register PixelType *dst;
233 register PixelType c;
234 register int xoff1, xoff2, xoff3, xoff4;
235 register glyphPointer char1, char2, char3, char4;
237 register int xoff5, xoff6, xoff7, xoff8;
238 register glyphPointer char5, char6, char7, char8;
242 register PixelType glyphMask;
243 register PixelType tmpSrc;
244 register int glyphBytes;
247 if (!(pGC->planemask & 1))
250 mfbGetPixelWidthAndPointer(pDrawable, widthDst, pdstBase);
252 xpos = x + pDrawable->x;
253 ypos = y + pDrawable->y;
255 widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
256 h = FONTASCENT(pfont) + FONTDESCENT(pfont);
258 xpos += FONTMAXBOUNDS(pfont,leftSideBearing);
259 ypos -= FONTASCENT(pfont);
262 bbox.x2 = xpos + (widthGlyph * nglyph);
266 switch (RECT_IN_REGION(pGC->pScreen,
267 ((mfbPrivGC *)(pGC->devPrivates[mfbGCPrivateIndex].ptr))->pCompositeClip, &bbox))
270 /* this is the WRONG thing to do, but it works.
271 calling the non-terminal text is easy, but slow, given
272 what we know about the font.
274 the right thing to do is something like:
275 for each clip rectangle
276 compute at which row the glyph starts to be in it,
277 and at which row the glyph ceases to be in it
278 compute which is the first glyph inside the left
279 edge, and the last one inside the right edge
280 draw a fractional first glyph, using only
281 the rows we know are in
282 draw all the whole glyphs, using the appropriate rows
283 draw any pieces of the last glyph, using the right rows
285 this way, the code would take advantage of knowing that
286 all glyphs are the same height and don't overlap.
290 CLIPTETEXT(pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
294 pdstBase = mfbScanlineDeltaNoBankSwitch(pdstBase, ypos, widthDst);
295 widthGlyphs = widthGlyph * PGSZB;
298 glyphMask = endtab[widthGlyph];
299 glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci);
302 if (nglyph >= PGSZB && widthGlyphs <= PPW)
304 while (nglyph >= PGSZB)
309 xoff3 = xoff2 + widthGlyph;
310 xoff4 = xoff3 + widthGlyph;
312 xoff5 = xoff4 + widthGlyph;
313 xoff6 = xoff5 + widthGlyph;
314 xoff7 = xoff6 + widthGlyph;
315 xoff8 = xoff7 + widthGlyph;
317 char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
318 char2 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
319 char3 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
320 char4 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
322 char5 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
323 char6 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
324 char7 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
325 char8 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
329 dst = mfbScanlineOffset(pdstBase, (xpos >> PWSH)); /* switch now */
332 if (xoff1 + widthGlyphs <= PPW)
334 maskpartialbits (xoff1, widthGlyphs, startmask);
340 # if BITMAP_BIT_ORDER == MSBFirst
341 c >>= PPW - widthGlyphs;
343 FASTPUTBITS(OP(c), xoff1, widthGlyphs, dst);
345 *(dst) = (*dst) & ~startmask | OP(SCRRIGHT(c, xoff1)) & startmask;
347 mfbScanlineInc(dst, widthDst);
353 maskPPWbits (xoff1, widthGlyphs, startmask, endmask);
354 nfirst = PPW - xoff1;
358 dst[0] = dst[0] & ~startmask |
359 OP(SCRRIGHT(c,xoff1)) & startmask;
360 dst[1] = dst[1] & ~endmask |
361 OP(SCRLEFT(c,nfirst)) & endmask;
362 mfbScanlineInc(dst, widthDst);
373 char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase,(*ppci++));
375 dst = mfbScanlineOffset(pdstBase, (xpos >> PWSH));
378 if (xoff1 + widthGlyph <= PPW)
380 maskpartialbits (xoff1, widthGlyph, startmask);
386 FASTGETBITS (char1,0,widthGlyph,c);
387 char1 = (glyphPointer) (((char *) char1) + glyphBytes);
390 #if BITMAP_BIT_ORDER == MSBFirst
391 c >>= PPW - widthGlyph;
394 FASTPUTBITS (OP(c),xoff1,widthGlyph,dst);
397 (*dst) = (*dst) & ~startmask | OP(SCRRIGHT(c, xoff1)) & startmask;
399 mfbScanlineInc(dst, widthDst);
405 maskPPWbits (xoff1, widthGlyph, startmask, endmask);
406 nfirst = PPW - xoff1;
410 dst[0] = dst[0] & ~startmask |
411 OP(SCRRIGHT(c,xoff1)) & startmask;
412 dst[1] = dst[1] & ~endmask |
413 OP(SCRLEFT(c,nfirst)) & endmask;
414 mfbScanlineInc(dst, widthDst);