~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/kdrive/savage/s3draw.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Id: s3draw.c,v 1.1 1999/11/02 03:54:47 keithp Exp $
 
3
 *
 
4
 * Copyright 1999 SuSE, Inc.
 
5
 *
 
6
 * Permission to use, copy, modify, distribute, and sell this software and its
 
7
 * documentation for any purpose is hereby granted without fee, provided that
 
8
 * the above copyright notice appear in all copies and that both that
 
9
 * copyright notice and this permission notice appear in supporting
 
10
 * documentation, and that the name of SuSE not be used in advertising or
 
11
 * publicity pertaining to distribution of the software without specific,
 
12
 * written prior permission.  SuSE makes no representations about the
 
13
 * suitability of this software for any purpose.  It is provided "as is"
 
14
 * without express or implied warranty.
 
15
 *
 
16
 * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
 
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE
 
18
 * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 
19
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 
20
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 
 
21
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
22
 *
 
23
 * Author:  Keith Packard, SuSE, Inc.
 
24
 */
 
25
/* $RCSId: xc/programs/Xserver/hw/kdrive/savage/s3draw.c,v 1.6 2001/05/29 04:54:11 keithp Exp $ */
 
26
 
 
27
#ifdef HAVE_CONFIG_H
 
28
#include <kdrive-config.h>
 
29
#endif
 
30
#include        "s3.h"
 
31
#include        "s3draw.h"
 
32
 
 
33
#include        "Xmd.h"
 
34
#include        "gcstruct.h"
 
35
#include        "scrnintstr.h"
 
36
#include        "pixmapstr.h"
 
37
#include        "regionstr.h"
 
38
#include        "mistruct.h"
 
39
#include        "fontstruct.h"
 
40
#include        "dixfontstr.h"
 
41
#include        "fb.h"
 
42
#include        "migc.h"
 
43
#include        "miline.h"
 
44
 
 
45
/*
 
46
 * Map X rops to S3 rops
 
47
 */
 
48
 
 
49
short s3alu[16] = {
 
50
    MIX_0,
 
51
    MIX_AND,
 
52
    MIX_SRC_AND_NOT_DST,
 
53
    MIX_SRC,
 
54
    MIX_NOT_SRC_AND_DST,
 
55
    MIX_DST,
 
56
    MIX_XOR,
 
57
    MIX_OR,
 
58
    MIX_NOR,
 
59
    MIX_XNOR,
 
60
    MIX_NOT_DST,
 
61
    MIX_SRC_OR_NOT_DST,
 
62
    MIX_NOT_SRC,
 
63
    MIX_NOT_SRC_OR_DST,
 
64
    MIX_NAND,
 
65
    MIX_1
 
66
};
 
67
 
 
68
/*
 
69
 * Handle pixel transfers
 
70
 */
 
71
 
 
72
#define BURST
 
73
#ifdef BURST
 
74
#define PixTransDeclare VOL32   *pix_trans_base = (VOL32 *) (s3c->registers),\
 
75
                                *pix_trans = pix_trans_base
 
76
#define PixTransStart(n)        if (pix_trans + (n) > pix_trans_base + 8192) pix_trans = pix_trans_base
 
77
#define PixTransStore(t)        *pix_trans++ = (t)
 
78
#else
 
79
#define PixTransDeclare VOL32   *pix_trans = &s3->pix_trans
 
80
#define PixTransStart(n)        
 
81
#define PixTransStore(t)        *pix_trans = (t)
 
82
#endif
 
83
 
 
84
int     s3GCPrivateIndex;
 
85
int     s3WindowPrivateIndex;
 
86
int     s3Generation;
 
87
 
 
88
/*
 
89
  s3DoBitBlt
 
90
  =============
 
91
  Bit Blit for all window to window blits.
 
92
*/
 
93
 
 
94
#define sourceInvarient(alu)    (((alu) & 3) == (((alu) >> 2) & 3))
 
95
 
 
96
void
 
97
s3CopyNtoN (DrawablePtr pSrcDrawable,
 
98
            DrawablePtr pDstDrawable,
 
99
            GCPtr       pGC,
 
100
            BoxPtr      pbox,
 
101
            int         nbox,
 
102
            int         dx,
 
103
            int         dy,
 
104
            Bool        reverse,
 
105
            Bool        upsidedown,
 
106
            Pixel       bitplane,
 
107
            void        *closure)
 
108
{
 
109
    SetupS3(pDstDrawable->pScreen);
 
110
    int     srcX, srcY, dstX, dstY;
 
111
    int     w, h;
 
112
    int     flags;
 
113
    
 
114
    if (sourceInvarient (pGC->alu))
 
115
    {
 
116
        s3FillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
 
117
        return;
 
118
    }
 
119
    
 
120
    s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
 
121
    _s3SetBlt(s3,pGC->alu,pGC->planemask);
 
122
    DRAW_DEBUG ((DEBUG_RENDER, "s3CopyNtoN alu %d planemask 0x%x",
 
123
                pGC->alu, pGC->planemask));
 
124
    while (nbox--)
 
125
    {
 
126
        w = pbox->x2 - pbox->x1;
 
127
        h = pbox->y2 - pbox->y1;
 
128
        flags = 0;
 
129
        if (reverse)
 
130
        {
 
131
            dstX = pbox->x2 - 1;
 
132
        }
 
133
        else
 
134
        {
 
135
            dstX = pbox->x1;
 
136
            flags |= INC_X;
 
137
        }
 
138
        srcX = dstX + dx;
 
139
        
 
140
        if (upsidedown)
 
141
        {
 
142
            dstY = pbox->y2 - 1;
 
143
        }
 
144
        else
 
145
        {
 
146
            dstY = pbox->y1;
 
147
            flags |= INC_Y;
 
148
        }
 
149
        srcY = dstY + dy;
 
150
        
 
151
        _s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
 
152
        pbox++;
 
153
    }
 
154
    MarkSyncS3 (pSrcDrawable->pScreen);
 
155
}
 
156
 
 
157
RegionPtr
 
158
s3CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 
159
           int srcx, int srcy, int width, int height, int dstx, int dsty)
 
160
{
 
161
    SetupS3(pDstDrawable->pScreen);
 
162
    
 
163
    if (pSrcDrawable->type == DRAWABLE_WINDOW &&
 
164
        pDstDrawable->type == DRAWABLE_WINDOW)
 
165
    {
 
166
        return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, 
 
167
                         srcx, srcy, width, height, 
 
168
                         dstx, dsty, s3CopyNtoN, 0, 0);
 
169
    }
 
170
    return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC, 
 
171
                            srcx, srcy, width, height, dstx, dsty);
 
172
}
 
173
 
 
174
typedef struct _s31toNargs {
 
175
    unsigned long       copyPlaneFG, copyPlaneBG;
 
176
    Bool                opaque;
 
177
} s31toNargs;
 
178
 
 
179
void
 
180
_s3Stipple (S3CardInfo  *s3c,
 
181
            FbStip      *psrcBase,
 
182
            FbStride    widthSrc,
 
183
            int         srcx,
 
184
            int         srcy,
 
185
            int         dstx,
 
186
            int         dsty,
 
187
            int         width,
 
188
            int         height)
 
189
{
 
190
    S3Ptr       s3 = s3c->s3;
 
191
    FbStip      *psrcLine, *psrc;
 
192
    FbStride    widthRest;
 
193
    FbStip      bits, tmp, lastTmp;
 
194
    int         leftShift, rightShift;
 
195
    int         nl, nlMiddle;
 
196
    int         r;
 
197
    PixTransDeclare;
 
198
    
 
199
    /* Compute blt address and parameters */
 
200
    psrc = psrcBase + srcy * widthSrc + (srcx >> 5);
 
201
    nlMiddle = (width + 31) >> 5;
 
202
    leftShift = srcx & 0x1f;
 
203
    rightShift = 32 - leftShift;
 
204
    widthRest = widthSrc - nlMiddle;
 
205
    
 
206
    _s3PlaneBlt(s3,dstx,dsty,width,height);
 
207
    
 
208
    if (leftShift == 0)
 
209
    {
 
210
        while (height--)
 
211
        {
 
212
            nl = nlMiddle;
 
213
            PixTransStart(nl);
 
214
            while (nl--)
 
215
            {
 
216
                tmp = *psrc++;
 
217
                S3AdjustBits32 (tmp);
 
218
                PixTransStore (tmp);
 
219
            }
 
220
            psrc += widthRest;
 
221
        }
 
222
    }
 
223
    else
 
224
    {
 
225
        widthRest--;
 
226
        while (height--)
 
227
        {
 
228
            bits = *psrc++;
 
229
            nl = nlMiddle;
 
230
            PixTransStart(nl);
 
231
            while (nl--)
 
232
            {
 
233
                tmp = FbStipLeft(bits, leftShift);
 
234
                bits = *psrc++;
 
235
                tmp |= FbStipRight(bits, rightShift);
 
236
                S3AdjustBits32(tmp);
 
237
                PixTransStore (tmp);
 
238
            }
 
239
            psrc += widthRest;
 
240
        }
 
241
    }
 
242
}
 
243
            
 
244
void
 
245
s3Copy1toN (DrawablePtr pSrcDrawable,
 
246
            DrawablePtr pDstDrawable,
 
247
            GCPtr       pGC,
 
248
            BoxPtr      pbox,
 
249
            int         nbox,
 
250
            int         dx,
 
251
            int         dy,
 
252
            Bool        reverse,
 
253
            Bool        upsidedown,
 
254
            Pixel       bitplane,
 
255
            void        *closure)
 
256
{
 
257
    SetupS3(pDstDrawable->pScreen);
 
258
    
 
259
    s31toNargs          *args = closure;
 
260
    int                 dstx, dsty;
 
261
    FbStip              *psrcBase;
 
262
    FbStride            widthSrc;
 
263
    int                 srcBpp;
 
264
    int                 srcXoff, srcYoff;
 
265
 
 
266
    if (args->opaque && sourceInvarient (pGC->alu))
 
267
    {
 
268
        s3FillBoxSolid (pDstDrawable, nbox, pbox,
 
269
                        pGC->bgPixel, pGC->alu, pGC->planemask);
 
270
        return;
 
271
    }
 
272
    
 
273
    s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
 
274
    fbGetStipDrawable (pSrcDrawable, psrcBase, widthSrc, srcBpp, srcXoff, srcYoff);
 
275
    
 
276
    if (args->opaque)
 
277
    {
 
278
        _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,args->copyPlaneFG,
 
279
                             args->copyPlaneBG);
 
280
    }
 
281
    else
 
282
    {
 
283
        _s3SetTransparentPlaneBlt (s3, pGC->alu, 
 
284
                                   pGC->planemask, args->copyPlaneFG);
 
285
    }
 
286
    
 
287
    while (nbox--)
 
288
    {
 
289
        dstx = pbox->x1;
 
290
        dsty = pbox->y1;
 
291
        
 
292
        _s3Stipple (s3c,
 
293
                    psrcBase, widthSrc, 
 
294
                    dstx + dx - srcXoff, dsty + dy - srcYoff,
 
295
                    dstx, dsty, 
 
296
                    pbox->x2 - dstx, pbox->y2 - dsty);
 
297
        pbox++;
 
298
    }
 
299
    MarkSyncS3 (pDstDrawable->pScreen);
 
300
}
 
301
 
 
302
RegionPtr
 
303
s3CopyPlane(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 
304
        int srcx, int srcy, int width, int height, 
 
305
        int dstx, int dsty, unsigned long bitPlane)
 
306
{
 
307
    SetupS3 (pDstDrawable->pScreen);
 
308
    RegionPtr           ret;
 
309
    s31toNargs          args;
 
310
 
 
311
    if (pDstDrawable->type == DRAWABLE_WINDOW &&
 
312
        pSrcDrawable->depth == 1)
 
313
    {
 
314
        args.copyPlaneFG = pGC->fgPixel;
 
315
        args.copyPlaneBG = pGC->bgPixel;
 
316
        args.opaque = TRUE;
 
317
        return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, 
 
318
                         srcx, srcy, width, height, 
 
319
                         dstx, dsty, s3Copy1toN, bitPlane, &args);
 
320
    }
 
321
    return KdCheckCopyPlane(pSrcDrawable, pDstDrawable, pGC, 
 
322
                            srcx, srcy, width, height, 
 
323
                            dstx, dsty, bitPlane);
 
324
}
 
325
 
 
326
void
 
327
s3PushPixels (GCPtr pGC, PixmapPtr pBitmap,
 
328
              DrawablePtr pDrawable,
 
329
              int w, int h, int x, int y)
 
330
{
 
331
    SetupS3 (pDrawable->pScreen);
 
332
    s31toNargs          args;
 
333
    
 
334
    if (pDrawable->type == DRAWABLE_WINDOW && pGC->fillStyle == FillSolid)
 
335
    {
 
336
        args.opaque = FALSE;
 
337
        args.copyPlaneFG = pGC->fgPixel;
 
338
        (void) fbDoCopy ((DrawablePtr) pBitmap, pDrawable, pGC,
 
339
                          0, 0, w, h, x, y, s3Copy1toN, 1, &args);
 
340
    }
 
341
    else
 
342
    {
 
343
        KdCheckPushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
 
344
    }
 
345
}
 
346
 
 
347
void
 
348
s3FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox, 
 
349
                unsigned long pixel, int alu, unsigned long planemask)
 
350
{
 
351
    SetupS3(pDrawable->pScreen);
 
352
    register int        r;
 
353
 
 
354
    s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
 
355
    _s3SetSolidFill(s3,pixel,alu,planemask);
 
356
    
 
357
    while (nBox--) {
 
358
        _s3SolidRect(s3,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1);
 
359
        pBox++;
 
360
    }
 
361
    MarkSyncS3 (pDrawable->pScreen);
 
362
}
 
363
 
 
364
void
 
365
_s3SetPattern (ScreenPtr pScreen, int ma,
 
366
              int alu, unsigned long planemask, s3PatternPtr pPattern)
 
367
{
 
368
    SetupS3(pScreen);
 
369
    S3PatternCache  *cache;
 
370
    
 
371
    _s3LoadPattern (pScreen, ma, pPattern);
 
372
    cache = pPattern->cache;
 
373
    
 
374
    switch (pPattern->fillStyle) {
 
375
    case FillTiled:
 
376
        _s3SetTile(s3,alu,planemask);
 
377
        break;
 
378
    case FillStippled:
 
379
        _s3SetStipple(s3,alu,planemask,pPattern->fore);
 
380
        break;
 
381
    case FillOpaqueStippled:
 
382
        _s3SetOpaqueStipple(s3,alu,planemask,pPattern->fore,pPattern->back);
 
383
        break;
 
384
    }
 
385
}
 
386
 
 
387
void
 
388
s3FillBoxPattern (DrawablePtr pDrawable, int nBox, BoxPtr pBox, 
 
389
                  int alu, unsigned long planemask, s3PatternPtr pPattern)
 
390
{
 
391
    SetupS3(pDrawable->pScreen);
 
392
    S3PatternCache      *cache;
 
393
    int                 patx, paty;
 
394
 
 
395
    s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
 
396
    _s3SetPattern (pDrawable->pScreen, s3DrawMap(pDrawable), alu, planemask, pPattern);
 
397
    cache = pPattern->cache;
 
398
    while (nBox--) 
 
399
    {
 
400
        _s3PatRect(s3,cache->x, cache->y,
 
401
                   pBox->x1, pBox->y1, 
 
402
                   pBox->x2-pBox->x1, pBox->y2-pBox->y1);
 
403
        pBox++;
 
404
    }
 
405
    MarkSyncS3 (pDrawable->pScreen);
 
406
}
 
407
 
 
408
void
 
409
s3FillBoxLargeStipple (DrawablePtr pDrawable, GCPtr pGC,
 
410
                       int nBox, BoxPtr pBox)
 
411
{
 
412
    SetupS3(pDrawable->pScreen);
 
413
    DrawablePtr pStipple = &pGC->stipple->drawable;
 
414
    int         xRot = pGC->patOrg.x + pDrawable->x;
 
415
    int         yRot = pGC->patOrg.y + pDrawable->y;
 
416
    FbStip      *stip;
 
417
    FbStride    stipStride;
 
418
    int         stipBpp;
 
419
    int         stipXoff, stipYoff;
 
420
    int         stipWidth, stipHeight;
 
421
    int         dstX, dstY, width, height;
 
422
    
 
423
    stipWidth = pStipple->width;
 
424
    stipHeight = pStipple->height;
 
425
    fbGetStipDrawable (pStipple, stip, stipStride, stipBpp, stipXoff, stipYoff);
 
426
 
 
427
    s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
 
428
    if (pGC->fillStyle == FillOpaqueStippled)
 
429
    {
 
430
        _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,
 
431
                             pGC->fgPixel, pGC->bgPixel);
 
432
    
 
433
    }
 
434
    else
 
