2 * TEGblt - ImageText expanded glyph fonts only. For
3 * 8 bit displays, in Copy mode with no clipping.
8 Copyright (c) 1989 X Consortium
10 Permission is hereby granted, free of charge, to any person obtaining a copy
11 of this software and associated documentation files (the "Software"), to deal
12 in the Software without restriction, including without limitation the rights
13 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 copies of the Software, and to permit persons to whom the Software is
15 furnished to do so, subject to the following conditions:
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
20 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
24 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
25 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 Except as contained in this notice, the name of the X Consortium shall not be
28 used in advertising or otherwise to promote the sale, use or other dealings
29 in this Software without prior written authorization from the X Consortium.
32 /* $XConsortium: cfbteblt8.c,v 5.24 94/09/29 15:26:00 dpw Exp $ */
40 #include "fontstruct.h"
41 #include "dixfontstr.h"
43 #include "windowstr.h"
44 #include "scrnintstr.h"
45 #include "pixmapstr.h"
46 #include "regionstr.h"
47 #include "cfbmskbits.h"
51 * this code supports up to 5 characters at a time. The performance
52 * differences between 4 and 5 is usually small (~7% on PMAX) and
53 * frequently negative (SPARC and Sun3), so this file is compiled
54 * only once for now. If you want to use the other options, you'll
55 * need to hack cfbgc.c as well.
64 #define CFBTEGBLT8 cfbTEGlyphBlt8
68 * On little-endian machines (or where fonts are padded to 32-bit
69 * boundaries) we can use some magic to avoid the expense of getleftbits
72 #if ((BITMAP_BIT_ORDER == LSBFirst && NGLYPHS >= 4) || GLYPHPADBYTES == 4)
74 #if GLYPHPADBYTES == 1
75 typedef unsigned char *glyphPointer;
79 #if GLYPHPADBYTES == 2
80 typedef unsigned short *glyphPointer;
84 #if GLYPHPADBYTES == 4
85 typedef unsigned int *glyphPointer;
88 #define GetBitsL c = BitLeft (*leftChar++, lshift)
89 #define NGetBits1S(r) c = BitRight(*char1++ r, xoff1)
90 #define NGetBits1L(r) GetBitsL | BitRight(*char1++ r, xoff1)
91 #define NGetBits1U(r) c = *char1++ r
92 #define NGetBits2S(r) NGetBits1S(| BitRight(*char2++ r, widthGlyph))
93 #define NGetBits2L(r) NGetBits1L(| BitRight(*char2++ r, widthGlyph))
94 #define NGetBits2U(r) NGetBits1U(| BitRight(*char2++ r, widthGlyph))
95 #define NGetBits3S(r) NGetBits2S(| BitRight(*char3++ r, widthGlyph))
96 #define NGetBits3L(r) NGetBits2L(| BitRight(*char3++ r, widthGlyph))
97 #define NGetBits3U(r) NGetBits2U(| BitRight(*char3++ r, widthGlyph))
98 #define NGetBits4S(r) NGetBits3S(| BitRight(*char4++ r, widthGlyph))
99 #define NGetBits4L(r) NGetBits3L(| BitRight(*char4++ r, widthGlyph))
100 #define NGetBits4U(r) NGetBits3U(| BitRight(*char4++ r, widthGlyph))
101 #define NGetBits5S(r) NGetBits4S(| BitRight(*char5++ r, widthGlyph))
102 #define NGetBits5L(r) NGetBits4L(| BitRight(*char5++ r, widthGlyph))
103 #define NGetBits5U(r) NGetBits4U(| BitRight(*char5++ r, widthGlyph))
104 #define GetBits1S c = BitRight(*char1++, xoff1)
105 #define GetBits1L GetBitsL | BitRight(*char1++, xoff1)
106 #define GetBits1U c = *char1++
107 #define GetBits2S NGetBits1S(| BitRight(*char2++, widthGlyph))
108 #define GetBits2L NGetBits1L(| BitRight(*char2++, widthGlyph))
109 #define GetBits2U NGetBits1U(| BitRight(*char2++, widthGlyph))
110 #define GetBits3S NGetBits2S(| BitRight(*char3++, widthGlyph))
111 #define GetBits3L NGetBits2L(| BitRight(*char3++, widthGlyph))
112 #define GetBits3U NGetBits2U(| BitRight(*char3++, widthGlyph))
113 #define GetBits4S NGetBits3S(| BitRight(*char4++, widthGlyph))
114 #define GetBits4L NGetBits3L(| BitRight(*char4++, widthGlyph))
115 #define GetBits4U NGetBits3U(| BitRight(*char4++, widthGlyph))
116 #define GetBits5S NGetBits4S(| BitRight(*char5++, widthGlyph))
117 #define GetBits5L NGetBits4L(| BitRight(*char5++, widthGlyph))
118 #define GetBits5U NGetBits4U(| BitRight(*char5++, widthGlyph))
122 typedef unsigned int *glyphPointer;
127 #define GetBitsL WGetBitsL
128 #define GetBits1S WGetBits1S
129 #define GetBits1L WGetBits1L
130 #define GetBits1U WGetBits1U
132 #define GetBits2S GetBits1S Get1Bits (char2, tmpSrc) \
133 c |= BitRight(tmpSrc, xoff2);
134 #define GetBits2L GetBits1L Get1Bits (char2, tmpSrc) \
135 c |= BitRight(tmpSrc, xoff2);
136 #define GetBits2U GetBits1U Get1Bits (char2, tmpSrc) \
137 c |= BitRight(tmpSrc, xoff2);
139 #define GetBits3S GetBits2S Get1Bits (char3, tmpSrc) \
140 c |= BitRight(tmpSrc, xoff3);
141 #define GetBits3L GetBits2L Get1Bits (char3, tmpSrc) \
142 c |= BitRight(tmpSrc, xoff3);
143 #define GetBits3U GetBits2U Get1Bits (char3, tmpSrc) \
144 c |= BitRight(tmpSrc, xoff3);
146 #define GetBits4S GetBits3S Get1Bits (char4, tmpSrc) \
147 c |= BitRight(tmpSrc, xoff4);
148 #define GetBits4L GetBits3L Get1Bits (char4, tmpSrc) \
149 c |= BitRight(tmpSrc, xoff4);
150 #define GetBits4U GetBits3U Get1Bits (char4, tmpSrc) \
151 c |= BitRight(tmpSrc, xoff4);
153 #define GetBits5S GetBits4S Get1Bits (char5, tmpSrc) \
154 c |= BitRight(tmpSrc, xoff5);
155 #define GetBits5L GetBits4L Get1Bits (char5, tmpSrc) \
156 c |= BitRight(tmpSrc, xoff5);
157 #define GetBits5U GetBits4U Get1Bits (char5, tmpSrc) \
158 c |= BitRight(tmpSrc, xoff5);
163 extern unsigned long endtab[];
165 #define IncChar(c) (c = (glyphPointer) (((char *) c) + glyphBytes))
167 #define Get1Bits(ch,dst) glyphbits (ch, widthGlyph, glyphMask, dst); \
170 #define glyphbits(bits,width,mask,dst) getleftbits(bits,width,dst); \
173 #define WGetBitsL Get1Bits(leftChar,c); \
174 c = BitLeft (c, lshift);
175 #define WGetBits1S Get1Bits (char1, c) \
176 c = BitRight (c, xoff1);
177 #define WGetBits1L WGetBitsL Get1Bits (char1, tmpSrc) \
178 c |= BitRight (tmpSrc, xoff1);
179 #define WGetBits1U Get1Bits (char1, c)
182 #define WGetBitsL GetBitsL
183 #define WGetBits1S GetBits1S
184 #define WGetBits1L GetBits1L
185 #define WGetBits1U GetBits1U
189 # define GetBitsNS GetBits2S
190 # define GetBitsNL GetBits2L
191 # define GetBitsNU GetBits2U
192 # define LastChar char2
194 # define CFBTEGBLT8 cfbTEGlyphBlt8x2
198 # define GetBitsNS GetBits3S
199 # define GetBitsNL GetBits3L
200 # define GetBitsNU GetBits3U
201 # define LastChar char3
203 # define CFBTEGBLT8 cfbTEGlyphBlt8x3
207 # define GetBitsNS GetBits4S
208 # define GetBitsNL GetBits4L
209 # define GetBitsNU GetBits4U
210 # define LastChar char4
212 # define CFBTEGBLT8 cfbTEGlyphBlt8x4
216 # define GetBitsNS GetBits5S
217 # define GetBitsNL GetBits5L
218 # define GetBitsNU GetBits5U
219 # define LastChar char5
221 # define CFBTEGBLT8 cfbTEGlyphBlt8x5
225 /* another ugly giant macro */
226 #define SwitchEm switch (ew) \
240 StoreBits0 FirstStep StoreBits(1) \
247 StoreBits0 FirstStep StoreBits(1) Step StoreBits(2) \
254 StoreBits0 FirstStep StoreBits(1) Step \
255 StoreBits(2) Step StoreBits(3) \
262 StoreBits0 FirstStep StoreBits(1) Step \
263 StoreBits(2) Step StoreBits(3) Step \
271 StoreBits0 FirstStep StoreBits(1) Step \
272 StoreBits(2) Step StoreBits(3) Step \
273 StoreBits(4) Step StoreBits(5) \
280 StoreBits0 FirstStep StoreBits(1) Step \
281 StoreBits(2) Step StoreBits(3) Step \
282 StoreBits(4) Step StoreBits(5) Step \
290 StoreBits0 FirstStep StoreBits(1) Step \
291 StoreBits(2) Step StoreBits(3) Step \
292 StoreBits(4) Step StoreBits(5) Step \
293 StoreBits(6) Step StoreBits(7) \
299 #ifdef FAST_CONSTANT_OFFSET_MODE
300 #define StorePixels(o,p) dst[o] = p
301 #define Loop dst += widthDst;
303 #define StorePixels(o,p) *dst++ = (p)
304 #define Loop dst += widthLeft;
307 #define Step NextBitGroup(c);
309 #if (BITMAP_BIT_ORDER == MSBFirst)
310 #define StoreBits(o) StorePixels(o,GetPixelGroup(c));
311 #define FirstStep Step
314 #define StoreBits(o) StorePixels(o,cfb8Pixels[(c) & PGSZBMSK]);
315 #define FirstStep Step
316 #else /* PGSZ == 32 */
317 #define StoreBits(o) StorePixels(o,*((unsigned long *) (((char *) cfb8Pixels) + (c & 0x3c))));
318 #define FirstStep c = BitLeft (c, 2);
320 #endif /* BITMAP_BIT_ORDER */
324 CFBTEGBLT8 (pDrawable, pGC, xInit, yInit, nglyph, ppci, pglyphBase)
325 DrawablePtr pDrawable;
329 CharInfoPtr *ppci; /* array of character info */
330 pointer pglyphBase; /* start of array of glyphs */
332 register unsigned long c;
333 register unsigned long *dst;
334 register unsigned long leftMask, rightMask;
337 register glyphPointer char1;
338 register glyphPointer char2;
340 register glyphPointer char3;
343 register glyphPointer char4;
346 register glyphPointer char5;
349 int xoff2, xoff3, xoff4, xoff5;
352 FontPtr pfont = pGC->font;
353 unsigned long *dstLine;
354 glyphPointer oldRightChar;
355 unsigned long *pdstBase;
356 glyphPointer leftChar;
357 int widthDst, widthLeft;
362 BoxRec bbox; /* for clipping */
366 register unsigned long glyphMask;
367 register unsigned long tmpSrc;
368 register int glyphBytes;
371 widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
372 h = FONTASCENT(pfont) + FONTDESCENT(pfont);
375 x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x;
376 y = yInit - FONTASCENT(pfont) + pDrawable->y;
378 bbox.x2 = x + (widthGlyph * nglyph);
382 switch (RECT_IN_REGION(pGC->pScreen, cfbGetCompositeClip(pGC), &bbox))
385 cfbImageGlyphBlt8(pDrawable, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
390 if (!cfb8CheckPixels (pGC->fgPixel, pGC->bgPixel))
391 cfb8SetPixels (pGC->fgPixel, pGC->bgPixel);
395 cfbGetLongWidthAndPointer(pDrawable, widthDst, pdstBase)
398 widthGlyphs = widthGlyph << 1;
401 widthGlyphs = widthGlyph << 2;
403 widthGlyphs = widthGlyph * NGLYPHS;
408 glyphMask = endtab[widthGlyph];
409 glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci);
412 pdstBase += y * widthDst;
414 if (widthGlyphs <= 32)
416 while (nglyph >= NGLYPHS)
420 dstLine = pdstBase + (x >> PWSH);
422 char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
423 char2 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
425 xoff2 = xoff1 + widthGlyph;
428 char3 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
430 xoff3 = xoff2 + widthGlyph;
434 char4 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
436 xoff4 = xoff3 + widthGlyph;
440 char5 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
442 xoff5 = xoff4 + widthGlyph;
445 oldRightChar = LastChar;
449 ew = ((widthGlyphs - (PGSZB - xoff1)) >> PWSH) + 1;
450 #ifndef FAST_CONSTANT_OFFSET_MODE
451 widthLeft = widthDst - ew;
455 leftMask = cfbendtab[xoff1];
456 rightMask = cfbstarttab[xoff1];
458 #define StoreBits0 StorePixels (0,dst[0] & leftMask | \
459 GetPixelGroup(c) & rightMask);
460 #define GetBits GetBitsNS
470 lshift = widthGlyph - xoff1;
472 #define StoreBits0 StorePixels (0,GetPixelGroup(c));
473 #define GetBits GetBitsNL
484 #if NGLYPHS == 4 && PGSZ == 32
485 ew = widthGlyph; /* widthGlyphs >> 2 */
487 ew = widthGlyphs >> PWSH;
489 #ifndef FAST_CONSTANT_OFFSET_MODE
490 widthLeft = widthDst - ew;
493 #define StoreBits0 StorePixels (0,GetPixelGroup(c));
494 #define GetBits GetBitsNU
503 leftChar = oldRightChar;
508 char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
510 dstLine = pdstBase + (x >> PWSH);
511 oldRightChar = char1;
515 ew = ((widthGlyph - (PGSZB - xoff1)) >> PWSH) + 1;
516 #ifndef FAST_CONSTANT_OFFSET_MODE
517 widthLeft = widthDst - ew;
521 leftMask = cfbendtab[xoff1];
522 rightMask = cfbstarttab[xoff1];
524 #define StoreBits0 StorePixels (0,dst[0] & leftMask | GetPixelGroup(c) & rightMask);
525 #define GetBits WGetBits1S
534 lshift = widthGlyph - xoff1;
536 #define StoreBits0 StorePixels (0,GetPixelGroup(c));
537 #define GetBits WGetBits1L
547 ew = widthGlyph >> PWSH;
549 #ifndef FAST_CONSTANT_OFFSET_MODE
550 widthLeft = widthDst - ew;
553 #define StoreBits0 StorePixels (0,GetPixelGroup(c));
554 #define GetBits WGetBits1U
563 leftChar = oldRightChar;
566 * draw the tail of the last character
571 rightMask = cfbstarttab[xoff1];
572 leftMask = cfbendtab[xoff1];
573 lshift = widthGlyph - xoff1;
574 dst = pdstBase + (x >> PWSH);
579 *dst = (*dst & rightMask) | (GetPixelGroup(c) & leftMask);
584 #endif /* PSZ == 8 */