Annotation of researchv9/X11/src/X.V11R1/server/ddx/cfb/cfbgc.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: #include "X.h"
                     25: #include "Xmd.h"
                     26: #include "Xproto.h"
                     27: #include "dixfontstr.h"
                     28: #include "fontstruct.h"
                     29: #include "gcstruct.h"
                     30: #include "windowstr.h"
                     31: #include "pixmapstr.h"
                     32: #include "scrnintstr.h"
                     33: #include "region.h"
                     34: 
                     35: #include "cfb.h"
                     36: #include "mistruct.h"
                     37: 
                     38: #include "cfbmskbits.h"
                     39: extern cfbXRotatePixmap();
                     40: extern cfbYRotatePixmap();
                     41: extern void mfbPushPixels();
                     42: 
                     43: Bool
                     44: cfbCreateGC(pGC)
                     45:     register GCPtr pGC;
                     46: {
                     47:     GCInterestPtr pQ;
                     48: 
                     49:     switch (pGC->depth) {
                     50:     case 1:
                     51:        return (mfbCreateGC(pGC));
                     52:     case PSZ:
                     53:        break;
                     54:     default:
                     55:        ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth);
                     56:        return FALSE;
                     57:     }
                     58:     pGC->clientClip = NULL;
                     59:     pGC->clientClipType = CT_NONE;
                     60: 
                     61:     /*
                     62:      * some of the output primitives aren't really necessary, since they
                     63:      * will be filled in ValidateGC because of dix/CreateGC() setting all
                     64:      * the change bits.  Others are necessary because although they depend
                     65:      * on being a color frame buffer, they don't change 
                     66:      */
                     67: 
                     68:     pGC->FillSpans = cfbSolidFS;
                     69:     pGC->SetSpans = cfbSetSpans;
                     70:     pGC->PutImage = miPutImage;
                     71:     pGC->CopyArea = miCopyArea;
                     72:     pGC->CopyPlane = miCopyPlane;
                     73:     pGC->PolyPoint = miPolyPoint;
                     74: 
                     75: #ifdef notdef
                     76:     pGC->Polylines = miNotMiter;    /* Doesn't work for 0-width lines */
                     77: #else
                     78:     pGC->Polylines = miZeroLine;
                     79: #endif notdef
                     80:     pGC->PolySegment = miPolySegment;
                     81:     pGC->PolyRectangle = miPolyRectangle;
                     82:     pGC->PolyArc = miPolyArc;
                     83:     pGC->FillPolygon = miFillPolygon;
                     84:     pGC->PolyFillRect = miPolyFillRect;
                     85:     pGC->PolyFillArc = miPolyFillArc;
                     86:     pGC->PolyText8 = miPolyText8;
                     87:     pGC->ImageText8 = miImageText8;
                     88:     pGC->PolyText16 = miPolyText16;
                     89:     pGC->ImageText16 = miImageText16;
                     90:     pGC->ImageGlyphBlt = miImageGlyphBlt;
                     91:     pGC->PolyGlyphBlt = miPolyGlyphBlt;
                     92: #ifdef notdef
                     93:     pGC->PushPixels = miPushPixels;    /* miPushPixels is garbage */
                     94: #else
                     95:     pGC->PushPixels = mfbPushPixels;   /* but mfbPushPixels isn't depth
                     96:                                         * dependent */
                     97: #endif
                     98:     pGC->LineHelper = miMiter;
                     99:     pGC->ChangeClip = cfbChangeClip;
                    100:     pGC->DestroyClip = cfbDestroyClip;
                    101:     pGC->CopyClip = cfbCopyClip;
                    102: 
                    103:     /* cfb wants to translate before scan convesion */
                    104:     pGC->miTranslate = 1;
                    105: 
                    106:     {
                    107:        cfbPrivGC  *pPriv;
                    108: 
                    109:        pPriv = (cfbPrivGC *) Xalloc(sizeof(cfbPrivGC));
                    110:        if (!pPriv)
                    111:            return FALSE;
                    112:        else {
                    113:            pPriv->rop = pGC->alu;
                    114:            pPriv->fExpose = TRUE;
                    115:            pGC->devPriv = (pointer) pPriv;
                    116:            pPriv->pRotatedTile = NullPixmap;
                    117:            pPriv->pRotatedStipple = NullPixmap;
                    118:            pPriv->pAbsClientRegion = (*pGC->pScreen->RegionCreate) (NULL, 1);
                    119:            pPriv->pCompositeClip = (*pGC->pScreen->RegionCreate) (NULL, 1);
                    120:            pPriv->freeCompClip = REPLACE_CC;
                    121:        }
                    122:     }
                    123:     pQ = (GCInterestPtr) Xalloc(sizeof(GCInterestRec));
                    124:     if (!pQ) {
                    125:        Xfree(pGC->devPriv);
                    126:        return FALSE;
                    127:     }
                    128: 
                    129:     /* Now link this device into the GCque */
                    130:     pGC->pNextGCInterest = pQ;
                    131:     pGC->pLastGCInterest = pQ;
                    132:     pQ->pNextGCInterest = (GCInterestPtr) & pGC->pNextGCInterest;
                    133:     pQ->pLastGCInterest = (GCInterestPtr) & pGC->pNextGCInterest;
                    134:     pQ->length = sizeof(GCInterestRec);
                    135:     pQ->owner = 0;             /* server owns this */
                    136:     pQ->ValInterestMask = ~0;  /* interested in everything at validate
                    137:                                 * time */
                    138:     pQ->ValidateGC = cfbValidateGC;
                    139:     pQ->ChangeInterestMask = 0;        /* interested in nothing at change time */
                    140:     pQ->ChangeGC = (int (*) ()) NULL;
                    141:     pQ->CopyGCSource = (void (*) ()) NULL;
                    142:     pQ->CopyGCDest = cfbCopyGCDest;
                    143:     pQ->DestroyGC = cfbDestroyGC;
                    144:     return TRUE;
                    145: }
                    146: 
                    147: void
                    148: cfbDestroyGC(pGC, pQ)
                    149:     GC                         *pGC;
                    150:     GCInterestPtr      pQ;
                    151: 
                    152: {
                    153:     cfbPrivGC *pPriv;
                    154: 
                    155:     switch (pGC->depth) {
                    156:     case 1:
                    157:        mfbDestroyGC(pGC, pQ);
                    158:        return;
                    159:     case PSZ:
                    160:        break;
                    161:     default:
                    162:        ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth);
                    163:        return;
                    164:     }
                    165:     /* Most GCInterest pointers would free pQ->devPriv.  This one is privileged
                    166:      * and allowed to allocate its private data directly in the GC (this
                    167:      * saves an indirection).  We must also unlink and free the pQ.
                    168:      */
                    169:     pQ->pLastGCInterest->pNextGCInterest = pGC->pNextGCInterest;
                    170:     pQ->pNextGCInterest->pLastGCInterest = pGC->pLastGCInterest;
                    171: 
                    172:     pPriv = (cfbPrivGC *)(pGC->devPriv);
                    173:     if (pPriv->pRotatedTile)
                    174:        cfbDestroyPixmap(pPriv->pRotatedTile);
                    175:     if (pPriv->pRotatedStipple)
                    176:        cfbDestroyPixmap(pPriv->pRotatedStipple);
                    177:     if (pPriv->freeCompClip == FREE_CC && pPriv->pCompositeClip)
                    178:        (*pGC->pScreen->RegionDestroy)(pPriv->pCompositeClip);
                    179:     if(pPriv->pAbsClientRegion)
                    180:        (*pGC->pScreen->RegionDestroy)(pPriv->pAbsClientRegion);
                    181:     Xfree(pGC->devPriv);
                    182:     Xfree(pQ);
                    183: }
                    184: 
                    185: #define WINMOVED(pWin, pGC) \
                    186: ((pWin->absCorner.x != pGC->lastWinOrg.x) || \
                    187:  (pWin->absCorner.y != pGC->lastWinOrg.y))
                    188: 
                    189: /* Clipping conventions
                    190:        if the drawable is a window
                    191:            CT_REGION ==> pCompositeClip really is the composite
                    192:            CT_other ==> pCompositeClip is the window clip region
                    193:        if the drawable is a pixmap
                    194:            CT_REGION ==> pCompositeClip is the translated client region
                    195:                clipped to the pixmap boundary
                    196:            CT_other ==> pCompositeClip is the pixmap bounding box
                    197: */
                    198: 
                    199: void
                    200: cfbValidateGC(pGC, pQ, changes, pDrawable)
                    201:     register GC *pGC;
                    202:     GCInterestPtr      *pQ;
                    203:     Mask changes;
                    204:     DrawablePtr pDrawable;
                    205: {
                    206:     WindowPtr   pWin;
                    207:     int         mask;          /* stateChanges */
                    208:     int         index;         /* used for stepping through bitfields */
                    209:     int         xrot, yrot;    /* rotations for tile and stipple pattern */
                    210:     Bool        fRotate = FALSE;/* True if rotated pixmaps are needed */
                    211:     int         new_line, new_text, new_fillspans;
                    212:     /* flags for changing the proc vector */
                    213:     cfbPrivGCPtr devPriv;
                    214: 
                    215:     switch (pGC->depth) {
                    216:     case PSZ:
                    217:        break;
                    218:     case 1:
                    219:        if (pDrawable->type == DRAWABLE_PIXMAP) {
                    220:            mfbValidateGC(pGC, pQ, changes, pDrawable);
                    221:            return;
                    222:        }
                    223:        /* WARNING - FALL THROUGH */
                    224:     default:
                    225:        ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth);
                    226:        return;
                    227:     }
                    228:     if (pDrawable->type == DRAWABLE_WINDOW)
                    229:        pWin = (WindowPtr) pDrawable;
                    230:     else
                    231:        pWin = (WindowPtr) NULL;
                    232: 
                    233:     devPriv = ((cfbPrivGCPtr) (pGC->devPriv));
                    234: 
                    235:     /*
                    236:      * if the client clip is different or moved OR the subwindowMode has
                    237:      * changed OR the window's clip has changed since the last validation
                    238:      * we need to recompute the composite clip 
                    239:      */
                    240: 
                    241:     if ((changes & (GCClipXOrigin | GCClipYOrigin | GCClipMask)) ||
                    242:        (changes & GCSubwindowMode) ||
                    243:        (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
                    244:        ) {
                    245: 
                    246:        /*
                    247:         * if there is a client clip (always a region, for us) AND it has
                    248:         * moved or is different OR the window has moved we need to
                    249:         * (re)translate it. 
                    250:         */
                    251:        if ((pGC->clientClipType == CT_REGION) &&
                    252:            ((changes & (GCClipXOrigin | GCClipYOrigin | GCClipMask)) ||
                    253:             (pWin && WINMOVED(pWin, pGC))
                    254:             )
                    255:            ) {
                    256:            /* retranslate client clip */
                    257:            (*pGC->pScreen->RegionCopy) (devPriv->pAbsClientRegion,
                    258:                                         pGC->clientClip);
                    259: 
                    260:            if (pWin) {
                    261:                pGC->lastWinOrg.x = pWin->absCorner.x;
                    262:                pGC->lastWinOrg.y = pWin->absCorner.y;
                    263:                (*pGC->pScreen->TranslateRegion) (
                    264:                                               devPriv->pAbsClientRegion,
                    265:                                      pGC->lastWinOrg.x + pGC->clipOrg.x,
                    266:                                     pGC->lastWinOrg.y + pGC->clipOrg.y);
                    267:            }
                    268:            else {
                    269:                pGC->lastWinOrg.x = 0;
                    270:                pGC->lastWinOrg.y = 0;
                    271:                (*pGC->pScreen->TranslateRegion) (
                    272:                                                  devPriv->pAbsClientRegion, pGC->clipOrg.x, pGC->clipOrg.y);
                    273:            }
                    274:        }
                    275: 
                    276:        if (pWin) {
                    277:            RegionPtr   pregWin;
                    278:            int         freeTmpClip, freeCompClip;
                    279: 
                    280:            if (pGC->subWindowMode == IncludeInferiors) {
                    281:                pregWin = NotClippedByChildren(pWin);
                    282:                freeTmpClip = FREE_CC;
                    283:            }
                    284:            else {
                    285:                pregWin = pWin->clipList;
                    286:                freeTmpClip = REPLACE_CC;
                    287:            }
                    288:            freeCompClip = devPriv->freeCompClip;
                    289: 
                    290:            /*
                    291:             * if there is no client clip, we can get by with just keeping
                    292:             * the pointer we got, and remembering whether or not should
                    293:             * destroy (or maybe re-use) it later.  this way, we avoid
                    294:             * unnecessary copying of regions.  (this wins especially if
                    295:             * many clients clip by children and have no client clip.) 
                    296:             */
                    297:            if (pGC->clientClipType == CT_NONE) {
                    298:                if (freeCompClip == FREE_CC) {
                    299:                    (*pGC->pScreen->RegionDestroy) (devPriv->pCompositeClip);
                    300:                }
                    301:                devPriv->pCompositeClip = pregWin;
                    302:                devPriv->freeCompClip = freeTmpClip;
                    303:            }
                    304:            else {
                    305:                /*
                    306:                 * we need one 'real' region to put into the composite
                    307:                 * clip. if pregWin the current composite clip are real,
                    308:                 * we can get rid of one. if pregWin is real and the
                    309:                 * current composite clip isn't, use pregWin for the
                    310:                 * composite clip. if the current composite clip is real
                    311:                 * and pregWin isn't, use the current composite clip. if
                    312:                 * neither is real, create a new region. 
                    313:                 */
                    314: 
                    315:                if ((freeTmpClip == FREE_CC) && (freeCompClip == FREE_CC)) {
                    316:                    (*pGC->pScreen->Intersect) (
                    317:                                                devPriv->pCompositeClip,
                    318:                                                pregWin,
                    319:                                              devPriv->pAbsClientRegion);
                    320:                    (*pGC->pScreen->RegionDestroy) (pregWin);
                    321:                }
                    322:                else if ((freeTmpClip == REPLACE_CC) &&
                    323:                         (freeCompClip == FREE_CC)) {
                    324:                    devPriv->pCompositeClip = pregWin;
                    325:                    (*pGC->pScreen->Intersect) (
                    326:                                                devPriv->pCompositeClip,
                    327:                                                devPriv->pCompositeClip,
                    328:                                              devPriv->pAbsClientRegion);
                    329:                }
                    330:                else if ((freeTmpClip == FREE_CC) &&
                    331:                         (freeCompClip == REPLACE_CC)) {
                    332:                    (*pGC->pScreen->Intersect) (
                    333:                                                devPriv->pCompositeClip,
                    334:                                                pregWin,
                    335:                                              devPriv->pAbsClientRegion);
                    336:                }
                    337:                else if ((freeTmpClip == REPLACE_CC) &&
                    338:                         (freeCompClip == REPLACE_CC)) {
                    339:                    devPriv->pCompositeClip =
                    340:                        (*pGC->pScreen->RegionCreate) (NULL, 1);
                    341:                    (*pGC->pScreen->Intersect) (
                    342:                                                devPriv->pCompositeClip,
                    343:                                                pregWin,
                    344:                                              devPriv->pAbsClientRegion);
                    345:                }
                    346:            }
                    347:        }                       /* end of composite clip for a window */
                    348:        else {
                    349:            BoxRec      pixbounds;
                    350: 
                    351:            pixbounds.x1 = 0;
                    352:            pixbounds.y1 = 0;
                    353:            pixbounds.x2 = ((PixmapPtr) pDrawable)->width;
                    354:            pixbounds.y2 = ((PixmapPtr) pDrawable)->height;
                    355: 
                    356:            if (devPriv->freeCompClip == FREE_CC)
                    357:                (*pGC->pScreen->RegionReset) (
                    358:                                    devPriv->pCompositeClip, &pixbounds);
                    359:            else {
                    360:                devPriv->freeCompClip = FREE_CC;
                    361:                devPriv->pCompositeClip =
                    362:                    (*pGC->pScreen->RegionCreate) (&pixbounds, 1);
                    363:            }
                    364: 
                    365:            if (pGC->clientClipType == CT_REGION)
                    366:                (*pGC->pScreen->Intersect) (
                    367:                                            devPriv->pCompositeClip,
                    368:                                            devPriv->pCompositeClip,
                    369:                                            devPriv->pAbsClientRegion);
                    370:        }                       /* end of composute clip for pixmap */
                    371:     }
                    372: 
                    373:     if (pWin) {
                    374: 
                    375:        /*
                    376:         * rotate tile patterns so that pattern can be combined in word by
                    377:         * word, but the pattern seems to begin aligned with the window 
                    378:         */
                    379:        xrot = pWin->absCorner.x;
                    380:        yrot = pWin->absCorner.y;
                    381:     }
                    382:     else {
                    383:        yrot = 0;
                    384:        xrot = 0;
                    385:     }
                    386: 
                    387: 
                    388:     new_line = FALSE;
                    389:     new_text = FALSE;
                    390:     new_fillspans = FALSE;
                    391: 
                    392:     mask = changes;
                    393:     while (mask) {
                    394:        index = ffs(mask) - 1;
                    395:        mask &= ~(index = (1 << index));
                    396: 
                    397:        /*
                    398:         * this switch acculmulates a list of which procedures might have
                    399:         * to change due to changes in the GC.  in some cases (e.g.
                    400:         * changing one 16 bit tile for another) we might not really need
                    401:         * a change, but the code is being paranoid. this sort of batching
                    402:         * wins if, for example, the alu and the font have been changed,
                    403:         * or any other pair of items that both change the same thing. 
                    404:         */
                    405:        switch (index) {
                    406:        case GCFunction:
                    407:        case GCForeground:
                    408:            new_text = TRUE;
                    409:            break;
                    410:        case GCPlaneMask:
                    411:            break;
                    412:        case GCBackground:
                    413:            new_fillspans = TRUE;
                    414:            break;
                    415:        case GCLineStyle:
                    416:            break;
                    417:        case GCLineWidth:
                    418:        case GCCapStyle:
                    419:        case GCJoinStyle:
                    420:            new_line = TRUE;
                    421:            break;
                    422:        case GCFillStyle:
                    423:            new_text = TRUE;
                    424:            new_fillspans = TRUE;
                    425:            new_line = TRUE;
                    426:            break;
                    427:        case GCFillRule:
                    428:            break;
                    429:        case GCTile:
                    430:            if (pGC->tile == (PixmapPtr) NULL)
                    431:                break;
                    432:            cfbPadPixmap(pGC->tile);
                    433:            fRotate = TRUE;
                    434:            new_fillspans = TRUE;
                    435:            break;
                    436: 
                    437:        case GCStipple:
                    438:            if (pGC->stipple == (PixmapPtr) NULL)
                    439:                break;
                    440:            cfbPadPixmap(pGC->stipple);
                    441:            fRotate = TRUE;
                    442:            new_fillspans = TRUE;
                    443:            break;
                    444: 
                    445:        case GCTileStipXOrigin:
                    446:            fRotate = TRUE;
                    447:            break;
                    448: 
                    449:        case GCTileStipYOrigin:
                    450:            fRotate = TRUE;
                    451:            break;
                    452: 
                    453:        case GCFont:
                    454:            new_text = TRUE;
                    455:            break;
                    456:        case GCSubwindowMode:
                    457:            break;
                    458:        case GCGraphicsExposures:
                    459:            break;
                    460:        case GCClipXOrigin:
                    461:            break;
                    462:        case GCClipYOrigin:
                    463:            break;
                    464:        case GCClipMask:
                    465:            break;
                    466:        case GCDashOffset:
                    467:            break;
                    468:        case GCDashList:
                    469:            break;
                    470:        case GCArcMode:
                    471:            break;
                    472:        default:
                    473:            break;
                    474:        }
                    475:     }
                    476: 
                    477:     /*
                    478:      * If the drawable has changed,  check its depth & ensure suitable
                    479:      * entries are in the proc vector. 
                    480:      */
                    481:     if (pDrawable->serialNumber != (pGC->serialNumber & (DRAWABLE_SERIAL_BITS))) {
                    482:        new_fillspans = TRUE;   /* deal with FillSpans later */
                    483:        pGC->SetSpans = cfbSetSpans;
                    484:     }
                    485: 
                    486:     /* deal with the changes we've collected */
                    487: 
                    488:     if (new_line) {
                    489:        if (pGC->lineWidth == 0) {
                    490: #ifdef notdef
                    491:            if (pGC->fillStyle == FillSolid)
                    492:                pGC->Polylines = miNotMiter;    /* XXX - doesn't work for
                    493:                                                 * zero. ???miNotMiter??? */
                    494:            else
                    495: #endif
                    496:                pGC->Polylines = miZeroLine;
                    497:        }
                    498:        else {
                    499:            switch (pGC->joinStyle) {
                    500:            case JoinMiter:
                    501:                pGC->LineHelper = miMiter;
                    502:                break;
                    503:            case JoinRound:
                    504:            case JoinBevel:
                    505:                pGC->LineHelper = miNotMiter;
                    506:                break;
                    507:            }
                    508:        }
                    509:     }
                    510: 
                    511:     if (new_text && pGC->font) {
                    512:        pGC->PolyGlyphBlt = miPolyGlyphBlt;
                    513:        pGC->ImageGlyphBlt = miImageGlyphBlt;
                    514:        pGC->PolyGlyphBlt = miPolyGlyphBlt;
                    515:        pGC->ImageGlyphBlt = miImageGlyphBlt;
                    516:     }
                    517: 
                    518:     if (new_fillspans) {
                    519:        switch (pGC->fillStyle) {
                    520:        case FillSolid:
                    521:            pGC->FillSpans = cfbSolidFS;
                    522:            break;
                    523:        case FillTiled:
                    524:            pGC->FillSpans = cfbUnnaturalTileFS;
                    525:            if (!pGC->tile)
                    526:                FatalError("cfbValidateGC: tile mode & no tile\n");
                    527:            if (((DrawablePtr)pGC->tile)->depth != pGC->depth)
                    528:                FatalError("cfbValidateGC: tile wrong depth\n");
                    529:            break;
                    530:        case FillStippled:
                    531:            pGC->FillSpans = cfbUnnaturalStippleFS;
                    532:            if (!pGC->stipple)
                    533:                FatalError("cfbValidateGC: stipple mode & no stipple\n");
                    534:            if (((DrawablePtr)pGC->stipple)->depth != 1)
                    535:                FatalError("cfbValidateGC: stipple wrong depth\n");
                    536:            break;
                    537:        case FillOpaqueStippled:
                    538:            if (pGC->fgPixel == pGC->bgPixel)
                    539:                pGC->FillSpans = cfbSolidFS;
                    540:            else {
                    541:                pGC->FillSpans = cfbUnnaturalStippleFS;
                    542:                if (!pGC->stipple)
                    543:                    FatalError("cfbValidateGC: stipple mode & no stipple\n");
                    544:                if (((DrawablePtr)pGC->stipple)->depth != 1)
                    545:                    FatalError("cfbValidateGC: stipple wrong depth\n");
                    546:            }
                    547:            break;
                    548:        default:
                    549:            FatalError("cfbValidateGC: illegal fillStyle\n");
                    550:        }
                    551:     } /* end of new_fillspans */
                    552: 
                    553:     if (xrot || yrot || fRotate) {
                    554:        /*
                    555:         * First destroy any previously-rotated tile/stipple
                    556:         */
                    557:        if (devPriv->pRotatedTile) {
                    558:            cfbDestroyPixmap(devPriv->pRotatedTile);
                    559:            devPriv->pRotatedTile = (PixmapPtr)NULL;
                    560:        }
                    561:        if (devPriv->pRotatedStipple) {
                    562:            cfbDestroyPixmap(devPriv->pRotatedStipple);
                    563:            devPriv->pRotatedStipple = (PixmapPtr)NULL;
                    564:        }
                    565:        if (pGC->tile &&
                    566:            (devPriv->pRotatedTile = cfbCopyPixmap(pGC->tile))
                    567:                == (PixmapPtr) NULL)
                    568:            FatalError("cfbValidateGC: cannot rotate tile\n");
                    569:        if (pGC->stipple && 
                    570:            (devPriv->pRotatedStipple = cfbCopyPixmap(pGC->stipple))
                    571:                == (PixmapPtr) NULL)
                    572:            FatalError("cfbValidateGC: cannot rotate stipple\n");
                    573:        /*
                    574:         * If we've gotten here, we're probably going to rotate the tile
                    575:         * and/or stipple, so we have to add the pattern origin into
                    576:         * the rotation factor, even if it hasn't changed.
                    577:         */
                    578:        xrot += pGC->patOrg.x;
                    579:        yrot += pGC->patOrg.y;
                    580:        if (xrot) {
                    581:            if (pGC->tile && devPriv->pRotatedTile)
                    582:                cfbXRotatePixmap(devPriv->pRotatedTile, xrot);
                    583:            if (pGC->stipple && devPriv->pRotatedStipple)
                    584:                cfbXRotatePixmap(devPriv->pRotatedStipple, xrot);
                    585:        }
                    586:        if (yrot) {
                    587:            if (pGC->tile && devPriv->pRotatedTile)
                    588:                cfbYRotatePixmap(devPriv->pRotatedTile, yrot);
                    589:            if (pGC->stipple && devPriv->pRotatedStipple)
                    590:                cfbYRotatePixmap(devPriv->pRotatedStipple, yrot);
                    591:        }
                    592:     }
                    593: }
                    594: 
                    595: 
                    596: void
                    597: cfbDestroyClip(pGC)
                    598:     GCPtr      pGC;
                    599: {
                    600:     switch (pGC->depth) {
                    601:     case 1:
                    602:        mfbDestroyClip(pGC);
                    603:        return;
                    604:     case PSZ:
                    605:        break;
                    606:     default:
                    607:        ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth);
                    608:        return;
                    609:     }
                    610:     if(pGC->clientClipType == CT_NONE)
                    611:        return;
                    612:     (*pGC->pScreen->RegionDestroy)(pGC->clientClip);
                    613:     pGC->clientClip = NULL;
                    614:     pGC->clientClipType = CT_NONE;
                    615:     pGC->stateChanges |= (GCClipXOrigin | GCClipYOrigin | GCClipMask);
                    616: }
                    617: 
                    618: void
                    619: cfbChangeClip(pGC, type, pvalue, nrects)
                    620:     GCPtr      pGC;
                    621:     int                type;
                    622:     pointer    pvalue;
                    623:     int                nrects;
                    624: {
                    625:     switch (pGC->depth) {
                    626:     case 1:
                    627:        mfbChangeClip(pGC, type, pvalue, nrects);
                    628:        return;
                    629:     case PSZ:
                    630:        break;
                    631:     default:
                    632:        ErrorF("cfbChangeClip: unsupported depth: %d\n", pGC->depth);
                    633:        return;
                    634:     }
                    635:     cfbDestroyClip(pGC);
                    636:     if(type == CT_PIXMAP)
                    637:     {
                    638:        pGC->clientClip = (pointer) mfbPixmapToRegion(pvalue);
                    639:        (*pGC->pScreen->DestroyPixmap)(pvalue);
                    640:     }
                    641:     else if (type == CT_REGION) {
                    642:        pGC->clientClip = (pointer) (*pGC->pScreen->RegionCreate)( NULL, 0 );
                    643:        (*pGC->pScreen->RegionCopy)( pGC->clientClip, pvalue );
                    644:     }
                    645:     else if (type != CT_NONE)
                    646:     {
                    647:        pGC->clientClip = (pointer) miRectsToRegion(pGC, nrects, pvalue, type);
                    648:        Xfree(pvalue);
                    649:     }
                    650:     pGC->clientClipType = (pGC->clientClip) ? CT_REGION : CT_NONE;
                    651:     pGC->stateChanges |= (GCClipXOrigin | GCClipYOrigin | GCClipMask);
                    652: }
                    653: 
                    654: void
                    655: cfbCopyClip (pgcDst, pgcSrc)
                    656:     GCPtr pgcDst, pgcSrc;
                    657: {
                    658:     RegionPtr prgnNew;
                    659: 
                    660:     switch (pgcSrc->depth) {
                    661:     case 1:
                    662:        mfbCopyClip(pgcDst, pgcSrc);
                    663:        return;
                    664:     case PSZ:
                    665:        break;
                    666:     default:
                    667:        ErrorF("cfbCopyClip: unsupported depth: %d\n", pgcSrc->depth);
                    668:        return;
                    669:     }
                    670:     switch(pgcSrc->clientClipType)
                    671:     {
                    672:       case CT_NONE:
                    673:       case CT_PIXMAP:
                    674:         cfbChangeClip(pgcDst, pgcSrc->clientClipType, pgcSrc->clientClip, 0);
                    675:         break;
                    676:       case CT_REGION:
                    677:         prgnNew = (*pgcSrc->pScreen->RegionCreate)(NULL, 1);
                    678:         (*pgcSrc->pScreen->RegionCopy)(prgnNew,
                    679:                                        (RegionPtr)(pgcSrc->clientClip));
                    680:         cfbChangeClip(pgcDst, CT_REGION, prgnNew, 0);
                    681:         break;
                    682:     }
                    683: }
                    684: 
                    685: void
                    686: cfbCopyGCDest (pGC, pQ, changes, pGCSrc)
                    687:     GCPtr      pGC;
                    688:     GCInterestPtr      pQ;
                    689:     Mask               changes;
                    690:     GCPtr              pGCSrc;
                    691: {
                    692:     RegionPtr          pClip;
                    693: 
                    694:     switch (pGC->depth) {
                    695:     case 1:
                    696:        mfbCopyGCDest(pGC);
                    697:        return;
                    698:     case PSZ:
                    699:        break;
                    700:     default:
                    701:        ErrorF("cfbCreateGC: unsupported depth: %d\n", pGC->depth);
                    702:        return;
                    703:     }
                    704:     if(changes & GCClipMask)
                    705:     {
                    706:        if(pGC->clientClipType == CT_PIXMAP)
                    707:        {
                    708:            ((PixmapPtr)pGC->clientClip)->refcnt++;
                    709:        }
                    710:        else if(pGC->clientClipType == CT_REGION)
                    711:        {
                    712:            BoxRec pixbounds;
                    713: 
                    714:            pixbounds.x1 = 0;
                    715:            pixbounds.y1 = 0;
                    716:            pixbounds.x2 = 0;
                    717:            pixbounds.y2 = 0;
                    718: 
                    719:            pClip = (RegionPtr) pGC->clientClip;
                    720:            pGC->clientClip =
                    721:                (pointer)(* pGC->pScreen->RegionCreate)(&pixbounds, 1);
                    722:            (* pGC->pScreen->RegionCopy)(pGC->clientClip, pClip);
                    723:        }
                    724:     }
                    725: }

unix.superglobalmegacorp.com

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