435
    {
 
436
        _s3SetTransparentPlaneBlt(s3,pGC->alu,pGC->planemask, pGC->fgPixel);
 
437
    }
 
438
    
 
439
    while (nBox--)
 
440
    {
 
441
        int             stipX, stipY, sx;
 
442
        int             widthTmp;
 
443
        int             h, w;
 
444
        int             x, y;
 
445
    
 
446
        dstX = pBox->x1;
 
447
        dstY = pBox->y1;
 
448
        width = pBox->x2 - pBox->x1;
 
449
        height = pBox->y2 - pBox->y1;
 
450
        pBox++;
 
451
        modulus (dstY - yRot - stipYoff, stipHeight, stipY);
 
452
        modulus (dstX - xRot - stipXoff, stipWidth, stipX);
 
453
        y = dstY;
 
454
        while (height)
 
455
        {
 
456
            h = stipHeight - stipY;
 
457
            if (h > height)
 
458
                h = height;
 
459
            height -= h;
 
460
            widthTmp = width;
 
461
            x = dstX;
 
462
            sx = stipX;
 
463
            while (widthTmp)
 
464
            {
 
465
                w = (stipWidth - sx);
 
466
                if (w > widthTmp)
 
467
                    w = widthTmp;
 
468
                widthTmp -= w;
 
469
                _s3Stipple (s3c,
 
470
                            stip,
 
471
                            stipStride,
 
472
                            sx, stipY,
 
473
                            x, y,
 
474
                            w, h);
 
475
                x += w;
 
476
                sx = 0;
 
477
            }
 
478
            y += h;
 
479
            stipY = 0;
 
480
        }
 
481
    }
 
482
    MarkSyncS3 (pDrawable->pScreen);
 
483
}
 
484
 
 
485
#define NUM_STACK_RECTS 1024
 
486
 
 
487
void
 
488
s3PolyFillRect (DrawablePtr pDrawable, GCPtr pGC, 
 
489
                int nrectFill, xRectangle *prectInit)
 
490
{
 
491
    s3GCPrivate(pGC);
 
492
    xRectangle      *prect;
 
493
    RegionPtr       prgnClip;
 
494
    register BoxPtr pbox;
 
495
    register BoxPtr pboxClipped;
 
496
    BoxPtr          pboxClippedBase;
 
497
    BoxPtr          pextent;
 
498
    BoxRec          stackRects[NUM_STACK_RECTS];
 
499
    int             numRects;
 
500
    int             n;
 
501
    int             xorg, yorg;
 
502
    int             x, y;
 
503
 
 
504
    prgnClip = fbGetCompositeClip(pGC);
 
505
    xorg = pDrawable->x;
 
506
    yorg = pDrawable->y;
 
507
    
 
508
    if (xorg || yorg)
 
509
    {
 
510
        prect = prectInit;
 
511
        n = nrectFill;
 
512
        while(n--)
 
513
        {
 
514
            prect->x += xorg;
 
515
            prect->y += yorg;
 
516
            prect++;
 
517
        }
 
518
    }
 
519
    
 
520
    prect = prectInit;
 
521
 
 
522
    numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
 
523
    if (numRects > NUM_STACK_RECTS)
 
524
    {
 
525
        pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
 
526
        if (!pboxClippedBase)
 
527
            return;
 
528
    }
 
529
    else
 
530
        pboxClippedBase = stackRects;
 
531
 
 
532
    pboxClipped = pboxClippedBase;
 
533
        
 
534
    if (REGION_NUM_RECTS(prgnClip) == 1)
 
535
    {
 
536
        int x1, y1, x2, y2, bx2, by2;
 
537
 
 
538
        pextent = REGION_RECTS(prgnClip);
 
539
        x1 = pextent->x1;
 
540
        y1 = pextent->y1;
 
541
        x2 = pextent->x2;
 
542
        y2 = pextent->y2;
 
543
        while (nrectFill--)
 
544
        {
 
545
            if ((pboxClipped->x1 = prect->x) < x1)
 
546
                pboxClipped->x1 = x1;
 
547
    
 
548
            if ((pboxClipped->y1 = prect->y) < y1)
 
549
                pboxClipped->y1 = y1;
 
550
    
 
551
            bx2 = (int) prect->x + (int) prect->width;
 
552
            if (bx2 > x2)
 
553
                bx2 = x2;
 
554
            pboxClipped->x2 = bx2;
 
555
    
 
556
            by2 = (int) prect->y + (int) prect->height;
 
557
            if (by2 > y2)
 
558
                by2 = y2;
 
559
            pboxClipped->y2 = by2;
 
560
 
 
561
            prect++;
 
562
            if ((pboxClipped->x1 < pboxClipped->x2) &&
 
563
                (pboxClipped->y1 < pboxClipped->y2))
 
564
            {
 
565
                pboxClipped++;
 
566
            }
 
567
        }
 
568
    }
 
569
    else
 
570
    {
 
571
        int x1, y1, x2, y2, bx2, by2;
 
572
 
 
573
        pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
 
574
        x1 = pextent->x1;
 
575
        y1 = pextent->y1;
 
576
        x2 = pextent->x2;
 
577
        y2 = pextent->y2;
 
578
        while (nrectFill--)
 
579
        {
 
580
            BoxRec box;
 
581
    
 
582
            if ((box.x1 = prect->x) < x1)
 
583
                box.x1 = x1;
 
584
    
 
585
            if ((box.y1 = prect->y) < y1)
 
586
                box.y1 = y1;
 
587
    
 
588
            bx2 = (int) prect->x + (int) prect->width;
 
589
            if (bx2 > x2)
 
590
                bx2 = x2;
 
591
            box.x2 = bx2;
 
592
    
 
593
            by2 = (int) prect->y + (int) prect->height;
 
594
            if (by2 > y2)
 
595
                by2 = y2;
 
596
            box.y2 = by2;
 
597
    
 
598
            prect++;
 
599
    
 
600
            if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
 
601
                continue;
 
602
    
 
603
            n = REGION_NUM_RECTS (prgnClip);
 
604
            pbox = REGION_RECTS(prgnClip);
 
605
    
 
606
            /* clip the rectangle to each box in the clip region
 
607
               this is logically equivalent to calling Intersect()
 
608
            */
 
609
            while(n--)
 
610
            {
 
611
                pboxClipped->x1 = max(box.x1, pbox->x1);
 
612
                pboxClipped->y1 = max(box.y1, pbox->y1);
 
613
                pboxClipped->x2 = min(box.x2, pbox->x2);
 
614
                pboxClipped->y2 = min(box.y2, pbox->y2);
 
615
                pbox++;
 
616
 
 
617
                /* see if clipping left anything */
 
618
                if(pboxClipped->x1 < pboxClipped->x2 && 
 
619
                   pboxClipped->y1 < pboxClipped->y2)
 
620
                {
 
621
                    pboxClipped++;
 
622
                }
 
623
            }
 
624
        }
 
625
    }
 
626
    if (pboxClipped != pboxClippedBase)
 
627
    {
 
628
        if (pGC->fillStyle == FillSolid)
 
629
            s3FillBoxSolid(pDrawable,
 
630
                           pboxClipped-pboxClippedBase, pboxClippedBase,
 
631
                           pGC->fgPixel, pGC->alu, pGC->planemask);
 
632
        else if (s3Priv->pPattern)
 
633
            s3FillBoxPattern (pDrawable,
 
634
                              pboxClipped-pboxClippedBase, pboxClippedBase,
 
635
                              pGC->alu, pGC->planemask,
 
636
                              s3Priv->pPattern);
 
637
        else
 
638
            s3FillBoxLargeStipple (pDrawable, pGC,
 
639
                                   pboxClipped-pboxClippedBase, 
 
640
                                   pboxClippedBase);
 
641
    }
 
642
    if (pboxClippedBase != stackRects)
 
643
        DEALLOCATE_LOCAL(pboxClippedBase);
 
644
}
 
645
 
 
646
void
 
647
_s3FillSpanLargeStipple (DrawablePtr pDrawable, GCPtr pGC,
 
648
                         int n, DDXPointPtr ppt, int *pwidth)
 
649
{
 
650
    SetupS3 (pDrawable->pScreen);
 
651
    DrawablePtr pStipple = &pGC->stipple->drawable;
 
652
    int         xRot = pGC->patOrg.x + pDrawable->x;
 
653
    int         yRot = pGC->patOrg.y + pDrawable->y;
 
654
    FbStip      *stip;
 
655
    FbStride    stipStride;
 
656
    int         stipBpp;
 
657
    int         stipXoff, stipYoff;
 
658
    int         stipWidth, stipHeight;
 
659
    int         dstX, dstY, width, height;
 
660
    
 
661
    s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
662
    stipWidth = pStipple->width;
 
663
    stipHeight = pStipple->height;
 
664
    fbGetStipDrawable (pStipple, stip, stipStride, stipBpp, stipXoff, stipYoff);
 
665
    if (pGC->fillStyle == FillOpaqueStippled)
 
666
    {
 
667
        _s3SetOpaquePlaneBlt(s3,pGC->alu,pGC->planemask,
 
668
                             pGC->fgPixel, pGC->bgPixel);
 
669
    
 
670
    }
 
671
    else
 
672
    {
 
673
        _s3SetTransparentPlaneBlt(s3,pGC->alu,pGC->planemask, pGC->fgPixel);
 
674
    }
 
675
    while (n--)
 
676
    {
 
677
        int             stipX, stipY, sx;
 
678
        int             w;
 
679
        int             x, y;
 
680
    
 
681
        dstX = ppt->x;
 
682
        dstY = ppt->y;
 
683
        ppt++;
 
684
        width = *pwidth++;
 
685
        modulus (dstY - yRot - stipYoff, stipHeight, stipY);
 
686
        modulus (dstX - xRot - stipXoff, stipWidth, stipX);
 
687
        y = dstY;
 
688
        x = dstX;
 
689
        sx = stipX;
 
690
        while (width)
 
691
        {
 
692
            w = (stipWidth - sx);
 
693
            if (w > width)
 
694
                w = width;
 
695
            width -= w;
 
696
            _s3Stipple (s3c,
 
697
                        stip,
 
698
                        stipStride,
 
699
                        sx, stipY,
 
700
                        x, y,
 
701
                        w, 1);
 
702
            x += w;
 
703
            sx = 0;
 
704
        }
 
705
    }
 
706
}
 
707
 
 
708
void
 
709
s3FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n, 
 
710
             DDXPointPtr ppt, int *pwidth, int fSorted)
 
711
{
 
712
    s3GCPrivate(pGC);
 
713
    SetupS3(pDrawable->pScreen);
 
714
    int             x, y, x1, y1, x2, y2;
 
715
    int             width;
 
716
                                /* next three parameters are post-clip */
 
717
    int             nTmp;
 
718
    int             *pwidthFree;/* copies of the pointers to free */
 
719
    DDXPointPtr     pptFree;
 
720
    BoxPtr          extents;
 
721
    S3PatternCache  *cache;
 
722
    RegionPtr       pClip = fbGetCompositeClip (pGC);
 
723
 
 
724
    s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
725
    if (REGION_NUM_RECTS(pClip) == 1 && 
 
726
        (pGC->fillStyle == FillSolid  || s3Priv->pPattern))
 
727
    {
 
728
        extents = REGION_RECTS(pClip);
 
729
        x1 = extents->x1;
 
730
        x2 = extents->x2;
 
731
        y1 = extents->y1;
 
732
        y2 = extents->y2;
 
733
        if (pGC->fillStyle == FillSolid)
 
734
        {
 
735
            _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
 
736
            cache = 0;
 
737
        }
 
738
        else
 
739
        {
 
740
            _s3SetPattern (pDrawable->pScreen, s3GCMap(pGC), pGC->alu, pGC->planemask,
 
741
                           s3Priv->pPattern);
 
742
            cache = s3Priv->pPattern->cache;
 
743
        }
 
744
        while (n--)
 
745
        {
 
746
            y = ppt->y;
 
747
            if (y1 <= y && y < y2)
 
748
            {
 
749
                x = ppt->x;
 
750
                width = *pwidth;
 
751
                if (x < x1)
 
752
                {
 
753
                    width -= (x1 - x);
 
754
                    x = x1;
 
755
                }
 
756
                if (x2 < x + width)
 
757
                    width = x2 - x;
 
758
                if (width > 0)
 
759
                {
 
760
                    if (cache)
 
761
                    {
 
762
                        _s3PatRect(s3, cache->x, cache->y, x, y, width, 1);
 
763
                    }
 
764
                    else
 
765
                    {
 
766
                        _s3SolidRect(s3,x,y,width,1);
 
767
                    }
 
768
                }
 
769
            }
 
770
            ppt++;
 
771
            pwidth++;
 
772
        }
 
773
    }
 
774
    else
 
775
    {
 
776
        nTmp = n * miFindMaxBand(pClip);
 
777
        pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
 
778
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
 
779
        if(!pptFree || !pwidthFree)
 
780
        {
 
781
            if (pptFree) DEALLOCATE_LOCAL(pptFree);
 
782
            if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
 
783
            return;
 
784
        }
 
785
        n = miClipSpans(fbGetCompositeClip(pGC),
 
786
                        ppt, pwidth, n,
 
787
                        pptFree, pwidthFree, fSorted);
 
788
        pwidth = pwidthFree;
 
789
        ppt = pptFree;
 
790
        if (pGC->fillStyle == FillSolid)
 
791
        {
 
792
            _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
 
793
            while (n--)
 
794
            {
 
795
                x = ppt->x;
 
796
                y = ppt->y;
 
797
                ppt++;
 
798
                width = *pwidth++;
 
799
                if (width)
 
800
                {
 
801
                    _s3SolidRect(s3,x,y,width,1);
 
802
                }
 
803
            }
 
804
        }
 
805
        else if (s3Priv->pPattern)
 
806
        {
 
807
            _s3SetPattern (pDrawable->pScreen, s3GCMap(pGC), pGC->alu, pGC->planemask,
 
808
                           s3Priv->pPattern);
 
809
            cache = s3Priv->pPattern->cache;
 
810
            while (n--)
 
811
            {
 
812
                x = ppt->x;
 
813
                y = ppt->y;
 
814
                ppt++;
 
815
                width = *pwidth++;
 
816
                if (width)
 
817
                {
 
818
                    _s3PatRect(s3, cache->x, cache->y, x, y, width, 1);
 
819
                }
 
820
            }
 
821
        }
 
822
        else
 
823
        {
 
824
            _s3FillSpanLargeStipple (pDrawable, pGC, n, ppt, pwidth);
 
825
        }
 
826
        DEALLOCATE_LOCAL(pptFree);
 
827
        DEALLOCATE_LOCAL(pwidthFree);
 
828
    }
 
829
    MarkSyncS3 (pDrawable->pScreen);
 
830
}
 
831
 
 
832
#include "mifillarc.h"
 
833
 
 
834
#define FILLSPAN(s3,y,__x1,__x2) {\
 
835
    DRAW_DEBUG ((DEBUG_ARCS, "FILLSPAN %d: %d->%d", y, __x1, __x2)); \
 
836
    if ((__x2) >= (__x1)) {\
 
837
        _s3SolidRect(s3,(__x1),(y),(__x2)-(__x1)+1,1); \
 
838
    } \
 
839
}
 
840
 
 
841
#define FILLSLICESPANS(flip,__y) \
 
842
    if (!flip) \
 
843
    { \
 
844
        FILLSPAN(s3,__y,xl,xr) \
 
845
    } \
 
846
    else \
 
847
    { \
 
848
        xc = xorg - x; \
 
849
        FILLSPAN(s3, __y, xc, xr) \
 
850
        xc += slw - 1; \
 
851
        FILLSPAN(s3, __y, xl, xc) \
 
852
    }
 
853
 
 
854
static void
 
855
_s3FillEllipse (DrawablePtr pDraw, S3Ptr s3, xArc *arc)
 
856
{
 
857
    KdScreenPriv(pDraw->pScreen);
 
858
    int x, y, e;
 
859
    int yk, xk, ym, xm, dx, dy, xorg, yorg;
 
860
    int y_top, y_bot;
 
861
    miFillArcRec info;
 
862
    register int xpos;
 
863
    int slw;
 
864
 
 
865
    s3SetGlobalBitmap (pDraw->pScreen, s3DrawMap (pDraw));
 
866
    miFillArcSetup(arc, &info);
 
867
    MIFILLARCSETUP();
 
868
    y_top = pDraw->y + yorg - y;
 
869
    y_bot = pDraw->y + yorg + y + dy;
 
870
    xorg += pDraw->x;
 
871
    while (y)
 
872
    {
 
873
        y_top++;
 
874
        y_bot--;
 
875
        MIFILLARCSTEP(slw);
 
876
        if (!slw)
 
877
            continue;
 
878
        xpos = xorg - x;
 
879
        _s3SolidRect (s3,xpos,y_top,slw,1);
 
880
        if (miFillArcLower(slw))
 
881
            _s3SolidRect (s3,xpos,y_bot,slw,1);
 
882
    }
 
883
}
 
