~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/ilbm/ilbmfillsp.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/ilbm/ilbmfillsp.c,v 3.1 1998/03/20 21:08:01 hohndel Exp $ */
 
2
/* Combined Purdue/PurduePlus patches, level 2.0, 1/17/89 */
 
3
/***********************************************************
 
4
 
 
5
Copyright (c) 1987  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
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 
30
 
 
31
                        All Rights Reserved
 
32
 
 
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.  
 
40
 
 
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
 
47
SOFTWARE.
 
48
 
 
49
******************************************************************/
 
50
/* $XConsortium: ilbmfillsp.c,v 5.13 94/04/17 20:28:21 dpw Exp $ */
 
51
 
 
52
/* Modified jun 95 by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
 
53
   to use interleaved bitplanes instead of normal bitplanes */
 
54
 
 
55
#include "X.h"
 
56
#include "Xmd.h"
 
57
#include "gcstruct.h"
 
58
#include "window.h"
 
59
#include "pixmapstr.h"
 
60
#include "scrnintstr.h"
 
61
#include "windowstr.h"
 
62
#include "ilbm.h"
 
63
#include "maskbits.h"
 
64
 
 
65
#include "mergerop.h"
 
66
 
 
67
#include "servermd.h"
 
68
#include "mi.h"
 
69
#include "mispans.h"
 
70
 
 
71
/* scanline filling for monochrome frame buffer
 
72
   written by drewry, oct 1986
 
73
 
 
74
   these routines all clip.  they assume that anything that has called
 
75
them has already translated the points (i.e. pGC->miTranslate is
 
76
non-zero, which is howit gets set in ilbmCreateGC().)
 
77
 
 
78
   the number of new scnalines created by clipping ==
 
79
MaxRectsPerBand * nSpans.
 
80
 
 
81
*/
 
82
 
 
83
 
 
84
void
 
85
ilbmSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
 
86
        DrawablePtr pDrawable;
 
87
        GCPtr           pGC;
 
88
        int                             nInit;                          /* number of spans to fill */
 
89
        DDXPointPtr pptInit;            /* pointer to list of start points */
 
90
        int                             *pwidthInit;            /* pointer to list of n widths */
 
91
        int             fSorted;
 
92
{
 
93
                                                                /* next three parameters are post-clip */
 
94
        int n;                                          /* number of spans to fill */
 
95
        register DDXPointPtr ppt;               /* pointer to list of start points */
 
96
        register int *pwidth;           /* pointer to list of n widths */
 
97
        PixelType *addrlBase;           /* pointer to start of bitmap */
 
98
        PixelType *pBase;
 
99
        int nlwidth;                            /* width in longwords of bitmap */
 
100
        register PixelType *addrl;/* pointer to current longword in bitmap */
 
101
        register int nlmiddle;
 
102
        register PixelType startmask;
 
103
        register PixelType endmask;
 
104
        int *pwidthFree;                                /* copies of the pointers to free */
 
105
        DDXPointPtr pptFree;
 
106
        int depthDst;
 
107
        int auxDst;
 
108
        int d;
 
109
        unsigned char *rrops;
 
110
 
 
111
        n = nInit * miFindMaxBand(pGC->pCompositeClip);
 
112
        pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
 
113
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
 
114
        if (!pptFree || !pwidthFree) {
 
115
                if (pptFree)
 
116
                        DEALLOCATE_LOCAL(pptFree);
 
117
                if (pwidthFree)
 
118
                        DEALLOCATE_LOCAL(pwidthFree);
 
119
                return;
 
120
        }
 
121
        pwidth = pwidthFree;
 
122
        ppt = pptFree;
 
123
        n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
 
124
                ppt, pwidth, fSorted);
 
125
 
 
126
        ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
 
127
                                                                                                        pBase);
 
128
        rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
 
129
        while (n--) {
 
130
                addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
131
 
 
132
                for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {  /* @@@ NEXT PLANE @@@ */
 
133
                        if (*pwidth) {
 
134
                                addrl = addrlBase;
 
135
 
 
136
                                switch (rrops[d]) {
 
137
                                        case RROP_BLACK:
 
138
                                                if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
139
                                                        /* all bits inside same longword */
 
140
                                                        maskpartialbits(ppt->x, *pwidth, startmask);
 
141
                                                                *addrl &= ~startmask;
 
142
                                                } else {
 
143
                                                        maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
144
                                                        if (startmask)
 
145
                                                                *addrl++ &= ~startmask;
 
146
                                                        Duff (nlmiddle, *addrl++ = 0x0);
 
147
                                                        if (endmask)
 
148
                                                                *addrl &= ~endmask;
 
149
                                                }
 
150
                                                break;
 
151
 
 
152
                                        case RROP_WHITE:
 
153
                                                if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
154
                                                        /* all bits inside same longword */
 
155
                                                        maskpartialbits(ppt->x, *pwidth, startmask);
 
156
                                                        *addrl |= startmask;
 
157
                                                } else {
 
158
                                                        maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
159
                                                        if (startmask)
 
160
                                                                *addrl++ |= startmask;
 
161
                                                        Duff (nlmiddle, *addrl++ = ~0);
 
162
                                                        if (endmask)
 
163
                                                                *addrl |= endmask;
 
164
                                                }
 
165
                                                break;
 
166
                                        case RROP_INVERT:
 
167
                                                if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
168
                                                        /* all bits inside same longword */
 
169
                                                        maskpartialbits(ppt->x, *pwidth, startmask);
 
170
                                                        *addrl ^= startmask;
 
171
                                                } else {
 
172
                                                        maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
173
                                                        if (startmask)
 
174
                                                                *addrl++ ^= startmask;
 
175
                                                        Duff (nlmiddle, *addrl++ ^= ~0);
 
176
                                                        if (endmask)
 
177
                                                                *addrl ^= endmask;
 
178
                                                }
 
179
                                                break;
 
180
                                        case RROP_NOP:
 
181
                                                break;
 
182
                                }
 
183
                        }
 
184
                }
 
185
                pwidth++;
 
186
                ppt++;
 
187
        }
 
