|
|
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.