884
 
 
885
 
 
886
static void
 
887
_s3FillArcSlice (DrawablePtr pDraw, GCPtr pGC, S3Ptr s3, xArc *arc)
 
888
{
 
889
    KdScreenPriv(pDraw->pScreen);
 
890
    int yk, xk, ym, xm, dx, dy, xorg, yorg, slw;
 
891
    register int x, y, e;
 
892
    miFillArcRec info;
 
893
    miArcSliceRec slice;
 
894
    int xl, xr, xc;
 
895
    int y_top, y_bot;
 
896
 
 
897
    s3SetGlobalBitmap (pDraw->pScreen, s3DrawMap (pDraw));
 
898
    DRAW_DEBUG ((DEBUG_ARCS, "slice %dx%d+%d+%d %d->%d",
 
899
                 arc->width, arc->height, arc->x, arc->y,
 
900
                 arc->angle1, arc->angle2));
 
901
    miFillArcSetup(arc, &info);
 
902
    miFillArcSliceSetup(arc, &slice, pGC);
 
903
    DRAW_DEBUG ((DEBUG_ARCS, "edge1.x %d edge2.x %d", 
 
904
                slice.edge1.x, slice.edge2.x));
 
905
    MIFILLARCSETUP();
 
906
    DRAW_DEBUG ((DEBUG_ARCS, "xorg %d yorg %d",
 
907
                xorg, yorg));
 
908
    xorg += pDraw->x;
 
909
    yorg += pDraw->y;
 
910
    y_top = yorg - y;
 
911
    y_bot = yorg + y + dy;
 
912
    slice.edge1.x += pDraw->x;
 
913
    slice.edge2.x += pDraw->x;
 
914
    DRAW_DEBUG ((DEBUG_ARCS, "xorg %d y_top %d y_bot %d",
 
915
                 xorg, y_top, y_bot));
 
916
    while (y > 0)
 
917
    {
 
918
        y_top++;
 
919
        y_bot--;
 
920
        MIFILLARCSTEP(slw);
 
921
        MIARCSLICESTEP(slice.edge1);
 
922
        MIARCSLICESTEP(slice.edge2);
 
923
        if (miFillSliceUpper(slice))
 
924
        {
 
925
            MIARCSLICEUPPER(xl, xr, slice, slw);
 
926
            FILLSLICESPANS(slice.flip_top, y_top);
 
927
        }
 
928
        if (miFillSliceLower(slice))
 
929
        {
 
930
            MIARCSLICELOWER(xl, xr, slice, slw);
 
931
            FILLSLICESPANS(slice.flip_bot, y_bot);
 
932
        }
 
933
    }
 
934
}
 
935
 
 
936
void
 
937
s3PolyFillArcSolid (DrawablePtr pDraw, GCPtr pGC, int narcs, xArc *parcs)
 
938
{
 
939
    SetupS3(pDraw->pScreen);
 
940
    xArc            *arc;
 
941
    int             i;
 
942
    int             x, y;
 
943
    BoxRec          box;
 
944
    RegionPtr       pClip = fbGetCompositeClip(pGC);
 
945
    BOOL            set;
 
946
 
 
947
    set = FALSE;
 
948
    for (; --narcs >= 0; parcs++)
 
949
    {
 
950
        if (miFillArcEmpty(parcs))
 
951
            continue;
 
952
        if (miCanFillArc(parcs))
 
953
        {
 
954
            box.x1 = parcs->x + pDraw->x;
 
955
            box.y1 = parcs->y + pDraw->y;
 
956
            box.x2 = box.x1 + (int)parcs->width + 1;
 
957
            box.y2 = box.y1 + (int)parcs->height + 1;
 
958
            switch (RECT_IN_REGION(pDraw->pScreen, pClip, &box))
 
959
            {
 
960
            case rgnIN:
 
961
                if (!set)
 
962
                {
 
963
                    _s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
 
964
                    set = TRUE;
 
965
                }
 
966
                if ((parcs->angle2 >= FULLCIRCLE) ||
 
967
                    (parcs->angle2 <= -FULLCIRCLE))
 
968
                {
 
969
                    DRAW_DEBUG ((DEBUG_ARCS, "Full circle ellipse %dx%d",
 
970
                                 parcs->width, parcs->height));
 
971
                    _s3FillEllipse (pDraw, s3, parcs);
 
972
                }
 
973
                else
 
974
                {
 
975
                    DRAW_DEBUG ((DEBUG_ARCS, "Partial ellipse %dx%d",
 
976
                                 parcs->width, parcs->height));
 
977
                    _s3FillArcSlice (pDraw, pGC, s3, parcs);
 
978
                }
 
979
                /* fall through ... */
 
980
            case rgnOUT:
 
981
                continue;
 
982
            case rgnPART:
 
983
                break;
 
984
            }
 
985
        }
 
986
        if (set)
 
987
        {
 
988
            MarkSyncS3 (pDraw->pScreen);
 
989
            set = FALSE;
 
990
        }
 
991
        KdCheckPolyFillArc(pDraw, pGC, 1, parcs);
 
992
    }
 
993
    if (set)
 
994
    {
 
995
        MarkSyncS3 (pDraw->pScreen);
 
996
        set = FALSE;
 
997
    }
 
998
}
 
999
 
 
1000
void
 
1001
s3FillPoly (DrawablePtr pDrawable, GCPtr pGC, int shape, 
 
1002
            int mode, int countInit, DDXPointPtr ptsIn)
 
1003
{
 
1004
    SetupS3(pDrawable->pScreen);
 
1005
    int             nwidth;
 
1006
    int             maxy;
 
1007
    int             origin;
 
1008
    int             count;
 
1009
    register int    vertex1, vertex2;
 
1010
    int             c;
 
1011
    RegionPtr       pClip = fbGetCompositeClip(pGC);    
 
1012
    BoxPtr          extents;
 
1013
    int             clip;
 
1014
    int             y, sy;
 
1015
    int             *vertex1p, *vertex2p;
 
1016
    int             *endp;
 
1017
    int             x1, x2, sx;
 
1018
    int             dx1, dx2;
 
1019
    int             dy1, dy2;
 
1020
    int             e1, e2;
 
1021
    int             step1, step2;
 
1022
    int             sign1, sign2;
 
1023
    int             h;
 
1024
    int             l, r;
 
1025
    int             nmiddle;
 
1026
 
 
1027
    if (mode == CoordModePrevious || REGION_NUM_RECTS(pClip) != 1)
 
1028
    {
 
1029
        KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn);
 
1030
        return;
 
1031
    }
 
1032
    
 
1033
    s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
1034
    sy = pDrawable->y;
 
1035
    sx = pDrawable->x;
 
1036
    origin = *((int *) &pDrawable->x);
 
1037
    origin -= (origin & 0x8000) << 1;
 
1038
    extents = &pClip->extents;
 
1039
    vertex1 = *((int *) &extents->x1) - origin;
 
1040
    vertex2 = *((int *) &extents->x2) - origin - 0x00010001;
 
1041
    clip = 0;
 
1042
    
 
1043
    y = 32767;
 
1044
    maxy = 0;
 
1045
    vertex2p = (int *) ptsIn;
 
1046
    endp = vertex2p + countInit;
 
1047
    if (shape == Convex)
 
1048
    {
 
1049
        count = countInit;
 
1050
        while (count--)
 
1051
        {
 
1052
            c = *vertex2p;
 
1053
            clip |= (c - vertex1) | (vertex2 - c);
 
1054
            c = intToY(c);
 
1055
            DRAW_DEBUG ((DEBUG_POLYGON, "Y coordinate %d", c));
 
1056
            if (c < y) 
 
1057
            {
 
1058
                y = c;
 
1059
                vertex1p = vertex2p;
 
1060
            }
 
1061
            vertex2p++;
 
1062
            if (c > maxy)
 
1063
                maxy = c;
 
1064
        }
 
1065
    }
 
1066
    else
 
1067
    {
 
1068
        int yFlip = 0;
 
1069
        dx1 = 1;
 
1070
        x2 = -1;
 
1071
        x1 = -1;
 
1072
        count = countInit;
 
1073
        while (count--)
 
1074
        {
 
1075
            c = *vertex2p;
 
1076
            clip |= (c - vertex1) | (vertex2 - c);
 
1077
            c = intToY(c);
 
1078
            DRAW_DEBUG ((DEBUG_POLYGON, "Y coordinate %d", c));
 
1079
            if (c < y) 
 
1080
            {
 
1081
                y = c;
 
1082
                vertex1p = vertex2p;
 
1083
            }
 
1084
            vertex2p++;
 
1085
            if (c > maxy)
 
1086
                maxy = c;
 
1087
            if (c == x1)
 
1088
                continue;
 
1089
            if (dx1 > 0)
 
1090
            {
 
1091
                if (x2 < 0)
 
1092
                    x2 = c;
 
1093
                else
 
1094
                    dx2 = dx1 = (c - x1) >> 31;
 
1095
            }
 
1096
            else
 
1097
                if ((c - x1) >> 31 != dx1) 
 
1098
                {
 
1099
                    dx1 = ~dx1;
 
1100
                    yFlip++;
 
1101
                }
 
1102
            x1 = c;
 
1103
        }
 
1104
        x1 = (x2 - c) >> 31;
 
1105
        if (x1 != dx1)
 
1106
            yFlip++;
 
1107
        if (x1 != dx2)
 
1108
            yFlip++;
 
1109
        if (yFlip != 2) 
 
1110
            clip = 0x8000;
 
1111
    }
 
1112
    if (y == maxy)
 
1113
        return;
 
1114
 
 
1115
    if (clip & 0x80008000)
 
1116
    {
 
1117
        KdCheckFillPolygon (pDrawable, pGC, shape, mode, countInit, ptsIn);
 
1118
        return;
 
1119
    }
 
1120
    _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
 
1121
    
 
1122
    vertex2p = vertex1p;
 
1123
    vertex2 = vertex1 = *vertex2p++;
 
1124
    if (vertex2p == endp)
 
1125
        vertex2p = (int *) ptsIn;
 
1126
#define Setup(c,x,vertex,dx,dy,e,sign,step) {\
 
1127
    x = intToX(vertex); \
 
1128
    if (dy = intToY(c) - y) { \
 
1129
        dx = intToX(c) - x; \
 
1130
        step = 0; \
 
1131
        if (dx >= 0) \
 
1132
        { \
 
1133
            e = 0; \
 
1134
            sign = 1; \
 
1135
            if (dx >= dy) {\
 
1136
                step = dx / dy; \
 
1137
                dx = dx % dy; \
 
1138
            } \
 
1139
        } \
 
1140
        else \
 
1141
        { \
 
1142
            e = 1 - dy; \
 
1143
            sign = -1; \
 
1144
            dx = -dx; \
 
1145
            if (dx >= dy) { \
 
1146
                step = - (dx / dy); \
 
1147
                dx = dx % dy; \
 
1148
            } \
 
1149
        } \
 
1150
    } \
 
1151
    x += sx; \
 
1152
    vertex = c; \
 
1153
}
 
1154
 
 
1155
#define Step(x,dx,dy,e,sign,step) {\
 
1156
    x += step; \
 
1157
    if ((e += dx) > 0) \
 
1158
    { \
 
1159
        x += sign; \
 
1160
        e -= dy; \
 
1161
    } \
 
1162
}
 
1163
    sy += y;
 
1164
    DRAW_DEBUG ((DEBUG_POLYGON, "Starting polygon at %d", sy));
 
1165
    for (;;)
 
1166
    {
 
1167
        DRAW_DEBUG ((DEBUG_POLYGON, "vertex1 0x%x vertex2 0x%x y %d vy1 %d vy2 %d",
 
1168
                     vertex1, vertex2,
 
1169
                     y, intToY(vertex1), intToY (vertex2)));
 
1170
        if (y == intToY(vertex1))
 
1171
        {
 
1172
            DRAW_DEBUG ((DEBUG_POLYGON, "Find next -- vertext"));
 
1173
            do
 
1174
            {
 
1175
                if (vertex1p == (int *) ptsIn)
 
1176
                    vertex1p = endp;
 
1177
                c = *--vertex1p;
 
1178
                Setup (c,x1,vertex1,dx1,dy1,e1,sign1,step1);
 
1179
                DRAW_DEBUG ((DEBUG_POLYGON, "-- vertex 0x%x y %d",
 
1180
                             vertex1, intToY(vertex1)));
 
1181
            } while (y >= intToY(vertex1));
 
1182
            h = dy1;
 
1183
        }
 
1184
        else
 
1185
        {
 
1186
            Step(x1,dx1,dy1,e1,sign1,step1)
 
1187
            h = intToY(vertex1) - y;
 
1188
        }
 
1189
        if (y == intToY(vertex2))
 
1190
        {
 
1191
            DRAW_DEBUG ((DEBUG_POLYGON, "Find next ++ vertext"));
 
1192
            do
 
1193
            {
 
1194
                c = *vertex2p++;
 
1195
                if (vertex2p == endp)
 
1196
                    vertex2p = (int *) ptsIn;
 
1197
                Setup (c,x2,vertex2,dx2,dy2,e2,sign2,step2)
 
1198
                DRAW_DEBUG ((DEBUG_POLYGON, "++ vertex 0x%x y %d",
 
1199
                             vertex1, intToY(vertex1)));
 
1200
            } while (y >= intToY(vertex2));
 
1201
            if (dy2 < h)
 
1202
                h = dy2;
 
1203
        }
 
1204
        else
 
1205
        {
 
1206
            Step(x2,dx2,dy2,e2,sign2,step2)
 
1207
            if ((c = (intToY(vertex2) - y)) < h)
 
1208
                h = c;
 
1209
        }
 
1210
        DRAW_DEBUG ((DEBUG_POLYGON, "This band %d", h));
 
1211
        /* fill spans for this segment */
 
1212
        for (;;)
 
1213
        {
 
1214
            nmiddle = x2 - x1;
 
1215
            DRAW_DEBUG ((DEBUG_POLYGON, "This span %d->%d", x1, x2));
 
1216
            if (nmiddle)
 
1217
            {
 
1218
                l = x1;
 
1219
                if (nmiddle < 0)
 
1220
                {
 
1221
                    nmiddle = -nmiddle;
 
1222
                    l = x2;
 
1223
                }
 
1224
                _s3SolidRect(s3,l,sy,nmiddle,1);
 
1225
            }
 
1226
            y++;
 
1227
            sy++;
 
1228
            if (!--h)
 
1229
                break;
 
1230
            Step(x1,dx1,dy1,e1,sign1,step1)
 
1231
            Step(x2,dx2,dy2,e2,sign2,step2)
 
1232
        }
 
1233
        if (y == maxy)
 
1234
            break;
 
1235
    }
 
1236
    MarkSyncS3 (pDrawable->pScreen);
 
1237
}
 
1238
 
 
1239
void
 
1240
s3PolyGlyphBltClipped (DrawablePtr pDrawable,
 
1241
                       GCPtr pGC,
 
1242
                       int x, int y, 
 
1243
                       unsigned int nglyph,
 
1244
                       CharInfoPtr *ppciInit, 
 
1245
                       pointer pglyphBase)
 