188
        DEALLOCATE_LOCAL(pptFree);
 
189
        DEALLOCATE_LOCAL(pwidthFree);
 
190
}
 
191
 
 
192
void 
 
193
ilbmStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
 
194
        DrawablePtr pDrawable;
 
195
        GC *pGC;
 
196
        int nInit;                                              /* number of spans to fill */
 
197
        DDXPointPtr pptInit;            /* pointer to list of start points */
 
198
        int *pwidthInit;                                /* pointer to list of n widths */
 
199
        int fSorted;
 
200
{
 
201
                                                                /* next three parameters are post-clip */
 
202
        int n;                                          /* number of spans to fill */
 
203
        register DDXPointPtr ppt;               /* pointer to list of start points */
 
204
        register int *pwidth;           /* pointer to list of n widths */
 
205
        PixelType *addrlBase;           /* pointer to start of bitmap */
 
206
        PixelType *pBase;
 
207
        int nlwidth;                            /* width in longwords of bitmap */
 
208
        register PixelType *addrl;/* pointer to current longword in bitmap */
 
209
        register PixelType src;
 
210
        register int nlmiddle;
 
211
        register PixelType startmask;
 
212
        register PixelType endmask;
 
213
        PixmapPtr pStipple;
 
214
        PixelType *psrc;
 
215
        int tileHeight;
 
216
        int *pwidthFree;                                /* copies of the pointers to free */
 
217
        DDXPointPtr pptFree;
 
218
        int d;
 
219
        int depthDst;
 
220
        int auxDst;
 
221
        unsigned char *rrops;
 
222
 
 
223
        n = nInit * miFindMaxBand(pGC->pCompositeClip);
 
224
        pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
 
225
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
 
226
        if (!pptFree || !pwidthFree) {
 
227
                if (pptFree)
 
228
                        DEALLOCATE_LOCAL(pptFree);
 
229
                if (pwidthFree)
 
230
                        DEALLOCATE_LOCAL(pwidthFree);
 
231
                return;
 
232
        }
 
233
        pwidth = pwidthFree;
 
234
        ppt = pptFree;
 
235
        n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
 
236
                ppt, pwidth, fSorted);
 
237
 
 
238
        ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
 
239
                                                                                                        pBase);
 
240
 
 
241
        pStipple = pGC->pRotatedPixmap;
 
242
        tileHeight = pStipple->drawable.height;
 
243
        psrc = (PixelType *)(pStipple->devPrivate.ptr);
 
244
 
 
245
        rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
 
246
 
 
247
        while (n--) {
 
248
                src = psrc[ppt->y % tileHeight];
 
249
                addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
250
                for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {  /* @@@ NEXT PLANE @@@ */
 
251
                        addrl = addrlBase;
 
252
 
 
253
                        switch (rrops[d]) {
 
254
                                case RROP_BLACK:
 
255
                                        /* all bits inside same longword */
 
256
                                        if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
257
                                                maskpartialbits(ppt->x, *pwidth, startmask);
 
258
                                                *addrl &= ~(src & startmask);
 
259
                                        } else {
 
260
                                                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
261
                                                if (startmask)
 
262
                                                        *addrl++ &= ~(src & startmask);
 
263
                                                Duff (nlmiddle, *addrl++ &= ~src);
 
264
                                                if (endmask)
 
265
                                                        *addrl &= ~(src & endmask);
 
266
                                        }
 
267
                                        break;
 
268
                                case RROP_WHITE:
 
269
                                        /* all bits inside same longword */
 
270
                                        if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
271
                                                maskpartialbits(ppt->x, *pwidth, startmask);
 
272
                                                *addrl |= (src & startmask);
 
273
                                        } else {
 
274
                                                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
275
                                                if (startmask)
 
276
                                                        *addrl++ |= (src & startmask);
 
277
                                                Duff (nlmiddle, *addrl++ |= src);
 
278
                                                if (endmask)
 
279
                                                        *addrl |= (src & endmask);
 
280
                                        }
 
281
                                        break;
 
282
                                case RROP_INVERT:
 
283
                                        /* all bits inside same longword */
 
284
                                        if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
285
                                                maskpartialbits(ppt->x, *pwidth, startmask);
 
286
                                                *addrl ^= (src & startmask);
 
287
                                        } else {
 
288
                                                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
289
                                                if (startmask)
 
290
                                                        *addrl++ ^= (src & startmask);
 
291
                                                Duff (nlmiddle, *addrl++ ^= src);
 
292
                                                if (endmask)
 
293
                                                        *addrl ^= (src & endmask);
 
294
                                        }
 
295
                                        break;
 
296
 
 
297
                                case RROP_NOP:
 
298
                                        break;
 
299
                        }
 
300
                }
 
301
                pwidth++;
 
302
                ppt++;
 
303
        }
 
304
        DEALLOCATE_LOCAL(pptFree);
 
305
        DEALLOCATE_LOCAL(pwidthFree);
 
306
}
 
307
 
 
308
void
 
309
ilbmTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
 
310
        DrawablePtr pDrawable;
 
311
        GC *pGC;
 
312
        int nInit;                                              /* number of spans to fill */
 
313
        DDXPointPtr pptInit;            /* pointer to list of start points */
 
314
        int *pwidthInit;                                /* pointer to list of n widths */
 
315
        int fSorted;
 
