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

1.1       root        1: /***********************************************************
                      2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
                      3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
                      4: 
                      5:                         All Rights Reserved
                      6: 
                      7: Permission to use, copy, modify, and distribute this software and its 
                      8: documentation for any purpose and without fee is hereby granted, 
                      9: provided that the above copyright notice appear in all copies and that
                     10: both that copyright notice and this permission notice appear in 
                     11: supporting documentation, and that the names of Digital or MIT not be
                     12: used in advertising or publicity pertaining to distribution of the
                     13: software without specific, written prior permission.  
                     14: 
                     15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     21: SOFTWARE.
                     22: 
                     23: ******************************************************************/
                     24: /* $Header: 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.