1246
{
 
1247
    SetupS3(pDrawable->pScreen);
 
1248
    int             h;
 
1249
    int             w;
 
1250
    int             xBack, yBack;
 
1251
    int             hBack, wBack;
 
1252
    int             lw;
 
1253
    FontPtr         pfont = pGC->font;
 
1254
    CharInfoPtr     pci;
 
1255
    unsigned long   *bits;
 
1256
    BoxPtr          extents;
 
1257
    BoxRec          bbox;
 
1258
    CARD32          b;
 
1259
    CharInfoPtr     *ppci;
 
1260
    FbGCPrivPtr     fbPriv = fbGetGCPrivate(pGC);
 
1261
    RegionPtr       pClip = fbGetCompositeClip(pGC);
 
1262
    BoxPtr          pBox;
 
1263
    int             nbox;
 
1264
    int             x1, y1, x2, y2;
 
1265
    unsigned char   alu;
 
1266
    Bool            set;
 
1267
    PixTransDeclare;
 
1268
 
 
1269
    s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
1270
    x += pDrawable->x;
 
1271
    y += pDrawable->y;
 
1272
 
 
1273
    if (pglyphBase == (pointer) 1)
 
1274
    {
 
1275
        xBack = x;
 
1276
        yBack = y - FONTASCENT(pGC->font);
 
1277
        wBack = 0;
 
1278
        hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
 
1279
        if (hBack)
 
1280
        {
 
1281
            h = nglyph;
 
1282
            ppci = ppciInit;
 
1283
            while (h--)
 
1284
                wBack += (*ppci++)->metrics.characterWidth;
 
1285
        }
 
1286
        if (wBack < 0)
 
1287
        {
 
1288
            xBack = xBack + wBack;
 
1289
            wBack = -wBack;
 
1290
        }
 
1291
        if (hBack < 0)
 
1292
        {
 
1293
            yBack = yBack + hBack;
 
1294
            hBack = -hBack;
 
1295
        }
 
1296
        alu = GXcopy;
 
1297
    }
 
1298
    else
 
1299
    {
 
1300
        wBack = 0;
 
1301
        alu = pGC->alu;
 
1302
    }
 
1303
    
 
1304
    if (wBack)
 
1305
    {
 
1306
        _s3SetSolidFill (s3, pGC->bgPixel, GXcopy, pGC->planemask);
 
1307
        for (nbox = REGION_NUM_RECTS (pClip),
 
1308
             pBox = REGION_RECTS (pClip);
 
1309
             nbox--;
 
1310
             pBox++)
 
1311
        {
 
1312
            x1 = xBack;
 
1313
            x2 = xBack + wBack;
 
1314
            y1 = yBack;
 
1315
            y2 = yBack + hBack;
 
1316
            if (x1 < pBox->x1) x1 = pBox->x1;
 
1317
            if (x2 > pBox->x2) x2 = pBox->x2;
 
1318
            if (y1 < pBox->y1) y1 = pBox->y1;
 
1319
            if (y2 > pBox->y2) y2 = pBox->y2;
 
1320
            if (x1 < x2 && y1 < y2)
 
1321
            {
 
1322
                _s3SolidRect (s3, x1, y1, x2 - x1, y2 - y1);
 
1323
            }
 
1324
        }
 
1325
        MarkSyncS3 (pDrawable->pScreen);
 
1326
    }
 
1327
    ppci = ppciInit;
 
1328
    set = FALSE;
 
1329
    while (nglyph--)
 
1330
    {
 
1331
        pci = *ppci++;
 
1332
        h = pci->metrics.ascent + pci->metrics.descent;
 
1333
        w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
 
1334
        x1 = x + pci->metrics.leftSideBearing;
 
1335
        y1 = y - pci->metrics.ascent;
 
1336
        bbox.x1 = x1;
 
1337
        bbox.y1 = y1;
 
1338
        bbox.x2 = x1 + w;
 
1339
        bbox.y2 = y1 + h;
 
1340
        switch (RECT_IN_REGION(pGC->pScreen, pClip, &bbox))
 
1341
        {
 
1342
        case rgnIN:
 
1343
#if 1
 
1344
            lw = h * ((w + 31) >> 5);
 
1345
            if (lw)
 
1346
            {
 
1347
                if (!set)
 
1348
                {
 
1349
                    _s3SetTransparentPlaneBlt (s3, alu, pGC->planemask, pGC->fgPixel);
 
1350
                    set = TRUE;
 
1351
                }
 
1352
                _s3PlaneBlt(s3,
 
1353
                            x + pci->metrics.leftSideBearing,
 
1354
                            y - pci->metrics.ascent,
 
1355
                            w, h);
 
1356
                bits = (unsigned long *) pci->bits;
 
1357
                PixTransStart (lw);
 
1358
                while (lw--) 
 
1359
                {
 
1360
                    b = *bits++;
 
1361
                    S3AdjustBits32 (b);
 
1362
                    PixTransStore(b);
 
1363
                }
 
1364
                MarkSyncS3 (pDrawable->pScreen);
 
1365
            }
 
1366
            break;
 
1367
#endif
 
1368
        case rgnPART:
 
1369
            set = FALSE;
 
1370
            CheckSyncS3 (pDrawable->pScreen);
 
1371
            fbPutXYImage (pDrawable,
 
1372
                          pClip,
 
1373
                          fbPriv->fg,
 
1374
                          fbPriv->bg,
 
1375
                          fbPriv->pm,
 
1376
                          alu,
 
1377
                          FALSE,
 
1378
                          x1, y1,
 
1379
                          w, h,
 
1380
                          (FbStip *) pci->bits,
 
1381
                          (w + 31) >> 5,
 
1382
                          0);
 
1383
            break;
 
1384
        case rgnOUT:
 
1385
            break;
 
1386
        }
 
1387
        x += pci->metrics.characterWidth;
 
1388
    }
 
1389
}
 
1390
                       
 
1391
/*
 
1392
 * Blt glyphs using S3 image transfer register, this does both
 
1393
 * poly glyph blt and image glyph blt (when pglyphBase == 1)
 
1394
 */
 
1395
 
 
1396
void
 
1397
s3PolyGlyphBlt (DrawablePtr pDrawable, 
 
1398
                GCPtr pGC, 
 
1399
                int x, int y, 
 
1400
                unsigned int nglyph,
 
1401
                CharInfoPtr *ppciInit, 
 
1402
                pointer pglyphBase)
 
1403
{
 
1404
    SetupS3(pDrawable->pScreen);
 
1405
    int             h;
 
1406
    int             w;
 
1407
    int             xBack, yBack;
 
1408
    int             hBack, wBack;
 
1409
    int             lw;
 
1410
    FontPtr         pfont = pGC->font;
 
1411
    CharInfoPtr     pci;
 
1412
    unsigned long   *bits;
 
1413
    BoxPtr          extents;
 
1414
    BoxRec          bbox;
 
1415
    CARD32          b;
 
1416
    CharInfoPtr     *ppci;
 
1417
    unsigned char   alu;
 
1418
    PixTransDeclare;
 
1419
 
 
1420
    s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
1421
    x += pDrawable->x;
 
1422
    y += pDrawable->y;
 
1423
 
 
1424
    /* compute an approximate (but covering) bounding box */
 
1425
    ppci = ppciInit;
 
1426
    w = 0;
 
1427
    h = nglyph;
 
1428
    while (h--)
 
1429
        w += (*ppci++)->metrics.characterWidth;
 
1430
    if (w < 0)
 
1431
    {
 
1432
        bbox.x1 = x + w;
 
1433
        bbox.x2 = x;
 
1434
    }
 
1435
    else
 
1436
    {
 
1437
        bbox.x1 = x;
 
1438
        bbox.x2 = x + w;
 
1439
    }
 
1440
    w = FONTMINBOUNDS(pfont,leftSideBearing);
 
1441
    if (w < 0)
 
1442
        bbox.x1 += w;
 
1443
    w = FONTMAXBOUNDS(pfont, rightSideBearing) - FONTMINBOUNDS(pfont, characterWidth);
 
1444
    if (w > 0)
 
1445
        bbox.x2 += w;
 
1446
    bbox.y1 = y - FONTMAXBOUNDS(pfont,ascent);
 
1447
    bbox.y2 = y + FONTMAXBOUNDS(pfont,descent);
 
1448
    
 
1449
    DRAW_DEBUG ((DEBUG_TEXT, "PolyGlyphBlt %d box is %d %d", nglyph,
 
1450
                 bbox.x1, bbox.x2));
 
1451
    switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
 
1452
    {
 
1453
    case rgnIN:
 
1454
        break;
 
1455
    case rgnPART:
 
1456
        s3PolyGlyphBltClipped(pDrawable, pGC, x - pDrawable->x,
 
1457
                              y - pDrawable->y,
 
1458
                              nglyph, ppciInit, pglyphBase);
 
1459
    case rgnOUT:
 
1460
        return;
 
1461
    }
 
1462
    
 
1463
    if (pglyphBase == (pointer) 1)
 
1464
    {
 
1465
        xBack = x;
 
1466
        yBack = y - FONTASCENT(pGC->font);
 
1467
        wBack = 0;
 
1468
        hBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
 
1469
        if (hBack)
 
1470
        {
 
1471
            h = nglyph;
 
1472
            ppci = ppciInit;
 
1473
            while (h--)
 
1474
                wBack += (*ppci++)->metrics.characterWidth;
 
1475
        }
 
1476
        if (wBack < 0)
 
1477
        {
 
1478
            xBack = xBack + wBack;
 
1479
            wBack = -wBack;
 
1480
        }
 
1481
        if (hBack < 0)
 
1482
        {
 
1483
            yBack = yBack + hBack;
 
1484
            hBack = -hBack;
 
1485
        }
 
1486
        alu = GXcopy;
 
1487
    }
 
1488
    else
 
1489
    {
 
1490
        wBack = 0;
 
1491
        alu = pGC->alu;
 
1492
    }
 
1493
    
 
1494
    if (wBack)
 
1495
    {
 
1496
        _s3SetSolidFill (s3, pGC->bgPixel, GXcopy, pGC->planemask);
 
1497
        _s3SolidRect (s3, xBack, yBack, wBack, hBack);
 
1498
    }
 
1499
    _s3SetTransparentPlaneBlt (s3, alu, pGC->planemask, pGC->fgPixel);
 
1500
    ppci = ppciInit;
 
1501
    while (nglyph--)
 
1502
    {
 
1503
        pci = *ppci++;
 
1504
        h = pci->metrics.ascent + pci->metrics.descent;
 
1505
        w = pci->metrics.rightSideBearing - pci->metrics.leftSideBearing;
 
1506
        lw = h * ((w + 31) >> 5);
 
1507
        if (lw)
 
1508
        {
 
1509
            _s3PlaneBlt(s3,
 
1510
                        x + pci->metrics.leftSideBearing,
 
1511
                        y - pci->metrics.ascent,
 
1512
                        w, h);
 
1513
            bits = (unsigned long *) pci->bits;
 
1514
            PixTransStart(lw);
 
1515
            while (lw--) 
 
1516
            {
 
1517
                b = *bits++;
 
1518
                S3AdjustBits32 (b);
 
1519
                PixTransStore(b);
 
1520
            }
 
1521
        }
 
1522
        x += pci->metrics.characterWidth;
 
1523
    }
 
1524
    MarkSyncS3 (pDrawable->pScreen);
 
1525
}
 
1526
 
 
1527
void
 
1528
s3ImageGlyphBlt (DrawablePtr pDrawable, 
 
1529
                GCPtr pGC, 
 
1530
                int x, int y, 
 
1531
                unsigned int nglyph, 
 
1532
                CharInfoPtr *ppci, 
 
1533
                pointer pglyphBase)
 
1534
{
 
1535
    s3PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, (pointer) 1);
 
1536
}
 
1537
 
 
1538
/*
 
1539
 * Blt TE fonts using S3 image transfer.  Differs from
 
1540
 * above in that it doesn't need to fill a solid rect for
 
1541
 * the background and it can draw multiple characters at a time
 
1542
 */
 
1543
 
 
1544
void
 
1545
s3ImageTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
 
1546
                   int xInit, int yInit,
 
1547
                   unsigned int nglyph,
 
1548
                   CharInfoPtr *ppci,
 
1549
                   pointer pglyphBase)
 
1550
{
 
1551
    SetupS3(pDrawable->pScreen);
 
1552
    int             x, y;
 
1553
    int             h, lw, lwTmp;
 
1554
    int             w;
 
1555
    FontPtr         pfont = pGC->font;
 
1556
    unsigned long   *char1, *char2, *char3, *char4;
 
1557
    int             widthGlyphs, widthGlyph;
 
1558
    BoxRec          bbox;
 
1559
    CARD32          tmp;
 
1560
    PixTransDeclare;
 
1561
 
 
1562
    s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
1563
    widthGlyph = FONTMAXBOUNDS(pfont,characterWidth);
 
1564
    if (!widthGlyph)
 
1565
        return;
 
1566
    
 
1567
    h = FONTASCENT(pfont) + FONTDESCENT(pfont);
 
1568
    if (!h)
 
1569
        return;
 
1570
    
 
1571
    DRAW_DEBUG ((DEBUG_TEXT, "ImageTEGlyphBlt chars are %d %d",
 
1572
                 widthGlyph, h));
 
1573
    
 
1574
    x = xInit + FONTMAXBOUNDS(pfont,leftSideBearing) + pDrawable->x;
 
1575
    y = yInit - FONTASCENT(pfont) + pDrawable->y;
 
1576
    
 
1577
    bbox.x1 = x;
 
1578
    bbox.x2 = x + (widthGlyph * nglyph);
 
1579
    bbox.y1 = y;
 
1580
    bbox.y2 = y + h;
 
1581
 
 
1582
    switch (RECT_IN_REGION(pGC->pScreen, fbGetCompositeClip(pGC), &bbox))
 
1583
    {
 
1584
      case rgnIN:
 
1585
        break;
 
1586
      case rgnPART:
 
1587
        if (pglyphBase == (pointer) 1)
 
1588
            pglyphBase = 0;
 
1589
        else
 
1590
            pglyphBase = (pointer) 1;
 
1591
        s3PolyGlyphBltClipped(pDrawable, pGC, 
 
1592
                              xInit,
 
1593
                              yInit,
 
1594
                              nglyph, ppci, 
 
1595
                              pglyphBase);
 
1596
      case rgnOUT:
 
1597
        return;
 
1598
    }
 
1599
 
 
1600
    if (pglyphBase == (pointer) 1)
 
1601
    {
 
1602
        _s3SetTransparentPlaneBlt (s3, pGC->alu, pGC->planemask, pGC->fgPixel);
 
1603
    }
 
1604
    else
 
1605
    {
 
1606
        _s3SetOpaquePlaneBlt (s3, GXcopy, pGC->planemask, pGC->fgPixel, pGC->bgPixel);
 
1607
    }
 
1608
 
 
1609
#if BITMAP_BIT_ORDER == LSBFirst
 
1610
#define SHIFT   <<
 
1611
#else
 
1612
#define SHIFT   >>
 
1613
#endif
 
1614
    
 
1615
#define LoopIt(count, w, loadup, fetch) \
 
1616
    while (nglyph >= count) \
 
1617
    { \
 
1618
        nglyph -= count; \
 
1619
        _s3PlaneBlt (s3, x, y, w, h); \
 
1620
        x += w; \
 
1621
        loadup \
 
1622
        lwTmp = h; \
 
1623
        PixTransStart(h); \
 
1624
        while (lwTmp--) { \
 
1625
            tmp = fetch; \
 
1626
            S3AdjustBits32(tmp); \
 
1627
            PixTransStore(tmp); \
 
1628
        } \
 
1629
    }
 
1630
 
 
1631
    if (widthGlyph <= 8)
 
1632
    {
 
1633
        widthGlyphs = widthGlyph << 2;
 
1634
        LoopIt(4, widthGlyphs,
 
1635
               char1 = (unsigned long *) (*ppci++)->bits;
 
1636
               char2 = (unsigned long *) (*ppci++)->bits;
 
1637
               char3 = (unsigned long *) (*ppci++)->bits;
 
1638
               char4 = (unsigned long *) (*ppci++)->bits;,
 
1639
               (*char1++ | ((*char2++ | ((*char3++ | (*char4++
 
1640
                                                      SHIFT widthGlyph))
 
1641
                                         SHIFT widthGlyph))
 
1642
                            SHIFT widthGlyph)))
 
1643
    }
 
1644
    else if (widthGlyph <= 10)
 
1645
    {
 
1646
        widthGlyphs = (widthGlyph << 1) + widthGlyph;
 
1647
        LoopIt(3, widthGlyphs,
 
1648
               char1 = (unsigned long *) (*ppci++)->bits;
 
1649
               char2 = (unsigned long *) (*ppci++)->bits;
 
1650
               char3 = (unsigned long *) (*ppci++)->bits;,
 
1651
               (*char1++ | ((*char2++ | (*char3++ SHIFT widthGlyph)) SHIFT widthGlyph)))
 
1652
    }
 
1653
    else if (widthGlyph <= 16)
 
1654
    {
 
1655
        widthGlyphs = widthGlyph << 1;
 
1656
        LoopIt(2, widthGlyphs,
 
1657
               char1 = (unsigned long *) (*ppci++)->bits;
 
1658
               char2 = (unsigned long *) (*ppci++)->bits;,
 
1659
               (*char1++ | (*char2++ SHIFT widthGlyph)))
 
1660
    }
 
1661
    lw = h * ((widthGlyph + 31) >> 5);
 
1662
    while (nglyph--) 
 
1663
    {
 
1664
        _s3PlaneBlt (s3, x, y, widthGlyph, h);
 
1665
        x += widthGlyph;
 
1666
        char1 = (unsigned long *) (*ppci++)->bits;
 
1667
        lwTmp = lw;
 
1668
        PixTransStart(lw);
 
1669
        while (lwTmp--)
 
1670
        {
 
1671
            tmp = *char1++;
 
1672
            S3AdjustBits32(tmp);
 
1673
            PixTransStore(tmp);
 
1674
        }
 
1675
    }
 
1676
    MarkSyncS3 (pDrawable->pScreen);
 
1677
}
 
1678
 
 
1679
void
 
1680
s3PolyTEGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, 
 
1681
                  int x, int y, 
 
1682
                  unsigned int nglyph, CharInfoPtr *ppci, 
 
1683
                  pointer pglyphBase)
 
1684
{
 
1685
    s3ImageTEGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, (pointer) 1);
 
1686
}
 
1687
 
 
1688
Bool
 
