Annotation of researchv9/X11/src/X.V11R1/server/ddx/mfb/mfbfillsp.c, revision 1.1.1.1

1.1       root        1: /***********************************************************
                      2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      4: 
                      5:                         All Rights Reserved
                      6: 
                      7: Permission to use, copy, modify, and distribute this software and its 
                      8: documentation for any purpose and without fee is hereby granted, 
                      9: provided that the above copyright notice appear in all copies and that
                     10: both that copyright notice and this permission notice appear in 
                     11: supporting documentation, and that the names of Digital or MIT not be
                     12: used in advertising or publicity pertaining to distribution of the
                     13: software without specific, written prior permission.  
                     14: 
                     15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     21: SOFTWARE.
                     22: 
                     23: ******************************************************************/
                     24: /* $Header: mfbfillsp.c,v 1.29 87/09/07 19:08:34 toddb Exp $ */
                     25: #include "X.h"
                     26: #include "Xmd.h"
                     27: #include "gcstruct.h"
                     28: #include "window.h"
                     29: #include "pixmapstr.h"
                     30: #include "scrnintstr.h"
                     31: #include "windowstr.h"
                     32: #include "mfb.h"
                     33: #include "maskbits.h"
                     34: 
                     35: #include "servermd.h"
                     36: 
                     37: /* scanline filling for monochrome frame buffer
                     38:    written by drewry, oct 1986
                     39: 
                     40:    these routines all clip.  they assume that anything that has called
                     41: them has already translated the points (i.e. pGC->miTranslate is
                     42: non-zero, which is howit gets set in mfbCreateGC().)
                     43: 
                     44:    the number of new scnalines created by clipping ==
                     45: MaxRectsPerBand * nSpans.
                     46: 
                     47:     FillSolid is overloaded to be used for OpaqueStipple as well,
                     48: if fgPixel == bgPixel.  
                     49: 
                     50: 
                     51:     FillTiled is overloaded to be used for OpaqueStipple, if
                     52: fgPixel != bgPixel.  based on the fill style, it uses
                     53: {RotatedTile, gc.alu} or {RotatedStipple, PrivGC.ropOpStip}
                     54: */
                     55: 
                     56: 
                     57: void mfbBlackSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                     58:     DrawablePtr pDrawable;
                     59:     GCPtr      pGC;
                     60:     int                nInit;                  /* number of spans to fill */
                     61:     DDXPointPtr pptInit;               /* pointer to list of start points */
                     62:     int                *pwidthInit;            /* pointer to list of n widths */
                     63:     int        fSorted;
                     64: {
                     65:                                /* next three parameters are post-clip */
                     66:     int n;                     /* number of spans to fill */
                     67:     register DDXPointPtr ppt;  /* pointer to list of start points */
                     68:     register int *pwidth;      /* pointer to list of n widths */
                     69:     int *addrlBase;            /* pointer to start of bitmap */
                     70:     int nlwidth;               /* width in longwords of bitmap */
                     71:     register int *addrl;       /* pointer to current longword in bitmap */
                     72:     register int startmask;
                     73:     register int endmask;
                     74:     register int nlmiddle;
                     75:     int *pwidthFree;           /* copies of the pointers to free */
                     76:     DDXPointPtr pptFree;
                     77: 
                     78:     if (!(pGC->planemask & 1))
                     79:        return;
                     80: 
                     81:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                     82:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                     83:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                     84:     if(!pptFree || !pwidthFree)
                     85:     {
                     86:        DEALLOCATE_LOCAL(pptFree);
                     87:        DEALLOCATE_LOCAL(pwidthFree);
                     88:        return;
                     89:     }
                     90:     pwidth = pwidthFree;
                     91:     ppt = pptFree;
                     92:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                     93:                    pptInit, pwidthInit, nInit,
                     94:                    ppt, pwidth, fSorted);
                     95: 
                     96:     if (pDrawable->type == DRAWABLE_WINDOW)
                     97:     {
                     98:        addrlBase = (int *)
                     99:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    100:        nlwidth = (int)
                    101:                  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    102:     }
                    103:     else
                    104:     {
                    105:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    106:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    107:     }
                    108: 
                    109:     while (n--)
                    110:     {
                    111:         addrl = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5);
                    112: 
                    113:        if (*pwidth)
                    114:        {
                    115:            if ( ((ppt->x & 0x1f) + *pwidth) < 32)
                    116:            {
                    117:                /* all bits inside same longword */
                    118:                maskpartialbits(ppt->x, *pwidth, startmask);
                    119:                    *addrl &= ~startmask;
                    120:            }
                    121:            else
                    122:            {
                    123:                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
                    124:                if (startmask)
                    125:                    *addrl++ &= ~startmask;
                    126:                while (nlmiddle--)
                    127:                    *addrl++ = 0x0;
                    128:                if (endmask)
                    129:                    *addrl &= ~endmask;
                    130:            }
                    131:        }
                    132:        pwidth++;
                    133:        ppt++;
                    134:     }
                    135:     DEALLOCATE_LOCAL(pptFree);
                    136:     DEALLOCATE_LOCAL(pwidthFree);
                    137: }
                    138: 
                    139: 
                    140: 
                    141: void mfbWhiteSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                    142:     DrawablePtr pDrawable;
                    143:     GCPtr      pGC;
                    144:     int                nInit;                  /* number of spans to fill */
                    145:     DDXPointPtr pptInit;               /* pointer to list of start points */
                    146:     int                *pwidthInit;            /* pointer to list of n widths */
                    147:     int        fSorted;
                    148: {
                    149:                                /* next three parameters are post-clip */
                    150:     int n;                     /* number of spans to fill */
                    151:     register DDXPointPtr ppt;  /* pointer to list of start points */
                    152:     register int *pwidth;      /* pointer to list of n widths */
                    153:     int *addrlBase;            /* pointer to start of bitmap */
                    154:     int nlwidth;               /* width in longwords of bitmap */
                    155:     register int *addrl;       /* pointer to current longword in bitmap */
                    156:     register int startmask;
                    157:     register int endmask;
                    158:     register int nlmiddle;
                    159:     int *pwidthFree;           /* copies of the pointers to free */
                    160:     DDXPointPtr pptFree;
                    161: 
                    162:     if (!(pGC->planemask & 1))
                    163:        return;
                    164: 
                    165:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                    166:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                    167:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                    168:     if(!pptFree || !pwidthFree)
                    169:     {
                    170:        DEALLOCATE_LOCAL(pptFree);
                    171:        DEALLOCATE_LOCAL(pwidthFree);
                    172:        return;
                    173:     }
                    174:     pwidth = pwidthFree;
                    175:     ppt = pptFree;
                    176:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                    177:                    pptInit, pwidthInit, nInit,
                    178:                    ppt, pwidth, fSorted);
                    179: 
                    180:     if (pDrawable->type == DRAWABLE_WINDOW)
                    181:     {
                    182:        addrlBase = (int *)
                    183:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    184:        nlwidth = (int)
                    185:                 (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    186:     }
                    187:     else
                    188:     {
                    189:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    190:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    191:     }
                    192: 
                    193:     while (n--)
                    194:     {
                    195:         addrl = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5);
                    196: 
                    197:        if (*pwidth)
                    198:        {
                    199:            if ( ((ppt->x & 0x1f) + *pwidth) < 32)
                    200:            {
                    201:                /* all bits inside same longword */
                    202:                maskpartialbits(ppt->x, *pwidth, startmask);
                    203:                *addrl |= startmask;
                    204:            }
                    205:            else
                    206:            {
                    207:                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
                    208:                if (startmask)
                    209:                    *addrl++ |= startmask;
                    210:                while (nlmiddle--)
                    211:                    *addrl++ = 0xffffffff;
                    212:                if (endmask)
                    213:                    *addrl |= endmask;
                    214:            }
                    215:        }
                    216:        pwidth++;
                    217:        ppt++;
                    218:     }
                    219:     DEALLOCATE_LOCAL(pptFree);
                    220:     DEALLOCATE_LOCAL(pwidthFree);
                    221: }
                    222: 
                    223: 
                    224: 
                    225: void mfbInvertSolidFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                    226:     DrawablePtr pDrawable;
                    227:     GCPtr      pGC;
                    228:     int                nInit;                  /* number of spans to fill */
                    229:     DDXPointPtr pptInit;               /* pointer to list of start points */
                    230:     int                *pwidthInit;            /* pointer to list of n widths */
                    231:     int        fSorted;
                    232: {
                    233:                                /* next three parameters are post-clip */
                    234:     int n;                     /* number of spans to fill */
                    235:     register DDXPointPtr ppt;  /* pointer to list of start points */
                    236:     register int *pwidth;      /* pointer to list of n widths */
                    237:     int *addrlBase;            /* pointer to start of bitmap */
                    238:     int nlwidth;               /* width in longwords of bitmap */
                    239:     register int *addrl;       /* pointer to current longword in bitmap */
                    240:     register int startmask;
                    241:     register int endmask;
                    242:     register int nlmiddle;
                    243:     int *pwidthFree;           /* copies of the pointers to free */
                    244:     DDXPointPtr pptFree;
                    245: 
                    246:     if (!(pGC->planemask & 1))
                    247:        return;
                    248: 
                    249:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                    250:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                    251:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                    252:     if(!pptFree || !pwidthFree)
                    253:     {
                    254:        DEALLOCATE_LOCAL(pptFree);
                    255:        DEALLOCATE_LOCAL(pwidthFree);
                    256:        return;
                    257:     }
                    258:     pwidth = pwidthFree;
                    259:     ppt = pptFree;
                    260:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                    261:                    pptInit, pwidthInit, nInit,
                    262:                    ppt, pwidth, fSorted);
                    263: 
                    264:     if (pDrawable->type == DRAWABLE_WINDOW)
                    265:     {
                    266:        addrlBase = (int *)
                    267:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    268:        nlwidth = (int)
                    269:                  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    270:     }
                    271:     else
                    272:     {
                    273:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    274:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    275:     }
                    276: 
                    277:     while (n--)
                    278:     {
                    279:         addrl = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5);
                    280: 
                    281:        if (*pwidth)
                    282:        {
                    283:            if ( ((ppt->x & 0x1f) + *pwidth) < 32)
                    284:            {
                    285:                /* all bits inside same longword */
                    286:                maskpartialbits(ppt->x, *pwidth, startmask);
                    287:                *addrl ^= startmask;
                    288:            }
                    289:            else
                    290:            {
                    291:                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
                    292:                if (startmask)
                    293:                    *addrl++ ^= startmask;
                    294:                while (nlmiddle--)
                    295:                    *addrl++ ^= 0xffffffff;
                    296:                if (endmask)
                    297:                    *addrl ^= endmask;
                    298:            }
                    299:        }
                    300:        pwidth++;
                    301:        ppt++;
                    302:     }
                    303:     DEALLOCATE_LOCAL(pptFree);
                    304:     DEALLOCATE_LOCAL(pwidthFree);
                    305: }
                    306: 
                    307: 
                    308: void 
                    309: mfbWhiteStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                    310: DrawablePtr pDrawable;
                    311: GC *pGC;
                    312: int nInit;                     /* number of spans to fill */
                    313: DDXPointPtr pptInit;           /* pointer to list of start points */
                    314: int *pwidthInit;               /* pointer to list of n widths */
                    315: int fSorted;
                    316: {
                    317:                                /* next three parameters are post-clip */
                    318:     int n;                     /* number of spans to fill */
                    319:     register DDXPointPtr ppt;  /* pointer to list of start points */
                    320:     register int *pwidth;      /* pointer to list of n widths */
                    321:     int *addrlBase;            /* pointer to start of bitmap */
                    322:     int nlwidth;               /* width in longwords of bitmap */
                    323:     register int *addrl;       /* pointer to current longword in bitmap */
                    324:     register int startmask;
                    325:     register int endmask;
                    326:     register int nlmiddle;
                    327:     PixmapPtr pStipple;
                    328:     int *psrc;
                    329:     int src;
                    330:     int tileHeight;
                    331:     int *pwidthFree;           /* copies of the pointers to free */
                    332:     DDXPointPtr pptFree;
                    333: 
                    334:     if (!(pGC->planemask & 1))
                    335:        return;
                    336: 
                    337:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                    338:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                    339:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                    340:     if(!pptFree || !pwidthFree)
                    341:     {
                    342:        DEALLOCATE_LOCAL(pptFree);
                    343:        DEALLOCATE_LOCAL(pwidthFree);
                    344:        return;
                    345:     }
                    346:     pwidth = pwidthFree;
                    347:     ppt = pptFree;
                    348:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                    349:                    pptInit, pwidthInit, nInit, 
                    350:                    ppt, pwidth, fSorted);
                    351: 
                    352:     if (pDrawable->type == DRAWABLE_WINDOW)
                    353:     {
                    354:        addrlBase = (int *)
                    355:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    356:        nlwidth = (int)
                    357:                  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    358:     }
                    359:     else
                    360:     {
                    361:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    362:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    363:     }
                    364: 
                    365:     pStipple = ((mfbPrivGC *)(pGC->devPriv))->pRotatedStipple;
                    366:     tileHeight = pStipple->height;
                    367:     psrc = (int *)(pStipple->devPrivate);
                    368: 
                    369:     while (n--)
                    370:     {
                    371:         addrl = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5);
                    372:        src = psrc[ppt->y % tileHeight];
                    373: 
                    374:         /* all bits inside same longword */
                    375:         if ( ((ppt->x & 0x1f) + *pwidth) < 32)
                    376:         {
                    377:            maskpartialbits(ppt->x, *pwidth, startmask);
                    378:            *addrl |= (src & startmask);
                    379:         }
                    380:         else
                    381:         {
                    382:            maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
                    383:            if (startmask)
                    384:                *addrl++ |= (src & startmask);
                    385:            while (nlmiddle--)
                    386:                *addrl++ |= src;
                    387:            if (endmask)
                    388:                *addrl |= (src & endmask);
                    389:         }
                    390:        pwidth++;
                    391:        ppt++;
                    392:     }
                    393:     DEALLOCATE_LOCAL(pptFree);
                    394:     DEALLOCATE_LOCAL(pwidthFree);
                    395: }
                    396: 
                    397: 
                    398: void 
                    399: mfbBlackStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                    400: DrawablePtr pDrawable;
                    401: GC *pGC;
                    402: int nInit;                     /* number of spans to fill */
                    403: DDXPointPtr pptInit;           /* pointer to list of start points */
                    404: int *pwidthInit;               /* pointer to list of n widths */
                    405: int fSorted;
                    406: {
                    407:                                /* next three parameters are post-clip */
                    408:     int n;                     /* number of spans to fill */
                    409:     register DDXPointPtr ppt;  /* pointer to list of start points */
                    410:     register int *pwidth;      /* pointer to list of n widths */
                    411:     int *addrlBase;            /* pointer to start of bitmap */
                    412:     int nlwidth;               /* width in longwords of bitmap */
                    413:     register int *addrl;       /* pointer to current longword in bitmap */
                    414:     register int startmask;
                    415:     register int endmask;
                    416:     register int nlmiddle;
                    417:     PixmapPtr pStipple;
                    418:     int *psrc;
                    419:     int src;
                    420:     int tileHeight;
                    421:     int *pwidthFree;           /* copies of the pointers to free */
                    422:     DDXPointPtr pptFree;
                    423: 
                    424:     if (!(pGC->planemask & 1))
                    425:        return;
                    426: 
                    427:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                    428:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                    429:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                    430:     if(!pptFree || !pwidthFree)
                    431:     {
                    432:        DEALLOCATE_LOCAL(pptFree);
                    433:        DEALLOCATE_LOCAL(pwidthFree);
                    434:        return;
                    435:     }
                    436:     pwidth = pwidthFree;
                    437:     ppt = pptFree;
                    438:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                    439:                    pptInit, pwidthInit, nInit, 
                    440:                    ppt, pwidth, fSorted);
                    441: 
                    442:     if (pDrawable->type == DRAWABLE_WINDOW)
                    443:     {
                    444:        addrlBase = (int *)
                    445:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    446:        nlwidth = (int)
                    447:                  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    448:     }
                    449:     else
                    450:     {
                    451:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    452:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    453:     }
                    454: 
                    455:     pStipple = ((mfbPrivGC *)(pGC->devPriv))->pRotatedStipple;
                    456:     tileHeight = pStipple->height;
                    457:     psrc = (int *)(pStipple->devPrivate);
                    458: 
                    459:     while (n--)
                    460:     {
                    461:         addrl = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5);
                    462:        src = psrc[ppt->y % tileHeight];
                    463: 
                    464:         /* all bits inside same longword */
                    465:         if ( ((ppt->x & 0x1f) + *pwidth) < 32)
                    466:         {
                    467:            maskpartialbits(ppt->x, *pwidth, startmask);
                    468:            *addrl &= ~(src & startmask);
                    469:         }
                    470:         else
                    471:         {
                    472:            maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
                    473:            if (startmask)
                    474:                *addrl++ &= ~(src & startmask);
                    475:            while (nlmiddle--)
                    476:                *addrl++ &= ~src;
                    477:            if (endmask)
                    478:                *addrl &= ~(src & endmask);
                    479:         }
                    480:        pwidth++;
                    481:        ppt++;
                    482:     }
                    483:     DEALLOCATE_LOCAL(pptFree);
                    484:     DEALLOCATE_LOCAL(pwidthFree);
                    485: }
                    486: 
                    487: 
                    488: void 
                    489: mfbInvertStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                    490: DrawablePtr pDrawable;
                    491: GC *pGC;
                    492: int nInit;                     /* number of spans to fill */
                    493: DDXPointPtr pptInit;           /* pointer to list of start points */
                    494: int *pwidthInit;               /* pointer to list of n widths */
                    495: int fSorted;
                    496: {
                    497:                                /* next three parameters are post-clip */
                    498:     int n;                     /* number of spans to fill */
                    499:     register DDXPointPtr ppt;  /* pointer to list of start points */
                    500:     register int *pwidth;      /* pointer to list of n widths */
                    501:     int *addrlBase;            /* pointer to start of bitmap */
                    502:     int nlwidth;               /* width in longwords of bitmap */
                    503:     register int *addrl;       /* pointer to current longword in bitmap */
                    504:     register int startmask;
                    505:     register int endmask;
                    506:     register int nlmiddle;
                    507:     PixmapPtr pStipple;
                    508:     int *psrc;
                    509:     int src;
                    510:     int tileHeight;
                    511:     int *pwidthFree;           /* copies of the pointers to free */
                    512:     DDXPointPtr pptFree;
                    513: 
                    514:     if (!(pGC->planemask & 1))
                    515:        return;
                    516: 
                    517:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                    518:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                    519:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                    520:     if(!pptFree || !pwidthFree)
                    521:     {
                    522:        DEALLOCATE_LOCAL(pptFree);
                    523:        DEALLOCATE_LOCAL(pwidthFree);
                    524:        return;
                    525:     }
                    526:     pwidth = pwidthFree;
                    527:     ppt = pptFree;
                    528:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                    529:                    pptInit, pwidthInit, nInit, 
                    530:                    ppt, pwidth, fSorted);
                    531: 
                    532:     if (pDrawable->type == DRAWABLE_WINDOW)
                    533:     {
                    534:        addrlBase = (int *)
                    535:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    536:        nlwidth = (int)
                    537:                  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    538:     }
                    539:     else
                    540:     {
                    541:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    542:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    543:     }
                    544: 
                    545:     pStipple = ((mfbPrivGC *)(pGC->devPriv))->pRotatedStipple;
                    546:     tileHeight = pStipple->height;
                    547:     psrc = (int *)(pStipple->devPrivate);
                    548: 
                    549:     while (n--)
                    550:     {
                    551:         addrl = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5);
                    552:        src = psrc[ppt->y % tileHeight];
                    553: 
                    554:         /* all bits inside same longword */
                    555:         if ( ((ppt->x & 0x1f) + *pwidth) < 32)
                    556:         {
                    557:            maskpartialbits(ppt->x, *pwidth, startmask);
                    558:            *addrl ^= (src & startmask);
                    559:         }
                    560:         else
                    561:         {
                    562:            maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle);
                    563:            if (startmask)
                    564:                *addrl++ ^= (src & startmask);
                    565:            while (nlmiddle--)
                    566:                *addrl++ ^= src;
                    567:            if (endmask)
                    568:                *addrl ^= (src & endmask);
                    569:         }
                    570:        pwidth++;
                    571:        ppt++;
                    572:     }
                    573:     DEALLOCATE_LOCAL(pptFree);
                    574:     DEALLOCATE_LOCAL(pwidthFree);
                    575: }
                    576: 
                    577: 
                    578: /* this works with tiles of width == 32 */
                    579: #define FILLSPAN32(ROP) \
                    580:     while (n--) \
                    581:     { \
                    582:        if (*pwidth) \
                    583:        { \
                    584:             addrl = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5); \
                    585:            src = psrc[ppt->y % tileHeight]; \
                    586:             if ( ((ppt->x & 0x1f) + *pwidth) < 32) \
                    587:             { \
                    588:                maskpartialbits(ppt->x, *pwidth, startmask); \
                    589:                *addrl = (*addrl & ~startmask) | \
                    590:                         (ROP(src, *addrl) & startmask); \
                    591:             } \
                    592:             else \
                    593:             { \
                    594:                maskbits(ppt->x, *pwidth, startmask, endmask, nlmiddle); \
                    595:                if (startmask) \
                    596:                { \
                    597:                    *addrl = (*addrl & ~startmask) | \
                    598:                             (ROP(src, *addrl) & startmask); \
                    599:                    addrl++; \
                    600:                } \
                    601:                while (nlmiddle--) \
                    602:                { \
                    603:                    *addrl = ROP(src, *addrl); \
                    604:                    addrl++; \
                    605:                } \
                    606:                if (endmask) \
                    607:                    *addrl = (*addrl & ~endmask) | \
                    608:                             (ROP(src, *addrl) & endmask); \
                    609:             } \
                    610:        } \
                    611:        pwidth++; \
                    612:        ppt++; \
                    613:     }
                    614: 
                    615: 
                    616: 
                    617: void mfbTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                    618: DrawablePtr pDrawable;
                    619: GC *pGC;
                    620: int nInit;                     /* number of spans to fill */
                    621: DDXPointPtr pptInit;           /* pointer to list of start points */
                    622: int *pwidthInit;               /* pointer to list of n widths */
                    623: int fSorted;
                    624: {
                    625:                                /* next three parameters are post-clip */
                    626:     int n;                     /* number of spans to fill */
                    627:     register DDXPointPtr ppt;  /* pointer to list of start points */
                    628:     register int *pwidth;      /* pointer to list of n widths */
                    629:     int *addrlBase;            /* pointer to start of bitmap */
                    630:     int nlwidth;               /* width in longwords of bitmap */
                    631:     register int *addrl;       /* pointer to current longword in bitmap */
                    632:     register int startmask;
                    633:     register int endmask;
                    634:     register int nlmiddle;
                    635:     PixmapPtr pTile;
                    636:     int *psrc;
                    637:     register int src;
                    638:     int tileHeight;
                    639:     int rop;
                    640:     int *pwidthFree;           /* copies of the pointers to free */
                    641:     DDXPointPtr pptFree;
                    642: 
                    643:     if (!(pGC->planemask & 1))
                    644:        return;
                    645: 
                    646:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                    647:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                    648:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                    649:     if(!pptFree || !pwidthFree)
                    650:     {
                    651:        DEALLOCATE_LOCAL(pptFree);
                    652:        DEALLOCATE_LOCAL(pwidthFree);
                    653:        return;
                    654:     }
                    655:     pwidth = pwidthFree;
                    656:     ppt = pptFree;
                    657:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                    658:                    pptInit, pwidthInit, nInit, 
                    659:                    ppt, pwidth, fSorted);
                    660: 
                    661:     if (pDrawable->type == DRAWABLE_WINDOW)
                    662:     {
                    663:        addrlBase = (int *)
                    664:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    665:        nlwidth = (int)
                    666:                  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    667:     }
                    668:     else
                    669:     {
                    670:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    671:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    672:     }
                    673: 
                    674:     if (pGC->fillStyle == FillTiled)
                    675:     {
                    676:        pTile = ((mfbPrivGC *)(pGC->devPriv))->pRotatedTile;
                    677:        tileHeight = pTile->height;
                    678:        psrc = (int *)(pTile->devPrivate);
                    679:        rop = pGC->alu;
                    680:     }
                    681:     else
                    682:     {
                    683:        pTile = ((mfbPrivGC *)(pGC->devPriv))->pRotatedStipple;
                    684:        tileHeight = pTile->height;
                    685:        psrc = (int *)(pTile->devPrivate);
                    686:        rop = ((mfbPrivGC *)(pGC->devPriv))->ropOpStip;
                    687:     }
                    688: 
                    689: 
                    690:     switch(rop)
                    691:     {
                    692:       case GXclear:
                    693:        FILLSPAN32(fnCLEAR)
                    694:        break;
                    695:       case GXand:
                    696:        FILLSPAN32(fnAND)
                    697:        break;
                    698:       case GXandReverse:
                    699:        FILLSPAN32(fnANDREVERSE)
                    700:        break;
                    701:       case GXcopy:
                    702:        FILLSPAN32(fnCOPY)
                    703:        break;
                    704:       case GXandInverted:
                    705:        FILLSPAN32(fnANDINVERTED)
                    706:        break;
                    707:       case GXnoop:
                    708:        break;
                    709:       case GXxor:
                    710:        FILLSPAN32(fnXOR)
                    711:        break;
                    712:       case GXor:
                    713:        FILLSPAN32(fnOR)
                    714:        break;
                    715:       case GXnor:
                    716:        FILLSPAN32(fnNOR)
                    717:        break;
                    718:       case GXequiv:
                    719:        FILLSPAN32(fnEQUIV)
                    720:        break;
                    721:       case GXinvert:
                    722:        FILLSPAN32(fnINVERT)
                    723:        break;
                    724:       case GXorReverse:
                    725:        FILLSPAN32(fnORREVERSE)
                    726:        break;
                    727:       case GXcopyInverted:
                    728:        FILLSPAN32(fnCOPYINVERTED)
                    729:        break;
                    730:       case GXorInverted:
                    731:        FILLSPAN32(fnORINVERTED)
                    732:        break;
                    733:       case GXnand:
                    734:        FILLSPAN32(fnNAND)
                    735:        break;
                    736:       case GXset:
                    737:        FILLSPAN32(fnSET)
                    738:        break;
                    739:     }
                    740:     DEALLOCATE_LOCAL(pptFree);
                    741:     DEALLOCATE_LOCAL(pwidthFree);
                    742: }
                    743: 
                    744: 
                    745: /* Fill spans with tiles that aren't 32 bits wide */
                    746: void
                    747: mfbUnnaturalTileFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                    748: DrawablePtr pDrawable;
                    749: GC             *pGC;
                    750: int            nInit;          /* number of spans to fill */
                    751: DDXPointPtr pptInit;           /* pointer to list of start points */
                    752: int *pwidthInit;               /* pointer to list of n widths */
                    753: int fSorted;
                    754: {
                    755:     int                iline;          /* first line of tile to use */
                    756:                                /* next three parameters are post-clip */
                    757:     int n;                     /* number of spans to fill */
                    758:     register DDXPointPtr ppt;  /* pointer to list of start points */
                    759:     register int *pwidth;      /* pointer to list of n widths */
                    760:     int                *addrlBase;     /* pointer to start of bitmap */
                    761:     int                 nlwidth;       /* width in longwords of bitmap */
                    762:     register int *pdst;                /* pointer to current word in bitmap */
                    763:     register int *psrc;                /* pointer to current word in tile */
                    764:     register int startmask;
                    765:     register int nlMiddle;
                    766:     PixmapPtr  pTile;          /* pointer to tile we want to fill with */
                    767:     int                w, width, x, xSrc, ySrc, tmpSrc, srcStartOver, nstart, nend;
                    768:     int        endmask, tlwidth, rem, tileWidth, *psrcT, endinc, rop;
                    769:     int *pwidthFree;           /* copies of the pointers to free */
                    770:     DDXPointPtr pptFree;
                    771: 
                    772:     if (!(pGC->planemask & 1))
                    773:        return;
                    774: 
                    775:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                    776:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                    777:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                    778:     if(!pptFree || !pwidthFree)
                    779:     {
                    780:        DEALLOCATE_LOCAL(pptFree);
                    781:        DEALLOCATE_LOCAL(pwidthFree);
                    782:        return;
                    783:     }
                    784:     pwidth = pwidthFree;
                    785:     ppt = pptFree;
                    786:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                    787:                    pptInit, pwidthInit, nInit, 
                    788:                    ppt, pwidth, fSorted);
                    789: 
                    790:     if (pGC->fillStyle == FillTiled)
                    791:     {
                    792:        pTile = pGC->tile;
                    793:        tlwidth = pTile->devKind >> 2;
                    794:        rop = pGC->alu;
                    795:     }
                    796:     else
                    797:     {
                    798:        pTile = pGC->stipple;
                    799:        tlwidth = pTile->devKind >> 2;
                    800:        rop = ((mfbPrivGC *)(pGC->devPriv))->ropOpStip;
                    801:     }
                    802: 
                    803:     if (pDrawable->type == DRAWABLE_WINDOW)
                    804:     {
                    805:        addrlBase = (int *)
                    806:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    807:        nlwidth = (int)
                    808:                  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    809:        xSrc = ((WindowPtr) pDrawable)->absCorner.x;
                    810:        ySrc = ((WindowPtr) pDrawable)->absCorner.y;
                    811:     }
                    812:     else
                    813:     {
                    814:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    815:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    816:        xSrc = 0;
                    817:        ySrc = 0;
                    818:     }
                    819: 
                    820:     tileWidth = pTile->width;
                    821: 
                    822:     /* this replaces rotating the tile. Instead we just adjust the offset
                    823:      * at which we start grabbing bits from the tile */
                    824:     xSrc += pGC->patOrg.x;
                    825:     ySrc += pGC->patOrg.y;
                    826: 
                    827:     while (n--)
                    828:     {
                    829:        iline = (ppt->y - ySrc) % pTile->height;
                    830:         pdst = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5);
                    831:         psrcT = (int *) pTile->devPrivate + (iline * tlwidth);
                    832:        x = ppt->x;
                    833: 
                    834:        if (*pwidth)
                    835:        {
                    836:            width = *pwidth;
                    837:            while(width > 0)
                    838:            {
                    839:                psrc = psrcT;
                    840:                w = min(tileWidth, width);
                    841:                if((rem = (x - xSrc)  % tileWidth) != 0)
                    842:                {
                    843:                    /* if we're in the middle of the tile, get
                    844:                       as many bits as will finish the span, or
                    845:                       as many as will get to the left edge of the tile,
                    846:                       or a longword worth, starting at the appropriate
                    847:                       offset in the tile.
                    848:                    */
                    849:                    w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_UNIT);
                    850:                    endinc = rem / BITMAP_SCANLINE_UNIT;
                    851:                    getbits(psrc + endinc, rem & 0x1f, w, tmpSrc);
                    852:                    putbitsrop(tmpSrc, (x & 0x1f), w, pdst, rop);
                    853:                    if((x & 0x1f) + w >= 0x20)
                    854:                        pdst++;
                    855:                }
                    856:                else if(((x & 0x1f) + w) < 32)
                    857:                {
                    858:                    /* doing < 32 bits is easy, and worth special-casing */
                    859:                    getbits(psrc, 0, w, tmpSrc);
                    860:                    putbitsrop(tmpSrc, x & 0x1f, w, pdst, rop);
                    861:                }
                    862:                else
                    863:                {
                    864:                    /* start at the left edge of the tile,
                    865:                       and put down as much as we can
                    866:                    */
                    867:                    maskbits(x, w, startmask, endmask, nlMiddle);
                    868: 
                    869:                    if (startmask)
                    870:                        nstart = 32 - (x & 0x1f);
                    871:                    else
                    872:                        nstart = 0;
                    873:                    if (endmask)
                    874:                        nend = (x + w)  & 0x1f;
                    875:                    else
                    876:                        nend = 0;
                    877: 
                    878:                    srcStartOver = nstart > 31;
                    879: 
                    880:                    if(startmask)
                    881:                    {
                    882:                        getbits(psrc, 0, nstart, tmpSrc);
                    883:                        putbitsrop(tmpSrc, (x & 0x1f), nstart, pdst, rop);
                    884:                        pdst++;
                    885:                        if(srcStartOver)
                    886:                            psrc++;
                    887:                    }
                    888:                     
                    889:                    while(nlMiddle--)
                    890:                    {
                    891:                            getbits(psrc, nstart, 32, tmpSrc);
                    892:                            *pdst = DoRop(rop, tmpSrc, *pdst);
                    893:                            pdst++;
                    894:                            psrc++;
                    895:                    }
                    896:                    if(endmask)
                    897:                    {
                    898:                        getbits(psrc, nstart, nend, tmpSrc);
                    899:                        putbitsrop(tmpSrc, 0, nend, pdst, rop);
                    900:                    }
                    901:                 }
                    902:                 x += w;
                    903:                 width -= w;
                    904:            }
                    905:        }
                    906:        ppt++;
                    907:        pwidth++;
                    908:     }
                    909:     DEALLOCATE_LOCAL(pptFree);
                    910:     DEALLOCATE_LOCAL(pwidthFree);
                    911: }
                    912: 
                    913: 
                    914: /* Fill spans with stipples that aren't 32 bits wide */
                    915: void
                    916: mfbUnnaturalStippleFS(pDrawable, pGC, nInit, pptInit, pwidthInit, fSorted)
                    917: DrawablePtr pDrawable;
                    918: GC             *pGC;
                    919: int            nInit;          /* number of spans to fill */
                    920: DDXPointPtr pptInit;           /* pointer to list of start points */
                    921: int *pwidthInit;               /* pointer to list of n widths */
                    922: int fSorted;
                    923: {
                    924:                                /* next three parameters are post-clip */
                    925:     int n;                     /* number of spans to fill */
                    926:     register DDXPointPtr ppt;  /* pointer to list of start points */
                    927:     register int *pwidth;      /* pointer to list of n widths */
                    928:     int                iline;          /* first line of tile to use */
                    929:     int                *addrlBase;     /* pointer to start of bitmap */
                    930:     int                 nlwidth;       /* width in longwords of bitmap */
                    931:     register int *pdst;                /* pointer to current word in bitmap */
                    932:     register int *psrc;                /* pointer to current word in tile */
                    933:     register int startmask;
                    934:     register int nlMiddle;
                    935:     PixmapPtr  pTile;          /* pointer to tile we want to fill with */
                    936:     int                w, width,  x, xSrc, ySrc, tmpSrc, srcStartOver, nstart, nend;
                    937:     int        endmask, tlwidth, rem, tileWidth, *psrcT, endinc, rop;
                    938:     int *pwidthFree;           /* copies of the pointers to free */
                    939:     DDXPointPtr pptFree;
                    940: 
                    941:     if (!(pGC->planemask & 1))
                    942:        return;
                    943: 
                    944:     n = nInit * miFindMaxBand(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip);
                    945:     pwidthFree = (int *)ALLOCATE_LOCAL(n * sizeof(int));
                    946:     pptFree = (DDXPointRec *)ALLOCATE_LOCAL(n * sizeof(DDXPointRec));
                    947:     if(!pptFree || !pwidthFree)
                    948:     {
                    949:        DEALLOCATE_LOCAL(pptFree);
                    950:        DEALLOCATE_LOCAL(pwidthFree);
                    951:        return;
                    952:     }
                    953:     pwidth = pwidthFree;
                    954:     ppt = pptFree;
                    955:     n = miClipSpans(((mfbPrivGC *)(pGC->devPriv))->pCompositeClip,
                    956:                    pptInit, pwidthInit, nInit, 
                    957:                    ppt, pwidth, fSorted);
                    958: 
                    959:     pTile = pGC->stipple;
                    960:     rop = ((mfbPrivGC *)(pGC->devPriv))->rop;
                    961:     tlwidth = pTile->devKind >> 2;
                    962:     if (pDrawable->type == DRAWABLE_WINDOW)
                    963:     {
                    964:        addrlBase = (int *)
                    965:                (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devPrivate);
                    966:        nlwidth = (int)
                    967:                  (((PixmapPtr)(pDrawable->pScreen->devPrivate))->devKind) >> 2;
                    968:        xSrc = ((WindowPtr)pDrawable)->absCorner.x;
                    969:        ySrc = ((WindowPtr)pDrawable)->absCorner.y;
                    970:     }
                    971:     else
                    972:     {
                    973:        addrlBase = (int *)(((PixmapPtr)pDrawable)->devPrivate);
                    974:        nlwidth = (int)(((PixmapPtr)pDrawable)->devKind) >> 2;
                    975:        xSrc = 0;
                    976:        ySrc = 0;
                    977:     }
                    978: 
                    979:     tileWidth = pTile->width;
                    980: 
                    981:     /* this replaces rotating the stipple.  Instead, we just adjust the offset
                    982:      * at which we start grabbing bits from the stipple */
                    983:     xSrc += pGC->patOrg.x;
                    984:     ySrc += pGC->patOrg.y;
                    985:     while (n--)
                    986:     {
                    987:        iline = (ppt->y - ySrc) % pTile->height;
                    988:         pdst = addrlBase + (ppt->y * nlwidth) + (ppt->x >> 5);
                    989:         psrcT = (int *) pTile->devPrivate + (iline * tlwidth);
                    990:        x = ppt->x;
                    991: 
                    992:        if (*pwidth)
                    993:        {
                    994:            width = *pwidth;
                    995:            while(width > 0)
                    996:            {
                    997:                psrc = psrcT;
                    998:                w = min(tileWidth, width);
                    999:                if((rem = (x - xSrc) % tileWidth) != 0)
                   1000:                {
                   1001:                    /* if we're in the middle of the tile, get
                   1002:                       as many bits as will finish the span, or
                   1003:                       as many as will get to the left edge of the tile,
                   1004:                       or a longword worth, starting at the appropriate
                   1005:                       offset in the tile.
                   1006:                    */
                   1007:                    w = min(min(tileWidth - rem, width), BITMAP_SCANLINE_UNIT);
                   1008:                    endinc = rem / BITMAP_SCANLINE_UNIT;
                   1009:                    getbits(psrc + endinc, rem & 0x1f, w, tmpSrc);
                   1010:                    putbitsrrop(tmpSrc, (x & 0x1f), w, pdst, rop);
                   1011:                    if((x & 0x1f) + w >= 0x20)
                   1012:                        pdst++;
                   1013:                }
                   1014: 
                   1015:                else if(((x & 0x1f) + w) < 32)
                   1016:                {
                   1017:                    /* doing < 32 bits is easy, and worth special-casing */
                   1018:                    getbits(psrc, 0, w, tmpSrc);
                   1019:                    putbitsrrop(tmpSrc, x & 0x1f, w, pdst, rop);
                   1020:                }
                   1021:                else
                   1022:                {
                   1023:                    /* start at the left edge of the tile,
                   1024:                       and put down as much as we can
                   1025:                    */
                   1026:                    maskbits(x, w, startmask, endmask, nlMiddle);
                   1027: 
                   1028:                    if (startmask)
                   1029:                        nstart = 32 - (x & 0x1f);
                   1030:                    else
                   1031:                        nstart = 0;
                   1032:                    if (endmask)
                   1033:                        nend = (x + w)  & 0x1f;
                   1034:                    else
                   1035:                        nend = 0;
                   1036: 
                   1037:                    srcStartOver = nstart > 31;
                   1038: 
                   1039:                    if(startmask)
                   1040:                    {
                   1041:                        getbits(psrc, 0, nstart, tmpSrc);
                   1042:                        putbitsrrop(tmpSrc, (x & 0x1f), nstart, pdst, rop);
                   1043:                        pdst++;
                   1044:                        if(srcStartOver)
                   1045:                            psrc++;
                   1046:                    }
                   1047:                     
                   1048:                    while(nlMiddle--)
                   1049:                    {
                   1050:                            getbits(psrc, nstart, 32, tmpSrc);
                   1051:                            *pdst = DoRRop(rop, tmpSrc, *pdst);
                   1052:                            pdst++;
                   1053:                            psrc++;
                   1054:                    }
                   1055:                    if(endmask)
                   1056:                    {
                   1057:                        getbits(psrc, nstart, nend, tmpSrc);
                   1058:                        putbitsrrop(tmpSrc, 0, nend, pdst, rop);
                   1059:                    }
                   1060:                 }
                   1061:                 x += w;
                   1062:                 width -= w;
                   1063:            }
                   1064:        }
                   1065:        ppt++;
                   1066:        pwidth++;
                   1067:     }
                   1068:     DEALLOCATE_LOCAL(pptFree);
                   1069:     DEALLOCATE_LOCAL(pwidthFree);
                   1070: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.