]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbteblt8.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbteblt8.c
1 /*
2  * TEGblt - ImageText expanded glyph fonts only.  For
3  * 8 bit displays, in Copy mode with no clipping.
4  */
5
6 /*
7
8 Copyright (c) 1989  X Consortium
9
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:
16
17 The above copyright notice and this permission notice shall be included in
18 all copies or substantial portions of the Software.
19
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.
26
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.
30 */
31
32 /* $XConsortium: cfbteblt8.c,v 5.24 94/09/29 15:26:00 dpw Exp $ */
33
34 #if PSZ == 8
35
36 #include        "X.h"
37 #include        "Xmd.h"
38 #include        "Xproto.h"
39 #include        "cfb.h"
40 #include        "fontstruct.h"
41 #include        "dixfontstr.h"
42 #include        "gcstruct.h"
43 #include        "windowstr.h"
44 #include        "scrnintstr.h"
45 #include        "pixmapstr.h"
46 #include        "regionstr.h"
47 #include        "cfbmskbits.h"
48 #include        "cfb8bit.h"
49
50 /*
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.
56  */
57
58 #ifndef NGLYPHS
59 #define NGLYPHS 4
60 #define DO_COMMON
61 #endif
62
63 #ifdef DO_COMMON
64 #define CFBTEGBLT8 cfbTEGlyphBlt8
65 #endif
66
67 /*
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
70  */
71
72 #if ((BITMAP_BIT_ORDER == LSBFirst && NGLYPHS >= 4) || GLYPHPADBYTES == 4)
73
74 #if GLYPHPADBYTES == 1
75 typedef unsigned char   *glyphPointer;
76 #define USE_LEFTBITS
77 #endif
78
79 #if GLYPHPADBYTES == 2
80 typedef unsigned short  *glyphPointer;
81 #define USE_LEFTBITS
82 #endif
83
84 #if GLYPHPADBYTES == 4
85 typedef unsigned int    *glyphPointer;
86 #endif
87
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))
119
120 #else
121
122 typedef unsigned int    *glyphPointer;
123
124 #define USE_LEFTBITS
125 #define ALL_LEFTBITS
126
127 #define GetBitsL    WGetBitsL
128 #define GetBits1S   WGetBits1S
129 #define GetBits1L   WGetBits1L
130 #define GetBits1U   WGetBits1U
131
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);
138
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);
145
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);
152
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);
159
160 #endif
161
162 #ifdef USE_LEFTBITS
163 extern unsigned long endtab[];
164
165 #define IncChar(c)  (c = (glyphPointer) (((char *) c) + glyphBytes))
166
167 #define Get1Bits(ch,dst)    glyphbits (ch, widthGlyph, glyphMask, dst); \
168                             IncChar (ch);
169
170 #define glyphbits(bits,width,mask,dst)  getleftbits(bits,width,dst); \
171                                         dst &= mask;
172
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)
180
181 #else
182 #define WGetBitsL   GetBitsL
183 #define WGetBits1S  GetBits1S
184 #define WGetBits1L  GetBits1L
185 #define WGetBits1U  GetBits1U
186 #endif
187
188 #if NGLYPHS == 2
189 # define GetBitsNS GetBits2S
190 # define GetBitsNL GetBits2L
191 # define GetBitsNU GetBits2U
192 # define LastChar char2
193 #ifndef CFBTEGBLT8
194 # define CFBTEGBLT8 cfbTEGlyphBlt8x2
195 #endif
196 #endif
197 #if NGLYPHS == 3
198 # define GetBitsNS GetBits3S
199 # define GetBitsNL GetBits3L
200 # define GetBitsNU GetBits3U
201 # define LastChar char3
202 #ifndef CFBTEGBLT8
203 # define CFBTEGBLT8 cfbTEGlyphBlt8x3
204 #endif
205 #endif
206 #if NGLYPHS == 4
207 # define GetBitsNS GetBits4S
208 # define GetBitsNL GetBits4L
209 # define GetBitsNU GetBits4U
210 # define LastChar char4
211 #ifndef CFBTEGBLT8
212 # define CFBTEGBLT8 cfbTEGlyphBlt8x4
213 #endif
214 #endif
215 #if NGLYPHS == 5
216 # define GetBitsNS GetBits5S
217 # define GetBitsNL GetBits5L
218 # define GetBitsNU GetBits5U
219 # define LastChar char5
220 #ifndef CFBTEGBLT8
221 # define CFBTEGBLT8 cfbTEGlyphBlt8x5
222 #endif
223 #endif
224
225 /* another ugly giant macro */
226 #define SwitchEm    switch (ew) \
227                     { \
228                     case 0: \
229                         break; \
230                     case 1: \
231                         while (hTmp--) { \
232                             GetBits; \
233                             StoreBits0 \
234                             Loop \
235                         } \
236                         break; \
237                     case 2: \
238                         while (hTmp--) { \
239                             GetBits; \
240                             StoreBits0 FirstStep StoreBits(1) \
241                             Loop \
242                         } \
243                         break; \
244                     case 3: \
245                         while (hTmp--) { \
246                             GetBits; \
247                             StoreBits0 FirstStep StoreBits(1) Step StoreBits(2) \
248                             Loop \
249                         } \
250                         break; \
251                     case 4: \
252                         while (hTmp--) { \
253                             GetBits; \
254                             StoreBits0 FirstStep StoreBits(1) Step \
255                             StoreBits(2) Step StoreBits(3) \
256                             Loop \
257                         } \
258                         break; \
259                     case 5: \
260                         while (hTmp--) { \
261                             GetBits; \
262                             StoreBits0 FirstStep StoreBits(1) Step \
263                             StoreBits(2) Step StoreBits(3) Step \
264                             StoreBits(4) \
265                             Loop \
266                         } \
267                         break; \
268                     case 6: \
269                         while (hTmp--) { \
270                             GetBits; \
271                             StoreBits0 FirstStep StoreBits(1) Step \
272                             StoreBits(2) Step StoreBits(3) Step \
273                             StoreBits(4) Step StoreBits(5) \
274                             Loop \
275                         } \
276                         break; \
277                     case 7: \
278                         while (hTmp--) { \
279                             GetBits; \
280                             StoreBits0 FirstStep StoreBits(1) Step \
281                             StoreBits(2) Step StoreBits(3) Step \
282                             StoreBits(4) Step StoreBits(5) Step \
283                             StoreBits(6) \
284                             Loop \
285                         } \
286                         break; \
287                     case 8: \
288                         while (hTmp--) { \
289                             GetBits; \
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) \
294                             Loop \
295                         } \
296                         break; \
297                     }
298
299 #ifdef FAST_CONSTANT_OFFSET_MODE
300 #define StorePixels(o,p)    dst[o] = p
301 #define Loop                dst += widthDst;
302 #else
303 #define StorePixels(o,p)    *dst++ = (p)
304 #define Loop                dst += widthLeft;
305 #endif
306
307 #define Step                NextBitGroup(c);
308
309 #if (BITMAP_BIT_ORDER == MSBFirst)
310 #define StoreBits(o)    StorePixels(o,GetPixelGroup(c));
311 #define FirstStep       Step
312 #else
313 #if PGSZ == 64
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);
319 #endif /* PGSZ */
320 #endif /* BITMAP_BIT_ORDER */
321
322
323 void
324 CFBTEGBLT8 (pDrawable, pGC, xInit, yInit, nglyph, ppci, pglyphBase)
325     DrawablePtr pDrawable;
326     GC          *pGC;
327     int         xInit, yInit;
328     unsigned int nglyph;
329     CharInfoPtr *ppci;          /* array of character info */
330     pointer     pglyphBase;     /* start of array of glyphs */
331 {
332     register unsigned long  c;
333     register unsigned long  *dst;
334     register unsigned long  leftMask, rightMask;
335     register int            hTmp;
336     register int            xoff1;
337     register glyphPointer   char1;
338     register glyphPointer   char2;
339 #if NGLYPHS >= 3
340     register glyphPointer   char3;
341 #endif
342 #if NGLYPHS >= 4
343     register glyphPointer   char4;
344 #endif
345 #if NGLYPHS >= 5
346     register glyphPointer   char5;
347 #endif
348 #ifdef ALL_LEFTBITS
349     int xoff2, xoff3, xoff4, xoff5;
350 #endif
351
352     FontPtr             pfont = pGC->font;
353     unsigned long       *dstLine;
354     glyphPointer        oldRightChar;
355     unsigned long       *pdstBase;
356     glyphPointer        leftChar;
357     int                 widthDst, widthLeft;
358     int                 widthGlyph;
359     int                 h;
360     int                 ew;
361     int                 x, y;
362     BoxRec              bbox;           /* for clipping */
363     int                 lshift;
364     int                 widthGlyphs;
365 #ifdef USE_LEFTBITS
366     register unsigned long  glyphMask;
367     register unsigned long  tmpSrc;
368     register int            glyphBytes;
369 #endif
370
371     widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
372     h = FONTASCENT(pfont) + FONTDESCENT(pfont);
373     if (!h)
374         return;
375     x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x;
376     y = yInit - FONTASCENT(pfont) + pDrawable->y;
377     bbox.x1 = x;
378     bbox.x2 = x + (widthGlyph * nglyph);
379     bbox.y1 = y;
380     bbox.y2 = y + h;
381
382     switch (RECT_IN_REGION(pGC->pScreen,  cfbGetCompositeClip(pGC), &bbox))
383     {
384       case rgnPART:
385         cfbImageGlyphBlt8(pDrawable, pGC, xInit, yInit, nglyph, ppci, pglyphBase);
386       case rgnOUT:
387         return;
388     }
389
390     if (!cfb8CheckPixels (pGC->fgPixel, pGC->bgPixel))
391         cfb8SetPixels (pGC->fgPixel, pGC->bgPixel);
392
393     leftChar = 0;
394
395     cfbGetLongWidthAndPointer(pDrawable, widthDst, pdstBase)
396
397 #if NGLYPHS == 2
398     widthGlyphs = widthGlyph << 1;
399 #else
400 #if NGLYPHS == 4
401     widthGlyphs = widthGlyph << 2;
402 #else
403     widthGlyphs = widthGlyph * NGLYPHS;
404 #endif
405 #endif
406
407 #ifdef USE_LEFTBITS
408     glyphMask = endtab[widthGlyph];
409     glyphBytes = GLYPHWIDTHBYTESPADDED(*ppci);
410 #endif
411
412     pdstBase += y * widthDst;
413 #ifdef DO_COMMON
414     if (widthGlyphs <= 32)
415 #endif
416         while (nglyph >= NGLYPHS)
417         {
418             nglyph -= NGLYPHS;
419             hTmp = h;
420             dstLine = pdstBase + (x >> PWSH);
421             xoff1 = x & PIM;
422             char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
423             char2 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
424 #ifdef ALL_LEFTBITS
425             xoff2 = xoff1 + widthGlyph;
426 #endif
427 #if NGLYPHS >= 3
428             char3 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
429 #ifdef ALL_LEFTBITS
430             xoff3 = xoff2 + widthGlyph;
431 #endif
432 #endif
433 #if NGLYPHS >= 4
434             char4 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
435 #ifdef ALL_LEFTBITS
436             xoff4 = xoff3 + widthGlyph;
437 #endif
438 #endif
439 #if NGLYPHS >= 5
440             char5 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
441 #ifdef ALL_LEFTBITS
442             xoff5 = xoff4 + widthGlyph;
443 #endif
444 #endif
445             oldRightChar = LastChar;
446             dst = dstLine;
447             if (xoff1)
448             {
449                 ew = ((widthGlyphs - (PGSZB - xoff1)) >> PWSH) + 1;
450 #ifndef FAST_CONSTANT_OFFSET_MODE
451                 widthLeft = widthDst - ew;
452 #endif
453                 if (!leftChar)
454                 {
455                     leftMask = cfbendtab[xoff1];
456                     rightMask = cfbstarttab[xoff1];
457
458 #define StoreBits0      StorePixels (0,dst[0] & leftMask | \
459                                        GetPixelGroup(c) & rightMask);
460 #define GetBits GetBitsNS
461
462                     SwitchEm
463
464 #undef GetBits
465 #undef StoreBits0
466
467                 }
468                 else
469                 {
470                     lshift = widthGlyph - xoff1;
471     
472 #define StoreBits0  StorePixels (0,GetPixelGroup(c));
473 #define GetBits GetBitsNL
474     
475                     SwitchEm
476     
477 #undef GetBits
478 #undef StoreBits0
479     
480                 }
481             }
482             else
483             {
484 #if NGLYPHS == 4 && PGSZ == 32
485                 ew = widthGlyph;    /* widthGlyphs >> 2 */
486 #else
487                 ew = widthGlyphs >> PWSH;
488 #endif
489 #ifndef FAST_CONSTANT_OFFSET_MODE
490                 widthLeft = widthDst - ew;
491 #endif
492
493 #define StoreBits0  StorePixels (0,GetPixelGroup(c));
494 #define GetBits GetBitsNU
495
496                 SwitchEm
497
498 #undef GetBits
499 #undef StoreBits0
500
501             }
502             x += widthGlyphs;
503             leftChar = oldRightChar;
504         }
505     while (nglyph--)
506     {
507         xoff1 = x & PIM;
508         char1 = (glyphPointer) FONTGLYPHBITS(pglyphBase, *ppci++);
509         hTmp = h;
510         dstLine = pdstBase + (x >> PWSH);
511         oldRightChar = char1;
512         dst = dstLine;
513         if (xoff1)
514         {
515             ew = ((widthGlyph - (PGSZB - xoff1)) >> PWSH) + 1;
516 #ifndef FAST_CONSTANT_OFFSET_MODE
517             widthLeft = widthDst - ew;
518 #endif
519             if (!leftChar)
520             {
521                 leftMask = cfbendtab[xoff1];
522                 rightMask = cfbstarttab[xoff1];
523
524 #define StoreBits0      StorePixels (0,dst[0] & leftMask | GetPixelGroup(c) & rightMask);
525 #define GetBits WGetBits1S
526
527                 SwitchEm
528 #undef GetBits
529 #undef StoreBits0
530
531             }
532             else
533             {
534                 lshift = widthGlyph - xoff1;
535
536 #define StoreBits0  StorePixels (0,GetPixelGroup(c));
537 #define GetBits WGetBits1L
538
539                 SwitchEm
540 #undef GetBits
541 #undef StoreBits0
542
543             }
544         }
545         else
546         {
547             ew = widthGlyph >> PWSH;
548
549 #ifndef FAST_CONSTANT_OFFSET_MODE
550             widthLeft = widthDst - ew;
551 #endif
552
553 #define StoreBits0  StorePixels (0,GetPixelGroup(c));
554 #define GetBits WGetBits1U
555
556             SwitchEm
557
558 #undef GetBits
559 #undef StoreBits0
560
561         }
562         x += widthGlyph;
563         leftChar = oldRightChar;
564     }
565     /*
566      * draw the tail of the last character
567      */
568     xoff1 = x & PIM;
569     if (xoff1)
570     {
571         rightMask = cfbstarttab[xoff1];
572         leftMask = cfbendtab[xoff1];
573         lshift = widthGlyph - xoff1;
574         dst = pdstBase + (x >> PWSH);
575         hTmp = h;
576         while (hTmp--)
577         {
578             GetBitsL;
579             *dst = (*dst & rightMask) | (GetPixelGroup(c) & leftMask);
580             dst += widthDst;
581         }
582     }
583 }
584 #endif /* PSZ == 8 */