1689
_s3Segment (DrawablePtr pDrawable,
 
1690
            GCPtr       pGC,
 
1691
            int         x1,
 
1692
            int         y1,
 
1693
            int         x2,
 
1694
            int         y2,
 
1695
            Bool        drawLast,
 
1696
            Bool        s3Set)
 
1697
{
 
1698
    SetupS3(pDrawable->pScreen);
 
1699
    FbGCPrivPtr pPriv = fbGetGCPrivate(pGC);
 
1700
    RegionPtr   pClip = fbGetCompositeClip(pGC);
 
1701
    BoxPtr      pBox;
 
1702
    int         nBox;
 
1703
    int         adx;            /* abs values of dx and dy */
 
1704
    int         ady;
 
1705
    int         signdx;         /* sign of dx and dy */
 
1706
    int         signdy;
 
1707
    int         e, e1, e2;              /* bresenham error and increments */
 
1708
    int         len;                    /* length of segment */
 
1709
    int         axis;                   /* major axis */
 
1710
    int         octant;
 
1711
    int         cmd;
 
1712
    unsigned int bias = miGetZeroLineBias(pDrawable->pScreen);
 
1713
    unsigned int oc1;   /* outcode of point 1 */
 
1714
    unsigned int oc2;   /* outcode of point 2 */
 
1715
 
 
1716
    CalcLineDeltas(x1, y1, x2, y2, adx, ady, signdx, signdy,
 
1717
                   1, 1, octant);
 
1718
    
 
1719
    cmd = LASTPIX;
 
1720
    
 
1721
    if (adx > ady)
 
1722
    {
 
1723
        axis = X_AXIS;
 
1724
        e1 = ady << 1;
 
1725
        e2 = e1 - (adx << 1);
 
1726
        e = e1 - adx;
 
1727
        len = adx;
 
1728
    }
 
1729
    else
 
1730
    {
 
1731
        cmd |= YMAJAXIS;
 
1732
        axis = Y_AXIS;
 
1733
        e1 = adx << 1;
 
1734
        e2 = e1 - (ady << 1);
 
1735
        e = e1 - ady;
 
1736
        SetYMajorOctant(octant);
 
1737
        len = ady;
 
1738
    }
 
1739
 
 
1740
    /* S3 line drawing hardware has limited resolution for error terms */
 
1741
    if (len >= 4096)
 
1742
    {
 
1743
        int dashOff = 0;
 
1744
        
 
1745
        KdCheckSync (pDrawable->pScreen);
 
1746
        fbSegment (pDrawable, pGC, x1, y1, x2, y2, drawLast, &dashOff);
 
1747
        return FALSE;
 
1748
    }
 
1749
 
 
1750
    FIXUP_ERROR (e, octant, bias);
 
1751
    
 
1752
    nBox = REGION_NUM_RECTS (pClip);
 
1753
    pBox = REGION_RECTS (pClip);
 
1754
 
 
1755
    if (signdx > 0)
 
1756
        cmd |= INC_X;
 
1757
    if (signdy > 0)
 
1758
        cmd |= INC_Y;
 
1759
        
 
1760
    /* we have bresenham parameters and two points.
 
1761
       all we have to do now is clip and draw.
 
1762
    */
 
1763
 
 
1764
    if (drawLast)
 
1765
        len++;
 
1766
    while(nBox--)
 
1767
    {
 
1768
        oc1 = 0;
 
1769
        oc2 = 0;
 
1770
        OUTCODES(oc1, x1, y1, pBox);
 
1771
        OUTCODES(oc2, x2, y2, pBox);
 
1772
        if ((oc1 | oc2) == 0)
 
1773
        {
 
1774
            if (!s3Set)
 
1775
            {
 
1776
                s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
1777
                _s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
 
1778
                s3Set = TRUE;
 
1779
            }
 
1780
            _s3SetCur (s3, x1, y1);
 
1781
            _s3ClipLine (s3, cmd, e1, e2, e, len);
 
1782
            break;
 
1783
        }
 
1784
        else if (oc1 & oc2)
 
1785
        {
 
1786
            pBox++;
 
1787
        }
 
1788
        else
 
1789
        {
 
1790
            int new_x1 = x1, new_y1 = y1, new_x2 = x2, new_y2 = y2;
 
1791
            int clip1 = 0, clip2 = 0;
 
1792
            int clipdx, clipdy;
 
1793
            int err;
 
1794
            
 
1795
            if (miZeroClipLine(pBox->x1, pBox->y1, pBox->x2-1,
 
1796
                               pBox->y2-1,
 
1797
                               &new_x1, &new_y1, &new_x2, &new_y2,
 
1798
                               adx, ady, &clip1, &clip2,
 
1799
                               octant, bias, oc1, oc2) == -1)
 
1800
            {
 
1801
                pBox++;
 
1802
                continue;
 
1803
            }
 
1804
 
 
1805
            if (axis == X_AXIS)
 
1806
                len = abs(new_x2 - new_x1);
 
1807
            else
 
1808
                len = abs(new_y2 - new_y1);
 
1809
            if (clip2 != 0 || drawLast)
 
1810
                len++;
 
1811
            if (len)
 
1812
            {
 
1813
                /* unwind bresenham error term to first point */
 
1814
                err = e;
 
1815
                if (clip1)
 
1816
                {
 
1817
                    clipdx = abs(new_x1 - x1);
 
1818
                    clipdy = abs(new_y1 - y1);
 
1819
                    if (axis == X_AXIS)
 
1820
                        err  += (e2 - e1) * clipdy + e1 * clipdx;
 
1821
                    else
 
1822
                        err  += (e2 - e1) * clipdx + e1 * clipdy;
 
1823
                }
 
1824
                if (!s3Set)
 
1825
                {
 
1826
                    s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
1827
                    _s3SetSolidFill (s3, pGC->fgPixel, pGC->alu, pGC->planemask);
 
1828
                    s3Set = TRUE;
 
1829
                }
 
1830
                _s3SetCur (s3, new_x1, new_y1);
 
1831
                _s3ClipLine (s3, cmd, e1, e2, err, len);
 
1832
            }
 
1833
            pBox++;
 
1834
        }
 
1835
    } /* while (nBox--) */
 
1836
    return s3Set;
 
1837
}
 
1838
 
 
1839
void
 
1840
s3Polylines (DrawablePtr pDrawable, GCPtr pGC,
 
1841
             int mode, int npt, DDXPointPtr ppt)
 
1842
{
 
1843
    SetupS3(pDrawable->pScreen);
 
1844
    int         x, y, nx, ny;
 
1845
    int         ox = pDrawable->x, oy = pDrawable->y;
 
1846
    Bool        s3Set = FALSE;
 
1847
    
 
1848
    if (!npt)
 
1849
        return;
 
1850
    
 
1851
    x = ppt->x + ox;
 
1852
    y = ppt->y + oy;
 
1853
    while (--npt)
 
1854
    {
 
1855
        ++ppt;
 
1856
        if (mode == CoordModePrevious)
 
1857
        {
 
1858
            nx = x + ppt->x;
 
1859
            ny = y + ppt->y;
 
1860
        }
 
1861
        else
 
1862
        {
 
1863
            nx = ppt->x + ox;
 
1864
            ny = ppt->y + oy;
 
1865
        }
 
1866
        s3Set = _s3Segment (pDrawable, pGC, x, y, nx, ny,
 
1867
                            npt == 1 && pGC->capStyle != CapNotLast, 
 
1868
                            s3Set);
 
1869
        x = nx;
 
1870
        y = ny;
 
1871
    }
 
1872
    if (s3Set)
 
1873
        MarkSyncS3 (pDrawable->pScreen);
 
1874
}
 
1875
 
 
1876
void
 
1877
s3PolySegment (DrawablePtr pDrawable, GCPtr pGC, 
 
1878
               int nsegInit, xSegment *pSegInit)
 
1879
{
 
1880
    SetupS3(pDrawable->pScreen);
 
1881
    int         x, y;
 
1882
    int         ox = pDrawable->x, oy = pDrawable->y;
 
1883
    RegionPtr   pClip = fbGetCompositeClip (pGC);
 
1884
    BoxPtr      pBox;
 
1885
    int         nbox;
 
1886
    int         nseg;
 
1887
    xSegment    *pSeg;
 
1888
    int         dx, dy;
 
1889
    int         maj, min, len, inc;
 
1890
    int         t;
 
1891
    CARD32      cmd;
 
1892
    CARD32      init_cmd;
 
1893
    Bool        drawLast;
 
1894
    Bool        s3Set = FALSE;
 
1895
    
 
1896
    drawLast = pGC->capStyle != CapNotLast;
 
1897
    
 
1898
    for (nseg = nsegInit, pSeg = pSegInit; nseg--; pSeg++)
 
1899
    {
 
1900
        s3Set = _s3Segment (pDrawable, pGC, pSeg->x1 + ox, pSeg->y1 + oy,
 
1901
                            pSeg->x2 + ox, pSeg->y2 + oy, drawLast, s3Set);
 
1902
                    
 
1903
    }
 
1904
    if (s3Set)
 
1905
        MarkSyncS3 (pDrawable->pScreen);
 
1906
}
 
1907
 
 
1908
/*
 
1909
 * Check to see if a pattern can be painted with the S3
 
1910
 */
 
1911
 
 
1912
#define _s3CheckPatternSize(s)  ((s) <= S3_TILE_SIZE && ((s) & ((s) - 1)) == 0)
 
1913
#define s3CheckPattern(w,h) (_s3CheckPatternSize(w) && _s3CheckPatternSize(h))
 
1914
                             
 
1915
Bool
 
1916
s3AllocPattern (ScreenPtr pScreen,
 
1917
                int ma,
 
1918
                PixmapPtr pPixmap, 
 
1919
                int xorg, int yorg,
 
1920
                int fillStyle, Pixel fg, Pixel bg,
 
1921
                s3PatternPtr *ppPattern)
 
1922
{
 
1923
    KdScreenPriv(pScreen);
 
1924
    s3ScreenInfo(pScreenPriv);
 
1925
    s3PatternPtr    pPattern;
 
1926
    
 
1927
    if (s3s->fb[ma].patterns.cache && fillStyle != FillSolid &&
 
1928
        s3CheckPattern (pPixmap->drawable.width, pPixmap->drawable.height))
 
1929
    {
 
1930
        if (!(pPattern = *ppPattern))
 
1931
        {
 
1932
            pPattern = (s3PatternPtr) xalloc (sizeof (s3PatternRec));
 
1933
            if (!pPattern)
 
1934
                return FALSE;
 
1935
            *ppPattern = pPattern;
 
1936
        }
 
1937
        
 
1938
        pPattern->cache = 0;
 
1939
        pPattern->id = 0;
 
1940
        pPattern->pPixmap = pPixmap;
 
1941
        pPattern->fillStyle = fillStyle;
 
1942
        pPattern->xrot = (-xorg) & (S3_TILE_SIZE-1);
 
1943
        pPattern->yrot = (-yorg) & (S3_TILE_SIZE-1);
 
1944
        pPattern->fore = fg;
 
1945
        pPattern->back = bg;
 
1946
        return TRUE;
 
1947
    }
 
1948
    else
 
1949
    {
 
1950
        if (*ppPattern)
 
1951
        {
 
1952
            xfree (*ppPattern);
 
1953
            *ppPattern = 0;
 
1954
        }
 
1955
        return FALSE;
 
1956
    }
 
1957
}
 
1958
 
 
1959
void
 
1960
s3CheckGCFill (GCPtr pGC)
 
1961
{
 
1962
    s3PrivGCPtr     s3Priv = s3GetGCPrivate (pGC);
 
1963
    PixmapPtr       pPixmap;
 
1964
 
 
1965
    switch (pGC->fillStyle) {
 
1966
    case FillSolid:
 
1967
        pPixmap = 0;
 
1968
        break;
 
1969
    case FillOpaqueStippled:
 
1970
    case FillStippled:
 
1971
        pPixmap = pGC->stipple;
 
1972
        break;
 
1973
    case FillTiled:
 
1974
        pPixmap = pGC->tile.pixmap;
 
1975
        break;
 
1976
    }
 
1977
    s3AllocPattern (pGC->pScreen,
 
1978
                    s3GCMap(pGC),
 
1979
                    pPixmap,
 
1980
                    pGC->patOrg.x + pGC->lastWinOrg.x,
 
1981
                    pGC->patOrg.y + pGC->lastWinOrg.y,
 
1982
                    pGC->fillStyle, pGC->fgPixel, pGC->bgPixel,
 
1983
                    &s3Priv->pPattern);
 
1984
}
 
1985
 
 
1986
void
 
1987
s3MoveGCFill (GCPtr pGC)
 
1988
{
 
1989
    s3PrivGCPtr     s3Priv = s3GetGCPrivate (pGC);
 
1990
    int             xorg, yorg;
 
1991
    s3PatternPtr    pPattern;
 
1992
    
 
1993
    if (pPattern = s3Priv->pPattern)
 
1994
    {
 
1995
        /*
 
1996
         * Reset origin
 
1997
         */
 
1998
        xorg = pGC->patOrg.x + pGC->lastWinOrg.x;
 
1999
        yorg = pGC->patOrg.y + pGC->lastWinOrg.y;
 
2000
        pPattern->xrot = (-xorg) & (S3_TILE_SIZE - 1);
 
2001
        pPattern->yrot = (-yorg) & (S3_TILE_SIZE - 1);
 
2002
        /*
 
2003
         * Invalidate cache entry
 
2004
         */
 
2005
        pPattern->id = 0;
 
2006
        pPattern->cache = 0;
 
2007
    }
 
2008
}
 
2009
 
 
2010
/*
 
2011
 * S3 Patterns.  These are always full-depth images, stored in off-screen
 
2012
 * memory.
 
2013
 */
 
2014
 
 
2015
Pixel
 
2016
s3FetchPatternPixel (s3PatternPtr pPattern, int x, int y)
 
2017
{
 
2018
    CARD8       *src;
 
2019
    CARD16      *src16;
 
2020
    CARD32      *src32;
 
2021
    PixmapPtr   pPixmap = pPattern->pPixmap;
 
2022
    
 
2023
    x = (x + pPattern->xrot) % pPixmap->drawable.width;
 
2024
    y = (y + pPattern->yrot) % pPixmap->drawable.height;
 
2025
    src = (CARD8 *) pPixmap->devPrivate.ptr + y * pPixmap->devKind;
 
2026
    switch (pPixmap->drawable.bitsPerPixel) {
 
2027
    case 1:
 
2028
        return (src[x>>3] >> (x & 7)) & 1 ? 0xffffffff : 0x00;
 
2029
    case 4:
 
2030
        if (x & 1)
 
2031
            return src[x>>1] >> 4;
 
2032
        else
 
2033
            return src[x>>1] & 0xf;
 
2034
    case 8:
 
2035
        return src[x];
 
2036
    case 16:
 
2037
        src16 = (CARD16 *) src;
 
2038
        return src16[x];
 
2039
    case 32:
 
2040
        src32 = (CARD32 *) src;
 
2041
        return src32[x];
 
2042
    }
 
2043
}
 
2044
 
 
2045
/*
 
2046
 * Place pattern image on screen; done with S3 locked
 
2047
 */
 
2048
void
 
2049
_s3PutPattern (ScreenPtr pScreen, int ma, s3PatternPtr pPattern)
 
2050
{
 
2051
    SetupS3(pScreen);
 
2052
    s3ScreenInfo(pScreenPriv);
 
2053
    int             x, y;
 
2054
    CARD8           *dstLine, *dst8;
 
2055
    CARD16          *dst16;
 
2056
    CARD32          *dst32;
 
2057
    S3PatternCache  *cache = pPattern->cache;
 
2058
#ifdef S3_TRIO
 
2059
    int             fb = 0;
 
2060
#else
 
2061
    int             fb = s3s->fbmap[ma];
 
2062
#endif
 
2063
    
 
2064
    DRAW_DEBUG ((DEBUG_PATTERN, "_s3PutPattern 0x%x id %d to %d %d",
 
2065
                pPattern, pPattern->id, cache->x, cache->y));
 
2066
    
 
2067
    dstLine = (pScreenPriv->screen->fb[fb].frameBuffer + 
 
2068
               cache->y * pScreenPriv->screen->fb[fb].byteStride + 
 
2069
               cache->x * pScreenPriv->bytesPerPixel[fb]);
 
2070
    
 
2071
    CheckSyncS3 (pScreen);
 
2072
    
 
2073
    for (y = 0; y < S3_TILE_SIZE; y++)
 
2074
    {
 
2075
        switch (pScreenPriv->screen->fb[fb].bitsPerPixel) {
 
2076
        case 8:
 
2077
            dst8 = dstLine;
 
2078
            for (x = 0; x < S3_TILE_SIZE; x++)
 
2079
                *dst8++ = s3FetchPatternPixel (pPattern, x, y);
 
2080
            DRAW_DEBUG ((DEBUG_PATTERN, "%c%c%c%c%c%c%c%c",
 
2081
                         dstLine[0] ? 'X' : ' ',
 
2082
                         dstLine[1] ? 'X' : ' ',
 
2083
                         dstLine[2] ? 'X' : ' ',
 
2084
                         dstLine[3] ? 'X' : ' ',
 
2085
                         dstLine[4] ? 'X' : ' ',
 
2086
                         dstLine[5] ? 'X' : ' ',
 
2087
                         dstLine[6] ? 'X' : ' ',
 
2088
                         dstLine[7] ? 'X' : ' '));
 
2089
            break;
 
2090
        case 16:
 
2091
            dst16 = (CARD16 *) dstLine;
 
2092
            for (x = 0; x < S3_TILE_SIZE; x++)
 
2093
                *dst16++ = s3FetchPatternPixel (pPattern, x, y);
 
2094
            break;
 
2095
        case 32:
 
2096
            dst32 = (CARD32 *) dstLine;
 
2097
            for (x = 0; x < S3_TILE_SIZE; x++)
 
2098
                *dst32++ = s3FetchPatternPixel (pPattern, x, y);
 
2099
            break;
 
2100
        }
 
2101
        dstLine += pScreenPriv->screen->fb[fb].byteStride;
 
2102
    }
 
2103
}
 
