Annotation of researchv9/X11/src/X.V11R1/server/ddx/mfb/mfbgc.c, revision 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: mfbgc.c,v 1.115 87/09/03 09:04:25 toddb Exp $ */
        !            25: #include "X.h"
        !            26: #include "Xmd.h"
        !            27: #include "Xproto.h"
        !            28: #include "dixfontstr.h"
        !            29: #include "fontstruct.h"
        !            30: #include "gcstruct.h"
        !            31: #include "windowstr.h"
        !            32: #include "pixmapstr.h"
        !            33: #include "scrnintstr.h"
        !            34: #include "region.h"
        !            35: 
        !            36: #include "mfb.h"
        !            37: #include "mistruct.h"
        !            38: 
        !            39: #include "maskbits.h"
        !            40: 
        !            41: static PixmapPtr BogusPixmap = (PixmapPtr)1;
        !            42: 
        !            43: Bool
        !            44: mfbCreateGC(pGC)
        !            45:     register GCPtr pGC;
        !            46: {
        !            47:     mfbPrivGC  *pPriv;
        !            48:     GCInterestPtr      pQ;
        !            49: 
        !            50:     pGC->clientClip = NULL;
        !            51:     pGC->clientClipType = CT_NONE;
        !            52:     
        !            53:     /* some of the output primitives aren't really necessary, since
        !            54:        they will be filled in ValidateGC because of dix/CreateGC()
        !            55:        setting all the change bits.  Others are necessary because although
        !            56:        they depend on being a monochrome frame buffer, they don't change 
        !            57:     */
        !            58: 
        !            59:     pGC->FillSpans = mfbWhiteSolidFS;
        !            60:     pGC->SetSpans = mfbSetSpans;
        !            61:     pGC->PutImage = mfbPutImage;
        !            62:     pGC->CopyArea = mfbCopyArea;
        !            63:     pGC->CopyPlane = mfbCopyPlane;
        !            64:     pGC->PolyPoint = mfbPolyPoint;
        !            65: 
        !            66:     pGC->Polylines = mfbLineSS;
        !            67:     pGC->PolySegment = miPolySegment;
        !            68:     pGC->PolyRectangle = miPolyRectangle;
        !            69:     pGC->PolyArc = miPolyArc;
        !            70:     pGC->FillPolygon = miFillPolygon;
        !            71:     pGC->PolyFillRect = mfbPolyFillRect;
        !            72:     pGC->PolyFillArc = miPolyFillArc;
        !            73:     pGC->PolyText8 = miPolyText8;
        !            74:     pGC->ImageText8 = miImageText8;
        !            75:     pGC->PolyText16 = miPolyText16;
        !            76:     pGC->ImageText16 = miImageText16;
        !            77:     pGC->ImageGlyphBlt = mfbImageGlyphBltWhite;
        !            78:     pGC->PolyGlyphBlt = mfbPolyGlyphBltInvert;
        !            79:     pGC->PushPixels = mfbPushPixels;
        !            80:     pGC->LineHelper = miMiter;
        !            81:     pGC->ChangeClip = mfbChangeClip;
        !            82:     pGC->DestroyClip = mfbDestroyClip;
        !            83:     pGC->CopyClip = mfbCopyClip;
        !            84: 
        !            85:     /* mfb wants to translate before scan convesion */
        !            86:     pGC->miTranslate = 1;
        !            87: 
        !            88:     pPriv = (mfbPrivGC *)Xalloc(sizeof(mfbPrivGC));
        !            89:     if (!pPriv)
        !            90:        return FALSE;
        !            91:     else
        !            92:     {
        !            93:        pPriv->rop = ReduceRop(pGC->alu, pGC->fgPixel);
        !            94:        pPriv->fExpose = TRUE;
        !            95:        pGC->devPriv = (pointer)pPriv;
        !            96:        pPriv->pRotatedTile = NullPixmap;
        !            97:        pPriv->pRotatedStipple = NullPixmap;
        !            98:        pPriv->pAbsClientRegion =(* pGC->pScreen->RegionCreate)(NULL, 1); 
        !            99: 
        !           100:        /* since freeCompClip isn't FREE_CC, we don't need to create
        !           101:           a null region -- no one will try to free the field.
        !           102:        */
        !           103:        pPriv->freeCompClip = REPLACE_CC;
        !           104:        pPriv->ppPixmap = &BogusPixmap;
        !           105:        pPriv->FillArea = mfbSolidInvertArea;
        !           106:     }
        !           107:     pQ = (GCInterestPtr) Xalloc(sizeof(GCInterestRec));
        !           108:     if(!pQ)
        !           109:     {
        !           110:        Xfree(pPriv);
        !           111:        return FALSE;
        !           112:     }
        !           113:      
        !           114:     /* Now link this device into the GCque */
        !           115:     pGC->pNextGCInterest = pQ;
        !           116:     pGC->pLastGCInterest = pQ;
        !           117:     pQ->pNextGCInterest = (GCInterestPtr) &pGC->pNextGCInterest;
        !           118:     pQ->pLastGCInterest = (GCInterestPtr) &pGC->pNextGCInterest;
        !           119:     pQ->length = sizeof(GCInterestRec);
        !           120:     pQ->owner = 0;             /* server owns this */
        !           121:     pQ->ValInterestMask = ~0;  /* interested in everything at validate time */
        !           122:     pQ->ValidateGC = mfbValidateGC;
        !           123:     pQ->ChangeInterestMask = 0; /* interested in nothing at change time */
        !           124:     pQ->ChangeGC = (int (*) () ) NULL;
        !           125:     pQ->CopyGCSource = (void (*) () ) NULL;
        !           126:     pQ->CopyGCDest = (void (*) () ) NULL;
        !           127:     pQ->DestroyGC = mfbDestroyGC;
        !           128:     return TRUE;
        !           129: }
        !           130: 
        !           131: void
        !           132: mfbDestroyGC(pGC, pQ)
        !           133:     GC                         *pGC;
        !           134:     GCInterestPtr      pQ;
        !           135: 
        !           136: {
        !           137:     mfbPrivGC *pPriv;
        !           138: 
        !           139:     /* Most GCInterest pointers would free pQ->devPriv.  This one is privileged
        !           140:      * and allowed to allocate its private data directly in the GC (this
        !           141:      * saves an indirection).  We must also unlink and free the pQ.
        !           142:      */
        !           143:     pQ->pLastGCInterest->pNextGCInterest = pQ->pNextGCInterest;
        !           144:     pQ->pNextGCInterest->pLastGCInterest = pQ->pLastGCInterest;
        !           145: 
        !           146:     pPriv = (mfbPrivGC *)(pGC->devPriv);
        !           147:     if (pPriv->pRotatedTile)
        !           148:        mfbDestroyPixmap(pPriv->pRotatedTile);
        !           149:     if (pPriv->pRotatedStipple)
        !           150:        mfbDestroyPixmap(pPriv->pRotatedStipple);
        !           151:     if (pPriv->freeCompClip == FREE_CC)
        !           152:        (*pGC->pScreen->RegionDestroy)(pPriv->pCompositeClip);
        !           153:     if(pPriv->pAbsClientRegion)
        !           154:        (*pGC->pScreen->RegionDestroy)(pPriv->pAbsClientRegion);
        !           155:     Xfree(pGC->devPriv);
        !           156:     Xfree(pQ);
        !           157: }
        !           158: 
        !           159: #define WINMOVED(pWin, pGC) \
        !           160: ((pWin->absCorner.x != pGC->lastWinOrg.x) || \
        !           161:  (pWin->absCorner.y != pGC->lastWinOrg.y))
        !           162: 
        !           163: /* Clipping conventions
        !           164:        if the drawable is a window
        !           165:            CT_REGION ==> pCompositeClip really is the composite
        !           166:            CT_other ==> pCompositeClip is the window clip region
        !           167:        if the drawable is a pixmap
        !           168:            CT_REGION ==> pCompositeClip is the translated client region
        !           169:                clipped to the pixmap boundary
        !           170:            CT_other ==> pCompositeClip is the pixmap bounding box
        !           171: */
        !           172: 
        !           173: void
        !           174: mfbValidateGC(pGC, pQ, changes, pDrawable)
        !           175:     register GCPtr     pGC;
        !           176:     GCInterestPtr      pQ;
        !           177:     Mask               changes;
        !           178:     DrawablePtr        pDrawable;
        !           179: {
        !           180:     register mfbPrivGCPtr      devPriv;
        !           181:     WindowPtr pWin;
        !           182:     int mask;                  /* stateChanges */
        !           183:     int index;                 /* used for stepping through bitfields */
        !           184:     int        xrot, yrot;             /* rotations for tile and stipple pattern */
        !           185:     int rrop;                  /* reduced rasterop */
        !           186:                                /* flags for changing the proc vector 
        !           187:                                   and updating things in devPriv
        !           188:                                */
        !           189:     int new_rotate, new_rrop,  new_line, new_text, new_fill;
        !           190:     DDXPointRec        oldOrg;         /* origin of thing GC was last used with */
        !           191: 
        !           192:     if (pDrawable->type == DRAWABLE_WINDOW)
        !           193:        pWin = (WindowPtr)pDrawable;
        !           194:     else
        !           195:        pWin = (WindowPtr)NULL;
        !           196: 
        !           197:     devPriv = ((mfbPrivGCPtr) (pGC->devPriv));
        !           198:     oldOrg = pGC->lastWinOrg;
        !           199:     /*
        !           200:        if the client clip is different or moved OR
        !           201:        the subwindowMode has changed OR
        !           202:        the window's clip has changed since the last validation
        !           203:        we need to recompute the composite clip
        !           204:     */
        !           205: 
        !           206:     if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask)) ||
        !           207:        (changes & GCSubwindowMode) ||
        !           208:        (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS))
        !           209:        )
        !           210:     {
        !           211: 
        !           212:         /* if there is a client clip (always a region, for us) AND
        !           213:                it has moved or is different OR
        !           214:                the window has moved
        !           215:            we need to (re)translate it.
        !           216:         */
        !           217:        if ((pGC->clientClipType == CT_REGION) &&
        !           218:            ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask)) ||
        !           219:             (pWin && WINMOVED(pWin, pGC))
        !           220:            )
        !           221:           )
        !           222:        {
        !           223:            /* retranslate client clip */
        !           224:            (* pGC->pScreen->RegionCopy)( devPriv->pAbsClientRegion, 
        !           225:                                          pGC->clientClip);
        !           226: 
        !           227:            if (pWin)
        !           228:            {
        !           229:                pGC->lastWinOrg.x = pWin->absCorner.x;
        !           230:                pGC->lastWinOrg.y = pWin->absCorner.y;
        !           231:                (* pGC->pScreen->TranslateRegion)(
        !           232:                               devPriv->pAbsClientRegion, 
        !           233:                               pGC->lastWinOrg.x + pGC->clipOrg.x,
        !           234:                               pGC->lastWinOrg.y + pGC->clipOrg.y);
        !           235:            }
        !           236:            else
        !           237:            {
        !           238:                pGC->lastWinOrg.x = 0;
        !           239:                pGC->lastWinOrg.y = 0;
        !           240:                (* pGC->pScreen->TranslateRegion)(
        !           241:                    devPriv->pAbsClientRegion, pGC->clipOrg.x, pGC->clipOrg.y);
        !           242:            }
        !           243:        }
        !           244: 
        !           245:        if (pWin)
        !           246:        {
        !           247:            int freeTmpClip, freeCompClip;
        !           248:            RegionPtr pregWin;          /* clip for this window, without
        !           249:                                           client clip */
        !           250: 
        !           251:            if (pGC->subWindowMode == IncludeInferiors)
        !           252:            {
        !           253:                pregWin = NotClippedByChildren(pWin);
        !           254:                freeTmpClip = FREE_CC;
        !           255:            }
        !           256:            else
        !           257:            {
        !           258:                pregWin = pWin->clipList;
        !           259:                freeTmpClip = REPLACE_CC;
        !           260:            }
        !           261:            freeCompClip = devPriv->freeCompClip;
        !           262: 
        !           263:            /* if there is no client clip, we can get by with
        !           264:               just keeping the pointer we got, and remembering
        !           265:               whether or not should destroy (or maybe re-use)
        !           266:               it later.  this way, we avoid unnecessary copying
        !           267:               of regions.  (this wins especially if many clients clip
        !           268:               by children and have no client clip.)
        !           269:            */
        !           270:            if (pGC->clientClipType == CT_NONE)
        !           271:            {
        !           272:                if(freeCompClip == FREE_CC) 
        !           273:                {
        !           274:                    (* pGC->pScreen->RegionDestroy) (devPriv->pCompositeClip);
        !           275:                }
        !           276:                devPriv->pCompositeClip = pregWin;
        !           277:                devPriv->freeCompClip = freeTmpClip;
        !           278:            }
        !           279:            else
        !           280:            {
        !           281:                /* we need one 'real' region to put into the composite
        !           282:                   clip.
        !           283:                        if pregWin and the current composite clip 
        !           284:                   are real, we can get rid of one.
        !           285:                        if the current composite clip is real and
        !           286:                   pregWin isn't, intersect the client clip and
        !           287:                   pregWin into the existing composite clip.
        !           288:                        if pregWin is real and the current composite
        !           289:                   clip isn't, intersect pregWin with the client clip
        !           290:                   and replace the composite clip with it.
        !           291:                        if neither is real, create a new region and
        !           292:                   do the intersection into it.
        !           293:                */
        !           294: 
        !           295:                if ((freeTmpClip == FREE_CC) && (freeCompClip == FREE_CC))
        !           296:                {
        !           297:                    (* pGC->pScreen->Intersect)(
        !           298:                        devPriv->pCompositeClip,
        !           299:                        pregWin,
        !           300:                        devPriv->pAbsClientRegion);
        !           301:                    (* pGC->pScreen->RegionDestroy)(pregWin);
        !           302:                }
        !           303:                else if ((freeTmpClip == REPLACE_CC) && 
        !           304:                        (freeCompClip == FREE_CC))
        !           305:                {
        !           306:                    (* pGC->pScreen->Intersect)(
        !           307:                        devPriv->pCompositeClip,
        !           308:                        pregWin,
        !           309:                        devPriv->pAbsClientRegion);
        !           310:                }
        !           311:                else if ((freeTmpClip == FREE_CC) &&
        !           312:                         (freeCompClip == REPLACE_CC))
        !           313:                {
        !           314:                    (* pGC->pScreen->Intersect)( 
        !           315:                       pregWin,
        !           316:                       pregWin,
        !           317:                       devPriv->pAbsClientRegion);
        !           318:                    devPriv->pCompositeClip = pregWin;
        !           319:                }
        !           320:                else if ((freeTmpClip == REPLACE_CC) &&
        !           321:                         (freeCompClip == REPLACE_CC))
        !           322:                {
        !           323:                    devPriv->pCompositeClip = 
        !           324:                        (* pGC->pScreen->RegionCreate)(NULL, 1);
        !           325:                    (* pGC->pScreen->Intersect)(
        !           326:                        devPriv->pCompositeClip,
        !           327:                        pregWin,
        !           328:                        devPriv->pAbsClientRegion);
        !           329:                }
        !           330:                devPriv->freeCompClip = FREE_CC;
        !           331:            }
        !           332:        } /* end of composite clip for a window */
        !           333:        else
        !           334:        {
        !           335:            BoxRec pixbounds;
        !           336: 
        !           337:            pixbounds.x1 = 0;
        !           338:            pixbounds.y1 = 0;
        !           339:            pixbounds.x2 = ((PixmapPtr)pDrawable)->width;
        !           340:            pixbounds.y2 = ((PixmapPtr)pDrawable)->height;
        !           341: 
        !           342:            if (devPriv->freeCompClip == FREE_CC)
        !           343:                (* pGC->pScreen->RegionReset)(
        !           344:                    devPriv->pCompositeClip, &pixbounds);
        !           345:            else
        !           346:            {
        !           347:                devPriv->freeCompClip = FREE_CC;
        !           348:                devPriv->pCompositeClip = 
        !           349:                        (* pGC->pScreen->RegionCreate)(&pixbounds, 1);
        !           350:            }
        !           351: 
        !           352:            if (pGC->clientClipType == CT_REGION)
        !           353:                (* pGC->pScreen->Intersect)(
        !           354:                   devPriv->pCompositeClip, 
        !           355:                   devPriv->pCompositeClip,
        !           356:                   devPriv->pAbsClientRegion);
        !           357:        } /* end of composite clip for pixmap */
        !           358:     }
        !           359: 
        !           360:     /* we need to re-rotate the tile if the previous window/pixmap
        !           361:        origin (oldOrg) differs from the new window/pixmap origin
        !           362:        (pGC->lastWinOrg)
        !           363:     */
        !           364:     if ((oldOrg.x != pGC->lastWinOrg.x) ||
        !           365:        (oldOrg.y != pGC->lastWinOrg.y))
        !           366:     {
        !           367:        new_rotate = TRUE;
        !           368:     }
        !           369:     else
        !           370:     {
        !           371:        new_rotate = FALSE;
        !           372:     }
        !           373: 
        !           374:     new_rrop = FALSE;
        !           375:     new_line = FALSE;
        !           376:     new_text = FALSE;
        !           377:     new_fill = FALSE;
        !           378: 
        !           379:     mask = changes;
        !           380:     while (mask)
        !           381:     {
        !           382:        index = ffs(mask) - 1;
        !           383:        mask &= ~(index = (1 << index));
        !           384: 
        !           385:        /* this switch acculmulates a list of which procedures
        !           386:           might have to change due to changes in the GC.  in
        !           387:           some cases (e.g. changing one 16 bit tile for another)
        !           388:           we might not really need a change, but the code is
        !           389:           being paranoid.
        !           390:           this sort of batching wins if, for example, the alu
        !           391:           and the font have been changed, or any other pair
        !           392:           of items that both change the same thing.
        !           393:        */
        !           394:        switch (index)
        !           395:        {
        !           396:          case GCFunction:
        !           397:          case GCForeground:
        !           398:            new_rrop = TRUE;
        !           399:            break;
        !           400:          case GCPlaneMask:
        !           401:            break;
        !           402:          case GCBackground:
        !           403:            new_rrop = TRUE;    /* for opaque stipples */
        !           404:            break;
        !           405:          case GCLineStyle:
        !           406:            new_line = TRUE;
        !           407:            break;
        !           408:          case GCLineWidth:
        !           409:          case GCCapStyle:
        !           410:          case GCJoinStyle:
        !           411:            new_line = TRUE;
        !           412:            break;
        !           413:          case GCFillStyle:
        !           414:            new_fill = TRUE;
        !           415:            break;
        !           416:          case GCFillRule:
        !           417:            break;
        !           418:          case GCTile:
        !           419:            if(pGC->tile == (PixmapPtr)NULL)
        !           420:                break;
        !           421:            mfbPadPixmap(pGC->tile);
        !           422:            new_rotate = TRUE;
        !           423:            new_fill = TRUE;
        !           424:            break;
        !           425: 
        !           426:          case GCStipple:
        !           427:            if(pGC->stipple == (PixmapPtr)NULL)
        !           428:                break;
        !           429:            mfbPadPixmap(pGC->stipple);
        !           430:            new_rotate = TRUE;
        !           431:            new_fill = TRUE;
        !           432:            break;
        !           433: 
        !           434:          case GCTileStipXOrigin:
        !           435:            new_rotate = TRUE;
        !           436:            break;
        !           437: 
        !           438:          case GCTileStipYOrigin:
        !           439:            new_rotate = TRUE;
        !           440:            break;
        !           441: 
        !           442:          case GCFont:
        !           443:            new_text = TRUE;
        !           444:            break;
        !           445:          case GCSubwindowMode:
        !           446:            break;
        !           447:          case GCGraphicsExposures:
        !           448:            break;
        !           449:          case GCClipXOrigin:
        !           450:            break;
        !           451:          case GCClipYOrigin:
        !           452:            break;
        !           453:          case GCClipMask:
        !           454:            break;
        !           455:          case GCDashOffset:
        !           456:            break;
        !           457:          case GCDashList:
        !           458:            break;
        !           459:          case GCArcMode:
        !           460:            break;
        !           461:          default:
        !           462:            break;
        !           463:        }
        !           464:     }
        !           465: 
        !           466:     /* deal with the changes we've collected .
        !           467:        new_rrop must be done first because subsequent things
        !           468:        depend on it.
        !           469:     */
        !           470:     if (new_rrop || new_fill)
        !           471:     {
        !           472:        rrop = ReduceRop(pGC->alu, pGC->fgPixel);
        !           473:        devPriv->rop = rrop;
        !           474:        new_fill = TRUE;
        !           475:        /* FillArea raster op is GC's for tile filling,
        !           476:           and the reduced rop for solid and stipple
        !           477:        */
        !           478:        if (pGC->fillStyle == FillTiled)
        !           479:            devPriv->ropFillArea = pGC->alu;
        !           480:        else
        !           481:            devPriv->ropFillArea = rrop;
        !           482: 
        !           483:        /* opaque stipples:
        !           484:           fg   bg      ropOpStip       fill style
        !           485:           1    0       alu             tile
        !           486:           0    1       inverseAlu      tile
        !           487:           1    1       rrop(fg, alu)   solid
        !           488:           0    0       rrop(fg, alu)   solid
        !           489:        Note that rrop(fg, alu) == mfbPrivGC.rop, so we don't really need to
        !           490:        compute it.
        !           491:        */
        !           492:         if (pGC->fillStyle == FillOpaqueStippled)
        !           493:         {
        !           494:            if (pGC->fgPixel != pGC->bgPixel)
        !           495:            {
        !           496:                if (pGC->fgPixel)
        !           497:                    devPriv->ropOpStip = pGC->alu;
        !           498:                else
        !           499:                    devPriv->ropOpStip = InverseAlu[pGC->alu];
        !           500:            }
        !           501:            else
        !           502:                devPriv->ropOpStip = rrop;
        !           503:            devPriv->ropFillArea = devPriv->ropOpStip;
        !           504:         }
        !           505:     }
        !           506:     else
        !           507:        rrop = devPriv->rop;
        !           508: 
        !           509:     if (new_line || new_fill)
        !           510:     {
        !           511:        if (pGC->lineStyle == LineSolid)
        !           512:        {
        !           513:            if(pGC->lineWidth == 0)
        !           514:            {
        !           515:                if (pGC->fillStyle == FillSolid)
        !           516:                    pGC->Polylines = mfbLineSS;
        !           517:                else
        !           518:                    pGC->Polylines = miZeroLine;
        !           519:            }
        !           520:            else
        !           521:            {
        !           522:                pGC->Polylines = miWideLine;
        !           523:            }
        !           524:        }
        !           525:        else
        !           526:            if(pGC->lineWidth == 0)
        !           527:                pGC->Polylines = mfbDashLine;
        !           528:            else
        !           529:                pGC->Polylines = miWideDash;
        !           530: 
        !           531:        switch(pGC->joinStyle)
        !           532:        {
        !           533:          case JoinMiter:
        !           534:            pGC->LineHelper = miMiter;
        !           535:            break;
        !           536:          case JoinRound:
        !           537:          case JoinBevel:
        !           538:            pGC->LineHelper = miNotMiter;
        !           539:            break;
        !           540:        }
        !           541:     }
        !           542: 
        !           543:     if (new_text || new_fill)
        !           544:     {
        !           545:        if ((pGC->font) &&
        !           546:            (pGC->font->pFI->maxbounds.metrics.rightSideBearing -
        !           547:             pGC->font->pFI->maxbounds.metrics.leftSideBearing) > 32)
        !           548:        {
        !           549:            pGC->PolyGlyphBlt = miPolyGlyphBlt;
        !           550:            pGC->ImageGlyphBlt = miImageGlyphBlt;
        !           551:        }
        !           552:        else
        !           553:        {
        !           554:            /* special case ImageGlyphBlt for terminal emulator fonts */
        !           555:            if ((pGC->font) &&
        !           556:                (pGC->font->pFI->terminalFont) &&
        !           557:                (pGC->fgPixel != pGC->bgPixel))
        !           558:            {
        !           559:                /* pcc bug makes this not compile...
        !           560:                pGC->ImageGlyphBlt = (pGC->fgPixel) ? mfbTEGlyphBltWhite :
        !           561:                                                      mfbTEGlyphBltBlack;
        !           562:                */
        !           563:                if (pGC->fgPixel)
        !           564:                    pGC->ImageGlyphBlt = mfbTEGlyphBltWhite;
        !           565:                else
        !           566:                    pGC->ImageGlyphBlt = mfbTEGlyphBltBlack;
        !           567:            }
        !           568:            else
        !           569:            {
        !           570:                if (pGC->fgPixel == 0)
        !           571:                    pGC->ImageGlyphBlt = mfbImageGlyphBltBlack;
        !           572:                else
        !           573:                    pGC->ImageGlyphBlt = mfbImageGlyphBltWhite;
        !           574:            }
        !           575: 
        !           576:            /* now do PolyGlyphBlt */
        !           577:            if (pGC->fillStyle == FillSolid ||
        !           578:                (pGC->fillStyle == FillOpaqueStippled &&
        !           579:                 pGC->fgPixel == pGC->bgPixel
        !           580:                )
        !           581:               )
        !           582:            {
        !           583:                if (rrop == RROP_WHITE)
        !           584:                    pGC->PolyGlyphBlt = mfbPolyGlyphBltWhite;
        !           585:                else if (rrop == RROP_BLACK)
        !           586:                    pGC->PolyGlyphBlt = mfbPolyGlyphBltBlack;
        !           587:                else if (rrop == RROP_INVERT)
        !           588:                    pGC->PolyGlyphBlt = mfbPolyGlyphBltInvert;
        !           589:                else
        !           590:                    pGC->PolyGlyphBlt = NoopDDA;
        !           591:            }
        !           592:            else
        !           593:            {
        !           594:                pGC->PolyGlyphBlt = miPolyGlyphBlt;
        !           595:            }
        !           596:        }
        !           597:     }
        !           598: 
        !           599:     if (new_fill)
        !           600:     {
        !           601:        /* install a suitable fillspans */
        !           602:        if ((pGC->fillStyle == FillSolid) ||
        !           603:            (pGC->fillStyle == FillOpaqueStippled && pGC->fgPixel==pGC->bgPixel)
        !           604:           )
        !           605:        {
        !           606:            switch(devPriv->rop)
        !           607:            {
        !           608:              case RROP_WHITE:
        !           609:                pGC->FillSpans = mfbWhiteSolidFS;
        !           610:                break;
        !           611:              case RROP_BLACK:
        !           612:                pGC->FillSpans = mfbBlackSolidFS;
        !           613:                break;
        !           614:              case RROP_INVERT:
        !           615:                pGC->FillSpans = mfbInvertSolidFS;
        !           616:                break;
        !           617:              case RROP_NOP:
        !           618:                pGC->FillSpans = NoopDDA;
        !           619:                break;
        !           620:            }
        !           621:        }
        !           622:        /* beyond this point, opaqueStippled ==> fg != bg */
        !           623:        else if ((pGC->fillStyle==FillTiled && pGC->tile->width!=32) ||
        !           624:                 (pGC->fillStyle==FillOpaqueStippled && pGC->stipple->width!=32)
        !           625:                )
        !           626:        {
        !           627:            pGC->FillSpans = mfbUnnaturalTileFS;
        !           628:        }
        !           629:        else if (pGC->fillStyle == FillStippled && pGC->stipple->width != 32)
        !           630:        {
        !           631:            pGC->FillSpans = mfbUnnaturalStippleFS;
        !           632:        }
        !           633:        else if (pGC->fillStyle == FillStippled)
        !           634:        {
        !           635:            switch(devPriv->rop)
        !           636:            {
        !           637:              case RROP_WHITE:
        !           638:                pGC->FillSpans = mfbWhiteStippleFS;
        !           639:                break;
        !           640:              case RROP_BLACK:
        !           641:                pGC->FillSpans = mfbBlackStippleFS;
        !           642:                break;
        !           643:              case RROP_INVERT:
        !           644:                pGC->FillSpans = mfbInvertStippleFS;
        !           645:                break;
        !           646:              case RROP_NOP:
        !           647:                pGC->FillSpans = NoopDDA;
        !           648:                break;
        !           649:            }
        !           650:        }
        !           651:        else /* overload tiles to do parti-colored opaque stipples */
        !           652:        {
        !           653:            pGC->FillSpans = mfbTileFS;
        !           654:        }
        !           655: 
        !           656:        /* the rectangle code doesn't deal with opaque stipples that
        !           657:           are two colors -- we can fool it for fg==bg, though
        !           658:         */
        !           659:        if (((pGC->fillStyle == FillTiled) && (pGC->tile->width!=32)) ||
        !           660:            ((pGC->fillStyle == FillStippled) && (pGC->stipple->width!=32)) ||
        !           661:            ((pGC->fillStyle == FillOpaqueStippled) &&
        !           662:             (pGC->fgPixel != pGC->bgPixel))
        !           663:           )
        !           664:        {
        !           665:            pGC->PolyFillRect = miPolyFillRect;
        !           666:            devPriv->ppPixmap = &BogusPixmap;
        !           667:        }
        !           668:        else /* deal with solids and natural stipples and tiles */
        !           669:        {
        !           670:            pGC->PolyFillRect = mfbPolyFillRect;
        !           671: 
        !           672:            if ((pGC->fillStyle == FillSolid) ||
        !           673:                (pGC->fillStyle == FillOpaqueStippled &&
        !           674:                 pGC->fgPixel == pGC->bgPixel)
        !           675:               )
        !           676:            {
        !           677:                devPriv->ppPixmap = &BogusPixmap;
        !           678:                switch(devPriv->rop)
        !           679:                {
        !           680:                  case RROP_WHITE:
        !           681:                    devPriv->FillArea = mfbSolidWhiteArea;
        !           682:                    break;
        !           683:                  case RROP_BLACK:
        !           684:                    devPriv->FillArea = mfbSolidBlackArea;
        !           685:                    break;
        !           686:                  case RROP_INVERT:
        !           687:                    devPriv->FillArea = mfbSolidInvertArea;
        !           688:                    break;
        !           689:                  case RROP_NOP:
        !           690:                    devPriv->FillArea = NoopDDA;
        !           691:                    break;
        !           692:                }
        !           693:            }
        !           694:            else if (pGC->fillStyle == FillStippled)
        !           695:            {
        !           696:                devPriv->ppPixmap = &devPriv->pRotatedStipple;
        !           697:                switch(devPriv->rop)
        !           698:                {
        !           699:                  case RROP_WHITE:
        !           700:                    devPriv->FillArea = mfbStippleWhiteArea;
        !           701:                    break;
        !           702:                  case RROP_BLACK:
        !           703:                    devPriv->FillArea = mfbStippleBlackArea;
        !           704:                    break;
        !           705:                  case RROP_INVERT:
        !           706:                    devPriv->FillArea = mfbStippleInvertArea;
        !           707:                    break;
        !           708:                  case RROP_NOP:
        !           709:                    devPriv->FillArea = NoopDDA;
        !           710:                    break;
        !           711:                }
        !           712:            }
        !           713:            else /* deal with tiles */
        !           714:            {
        !           715:                if (pGC->fillStyle == FillTiled)
        !           716:                    devPriv->ppPixmap = &devPriv->pRotatedTile;
        !           717:                else
        !           718:                    devPriv->ppPixmap = &devPriv->pRotatedStipple;
        !           719:                devPriv->FillArea = mfbTileArea32;
        !           720:            }
        !           721:        } /* end of natural rectangles */
        !           722:     } /* end of new_fill */
        !           723: 
        !           724: 
        !           725:     if(new_rotate)
        !           726:     {
        !           727:        /* figure out how much to rotate */
        !           728:         xrot = pGC->patOrg.x;
        !           729:         yrot = pGC->patOrg.y;
        !           730:        if (pWin)
        !           731:        {
        !           732:            xrot += pWin->absCorner.x;
        !           733:            yrot += pWin->absCorner.y;
        !           734:        }
        !           735: 
        !           736:        /* destroy any previously rotated tile or stipple */
        !           737:        if(devPriv->pRotatedTile)
        !           738:        {
        !           739:            mfbDestroyPixmap(devPriv->pRotatedTile);
        !           740:            devPriv->pRotatedTile = (PixmapPtr)NULL;
        !           741:        }
        !           742:        if(devPriv->pRotatedStipple)
        !           743:        {
        !           744:            mfbDestroyPixmap(devPriv->pRotatedStipple);
        !           745:            devPriv->pRotatedStipple = (PixmapPtr)NULL;
        !           746:        }
        !           747: 
        !           748:        /* copy current tile and stipple */
        !           749:         if(pGC->tile &&
        !           750:           (pGC->tile->width == 32) &&
        !           751:           (devPriv->pRotatedTile = mfbCopyPixmap(pGC->tile)) ==
        !           752:               (PixmapPtr)NULL)
        !           753:            return ;           /* shouldn't happen, internal error */
        !           754:         if(pGC->stipple &&
        !           755:           (pGC->stipple->width == 32) &&
        !           756:           (devPriv->pRotatedStipple = mfbCopyPixmap(pGC->stipple)) ==
        !           757:               (PixmapPtr)NULL)
        !           758:            return ;          /* shouldn't happen, internal error */
        !           759: 
        !           760:         if(xrot)
        !           761:         {
        !           762:            if (pGC->tile && pGC->tile->width == 32 && 
        !           763:                devPriv->pRotatedTile)
        !           764:                mfbXRotatePixmap(devPriv->pRotatedTile, xrot); 
        !           765:            if (pGC->stipple && pGC->stipple->width == 32 && 
        !           766:                devPriv->pRotatedStipple)
        !           767:                mfbXRotatePixmap(devPriv->pRotatedStipple, xrot); 
        !           768:         }
        !           769:         if(yrot)
        !           770:         {
        !           771:            if (pGC->tile && pGC->tile->width == 32 && 
        !           772:                devPriv->pRotatedTile)
        !           773:                mfbYRotatePixmap(devPriv->pRotatedTile, yrot); 
        !           774:            if (pGC->tile && pGC->tile->width == 32 && 
        !           775:                devPriv->pRotatedStipple)
        !           776:                mfbYRotatePixmap(devPriv->pRotatedStipple, yrot); 
        !           777:         }
        !           778:     }
        !           779: 
        !           780:     return ;
        !           781: }
        !           782: 
        !           783: /* table to map alu(src, dst) to alu(~src, dst) */
        !           784: int InverseAlu[16] = {
        !           785:        GXclear,
        !           786:        GXandInverted,
        !           787:        GXnor,
        !           788:        GXcopyInverted,
        !           789:        GXand,
        !           790:        GXnoop,
        !           791:        GXequiv,
        !           792:        GXorInverted,
        !           793:        GXandReverse,
        !           794:        GXxor,
        !           795:        GXinvert,
        !           796:        GXnand,
        !           797:        GXcopy,
        !           798:        GXor,
        !           799:        GXorReverse,
        !           800:        GXset
        !           801:        };
        !           802: 
        !           803: ReduceRop(alu, src)
        !           804:     register int alu;
        !           805:     register int src;
        !           806: {
        !           807:     int rop;
        !           808:     if (src == 0)      /* src is black */
        !           809:     {
        !           810:        switch(alu)
        !           811:        {
        !           812:          case GXclear:
        !           813:            rop = RROP_BLACK;
        !           814:            break;
        !           815:          case GXand:
        !           816:            rop = RROP_BLACK;
        !           817:            break;
        !           818:          case GXandReverse:
        !           819:            rop = RROP_BLACK;
        !           820:            break;
        !           821:          case GXcopy:
        !           822:            rop = RROP_BLACK;
        !           823:            break;
        !           824:          case GXandInverted:
        !           825:            rop = RROP_NOP;
        !           826:            break;
        !           827:          case GXnoop:
        !           828:            rop = RROP_NOP;
        !           829:            break;
        !           830:          case GXxor:
        !           831:            rop = RROP_NOP;
        !           832:            break;
        !           833:          case GXor:
        !           834:            rop = RROP_NOP;
        !           835:            break;
        !           836:          case GXnor:
        !           837:            rop = RROP_INVERT;
        !           838:            break;
        !           839:          case GXequiv:
        !           840:            rop = RROP_INVERT;
        !           841:            break;
        !           842:          case GXinvert:
        !           843:            rop = RROP_INVERT;
        !           844:            break;
        !           845:          case GXorReverse:
        !           846:            rop = RROP_INVERT;
        !           847:            break;
        !           848:          case GXcopyInverted:
        !           849:            rop = RROP_WHITE;
        !           850:            break;
        !           851:          case GXorInverted:
        !           852:            rop = RROP_WHITE;
        !           853:            break;
        !           854:          case GXnand:
        !           855:            rop = RROP_WHITE;
        !           856:            break;
        !           857:          case GXset:
        !           858:            rop = RROP_WHITE;
        !           859:            break;
        !           860:        }
        !           861:     }
        !           862:     else /* src is white */
        !           863:     {
        !           864:        switch(alu)
        !           865:        {
        !           866:          case GXclear:
        !           867:            rop = RROP_BLACK;
        !           868:            break;
        !           869:          case GXand:
        !           870:            rop = RROP_NOP;
        !           871:            break;
        !           872:          case GXandReverse:
        !           873:            rop = RROP_INVERT;
        !           874:            break;
        !           875:          case GXcopy:
        !           876:            rop = RROP_WHITE;
        !           877:            break;
        !           878:          case GXandInverted:
        !           879:            rop = RROP_BLACK;
        !           880:            break;
        !           881:          case GXnoop:
        !           882:            rop = RROP_NOP;
        !           883:            break;
        !           884:          case GXxor:
        !           885:            rop = RROP_INVERT;
        !           886:            break;
        !           887:          case GXor:
        !           888:            rop = RROP_WHITE;
        !           889:            break;
        !           890:          case GXnor:
        !           891:            rop = RROP_BLACK;
        !           892:            break;
        !           893:          case GXequiv:
        !           894:            rop = RROP_NOP;
        !           895:            break;
        !           896:          case GXinvert:
        !           897:            rop = RROP_INVERT;
        !           898:            break;
        !           899:          case GXorReverse:
        !           900:            rop = RROP_WHITE;
        !           901:            break;
        !           902:          case GXcopyInverted:
        !           903:            rop = RROP_BLACK;
        !           904:            break;
        !           905:          case GXorInverted:
        !           906:            rop = RROP_NOP;
        !           907:            break;
        !           908:          case GXnand:
        !           909:            rop = RROP_INVERT;
        !           910:            break;
        !           911:          case GXset:
        !           912:            rop = RROP_WHITE;
        !           913:            break;
        !           914:        }
        !           915:     }
        !           916:     return rop;
        !           917: }
        !           918: 
        !           919: void
        !           920: mfbDestroyClip(pGC)
        !           921:     GCPtr      pGC;
        !           922: {
        !           923:     if(pGC->clientClipType == CT_NONE)
        !           924:        return;
        !           925:     else if (pGC->clientClipType == CT_PIXMAP)
        !           926:     {
        !           927:        mfbDestroyPixmap((PixmapPtr)(pGC->clientClip));
        !           928:     }
        !           929:     else
        !           930:     {
        !           931:        /* we know we'll never have a list of rectangles, since
        !           932:           ChangeClip immediately turns them into a region 
        !           933:        */
        !           934:         (*pGC->pScreen->RegionDestroy)(pGC->clientClip);
        !           935:     }
        !           936:     pGC->clientClip = NULL;
        !           937:     pGC->clientClipType = CT_NONE;
        !           938: }
        !           939: 
        !           940: void
        !           941: mfbChangeClip(pGC, type, pvalue, nrects)
        !           942:     GCPtr      pGC;
        !           943:     int                type;
        !           944:     pointer    pvalue;
        !           945:     int                nrects;
        !           946: {
        !           947:     /*
        !           948:        remember to bump the pixmap's refcnt before destroying the old
        !           949:        one, since the two may be the same.
        !           950:        regions that have been fed to the clip code are assumed to have
        !           951:        disappeared, so we'll never see the same one twice.
        !           952:     */
        !           953: 
        !           954:     if (type == CT_PIXMAP)
        !           955:     {
        !           956:        /* so we can call destroy later, and leave this as
        !           957:           an example
        !           958:        */
        !           959:        ((PixmapPtr)(pvalue))->refcnt++;
        !           960:     }
        !           961: 
        !           962:     mfbDestroyClip(pGC);
        !           963:     if(type == CT_PIXMAP)
        !           964:     {
        !           965:        /* convert the pixmap to a region */
        !           966:        pGC->clientClip = (pointer) mfbPixmapToRegion(pvalue);
        !           967:        /* you wouldn't do this if you were leaving the pixmap in
        !           968:           rather than converting it.
        !           969:        */
        !           970:        (*pGC->pScreen->DestroyPixmap)(pvalue);
        !           971:     }
        !           972:     else if (type == CT_REGION)
        !           973:     {
        !           974:        /* stuff the region in the GC */
        !           975:        pGC->clientClip = pvalue;
        !           976:     }
        !           977:     else if (type != CT_NONE)
        !           978:     {
        !           979:        pGC->clientClip = (pointer) miRectsToRegion(pGC, nrects, pvalue, type);
        !           980:        Xfree(pvalue);
        !           981:     }
        !           982:     pGC->clientClipType = (type != CT_NONE && pGC->clientClip) ? CT_REGION :
        !           983:         CT_NONE;
        !           984:     pGC->stateChanges |= GCClipMask;
        !           985: }
        !           986: 
        !           987: void
        !           988: mfbCopyClip (pgcDst, pgcSrc)
        !           989:     GCPtr pgcDst, pgcSrc;
        !           990: {
        !           991:     RegionPtr prgnNew;
        !           992: 
        !           993:     switch(pgcSrc->clientClipType)
        !           994:     {
        !           995:       case CT_NONE:
        !           996:       case CT_PIXMAP:
        !           997:        mfbChangeClip(pgcDst, pgcSrc->clientClipType, pgcSrc->clientClip, 0);
        !           998:        break;
        !           999:       case CT_REGION:
        !          1000:        prgnNew = (*pgcSrc->pScreen->RegionCreate)(NULL, 1);
        !          1001:        (*pgcSrc->pScreen->RegionCopy)(prgnNew,
        !          1002:                                       (RegionPtr)(pgcSrc->clientClip));
        !          1003:        mfbChangeClip(pgcDst, CT_REGION, prgnNew, 0);
        !          1004:        break;
        !          1005:     }
        !          1006: }
        !          1007: 
        !          1008: void
        !          1009: mfbCopyGCDest (pGC, pQ, changes, pGCSrc)
        !          1010:     GCPtr      pGC;
        !          1011:     GCInterestPtr      pQ;
        !          1012:     Mask               changes;
        !          1013:     GCPtr              pGCSrc;
        !          1014: {
        !          1015:     RegionPtr          pClip;
        !          1016: 
        !          1017:     if(changes & GCClipMask)
        !          1018:     {
        !          1019:        if(pGC->clientClipType == CT_PIXMAP)
        !          1020:        {
        !          1021:            ((PixmapPtr)pGC->clientClip)->refcnt++;
        !          1022:        }
        !          1023:        else if(pGC->clientClipType == CT_REGION)
        !          1024:        {
        !          1025:            BoxRec pixbounds;
        !          1026: 
        !          1027:            pixbounds.x1 = 0;
        !          1028:            pixbounds.y1 = 0;
        !          1029:            pixbounds.x2 = 0;
        !          1030:            pixbounds.y2 = 0;
        !          1031: 
        !          1032:            pClip = (RegionPtr) pGC->clientClip;
        !          1033:            pGC->clientClip =
        !          1034:                (pointer)(* pGC->pScreen->RegionCreate)(&pixbounds, 1);
        !          1035:            (* pGC->pScreen->RegionCopy)(pGC->clientClip, pClip);
        !          1036:        }
        !          1037:     }
        !          1038: }

unix.superglobalmegacorp.com

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