316
{
 
317
                                                                /* next three parameters are post-clip */
 
318
        int n;                                          /* number of spans to fill */
 
319
        register DDXPointPtr ppt;               /* pointer to list of start points */
 
320
        register int *pwidth;           /* pointer to list of n widths */
 
321
        PixelType *addrlBase;           /* pointer to start of bitmap */
 
322
        PixelType *pBase;
 
323
        int nlwidth;                            /* width in longwords of bitmap */
 
324
        register PixelType *addrl;              /* pointer to current longword in bitmap */
 
325
        register PixelType src;
 
326
        register int nlmiddle;
 
327
        register PixelType startmask;
 
328
        register PixelType endmask;
 
329
        PixmapPtr pTile;
 
330
        PixelType *psrc;
 
331
        int tileHeight;
 
332
        int rop;
 
333
        int *pwidthFree;                                /* copies of the pointers to free */
 
334
        DDXPointPtr pptFree;
 
335
        int auxDst;
 
336
        int depthDst;
 
337
        int d;
 
338
 
 
339
        n = nInit * miFindMaxBand(pGC->pCompositeClip);
 
340
        pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
 
341
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
 
342
        if (!pptFree || !pwidthFree) {
 
343
                if (pptFree)
 
344
                        DEALLOCATE_LOCAL(pptFree);
 
345
                if (pwidthFree)
 
346
                        DEALLOCATE_LOCAL(pwidthFree);
 
347
                return;
 
348
        }
 
349
        pwidth = pwidthFree;
 
350
        ppt = pptFree;
 
351
        n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
 
352
                ppt, pwidth, fSorted);
 
353
 
 
354
        ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
 
355
                                                                                                        pBase);
 
356
 
 
357
        pTile = pGC->pRotatedPixmap;
 
358
        tileHeight = pTile->drawable.height;
 
359
        psrc = (PixelType *)(pTile->devPrivate.ptr);
 
360
        rop = pGC->alu;
 
361
 
 
362
        switch (rop) {
 
363
                case GXcopy:
 
364
#define DoMaskCopyRop(src,dst,mask)             ((dst) & ~(mask) | (src) & (mask))
 
365
                        while (n--) {
 
366
                                if (*pwidth) {
 
367
                                        addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
368
 
 
369
                                        for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {  /* @@@ NEXT PLANE @@@ */
 
370
                                                if (!(pGC->planemask & (1 << d)))
 
371
                                                        continue;
 
372
 
 
373
                                                addrl = addrlBase;
 
374
                                                src = psrc[ppt->y % tileHeight + tileHeight * d]; 
 
375
                                                if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
376
                                                        maskpartialbits(ppt->x, *pwidth, startmask);
 
377
                                                        *addrl = DoMaskCopyRop (src, *addrl, startmask);
 
378
                                                } else {
 
379
                                                        maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
380
                                                        if (startmask) {
 
381
                                                                *addrl = DoMaskCopyRop (src, *addrl, startmask);
 
382
                                                                addrl++;
 
383
                                                        }
 
384
                                                        while (nlmiddle--) {
 
385
                                                                *addrl = src;
 
386
                                                                addrl++;
 
387
                                                        }
 
388
                                                        if (endmask)
 
389
                                                                *addrl = DoMaskCopyRop (src, *addrl, endmask);
 
390
                                                }
 
391
                                        }
 
392
                                }
 
393
                                pwidth++;
 
394
                                ppt++;
 
395
                        }
 
396
                        break;
 
397
 
 
398
                default:
 
399
                        {
 
400
                                register DeclareMergeRop ();
 
401
 
 
402
                                InitializeMergeRop(rop,~0);
 
403
                                while (n--) {
 
404
                                        if (*pwidth) {
 
405
                                                addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
406
                                                for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {  /* @@@ NEXT PLANE @@@ */
 
407
                                                        if (!(pGC->planemask & (1 << d)))
 
408
                                                                continue;
 
409
 
 
410
                                                        addrl = addrlBase;
 
411
 
 
412
                                                        src = psrc[ppt->y % tileHeight + tileHeight * d];
 
413
                                                        if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
414
                                                                maskpartialbits(ppt->x, *pwidth, startmask);
 
415
                                                                *addrl = DoMaskMergeRop (src, *addrl, startmask);
 
416
                                                        } else {
 
417
                                                                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
418
                                                                if (startmask) {
 
419
                                                                        *addrl = DoMaskMergeRop (src, *addrl, startmask);
 
420
                                                                        addrl++;
 
421
                                                                }
 
422
                                                                while (nlmiddle--) {
 
423
                                                                        *addrl = DoMergeRop (src, *addrl);
 
424
                                                                        addrl++;
 
425
                                                                }
 
426
                                                                if (endmask)
 
427
                                                                        *addrl = DoMaskMergeRop (src, *addrl, endmask);
 
428
                                                        }
 
429
                                                }
 
430
                                        }
 
431
                                        pwidth++;
 
432
                                        ppt++;
 
433
                                }
 
434
                                break;
 
435
                        }
 
436
        }
 
437
        DEALLOCATE_LOCAL(pptFree);
 
438
        DEALLOCATE_LOCAL(pwidthFree);
 
439
}
 
440
 
 
441
void
 
442
ilbmOpaqueStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
 
443
        DrawablePtr pDrawable;
 
444
        GC *pGC;
 
445
        int nInit;                                              /* number of spans to fill */
 
446
        DDXPointPtr pptInit;            /* pointer to list of start points */
 
447
        int *pwidthInit;                                /* pointer to list of n widths */
 
448
        int fSorted;
 
449
{
 
450
                                                                /* next three parameters are post-clip */
 
451
        int n;                                          /* number of spans to fill */
 
452
        register DDXPointPtr ppt;               /* pointer to list of start points */
 
453
        register int *pwidth;           /* pointer to list of n widths */
 
454
        PixelType *addrlBase;           /* pointer to start of bitmap */
 
455
        PixelType *pBase;
 
456
        int nlwidth;                            /* width in longwords of bitmap */
 
457
        register PixelType *addrl;              /* pointer to current longword in bitmap */
 
458
        register PixelType src;
 
459
        register int nlmiddle;
 
460
        register PixelType startmask;
 
461
        register PixelType endmask;
 
462
        PixmapPtr pTile;
 
463
        PixelType *psrc;
 
464
        int tileHeight;
 
465
        int rop;
 
466
        unsigned char *rropsOS;
 
467
        int *pwidthFree;                                /* copies of the pointers to free */
 
468
        DDXPointPtr pptFree;
 
469
        int auxDst;
 
470
        int depthDst;
 
471
        int d;
 
472
 
 
473
        n = nInit * miFindMaxBand(pGC->pCompositeClip);
 
474
        pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
 
475
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
 
476
        if (!pptFree || !pwidthFree) {
 
477
                if (pptFree)
 
478
                        DEALLOCATE_LOCAL(pptFree);
 
479
                if (pwidthFree)
 
480
                        DEALLOCATE_LOCAL(pwidthFree);
 
481
                return;
 
482
        }
 
483
        pwidth = pwidthFree;
 
484
        ppt = pptFree;
 
485
        n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
 
486
                ppt, pwidth, fSorted);
 