2104
 
 
2105
/*
 
2106
 * Load a stipple to off-screen memory; done with S3 locked
 
2107
 */
 
2108
void
 
2109
_s3LoadPattern (ScreenPtr pScreen, int ma, s3PatternPtr pPattern)
 
2110
{
 
2111
    SetupS3(pScreen);
 
2112
    s3ScreenInfo(pScreenPriv);
 
2113
    S3PatternCache  *cache;
 
2114
 
 
2115
    DRAW_DEBUG((DEBUG_PATTERN,
 
2116
               "s3LoadPattern 0x%x id %d cache 0x%x cacheid %d",
 
2117
               pPattern, pPattern->id, pPattern->cache, 
 
2118
               pPattern->cache ? pPattern->cache->id : -1));
 
2119
    /*
 
2120
     * Check to see if its still loaded
 
2121
     */
 
2122
    cache = pPattern->cache;
 
2123
    if (cache && cache->id == pPattern->id)
 
2124
        return;
 
2125
    /*
 
2126
     * Lame replacement strategy; assume we'll have plenty of room.
 
2127
     */
 
2128
    cache = &s3s->fb[ma].patterns.cache[s3s->fb[ma].patterns.last_used];
 
2129
    if (++s3s->fb[ma].patterns.last_used == s3s->fb[ma].patterns.ncache)
 
2130
        s3s->fb[ma].patterns.last_used = 0;
 
2131
    cache->id = ++s3s->fb[ma].patterns.last_id;
 
2132
    pPattern->id = cache->id;
 
2133
    pPattern->cache = cache;
 
2134
    _s3PutPattern (pScreen, ma, pPattern);
 
2135
}
 
2136
 
 
2137
void
 
2138
s3DestroyGC (GCPtr pGC)
 
2139
{
 
2140
    s3PrivGCPtr     s3Priv = s3GetGCPrivate (pGC);
 
2141
 
 
2142
    if (s3Priv->pPattern)
 
2143
        xfree (s3Priv->pPattern);
 
2144
    miDestroyGC (pGC);
 
2145
}
 
2146
 
 
2147
GCFuncs s3GCFuncs = {
 
2148
    s3ValidateGC,
 
2149
    miChangeGC,
 
2150
    miCopyGC,
 
2151
    s3DestroyGC,
 
2152
    miChangeClip,
 
2153
    miDestroyClip,
 
2154
    miCopyClip
 
2155
};
 
2156
 
 
2157
int
 
2158
s3CreateGC (GCPtr pGC)
 
2159
{
 
2160
    KdScreenPriv(pGC->pScreen);
 
2161
    s3ScreenInfo(pScreenPriv);
 
2162
    s3PrivGCPtr  s3Priv;
 
2163
    
 
2164
    if (!fbCreateGC (pGC))
 
2165
        return FALSE;
 
2166
 
 
2167
    if (pGC->depth != 1)
 
2168
        pGC->funcs = &s3GCFuncs;
 
2169
    
 
2170
    s3Priv = s3GetGCPrivate(pGC);
 
2171
    s3Priv->type = DRAWABLE_PIXMAP;
 
2172
    s3Priv->pPattern = 0;
 
2173
#ifndef S3_TRIO
 
2174
    if (pGC->depth == s3s->primary_depth)
 
2175
        s3Priv->ma = 0;
 
2176
    else
 
2177
        s3Priv->ma = 1;
 
2178
#endif
 
2179
    return TRUE;
 
2180
}
 
2181
 
 
2182
Bool
 
2183
s3CreateWindow (WindowPtr pWin)
 
2184
{
 
2185
    KdScreenPriv(pWin->drawable.pScreen);
 
2186
    s3ScreenInfo(pScreenPriv);
 
2187
    
 
2188
    pWin->devPrivates[s3WindowPrivateIndex].ptr = 0;
 
2189
    return KdCreateWindow (pWin);
 
2190
}
 
2191
 
 
2192
Bool
 
2193
s3DestroyWindow (WindowPtr pWin)
 
2194
{
 
2195
    s3PatternPtr pPattern;
 
2196
    if (pPattern = s3GetWindowPrivate(pWin))
 
2197
        xfree (pPattern);
 
2198
    return fbDestroyWindow (pWin);
 
2199
}
 
2200
 
 
2201
Bool
 
2202
s3ChangeWindowAttributes (WindowPtr pWin, Mask mask)
 
2203
{
 
2204
    KdScreenPriv(pWin->drawable.pScreen);
 
2205
    Bool            ret;
 
2206
    s3PatternPtr    pPattern;
 
2207
    PixmapPtr       pPixmap;
 
2208
    int             fillStyle;
 
2209
 
 
2210
    ret = fbChangeWindowAttributes (pWin, mask);
 
2211
    if (mask & CWBackPixmap)
 
2212
    {
 
2213
        if (pWin->backgroundState == BackgroundPixmap)
 
2214
        {
 
2215
            pPixmap = pWin->background.pixmap;
 
2216
            fillStyle = FillTiled;
 
2217
        }
 
2218
        else
 
2219
        {
 
2220
            pPixmap = 0;
 
2221
            fillStyle = FillSolid;
 
2222
        }
 
2223
        pPattern = s3GetWindowPrivate(pWin);
 
2224
        s3AllocPattern (pWin->drawable.pScreen,
 
2225
                        s3DrawMap (&pWin->drawable),
 
2226
                        pPixmap, 
 
2227
                        pWin->drawable.x, pWin->drawable.y,
 
2228
                        fillStyle, 0, 0, &pPattern);
 
2229
        DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "Background pattern 0x%x pixmap 0x%x style %d",
 
2230
                    pPattern, pPixmap, fillStyle));
 
2231
        s3SetWindowPrivate (pWin, pPattern);
 
2232
    }
 
2233
    return ret;
 
2234
}
 
2235
 
 
2236
 
 
2237
#ifndef S3_TRIO
 
2238
void
 
2239
s3PaintKey (DrawablePtr pDrawable,
 
2240
            RegionPtr   pRegion,
 
2241
            CARD32      pixel,
 
2242
            int         fb)
 
2243
{
 
2244
    SetupS3 (pDrawable->pScreen);
 
2245
    s3ScreenInfo (pScreenPriv);
 
2246
    int     nBox = REGION_NUM_RECTS(pRegion);
 
2247
    BoxPtr  pBox = REGION_RECTS(pRegion);
 
2248
    int     ma;
 
2249
    
 
2250
    if (!nBox)
 
2251
        return;
 
2252
    
 
2253
    for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
 
2254
        if (s3s->fbmap[ma] == fb)
 
2255
            break;
 
2256
    s3SetGlobalBitmap (pDrawable->pScreen, ma);
 
2257
    _s3SetSolidFill (s3, pixel, GXcopy, 0xffffffff);
 
2258
    while (nBox--) 
 
2259
    {
 
2260
        _s3SolidRect(s3,pBox->x1,pBox->y1,pBox->x2-pBox->x1,pBox->y2-pBox->y1);
 
2261
        pBox++;
 
2262
    }
 
2263
    MarkSyncS3 (pDrawable->pScreen);
 
2264
}
 
2265
#endif
 
2266
 
 
2267
void
 
2268
s3PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
 
2269
{
 
2270
    SetupS3(pWin->drawable.pScreen);
 
2271
    s3ScreenInfo(pScreenPriv);
 
2272
    s3PatternPtr    pPattern;
 
2273
 
 
2274
    DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "s3PaintWindow 0x%x extents %d %d %d %d n %d",
 
2275
                 pWin->drawable.id,
 
2276
                 pRegion->extents.x1, pRegion->extents.y1,
 
2277
                 pRegion->extents.x2, pRegion->extents.y2,
 
2278
                 REGION_NUM_RECTS(pRegion)));
 
2279
    if (!REGION_NUM_RECTS(pRegion)) 
 
2280
        return;
 
2281
    switch (what) {
 
2282
    case PW_BACKGROUND:
 
2283
        switch (pWin->backgroundState) {
 
2284
        case None:
 
2285
            return;
 
2286
        case ParentRelative:
 
2287
            do {
 
2288
                pWin = pWin->parent;
 
2289
            } while (pWin->backgroundState == ParentRelative);
 
2290
            (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
 
2291
                                                             what);
 
2292
            return;
 
2293
        case BackgroundPixmap:
 
2294
            pPattern = s3GetWindowPrivate(pWin);
 
2295
            if (pPattern)
 
2296
            {
 
2297
                s3FillBoxPattern ((DrawablePtr)pWin,
 
2298
                                  (int)REGION_NUM_RECTS(pRegion),
 
2299
                                  REGION_RECTS(pRegion),
 
2300
                                  GXcopy, ~0, pPattern);
 
2301
                return;
 
2302
            }
 
2303
            break;
 
2304
        case BackgroundPixel:
 
2305
            s3FillBoxSolid((DrawablePtr)pWin,
 
2306
                             (int)REGION_NUM_RECTS(pRegion),
 
2307
                             REGION_RECTS(pRegion),
 
2308
                             pWin->background.pixel, GXcopy, ~0);
 
2309
            return;
 
2310
        }
 
2311
        break;
 
2312
    case PW_BORDER:
 
2313
#ifndef S3_TRIO
 
2314
        if (s3s->fbmap[1] >= 0)
 
2315
            fbOverlayUpdateLayerRegion (pWin->drawable.pScreen,
 
2316
                                        fbOverlayWindowLayer (pWin),
 
2317
                                        pRegion);
 
2318
#endif
 
2319
        if (pWin->borderIsPixel)
 
2320
        {
 
2321
            s3FillBoxSolid((DrawablePtr)pWin,
 
2322
                             (int)REGION_NUM_RECTS(pRegion),
 
2323
                             REGION_RECTS(pRegion),
 
2324
                             pWin->border.pixel, GXcopy, ~0);
 
2325
            return;
 
2326
        }
 
2327
        break;
 
2328
    }
 
2329
    KdCheckPaintWindow (pWin, pRegion, what);
 
2330
}
 
2331
 
 
2332
void
 
2333
s3CopyWindowProc (DrawablePtr pSrcDrawable,
 
2334
                  DrawablePtr pDstDrawable,
 
2335
                  GCPtr       pGC,
 
2336
                  BoxPtr      pboxOrig,
 
2337
                  int         nboxOrig,
 
2338
                  int         dx,
 
2339
                  int         dy,
 
2340
                  Bool        reverse,
 
2341
                  Bool        upsidedown,
 
2342
                  Pixel       bitplane,
 
2343
                  void        *closure)
 
2344
{
 
2345
    SetupS3(pDstDrawable->pScreen);
 
2346
    s3ScreenInfo(pScreenPriv);
 
2347
    KdScreenInfo    *screen = pScreenPriv->screen;
 
2348
    int             srcX, srcY, dstX, dstY;
 
2349
    int             x1, x2;
 
2350
    int             w, h;
 
2351
    int             flags;
 
2352
    int             fb = (int) closure;
 
2353
    int             ma;
 
2354
    BoxPtr          pbox;
 
2355
    int             nbox;
 
2356
    int             bitsPerPixel;
 
2357
    
 
2358
#ifdef S3_TRIO
 
2359
    ma = 0;
 
2360
#else
 
2361
    for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
 
2362
        if (s3s->fbmap[ma] == fb)
 
2363
            break;
 
2364
#endif
 
2365
    bitsPerPixel = screen->fb[fb].bitsPerPixel;
 
2366
    if (bitsPerPixel == 24)
 
2367
        dx *= 3;
 
2368
    nbox = nboxOrig;
 
2369
    pbox = pboxOrig;
 
2370
    s3SetGlobalBitmap (pDstDrawable->pScreen, ma);
 
2371
    _s3SetBlt(s3,GXcopy,~0);
 
2372
    while (nbox--)
 
2373
    {
 
2374
        x1 = pbox->x1;
 
2375
        x2 = pbox->x2;
 
2376
        if (bitsPerPixel == 24)
 
2377
        {
 
2378
            x1 *= 3;
 
2379
            x2 *= 3;
 
2380
        }
 
2381
        
 
2382
        w = x2 - x1;
 
2383
        h = pbox->y2 - pbox->y1;
 
2384
        flags = 0;
 
2385
        if (reverse)
 
2386
        {
 
2387
            dstX = x2 - 1;
 
2388
        }
 
2389
        else
 
2390
        {
 
2391
            dstX = x1;
 
2392
            flags |= INC_X;
 
2393
        }
 
2394
        srcX = dstX + dx;
 
2395
        
 
2396
        if (upsidedown)
 
2397
        {
 
2398
            dstY = pbox->y2 - 1;
 
2399
        }
 
2400
        else
 
2401
        {
 
2402
            dstY = pbox->y1;
 
2403
            flags |= INC_Y;
 
2404
        }
 
2405
        srcY = dstY + dy;
 
2406
        
 
2407
        _s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
 
2408
        pbox++;
 
2409
    }
 
2410
    MarkSyncS3 (pDstDrawable->pScreen);
 
2411
}
 
2412
 
 
2413
void 
 
2414
s3CopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
 
2415
{
 
2416
    ScreenPtr       pScreen = pWin->drawable.pScreen;
 
2417
    KdScreenPriv (pScreen);
 
2418
    s3ScreenInfo (pScreenPriv);
 
2419
    KdScreenInfo    *screen = pScreenPriv->screen;
 
2420
    RegionRec       rgnDst;
 
2421
    int             dx, dy;
 
2422
    WindowPtr       pwinRoot;
 
2423
 
 
2424
    pwinRoot = WindowTable[pWin->drawable.pScreen->myNum];
 
2425
 
 
2426
    dx = ptOldOrg.x - pWin->drawable.x;
 
2427
    dy = ptOldOrg.y - pWin->drawable.y;
 
2428
 
 
2429
    REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
 
2430
 
 
2431
    REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
 
2432
 
 
2433
    REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst,
 
2434
                     &pWin->borderClip, prgnSrc);
 
2435
 
 
2436
    fbCopyRegion ((DrawablePtr)pwinRoot, (DrawablePtr)pwinRoot,
 
2437
                  0,
 
2438
                  &rgnDst, dx, dy, s3CopyWindowProc, 0, 0);
 
2439
    
 
2440
    REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
 
2441
}
 
2442
 
 
2443
void
 
2444
s3_24FillBoxSolid (DrawablePtr pDrawable, int nBox, BoxPtr pBox, 
 
2445
                  unsigned long pixel, int alu, unsigned long planemask)
 
2446
{
 
2447
    SetupS3(pDrawable->pScreen);
 
2448
    register int        r;
 
2449
    int                 x1, x2;
 
2450
 
 
2451
    s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
 
2452
    _s3SetSolidFill(s3,pixel,alu,planemask);
 
2453
    
 
2454
    while (nBox--) {
 
2455
        x1 = pBox->x1 * 3;
 
2456
        x2 = pBox->x2 * 3;
 
2457
        _s3SolidRect(s3,x1,pBox->y1,x2-x1,pBox->y2-pBox->y1);
 
2458
        pBox++;
 
2459
    }
 
2460
    MarkSyncS3 (pDrawable->pScreen);
 
2461
}
 
2462
 
 
2463
#define ok24(p) (((p) & 0xffffff) == ((((p) & 0xff) << 16) | (((p) >> 8) & 0xffff)))
 
2464
 
 
2465
void
 
2466
s3_24FillSpans (DrawablePtr pDrawable, GCPtr pGC, int n, 
 
2467
                 DDXPointPtr ppt, int *pwidth, int fSorted)
 
