Annotation of ntddk/src/video/displays/vga256/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: #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.