Annotation of ntddk/src/video/displays/vga/stroke.c, revision 1.1.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.