Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1111 lines
37 KiB

  1. /*************************************************************************\
  2. * Module Name: EngLine.cxx
  3. *
  4. * EngLine for bitmap simulations
  5. *
  6. * Created: 5-Apr-91
  7. * Author: Paul Butzi
  8. *
  9. * Copyright (c) 1990-1999 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "precomp.hxx"
  12. #include "engline.hxx"
  13. /******************************Public*Routine******************************\
  14. * BOOL bLines(pbmi, pptfxFirst, pptfxBuf, prun, cptfx, pls, prclClip,
  15. * apfn[], flStart, pchBits, lDelta)
  16. *
  17. * Computes the DDA for the line and gets ready to draw it. Puts the
  18. * pixel data into an array of strips, and calls a strip routine to
  19. * do the actual drawing.
  20. *
  21. * Doing Lines Right
  22. * -----------------
  23. *
  24. * In NT, all lines are given to the device driver in fractional
  25. * coordinates, in a 28.4 fixed point format. The lower 4 bits are
  26. * fractional for sub-pixel positioning.
  27. *
  28. * Note that you CANNOT! just round the coordinates to integers
  29. * and pass the results to your favorite integer Bresenham routine!!
  30. * (Unless, of course, you have such a high resolution device that
  31. * nobody will notice -- not likely for a display device.) The
  32. * fractions give a more accurate rendering of the line -- this is
  33. * important for things like our Bezier curves, which would have 'kinks'
  34. * if the points in its polyline approximation were rounded to integers.
  35. *
  36. * Unfortunately, for fractional lines there is more setup work to do
  37. * a DDA than for integer lines. However, the main loop is exactly
  38. * the same (and can be done entirely with 32 bit math).
  39. *
  40. * Our Implementation
  41. * ------------------
  42. *
  43. * We employ a run length slice algorithm: our DDA calculates the
  44. * number of pixels that are in each row (or 'strip') of pixels.
  45. *
  46. * We've separated the running of the DDA and the drawing of pixels:
  47. * we run the DDA for several iterations and store the results in
  48. * a 'strip' buffer (which are the lengths of consecutive pixel rows of
  49. * the line), then we crank up a 'strip drawer' that will draw all the
  50. * strips in the buffer.
  51. *
  52. * We also employ a 'half-flip' to reduce the number of strip
  53. * iterations we need to do in the DDA and strip drawing loops: when a
  54. * (normalized) line's slope is more than 1/2, we do a final flip
  55. * about the line y = (1/2)x. So now, instead of each strip being
  56. * consecutive horizontal or vertical pixel rows, each strip is composed
  57. * of those pixels aligned in 45 degree rows. So a line like (0, 0) to
  58. * (128, 128) would generate only one strip.
  59. *
  60. * We also always draw only left-to-right.
  61. *
  62. * Style lines may have arbitrary style patterns. We specially
  63. * optimize the default patterns (and call them 'masked' styles).
  64. *
  65. * The DDA Derivation
  66. * ------------------
  67. *
  68. * Here is how I like to think of the DDA calculation.
  69. *
  70. * We employ Knuth's "diamond rule": rendering a one-pixel-wide line
  71. * can be thought of as dragging a one-pixel-wide by one-pixel-high
  72. * diamond along the true line. Pixel centers lie on the integer
  73. * coordinates, and so we light any pixel whose center gets covered
  74. * by the "drag" region (John D. Hobby, Journal of the Association
  75. * for Computing Machinery, Vol. 36, No. 2, April 1989, pp. 209-229).
  76. *
  77. * We must define which pixel gets lit when the true line falls
  78. * exactly half-way between two pixels. In this case, we follow
  79. * the rule: when two pels are equidistant, the upper or left pel
  80. * is illuminated, unless the slope is exactly one, in which case
  81. * the upper or right pel is illuminated. (So we make the edges
  82. * of the diamond exclusive, except for the top and left vertices,
  83. * which are inclusive, unless we have slope one.)
  84. *
  85. * This metric decides what pixels should be on any line BEFORE it is
  86. * flipped around for our calculation. Having a consistent metric
  87. * this way will let our lines blend nicely with our curves. The
  88. * metric also dictates that we will never have one pixel turned on
  89. * directly above another that's turned on. We will also never have
  90. * a gap; i.e., there will be exactly one pixel turned on for each
  91. * column between the start and end points. All that remains to be
  92. * done is to decide how many pixels should be turned on for each row.
  93. *
  94. * So lines we draw will consist of varying numbers of pixels on
  95. * successive rows, for example:
  96. *
  97. * ******
  98. * *****
  99. * ******
  100. * *****
  101. *
  102. * We'll call each set of pixels on a row a "strip".
  103. *
  104. * (Please remember that our coordinate space has the origin as the
  105. * upper left pixel on the screen; postive y is down and positive x
  106. * is right.)
  107. *
  108. * Device coordinates are specified as fixed point 28.4 numbers,
  109. * where the first 28 bits are the integer coordinate, and the last
  110. * 4 bits are the fraction. So coordinates may be thought of as
  111. * having the form (x, y) = (M/F, N/F) where F is the constant scaling
  112. * factor F = 2^4 = 16, and M and N are 32 bit integers.
  113. *
  114. * Consider the line from (M0/F, N0/F) to (M1/F, N1/F) which runs
  115. * left-to-right and whose slope is in the first octant, and let
  116. * dM = M1 - M0 and dN = N1 - N0. Then dM >= 0, dN >= 0 and dM >= dN.
  117. *
  118. * Since the slope of the line is less than 1, the edges of the
  119. * drag region are created by the top and bottom vertices of the
  120. * diamond. At any given pixel row y of the line, we light those
  121. * pixels whose centers are between the left and right edges.
  122. *
  123. * Let mL(n) denote the line representing the left edge of the drag
  124. * region. On pixel row j, the column of the first pixel to be
  125. * lit is
  126. *
  127. * iL(j) = ceiling( mL(j * F) / F)
  128. *
  129. * Since the line's slope is less than one:
  130. *
  131. * iL(j) = ceiling( mL([j + 1/2] F) / F )
  132. *
  133. * Recall the formula for our line:
  134. *
  135. * n(m) = (dN / dM) (m - M0) + N0
  136. *
  137. * m(n) = (dM / dN) (n - N0) + M0
  138. *
  139. * Since the line's slope is less than one, the line representing
  140. * the left edge of the drag region is the original line offset
  141. * by 1/2 pixel in the y direction:
  142. *
  143. * mL(n) = (dM / dN) (n - F/2 - N0) + M0
  144. *
  145. * From this we can figure out the column of the first pixel that
  146. * will be lit on row j, being careful of rounding (if the left
  147. * edge lands exactly on an integer point, the pixel at that
  148. * point is not lit because of our rounding convention):
  149. *
  150. * iL(j) = floor( mL(j F) / F ) + 1
  151. *
  152. * = floor( ((dM / dN) (j F - F/2 - N0) + M0) / F ) + 1
  153. *
  154. * = floor( F dM j - F/2 dM - N0 dM + dN M0) / F dN ) + 1
  155. *
  156. * F dM j - [ dM (N0 + F/2) - dN M0 ]
  157. * = floor( ---------------------------------- ) + 1
  158. * F dN
  159. *
  160. * dM j - [ dM (N0 + F/2) - dN M0 ] / F
  161. * = floor( ------------------------------------ ) + 1 (1)
  162. * dN
  163. *
  164. * = floor( (dM j + alpha) / dN ) + 1
  165. *
  166. * where
  167. *
  168. * alpha = - [ dM (N0 + F/2) - dN M0 ] / F
  169. *
  170. * We use equation (1) to calculate the DDA: there are iL(j+1) - iL(j)
  171. * pixels in row j. Because we are always calculating iL(j) for
  172. * integer quantities of j, we note that the only fractional term
  173. * is constant, and so we can 'throw away' the fractional bits of
  174. * alpha:
  175. *
  176. * beta = floor( - [ dM (N0 + F/2) - dN M0 ] / F ) (2)
  177. *
  178. * so
  179. *
  180. * iL(j) = floor( (dM j + beta) / dN ) + 1 (3)
  181. *
  182. * for integers j.
  183. *
  184. * Note if iR(j) is the line's rightmost pixel on row j, that
  185. * iR(j) = iL(j + 1) - 1.
  186. *
  187. * Similarly, rewriting equation (1) as a function of column i,
  188. * we can determine, given column i, on which pixel row j is the line
  189. * lit:
  190. *
  191. * dN i + [ dM (N0 + F/2) - dN M0 ] / F
  192. * j(i) = ceiling( ------------------------------------ ) - 1
  193. * dM
  194. *
  195. * Floors are easier to compute, so we can rewrite this:
  196. *
  197. * dN i + [ dM (N0 + F/2) - dN M0 ] / F + dM - 1/F
  198. * j(i) = floor( ----------------------------------------------- ) - 1
  199. * dM
  200. *
  201. * dN i + [ dM (N0 + F/2) - dN M0 ] / F + dM - 1/F - dM
  202. * = floor( ---------------------------------------------------- )
  203. * dM
  204. *
  205. * dN i + [ dM (N0 + F/2) - dN M0 - 1 ] / F
  206. * = floor( ---------------------------------------- )
  207. * dM
  208. *
  209. * We can once again wave our hands and throw away the fractional bits
  210. * of the remainder term:
  211. *
  212. * j(i) = floor( (dN i + gamma) / dM ) (4)
  213. *
  214. * where
  215. *
  216. * gamma = floor( [ dM (N0 + F/2) - dN M0 - 1 ] / F ) (5)
  217. *
  218. * We now note that
  219. *
  220. * beta = -gamma - 1 = ~gamma (6)
  221. *
  222. * To draw the pixels of the line, we could evaluate (3) on every scan
  223. * line to determine where the strip starts. Of course, we don't want
  224. * to do that because that would involve a multiply and divide for every
  225. * scan. So we do everything incrementally.
  226. *
  227. * We would like to easily compute c , the number of pixels on scan j:
  228. * j
  229. *
  230. * c = iL(j + 1) - iL(j)
  231. * j
  232. *
  233. * = floor((dM (j + 1) + beta) / dN) - floor((dM j + beta) / dN) (7)
  234. *
  235. * This may be rewritten as
  236. *
  237. * c = floor(i + r / dN) - floor(i + r / dN) (8)
  238. * j j+1 j+1 j j
  239. *
  240. * where i , i are integers and r < dN, r < dN.
  241. * j j+1 j j+1
  242. *
  243. * Rewriting (7) again:
  244. *
  245. * c = floor(i + r / dN + dM / dN) - floor(i + r / dN)
  246. * j j j j j
  247. *
  248. *
  249. * = floor((r + dM) / dN) - floor(r / dN)
  250. * j j
  251. *
  252. * This may be rewritten as
  253. *
  254. * c = dI + floor((r + dR) / dN) - floor(r / dN)
  255. * j j j
  256. *
  257. * where dI + dR / dN = dM / dN, dI is an integer and dR < dN.
  258. *
  259. * r is the remainder (or "error") term in the DDA loop: r / dN
  260. * j j
  261. * is the exact fraction of a pixel at which the strip ends. To go
  262. * on to the next scan and compute c we need to know r .
  263. * j+1 j+1
  264. *
  265. * So in the main loop of the DDA:
  266. *
  267. * c = dI + floor((r + dR) / dN) and r = (r + dR) % dN
  268. * j j j+1 j
  269. *
  270. * and we know r < dN, r < dN, and dR < dN.
  271. * j j+1
  272. *
  273. * We have derived the DDA only for lines in the first octant; to
  274. * handle other octants we do the common trick of flipping the line
  275. * to the first octant by first making the line left-to-right by
  276. * exchanging the end-points, then flipping about the lines y = 0 and
  277. * y = x, as necessary. We must record the transformation so we can
  278. * undo them later.
  279. *
  280. * We must also be careful of how the flips affect our rounding. If
  281. * to get the line to the first octant we flipped about x = 0, we now
  282. * have to be careful to round a y value of 1/2 up instead of down as
  283. * we would for a line originally in the first octant (recall that
  284. * "In the case where two pels are equidistant, the upper or left
  285. * pel is illuminated...").
  286. *
  287. * To account for this rounding when running the DDA, we shift the line
  288. * (or not) in the y direction by the smallest amount possible. That
  289. * takes care of rounding for the DDA, but we still have to be careful
  290. * about the rounding when determining the first and last pixels to be
  291. * lit in the line.
  292. *
  293. * Determining The First And Last Pixels In The Line
  294. * -------------------------------------------------
  295. *
  296. * Fractional coordinates also make it harder to determine which pixels
  297. * will be the first and last ones in the line. We've already taken
  298. * the fractional coordinates into account in calculating the DDA, but
  299. * the DDA cannot tell us which are the end pixels because it is quite
  300. * happy to calculate pixels on the line from minus infinity to positive
  301. * infinity.
  302. *
  303. * The diamond rule determines the start and end pixels. (Recall that
  304. * the sides are exclusive except for the left and top vertices.)
  305. * This convention can be thought of in another way: there are diamonds
  306. * around the pixels, and wherever the true line crosses a diamond,
  307. * that pel is illuminated.
  308. *
  309. * Consider a line where we've done the flips to the first octant, and the
  310. * floor of the start coordinates is the origin:
  311. *
  312. * +-----------------------> +x
  313. * |
  314. * | 0 1
  315. * | 0123456789abcdef
  316. * |
  317. * | 0 00000000?1111111
  318. * | 1 00000000 1111111
  319. * | 2 0000000 111111
  320. * | 3 000000 11111
  321. * | 4 00000 ** 1111
  322. * | 5 0000 ****1
  323. * | 6 000 1***
  324. * | 7 00 1 ****
  325. * | 8 ? ***
  326. * | 9 22 3 ****
  327. * | a 222 33 ***
  328. * | b 2222 333 ****
  329. * | c 22222 3333 **
  330. * | d 222222 33333
  331. * | e 2222222 333333
  332. * | f 22222222 3333333
  333. * |
  334. * | 2 3
  335. * v
  336. * +y
  337. *
  338. * If the start of the line lands on the diamond around pixel 0 (shown by
  339. * the '0' region here), pixel 0 is the first pel in the line. The same
  340. * is true for the other pels.
  341. *
  342. * A little more work has to be done if the line starts in the
  343. * 'nether-land' between the diamonds (as illustrated by the '*' line):
  344. * the first pel lit is the first diamond crossed by the line (pixel 1 in
  345. * our example). This calculation is determined by the DDA or slope of
  346. * the line.
  347. *
  348. * If the line starts exactly half way between two adjacent pixels
  349. * (denoted here by the '?' spots), the first pixel is determined by our
  350. * round-down convention (and is dependent on the flips done to
  351. * normalize the line).
  352. *
  353. * Last Pel Exclusive
  354. * ------------------
  355. *
  356. * To eliminate repeatedly lit pels between continuous connected lines,
  357. * we employ a last-pel exclusive convention: if the line ends exactly on
  358. * the diamond around a pel, that pel is not lit. (This eliminates the
  359. * checks we had in the old code to see if we were re-lighting pels.)
  360. *
  361. * The Half Flip
  362. * -------------
  363. *
  364. * To make our run length algorithm more efficient, we employ a "half
  365. * flip". If after normalizing to the first octant, the slope is more
  366. * than 1/2, we subtract the y coordinate from the x coordinate. This
  367. * has the effect of reflecting the coordinates through the line of slope
  368. * 1/2. Note that the diagonal gets mapped into the x-axis after a half
  369. * flip.
  370. *
  371. * How Many Bits Do We Need, Anyway?
  372. * ---------------------------------
  373. *
  374. * Note that if the line is visible on your screen, you must light up
  375. * exactly the correct pixels, no matter where in the 28.4 x 28.4 device
  376. * space the end points of the line lie (meaning you must handle 32 bit
  377. * DDAs, you can certainly have optimized cases for lesser DDAs).
  378. *
  379. * We move the origin to (floor(M0 / F), floor(N0 / F)), so when we
  380. * calculate gamma from (5), we know that 0 <= M0, N0 < F. And we
  381. * are in the first octant, so dM >= dN. Then we know that gamma can
  382. * be in the range [(-1/2)dM, (3/2)dM]. The DDI guarantees us that
  383. * valid lines will have dM and dN values at most 31 bits (unsigned)
  384. * of significance. So gamma requires 33 bits of significance (we store
  385. * this as a 64 bit number for convenience).
  386. *
  387. * When running through the DDA loop, r + dR can have a value in the
  388. * j
  389. * range 0 <= r < 2 dN; thus the result must be a 32 bit unsigned value.
  390. * j
  391. *
  392. * History:
  393. * 4-May-1992 -by- J. Andrew Goossen [andrewgo]
  394. * Wrote it.
  395. \**************************************************************************/
  396. BOOL bLines(
  397. BMINFO* pbmi, // Info about pixel format
  398. POINTFIX* pptfxFirst, // Start of first line
  399. POINTFIX* pptfxBuf, // Pointer to buffer of all remaining lines
  400. RUN* prun, // Pointer to runs if doing complex clipping
  401. ULONG cptfx, // Count of points in pptfxBuf or runs in prun
  402. LINESTATE* pls, // Color and style info
  403. RECTL* prclClip, // Clip rectangle if doing simple clipping
  404. PFNSTRIP *apfn, // Array of strip functions
  405. FLONG flStart, // Flags for each line
  406. CHUNK* pchBits, // Pointer to bitmap
  407. LONG lDelta) // Offset between rows of pixels (in CHUNKs)
  408. {
  409. POINTFIX* pptfxBufEnd = pptfxBuf + cptfx; // Last point in path record
  410. STYLEPOS spThis;
  411. ULONG M0;
  412. ULONG dM;
  413. ULONG N0;
  414. ULONG dN;
  415. ULONG dN_Original;
  416. ULONG N1;
  417. ULONG M1;
  418. FLONG fl;
  419. LONG x;
  420. LONG y;
  421. LONGLONG eqGamma;
  422. LONGLONG eqBeta;
  423. ULONG ulDelta;
  424. ULONG x0;
  425. ULONG y0;
  426. ULONG x1;
  427. ULONG x0_Original;
  428. ULONG y0_Original;
  429. ULONG x1_Original;
  430. POINTL ptlStart;
  431. STRIP strip;
  432. PFNSTRIP pfn;
  433. LONG* plStripEnd;
  434. ULONGLONG euq; // Temporary unsigned double-dword variable
  435. LONGLONG eq; // Temporary signed double-dword variable
  436. do {
  437. /***********************************************************************\
  438. * Start the DDA calculations. *
  439. \***********************************************************************/
  440. M0 = (LONG) pptfxFirst->x;
  441. dM = (LONG) pptfxBuf->x;
  442. N0 = (LONG) pptfxFirst->y;
  443. dN = (LONG) pptfxBuf->y;
  444. fl = flStart;
  445. if ((LONG) dM < (LONG) M0)
  446. {
  447. // Ensure that we run left-to-right:
  448. register ULONG ulTmp;
  449. SWAPL(M0, dM, ulTmp);
  450. SWAPL(N0, dN, ulTmp);
  451. fl |= FL_FLIP_H;
  452. }
  453. // We now have a line running left-to-right from (M0, N0) to
  454. // (M0 + dM, N0 + dN):
  455. if ((LONG) dN < (LONG) N0)
  456. {
  457. // Line runs from bottom to top, so flip across y = 0:
  458. N0 = -(LONG) N0;
  459. dN = -(LONG) dN;
  460. fl |= FL_FLIP_V;
  461. }
  462. // Compute the deltas. The DDI says we can never have a valid delta
  463. // with a magnitude more than 2^31 - 1, but the engine never actually
  464. // checks its transforms. To ensure that we'll never puke on our shoes,
  465. // we check for that case and simply refuse to draw the line:
  466. dM -= M0;
  467. if ((LONG) dM < 0)
  468. goto Next_Line;
  469. dN -= N0;
  470. if ((LONG) dN < 0)
  471. goto Next_Line;
  472. if (dN >= dM)
  473. {
  474. if (dN == dM)
  475. {
  476. // Have to special case slopes of one:
  477. fl |= FL_FLIP_SLOPE_ONE;
  478. }
  479. else
  480. {
  481. // Since line has slope greater than 1, flip across x = y:
  482. register ULONG ulTmp;
  483. SWAPL(dM, dN, ulTmp);
  484. SWAPL(M0, N0, ulTmp);
  485. fl |= FL_FLIP_D;
  486. }
  487. }
  488. fl |= gaflRound[(fl & FL_ROUND_MASK) >> FL_ROUND_SHIFT];
  489. x = LFLOOR((LONG) M0);
  490. y = LFLOOR((LONG) N0);
  491. M0 = FXFRAC(M0);
  492. N0 = FXFRAC(N0);
  493. {
  494. // Calculate the remainder term [ dM * (N0 + F/2) - M0 * dN ]:
  495. eqGamma = Int32x32To64((LONG) dM, N0 + F/2);
  496. eq = Int32x32To64(M0, (LONG) dN);
  497. eqGamma -= eq;
  498. if (fl & FL_V_ROUND_DOWN)
  499. eqGamma -= 1L; // Adjust so y = 1/2 rounds down
  500. eqGamma >>= FLOG2;
  501. eqBeta = ~eqGamma;
  502. }
  503. /***********************************************************************\
  504. * Figure out which pixels are at the ends of the line. *
  505. \***********************************************************************/
  506. // Calculate x0, x1:
  507. N1 = FXFRAC(N0 + dN);
  508. M1 = FXFRAC(M0 + dM);
  509. x1 = LFLOOR(M0 + dM);
  510. // The toughest part of GIQ is determining the start and end pels.
  511. //
  512. // Our approach here is to calculate x0 and x1 (the inclusive start
  513. // and end columns of the line respectively, relative to our normalized
  514. // origin). Then x1 - x0 + 1 is the number of pels in the line. The
  515. // start point is easily calculated by plugging x0 into our line equation
  516. // (which takes care of whether y = 1/2 rounds up or down in value)
  517. // getting y0, and then undoing the normalizing flips to get back
  518. // into device space.
  519. //
  520. // We look at the fractional parts of the coordinates of the start and
  521. // end points, and call them (M0, N0) and (M1, N1) respectively, where
  522. // 0 <= M0, N0, M1, N1 < 16. We plot (M0, N0) on the following grid
  523. // to determine x0:
  524. //
  525. // +-----------------------> +x
  526. // |
  527. // | 0 1
  528. // | 0123456789abcdef
  529. // |
  530. // | 0 ........?xxxxxxx
  531. // | 1 ..........xxxxxx
  532. // | 2 ...........xxxxx
  533. // | 3 ............xxxx
  534. // | 4 .............xxx
  535. // | 5 ..............xx
  536. // | 6 ...............x
  537. // | 7 ................
  538. // | 8 ................
  539. // | 9 ......**........
  540. // | a ........****...x
  541. // | b ............****
  542. // | c .............xxx****
  543. // | d ............xxxx ****
  544. // | e ...........xxxxx ****
  545. // | f ..........xxxxxx
  546. // |
  547. // | 2 3
  548. // v
  549. //
  550. // +y
  551. //
  552. // This grid accounts for the appropriate rounding of GIQ and last-pel
  553. // exclusion. If (M0, N0) lands on an 'x', x0 = 2. If (M0, N0) lands
  554. // on a '.', x0 = 1. If (M0, N0) lands on a '?', x0 rounds up or down,
  555. // depending on what flips have been done to normalize the line.
  556. //
  557. // For the end point, if (M1, N1) lands on an 'x', x1 =
  558. // floor((M0 + dM) / 16) + 1. If (M1, N1) lands on a '.', x1 =
  559. // floor((M0 + dM)). If (M1, N1) lands on a '?', x1 rounds up or down,
  560. // depending on what flips have been done to normalize the line.
  561. //
  562. // Lines of exactly slope one require a special case for both the start
  563. // and end. For example, if the line ends such that (M1, N1) is (9, 1),
  564. // the line has gone exactly through (8, 0) -- which may be considered
  565. // to be part of 'x' because of rounding! So slopes of exactly slope
  566. // one going through (8, 0) must also be considered as belonging in 'x'.
  567. //
  568. // For lines that go left-to-right, we have the following grid:
  569. //
  570. // +-----------------------> +x
  571. // |
  572. // | 0 1
  573. // | 0123456789abcdef
  574. // |
  575. // | 0 xxxxxxxx?.......
  576. // | 1 xxxxxxx.........
  577. // | 2 xxxxxx..........
  578. // | 3 xxxxx...........
  579. // | 4 xxxx............
  580. // | 5 xxx.............
  581. // | 6 xx..............
  582. // | 7 x...............
  583. // | 8 x...............
  584. // | 9 x.....**........
  585. // | a xx......****....
  586. // | b xxx.........****
  587. // | c xxxx............****
  588. // | d xxxxx........... ****
  589. // | e xxxxxx.......... ****
  590. // | f xxxxxxx.........
  591. // |
  592. // | 2 3
  593. // v
  594. //
  595. // +y
  596. //
  597. // This grid accounts for the appropriate rounding of GIQ and last-pel
  598. // exclusion. If (M0, N0) lands on an 'x', x0 = 0. If (M0, N0) lands
  599. // on a '.', x0 = 1. If (M0, N0) lands on a '?', x0 rounds up or down,
  600. // depending on what flips have been done to normalize the line.
  601. //
  602. // For the end point, if (M1, N1) lands on an 'x', x1 =
  603. // floor((M0 + dM) / 16) - 1. If (M1, N1) lands on a '.', x1 =
  604. // floor((M0 + dM)). If (M1, N1) lands on a '?', x1 rounds up or down,
  605. // depending on what flips have been done to normalize the line.
  606. //
  607. // Lines of exactly slope one must be handled similarly to the right-to-
  608. // left case.
  609. if (fl & FL_FLIP_H)
  610. {
  611. // ---------------------------------------------------------------
  612. // Line runs right-to-left: <----
  613. // Compute x1:
  614. if (N1 == 0)
  615. {
  616. if (LROUND(M1, fl & FL_H_ROUND_DOWN))
  617. {
  618. x1++;
  619. }
  620. }
  621. else if (ABS((LONG) (N1 - F/2)) + M1 > F)
  622. {
  623. x1++;
  624. }
  625. if ((fl & (FL_FLIP_SLOPE_ONE | FL_H_ROUND_DOWN))
  626. == (FL_FLIP_SLOPE_ONE))
  627. {
  628. // Have to special-case diagonal lines going through our
  629. // the point exactly equidistant between two horizontal
  630. // pixels, if we're supposed to round x=1/2 down:
  631. if ((N1 > 0) && (M1 == N1 + 8))
  632. x1++;
  633. // Don't you love special cases? Is this a rhetorical question?
  634. if ((N0 > 0) && (M0 == N0 + 8))
  635. {
  636. x0 = 2;
  637. ulDelta = dN;
  638. goto right_to_left_compute_y0;
  639. }
  640. }
  641. // Compute x0:
  642. x0 = 1;
  643. ulDelta = 0;
  644. if (N0 == 0)
  645. {
  646. if (LROUND(M0, fl & FL_H_ROUND_DOWN))
  647. {
  648. x0 = 2;
  649. ulDelta = dN;
  650. }
  651. }
  652. else if (ABS((LONG) (N0 - F/2)) + M0 > F)
  653. {
  654. x0 = 2;
  655. ulDelta = dN;
  656. }
  657. // Compute y0:
  658. right_to_left_compute_y0:
  659. y0 = 0;
  660. eq = eqGamma;
  661. eq += (LONGLONG) (ULONGLONG) ulDelta;
  662. if ((eq >> 32) >= 0)
  663. {
  664. if ((eq >> 32) > 0 || (ULONG) eq >= 2 * dM - dN)
  665. y0 = 2;
  666. else if ((ULONG) eq >= dM - dN)
  667. y0 = 1;
  668. }
  669. }
  670. else
  671. {
  672. // ---------------------------------------------------------------
  673. // Line runs left-to-right: ---->
  674. //
  675. // Compute x1:
  676. x1--;
  677. if (M1 > 0)
  678. {
  679. if (N1 == 0)
  680. {
  681. if (LROUND(M1, fl & FL_H_ROUND_DOWN))
  682. x1++;
  683. }
  684. else if (ABS((LONG) (N1 - F/2)) <= (LONG) M1)
  685. {
  686. x1++;
  687. }
  688. }
  689. if ((fl & (FL_FLIP_SLOPE_ONE | FL_H_ROUND_DOWN))
  690. == (FL_FLIP_SLOPE_ONE | FL_H_ROUND_DOWN))
  691. {
  692. // Have to special-case diagonal lines going through our
  693. // the point exactly equidistant between two horizontal
  694. // pixels, if we're supposed to round x=1/2 down:
  695. if ((M1 > 0) && (N1 == M1 + 8))
  696. x1--;
  697. if ((M0 > 0) && (N0 == M0 + 8))
  698. {
  699. x0 = 0;
  700. goto left_to_right_compute_y0;
  701. }
  702. }
  703. // Compute x0:
  704. x0 = 0;
  705. if (M0 > 0)
  706. {
  707. if (N0 == 0)
  708. {
  709. if (LROUND(M0, fl & FL_H_ROUND_DOWN))
  710. x0 = 1;
  711. }
  712. else if (ABS((LONG) (N0 - F/2)) <= (LONG) M0)
  713. {
  714. x0 = 1;
  715. }
  716. }
  717. // Compute y0:
  718. left_to_right_compute_y0:
  719. y0 = 0;
  720. if ((eqGamma>>32) >= 0 &&
  721. (ULONG) eqGamma >= dM - (dN & (-(LONG) x0)))
  722. {
  723. y0 = 1;
  724. }
  725. }
  726. y0_Original = y0;
  727. x0_Original = x0;
  728. x1_Original = x1;
  729. if ((LONG) x1 < (LONG) x0)
  730. goto Next_Line;
  731. /***********************************************************************\
  732. * Complex Clipping. *
  733. \***********************************************************************/
  734. if (fl & FL_COMPLEX_CLIP)
  735. {
  736. dN_Original = dN;
  737. Continue_Complex_Clipping:
  738. if (fl & FL_FLIP_H)
  739. {
  740. // Line runs right-to-left <-----
  741. x0 = x1_Original - prun->iStop;
  742. x1 = x1_Original - prun->iStart;
  743. }
  744. else
  745. {
  746. // Line runs left-to-right ----->
  747. x0 = x0_Original + prun->iStart;
  748. x1 = x0_Original + prun->iStop;
  749. }
  750. prun++;
  751. // Reset some variables we'll nuke a little later:
  752. dN = dN_Original;
  753. pls->spNext = pls->spComplex;
  754. euq = UInt32x32To64(x0, dN);
  755. euq += eqGamma;
  756. y0 = DIV(euq,dM);
  757. }
  758. /***********************************************************************\
  759. * Style calculations. *
  760. \***********************************************************************/
  761. if (fl & FL_STYLED)
  762. {
  763. ULONG cpelStyleLine; // # of style pels in entire line
  764. ULONG cpelStyleFromThis; // # of style pels from first pel of line
  765. STYLEPOS sp; // Style state at x0
  766. // For those rare devices where xStep != yStep, for complex clipped
  767. // lines that are non-major styled and have multiple runs, we will
  768. // be doing more work than we have to:
  769. BOOL bOffStyled = FALSE;
  770. ULONG xStep = pls->xStep;
  771. ULONG yStep = pls->yStep;
  772. spThis = pls->spNext;
  773. if (fl & FL_FLIP_D)
  774. {
  775. register ULONG ulTmp;
  776. SWAPL(xStep, yStep, ulTmp);
  777. }
  778. if (xStep != yStep)
  779. {
  780. bOffStyled = UInt32x32To64(yStep, dN) > UInt32x32To64(xStep, dM);
  781. }
  782. // xStep is now the major style direction step size.
  783. if (bOffStyled)
  784. {
  785. ULONG y1_Original;
  786. // We need the original y1, so we simply compute it:
  787. euq = UInt32x32To64(x1_Original, dN);
  788. euq += eqGamma;
  789. y1_Original = DIV(euq,dM);
  790. // Our line is x-major but y-styled, or y-major and x-styled.
  791. // We use xStep as the style-major step size, so adjust it:
  792. xStep = yStep;
  793. pls->ulStepRun = 0;
  794. pls->ulStepSide = xStep;
  795. pls->ulStepDiag = xStep;
  796. cpelStyleLine = (y1_Original - y0_Original + 1);
  797. if (fl & FL_FLIP_H)
  798. cpelStyleFromThis = (y1_Original - y0 + 1);
  799. else
  800. cpelStyleFromThis = (y0 - y0_Original);
  801. }
  802. else
  803. {
  804. // Our line is x-major and x-styled, or y-major and y-styled:
  805. pls->ulStepRun = xStep;
  806. pls->ulStepSide = 0;
  807. pls->ulStepDiag = xStep;
  808. cpelStyleLine = (x1_Original - x0_Original + 1);
  809. if (fl & FL_FLIP_H)
  810. cpelStyleFromThis = (x1_Original - x0 + 1);
  811. else
  812. cpelStyleFromThis = (x0 - x0_Original);
  813. }
  814. // Note: we may overflow here if step size is more than 15:
  815. sp = pls->spNext + xStep * cpelStyleFromThis;
  816. pls->spNext = pls->spNext + xStep * cpelStyleLine;
  817. // Normalize (being sure to cast to unsigned values because
  818. // we want unsigned divides and positive results even if we
  819. // overflowed):
  820. if ((ULONG) sp >= (ULONG) pls->spTotal2)
  821. sp = (ULONG) sp % pls->spTotal2;
  822. if ((ULONG) pls->spNext >= (ULONG) pls->spTotal2)
  823. pls->spNext = (ULONG) pls->spNext % pls->spTotal2;
  824. // Since we always draw the line left-to-right, but styling is
  825. // always done in the direction of the original style, we have
  826. // to figure out where we are in the style array for the left
  827. // edge of this line:
  828. if (fl & FL_FLIP_H)
  829. {
  830. // Line originally ran right-to-left:
  831. sp = -sp;
  832. if (sp < 0)
  833. sp += pls->spTotal2;
  834. pls->bIsGap = !pls->bStartGap;
  835. pls->pspStart = &pls->aspRightToLeft[0];
  836. pls->pspEnd = &pls->aspRightToLeft[pls->cStyle - 1];
  837. }
  838. else
  839. {
  840. pls->bIsGap = pls->bStartGap;
  841. pls->pspStart = &pls->aspLeftToRight[0];
  842. pls->pspEnd = &pls->aspLeftToRight[pls->cStyle - 1];
  843. }
  844. // If the style array is of odd length, and we are on the second
  845. // (or fourth, or sixth...) pass of the style array, the sense
  846. // of the current array value is reversed (gap -> dash or dash
  847. // -> gap):
  848. if (sp >= pls->spTotal)
  849. {
  850. sp -= pls->spTotal;
  851. if (pls->cStyle & 1)
  852. pls->bIsGap = !pls->bIsGap;
  853. }
  854. // Find our position in the style array:
  855. pls->psp = pls->pspStart;
  856. while (sp >= *pls->psp)
  857. sp -= *pls->psp++;
  858. ASSERTGDI(pls->psp <= pls->pspEnd, "Flew into NeverNeverLand");
  859. pls->spRemaining = *pls->psp - sp;
  860. // Our position in the style array tells us if we're currently
  861. // working on a gap or a dash:
  862. if ((pls->psp - pls->pspStart) & 1)
  863. pls->bIsGap = !pls->bIsGap;
  864. }
  865. // Flip back to device space:
  866. ptlStart.x = x + x0;
  867. ptlStart.y = y + y0;
  868. if (fl & FL_FLIP_D)
  869. {
  870. register LONG lTmp;
  871. SWAPL(ptlStart.x, ptlStart.y, lTmp);
  872. }
  873. if (fl & FL_FLIP_V)
  874. {
  875. ptlStart.y = -ptlStart.y;
  876. }
  877. if (2 * dN > dM)
  878. {
  879. // Do a half flip!
  880. fl |= FL_FLIP_HALF;
  881. eqBeta = eqGamma;
  882. eqBeta -= (LONGLONG) (ULONGLONG) dM;
  883. dN = dM - dN;
  884. y0 = x0 - y0; // Note this may overflow, but that's okay
  885. }
  886. // Now, run the DDA starting at (ptlStart.x, ptlStart.y)!
  887. strip.flFlips = fl;
  888. pfn = apfn[(fl & FL_STRIP_MASK) >> FL_STRIP_SHIFT];
  889. strip.iPixel = ptlStart.x & pbmi->maskPixel;
  890. strip.lDelta = lDelta;
  891. strip.pchScreen = pchBits + ptlStart.y * lDelta;
  892. if (pbmi->cShift < 0)
  893. {
  894. // 24bpp takes the address of the first byte:
  895. strip.pchScreen = (CHUNK*) ((BYTE*) strip.pchScreen + ptlStart.x * 3);
  896. }
  897. else
  898. {
  899. // All other formats take the address of the first dword:
  900. strip.pchScreen += (ptlStart.x >> pbmi->cShift);
  901. }
  902. plStripEnd = &strip.alStrips[STRIP_MAX];
  903. // Now calculate the DDA variables needed to figure out how many pixels
  904. // go in the very first strip:
  905. {
  906. register LONG* plStrip = &strip.alStrips[0];
  907. register LONG cPels = x1 - x0 + 1;
  908. register LONG i;
  909. register ULONG r;
  910. register ULONG dI;
  911. register ULONG dR;
  912. if (dN == 0)
  913. i = LONG_MAX;
  914. else
  915. {
  916. euq = UInt32x32To64(y0 + 1, dM);
  917. euq += eqBeta;
  918. i = DIVREM(euq, dN, &r) - x0 + 1;
  919. dI = dM / dN;
  920. dR = dM % dN; // 0 <= dR < dN
  921. }
  922. ASSERTGDI(i > 0 && i <= LONG_MAX, "Weird start strip length");
  923. ASSERTGDI(cPels > 0, "Zero cPels");
  924. /***********************************************************************\
  925. * Run the DDA! *
  926. \***********************************************************************/
  927. while(TRUE)
  928. {
  929. cPels -= i;
  930. if (cPels <= 0)
  931. break;
  932. *plStrip++ = i;
  933. if (plStrip == plStripEnd)
  934. {
  935. //Sundown: safe to truncate to LONG since will not exceed cPels
  936. strip.cStrips = (LONG)(plStrip - &strip.alStrips[0]);
  937. (*pfn)(&strip, pbmi, pls);
  938. plStrip = &strip.alStrips[0];
  939. }
  940. i = dI;
  941. r += dR;
  942. if (r >= dN)
  943. {
  944. r -= dN;
  945. i++;
  946. }
  947. }
  948. *plStrip++ = cPels + i;
  949. //Sundown safe truncation.
  950. strip.cStrips = (LONG)(plStrip - &strip.alStrips[0]);
  951. (*pfn)(&strip, pbmi, pls);
  952. }
  953. Next_Line:
  954. // We're done with that run. Figure out what to do next:
  955. if (fl & FL_COMPLEX_CLIP)
  956. {
  957. cptfx--;
  958. if (cptfx != 0)
  959. goto Continue_Complex_Clipping;
  960. break;
  961. }
  962. else
  963. {
  964. pptfxFirst = pptfxBuf;
  965. pptfxBuf++;
  966. }
  967. } while (pptfxBuf < pptfxBufEnd);
  968. return(TRUE);
  969. }