2468
{
 
2469
    SetupS3(pDrawable->pScreen);
 
2470
    int             x, y, x1, y1, x2, y2;
 
2471
    int             width;
 
2472
                                /* next three parameters are post-clip */
 
2473
    int             nTmp;
 
2474
    int             *pwidthFree;/* copies of the pointers to free */
 
2475
    DDXPointPtr     pptFree;
 
2476
    BoxPtr          extents;
 
2477
    RegionPtr       pClip = fbGetCompositeClip (pGC);
 
2478
 
 
2479
    if (pGC->fillStyle != FillSolid || !ok24 (pGC->fgPixel) || !ok24(pGC->planemask))
 
2480
    {
 
2481
        KdCheckFillSpans (pDrawable,  pGC, n, ppt, pwidth, fSorted);
 
2482
        return;
 
2483
    }
 
2484
    
 
2485
    s3SetGlobalBitmap (pDrawable->pScreen, s3GCMap (pGC));
 
2486
    if (REGION_NUM_RECTS(pClip) == 1)
 
2487
    {
 
2488
        extents = REGION_RECTS(pClip);
 
2489
        x1 = extents->x1;
 
2490
        x2 = extents->x2;
 
2491
        y1 = extents->y1;
 
2492
        y2 = extents->y2;
 
2493
        _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
 
2494
        while (n--)
 
2495
        {
 
2496
            y = ppt->y;
 
2497
            if (y1 <= y && y < y2)
 
2498
            {
 
2499
                x = ppt->x;
 
2500
                width = *pwidth;
 
2501
                if (x < x1)
 
2502
                {
 
2503
                    width -= (x1 - x);
 
2504
                    x = x1;
 
2505
                }
 
2506
                if (x2 < x + width)
 
2507
                    width = x2 - x;
 
2508
                if (width > 0)
 
2509
                {
 
2510
                    _s3SolidRect(s3,x*3,y,width*3,1);
 
2511
                }
 
2512
            }
 
2513
            ppt++;
 
2514
            pwidth++;
 
2515
        }
 
2516
    }
 
2517
    else
 
2518
    {
 
2519
        nTmp = n * miFindMaxBand(pClip);
 
2520
        pwidthFree = (int *)ALLOCATE_LOCAL(nTmp * sizeof(int));
 
2521
        pptFree = (DDXPointRec *)ALLOCATE_LOCAL(nTmp * sizeof(DDXPointRec));
 
2522
        if(!pptFree || !pwidthFree)
 
2523
        {
 
2524
            if (pptFree) DEALLOCATE_LOCAL(pptFree);
 
2525
            if (pwidthFree) DEALLOCATE_LOCAL(pwidthFree);
 
2526
            return;
 
2527
        }
 
2528
        n = miClipSpans(fbGetCompositeClip(pGC),
 
2529
                        ppt, pwidth, n,
 
2530
                        pptFree, pwidthFree, fSorted);
 
2531
        pwidth = pwidthFree;
 
2532
        ppt = pptFree;
 
2533
        _s3SetSolidFill(s3,pGC->fgPixel,pGC->alu,pGC->planemask);
 
2534
        while (n--)
 
2535
        {
 
2536
            x = ppt->x;
 
2537
            y = ppt->y;
 
2538
            ppt++;
 
2539
            width = *pwidth++;
 
2540
            if (width)
 
2541
            {
 
2542
                _s3SolidRect(s3,x*3,y,width*3,1);
 
2543
            }
 
2544
        }
 
2545
        DEALLOCATE_LOCAL(pptFree);
 
2546
        DEALLOCATE_LOCAL(pwidthFree);
 
2547
    }
 
2548
    MarkSyncS3 (pDrawable->pScreen);
 
2549
}
 
2550
 
 
2551
void
 
2552
s3_24CopyNtoN (DrawablePtr  pSrcDrawable,
 
2553
               DrawablePtr  pDstDrawable,
 
2554
               GCPtr        pGC,
 
2555
               BoxPtr       pbox,
 
2556
               int          nbox,
 
2557
               int          dx,
 
2558
               int          dy,
 
2559
               Bool         reverse,
 
2560
               Bool         upsidedown,
 
2561
               Pixel        bitplane,
 
2562
               void         *closure)
 
2563
{
 
2564
    SetupS3(pDstDrawable->pScreen);
 
2565
    int     srcX, srcY, dstX, dstY;
 
2566
    int     w, h;
 
2567
    int     flags;
 
2568
    int     x1, x2;
 
2569
    
 
2570
    if (sourceInvarient (pGC->alu))
 
2571
    {
 
2572
        s3_24FillBoxSolid (pDstDrawable, nbox, pbox, 0, pGC->alu, pGC->planemask);
 
2573
        return;
 
2574
    }
 
2575
    
 
2576
    s3SetGlobalBitmap (pDstDrawable->pScreen, s3GCMap (pGC));
 
2577
    _s3SetBlt(s3,pGC->alu,pGC->planemask);
 
2578
    DRAW_DEBUG ((DEBUG_RENDER, "s3CopyNtoN alu %d planemask 0x%x",
 
2579
                 pGC->alu, pGC->planemask));
 
2580
    dx *= 3;
 
2581
    while (nbox--)
 
2582
    {
 
2583
        x1 = pbox->x1 * 3;
 
2584
        x2 = pbox->x2 * 3;
 
2585
        w = x2 - x1;
 
2586
        h = pbox->y2 - pbox->y1;
 
2587
        flags = 0;
 
2588
        if (reverse)
 
2589
        {
 
2590
            dstX = x2 - 1;
 
2591
        }
 
2592
        else
 
2593
        {
 
2594
            dstX = x1;
 
2595
            flags |= INC_X;
 
2596
        }
 
2597
        srcX = dstX + dx;
 
2598
        
 
2599
        if (upsidedown)
 
2600
        {
 
2601
            dstY = pbox->y2 - 1;
 
2602
        }
 
2603
        else
 
2604
        {
 
2605
            dstY = pbox->y1;
 
2606
            flags |= INC_Y;
 
2607
        }
 
2608
        srcY = dstY + dy;
 
2609
        
 
2610
        _s3Blt (s3, srcX, srcY, dstX, dstY, w, h, flags);
 
2611
        pbox++;
 
2612
    }
 
2613
    MarkSyncS3 (pSrcDrawable->pScreen);
 
2614
}
 
2615
 
 
2616
RegionPtr
 
2617
s3_24CopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
 
2618
           int srcx, int srcy, int width, int height, int dstx, int dsty)
 
2619
{
 
2620
    SetupS3(pDstDrawable->pScreen);
 
2621
    
 
2622
    if (pSrcDrawable->type == DRAWABLE_WINDOW &&
 
2623
        pDstDrawable->type == DRAWABLE_WINDOW &&
 
2624
        ok24(pGC->planemask))
 
2625
    {
 
2626
        return fbDoCopy (pSrcDrawable, pDstDrawable, pGC, 
 
2627
                         srcx, srcy, width, height, 
 
2628
                         dstx, dsty, s3_24CopyNtoN, 0, 0);
 
2629
    }
 
2630
    return KdCheckCopyArea (pSrcDrawable, pDstDrawable, pGC, 
 
2631
                            srcx, srcy, width, height, dstx, dsty);
 
2632
}
 
2633
 
 
2634
 
 
2635
#define NUM_STACK_RECTS 1024
 
2636
 
 
2637
void
 
2638
s3_24PolyFillRect (DrawablePtr pDrawable, GCPtr pGC, 
 
2639
                   int nrectFill, xRectangle *prectInit)
 
2640
{
 
2641
    s3GCPrivate(pGC);
 
2642
    xRectangle      *prect;
 
2643
    RegionPtr       prgnClip;
 
2644
    register BoxPtr pbox;
 
2645
    register BoxPtr pboxClipped;
 
2646
    BoxPtr          pboxClippedBase;
 
2647
    BoxPtr          pextent;
 
2648
    BoxRec          stackRects[NUM_STACK_RECTS];
 
2649
    int             numRects;
 
2650
    int             n;
 
2651
    int             xorg, yorg;
 
2652
    int             x, y;
 
2653
 
 
2654
    if (pGC->fillStyle != FillSolid || !ok24 (pGC->fgPixel) || !ok24(pGC->planemask))
 
2655
    {
 
2656
        KdCheckPolyFillRect (pDrawable, pGC, nrectFill, prectInit);
 
2657
        return;
 
2658
    }
 
2659
    
 
2660
    prgnClip = fbGetCompositeClip(pGC);
 
2661
    xorg = pDrawable->x;
 
2662
    yorg = pDrawable->y;
 
2663
    
 
2664
    if (xorg || yorg)
 
2665
    {
 
2666
        prect = prectInit;
 
2667
        n = nrectFill;
 
2668
        while(n--)
 
2669
        {
 
2670
            prect->x += xorg;
 
2671
            prect->y += yorg;
 
2672
            prect++;
 
2673
        }
 
2674
    }
 
2675
    
 
2676
    prect = prectInit;
 
2677
 
 
2678
    numRects = REGION_NUM_RECTS(prgnClip) * nrectFill;
 
2679
    if (numRects > NUM_STACK_RECTS)
 
2680
    {
 
2681
        pboxClippedBase = (BoxPtr)ALLOCATE_LOCAL(numRects * sizeof(BoxRec));
 
2682
        if (!pboxClippedBase)
 
2683
            return;
 
2684
    }
 
2685
    else
 
2686
        pboxClippedBase = stackRects;
 
2687
 
 
2688
    pboxClipped = pboxClippedBase;
 
2689
        
 
2690
    if (REGION_NUM_RECTS(prgnClip) == 1)
 
2691
    {
 
2692
        int x1, y1, x2, y2, bx2, by2;
 
2693
 
 
2694
        pextent = REGION_RECTS(prgnClip);
 
2695
        x1 = pextent->x1;
 
2696
        y1 = pextent->y1;
 
2697
        x2 = pextent->x2;
 
2698
        y2 = pextent->y2;
 
2699
        while (nrectFill--)
 
2700
        {
 
2701
            if ((pboxClipped->x1 = prect->x) < x1)
 
2702
                pboxClipped->x1 = x1;
 
2703
    
 
2704
            if ((pboxClipped->y1 = prect->y) < y1)
 
2705
                pboxClipped->y1 = y1;
 
2706
    
 
2707
            bx2 = (int) prect->x + (int) prect->width;
 
2708
            if (bx2 > x2)
 
2709
                bx2 = x2;
 
2710
            pboxClipped->x2 = bx2;
 
2711
    
 
2712
            by2 = (int) prect->y + (int) prect->height;
 
2713
            if (by2 > y2)
 
2714
                by2 = y2;
 
2715
            pboxClipped->y2 = by2;
 
2716
 
 
2717
            prect++;
 
2718
            if ((pboxClipped->x1 < pboxClipped->x2) &&
 
2719
                (pboxClipped->y1 < pboxClipped->y2))
 
2720
            {
 
2721
                pboxClipped++;
 
2722
            }
 
2723
        }
 
2724
    }
 
2725
    else
 
2726
    {
 
2727
        int x1, y1, x2, y2, bx2, by2;
 
2728
 
 
2729
        pextent = REGION_EXTENTS(pGC->pScreen, prgnClip);
 
2730
        x1 = pextent->x1;
 
2731
        y1 = pextent->y1;
 
2732
        x2 = pextent->x2;
 
2733
        y2 = pextent->y2;
 
2734
        while (nrectFill--)
 
2735
        {
 
2736
            BoxRec box;
 
2737
    
 
2738
            if ((box.x1 = prect->x) < x1)
 
2739
                box.x1 = x1;
 
2740
    
 
2741
            if ((box.y1 = prect->y) < y1)
 
2742
                box.y1 = y1;
 
2743
    
 
2744
            bx2 = (int) prect->x + (int) prect->width;
 
2745
            if (bx2 > x2)
 
2746
                bx2 = x2;
 
2747
            box.x2 = bx2;
 
2748
    
 
2749
            by2 = (int) prect->y + (int) prect->height;
 
2750
            if (by2 > y2)
 
2751
                by2 = y2;
 
2752
            box.y2 = by2;
 
2753
    
 
2754
            prect++;
 
2755
    
 
2756
            if ((box.x1 >= box.x2) || (box.y1 >= box.y2))
 
2757
                continue;
 
2758
    
 
2759
            n = REGION_NUM_RECTS (prgnClip);
 
2760
            pbox = REGION_RECTS(prgnClip);
 
2761
    
 
2762
            /* clip the rectangle to each box in the clip region
 
2763
               this is logically equivalent to calling Intersect()
 
2764
            */
 
2765
            while(n--)
 
2766
            {
 
2767
                pboxClipped->x1 = max(box.x1, pbox->x1);
 
2768
                pboxClipped->y1 = max(box.y1, pbox->y1);
 
2769
                pboxClipped->x2 = min(box.x2, pbox->x2);
 
2770
                pboxClipped->y2 = min(box.y2, pbox->y2);
 
2771
                pbox++;
 
2772
 
 
2773
                /* see if clipping left anything */
 
2774
                if(pboxClipped->x1 < pboxClipped->x2 && 
 
2775
                   pboxClipped->y1 < pboxClipped->y2)
 
2776
                {
 
2777
                    pboxClipped++;
 
2778
                }
 
2779
            }
 
2780
        }
 
2781
    }
 
2782
    if (pboxClipped != pboxClippedBase)
 
2783
    {
 
2784
        s3_24FillBoxSolid(pDrawable,
 
2785
                          pboxClipped-pboxClippedBase, pboxClippedBase,
 
2786
                          pGC->fgPixel, pGC->alu, pGC->planemask);
 
2787
    }
 
2788
    if (pboxClippedBase != stackRects)
 
2789
        DEALLOCATE_LOCAL(pboxClippedBase);
 
2790
}
 
2791
 
 
2792
void
 
2793
s3_24SolidBoxClipped (DrawablePtr       pDrawable,
 
2794
                      RegionPtr         pClip,
 
2795
                      int               x1,
 
2796
                      int               y1,
 
2797
                      int               x2,
 
2798
                      int               y2,
 
2799
                      FbBits            fg)
 
2800
{
 
2801
    SetupS3 (pDrawable->pScreen);
 
2802
    BoxPtr      pbox;
 
2803
    int         nbox;
 
2804
    int         partX1, partX2, partY1, partY2;
 
2805
    
 
2806
    s3SetGlobalBitmap (pDrawable->pScreen, s3DrawMap (pDrawable));
 
2807
    _s3SetSolidFill(s3,fg,GXcopy,~0);
 
2808
    
 
2809
    for (nbox = REGION_NUM_RECTS(pClip), pbox = REGION_RECTS(pClip); 
 
2810
         nbox--; 
 
2811
         pbox++)
 
2812
    {
 
2813
        partX1 = pbox->x1;
 
2814
        if (partX1 < x1)
 
2815
            partX1 = x1;
 
2816
        
 
2817
        partX2 = pbox->x2;
 
2818
        if (partX2 > x2)
 
2819
            partX2 = x2;
 
2820
        
 
2821
        if (partX2 <= partX1)
 
2822
            continue;
 
2823
        
 
2824
        partY1 = pbox->y1;
 
2825
        if (partY1 < y1)
 
2826
            partY1 = y1;
 
2827
        
 
2828
        partY2 = pbox->y2;
 
2829
        if (partY2 > y2)
 
2830
            partY2 = y2;
 
2831
        
 
2832
        if (partY2 <= partY1)
 
2833
            continue;
 
2834
        
 
2835
        partX1 *= 3;
 
2836
        partX2 *= 3;
 
2837
        _s3SolidRect(s3,partX1, partY1, partX2-partX1, partY2-partY1);
 
2838
    }
 
2839
    MarkSyncS3(pDrawable->pScreen);
 
2840
}
 
2841
 
 
2842
void
 
2843
s3_24ImageGlyphBlt (DrawablePtr pDrawable,
 
2844
                    GCPtr               pGC,
 
2845
                    int         x, 
 
2846
                    int         y,
 
2847
                    unsigned int        nglyph,
 
2848
                    CharInfoPtr *ppciInit,
 
2849
                    pointer     pglyphBase)
 