487
 
 
488
        ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
 
489
                                                                                                        pBase);
 
490
 
 
491
        pTile = pGC->pRotatedPixmap;
 
492
        tileHeight = pTile->drawable.height;
 
493
        psrc = (PixelType *)(pTile->devPrivate.ptr);
 
494
        rop = pGC->alu;
 
495
        rropsOS = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rropOS;
 
496
 
 
497
        switch (rop) {
 
498
                case GXcopy:
 
499
#define DoMaskCopyRop(src,dst,mask)             ((dst) & ~(mask) | (src) & (mask))
 
500
                        while (n--) {
 
501
                                addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
502
                                if (*pwidth) {
 
503
                                        for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {  /* @@@ NEXT PLANE @@@ */
 
504
                                                switch (rropsOS[d]) {
 
505
                                                        case RROP_BLACK:
 
506
                                                                src = 0;
 
507
                                                                break;
 
508
                                                        case RROP_WHITE:
 
509
                                                                src = ~0;
 
510
                                                                break;
 
511
                                                        case RROP_INVERT:
 
512
                                                                src = ~psrc[ppt->y % tileHeight];
 
513
                                                                break;
 
514
                                                        case RROP_COPY:
 
515
                                                                src = psrc[ppt->y % tileHeight];
 
516
                                                                break;
 
517
                                                        case RROP_NOP:
 
518
                                                                continue;
 
519
                                                }
 
520
 
 
521
                                                addrl = addrlBase;
 
522
 
 
523
                                                if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
524
                                                        maskpartialbits(ppt->x, *pwidth, startmask);
 
525
                                                        *addrl = DoMaskCopyRop (src, *addrl, startmask);
 
526
                                                } else {
 
527
                                                        maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
528
                                                        if (startmask) {
 
529
                                                                *addrl = DoMaskCopyRop (src, *addrl, startmask);
 
530
                                                                addrl++;
 
531
                                                        }
 
532
                                                        while (nlmiddle--) {
 
533
                                                                *addrl = src;
 
534
                                                                addrl++;
 
535
                                                        }
 
536
                                                        if (endmask)
 
537
                                                                *addrl = DoMaskCopyRop (src, *addrl, endmask);
 
538
                                                }
 
539
                                        } /* for (d = ...) */
 
540
                                }
 
541
 
 
542
                                pwidth++;
 
543
                                ppt++;
 
544
                        }
 
545
                        break;
 
546
 
 
547
                default:
 
548
                        {
 
549
                                register DeclareMergeRop ();
 
550
 
 
551
                                InitializeMergeRop(rop,~0);
 
552
                                while (n--) {
 
553
                                        addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
554
                                        if (*pwidth) {
 
555
                                                for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {  /* @@@ NEXT PLANE @@@ */
 
556
                                                        switch (rropsOS[d]) {
 
557
                                                                case RROP_BLACK:
 
558
                                                                        src = 0;
 
559
                                                                        break;
 
560
                                                                case RROP_WHITE:
 
561
                                                                        src = ~0;
 
562
                                                                        break;
 
563
                                                                case RROP_INVERT:
 
564
                                                                        src = ~psrc[ppt->y % tileHeight];
 
565
                                                                        break;
 
566
                                                                case RROP_COPY:
 
567
                                                                        src = psrc[ppt->y % tileHeight];
 
568
                                                                        break;
 
569
                                                                case RROP_NOP:
 
570
                                                                        continue;
 
571
                                                        }
 
572
 
 
573
                                                        addrl = addrlBase;
 
574
 
 
575
                                                        if ( ((ppt->x & PIM) + *pwidth) < PPW) {
 
576
                                                                maskpartialbits(ppt->x, *pwidth, startmask);
 
577
                                                                *addrl = DoMaskMergeRop (src, *addrl, startmask);
 
578
                                                        } else {
 
579
                                                                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
 
580
                                                                if (startmask) {
 
581
                                                                        *addrl = DoMaskMergeRop (src, *addrl, startmask);
 
582
                                                                        addrl++;
 
583
                                                                }
 
584
                                                                while (nlmiddle--) {
 
585
                                                                        *addrl = DoMergeRop (src, *addrl);
 
586
                                                                        addrl++;
 
587
                                                                }
 
588
                                                                if (endmask)
 
589
                                                                        *addrl = DoMaskMergeRop (src, *addrl, endmask);
 
590
                                                        }
 
591
                                                } /* for (d = ...) */
 
592
                                        }
 
593
                                        pwidth++;
 
594
                                        ppt++;
 
595
                                } /* while (n) */
 
596
                                break;
 
597
                        }
 
598
        } /* switch (rop) */
 
599
        DEALLOCATE_LOCAL(pptFree);
 
600
        DEALLOCATE_LOCAL(pwidthFree);
 
601
}
 
602
 
 
603
/* Fill spans with tiles that aren't PPW bits wide */
 
604
void
 
605
ilbmUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
 
606
        DrawablePtr pDrawable;
 
607
        GC                              *pGC;
 
608
        int                             nInit;                          /* number of spans to fill */
 
609
        DDXPointPtr pptInit;            /* pointer to list of start points */
 
610
        int *pwidthInit;                                /* pointer to list of n widths */
 
611
        int fSorted;
 
