Annotation of ntddk/src/video/displays/vga/stroke.c, revision 1.1

1.1     ! root        1: /******************************Module*Header*******************************\
        !             2: * Module Name: Stroke.c
        !             3: *
        !             4: * DrvStrokePath for VGA driver
        !             5: *
        !             6: * Copyright (c) 1992 Microsoft Corporation
        !             7: \**************************************************************************/
        !             8: 
        !             9: #include "driver.h"
        !            10: 
        !            11: #include "lines.h"
        !            12: 
        !            13: // External calls
        !            14: 
        !            15: VOID vSetStrips(ULONG, ULONG);
        !            16: VOID vClearStrips(ULONG);
        !            17: 
        !            18: #define MIN(A,B)    ((A) < (B) ? (A) : (B))
        !            19: 
        !            20: // Prototypes to go to the screen:
        !            21: 
        !            22: VOID vStripSolidHorizontal(STRIP*, LINESTATE*, LONG*);
        !            23: VOID vStripSolidHorizontalSet(STRIP*, LINESTATE*, LONG*);
        !            24: VOID vStripSolidVertical(STRIP*, LINESTATE*, LONG*);
        !            25: VOID vStripSolidDiagonalHorizontal(STRIP*, LINESTATE*, LONG*);
        !            26: VOID vStripSolidDiagonalVertical(STRIP*, LINESTATE*, LONG*);
        !            27: 
        !            28: VOID vStripStyledHorizontal(STRIP*, LINESTATE*, LONG*);
        !            29: VOID vStripStyledVertical(STRIP*, LINESTATE*, LONG*);
        !            30: 
        !            31: VOID vStripMaskedHorizontal(STRIP*, LINESTATE*, LONG*);
        !            32: VOID vStripMaskedVertical(STRIP*, LINESTATE*, LONG*);
        !            33: 
        !            34: PFNSTRIP gapfnStripSolidSet[] = {
        !            35: 
        !            36: // Special strip drawers for solid lines with SET style ROPs:
        !            37: 
        !            38:     vStripSolidHorizontalSet,
        !            39:     vStripSolidVertical,
        !            40:     vStripSolidDiagonalHorizontal,
        !            41:     vStripSolidDiagonalVertical
        !            42: };
        !            43: 
        !            44: PFNSTRIP gapfnStrip[] = {
        !            45: 
        !            46: // The order of these first 3 sets of strip drawers is determined by
        !            47: // the FL_STYLE_MASK bits of the line flags:
        !            48: 
        !            49:     vStripSolidHorizontal,
        !            50:     vStripSolidVertical,
        !            51:     vStripSolidDiagonalHorizontal,
        !            52:     vStripSolidDiagonalVertical,
        !            53: 
        !            54:     vStripStyledHorizontal,
        !            55:     vStripStyledVertical,
        !            56:     NULL,    // Diagonal goes here
        !            57:     NULL,    // Diagonal goes here
        !            58: 
        !            59:     vStripMaskedHorizontal,
        !            60:     vStripMaskedVertical,
        !            61:     NULL,    // Diagonal goes here
        !            62:     NULL,    // Diagonal goes here
        !            63: };
        !            64: 
        !            65: // Prototypes to go to a device-format bitmap:
        !            66: 
        !            67: VOID vBitmapSolidHorizontal(STRIP*, LINESTATE*, LONG*);
        !            68: VOID vBitmapSolidVertical(STRIP*, LINESTATE*, LONG*);
        !            69: VOID vBitmapSolidDiagonal(STRIP*, LINESTATE*, LONG*);
        !            70: 
        !            71: VOID vBitmapStyledHorizontal(STRIP*, LINESTATE*, LONG*);
        !            72: VOID vBitmapStyledVertical(STRIP*, LINESTATE*, LONG*);
        !            73: 
        !            74: // For two-pass ROPs:
        !            75: 
        !            76: VOID vCatchTwoPass(STRIP*, LINESTATE*, LONG*);
        !            77: 
        !            78: PFNSTRIP gapfnCatchTwoPass[] = {
        !            79:     vCatchTwoPass,
        !            80:     vCatchTwoPass,
        !            81:     vCatchTwoPass,
        !            82:     vCatchTwoPass
        !            83: };
        !            84: 
        !            85: // VGA ulVgaMode constants:
        !            86: 
        !            87: #define DR_SET   0x00
        !            88: #define DR_AND   0x08
        !            89: #define DR_OR    0x10
        !            90: #define DR_XOR   0x18
        !            91: 
        !            92: // Bit flag set if two passes needed:
        !            93: 
        !            94: #define DR_2PASS 0x80
        !            95: 
        !            96: // Table to convert ROP to usable information:
        !            97: 
        !            98: static struct {
        !            99:     ULONG ulColorAnd;
        !           100:     ULONG ulColorXor;
        !           101:     ULONG ulVgaMode;
        !           102: } arop[] = {
        !           103:     {0x00, 0xff, DR_SET},          //  1   R2_WHITE
        !           104:     {0x00, 0x00, DR_SET},          //  0   R2_BLACK
        !           105:     {0xff, 0xff, DR_AND|DR_2PASS}, // DPon R2_NOTMERGEPEN   Dest invert + DPna
        !           106:     {0xff, 0xff, DR_AND},          // DPna R2_MASKNOTPEN
        !           107:     {0xff, 0xff, DR_SET},          // PN   R2_NOTCOPYPEN
        !           108:     {0xff, 0x00, DR_AND|DR_2PASS}, // PDna R2_MASKPENNOT    Dest invert + DPa
        !           109:     {0x00, 0xff, DR_XOR},          // Dn   R2_NOT           Invert dest without pen
        !           110:     {0xff, 0x00, DR_XOR},          // DPx  R2_XORPEN
        !           111:     {0xff, 0xff, DR_OR|DR_2PASS},  // DPan R2_NOTMASKPEN    Dest invert + DPno
        !           112:     {0xff, 0x00, DR_AND},          // DPa  R2_MASKPEN
        !           113:     {0xff, 0xff, DR_XOR},          // DPxn R2_NOTXORPEN     DPxn == DPnx
        !           114:     {0x00, 0x00, DR_OR},           // D    R2_NOP           Silliness!
        !           115:     {0xff, 0xff, DR_OR},           // DPno R2_MERGENOTPEN
        !           116:     {0xff, 0x00, DR_SET},          // P    R2_COPYPEN
        !           117:     {0xff, 0x00, DR_OR|DR_2PASS},  // PDno R2_MERGEPENNOT   Dest invert + DPo
        !           118:     {0xff, 0x00, DR_OR},           // DPo  R2_MERGEPEN
        !           119: };
        !           120: 
        !           121: // The gaulAndXorTable contains and-masks and xor-masks for setting
        !           122: // pels to one of four possible values.  The and-masks have been
        !           123: // inverted, and are stored in the low byte of each word.  The
        !           124: // xor-masks are stored in the high bytes.
        !           125: //
        !           126: //      ROP     XOR    ~AND
        !           127: //      -------------------
        !           128: //      DDx     00      FF        Set to zero
        !           129: //      Dn      FF      00        Not destination
        !           130: //      D       00      00        Leave alone
        !           131: //      DDxn    FF      FF        Set to one
        !           132: 
        !           133: ULONG gaulAndXorTable[] = {
        !           134:     0x00ff,     // Set to zero
        !           135:     0xff00,     // Not destination
        !           136:     0x0000,     // Leave alone
        !           137:     0xffff      // Set to one
        !           138: };
        !           139: 
        !           140: ULONG gaulInitMasksLtoR[] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f };
        !           141: ULONG gaulInitMasksRtoL[] = { 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe };
        !           142: 
        !           143: /******************************Public*Routine******************************\
        !           144: * BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrushOrg, pla, mix)
        !           145: *
        !           146: * Strokes the path.
        !           147: *
        !           148: \**************************************************************************/
        !           149: 
        !           150: BOOL DrvStrokePath(
        !           151: SURFOBJ*   pso,
        !           152: PATHOBJ*   ppo,
        !           153: CLIPOBJ*   pco,
        !           154: XFORMOBJ*  pxo,
        !           155: BRUSHOBJ*  pbo,
        !           156: POINTL*    pptlBrushOrg,
        !           157: LINEATTRS* pla,
        !           158: MIX        mix)
        !           159: {
        !           160:     STYLEPOS  aspLtoR[STYLE_MAX_COUNT];
        !           161:     STYLEPOS  aspRtoL[STYLE_MAX_COUNT];
        !           162:     LINESTATE ls;
        !           163:     PFNSTRIP* apfn;
        !           164:     FLONG     fl;
        !           165:     PDEVSURF  pdsurf;
        !           166:     ULONG     ulVgaMode;
        !           167: 
        !           168:     UNREFERENCED_PARAMETER(pxo);
        !           169:     UNREFERENCED_PARAMETER(pptlBrushOrg);
        !           170: 
        !           171: // Verify that things are as they should be:
        !           172: 
        !           173: //    ASSERT(pso != (SURFOBJ*) NULL,  "DrvStrokePath: surface");
        !           174: //    ASSERT(ppo != (PATHOBJ*) NULL,  "DrvStrokePath: path");
        !           175: //    ASSERT(pco != (CLIPOBJ*) NULL,  "DrvStrokePath: clipobj");
        !           176: //    ASSERT(pbo != (BRUSHOBJ*) NULL, "DrvStrokePath: brushobj");
        !           177: //    ASSERT(pla != (LINEATTRS*) NULL && !(pla->fl & LA_GEOMETRIC),
        !           178: //                                     "DrvStrokePath: lineattrs");
        !           179: //    ASSERT(pbo->iSolidColor != 0xffffffff,
        !           180: //                                     "DrvStrokePath: brushobj isn't solid");
        !           181: 
        !           182: // Get the device ready:
        !           183: 
        !           184:     pdsurf = (PDEVSURF) pso->dhsurf;
        !           185: //    ASSERT(pdsurf != (PDEVSURF) NULL, "DrvStrokePath: no surface");
        !           186: 
        !           187:     fl = 0;
        !           188: 
        !           189: // Look after styling initialization:
        !           190: 
        !           191:     if (pla->fl & LA_ALTERNATE)
        !           192:     {
        !           193: //        ASSERT(pla->pstyle == (FLOAT_LONG*) NULL && pla->cstyle == 0,
        !           194: //               "Non-empty style array for PS_ALTERNATE");
        !           195: 
        !           196:         ls.spTotal     = 1;
        !           197:         ls.spTotal2    = 2;
        !           198:         ls.xyDensity   = 1;
        !           199:         fl            |= (FL_ALTERNATESTYLED | FL_MASKSTYLED);
        !           200:     }
        !           201:     else if (pla->pstyle != (FLOAT_LONG*) NULL)
        !           202:     {
        !           203:         PFLOAT_LONG pstyle;
        !           204: 
        !           205: //        ASSERT(pla->cstyle <= STYLE_MAX_COUNT, "Style array too large");
        !           206: 
        !           207:         pstyle = &pla->pstyle[pla->cstyle];
        !           208: 
        !           209:         ls.xyDensity = STYLE_DENSITY;
        !           210:         ls.spTotal   = 0;
        !           211:         while (pstyle-- > pla->pstyle)
        !           212:         {
        !           213:             ls.spTotal += pstyle->l;
        !           214:         }
        !           215:         ls.spTotal *= STYLE_DENSITY;
        !           216:         ls.spTotal2 = 2 * ls.spTotal;
        !           217: 
        !           218:     // Compute starting style position (this is guaranteed not to overflow):
        !           219: 
        !           220:         ls.spNext = HIWORD(pla->elStyleState.l) * STYLE_DENSITY +
        !           221:                     LOWORD(pla->elStyleState.l);
        !           222: 
        !           223:     // We optimize the style arrays that are even length and sum to 8.  We
        !           224:     // also don't have any masked strip drawers for DFBs:
        !           225: 
        !           226:         if (ls.spTotal == (8 * STYLE_DENSITY) &&
        !           227:             (pla->cstyle & 1) == 0)
        !           228:         {
        !           229:         // Do "masked" styles.
        !           230:         // -------------------
        !           231:         //
        !           232:         // This case is merely an optimization; you can remove it and
        !           233:         // all style lines will still work.  It just so happens that the
        !           234:         // default styles (such as PS_DOT, PS_DASHDOT, etc.) will all
        !           235:         // sum to 8, and there are some optimizations we can do on the
        !           236:         // VGA for that case.
        !           237:         //
        !           238:         // We make an 8 bit mask that represents each style unit in the
        !           239:         // style array, and we pass this to the "Masked" strip drawers
        !           240:         // (instead of calling the "Styled" strip drawers which still
        !           241:         // handle the arbitrary styles).
        !           242: 
        !           243:             LONG ii;
        !           244: 
        !           245:             ls.ulStyleMaskLtoR = 0;
        !           246:             ls.ulStyleMaskRtoL = 0;
        !           247: 
        !           248:             for (pstyle = pla->pstyle, ii = 8; ii > 0;)
        !           249:             {
        !           250:                 LONG l1 = (pstyle++)->l;
        !           251:                 LONG l2 = (pstyle++)->l;
        !           252: 
        !           253:                 ls.ulStyleMaskRtoL >>= l1 + l2;
        !           254:                 ls.ulStyleMaskRtoL |= gaulInitMasksRtoL[l2];
        !           255: 
        !           256:                 ls.ulStyleMaskLtoR <<= l1 + l2;
        !           257:                 ls.ulStyleMaskLtoR |= gaulInitMasksLtoR[l2];
        !           258: 
        !           259:                 ii -= (l1 + l2);
        !           260:             }
        !           261: 
        !           262:         // Replicate byte and initialize to style position zero:
        !           263: 
        !           264:             ls.ulStyleMaskLtoR |= (ls.ulStyleMaskLtoR << 8);
        !           265:             ls.ulStyleMaskLtoR |= (ls.ulStyleMaskLtoR << 16);
        !           266: 
        !           267:             ls.ulStyleMaskRtoL |= (ls.ulStyleMaskRtoL << 8);
        !           268:             ls.ulStyleMaskRtoL |= (ls.ulStyleMaskRtoL << 16);
        !           269: 
        !           270:         // Check if we should start with a gap or start with a dash:
        !           271: 
        !           272:             if (pla->fl & LA_STARTGAP)
        !           273:             {
        !           274:                 ls.ulStyleMaskLtoR = ~ls.ulStyleMaskLtoR;
        !           275:                 ls.ulStyleMaskRtoL = ~ls.ulStyleMaskRtoL;
        !           276:             }
        !           277: 
        !           278:         // Initialize some other state:
        !           279: 
        !           280:             fl |= FL_MASKSTYLED;
        !           281:         }
        !           282:         else
        !           283: 
        !           284:     // Okay, we've got to do it the slow way:
        !           285: 
        !           286:         {
        !           287:         // Handle Arbitrary Styles
        !           288:         // -----------------------
        !           289:         //
        !           290:         // Because arbitrary styles are new to Win32, many apps won't
        !           291:         // know about them and will use the default styles (which will
        !           292:         // be handled by the "Masked" optimization case above), and so
        !           293:         // this code path won't get exercised too often.  (See GDI's
        !           294:         // ExtCreatePen API.)
        !           295:         //
        !           296:         // But you still have to handle them, and do them right!
        !           297: 
        !           298:             FLOAT_LONG* pstyle;
        !           299:             STYLEPOS*   pspDown;
        !           300:             STYLEPOS*   pspUp;
        !           301: 
        !           302:             fl        |= FL_ARBITRARYSTYLED;
        !           303:             ls.cStyle  = pla->cstyle;
        !           304:             ls.aspRtoL = aspRtoL;
        !           305:             ls.aspLtoR = aspLtoR;
        !           306: 
        !           307:             if (pla->fl & LA_STARTGAP)
        !           308:                 ls.ulStartMask = 0xffffffffL;
        !           309:             else
        !           310:                 ls.ulStartMask = 0L;
        !           311: 
        !           312:             pstyle  = pla->pstyle;
        !           313:             pspDown = &ls.aspRtoL[ls.cStyle - 1];
        !           314:             pspUp   = &ls.aspLtoR[0];
        !           315: 
        !           316:         // We always draw strips left-to-right, but styles have to be laid
        !           317:         // down in the direction of the original line.  This means that in
        !           318:         // the strip code we have to traverse the style array in the
        !           319:         // opposite direction;
        !           320: 
        !           321:             while (pspDown >= &ls.aspRtoL[0])
        !           322:             {
        !           323: //                ASSERT(pstyle->l > 0 && pstyle->l <= STYLE_MAX_VALUE,
        !           324: //                       "Illegal style array value");
        !           325: 
        !           326:                 *pspDown = pstyle->l * STYLE_DENSITY;
        !           327:                 *pspUp   = *pspDown;
        !           328: 
        !           329:                 pspUp++;
        !           330:                 pspDown--;
        !           331:                 pstyle++;
        !           332:             }
        !           333:         }
        !           334:     }
        !           335: 
        !           336:     {
        !           337:         ULONG iColor;
        !           338:         ULONG iStripIndex;
        !           339: 
        !           340:         fl |= FL_PHYSICAL_DEVICE;
        !           341: 
        !           342:     // Compute the pointer to the correct strip drawing table.  We
        !           343:     // have a special table for solid lines done with VGA mode == SET:
        !           344: 
        !           345:         iStripIndex = 4 * ((fl & FL_STYLE_MASK) >> FL_STYLE_SHIFT);
        !           346:         apfn = &gapfnStrip[iStripIndex];
        !           347: 
        !           348:         mix &= 0xf;
        !           349:         ulVgaMode = arop[mix].ulVgaMode;
        !           350: 
        !           351:         if (ulVgaMode == DR_SET && iStripIndex == 0)
        !           352:             apfn = &gapfnStripSolidSet[0];
        !           353: 
        !           354:     // Compute the correct color, based on the ROP we're doing:
        !           355: 
        !           356:         iColor = (pbo->iSolidColor & arop[mix].ulColorAnd)
        !           357:                ^ (arop[mix].ulColorXor);
        !           358: 
        !           359:         if (!(ulVgaMode & DR_2PASS))
        !           360:             vSetStrips(iColor, ulVgaMode);
        !           361:         else
        !           362:         {
        !           363:         // If the ROP requires 2 passes, we sneakily change our strip
        !           364:         // table pointer to point to only our own routine, and it
        !           365:         // handles calling the appropriate strip routines twice:
        !           366: 
        !           367:             ls.ulVgaMode = ulVgaMode ^ DR_2PASS;
        !           368:             ls.iColor    = iColor;
        !           369:             ls.apfnStrip = apfn;
        !           370:             apfn         = gapfnCatchTwoPass;
        !           371:         }
        !           372:     }
        !           373: 
        !           374: // Set up to enumerate the path:
        !           375: 
        !           376:     if (pco->iDComplexity != DC_COMPLEX)
        !           377:     {
        !           378:         RECTL     arclClip[4];                   // For rectangular clipping
        !           379:         PATHDATA  pd;
        !           380:         RECTL*    prclClip = (RECTL*) NULL;
        !           381:         BOOL      bMore;
        !           382:         ULONG     cptfx;
        !           383:         POINTFIX  ptfxStartFigure;
        !           384:         POINTFIX  ptfxLast;
        !           385:         POINTFIX* pptfxFirst;
        !           386:         POINTFIX* pptfxBuf;
        !           387: 
        !           388:         if (pco->iDComplexity == DC_RECT)
        !           389:         {
        !           390:             fl |= FL_SIMPLE_CLIP;
        !           391: 
        !           392:             arclClip[0]        =  pco->rclBounds;
        !           393: 
        !           394:         // FL_FLIP_D:
        !           395: 
        !           396:             arclClip[1].top    =  pco->rclBounds.left;
        !           397:             arclClip[1].left   =  pco->rclBounds.top;
        !           398:             arclClip[1].bottom =  pco->rclBounds.right;
        !           399:             arclClip[1].right  =  pco->rclBounds.bottom;
        !           400: 
        !           401:         // FL_FLIP_V:
        !           402: 
        !           403:             arclClip[2].top    = -pco->rclBounds.bottom + 1;
        !           404:             arclClip[2].left   =  pco->rclBounds.left;
        !           405:             arclClip[2].bottom = -pco->rclBounds.top + 1;
        !           406:             arclClip[2].right  =  pco->rclBounds.right;
        !           407: 
        !           408:         // FL_FLIP_V | FL_FLIP_D:
        !           409: 
        !           410:             arclClip[3].top    =  pco->rclBounds.left;
        !           411:             arclClip[3].left   = -pco->rclBounds.bottom + 1;
        !           412:             arclClip[3].bottom =  pco->rclBounds.right;
        !           413:             arclClip[3].right  = -pco->rclBounds.top + 1;
        !           414: 
        !           415:             prclClip = arclClip;
        !           416:         }
        !           417: 
        !           418:         PATHOBJ_vEnumStart(ppo);
        !           419: 
        !           420:         do {
        !           421:             bMore = PATHOBJ_bEnum(ppo, &pd);
        !           422: 
        !           423:             cptfx = pd.count;
        !           424:             if (cptfx == 0)
        !           425:             {
        !           426: //                ASSERT(!bMore, "Empty path record in non-empty path");
        !           427:                 break;
        !           428:             }
        !           429: 
        !           430:             if (pd.flags & PD_BEGINSUBPATH)
        !           431:             {
        !           432:                 ptfxStartFigure  = *pd.pptfx;
        !           433:                 pptfxFirst       = pd.pptfx;
        !           434:                 pptfxBuf         = pd.pptfx + 1;
        !           435:                 cptfx--;
        !           436:             }
        !           437:             else
        !           438:             {
        !           439:                 pptfxFirst       = &ptfxLast;
        !           440:                 pptfxBuf         = pd.pptfx;
        !           441:             }
        !           442: 
        !           443:             if (pd.flags & PD_RESETSTYLE)
        !           444:                 ls.spNext = 0;
        !           445: 
        !           446:         // We have to check for cptfx == 0 because the only point in the
        !           447:         // subpath may have been the StartFigure point:
        !           448: 
        !           449:             if (cptfx > 0)
        !           450:             {
        !           451:                 if (!bLines(pdsurf,
        !           452:                             pptfxFirst,
        !           453:                             pptfxBuf,
        !           454:                             (RUN*) NULL,
        !           455:                             cptfx,
        !           456:                             &ls,
        !           457:                             prclClip,
        !           458:                             apfn,
        !           459:                             fl))
        !           460:                     return(FALSE);
        !           461:             }
        !           462: 
        !           463:             ptfxLast = pd.pptfx[pd.count - 1];
        !           464: 
        !           465:             if (pd.flags & PD_CLOSEFIGURE)
        !           466:             {
        !           467:                 if (!bLines(pdsurf,
        !           468:                             &ptfxLast,
        !           469:                             &ptfxStartFigure,
        !           470:                             (RUN*) NULL,
        !           471:                             1,
        !           472:                             &ls,
        !           473:                             prclClip,
        !           474:                             apfn,
        !           475:                             fl))
        !           476:                     return(FALSE);
        !           477:             }
        !           478:         } while (bMore);
        !           479: 
        !           480:         if (fl & FL_STYLED)
        !           481:         {
        !           482:         // Save the style state:
        !           483: 
        !           484:             ULONG ulHigh;
        !           485:             ULONG ulLow;
        !           486: 
        !           487:         // !!! The engine handles unnormalized style states.  This can
        !           488:         // !!! be removed.  Might have to remove some asserts in the
        !           489:         // !!! engine.
        !           490: 
        !           491:         // Masked styles don't normalize the style state.  It's a good
        !           492:         // thing to do, so let's do it now:
        !           493: 
        !           494:             if ((ULONG) ls.spNext >= (ULONG) ls.spTotal2)
        !           495:                 ls.spNext = (ULONG) ls.spNext % (ULONG) ls.spTotal2;
        !           496: 
        !           497:             ulHigh = ls.spNext / ls.xyDensity;
        !           498:             ulLow  = ls.spNext % ls.xyDensity;
        !           499: 
        !           500:             pla->elStyleState.l = MAKELONG(ulLow, ulHigh);
        !           501:         }
        !           502:     }
        !           503:     else
        !           504:     {
        !           505:     // Local state for path enumeration:
        !           506: 
        !           507:         BOOL bMore;
        !           508:         union {
        !           509:             BYTE     aj[offsetof(CLIPLINE, arun) + RUN_MAX * sizeof(RUN)];
        !           510:             CLIPLINE cl;
        !           511:         } cl;
        !           512: 
        !           513:         fl |= FL_COMPLEX_CLIP;
        !           514: 
        !           515:     // We use the clip object when non-simple clipping is involved:
        !           516: 
        !           517:         PATHOBJ_vEnumStartClipLines(ppo, pco, pso, pla);
        !           518: 
        !           519:         do {
        !           520:             bMore = PATHOBJ_bEnumClipLines(ppo, sizeof(cl), &cl.cl);
        !           521:             if (cl.cl.c != 0)
        !           522:             {
        !           523:                 if (fl & FL_STYLED)
        !           524:                 {
        !           525:                     ls.spComplex = HIWORD(cl.cl.lStyleState) * ls.xyDensity
        !           526:                                  + LOWORD(cl.cl.lStyleState);
        !           527:                 }
        !           528:                 if (!bLines(pdsurf,
        !           529:                             &cl.cl.ptfxA,
        !           530:                             &cl.cl.ptfxB,
        !           531:                             &cl.cl.arun[0],
        !           532:                             cl.cl.c,
        !           533:                             &ls,
        !           534:                             (RECTL*) NULL,
        !           535:                             apfn,
        !           536:                             fl))
        !           537:                     return(FALSE);
        !           538:             }
        !           539:         } while (bMore);
        !           540:     }
        !           541: 
        !           542:     if (fl & FL_PHYSICAL_DEVICE)
        !           543:         vClearStrips(ulVgaMode);
        !           544: 
        !           545:     return(TRUE);
        !           546: }
        !           547: 
        !           548: /******************************Public*Routine******************************\
        !           549: * VOID vCatchTwoPass(pstrip, pls, plStripEnd)
        !           550: *
        !           551: * Handles ROPs that cannot be done in a single pass using the VGA
        !           552: * hardware.  In order not to have a check in our main drawing loop for
        !           553: * two-pass ROPs, we change the strip function table so that this function
        !           554: * intercepts the call to draw the strips.
        !           555: *
        !           556: * This routine then figures out the appropriate actual strip drawer, and
        !           557: * makes two calls to it: first to invert the destination, then to do the
        !           558: * rest of the ROP.
        !           559: *
        !           560: \**************************************************************************/
        !           561: 
        !           562: VOID vCatchTwoPass(STRIP* pstrip, LINESTATE* pls, LONG* plStripEnd)
        !           563: {
        !           564:     BYTE*     pjScreen    = pstrip->pjScreen;
        !           565:     BYTE      jBitMask    = pstrip->jBitMask;
        !           566:     BYTE      jStyleMask  = pstrip->jStyleMask;
        !           567:     STYLEPOS* psp         = pstrip->psp;
        !           568:     STYLEPOS  spRemaining = pstrip->spRemaining;
        !           569: 
        !           570: // Figure out the actual strip routine we're supposed to call:
        !           571: 
        !           572:     PFNSTRIP pfn = pls->apfnStrip[(pstrip->flFlips & FL_STRIP_MASK) >>
        !           573:                                   FL_STRIP_SHIFT];
        !           574: 
        !           575: // On the first pass, we invert the destination:
        !           576: 
        !           577:     vSetStrips(0xff, DR_XOR);
        !           578: 
        !           579:     (*pfn)(pstrip, pls, plStripEnd);
        !           580: 
        !           581: // We reset our strip variables for the second pass and handle the rest
        !           582: // of the ROP:
        !           583: 
        !           584:     pstrip->pjScreen    = pjScreen;
        !           585:     pstrip->jBitMask    = jBitMask;
        !           586:     pstrip->jStyleMask  = jStyleMask;
        !           587:     pstrip->psp         = psp;
        !           588:     pstrip->spRemaining = spRemaining;
        !           589: 
        !           590:     vSetStrips(pls->iColor, pls->ulVgaMode);
        !           591: 
        !           592:     (*pfn)(pstrip, pls, plStripEnd);
        !           593: }
        !           594: 

unix.superglobalmegacorp.com

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