|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.