612
{
 
613
        int                             iline;                          /* first line of tile to use */
 
614
                                                                /* next three parameters are post-clip */
 
615
        int n;                                          /* number of spans to fill */
 
616
        register DDXPointPtr ppt;               /* pointer to list of start points */
 
617
        register int *pwidth;           /* pointer to list of n widths */
 
618
        PixelType *addrlBase;           /* pointer to start of bitmap */
 
619
        PixelType *pBase;
 
620
        int                              nlwidth;               /* width in longwords of bitmap */
 
621
        register PixelType *pdst;/* pointer to current word in bitmap */
 
622
        register PixelType *psrc;/* pointer to current word in tile */
 
623
        register int nlMiddle;
 
624
        register int rop, nstart;
 
625
        PixelType startmask;
 
626
        PixmapPtr               pTile;                          /* pointer to tile we want to fill with */
 
627
        int                             w, width, x, xSrc, ySrc, srcStartOver, nend;
 
628
        int             tlwidth, rem, tileWidth, tileHeight, endinc;
 
629
        PixelType         endmask, *psrcT;
 
630
        int *pwidthFree;                                /* copies of the pointers to free */
 
631
        DDXPointPtr pptFree;
 
632
        int auxDst;
 
633
        int sizeTile;
 
634
        int depthDst;
 
635
        register int d;
 
636
 
 
637
        n = nInit * miFindMaxBand(pGC->pCompositeClip);
 
638
        pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
 
639
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
 
640
        if (!pptFree || !pwidthFree) {
 
641
                if (pptFree)
 
642
                        DEALLOCATE_LOCAL(pptFree);
 
643
                if (pwidthFree)
 
644
                        DEALLOCATE_LOCAL(pwidthFree);
 
645
                return;
 
646
        }
 
647
        pwidth = pwidthFree;
 
648
        ppt = pptFree;
 
649
        n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
 
650
                ppt, pwidth, fSorted);
 
651
 
 
652
        pTile = pGC->tile.pixmap;
 
653
        tlwidth = pTile->devKind/PGSZB;
 
654
        rop = pGC->alu;
 
655
 
 
656
        xSrc = pDrawable->x;
 
657
        ySrc = pDrawable->y;
 
658
 
 
659
        ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
 
660
                                                                                                        pBase);
 
661
 
 
662
        tileWidth = pTile->drawable.width;
 
663
        tileHeight = pTile->drawable.height;
 
664
        sizeTile = tlwidth * tileHeight;
 
665
 
 
666
        /* this replaces rotating the tile. Instead we just adjust the offset
 
667
         * at which we start grabbing bits from the tile.
 
668
         * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
 
669
         * so that iline and rem always stay within the tile bounds.
 
670
         */
 
671
        xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
 
672
        ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
 
673
 
 
674
        while (n--) {
 
675
                iline = (ppt->y - ySrc) % tileHeight;
 
676
                psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
 
677
                addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
678
 
 
679
                for (d = 0; d < depthDst; d++, psrcT += sizeTile, addrlBase += nlwidth) {       /* @@@ NEXT PLANE @@@ */
 
680
                        if (!(pGC->planemask & (1 << d)))
 
681
                                continue;
 
682
 
 
683
                        if (*pwidth) {
 
684
                                x = ppt->x;
 
685
                                pdst = addrlBase;
 
686
                                width = *pwidth;
 
687
                                while (width > 0) {
 
688
                                        psrc = psrcT;
 
689
                                        w = min(tileWidth, width);
 
690
                                        if ((rem = (x - xSrc)  % tileWidth) != 0) {
 
691
                                                /* if we're in the middle of the tile, get
 
692
                                                   as many bits as will finish the span, or
 
693
                                                   as many as will get to the left edge of the tile,
 
694
                                                   or a longword worth, starting at the appropriate
 
695
                                                   offset in the tile.
 
696
                                                */
 
697
                                                w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
 
698
                                                endinc = rem / BITMAP_SCANLINE_PAD;
 
699
                                                getandputrop((psrc+endinc), (rem&PIM), (x & PIM), w, pdst, rop);
 
700
                                                if ((x & PIM) + w >= PPW)
 
701
                                                        pdst++;
 
702
                                        } else if (((x & PIM) + w) < PPW) {
 
703
                                                /* doing < PPW bits is easy, and worth special-casing */
 
704
                                                putbitsrop(*psrc, x & PIM, w, pdst, rop);
 
705
                                        } else {
 
706
                                                /* start at the left edge of the tile,
 
707
                                                   and put down as much as we can
 
708
                                                */
 
709
                                                maskbits(x, w, startmask, endmask, nlMiddle);
 
710
 
 
711
                                                if (startmask)
 
712
                                                        nstart = PPW - (x & PIM);
 
713
                                                else
 
714
                                                        nstart = 0;
 
715
                                                if (endmask)
 
716
                                                        nend = (x + w)  & PIM;
 
717
                                                else
 
718
                                                        nend = 0;
 
719
 
 
720
                                                srcStartOver = nstart > PLST;
 
721
 
 
722
                                                if (startmask) {
 
723
                                                        putbitsrop(*psrc, (x & PIM), nstart, pdst, rop);
 
724
                                                        pdst++;
 
725
                                                        if (srcStartOver)
 
726
                                                                psrc++;
 
727
                                                }
 
728
                                                 
 
729
                                                while (nlMiddle--) {
 
730
                                                                getandputrop0(psrc, nstart, PPW, pdst, rop);
 
731
                                                                pdst++;
 
732
                                                                psrc++;
 
733
                                                }
 
734
                                                if (endmask) {
 
735
                                                        getandputrop0(psrc, nstart, nend, pdst, rop);
 
736
                                                }
 
737
                                         }
 
738
                                         x += w;
 
739
                                         width -= w;
 
740
                                }
 
741
                        }
 
742
                }
 
743
                ppt++;
 
744
                pwidth++;
 
745
        }
 
746
        DEALLOCATE_LOCAL(pptFree);
 
747
        DEALLOCATE_LOCAL(pwidthFree);
 
748
}
 
749
 
 
750
/* Fill spans with stipples that aren't PPW bits wide */
 
751
void
 
752
ilbmUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
 
753
        DrawablePtr pDrawable;
 
754
        GC                              *pGC;
 
755
        int                             nInit;                          /* number of spans to fill */
 
756
        DDXPointPtr pptInit;            /* pointer to list of start points */
 
757
        int *pwidthInit;                                /* pointer to list of n widths */
 
758
        int fSorted;
 