2850
{
 
2851
    FbGCPrivPtr     pPriv = fbGetGCPrivate(pGC);
 
2852
    CharInfoPtr     *ppci;
 
2853
    CharInfoPtr     pci;
 
2854
    unsigned char   *pglyph;            /* pointer bits in glyph */
 
2855
    int             gWidth, gHeight;    /* width and height of glyph */
 
2856
    FbStride        gStride;            /* stride of glyph */
 
2857
    Bool            opaque;
 
2858
    int             n;
 
2859
    int             gx, gy;
 
2860
    FbBits          *dst;
 
2861
    FbStride        dstStride;
 
2862
    int             dstBpp;
 
2863
    int             dstXoff, dstYoff;
 
2864
    FbBits          depthMask;
 
2865
    int             xBack, widthBack;
 
2866
    int             yBack, heightBack;
 
2867
    
 
2868
    depthMask = FbFullMask(pDrawable->depth);
 
2869
    if (!ok24 (pGC->fgPixel) || 
 
2870
        !ok24(pGC->bgPixel) || 
 
2871
        !ok24(pGC->planemask))
 
2872
    {
 
2873
        KdCheckImageGlyphBlt(pDrawable, pGC, x, y, nglyph, ppciInit, pglyphBase);
 
2874
        return;
 
2875
    }
 
2876
    fbGetDrawable (pDrawable, dst, dstStride, dstBpp, dstXoff, dstYoff);
 
2877
    
 
2878
    x += pDrawable->x;
 
2879
    y += pDrawable->y;
 
2880
 
 
2881
    ppci = ppciInit;
 
2882
    n = nglyph;
 
2883
    widthBack = 0;
 
2884
    while (n--)
 
2885
        widthBack += (*ppci++)->metrics.characterWidth;
 
2886
    
 
2887
    xBack = x;
 
2888
    if (widthBack < 0)
 
2889
    {
 
2890
        xBack += widthBack;
 
2891
        widthBack = -widthBack;
 
2892
    }
 
2893
    yBack = y - FONTASCENT(pGC->font);
 
2894
    heightBack = FONTASCENT(pGC->font) + FONTDESCENT(pGC->font);
 
2895
    s3_24SolidBoxClipped (pDrawable,
 
2896
                          fbGetCompositeClip(pGC),
 
2897
                          xBack,
 
2898
                          yBack,
 
2899
                          xBack + widthBack,
 
2900
                          yBack + heightBack,
 
2901
                          pPriv->bg);
 
2902
 
 
2903
    KdCheckSync (pDrawable->pScreen);
 
2904
    
 
2905
    ppci = ppciInit;
 
2906
    while (nglyph--)
 
2907
    {
 
2908
        pci = *ppci++;
 
2909
        pglyph = FONTGLYPHBITS(pglyphBase, pci);
 
2910
        gWidth = GLYPHWIDTHPIXELS(pci);
 
2911
        gHeight = GLYPHHEIGHTPIXELS(pci);
 
2912
        if (gWidth && gHeight)
 
2913
        {
 
2914
            gx = x + pci->metrics.leftSideBearing;
 
2915
            gy = y - pci->metrics.ascent; 
 
2916
            if (gWidth <= sizeof (FbStip) * 8 &&
 
2917
                fbGlyphIn (fbGetCompositeClip(pGC), gx, gy, gWidth, gHeight))
 
2918
            {
 
2919
                fbGlyph24 (dst + (gy - dstYoff) * dstStride,
 
2920
                          dstStride,
 
2921
                          dstBpp,
 
2922
                          (FbStip *) pglyph,
 
2923
                          pPriv->fg,
 
2924
                          gx - dstXoff,
 
2925
                          gHeight);
 
2926
            }
 
2927
            else
 
2928
            {
 
2929
                gStride = GLYPHWIDTHBYTESPADDED(pci) / sizeof (FbStip);
 
2930
                fbPutXYImage (pDrawable,
 
2931
                              fbGetCompositeClip(pGC),
 
2932
                              pPriv->fg,
 
2933
                              pPriv->bg,
 
2934
                              pPriv->pm,
 
2935
                              GXcopy,
 
2936
                              FALSE,
 
2937
    
 
2938
                              gx,
 
2939
                              gy,
 
2940
                              gWidth, gHeight,
 
2941
    
 
2942
                              (FbStip *) pglyph,
 
2943
                              gStride,
 
2944
                              0);
 
2945
            }
 
2946
        }
 
2947
        x += pci->metrics.characterWidth;
 
2948
    }
 
2949
}
 
2950
 
 
2951
static const GCOps      s3_24GCOps = {
 
2952
    s3_24FillSpans,
 
2953
    KdCheckSetSpans,
 
2954
    KdCheckPutImage,
 
2955
    KdCheckCopyArea,
 
2956
    KdCheckCopyPlane,
 
2957
    KdCheckPolyPoint,
 
2958
    KdCheckPolylines,
 
2959
    KdCheckPolySegment,
 
2960
    KdCheckPolyRectangle,
 
2961
    KdCheckPolyArc,
 
2962
    KdCheckFillPolygon,
 
2963
    s3_24PolyFillRect,
 
2964
    KdCheckPolyFillArc,
 
2965
    miPolyText8,
 
2966
    miPolyText16,
 
2967
    miImageText8,
 
2968
    miImageText16,
 
2969
    s3_24ImageGlyphBlt,
 
2970
    KdCheckPolyGlyphBlt,
 
2971
    KdCheckPushPixels,
 
2972
#ifdef NEED_LINEHELPER
 
2973
    ,NULL
 
2974
#endif
 
2975
};
 
2976
 
 
2977
void
 
2978
s3_24ValidateGC (GCPtr pGC, Mask changes, DrawablePtr pDrawable)
 
2979
{
 
2980
    if (pDrawable->type != DRAWABLE_WINDOW)
 
2981
        pGC->ops = (GCOps *) &kdAsyncPixmapGCOps;
 
2982
    else
 
2983
        pGC->ops = (GCOps *) &s3_24GCOps;
 
2984
    fbValidateGC (pGC, changes, pDrawable);
 
2985
}
 
2986
 
 
2987
GCFuncs s3_24GCFuncs = {
 
2988
    s3_24ValidateGC,
 
2989
    miChangeGC,
 
2990
    miCopyGC,
 
2991
    miDestroyGC,
 
2992
    miChangeClip,
 
2993
    miDestroyClip,
 
2994
    miCopyClip
 
2995
};
 
2996
 
 
2997
Bool
 
2998
s3_24CreateGC (GCPtr pGC)
 
2999
{
 
3000
    if (!fbCreateGC (pGC))
 
3001
        return FALSE;
 
3002
 
 
3003
    if (pGC->depth != 1)
 
3004
        pGC->funcs = &s3_24GCFuncs;
 
3005
    
 
3006
    return TRUE;
 
3007
}
 
3008
 
 
3009
Bool
 
3010
s3_24CreateWindow(WindowPtr pWin)
 
3011
{
 
3012
    return fbCreateWindow (pWin);
 
3013
}
 
3014
 
 
3015
void
 
3016
s3_24PaintWindow(WindowPtr pWin, RegionPtr pRegion, int what)
 
3017
{
 
3018
    SetupS3(pWin->drawable.pScreen);
 
3019
    s3PatternPtr    pPattern;
 
3020
 
 
3021
    DRAW_DEBUG ((DEBUG_PAINT_WINDOW, "s3PaintWindow 0x%x extents %d %d %d %d n %d",
 
3022
                 pWin->drawable.id,
 
3023
                 pRegion->extents.x1, pRegion->extents.y1,
 
3024
                 pRegion->extents.x2, pRegion->extents.y2,
 
3025
                 REGION_NUM_RECTS(pRegion)));
 
3026
    if (!REGION_NUM_RECTS(pRegion)) 
 
3027
        return;
 
3028
    switch (what) {
 
3029
    case PW_BACKGROUND:
 
3030
        switch (pWin->backgroundState) {
 
3031
        case None:
 
3032
            return;
 
3033
        case ParentRelative:
 
3034
            do {
 
3035
                pWin = pWin->parent;
 
3036
            } while (pWin->backgroundState == ParentRelative);
 
3037
            (*pWin->drawable.pScreen->PaintWindowBackground)(pWin, pRegion,
 
3038
                                                             what);
 
3039
            return;
 
3040
        case BackgroundPixel:
 
3041
            if (ok24(pWin->background.pixel))
 
3042
            {
 
3043
                s3_24FillBoxSolid((DrawablePtr)pWin,
 
3044
                                  (int)REGION_NUM_RECTS(pRegion),
 
3045
                                  REGION_RECTS(pRegion),
 
3046
                                  pWin->background.pixel, GXcopy, ~0);
 
3047
                return;
 
3048
            }
 
3049
        }
 
3050
        break;
 
3051
    case PW_BORDER:
 
3052
        if (pWin->borderIsPixel && ok24(pWin->border.pixel))
 
3053
        {
 
3054
            s3_24FillBoxSolid((DrawablePtr)pWin,
 
3055
                              (int)REGION_NUM_RECTS(pRegion),
 
3056
                              REGION_RECTS(pRegion),
 
3057
                              pWin->border.pixel, GXcopy, ~0);
 
3058
            return;
 
3059
        }
 
3060
        break;
 
3061
    }
 
3062
    KdCheckPaintWindow (pWin, pRegion, what);
 
3063
}
 
3064
 
 
3065
Bool
 
3066
s3DrawInit (ScreenPtr pScreen)
 
3067
{
 
3068
    KdScreenPriv(pScreen);
 
3069
    s3ScreenInfo(pScreenPriv);
 
3070
    int             ncache_w, ncache_h, ncache;
 
3071
    int             px, py;
 
3072
    S3PatternCache  *cache;
 
3073
    Bool            dumb = FALSE;
 
3074
    int             ma;
 
3075
 
 
3076
    switch (pScreenPriv->screen->fb[0].bitsPerPixel) {
 
3077
    case 8:
 
3078
    case 16:
 
3079
    case 32:
 
3080
        break;
 
3081
    case 24:
 
3082
        dumb = TRUE;
 
3083
        break;
 
3084
    default:
 
3085
        return FALSE;
 
3086
    }
 
3087
    /*
 
3088
     * Hook up asynchronous drawing
 
3089
     */
 
3090
    RegisterSync (pScreen);
 
3091
    /*
 
3092
     * Replace various fb screen functions
 
3093
     */
 
3094
    if (dumb)
 
3095
    {
 
3096
        pScreen->CreateGC = s3_24CreateGC;
 
3097
        pScreen->CreateWindow = s3_24CreateWindow;
 
3098
        pScreen->PaintWindowBackground = s3_24PaintWindow;
 
3099
        pScreen->PaintWindowBorder = s3_24PaintWindow;
 
3100
        pScreen->CopyWindow = s3CopyWindow;
 
3101
    }
 
3102
    else
 
3103
    {
 
3104
        if (serverGeneration != s3Generation)
 
3105
        {
 
3106
            s3GCPrivateIndex = AllocateGCPrivateIndex ();
 
3107
            s3WindowPrivateIndex = AllocateWindowPrivateIndex ();
 
3108
            s3Generation = serverGeneration;
 
3109
        }
 
3110
        if (!AllocateWindowPrivate(pScreen, s3WindowPrivateIndex, 0))
 
3111
            return FALSE;
 
3112
        if (!AllocateGCPrivate(pScreen, s3GCPrivateIndex, sizeof (s3PrivGCRec)))
 
3113
            return FALSE;
 
3114
        pScreen->CreateGC = s3CreateGC;
 
3115
        pScreen->CreateWindow = s3CreateWindow;
 
3116
        pScreen->ChangeWindowAttributes = s3ChangeWindowAttributes;
 
3117
        pScreen->DestroyWindow = s3DestroyWindow;
 
3118
        pScreen->PaintWindowBackground = s3PaintWindow;
 
3119
        pScreen->PaintWindowBorder = s3PaintWindow;
 
3120
#ifndef S3_TRIO
 
3121
        if (pScreenPriv->screen->fb[1].depth)
 
3122
        {
 
3123
            FbOverlayScrPrivPtr pScrPriv = fbOverlayGetScrPriv(pScreen);
 
3124
 
 
3125
            pScrPriv->PaintKey = s3PaintKey;
 
3126
            pScrPriv->CopyWindow = s3CopyWindowProc;
 
3127
            pScreen->CopyWindow = fbOverlayCopyWindow;
 
3128
        }
 
3129
        else
 
3130
#endif
 
3131
            pScreen->CopyWindow = s3CopyWindow;
 
3132
        
 
3133
        /*
 
3134
         * Initialize patterns
 
3135
         */
 
3136
#ifdef S3_TRIO
 
3137
        ma = 0;
 
3138
#else
 
3139
        for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
 
3140
#endif
 
3141
        {
 
3142
            ncache_w = s3s->fb[ma].offscreen_width / S3_TILE_SIZE;
 
3143
            ncache_h = s3s->fb[ma].offscreen_height / S3_TILE_SIZE;
 
3144
            ncache = ncache_w * ncache_h;
 
3145
            if (ncache > 64)
 
3146
                ncache = 64;
 
3147
            DRAW_DEBUG ((DEBUG_S3INIT, "ncache_w %d ncache_h %d ncache %d",
 
3148
                         ncache_w, ncache_h, ncache));
 
3149
            s3s->fb[ma].patterns.cache = (S3PatternCache *) xalloc (ncache * sizeof (S3PatternCache));
 
3150
            if (s3s->fb[ma].patterns.cache)
 
3151
            {
 
3152
                DRAW_DEBUG ((DEBUG_S3INIT, "Have pattern cache"));
 
3153
                s3s->fb[ma].patterns.ncache = ncache;
 
3154
                s3s->fb[ma].patterns.last_used = 0;
 
3155
                s3s->fb[ma].patterns.last_id = 0;
 
3156
                cache = s3s->fb[ma].patterns.cache;
 
3157
                for (py = 0; py < ncache_h && ncache; py++)
 
3158
                    for (px = 0; px < ncache_w && ncache; px++)
 
3159
                    {
 
3160
                        cache->id = 0;
 
3161
                        cache->x = s3s->fb[ma].offscreen_x + px * S3_TILE_SIZE;
 
3162
                        cache->y = s3s->fb[ma].offscreen_y + py * S3_TILE_SIZE;
 
3163
                        cache++;
 
3164
                        ncache--;
 
3165
                    }
 
3166
            }
 
3167
        }
 
3168
    }
 
3169
    return TRUE;
 
3170
}
 
3171
 
 
3172
void
 
3173
s3DrawEnable (ScreenPtr pScreen)
 
3174
{
 
3175
    SetupS3(pScreen);
 
3176
    s3ScreenInfo(pScreenPriv);
 
3177
    int     c;
 
3178
    int     ma;
 
3179
    
 
3180
    s3SetGlobalBitmap (pScreen, 0);
 
3181
    _s3WaitIdleEmpty (s3);
 
3182
    if (pScreenPriv->screen->fb[0].bitsPerPixel == 24)
 
3183
    {
 
3184
        _s3SetScissorsTl(s3, 0, 0);
 
3185
        _s3SetScissorsBr(s3, pScreenPriv->screen->width*3 - 1, pScreenPriv->screen->height - 1);
 
3186
        _s3SetSolidFill(s3, pScreen->whitePixel, GXcopy, ~0);
 
3187
        _s3SolidRect (s3, 0, 0, pScreenPriv->screen->width*3, pScreenPriv->screen->height);
 
3188
    }
 
3189
    else
 
3190
    {
 
3191
        /*
 
3192
         * Flush pattern cache
 
3193
         */
 
3194
#ifdef S3_TRIO
 
3195
        ma = 0;
 
3196
#else
 
3197
        for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
 
3198
#endif
 
3199
        {
 
3200
            for (c = 0; c < s3s->fb[ma].patterns.ncache; c++)
 
3201
                s3s->fb[ma].patterns.cache[c].id = 0;
 
3202
        }
 
3203
 
 
3204
        _s3SetScissorsTl(s3, 0, 0);
 
3205
        _s3SetScissorsBr(s3, pScreenPriv->screen->width - 1, pScreenPriv->screen->height - 1);
 
3206
        _s3SetSolidFill(s3, pScreen->blackPixel, GXcopy, ~0);
 
3207
        _s3SolidRect (s3, 0, 0, pScreenPriv->screen->width, pScreenPriv->screen->height);
 
3208
    }
 
3209
    MarkSyncS3 (pScreen);
 
3210
}
 
3211
 
 
3212
void
 
3213
s3DrawDisable (ScreenPtr pScreen)
 
3214
{
 
3215
    SetupS3 (pScreen);
 
3216
    _s3WaitIdleEmpty (s3);
 
3217
}
 
3218
 
 
3219
void
 
3220
s3DrawFini (ScreenPtr pScreen)
 
3221
{
 
3222
    SetupS3(pScreen);
 
3223
    s3ScreenInfo(pScreenPriv);
 
3224
    int     ma;
 
3225
    
 
3226
#ifdef S3_TRIO
 
3227
    ma = 0;
 
3228
#else
 
3229
    for (ma = 0; s3s->fbmap[ma] >= 0; ma++)
 
3230
#endif
 
3231
    {
 
3232
        if (s3s->fb[ma].patterns.cache)
 
3233
        {
 
3234
            xfree (s3s->fb[ma].patterns.cache);
 
3235
            s3s->fb[ma].patterns.cache = 0;
 
3236
            s3s->fb[ma].patterns.ncache = 0;
 
3237
        }
 
3238
    }
 
3239
}
 
3240
 
 
3241
void
 
3242
s3DrawSync (ScreenPtr pScreen)
 
3243
{
 
3244
    SetupS3(pScreen);
 
3245
    
 
3246
    _s3WaitIdleEmpty(s3c->s3);
 
3247
}