Annotation of ntddk/src/video/displays/vga256/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: #include "lines.h"
                     11: 
                     12: // Style array for alternate style (alternates one pixel on, one pixel off):
                     13: 
                     14: STYLEPOS gaspAlternateStyle[] = { 1 };
                     15: 
                     16: // Array to compute ROP masks:
                     17: 
                     18: LONG gaiLineMix[] = {
                     19:     AND_ZERO   | XOR_ONE,
                     20:     AND_ZERO   | XOR_ZERO,
                     21:     AND_NOTPEN | XOR_NOTPEN,
                     22:     AND_NOTPEN | XOR_ZERO,
                     23:     AND_ZERO   | XOR_NOTPEN,
                     24:     AND_PEN    | XOR_PEN,
                     25:     AND_ONE    | XOR_ONE,
                     26:     AND_ONE    | XOR_PEN,
                     27:     AND_PEN    | XOR_ONE,
                     28:     AND_PEN    | XOR_ZERO,
                     29:     AND_ONE    | XOR_NOTPEN,
                     30:     AND_ONE    | XOR_ZERO,
                     31:     AND_PEN    | XOR_NOTPEN,
                     32:     AND_ZERO   | XOR_PEN,
                     33:     AND_NOTPEN | XOR_ONE,
                     34:     AND_NOTPEN | XOR_PEN
                     35: };
                     36: 
                     37: // We have 4 basic strip drawers, one for every semi-octant.  The near-
                     38: // horizontal semi-octant is number 0, and the rest are numbered
                     39: // consecutively.
                     40: 
                     41: // Prototypes to go to the screen and handle any ROPs:
                     42: 
                     43: VOID vStripSolid0(STRIP*, LINESTATE*, LONG*);
                     44: VOID vStripSolid1(STRIP*, LINESTATE*, LONG*);
                     45: VOID vStripSolid2(STRIP*, LINESTATE*, LONG*);
                     46: VOID vStripSolid3(STRIP*, LINESTATE*, LONG*);
                     47: 
                     48: VOID vStripStyled0(STRIP*, LINESTATE*, LONG*);
                     49: VOID vStripStyled123(STRIP*, LINESTATE*, LONG*);
                     50: 
                     51: // Prototypes to go to the screen and handle only set-style ROPs:
                     52: 
                     53: VOID vStripSolidSet0(STRIP*, LINESTATE*, LONG*);
                     54: VOID vStripSolidSet1(STRIP*, LINESTATE*, LONG*);
                     55: VOID vStripSolidSet2(STRIP*, LINESTATE*, LONG*);
                     56: VOID vStripSolidSet3(STRIP*, LINESTATE*, LONG*);
                     57: 
                     58: VOID vStripStyledSet0(STRIP*, LINESTATE*, LONG*);
                     59: VOID vStripStyledSet123(STRIP*, LINESTATE*, LONG*);
                     60: 
                     61: PFNSTRIP gapfnStrip[] = {
                     62:     vStripSolid0,
                     63:     vStripSolid3,
                     64:     vStripSolid1,
                     65:     vStripSolid2,
                     66: 
                     67:     vStripStyled0,
                     68:     vStripStyled123,
                     69:     vStripStyled123,
                     70:     vStripStyled123,
                     71: 
                     72:     vStripSolidSet0,
                     73:     vStripSolidSet3,
                     74:     vStripSolidSet1,
                     75:     vStripSolidSet2,
                     76: 
                     77:     vStripStyledSet0,
                     78:     vStripStyledSet123,
                     79:     vStripStyledSet123,
                     80:     vStripStyledSet123,
                     81: };
                     82: 
                     83: /******************************Public*Routine******************************\
                     84: * BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrushOrg, pla, mix)
                     85: *
                     86: * Strokes the path.
                     87: \**************************************************************************/
                     88: 
                     89: BOOL DrvStrokePath(
                     90: SURFOBJ*   pso,
                     91: PATHOBJ*   ppo,
                     92: CLIPOBJ*   pco,
                     93: XFORMOBJ*  pxo,
                     94: BRUSHOBJ*  pbo,
                     95: POINTL*    pptlBrushOrg,
                     96: LINEATTRS* pla,
                     97: MIX        mix)
                     98: {
                     99:     STYLEPOS  aspLtoR[STYLE_MAX_COUNT];
                    100:     STYLEPOS  aspRtoL[STYLE_MAX_COUNT];
                    101:     LINESTATE ls;
                    102:     PFNSTRIP* apfn;
                    103:     FLONG     fl;
                    104:     PPDEV     ppdev = (PPDEV) pso->dhsurf;
                    105: 
                    106:     UNREFERENCED_PARAMETER(pxo);
                    107:     UNREFERENCED_PARAMETER(pptlBrushOrg);
                    108: 
                    109: // Fast lines can't handle trivial clipping, ROPs other than R2_COPYPEN, or
                    110: // styles:
                    111: 
                    112:     mix &= 0xf;
                    113:     if ((mix == 0x0d) &&
                    114:         (pco->iDComplexity == DC_TRIVIAL) &&
                    115:         (pla->pstyle == NULL) && !(pla->fl & LA_ALTERNATE))
                    116:     {
                    117:         vFastLine(ppdev, ppo, ppdev->lNextScan,
                    118:                   (pbo->iSolidColor << 8) | (pbo->iSolidColor & 0xff));
                    119:         return(TRUE);
                    120:     }
                    121: 
                    122:     fl = 0;
                    123: 
                    124: // Look after styling initialization:
                    125: 
                    126:     if (pla->fl & LA_ALTERNATE)
                    127:     {
                    128:         ASSERTVGA(pla->pstyle == (FLOAT_LONG*) NULL && pla->cstyle == 0,
                    129:                "Non-empty style array for PS_ALTERNATE");
                    130: 
                    131:         ls.bStartIsGap  = 0;                        // First pel is a dash
                    132:         ls.cStyle       = 1;                        // Size of style array
                    133:         ls.spTotal      = 1;                        // Sum of style array
                    134:         ls.spTotal2     = 2;                        // Twice the sum
                    135:         ls.aspRtoL      = &gaspAlternateStyle[0];   // Right-to-left array
                    136:         ls.aspLtoR      = &gaspAlternateStyle[0];   // Left-to-right array
                    137:         ls.spNext       = HIWORD(pla->elStyleState.l) & 1;
                    138:                                                     // Light first pixel if
                    139:                                                     //   a multiple of 2
                    140:         ls.xyDensity    = 1;                        // Each 'dot' is one
                    141:                                                     //   pixel long
                    142:         fl             |= FL_ARBITRARYSTYLED;
                    143:     }
                    144:     else if (pla->pstyle != (FLOAT_LONG*) NULL)
                    145:     {
                    146:         FLOAT_LONG* pstyle;
                    147:         STYLEPOS*   pspDown;
                    148:         STYLEPOS*   pspUp;
                    149: 
                    150:         ASSERTVGA(pla->cstyle <= STYLE_MAX_COUNT, "Style array too large");
                    151: 
                    152:     // Compute length of style array:
                    153: 
                    154:         pstyle = &pla->pstyle[pla->cstyle];
                    155: 
                    156:         ls.xyDensity = STYLE_DENSITY;
                    157:         ls.spTotal   = 0;
                    158:         while (pstyle-- > pla->pstyle)
                    159:         {
                    160:             ls.spTotal += pstyle->l;
                    161:         }
                    162: 
                    163:     // The style array is given in 'style' units.  Since we're going to
                    164:     // assign each unit to be STYLE_DENSITY (3) pixels long, multiply:
                    165: 
                    166:         ls.spTotal *= STYLE_DENSITY;
                    167:         ls.spTotal2 = 2 * ls.spTotal;
                    168: 
                    169:     // Compute starting style position (this is guaranteed not to overflow).
                    170:     // Note that since the array repeats infinitely, this number might
                    171:     // actually be more than ls.spTotal2, but we take care of that later
                    172:     // in our code:
                    173: 
                    174:         ls.spNext = HIWORD(pla->elStyleState.l) * STYLE_DENSITY +
                    175:                     LOWORD(pla->elStyleState.l);
                    176: 
                    177:         fl            |= FL_ARBITRARYSTYLED;
                    178:         ls.cStyle      = pla->cstyle;
                    179:         ls.aspRtoL     = aspRtoL;   // Style array in right-to-left order
                    180:         ls.aspLtoR     = aspLtoR;   // Style array in left-to-right order
                    181: 
                    182:     // ulStartMask determines if the first entry in the style array is for
                    183:     // a dash or a gap:
                    184: 
                    185:         ls.bStartIsGap = (pla->fl & LA_STARTGAP) ? -1L : 0L;
                    186: 
                    187:         pstyle  = pla->pstyle;
                    188:         pspDown = &ls.aspRtoL[ls.cStyle - 1];
                    189:         pspUp   = &ls.aspLtoR[0];
                    190: 
                    191:     // We always draw strips left-to-right, but styles have to be laid
                    192:     // down in the direction of the original line.  This means that in
                    193:     // the strip code we have to traverse the style array in the
                    194:     // opposite direction;
                    195: 
                    196:         while (pspDown >= &ls.aspRtoL[0])
                    197:         {
                    198:             ASSERTVGA(pstyle->l > 0 && pstyle->l <= STYLE_MAX_VALUE,
                    199:                    "Illegal style array value");
                    200: 
                    201:             *pspDown = pstyle->l * STYLE_DENSITY;
                    202:             *pspUp   = *pspDown;
                    203: 
                    204:             pspUp++;
                    205:             pspDown--;
                    206:             pstyle++;
                    207:         }
                    208:     }
                    209: 
                    210:     {
                    211:     // All ROPs are handled in a single pass:
                    212: 
                    213:         ULONG achColor[4];
                    214:         LONG  iIndex;
                    215:         ULONG iColor = (pbo->iSolidColor & 0xff);
                    216: 
                    217:         achColor[AND_ZERO]   =  0;
                    218:         achColor[AND_PEN]    =  pbo->iSolidColor;
                    219:         achColor[AND_NOTPEN] = ~pbo->iSolidColor;
                    220:         achColor[AND_ONE]    =  (ULONG) -1L;
                    221: 
                    222:         iIndex = gaiLineMix[mix];
                    223: 
                    224:     // We have special strip drawers for set-style ROPs (where we don't
                    225:     // have to read video memory):
                    226: 
                    227:         if ((iIndex & 0xff) == AND_ZERO)
                    228:             fl |= FL_SET;
                    229: 
                    230:     // Put the AND index in the low byte, and the XOR index in the next:
                    231: 
                    232:         *((BYTE*) &ls.chAndXor)     = (BYTE) achColor[iIndex & 0xff];
                    233:         *((BYTE*) &ls.chAndXor + 1) = (BYTE) achColor[iIndex >> MIX_XOR_OFFSET];
                    234:     }
                    235: 
                    236:     apfn = &gapfnStrip[4 * ((fl & FL_STRIP_ARRAY_MASK) >> FL_STRIP_ARRAY_SHIFT)];
                    237: 
                    238: // Set up to enumerate the path:
                    239: 
                    240:     if (pco->iDComplexity != DC_COMPLEX)
                    241:     {
                    242:         RECTL     arclClip[4];                   // For rectangular clipping
                    243:         PATHDATA  pd;
                    244:         RECTL*    prclClip = (RECTL*) NULL;
                    245:         BOOL      bMore;
                    246:         ULONG     cptfx;
                    247:         POINTFIX  ptfxStartFigure;
                    248:         POINTFIX  ptfxLast;
                    249:         POINTFIX* pptfxFirst;
                    250:         POINTFIX* pptfxBuf;
                    251: 
                    252:         if (pco->iDComplexity == DC_RECT)
                    253:         {
                    254:             fl |= FL_SIMPLE_CLIP;
                    255: 
                    256:             arclClip[0]        =  pco->rclBounds;
                    257: 
                    258:         // FL_FLIP_D:
                    259: 
                    260:             arclClip[1].top    =  pco->rclBounds.left;
                    261:             arclClip[1].left   =  pco->rclBounds.top;
                    262:             arclClip[1].bottom =  pco->rclBounds.right;
                    263:             arclClip[1].right  =  pco->rclBounds.bottom;
                    264: 
                    265:         // FL_FLIP_V:
                    266: 
                    267:             arclClip[2].top    = -pco->rclBounds.bottom + 1;
                    268:             arclClip[2].left   =  pco->rclBounds.left;
                    269:             arclClip[2].bottom = -pco->rclBounds.top + 1;
                    270:             arclClip[2].right  =  pco->rclBounds.right;
                    271: 
                    272:         // FL_FLIP_V | FL_FLIP_D:
                    273: 
                    274:             arclClip[3].top    =  pco->rclBounds.left;
                    275:             arclClip[3].left   = -pco->rclBounds.bottom + 1;
                    276:             arclClip[3].bottom =  pco->rclBounds.right;
                    277:             arclClip[3].right  = -pco->rclBounds.top + 1;
                    278: 
                    279:             prclClip = arclClip;
                    280:         }
                    281: 
                    282:         do {
                    283:             bMore = PATHOBJ_bEnum(ppo, &pd);
                    284: 
                    285:             cptfx = pd.count;
                    286:             if (cptfx == 0)
                    287:             {
                    288:                 ASSERTVGA(!bMore, "Empty path record in non-empty path");
                    289:                 break;
                    290:             }
                    291: 
                    292:             if (pd.flags & PD_BEGINSUBPATH)
                    293:             {
                    294:                 ptfxStartFigure  = *pd.pptfx;
                    295:                 pptfxFirst       = pd.pptfx;
                    296:                 pptfxBuf         = pd.pptfx + 1;
                    297:                 cptfx--;
                    298:             }
                    299:             else
                    300:             {
                    301:                 pptfxFirst       = &ptfxLast;
                    302:                 pptfxBuf         = pd.pptfx;
                    303:             }
                    304: 
                    305:             if (pd.flags & PD_RESETSTYLE)
                    306:                 ls.spNext = 0;
                    307: 
                    308:         // We have to check for cptfx == 0 because the only point in the
                    309:         // subpath may have been the StartFigure point:
                    310: 
                    311:             if (cptfx > 0)
                    312:             {
                    313:                 if (!bLines(ppdev,
                    314:                             pptfxFirst,
                    315:                             pptfxBuf,
                    316:                             (RUN*) NULL,
                    317:                             cptfx,
                    318:                             &ls,
                    319:                             prclClip,
                    320:                             apfn,
                    321:                             fl))
                    322:                     return(FALSE);
                    323:             }
                    324: 
                    325:             ptfxLast = pd.pptfx[pd.count - 1];
                    326: 
                    327:             if (pd.flags & PD_CLOSEFIGURE)
                    328:             {
                    329:                 if (!bLines(ppdev,
                    330:                             &ptfxLast,
                    331:                             &ptfxStartFigure,
                    332:                             (RUN*) NULL,
                    333:                             1,
                    334:                             &ls,
                    335:                             prclClip,
                    336:                             apfn,
                    337:                             fl))
                    338:                     return(FALSE);
                    339:             }
                    340:         } while (bMore);
                    341: 
                    342:         if (fl & FL_STYLED)
                    343:         {
                    344:         // Save the style state:
                    345: 
                    346:             ULONG ulHigh;
                    347:             ULONG ulLow;
                    348: 
                    349:             ulHigh = ls.spNext / ls.xyDensity;
                    350:             ulLow  = ls.spNext % ls.xyDensity;
                    351: 
                    352:             pla->elStyleState.l = MAKELONG(ulLow, ulHigh);
                    353:         }
                    354:     }
                    355:     else
                    356:     {
                    357:     // Local state for path enumeration:
                    358: 
                    359:         BOOL bMore;
                    360:         union {
                    361:             BYTE     aj[offsetof(CLIPLINE, arun) + RUN_MAX * sizeof(RUN)];
                    362:             CLIPLINE cl;
                    363:         } cl;
                    364: 
                    365:         fl |= FL_COMPLEX_CLIP;
                    366: 
                    367:     // We use the clip object when non-simple clipping is involved:
                    368: 
                    369:         PATHOBJ_vEnumStartClipLines(ppo, pco, pso, pla);
                    370: 
                    371:         do {
                    372:             bMore = PATHOBJ_bEnumClipLines(ppo, sizeof(cl), &cl.cl);
                    373:             if (cl.cl.c != 0)
                    374:             {
                    375:                 if (fl & FL_STYLED)
                    376:                 {
                    377:                     ls.spComplex = HIWORD(cl.cl.lStyleState) * ls.xyDensity
                    378:                                  + LOWORD(cl.cl.lStyleState);
                    379:                 }
                    380:                 if (!bLines(ppdev,
                    381:                             &cl.cl.ptfxA,
                    382:                             &cl.cl.ptfxB,
                    383:                             &cl.cl.arun[0],
                    384:                             cl.cl.c,
                    385:                             &ls,
                    386:                             (RECTL*) NULL,
                    387:                             apfn,
                    388:                             fl))
                    389:                     return(FALSE);
                    390:             }
                    391:         } while (bMore);
                    392:     }
                    393: 
                    394:     return(TRUE);
                    395: }

unix.superglobalmegacorp.com

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