759
{
 
760
                                                                /* next three parameters are post-clip */
 
761
        int n;                                          /* number of spans to fill */
 
762
        register DDXPointPtr ppt;               /* pointer to list of start points */
 
763
        register int *pwidth;           /* pointer to list of n widths */
 
764
        int                             iline;                          /* first line of tile to use */
 
765
        PixelType               *addrlBase;             /* pointer to start of bitmap */
 
766
        PixelType               *pBase;
 
767
        int                              nlwidth;               /* width in longwords of bitmap */
 
768
        register PixelType *pdst;                               /* pointer to current word in bitmap */
 
769
        register PixelType *psrc;                               /* pointer to current word in tile */
 
770
        register int nlMiddle;
 
771
        register int rop, nstart;
 
772
        PixelType startmask;
 
773
        PixmapPtr               pTile;                          /* pointer to tile we want to fill with */
 
774
        int                             w, width,  x, xSrc, ySrc, srcStartOver, nend;
 
775
        PixelType               endmask, *psrcT;
 
776
        int             tlwidth, rem, tileWidth, endinc;
 
777
        int                             tileHeight;
 
778
        int *pwidthFree;                                /* copies of the pointers to free */
 
779
        DDXPointPtr pptFree;
 
780
        unsigned char *rrops;
 
781
        register int d;
 
782
        int auxDst;
 
783
        int depthDst;
 
784
 
 
785
        n = nInit * miFindMaxBand(pGC->pCompositeClip);
 
786
        pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
 
787
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
 
788
        if (!pptFree || !pwidthFree) {
 
789
                if (pptFree)
 
790
                        DEALLOCATE_LOCAL(pptFree);
 
791
                if (pwidthFree)
 
792
                        DEALLOCATE_LOCAL(pwidthFree);
 
793
                return;
 
794
        }
 
795
        pwidth = pwidthFree;
 
796
        ppt = pptFree;
 
797
        n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
 
798
                ppt, pwidth, fSorted);
 
799
 
 
800
        pTile = pGC->stipple;
 
801
        tlwidth = pTile->devKind/PGSZB;
 
802
        xSrc = pDrawable->x;
 
803
        ySrc = pDrawable->y;
 
804
        ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
 
805
                                                                                                        pBase);
 
806
 
 
807
        tileWidth = pTile->drawable.width;
 
808
        tileHeight = pTile->drawable.height;
 
809
        rrops = ((ilbmPrivGC *)(pGC->devPrivates[ilbmGCPrivateIndex].ptr))->rrops;
 
810
 
 
811
        /* this replaces rotating the stipple.  Instead, we just adjust the offset
 
812
         * at which we start grabbing bits from the stipple.
 
813
         * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
 
814
         * so that iline and rem always stay within the tile bounds.
 
815
         */
 
816
        xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
 
817
        ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
 
818
        while (n--) {
 
819
                iline = (ppt->y - ySrc) % tileHeight;
 
820
                psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
 
821
                addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
822
 
 
823
                for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {  /* @@@ NEXT PLANE @@@ */
 
824
                        rop = rrops[d];
 
825
                        if (rop == RROP_NOP)
 
826
                                continue;
 
827
 
 
828
                        pdst = addrlBase;
 
829
                        x = ppt->x;
 
830
 
 
831
                        if (*pwidth) {
 
832
                                width = *pwidth;
 
833
                                while (width > 0) {
 
834
                                        psrc = psrcT;
 
835
                                        w = min(tileWidth, width);
 
836
                                        if ((rem = (x - xSrc) % tileWidth) != 0) {
 
837
                                                /* if we're in the middle of the tile, get
 
838
                                                   as many bits as will finish the span, or
 
839
                                                   as many as will get to the left edge of the tile,
 
840
                                                   or a longword worth, starting at the appropriate
 
841
                                                   offset in the tile.
 
842
                                                */
 
843
                                                w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
 
844
                                                endinc = rem / BITMAP_SCANLINE_PAD;
 
845
                                                getandputrrop((psrc + endinc), (rem & PIM), (x & PIM),
 
846
                                                                         w, pdst, rop)
 
847
                                                if ((x & PIM) + w >= PPW)
 
848
                                                        pdst++;
 
849
                                        } else if (((x & PIM) + w) < PPW) {
 
850
                                                /* doing < PPW bits is easy, and worth special-casing */
 
851
                                                putbitsrrop(*psrc, x & PIM, w, pdst, rop);
 
852
                                        } else {
 
853
                                                /* start at the left edge of the tile,
 
854
                                                   and put down as much as we can
 
855
                                                */
 
856
                                                maskbits(x, w, startmask, endmask, nlMiddle);
 
857
 
 
858
                                                if (startmask)
 
859
                                                        nstart = PPW - (x & PIM);
 
860
                                                else
 
861
                                                        nstart = 0;
 
862
                                                if (endmask)
 
863
                                                        nend = (x + w)  & PIM;
 
864
                                                else
 
865
                                                        nend = 0;
 
866
 
 
867
                                                srcStartOver = nstart > PLST;
 
868
 
 
869
                                                if (startmask) {
 
870
                                                        putbitsrrop(*psrc, (x & PIM), nstart, pdst, rop);
 
871
                                                        pdst++;
 
872
                                                        if (srcStartOver)
 
873
                                                                psrc++;
 
874
                                                }
 
875
                                                 
 
876
                                                while (nlMiddle--) {
 
877
                                                                getandputrrop0(psrc, nstart, PPW, pdst, rop);
 
878
                                                                pdst++;
 
879
                                                                psrc++;
 
880
                                                }
 
881
                                                if (endmask) {
 
882
                                                        getandputrrop0(psrc, nstart, nend, pdst, rop);
 
883
                                                }
 
884
                                         }
 
885
                                         x += w;
 
886
                                         width -= w;
 
887
                                }
 
888
                        }
 
889
                }
 
890
                ppt++;
 
891
                pwidth++;
 
892
        }
 
893
        DEALLOCATE_LOCAL(pptFree);
 
894
        DEALLOCATE_LOCAL(pwidthFree);
 
895
}
 
