|
|
1.1 ! root 1: /******************************Module*Header*******************************\ ! 2: * Module Name: Stroke.c ! 3: * ! 4: * DrvStrokePath for S3 driver ! 5: * ! 6: * Copyright (c) 1992 Microsoft Corporation ! 7: \**************************************************************************/ ! 8: ! 9: #include "driver.h" ! 10: #include "lines.h" ! 11: ! 12: VOID (*gapfnStrip[])(PPDEV, STRIP*, LINESTATE*) = { ! 13: vrlSolidHorizontal, ! 14: vrlSolidVertical, ! 15: vrlSolidDiagonalHorizontal, ! 16: vrlSolidDiagonalVertical, ! 17: ! 18: // Should be NUM_STRIP_DRAW_DIRECTIONS = 4 strip drawers in every group ! 19: ! 20: vssSolidHorizontal, ! 21: vssSolidVertical, ! 22: vssSolidDiagonalHorizontal, ! 23: vssSolidDiagonalVertical, ! 24: ! 25: // Should be NUM_STRIP_DRAW_STYLES = 8 strip drawers in total for doing ! 26: // solid lines, and the same number for non-solid lines: ! 27: ! 28: vStripStyledHorizontal, ! 29: vStripStyledVertical, ! 30: vStripStyledVertical, // Diagonal goes here ! 31: vStripStyledVertical, // Diagonal goes here ! 32: ! 33: vStripStyledHorizontal, ! 34: vStripStyledVertical, ! 35: vStripStyledVertical, // Diagonal goes here ! 36: vStripStyledVertical, // Diagonal goes here ! 37: }; ! 38: ! 39: // Style array for alternate style (alternates one pixel on, one pixel off): ! 40: ! 41: STYLEPOS gaspAlternateStyle[] = { 1 }; ! 42: ! 43: /******************************Public*Routine******************************\ ! 44: * BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrushOrg, pla, mix) ! 45: * ! 46: * Strokes the path. ! 47: * ! 48: \**************************************************************************/ ! 49: ! 50: BOOL DrvStrokePath( ! 51: SURFOBJ* pso, ! 52: PATHOBJ* ppo, ! 53: CLIPOBJ* pco, ! 54: XFORMOBJ* pxo, ! 55: BRUSHOBJ* pbo, ! 56: POINTL* pptlBrushOrg, ! 57: LINEATTRS* pla, ! 58: MIX mix) ! 59: { ! 60: STYLEPOS aspLtoR[STYLE_MAX_COUNT]; ! 61: STYLEPOS aspRtoL[STYLE_MAX_COUNT]; ! 62: LINESTATE ls; ! 63: PFNSTRIP* apfn; ! 64: FLONG fl; ! 65: PPDEV ppdev; ! 66: RECTL arclClip[4]; // For rectangular clipping ! 67: ! 68: UNREFERENCED_PARAMETER(pxo); ! 69: UNREFERENCED_PARAMETER(pptlBrushOrg); ! 70: ! 71: ppdev = (PPDEV) pso->dhsurf; ! 72: ! 73: // Get the device ready: ! 74: ! 75: vSetStrips(ppdev, pla, pbo->iSolidColor, mix); ! 76: ! 77: // x86 has special case ASM code for accelerating solid lines: ! 78: ! 79: #if defined(_X86_) || defined(i386) ! 80: ! 81: if ((pla->pstyle == NULL) && !(pla->fl & LA_ALTERNATE)) ! 82: { ! 83: // We can accelerate solid lines: ! 84: ! 85: if (pco->iDComplexity == DC_TRIVIAL) ! 86: { ! 87: vFastLine(ppdev, ppo, NULL, &gapfnStrip[0], 0); ! 88: ! 89: return(TRUE); ! 90: } ! 91: else if (pco->iDComplexity == DC_RECT) ! 92: { ! 93: RECTL rclBounds; ! 94: RECTFX rcfxBounds; ! 95: ! 96: // We have to be sure that we don't overflow the hardware registers ! 97: // for current position, line length, or DDA terms. We check ! 98: // here to make sure that the current position and line length ! 99: // values won't overflow (for integer lines, this check is ! 100: // sufficient to ensure that the DDA terms won't overflow; for GIQ ! 101: // lines, we specifically check on every line in vFastLines that we ! 102: // don't overflow). ! 103: ! 104: PATHOBJ_vGetBounds(ppo, &rcfxBounds); ! 105: ! 106: if (rcfxBounds.xLeft >= (MIN_INTEGER_BOUND * F) && ! 107: rcfxBounds.yTop >= (MIN_INTEGER_BOUND * F) && ! 108: rcfxBounds.xRight <= (MAX_INTEGER_BOUND * F) && ! 109: rcfxBounds.yBottom <= (MAX_INTEGER_BOUND * F)) ! 110: { ! 111: arclClip[0] = pco->rclBounds; ! 112: ! 113: // FL_FLIP_D: ! 114: ! 115: arclClip[1].top = pco->rclBounds.left; ! 116: arclClip[1].left = pco->rclBounds.top; ! 117: arclClip[1].bottom = pco->rclBounds.right; ! 118: arclClip[1].right = pco->rclBounds.bottom; ! 119: ! 120: // FL_FLIP_V: ! 121: ! 122: arclClip[2].top = -pco->rclBounds.bottom + 1; ! 123: arclClip[2].left = pco->rclBounds.left; ! 124: arclClip[2].bottom = -pco->rclBounds.top + 1; ! 125: arclClip[2].right = pco->rclBounds.right; ! 126: ! 127: // FL_FLIP_V | FL_FLIP_D: ! 128: ! 129: arclClip[3].top = pco->rclBounds.left; ! 130: arclClip[3].left = -pco->rclBounds.bottom + 1; ! 131: arclClip[3].bottom = pco->rclBounds.right; ! 132: arclClip[3].right = -pco->rclBounds.top + 1; ! 133: ! 134: rclBounds.left = pco->rclBounds.left; ! 135: rclBounds.top = pco->rclBounds.top; ! 136: rclBounds.right = pco->rclBounds.right; ! 137: rclBounds.bottom = pco->rclBounds.bottom; ! 138: ! 139: vSetS3ClipRect(ppdev, &rclBounds); ! 140: ! 141: vFastLine(ppdev, ppo, &arclClip[0], &gapfnStrip[0], ! 142: FL_SIMPLE_CLIP); ! 143: ! 144: vResetS3Clipping(ppdev); ! 145: return(TRUE); ! 146: } ! 147: } ! 148: } ! 149: ! 150: #endif ! 151: ! 152: fl = 0; ! 153: ! 154: // Look after styling initialization: ! 155: ! 156: if (pla->fl & LA_ALTERNATE) ! 157: { ! 158: ls.cStyle = 1; ! 159: ls.spTotal = 1; ! 160: ls.spTotal2 = 2; ! 161: ls.spRemaining = 1; ! 162: ls.aspRtoL = &gaspAlternateStyle[0]; ! 163: ls.aspLtoR = &gaspAlternateStyle[0]; ! 164: ls.spNext = HIWORD(pla->elStyleState.l); ! 165: ls.xyDensity = 1; ! 166: fl |= FL_ARBITRARYSTYLED; ! 167: ls.ulStartMask = 0L; ! 168: } ! 169: else if (pla->pstyle != (FLOAT_LONG*) NULL) ! 170: { ! 171: PFLOAT_LONG pstyle; ! 172: STYLEPOS* pspDown; ! 173: STYLEPOS* pspUp; ! 174: ! 175: pstyle = &pla->pstyle[pla->cstyle]; ! 176: ! 177: ls.xyDensity = STYLE_DENSITY; ! 178: ls.spTotal = 0; ! 179: while (pstyle-- > pla->pstyle) ! 180: { ! 181: ls.spTotal += pstyle->l; ! 182: } ! 183: ls.spTotal *= STYLE_DENSITY; ! 184: ls.spTotal2 = 2 * ls.spTotal; ! 185: ! 186: // Compute starting style position (this is guaranteed not to overflow): ! 187: ! 188: ls.spNext = HIWORD(pla->elStyleState.l) * STYLE_DENSITY + ! 189: LOWORD(pla->elStyleState.l); ! 190: ! 191: fl |= FL_ARBITRARYSTYLED; ! 192: ls.cStyle = pla->cstyle; ! 193: ls.aspRtoL = aspRtoL; ! 194: ls.aspLtoR = aspLtoR; ! 195: ! 196: if (pla->fl & LA_STARTGAP) ! 197: ls.ulStartMask = 0xffffffffL; ! 198: else ! 199: ls.ulStartMask = 0L; ! 200: ! 201: pstyle = pla->pstyle; ! 202: pspDown = &ls.aspRtoL[ls.cStyle - 1]; ! 203: pspUp = &ls.aspLtoR[0]; ! 204: ! 205: while (pspDown >= &ls.aspRtoL[0]) ! 206: { ! 207: *pspDown = pstyle->l * STYLE_DENSITY; ! 208: *pspUp = *pspDown; ! 209: ! 210: pspUp++; ! 211: pspDown--; ! 212: pstyle++; ! 213: } ! 214: } ! 215: ! 216: apfn = &gapfnStrip[NUM_STRIP_DRAW_STYLES * ! 217: ((fl & FL_STYLE_MASK) >> FL_STYLE_SHIFT)]; ! 218: ! 219: // Set up to enumerate the path: ! 220: ! 221: #if defined(_X86_) || defined(i386) ! 222: ! 223: // x86 ASM bLines supports DC_RECT clipping: ! 224: ! 225: if (pco->iDComplexity != DC_COMPLEX) ! 226: ! 227: #else ! 228: ! 229: // Non-x86 ASM bLines don't support DC_RECT clipping: ! 230: ! 231: if (pco->iDComplexity == DC_TRIVIAL) ! 232: ! 233: #endif ! 234: ! 235: { ! 236: PATHDATA pd; ! 237: RECTL* prclClip = (RECTL*) NULL; ! 238: BOOL bMore; ! 239: ULONG cptfx; ! 240: POINTFIX ptfxStartFigure; ! 241: POINTFIX ptfxLast; ! 242: POINTFIX* pptfxFirst; ! 243: POINTFIX* pptfxBuf; ! 244: ! 245: #if defined(_X86_) || defined(i386) ! 246: ! 247: if (pco->iDComplexity == DC_RECT) ! 248: { ! 249: fl |= FL_SIMPLE_CLIP; ! 250: ! 251: arclClip[0] = pco->rclBounds; ! 252: ! 253: // FL_FLIP_D: ! 254: ! 255: arclClip[1].top = pco->rclBounds.left; ! 256: arclClip[1].left = pco->rclBounds.top; ! 257: arclClip[1].bottom = pco->rclBounds.right; ! 258: arclClip[1].right = pco->rclBounds.bottom; ! 259: ! 260: // FL_FLIP_V: ! 261: ! 262: arclClip[2].top = -pco->rclBounds.bottom + 1; ! 263: arclClip[2].left = pco->rclBounds.left; ! 264: arclClip[2].bottom = -pco->rclBounds.top + 1; ! 265: arclClip[2].right = pco->rclBounds.right; ! 266: ! 267: // FL_FLIP_V | FL_FLIP_D: ! 268: ! 269: arclClip[3].top = pco->rclBounds.left; ! 270: arclClip[3].left = -pco->rclBounds.bottom + 1; ! 271: arclClip[3].bottom = pco->rclBounds.right; ! 272: arclClip[3].right = -pco->rclBounds.top + 1; ! 273: ! 274: prclClip = arclClip; ! 275: } ! 276: ! 277: #endif ! 278: ! 279: pd.flags = 0; ! 280: ! 281: do { ! 282: bMore = PATHOBJ_bEnum(ppo, &pd); ! 283: ! 284: cptfx = pd.count; ! 285: if (cptfx == 0) ! 286: { ! 287: break; ! 288: } ! 289: ! 290: if (pd.flags & PD_BEGINSUBPATH) ! 291: { ! 292: ptfxStartFigure = *pd.pptfx; ! 293: pptfxFirst = pd.pptfx; ! 294: pptfxBuf = pd.pptfx + 1; ! 295: cptfx--; ! 296: } ! 297: else ! 298: { ! 299: pptfxFirst = &ptfxLast; ! 300: pptfxBuf = pd.pptfx; ! 301: } ! 302: ! 303: if (pd.flags & PD_RESETSTYLE) ! 304: ls.spNext = 0; ! 305: ! 306: if (cptfx > 0) ! 307: { ! 308: if (!bLines(ppdev, ! 309: pptfxFirst, ! 310: pptfxBuf, ! 311: (RUN*) NULL, ! 312: cptfx, ! 313: &ls, ! 314: prclClip, ! 315: apfn, ! 316: fl)) ! 317: return(FALSE); ! 318: } ! 319: ! 320: ptfxLast = pd.pptfx[pd.count - 1]; ! 321: ! 322: if (pd.flags & PD_CLOSEFIGURE) ! 323: { ! 324: if (!bLines(ppdev, ! 325: &ptfxLast, ! 326: &ptfxStartFigure, ! 327: (RUN*) NULL, ! 328: 1, ! 329: &ls, ! 330: prclClip, ! 331: apfn, ! 332: fl)) ! 333: return(FALSE); ! 334: } ! 335: } while (bMore); ! 336: ! 337: if (fl & FL_STYLED) ! 338: { ! 339: // Save the style state: ! 340: ! 341: ULONG ulHigh; ! 342: ULONG ulLow; ! 343: ! 344: // Masked styles don't normalize the style state. It's a good ! 345: // thing to do, so let's do it now: ! 346: ! 347: if ((ULONG) ls.spNext >= (ULONG) ls.spTotal2) ! 348: ls.spNext = (ULONG) ls.spNext % (ULONG) ls.spTotal2; ! 349: ! 350: ulHigh = ls.spNext / ls.xyDensity; ! 351: ulLow = ls.spNext % ls.xyDensity; ! 352: ! 353: pla->elStyleState.l = MAKELONG(ulLow, ulHigh); ! 354: } ! 355: } ! 356: else ! 357: { ! 358: // Local state for path enumeration: ! 359: ! 360: BOOL bMore; ! 361: union { ! 362: BYTE aj[offsetof(CLIPLINE, arun) + RUN_MAX * sizeof(RUN)]; ! 363: CLIPLINE cl; ! 364: } cl; ! 365: ! 366: fl |= FL_COMPLEX_CLIP; ! 367: ! 368: // We use the clip object when non-simple clipping is involved: ! 369: ! 370: PATHOBJ_vEnumStartClipLines(ppo, pco, pso, pla); ! 371: ! 372: do { ! 373: bMore = PATHOBJ_bEnumClipLines(ppo, sizeof(cl), &cl.cl); ! 374: if (cl.cl.c != 0) ! 375: { ! 376: if (fl & FL_STYLED) ! 377: { ! 378: ls.spComplex = HIWORD(cl.cl.lStyleState) * ls.xyDensity ! 379: + LOWORD(cl.cl.lStyleState); ! 380: } ! 381: if (!bLines(ppdev, ! 382: &cl.cl.ptfxA, ! 383: &cl.cl.ptfxB, ! 384: &cl.cl.arun[0], ! 385: cl.cl.c, ! 386: &ls, ! 387: (RECTL*) NULL, ! 388: apfn, ! 389: fl)) ! 390: return(FALSE); ! 391: } ! 392: } while (bMore); ! 393: } ! 394: ! 395: return(TRUE); ! 396: } ! 397: ! 398: ! 399:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.