]> git.sesse.net Git - rdpsrv/blob - Xserver/programs/Xserver/cfb/cfbglblt8.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / programs / Xserver / cfb / cfbglblt8.c
1 /* $XConsortium: cfbglblt8.c,v 5.31 94/04/17 20:28:51 dpw Exp $ */
2 /* $XFree86: xc/programs/Xserver/cfb/cfbglblt8.c,v 3.1 1996/08/13 11:27:34 dawes Exp $ */
3 /*
4
5 Copyright (c) 1989  X Consortium
6
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:
13
14 The above copyright notice and this permission notice shall be included in
15 all copies or substantial portions of the Software.
16
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.
23
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.
27 */
28
29 /*
30  * Poly glyph blt.  Accepts an arbitrary font <= 32 bits wide, in Copy mode
31  * only.
32  */
33
34 #include        "X.h"
35 #include        "Xmd.h"
36 #include        "Xproto.h"
37 #include        "cfb.h"
38 #include        "fontstruct.h"
39 #include        "dixfontstr.h"
40 #include        "gcstruct.h"
41 #include        "windowstr.h"
42 #include        "scrnintstr.h"
43 #include        "pixmapstr.h"
44 #include        "regionstr.h"
45 #include        "cfbmskbits.h"
46 #include        "cfb8bit.h"
47
48 #define BOX_OVERLAP(box1, box2, xoffset, yoffset) \
49         ((box1)->x1 <= ((int) (box2)->x2 + (xoffset)) && \
50          ((int) (box2)->x1 + (xoffset)) <= (box1)->x2 && \
51          (box1)->y1 <= ((int) (box2)->y2 + (yoffset)) && \
52          ((int) (box2)->y1 + (yoffset)) <= (box1)->y2)
53
54 #define BOX_CONTAINS(box1, box2, xoffset, yoffset) \
55         ((box1)->x1 <= ((int) (box2)->x1 + (xoffset)) && \
56          ((int) (box2)->x2 + (xoffset)) <= (box1)->x2 && \
57          (box1)->y1 <= ((int) (box2)->y1 + (yoffset)) && \
58          ((int) (box2)->y2 + (yoffset)) <= (box1)->y2)
59
60 #if defined(FOUR_BIT_CODE) || defined(WriteBitGroup) && !defined(GLYPHROP)
61
62 #if GLYPHPADBYTES != 4
63 #define USE_LEFTBITS
64 #endif
65
66 #ifdef USE_LEFTBITS
67 typedef unsigned char   *glyphPointer;
68 extern unsigned long endtab[];
69
70 #define GlyphBits(bits,width,dst)       getleftbits(bits,width,dst); \
71                                         (dst) &= widthMask; \
72                                         (bits) += widthGlyph;
73 #define GlyphBitsS(bits,width,dst,off)  GlyphBits(bits,width,dst); \
74                                         dst = BitRight (dst, off);
75 #else
76 typedef CARD32  *glyphPointer;
77
78 #define GlyphBits(bits,width,dst)       dst = *bits++;
79 #define GlyphBitsS(bits,width,dst,off)  dst = BitRight(*bits++, off);
80 #endif
81
82 #ifdef GLYPHROP
83 #define cfbPolyGlyphBlt8        cfbPolyGlyphRop8
84 #define cfbPolyGlyphBlt8Clipped cfbPolyGlyphRop8Clipped
85
86 #undef WriteBitGroup
87 #define WriteBitGroup(dst,pixel,bits)   RRopBitGroup(dst,bits)
88
89 #endif
90
91 static void cfbPolyGlyphBlt8Clipped();
92
93 #if defined(HAS_STIPPLE_CODE) && !defined(GLYPHROP) && !defined(USE_LEFTBITS)
94 #define USE_STIPPLE_CODE
95 #endif
96
97 #if defined(__GNUC__) && !defined(GLYPHROP) && (defined(mc68020) || defined(mc68000) || defined(__mc68000__)) && PSZ == 8 && !defined(USE_LEFTBITS)
98 #ifdef USE_STIPPLE_CODE
99 #undef USE_STIPPLE_CODE
100 #endif
101 #include "stip68kgnu.h"
102 #endif
103
104 #if PSZ == 24
105 #define DST_INC     3
106 #else
107 #define DST_INC     (PGSZB >> PWSH)
108 #endif
109
110 /*  cfbStippleStack/cfbStippleStackTE are coded in assembly language.
111  *  They are only provided on some architecures.
112  */
113 #ifdef USE_STIPPLE_CODE
114 extern void             cfbStippleStack (), cfbStippleStackTE ();
115 #endif
116
117 void
118 cfbPolyGlyphBlt8 (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
119     DrawablePtr pDrawable;
120     GCPtr       pGC;
121     int         x, y;
122     unsigned int nglyph;
123     CharInfoPtr *ppci;          /* array of character info */
124     pointer     pglyphBase;     /* start of array of glyphs */
125 {
126     register unsigned long  c;
127 #ifndef GLYPHROP
128     register unsigned long  pixel;
129 #endif
130     register unsigned long  *dst;
131     register glyphPointer   glyphBits;
132     register int            xoff;
133
134     FontPtr             pfont = pGC->font;
135     CharInfoPtr         pci;
136     unsigned long       *dstLine;
137     unsigned long       *pdstBase;
138     int                 hTmp;
139     int                 bwidthDst;
140     int                 widthDst;
141     int                 h;
142     int                 ew;
143     BoxRec              bbox;           /* for clipping */
144     int                 widthDiff;
145     int                 w;
146     RegionPtr           clip;
147     BoxPtr              extents;
148 #ifdef USE_LEFTBITS
149     int                 widthGlyph;
150     unsigned long       widthMask;
151 #endif
152 #ifndef STIPPLE
153 #ifdef USE_STIPPLE_CODE
154     void                (*stipple)();
155
156     stipple = cfbStippleStack;
157     if (FONTCONSTMETRICS(pfont))
158         stipple = cfbStippleStackTE;
159 #endif
160 #endif
161     
162     x += pDrawable->x;
163     y += pDrawable->y;
164
165     /* compute an approximate (but covering) bounding box */
166     bbox.x1 = 0;
167     if ((ppci[0]->metrics.leftSideBearing < 0))
168         bbox.x1 = ppci[0]->metrics.leftSideBearing;
169     h = nglyph - 1;
170     w = ppci[h]->metrics.rightSideBearing;
171     while (--h >= 0)
172         w += ppci[h]->metrics.characterWidth;
173     bbox.x2 = w;
174     bbox.y1 = -FONTMAXBOUNDS(pfont,ascent);
175     bbox.y2 = FONTMAXBOUNDS(pfont,descent);
176
177     clip = cfbGetCompositeClip(pGC);
178     extents = &clip->extents;
179
180     if (!clip->data) 
181     {
182         if (!BOX_CONTAINS(extents, &bbox, x, y))
183         {
184             if (BOX_OVERLAP (extents, &bbox, x, y))
185                 cfbPolyGlyphBlt8Clipped(pDrawable, pGC, x, y,
186                                         nglyph, ppci, pglyphBase);
187             return;
188         }
189     }
190     else
191     {
192         /* check to make sure some of the text appears on the screen */
193         if (!BOX_OVERLAP (extents, &bbox, x, y))
194             return;
195     
196         bbox.x1 += x;
197         bbox.x2 += x;
198         bbox.y1 += y;
199         bbox.y2 += y;
200     
201         switch (RECT_IN_REGION(pGC->pScreen, clip, &bbox))
202         {
203           case rgnPART:
204             cfbPolyGlyphBlt8Clipped(pDrawable, pGC, x, y,
205                                     nglyph, ppci, pglyphBase);
206           case rgnOUT:
207             return;
208         }
209     }
210
211 #ifdef GLYPHROP
212     cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
213 #else
214     pixel = cfbGetGCPrivate(pGC)->xor;
215 #endif
216
217     cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, unsigned long)
218
219     widthDst = bwidthDst / PGSZB;
220     while (nglyph--)
221     {
222         pci = *ppci++;
223         glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci);
224         xoff = x + pci->metrics.leftSideBearing;
225 #if PSZ == 24
226         dstLine = pdstBase + (y - pci->metrics.ascent) * widthDst +((xoff>> 2)*3);
227 #else
228         dstLine = pdstBase +
229                   (y - pci->metrics.ascent) * widthDst + (xoff >> PWSH);
230 #endif
231         x += pci->metrics.characterWidth;
232         if (hTmp = pci->metrics.descent + pci->metrics.ascent)
233         {
234 #if PSZ == 24
235             xoff &= 0x03;
236 #else
237             xoff &= PIM;
238 #endif /* PSZ == 24 */
239 #ifdef STIPPLE
240             STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
241 #else
242 #ifdef USE_STIPPLE_CODE
243             (*stipple)(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
244 #else
245 #ifdef USE_LEFTBITS
246             w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
247             widthGlyph = PADGLYPHWIDTHBYTES(w);
248             widthMask = endtab[w];
249 #endif
250             do {
251                 dst = dstLine;
252                 dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
253                 GlyphBits(glyphBits, w, c)
254                 WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
255                 dst += DST_INC;
256                 c = BitLeft(c,PGSZB - xoff);
257                 while (c)
258                 {
259                     WriteBitGroup(dst, pixel, GetBitGroup(c));
260                     NextBitGroup(c);
261                     dst += DST_INC;
262                 }
263             } while (--hTmp);
264 #endif /* USE_STIPPLE_CODE else */
265 #endif /* STIPPLE else */
266         }
267     }
268 }
269
270 static void
271 cfbPolyGlyphBlt8Clipped (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase)
272     DrawablePtr pDrawable;
273     GCPtr       pGC;
274     int         x, y;
275     unsigned int nglyph;
276     CharInfoPtr *ppci;          /* array of character info */
277     unsigned char *pglyphBase;  /* start of array of glyphs */
278 {
279     register unsigned long  c;
280 #ifndef GLYPHROP
281     register unsigned long  pixel;
282 #endif
283     register unsigned long  *dst;
284     register glyphPointer   glyphBits;
285     register int            xoff;
286     unsigned long           c1;
287
288     CharInfoPtr         pci;
289     FontPtr             pfont = pGC->font;
290     unsigned long       *dstLine;
291     unsigned long       *pdstBase;
292     CARD32              *cTmp, *clips;
293     int                 maxAscent, maxDescent;
294     int                 minLeftBearing;
295     int                 hTmp;
296     int                 widthDst;
297     int                 bwidthDst;
298     int                 ew;
299     int                 xG, yG;
300     BoxPtr              pBox;
301     int                 numRects;
302     int                 widthDiff;
303     int                 w;
304     RegionPtr           pRegion;
305     int                 yBand;
306 #ifdef GLYPHROP
307     unsigned long       bits;
308 #endif
309 #ifdef USE_LEFTBITS
310     int                 widthGlyph;
311     unsigned long       widthMask;
312 #endif
313
314 #ifdef GLYPHROP
315     cfb8CheckStipple (pGC->alu, pGC->fgPixel, pGC->planemask);
316 #else
317     pixel = cfbGetGCPrivate(pGC)->xor;
318 #endif
319     
320     cfbGetTypedWidthAndPointer (pDrawable, bwidthDst, pdstBase, char, unsigned long)
321
322     widthDst = bwidthDst / PGSZB;
323     maxAscent = FONTMAXBOUNDS(pfont,ascent);
324     maxDescent = FONTMAXBOUNDS(pfont,descent);
325     minLeftBearing = FONTMINBOUNDS(pfont,leftSideBearing);
326
327     pRegion = cfbGetCompositeClip(pGC);
328
329     pBox = REGION_RECTS(pRegion);
330     numRects = REGION_NUM_RECTS (pRegion);
331     while (numRects && pBox->y2 <= y - maxAscent)
332     {
333         ++pBox;
334         --numRects;
335     }
336     if (!numRects || pBox->y1 >= y + maxDescent)
337         return;
338     yBand = pBox->y1;
339     while (numRects && pBox->y1 == yBand && pBox->x2 <= x + minLeftBearing)
340     {
341         ++pBox;
342         --numRects;
343     }
344     if (!numRects)
345         return;
346     clips = (CARD32 *)ALLOCATE_LOCAL ((maxAscent + maxDescent) *
347                                                 sizeof (CARD32));
348     while (nglyph--)
349     {
350         pci = *ppci++;
351         glyphBits = (glyphPointer) FONTGLYPHBITS(pglyphBase,pci);
352         w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
353         xG = x + pci->metrics.leftSideBearing;
354         yG = y - pci->metrics.ascent;
355         x += pci->metrics.characterWidth;
356         if (hTmp = pci->metrics.descent + pci->metrics.ascent)
357         {
358 #if PSZ == 24
359             dstLine = pdstBase + yG * widthDst + ((xG>> 2)*3);
360             /* never use (xG*3)>>2 */
361 #else
362             dstLine = pdstBase + yG * widthDst + (xG >> PWSH);
363 #endif
364 #if PSZ == 24
365             xoff = xG & 3;
366 #else
367             xoff = xG & PIM;
368 #endif
369 #ifdef USE_LEFTBITS
370             w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
371             widthGlyph = PADGLYPHWIDTHBYTES(w);
372             widthMask = endtab[w];
373 #endif
374             switch (cfb8ComputeClipMasks32 (pBox, numRects, xG, yG, w, hTmp, clips))
375             {
376             case rgnPART:
377 #ifdef USE_LEFTBITS
378                 cTmp = clips;
379                 do {
380                     dst = dstLine;
381                     dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
382                     GlyphBits(glyphBits, w, c)
383                     c &= *cTmp++;
384                     if (c)
385                     {
386                         WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
387                         c = BitLeft(c,PGSZB - xoff); 
388                         dst += DST_INC;
389                         while (c)
390                         {
391                             WriteBitGroup(dst, pixel, GetBitGroup(c));
392                             NextBitGroup(c);
393                             dst += DST_INC;
394                         }
395                     }
396                 } while (--hTmp);
397                 break;
398 #else /* !USE_LEFT_BITS */
399                 {
400                     int h;
401     
402                     h = hTmp;
403                     do
404                     {
405                         --h;
406                         clips[h] = clips[h] & glyphBits[h];
407                     } while (h);
408                 }
409                 glyphBits = clips;
410                 /* fall through */
411 #endif /* USE_LEFT_BITS */
412             case rgnIN:
413 #ifdef STIPPLE
414                 STIPPLE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
415 #else
416 #ifdef USE_STIPPLE_CODE
417                 cfbStippleStackTE(dstLine,glyphBits,pixel,bwidthDst,hTmp,xoff);
418 #else
419                 do {
420                     dst = dstLine;
421                     dstLine = (unsigned long *) (((char *) dstLine) + bwidthDst);
422                     GlyphBits(glyphBits, w, c)
423                     if (c)
424                     {
425                         /* This code originally could read memory locations
426                          * that were not mapped. Hence we have to check the
427                          * trailing bits to see whether they are zero and if
428                          * then skip them correctly. This is no problem for
429                          * the GXcopy case, since there only the pixels that
430                          * are non-zero are written ...
431                          */
432 #ifndef GLYPHROP
433                         WriteBitGroup(dst, pixel, GetBitGroup(BitRight(c,xoff)));
434                         c = BitLeft(c,PGSZB - xoff);
435                         dst += DST_INC;
436 #else /* GLYPHROP */
437                         if (bits = GetBitGroup(BitRight(c,xoff)))
438                           WriteBitGroup(dst, pixel, bits);
439                         c = BitLeft(c,PGSZB - xoff);
440                         dst += DST_INC;
441
442                         while (c && ((bits = GetBitGroup(c)) == 0))
443                         {
444                             NextBitGroup(c);
445                             dst += DST_INC;
446                         } 
447 #endif /* GLYPHROP */
448                         while (c)
449                         {
450                             WriteBitGroup(dst, pixel, GetBitGroup(c));
451                             NextBitGroup(c);
452                             dst += DST_INC;
453                         }
454                     }
455                 } while (--hTmp);
456 #endif /* USE_STIPPLE_CODE else */
457 #endif /* STIPPLE else */
458                 break;
459             }
460         }
461     }
462     DEALLOCATE_LOCAL (clips);
463 }
464
465 #endif /* FOUR_BIT_CODE */