896
 
 
897
/* Fill spans with OpaqueStipples that aren't PPW bits wide */
 
898
void
 
899
ilbmUnnaturalOpaqueStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
 
900
        DrawablePtr pDrawable;
 
901
        GC                              *pGC;
 
902
        int                             nInit;                          /* number of spans to fill */
 
903
        DDXPointPtr pptInit;            /* pointer to list of start points */
 
904
        int *pwidthInit;                                /* pointer to list of n widths */
 
905
        int fSorted;
 
906
{
 
907
        int                             iline;                          /* first line of tile to use */
 
908
                                                                /* next three parameters are post-clip */
 
909
        int n;                                          /* number of spans to fill */
 
910
        register DDXPointPtr ppt;               /* pointer to list of start points */
 
911
        register int *pwidth;           /* pointer to list of n widths */
 
912
        PixelType *addrlBase;           /* pointer to start of bitmap */
 
913
        PixelType *pBase;
 
914
        int                              nlwidth;               /* width in longwords of bitmap */
 
915
        register PixelType *pdst;/* pointer to current word in bitmap */
 
916
        register PixelType *psrc;/* pointer to current word in tile */
 
917
        register int nlMiddle;
 
918
        register int d;
 
919
        register PixelType tmpsrc;
 
920
        register PixelType tmpdst;
 
921
        register int alu, nstart;
 
922
        register unsigned char *rropsOS;
 
923
        PixelType startmask;
 
924
        PixmapPtr               pTile;                          /* pointer to tile we want to fill with */
 
925
        int                             w, width, x, xSrc, ySrc, srcStartOver, nend;
 
926
        int             tlwidth, rem, tileWidth, tileHeight, endinc;
 
927
        PixelType         endmask, *psrcT;
 
928
        int *pwidthFree;                                /* copies of the pointers to free */
 
929
        DDXPointPtr pptFree;
 
930
        int auxDst;
 
931
        int sizeTile;
 
932
        int depthDst;
 
933
 
 
934
        n = nInit * miFindMaxBand(pGC->pCompositeClip);
 
935
        pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
 
936
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
 
937
        if (!pptFree || !pwidthFree) {
 
938
                if (pptFree)
 
939
                        DEALLOCATE_LOCAL(pptFree);
 
940
                if (pwidthFree)
 
941
                        DEALLOCATE_LOCAL(pwidthFree);
 
942
                return;
 
943
        }
 
944
        pwidth = pwidthFree;
 
945
        ppt = pptFree;
 
946
        n = miClipSpans(pGC->pCompositeClip, pptInit, pwidthInit, nInit,
 
947
                ppt, pwidth, fSorted);
 
948
 
 
949
        pTile = pGC->stipple;
 
950
        tlwidth = pTile->devKind/PGSZB;
 
951
        alu = pGC->alu;
 
952
 
 
953
        xSrc = pDrawable->x;
 
954
        ySrc = pDrawable->y;
 
955
 
 
956
        ilbmGetPixelWidthAuxDepthAndPointer(pDrawable, nlwidth, auxDst, depthDst,
 
957
                                                                                                        pBase);
 
958
 
 
959
        tileWidth = pTile->drawable.width;
 
960
        tileHeight = pTile->drawable.height;
 
961
        rropsOS = ilbmGetGCPrivate(pGC)->rropOS;
 
962
 
 
963
        /* this replaces rotating the tile. Instead we just adjust the offset
 
964
         * at which we start grabbing bits from the tile.
 
965
         * Ensure that ppt->x - xSrc >= 0 and ppt->y - ySrc >= 0,
 
966
         * so that iline and rem always stay within the tile bounds.
 
967
         */
 
968
        xSrc += (pGC->patOrg.x % tileWidth) - tileWidth;
 
969
        ySrc += (pGC->patOrg.y % tileHeight) - tileHeight;
 
970
 
 
971
        while (n--) {
 
972
                iline = (ppt->y - ySrc) % tileHeight;
 
973
                psrcT = (PixelType *) pTile->devPrivate.ptr + (iline * tlwidth);
 
974
                addrlBase = ilbmScanline(pBase, ppt->x, ppt->y, auxDst);
 
975
 
 
976
                for (d = 0; d < depthDst; d++, addrlBase += nlwidth) {  /* @@@ NEXT PLANE @@@ */
 
977
                        if (!(pGC->planemask & (1 << d)))
 
978
                                continue;
 
979
 
 
980
                        if (*pwidth) {
 
981
                                x = ppt->x;
 
982
                                pdst = addrlBase;
 
983
                                width = *pwidth;
 
984
                                while (width > 0) {
 
985
                                        psrc = psrcT;
 
986
                                        w = min(tileWidth, width);
 
987
                                        if ((rem = (x - xSrc)  % tileWidth) != 0) {
 
988
                                                /* if we're in the middle of the tile, get
 
989
                                                   as many bits as will finish the span, or
 
990
                                                   as many as will get to the left edge of the tile,
 
991
                                                   or a longword worth, starting at the appropriate
 
992
                                                   offset in the tile.
 
993
                                                */
 
994
                                                w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_PAD);
 
995
                                                endinc = rem / BITMAP_SCANLINE_PAD;
 
996
                                                switch (rropsOS[d]) {
 
997
                                                        case RROP_BLACK:
 
998
                                                                tmpsrc = 0;
 
999
                                                                break;
 
1000
                                                        case RROP_WHITE:
 
1001
                                                                tmpsrc = ~0;
 
1002
                                                                break;
 
1003
 
 
1004
                                                        case RROP_COPY:
 
1005
                                                                getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
 
1006
                                                                break;
 
1007
 
 
1008
                                                        case RROP_INVERT:
 
1009
                                                                getbits ((psrc+endinc), (rem&PIM), w, tmpsrc);
 
1010
                                                                tmpsrc = ~tmpsrc;
 
1011
                                                                break;
 
1012
                                                }
 
1013
 
 
1014
                                                if (alu != GXcopy) {
 
1015
                                                        getbits (pdst, (x & PIM), w, tmpdst);
 
1016
                                                        DoRop (tmpsrc, alu, tmpsrc, tmpdst);
 
1017
                                                }
 
1018
 
 
1019
                                                putbits (tmpsrc, (x & PIM), w, pdst);
 
1020
                                                if ((x & PIM) + w >= PPW)
 
1021
                                                        pdst++;
 
1022
                                        } else if (((x & PIM) + w) < PPW) {
 
1023
                                                /* doing < PPW bits is easy, and worth special-casing */
 
1024
                                                switch (rropsOS[d]) {
 
1025
                                                        case RROP_BLACK:
 
1026
                                                                tmpsrc = 0;
 
1027
                                                                break;
 
1028
                                                        case RROP_WHITE:
 
1029
                                                                tmpsrc = ~0;
 
1030
                                                                break;
 
1031
                                                        case RROP_COPY:
 
1032
                                                                tmpsrc = *psrc;
 
1033
                                                                break;
 
1034
                                                        case RROP_INVERT:
 
1035
                                                                tmpsrc = ~*psrc;
 
1036
                                                                break;
 
1037
                                                }
 
1038
                                                if (alu != GXcopy) {
 
1039
                                                        getbits (pdst, (x & PIM), w, tmpdst);
 
1040
                                                        DoRop (tmpsrc, alu, tmpsrc, tmpdst);
 
1041
                                                }
 
1042
                                                putbits (tmpsrc, (x & PIM), w, pdst);
 
1043
                                        } else {
 
1044
                                                /* start at the left edge of the tile,
 
1045
                                                   and put down as much as we can
 
1046
                                                */
 
1047
                                                maskbits(x, w, startmask, endmask, nlMiddle);
 
1048
 
 
1049
                                                if (startmask)
 
1050
                                                        nstart = PPW - (x & PIM);
 
1051
                                                else
 
1052
                                                        nstart = 0;
 
1053
                                                if (endmask)
 
1054
                                                        nend = (x + w)  & PIM;
 
1055
                                                else
 
1056
                                                        nend = 0;
 
1057
 
 
1058
                                                srcStartOver = nstart > PLST;
 
1059
 
 
1060
                                                if (startmask) {
 
1061
                                                        switch (rropsOS[d]) {
 
1062
                                                                case RROP_BLACK:
 
1063
                                                                        tmpsrc = 0;
 
1064
                                                                        break;
 
1065
                                                                case RROP_WHITE:
 
1066
                                                                        tmpsrc = ~0;
 
1067
                                                                        break;
 
1068
                                                                case RROP_COPY:
 
1069
                                                                        tmpsrc = *psrc;
 
1070
                                                                        break;
 
1071
                                                                case RROP_INVERT:
 
1072
                                                                        tmpsrc = ~*psrc;
 
1073
                                                                        break;
 
1074
                                                        }
 
1075
                                                        if (alu != GXcopy) {
 
1076
                                                                getbits (pdst, (x & PIM), nstart, tmpdst);
 
1077
                                                                DoRop (tmpsrc, alu, tmpsrc, tmpdst);
 
1078
                                                        }
 
1079
                                                        putbits (tmpsrc, (x & PIM), nstart, pdst);
 
1080
                                                        pdst++;
 
1081
                                                        if (srcStartOver)
 
1082
                                                                psrc++;
 
1083
                                                }
 
1084
                                                 
 
1085
                                                while (nlMiddle--) {
 
1086
                                                        switch (rropsOS[d]) {
 
1087
                                                                case RROP_BLACK:
 
1088
                                                                        tmpsrc = 0;
 
1089
                                                                        break;
 
1090
                                                                case RROP_WHITE:
 
1091
                                                                        tmpsrc = ~0;
 
1092
                                                                        break;
 
1093
                                                                case RROP_COPY:
 
1094
                                                                        getbits (psrc, nstart, PPW, tmpsrc);
 
1095
                                                                        break;
 
1096
                                                                case RROP_INVERT:
 
1097
                                                                        getbits (psrc, nstart, PPW, tmpsrc);
 
1098
                                                                        tmpsrc = ~tmpsrc;
 
1099
                                                                        break;
 
1100
                                                        }
 
1101
                                                        if (alu != GXcopy) {
 
1102
                                                                tmpdst = *pdst;
 
1103
                                                                DoRop (tmpsrc, alu, tmpsrc, tmpdst);
 
1104
                                                        }
 
1105
                                                        *pdst++ = tmpsrc;
 
1106
                                                        /*putbits (tmpsrc, 0, PPW, pdst);
 
1107
                                                                pdst++;*/
 
1108
                                                                psrc++;
 
1109
                                                }
 
1110
                                                if (endmask) {
 
1111
                                                        switch (rropsOS[d]) {
 
1112
                                                                case RROP_BLACK:
 
1113
                                                                        tmpsrc = 0;
 
1114
                                                                        break;
 
1115
                                                                case RROP_WHITE:
 
1116
                                                                        tmpsrc = ~0;
 
1117
                                                                        break;
 
1118
 
 
1119
                                                                case RROP_COPY:
 
1120
                                                                        getbits (psrc, nstart, nend, tmpsrc);
 
1121
                                                                        break;
 
1122
 
 
1123
                                                                case RROP_INVERT:
 
1124
                                                                        getbits (psrc, nstart, nend, tmpsrc);
 
1125
                                                                        tmpsrc = ~tmpsrc;
 
1126
                                                                        break;
 
1127
                                                        }
 
1128
                                                        if (alu != GXcopy) {
 
1129
                                                                tmpdst = *pdst;
 
1130
                                                                DoRop (tmpsrc, alu, tmpsrc, tmpdst);
 
1131
                                                        }
 
1132
                                                        putbits (tmpsrc, 0, nend, pdst);
 
1133
                                                }
 
1134
                                        }
 
1135
                                         x += w;
 
1136
                                         width -= w;
 
1137
                                }
 
1138
                        }
 
1139
                }
 
1140
                ppt++;
 
1141
                pwidth++;
 
1142
        }
 
1143
        DEALLOCATE_LOCAL(pptFree);
 
1144
        DEALLOCATE_LOCAL(pwidthFree);
 
1145
}