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.

1342 lines
48 KiB

  1. /******************************Module*Header***********************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: lines.c
  8. *
  9. * Contains the code for drawing short fractional endpoint lines and
  10. * longer lines with strips.
  11. *
  12. * Copyright (C) 1994-1998 3Dlabs Inc. Ltd. All rights reserved.
  13. * Copyright (C) 1995-1999 Microsoft Corporation. All rights reserved.
  14. ******************************************************************************/
  15. #include "precomp.h"
  16. #define SWAPL(x,y,t) {t = x; x = y; y = t;}
  17. #define ABS(a) ((a) < 0 ? -(a) : (a))
  18. FLONG gaflRound[] = {
  19. FL_H_ROUND_DOWN | FL_V_ROUND_DOWN, // no flips
  20. FL_H_ROUND_DOWN | FL_V_ROUND_DOWN, // FL_FLIP_D
  21. FL_H_ROUND_DOWN, // FL_FLIP_V
  22. FL_V_ROUND_DOWN, // FL_FLIP_V | FL_FLIP_D
  23. FL_V_ROUND_DOWN, // FL_FLIP_SLOPE_ONE
  24. 0xbaadf00d, // FL_FLIP_SLOPE_ONE | FL_FLIP_D
  25. FL_H_ROUND_DOWN, // FL_FLIP_SLOPE_ONE | FL_FLIP_V
  26. 0xbaadf00d // FL_FLIP_SLOPE_ONE | FL_FLIP_V
  27. // | FL_FLIP_D
  28. };
  29. BOOL bIntegerLine(PDev*, ULONG, ULONG, ULONG, ULONG);
  30. BOOL bHardwareLine(PDev*, POINTFIX*, POINTFIX*);
  31. //------------------------------------------------------------------------------
  32. //
  33. // BOOL bLines(ppdev, pptfxFirst, pptfxBuf, cptfx, pls,
  34. // prclClip, apfn[], flStart)
  35. //
  36. // Computes the DDA for the line and gets ready to draw it. Puts the
  37. // pixel data into an array of strips, and calls a strip routine to
  38. // do the actual drawing.
  39. //
  40. // Doing Lines Right
  41. // -----------------
  42. //
  43. // In NT, all lines are given to the device driver in fractional
  44. // coordinates, in a 28.4 fixed point format. The lower 4 bits are
  45. // fractional for sub-pixel positioning.
  46. //
  47. // Note that you CANNOT! just round the coordinates to integers
  48. // and pass the results to your favorite integer Bresenham routine!!
  49. // (Unless, of course, you have such a high resolution device that
  50. // nobody will notice -- not likely for a display device.) The
  51. // fractions give a more accurate rendering of the line -- this is
  52. // important for things like our Bezier curves, which would have 'kinks'
  53. // if the points in its polyline approximation were rounded to integers.
  54. //
  55. // Unfortunately, for fractional lines there is more setup work to do
  56. // a DDA than for integer lines. However, the main loop is exactly
  57. // the same (and can be done entirely with 32 bit math).
  58. //
  59. // If You've Got Hardware That Does Bresenham
  60. // ------------------------------------------
  61. //
  62. // A lot of hardware limits DDA error terms to 'n' bits. With fractional
  63. // coordinates, 4 bits are given to the fractional part, letting
  64. // you draw in hardware only those lines that lie entirely in a 2^(n-4)
  65. // by 2^(n-4) pixel space.
  66. //
  67. // And you still have to correctly draw those lines with coordinates
  68. // outside that space! Remember that the screen is only a viewport
  69. // onto a 28.4 by 28.4 space -- if any part of the line is visible
  70. // you MUST render it precisely, regardless of where the end points lie.
  71. // So even if you do it in software, somewhere you'll have to have a
  72. // 32 bit DDA routine.
  73. //
  74. // Our Implementation
  75. // ------------------
  76. //
  77. // We employ a run length slice algorithm: our DDA calculates the
  78. // number of pixels that are in each row (or 'strip') of pixels.
  79. //
  80. // We've separated the running of the DDA and the drawing of pixels:
  81. // we run the DDA for several iterations and store the results in
  82. // a 'strip' buffer (which are the lengths of consecutive pixel rows of
  83. // the line), then we crank up a 'strip drawer' that will draw all the
  84. // strips in the buffer.
  85. //
  86. // We also employ a 'half-flip' to reduce the number of strip
  87. // iterations we need to do in the DDA and strip drawing loops: when a
  88. // (normalized) line's slope is more than 1/2, we do a final flip
  89. // about the line y = (1/2)x. So now, instead of each strip being
  90. // consecutive horizontal or vertical pixel rows, each strip is composed
  91. // of those pixels aligned in 45 degree rows. So a line like (0, 0) to
  92. // (128, 128) would generate only one strip.
  93. //
  94. // We also always draw only left-to-right.
  95. //
  96. // Style lines may have arbitrary style patterns. We specially
  97. // optimize the default patterns (and call them 'masked' styles).
  98. //
  99. // The DDA Derivation
  100. // ------------------
  101. //
  102. // Here is how I like to think of the DDA calculation.
  103. //
  104. // We employ Knuth's "diamond rule": rendering a one-pixel-wide line
  105. // can be thought of as dragging a one-pixel-wide by one-pixel-high
  106. // diamond along the true line. Pixel centers lie on the integer
  107. // coordinates, and so we light any pixel whose center gets covered
  108. // by the "drag" region (John D. Hobby, Journal of the Association
  109. // for Computing Machinery, Vol. 36, No. 2, April 1989, pp. 209-229).
  110. //
  111. // We must define which pixel gets lit when the true line falls
  112. // exactly half-way between two pixels. In this case, we follow
  113. // the rule: when two pels are equidistant, the upper or left pel
  114. // is illuminated, unless the slope is exactly one, in which case
  115. // the upper or right pel is illuminated. (So we make the edges
  116. // of the diamond exclusive, except for the top and left vertices,
  117. // which are inclusive, unless we have slope one.)
  118. //
  119. // This metric decides what pixels should be on any line BEFORE it is
  120. // flipped around for our calculation. Having a consistent metric
  121. // this way will let our lines blend nicely with our curves. The
  122. // metric also dictates that we will never have one pixel turned on
  123. // directly above another that's turned on. We will also never have
  124. // a gap; i.e., there will be exactly one pixel turned on for each
  125. // column between the start and end points. All that remains to be
  126. // done is to decide how many pixels should be turned on for each row.
  127. //
  128. // So lines we draw will consist of varying numbers of pixels on
  129. // successive rows, for example:
  130. //
  131. // ******
  132. // *****
  133. // ******
  134. // *****
  135. //
  136. // We'll call each set of pixels on a row a "strip".
  137. //
  138. // (Please remember that our coordinate space has the origin as the
  139. // upper left pixel on the screen; postive y is down and positive x
  140. // is right.)
  141. //
  142. // Device coordinates are specified as fixed point 28.4 numbers,
  143. // where the first 28 bits are the integer coordinate, and the last
  144. // 4 bits are the fraction. So coordinates may be thought of as
  145. // having the form (x, y) = (M/F, N/F) where F is the constant scaling
  146. // factor F = 2^4 = 16, and M and N are 32 bit integers.
  147. //
  148. // Consider the line from (M0/F, N0/F) to (M1/F, N1/F) which runs
  149. // left-to-right and whose slope is in the first octant, and let
  150. // dM = M1 - M0 and dN = N1 - N0. Then dM >= 0, dN >= 0 and dM >= dN.
  151. //
  152. // Since the slope of the line is less than 1, the edges of the
  153. // drag region are created by the top and bottom vertices of the
  154. // diamond. At any given pixel row y of the line, we light those
  155. // pixels whose centers are between the left and right edges.
  156. //
  157. // Let mL(n) denote the line representing the left edge of the drag
  158. // region. On pixel row j, the column of the first pixel to be
  159. // lit is
  160. //
  161. // iL(j) = ceiling( mL(j * F) / F)
  162. //
  163. // Since the line's slope is less than one:
  164. //
  165. // iL(j) = ceiling( mL([j + 1/2] F) / F )
  166. //
  167. // Recall the formula for our line:
  168. //
  169. // n(m) = (dN / dM) (m - M0) + N0
  170. //
  171. // m(n) = (dM / dN) (n - N0) + M0
  172. //
  173. // Since the line's slope is less than one, the line representing
  174. // the left edge of the drag region is the original line offset
  175. // by 1/2 pixel in the y direction:
  176. //
  177. // mL(n) = (dM / dN) (n - F/2 - N0) + M0
  178. //
  179. // From this we can figure out the column of the first pixel that
  180. // will be lit on row j, being careful of rounding (if the left
  181. // edge lands exactly on an integer point, the pixel at that
  182. // point is not lit because of our rounding convention):
  183. //
  184. // iL(j) = floor( mL(j F) / F ) + 1
  185. //
  186. // = floor( ((dM / dN) (j F - F/2 - N0) + M0) / F ) + 1
  187. //
  188. // = floor( F dM j - F/2 dM - N0 dM + dN M0) / F dN ) + 1
  189. //
  190. // F dM j - [ dM (N0 + F/2) - dN M0 ]
  191. // = floor( ---------------------------------- ) + 1
  192. // F dN
  193. //
  194. // dM j - [ dM (N0 + F/2) - dN M0 ] / F
  195. // = floor( ------------------------------------ ) + 1 (1)
  196. // dN
  197. //
  198. // = floor( (dM j + alpha) / dN ) + 1
  199. //
  200. // where
  201. //
  202. // alpha = - [ dM (N0 + F/2) - dN M0 ] / F
  203. //
  204. // We use equation (1) to calculate the DDA: there are iL(j+1) - iL(j)
  205. // pixels in row j. Because we are always calculating iL(j) for
  206. // integer quantities of j, we note that the only fractional term
  207. // is constant, and so we can 'throw away' the fractional bits of
  208. // alpha:
  209. //
  210. // beta = floor( - [ dM (N0 + F/2) - dN M0 ] / F ) (2)
  211. //
  212. // so
  213. //
  214. // iL(j) = floor( (dM j + beta) / dN ) + 1 (3)
  215. //
  216. // for integers j.
  217. //
  218. // Note if iR(j) is the line's rightmost pixel on row j, that
  219. // iR(j) = iL(j + 1) - 1.
  220. //
  221. // Similarly, rewriting equation (1) as a function of column i,
  222. // we can determine, given column i, on which pixel row j is the line
  223. // lit:
  224. //
  225. // dN i + [ dM (N0 + F/2) - dN M0 ] / F
  226. // j(i) = ceiling( ------------------------------------ ) - 1
  227. // dM
  228. //
  229. // Floors are easier to compute, so we can rewrite this:
  230. //
  231. // dN i + [ dM (N0 + F/2) - dN M0 ] / F + dM - 1/F
  232. // j(i) = floor( ----------------------------------------------- ) - 1
  233. // dM
  234. //
  235. // dN i + [ dM (N0 + F/2) - dN M0 ] / F + dM - 1/F - dM
  236. // = floor( ---------------------------------------------------- )
  237. // dM
  238. //
  239. // dN i + [ dM (N0 + F/2) - dN M0 - 1 ] / F
  240. // = floor( ---------------------------------------- )
  241. // dM
  242. //
  243. // We can once again wave our hands and throw away the fractional bits
  244. // of the remainder term:
  245. //
  246. // j(i) = floor( (dN i + gamma) / dM ) (4)
  247. //
  248. // where
  249. //
  250. // gamma = floor( [ dM (N0 + F/2) - dN M0 - 1 ] / F ) (5)
  251. //
  252. // We now note that
  253. //
  254. // beta = -gamma - 1 = ~gamma (6)
  255. //
  256. // To draw the pixels of the line, we could evaluate (3) on every scan
  257. // line to determine where the strip starts. Of course, we don't want
  258. // to do that because that would involve a multiply and divide for every
  259. // scan. So we do everything incrementally.
  260. //
  261. // We would like to easily compute c , the number of pixels on scan j:
  262. // j
  263. //
  264. // c = iL(j + 1) - iL(j)
  265. // j
  266. //
  267. // = floor((dM (j + 1) + beta) / dN) - floor((dM j + beta) / dN) (7)
  268. //
  269. // This may be rewritten as
  270. //
  271. // c = floor(i + r / dN) - floor(i + r / dN) (8)
  272. // j j+1 j+1 j j
  273. //
  274. // where i , i are integers and r < dN, r < dN.
  275. // j j+1 j j+1
  276. //
  277. // Rewriting (7) again:
  278. //
  279. // c = floor(i + r / dN + dM / dN) - floor(i + r / dN)
  280. // j j j j j
  281. //
  282. //
  283. // = floor((r + dM) / dN) - floor(r / dN)
  284. // j j
  285. //
  286. // This may be rewritten as
  287. //
  288. // c = dI + floor((r + dR) / dN) - floor(r / dN)
  289. // j j j
  290. //
  291. // where dI + dR / dN = dM / dN, dI is an integer and dR < dN.
  292. //
  293. // r is the remainder (or "error") term in the DDA loop: r / dN
  294. // j j
  295. // is the exact fraction of a pixel at which the strip ends. To go
  296. // on to the next scan and compute c we need to know r .
  297. // j+1 j+1
  298. //
  299. // So in the main loop of the DDA:
  300. //
  301. // c = dI + floor((r + dR) / dN) and r = (r + dR) % dN
  302. // j j j+1 j
  303. //
  304. // and we know r < dN, r < dN, and dR < dN.
  305. // j j+1
  306. //
  307. // We have derived the DDA only for lines in the first octant; to
  308. // handle other octants we do the common trick of flipping the line
  309. // to the first octant by first making the line left-to-right by
  310. // exchanging the end-points, then flipping about the lines y = 0 and
  311. // y = x, as necessary. We must record the transformation so we can
  312. // undo them later.
  313. //
  314. // We must also be careful of how the flips affect our rounding. If
  315. // to get the line to the first octant we flipped about x = 0, we now
  316. // have to be careful to round a y value of 1/2 up instead of down as
  317. // we would for a line originally in the first octant (recall that
  318. // "In the case where two pels are equidistant, the upper or left
  319. // pel is illuminated...").
  320. //
  321. // To account for this rounding when running the DDA, we shift the line
  322. // (or not) in the y direction by the smallest amount possible. That
  323. // takes care of rounding for the DDA, but we still have to be careful
  324. // about the rounding when determining the first and last pixels to be
  325. // lit in the line.
  326. //
  327. // Determining The First And Last Pixels In The Line
  328. // -------------------------------------------------
  329. //
  330. // Fractional coordinates also make it harder to determine which pixels
  331. // will be the first and last ones in the line. We've already taken
  332. // the fractional coordinates into account in calculating the DDA, but
  333. // the DDA cannot tell us which are the end pixels because it is quite
  334. // happy to calculate pixels on the line from minus infinity to positive
  335. // infinity.
  336. //
  337. // The diamond rule determines the start and end pixels. (Recall that
  338. // the sides are exclusive except for the left and top vertices.)
  339. // This convention can be thought of in another way: there are diamonds
  340. // around the pixels, and wherever the true line crosses a diamond,
  341. // that pel is illuminated.
  342. //
  343. // Consider a line where we've done the flips to the first octant, and the
  344. // floor of the start coordinates is the origin:
  345. //
  346. // +-----------------------> +x
  347. // |
  348. // | 0 1
  349. // | 0123456789abcdef
  350. // |
  351. // | 0 00000000?1111111
  352. // | 1 00000000 1111111
  353. // | 2 0000000 111111
  354. // | 3 000000 11111
  355. // | 4 00000 ** 1111
  356. // | 5 0000 ****1
  357. // | 6 000 1***
  358. // | 7 00 1 ****
  359. // | 8 ? ***
  360. // | 9 22 3 ****
  361. // | a 222 33 ***
  362. // | b 2222 333 ****
  363. // | c 22222 3333 **
  364. // | d 222222 33333
  365. // | e 2222222 333333
  366. // | f 22222222 3333333
  367. // |
  368. // | 2 3
  369. // v
  370. // +y
  371. //
  372. // If the start of the line lands on the diamond around pixel 0 (shown by
  373. // the '0' region here), pixel 0 is the first pel in the line. The same
  374. // is true for the other pels.
  375. //
  376. // A little more work has to be done if the line starts in the
  377. // 'nether-land' between the diamonds (as illustrated by the '*' line):
  378. // the first pel lit is the first diamond crossed by the line (pixel 1 in
  379. // our example). This calculation is determined by the DDA or slope of
  380. // the line.
  381. //
  382. // If the line starts exactly half way between two adjacent pixels
  383. // (denoted here by the '?' spots), the first pixel is determined by our
  384. // round-down convention (and is dependent on the flips done to
  385. // normalize the line).
  386. //
  387. // Last Pel Exclusive
  388. // ------------------
  389. //
  390. // To eliminate repeatedly lit pels between continuous connected lines,
  391. // we employ a last-pel exclusive convention: if the line ends exactly on
  392. // the diamond around a pel, that pel is not lit. (This eliminates the
  393. // checks we had in the old code to see if we were re-lighting pels.)
  394. //
  395. // The Half Flip
  396. // -------------
  397. //
  398. // To make our run length algorithm more efficient, we employ a "half
  399. // flip". If after normalizing to the first octant, the slope is more
  400. // than 1/2, we subtract the y coordinate from the x coordinate. This
  401. // has the effect of reflecting the coordinates through the line of slope
  402. // 1/2. Note that the diagonal gets mapped into the x-axis after a half
  403. // flip.
  404. //
  405. // How Many Bits Do We Need, Anyway?
  406. // ---------------------------------
  407. //
  408. // Note that if the line is visible on your screen, you must light up
  409. // exactly the correct pixels, no matter where in the 28.4 x 28.4 device
  410. // space the end points of the line lie (meaning you must handle 32 bit
  411. // DDAs, you can certainly have optimized cases for lesser DDAs).
  412. //
  413. // We move the origin to (floor(M0 / F), floor(N0 / F)), so when we
  414. // calculate gamma from (5), we know that 0 <= M0, N0 < F. And we
  415. // are in the first octant, so dM >= dN. Then we know that gamma can
  416. // be in the range [(-1/2)dM, (3/2)dM]. The DDI guarantees us that
  417. // valid lines will have dM and dN values at most 31 bits (unsigned)
  418. // of significance. So gamma requires 33 bits of significance (we store
  419. // this as a 64 bit number for convenience).
  420. //
  421. // When running through the DDA loop, r + dR can have a value in the
  422. // j
  423. // range 0 <= r < 2 dN; thus the result must be a 32 bit unsigned value.
  424. // j
  425. //
  426. // Testing Lines
  427. // -------------
  428. //
  429. // To be NT compliant, a display driver must exactly adhere to GIQ,
  430. // which means that for any given line, the driver must light exactly
  431. // the same pels as does GDI. This can be tested using the Guiman tool
  432. // provided elsewhere in the DDK, and 'ZTest', which draws random lines
  433. // on the screen and to a bitmap, and compares the results.
  434. //
  435. // If You've Got Line Hardware
  436. // ---------------------------
  437. //
  438. // If your hardware already adheres to GIQ, you're all set. Otherwise
  439. // you'll want to look at the S3 sample code and read the following:
  440. //
  441. // 1) You'll want to special case integer-only lines, since they require
  442. // less processing time and are more common (CAD programs will probably
  443. // only ever give integer lines). GDI does not provide a flag saying
  444. // that all lines in a path are integer lines; consequently, you will
  445. // have to explicitly check every line.
  446. //
  447. // 2) You are required to correctly draw any line in the 28.4 device
  448. // space that intersects the viewport. If you have less than 32 bits
  449. // of significance in the hardware for the Bresenham terms, extremely
  450. // long lines would overflow the hardware. For such (rare) cases, you
  451. // can fall back to strip-drawing code, of which there is a C version in
  452. // the S3's lines.cxx (or if your display is a frame buffer, fall back
  453. // to the engine).
  454. //
  455. // 3) If you can explicitly set the Bresenham terms in your hardware, you
  456. // can draw non-integer lines using the hardware. If your hardware has
  457. // 'n' bits of precision, you can draw GIQ lines that are up to 2^(n-5)
  458. // pels long (4 bits are required for the fractional part, and one bit is
  459. // used as a sign bit). Note that integer lines don't require the 4
  460. // fractional bits, so if you special case them as in 1), you can do
  461. // integer lines that are up to 2^(n - 1) pels long. See the S3's
  462. // fastline.asm for an example.
  463. //
  464. //------------------------------------------------------------------------------
  465. BOOL
  466. bLines(PDev* ppdev,
  467. POINTFIX* pptfxFirst, // Start of first line
  468. POINTFIX* pptfxBuf, // Pointer to buffer of all remaining lines
  469. RUN* prun, // Pointer to runs if doing complex clipping
  470. ULONG cptfx, // Number of points in pptfxBuf or number of runs
  471. // in prun
  472. LINESTATE* pls, // Colour and style info
  473. RECTL* prclClip, // Pointer to clip rectangle if doing simple
  474. // clipping
  475. PFNSTRIP apfn[], // Array of strip functions
  476. FLONG flStart) // Flags for each line
  477. {
  478. ULONG M0;
  479. ULONG dM;
  480. ULONG N0;
  481. ULONG dN;
  482. ULONG dN_Original;
  483. FLONG fl;
  484. LONG x;
  485. LONG y;
  486. LONGLONG llBeta;
  487. LONGLONG llGamma;
  488. LONGLONG dl;
  489. LONGLONG ll;
  490. ULONG ulDelta;
  491. ULONG x0;
  492. ULONG y0;
  493. ULONG x1;
  494. ULONG cStylePels; // Major length of line in pixels for styling
  495. ULONG xStart;
  496. POINTL ptlStart;
  497. STRIP strip;
  498. PFNSTRIP pfn;
  499. LONG cPels;
  500. LONG* plStrip;
  501. LONG* plStripEnd;
  502. LONG cStripsInNextRun;
  503. POINTFIX* pptfxBufEnd = pptfxBuf + cptfx - 1; // Last point in path record
  504. STYLEPOS spThis; // Style pos for this line
  505. LONG xmask = 0xffff800f;
  506. LONG ymask = 0xffffc00f;
  507. LONG xmask1 = 0xffff8000;
  508. LONG ymask1 = 0xffffc000;
  509. PERMEDIA_DECL;
  510. do
  511. {
  512. //
  513. // Start the DDA calculations
  514. //
  515. M0 = (LONG) pptfxFirst->x;
  516. dM = (LONG) pptfxBuf->x;
  517. N0 = (LONG) pptfxFirst->y;
  518. dN = (LONG) pptfxBuf->y;
  519. fl = flStart;
  520. //
  521. // Check for non-complex-clipped, non-styled integer endpoint lines
  522. // Essentially, we allow rendering of any line which 'looks' like an
  523. // unclipped solid line. Initialization of hardware will cause the
  524. // correct results to appear
  525. //
  526. if ((fl & (FL_COMPLEX_CLIP | FL_STYLED)) == 0 )
  527. {
  528. LONG orx = (LONG) (M0 | dM);
  529. LONG ory = (LONG) (N0 | dN);
  530. if (orx < 0)
  531. {
  532. // At least one point was negative. Compute using abs points.
  533. orx = ABS((LONG)M0) | ABS((LONG)dM);
  534. }
  535. if (ory < 0)
  536. {
  537. // At least one point was negative. Compute using abs points.
  538. ory = ABS((LONG)N0) | ABS((LONG)dN);
  539. }
  540. DBG_GDI((7, "Lines: Trying Fast Integer %x %x %x %x",
  541. M0, N0, dM, dN));
  542. // Call fast integer line routines it integer coordinates
  543. if (((orx & xmask) == 0) && ((ory & ymask) == 0))
  544. {
  545. if (bFastIntegerLine(ppdev, M0, N0, dM, dN))
  546. {
  547. if ((fl & FL_READ))
  548. {
  549. // If we have a logical op which requires reading from
  550. // the frame buffer, we cannot guarantee
  551. // ContinueNewLine's behaviour when overwriting pixels.
  552. // Also, avoid ContinueNewLine on an MX.
  553. pptfxFirst = pptfxBuf;
  554. pptfxBuf++;
  555. continue;
  556. }
  557. else
  558. {
  559. // This is an optimization to use continue new line
  560. // to draw any subequent integer lines. The loop is
  561. // essentially the same as the outer loop, however, we
  562. // dont need to check for a lot of things that we already
  563. // know. We need to be able to fall out to the standard
  564. // outer loop if we cant handle a line though.
  565. while (TRUE)
  566. {
  567. // Have we reached the end of the list of points.
  568. if (pptfxBuf == pptfxBufEnd)
  569. return(TRUE);
  570. pptfxFirst = pptfxBuf;
  571. pptfxBuf++;
  572. M0 = dM;
  573. N0 = dN;
  574. dM = (LONG) pptfxBuf->x;
  575. dN = (LONG) pptfxBuf->y;
  576. // We know M0 and N0 satisfy our criteria for a
  577. // continue new line. Therefore, we just have to
  578. // check the new coordinates
  579. orx = (LONG) dM;
  580. ory = (LONG) dN;
  581. if (orx < 0)
  582. {
  583. // At least one point was negative.
  584. // Recompute or using abs.
  585. orx = ABS((LONG)dM);
  586. }
  587. if (ory < 0)
  588. {
  589. // At least one point was negative.
  590. // Recompute or using abs.
  591. ory = ABS((LONG)dN);
  592. }
  593. // We need to call the routine to continue
  594. // the line now. If the line is not a fast integer
  595. // line, then we need to break out and try non
  596. // integer lines. In this case, or will still be
  597. // valid, because we know M0, N0 are integer coords
  598. // that Permedia2 can handle.
  599. DBG_GDI((7, "Lines: Trying %x %x %x %x",
  600. M0, N0, dM, dN));
  601. if (((orx & xmask) != 0) ||
  602. ((ory & ymask) != 0) ||
  603. (!bFastIntegerContinueLine(
  604. ppdev, M0, N0, dM, dN)))
  605. // Either we cant draw the line or the strip
  606. // drawer failed.
  607. break;
  608. }
  609. }
  610. }
  611. }
  612. // Call fast non integer line routines.
  613. if (((orx & xmask1) == 0) && ((ory & ymask1) == 0))
  614. {
  615. if (bFastLine(ppdev, M0, N0, dM, dN))
  616. {
  617. // This line done, do next line.
  618. pptfxFirst = pptfxBuf;
  619. pptfxBuf++;
  620. continue;
  621. }
  622. }
  623. }
  624. DBG_GDI((7, "Lines: Slow Lines %x %x %x %x", M0, N0, dM, dN));
  625. if ((LONG) M0 > (LONG) dM)
  626. {
  627. // Ensure that we run left-to-right:
  628. register ULONG ulTmp;
  629. SWAPL(M0, dM, ulTmp);
  630. SWAPL(N0, dN, ulTmp);
  631. fl |= FL_FLIP_H;
  632. }
  633. // Compute the delta dx. The DDI says we can never have a valid delta
  634. // with a magnitude more than 2^31 - 1, but GDI never actually checks
  635. // its transforms. So we have to check for this case to avoid overflow:
  636. dM -= M0;
  637. if ((LONG) dM < 0) // We can skip any lines with delta > 2^31 - 1
  638. {
  639. goto Next_Line;
  640. }
  641. if ((LONG) dN < (LONG) N0)
  642. {
  643. // Line runs from bottom to top, so flip across y = 0:
  644. N0 = -(LONG) N0;
  645. dN = -(LONG) dN;
  646. fl |= FL_FLIP_V;
  647. }
  648. dN -= N0;
  649. if ((LONG) dN < 0) // We can skip any lines with delta > 2^31 - 1
  650. {
  651. goto Next_Line;
  652. }
  653. // We now have a line running left-to-right, top-to-bottom from (M0, N0)
  654. // to (M0 + dM, N0 + dN):
  655. if (dN >= dM)
  656. {
  657. if (dN == dM)
  658. {
  659. // Have to special case slopes of one:
  660. fl |= FL_FLIP_SLOPE_ONE;
  661. }
  662. else
  663. {
  664. // Since line has slope greater than 1, flip across x = y:
  665. register ULONG ulTmp;
  666. SWAPL(dM, dN, ulTmp);
  667. SWAPL(M0, N0, ulTmp);
  668. fl |= FL_FLIP_D;
  669. }
  670. }
  671. fl |= gaflRound[(fl & FL_ROUND_MASK) >> FL_ROUND_SHIFT];
  672. //
  673. // Convert M0 and N0 from 28.4 format to normal interger
  674. //
  675. x = LFLOOR((LONG)M0);
  676. y = LFLOOR((LONG)N0);
  677. M0 = FXFRAC(M0);
  678. N0 = FXFRAC(N0);
  679. // Calculate the remainder term [ dM * (N0 + F/2) - M0 * dN ]:
  680. llGamma = Int32x32To64(dM, N0 + FBITS/2) - Int32x32To64(M0, dN);
  681. if (fl & FL_V_ROUND_DOWN) // Adjust so y = 1/2 rounds down
  682. {
  683. llGamma--;
  684. }
  685. llGamma >>= FLOG2;
  686. llBeta = ~llGamma;
  687. //
  688. // Figure out which pixels are at the ends of the line.
  689. //
  690. // The toughest part of GIQ is determining the start and end pels.
  691. //
  692. // Our approach here is to calculate x0 and x1 (the inclusive start
  693. // and end columns of the line respectively, relative to our normalized
  694. // origin). Then x1 - x0 + 1 is the number of pels in the line. The
  695. // start point is easily calculated by plugging x0 into our line equation
  696. // (which takes care of whether y = 1/2 rounds up or down in value)
  697. // getting y0, and then undoing the normalizing flips to get back
  698. // into device space.
  699. //
  700. // We look at the fractional parts of the coordinates of the start and
  701. // end points, and call them (M0, N0) and (M1, N1) respectively, where
  702. // 0 <= M0, N0, M1, N1 < 16. We plot (M0, N0) on the following grid
  703. // to determine x0:
  704. //
  705. // +-----------------------> +x
  706. // |
  707. // | 0 1
  708. // | 0123456789abcdef
  709. // |
  710. // | 0 ........?xxxxxxx
  711. // | 1 ..........xxxxxx
  712. // | 2 ...........xxxxx
  713. // | 3 ............xxxx
  714. // | 4 .............xxx
  715. // | 5 ..............xx
  716. // | 6 ...............x
  717. // | 7 ................
  718. // | 8 ................
  719. // | 9 ......**........
  720. // | a ........****...x
  721. // | b ............****
  722. // | c .............xxx****
  723. // | d ............xxxx ****
  724. // | e ...........xxxxx ****
  725. // | f ..........xxxxxx
  726. // |
  727. // | 2 3
  728. // v
  729. //
  730. // +y
  731. //
  732. // This grid accounts for the appropriate rounding of GIQ and last-pel
  733. // exclusion. If (M0, N0) lands on an 'x', x0 = 2. If (M0, N0) lands
  734. // on a '.', x0 = 1. If (M0, N0) lands on a '?', x0 rounds up or down,
  735. // depending on what flips have been done to normalize the line.
  736. //
  737. // For the end point, if (M1, N1) lands on an 'x', x1 =
  738. // floor((M0 + dM) / 16) + 1. If (M1, N1) lands on a '.', x1 =
  739. // floor((M0 + dM)). If (M1, N1) lands on a '?', x1 rounds up or down,
  740. // depending on what flips have been done to normalize the line.
  741. //
  742. // Lines of exactly slope one require a special case for both the start
  743. // and end. For example, if the line ends such that (M1, N1) is (9, 1),
  744. // the line has gone exactly through (8, 0) -- which may be considered
  745. // to be part of 'x' because of rounding! So slopes of exactly slope
  746. // one going through (8, 0) must also be considered as belonging in 'x'.
  747. //
  748. // For lines that go left-to-right, we have the following grid:
  749. //
  750. // +-----------------------> +x
  751. // |
  752. // | 0 1
  753. // | 0123456789abcdef
  754. // |
  755. // | 0 xxxxxxxx?.......
  756. // | 1 xxxxxxx.........
  757. // | 2 xxxxxx..........
  758. // | 3 xxxxx...........
  759. // | 4 xxxx............
  760. // | 5 xxx.............
  761. // | 6 xx..............
  762. // | 7 x...............
  763. // | 8 x...............
  764. // | 9 x.....**........
  765. // | a xx......****....
  766. // | b xxx.........****
  767. // | c xxxx............****
  768. // | d xxxxx........... ****
  769. // | e xxxxxx.......... ****
  770. // | f xxxxxxx.........
  771. // |
  772. // | 2 3
  773. // v
  774. //
  775. // +y
  776. //
  777. // This grid accounts for the appropriate rounding of GIQ and last-pel
  778. // exclusion. If (M0, N0) lands on an 'x', x0 = 0. If (M0, N0) lands
  779. // on a '.', x0 = 1. If (M0, N0) lands on a '?', x0 rounds up or down,
  780. // depending on what flips have been done to normalize the line.
  781. //
  782. // For the end point, if (M1, N1) lands on an 'x', x1 =
  783. // floor((M0 + dM) / 16) - 1. If (M1, N1) lands on a '.', x1 =
  784. // floor((M0 + dM)). If (M1, N1) lands on a '?', x1 rounds up or down,
  785. // depending on what flips have been done to normalize the line.
  786. //
  787. // Lines of exactly slope one must be handled similarly to the right-to-
  788. // left case.
  789. {
  790. // Calculate x0, x1
  791. ULONG N1 = FXFRAC(N0 + dN);
  792. ULONG M1 = FXFRAC(M0 + dM);
  793. //
  794. // Store normal integer in x1, not 28.4 format
  795. //
  796. x1 = LFLOOR(M0 + dM);
  797. if (fl & FL_FLIP_H)
  798. {
  799. // Line runs right-to-left: <----
  800. // Compute x1:
  801. if (N1 == 0)
  802. {
  803. if (LROUND(M1, fl & FL_H_ROUND_DOWN))
  804. {
  805. x1++;
  806. }
  807. }
  808. else if (ABS((LONG) (N1 - FBITS/2)) + M1 > FBITS)
  809. {
  810. x1++;
  811. }
  812. if ((fl & (FL_FLIP_SLOPE_ONE | FL_H_ROUND_DOWN))
  813. == (FL_FLIP_SLOPE_ONE))
  814. {
  815. // Have to special-case diagonal lines going through our
  816. // the point exactly equidistant between two horizontal
  817. // pixels, if we're supposed to round x=1/2 down:
  818. if ((N1 > 0) && (M1 == N1 + 8))
  819. x1++;
  820. if ((N0 > 0) && (M0 == N0 + 8))
  821. {
  822. x0 = 2;
  823. ulDelta = dN;
  824. goto right_to_left_compute_y0;
  825. }
  826. }
  827. // Compute x0:
  828. x0 = 1;
  829. ulDelta = 0;
  830. if (N0 == 0)
  831. {
  832. if (LROUND(M0, fl & FL_H_ROUND_DOWN))
  833. {
  834. x0 = 2;
  835. ulDelta = dN;
  836. }
  837. }
  838. else if (ABS((LONG) (N0 - FBITS/2)) + M0 > FBITS)
  839. {
  840. x0 = 2;
  841. ulDelta = dN;
  842. }
  843. // Compute y0:
  844. right_to_left_compute_y0:
  845. y0 = 0;
  846. ll = llGamma + (LONGLONG) ulDelta;
  847. if (ll >= (LONGLONG) (2 * dM - dN))
  848. y0 = 2;
  849. else if (ll >= (LONGLONG) (dM - dN))
  850. y0 = 1;
  851. }
  852. else
  853. {
  854. // ---------------------------------------------------------------
  855. // Line runs left-to-right: ---->
  856. // Compute x1:
  857. x1--;
  858. if (M1 > 0)
  859. {
  860. if (N1 == 0)
  861. {
  862. if (LROUND(M1, fl & FL_H_ROUND_DOWN))
  863. x1++;
  864. }
  865. else if (ABS((LONG) (N1 - FBITS/2)) <= (LONG) M1)
  866. {
  867. x1++;
  868. }
  869. }
  870. if ((fl & (FL_FLIP_SLOPE_ONE | FL_H_ROUND_DOWN))
  871. == (FL_FLIP_SLOPE_ONE | FL_H_ROUND_DOWN))
  872. {
  873. // Have to special-case diagonal lines going through our
  874. // the point exactly equidistant between two horizontal
  875. // pixels, if we're supposed to round x=1/2 down:
  876. if ((M1 > 0) && (N1 == M1 + 8))
  877. x1--;
  878. if ((M0 > 0) && (N0 == M0 + 8))
  879. {
  880. x0 = 0;
  881. goto left_to_right_compute_y0;
  882. }
  883. }
  884. // Compute x0:
  885. x0 = 0;
  886. if (M0 > 0)
  887. {
  888. if (N0 == 0)
  889. {
  890. if (LROUND(M0, fl & FL_H_ROUND_DOWN))
  891. x0 = 1;
  892. }
  893. else if (ABS((LONG) (N0 - FBITS/2)) <= (LONG) M0)
  894. {
  895. x0 = 1;
  896. }
  897. }
  898. // Compute y0:
  899. left_to_right_compute_y0:
  900. y0 = 0;
  901. if (llGamma >= (LONGLONG) (dM - (dN & (-(LONG) x0))))
  902. {
  903. y0 = 1;
  904. }
  905. }
  906. }
  907. cStylePels = x1 - x0 + 1;
  908. if ((LONG) cStylePels <= 0)
  909. goto Next_Line;
  910. xStart = x0;
  911. //
  912. // Complex clipping. *
  913. //
  914. if (fl & FL_COMPLEX_CLIP)
  915. {
  916. dN_Original = dN;
  917. Continue_Complex_Clipping:
  918. if (fl & FL_FLIP_H)
  919. {
  920. // Line runs right-to-left <-----
  921. x0 = xStart + cStylePels - prun->iStop - 1;
  922. x1 = xStart + cStylePels - prun->iStart - 1;
  923. }
  924. else
  925. {
  926. // Line runs left-to-right ----->
  927. x0 = xStart + prun->iStart;
  928. x1 = xStart + prun->iStop;
  929. }
  930. prun++;
  931. // Reset some variables we'll nuke a little later:
  932. dN = dN_Original;
  933. pls->spNext = pls->spComplex;
  934. // No overflow since large integer math is used. Both values
  935. // will be positive:
  936. dl = Int32x32To64(x0, dN) + llGamma;
  937. y0 = UInt64Div32To32(dl, dM);
  938. ASSERTDD((LONG) y0 >= 0, "y0 weird: Goofed up end pel calc?");
  939. }
  940. //
  941. // Simple rectangular clipping.
  942. //
  943. if (fl & FL_SIMPLE_CLIP)
  944. {
  945. ULONG y1;
  946. LONG xRight;
  947. LONG xLeft;
  948. LONG yBottom;
  949. LONG yTop;
  950. // Note that y0 and y1 are actually the lower and upper bounds,
  951. // respectively, of the y coordinates of the line (the line may
  952. // have actually shrunk due to first/last pel clipping).
  953. //
  954. // Also note that x0, y0 are not necessarily zero.
  955. RECTL* prcl = &prclClip[(fl & FL_RECTLCLIP_MASK) >>
  956. FL_RECTLCLIP_SHIFT];
  957. // Normalize to the same point we've normalized for the DDA
  958. // calculations:
  959. xRight = prcl->right - x;
  960. xLeft = prcl->left - x;
  961. yBottom = prcl->bottom - y;
  962. yTop = prcl->top - y;
  963. if (yBottom <= (LONG) y0 ||
  964. xRight <= (LONG) x0 ||
  965. xLeft > (LONG) x1)
  966. {
  967. Totally_Clipped:
  968. if (fl & FL_STYLED)
  969. {
  970. pls->spNext += cStylePels;
  971. if (pls->spNext >= pls->spTotal2)
  972. pls->spNext %= pls->spTotal2;
  973. }
  974. goto Next_Line;
  975. }
  976. if ((LONG) x1 >= xRight)
  977. x1 = xRight - 1;
  978. // We have to know the correct y1, which we haven't bothered to
  979. // calculate up until now. This multiply and divide is quite
  980. // expensive; we could replace it with code similar to that which
  981. // we used for computing y0.
  982. //
  983. // The reason why we need the actual value, and not an upper
  984. // bounds guess like y1 = LFLOOR(dM) + 2 is that we have to be
  985. // careful when calculating x(y) that y0 <= y <= y1, otherwise
  986. // we can overflow on the divide (which, needless to say, is very
  987. // bad).
  988. dl = Int32x32To64(x1, dN) + llGamma;
  989. y1 = UInt64Div32To32(dl, dM);
  990. if (yTop > (LONG) y1)
  991. goto Totally_Clipped;
  992. if (yBottom <= (LONG) y1)
  993. {
  994. y1 = yBottom;
  995. dl = Int32x32To64(y1, dM) + llBeta;
  996. x1 = UInt64Div32To32(dl, dN);
  997. }
  998. // At this point, we've taken care of calculating the intercepts
  999. // with the right and bottom edges. Now we work on the left and
  1000. // top edges:
  1001. if (xLeft > (LONG) x0)
  1002. {
  1003. x0 = xLeft;
  1004. dl = Int32x32To64(x0, dN) + llGamma;
  1005. y0 = UInt64Div32To32(dl, dM);
  1006. if (yBottom <= (LONG) y0)
  1007. goto Totally_Clipped;
  1008. }
  1009. if (yTop > (LONG) y0)
  1010. {
  1011. y0 = yTop;
  1012. dl = Int32x32To64(y0, dM) + llBeta;
  1013. x0 = UInt64Div32To32(dl, dN) + 1;
  1014. if (xRight <= (LONG) x0)
  1015. goto Totally_Clipped;
  1016. }
  1017. ASSERTDD(x0 <= x1, "Improper rectangle clip");
  1018. }
  1019. //
  1020. // Done clipping. Unflip if necessary.
  1021. //
  1022. ptlStart.x = x + x0;
  1023. ptlStart.y = y + y0;
  1024. if (fl & FL_FLIP_D)
  1025. {
  1026. register LONG lTmp;
  1027. SWAPL(ptlStart.x, ptlStart.y, lTmp);
  1028. }
  1029. if (fl & FL_FLIP_V)
  1030. {
  1031. ptlStart.y = -ptlStart.y;
  1032. }
  1033. cPels = x1 - x0 + 1;
  1034. // Style calculations.
  1035. if (fl & FL_STYLED)
  1036. {
  1037. STYLEPOS sp;
  1038. spThis = pls->spNext;
  1039. pls->spNext += cStylePels;
  1040. {
  1041. if (pls->spNext >= pls->spTotal2)
  1042. pls->spNext %= pls->spTotal2;
  1043. if (fl & FL_FLIP_H)
  1044. sp = pls->spNext - x0 + xStart;
  1045. else
  1046. sp = spThis + x0 - xStart;
  1047. ASSERTDD(fl & FL_ARBITRARYSTYLED, "Oops");
  1048. // Normalize our target style position:
  1049. if ((sp < 0) || (sp >= pls->spTotal2))
  1050. {
  1051. sp %= pls->spTotal2;
  1052. // The modulus of a negative number is not well-defined
  1053. // in C -- if it's negative we'll adjust it so that it's
  1054. // back in the range [0, spTotal2):
  1055. if (sp < 0)
  1056. sp += pls->spTotal2;
  1057. }
  1058. // Since we always draw the line left-to-right, but styling is
  1059. // always done in the direction of the original line, we have
  1060. // to figure out where we are in the style array for the left
  1061. // edge of this line.
  1062. if (fl & FL_FLIP_H)
  1063. {
  1064. // Line originally ran right-to-left:
  1065. sp = -sp;
  1066. if (sp < 0)
  1067. sp += pls->spTotal2;
  1068. pls->ulStyleMask = ~pls->ulStartMask;
  1069. pls->pspStart = &pls->aspRtoL[0];
  1070. pls->pspEnd = &pls->aspRtoL[pls->cStyle - 1];
  1071. }
  1072. else
  1073. {
  1074. // Line originally ran left-to-right:
  1075. pls->ulStyleMask = pls->ulStartMask;
  1076. pls->pspStart = &pls->aspLtoR[0];
  1077. pls->pspEnd = &pls->aspLtoR[pls->cStyle - 1];
  1078. }
  1079. if (sp >= pls->spTotal)
  1080. {
  1081. sp -= pls->spTotal;
  1082. if (pls->cStyle & 1)
  1083. pls->ulStyleMask = ~pls->ulStyleMask;
  1084. }
  1085. pls->psp = pls->pspStart;
  1086. while (sp >= *pls->psp)
  1087. sp -= *pls->psp++;
  1088. ASSERTDD(pls->psp <= pls->pspEnd,
  1089. "Flew off into NeverNeverLand");
  1090. pls->spRemaining = *pls->psp - sp;
  1091. if ((pls->psp - pls->pspStart) & 1)
  1092. pls->ulStyleMask = ~pls->ulStyleMask;
  1093. }
  1094. }
  1095. plStrip = &strip.alStrips[0];
  1096. plStripEnd = &strip.alStrips[STRIP_MAX]; // Is exclusive
  1097. cStripsInNextRun = 0x7fffffff;
  1098. strip.ptlStart = ptlStart;
  1099. if (2 * dN > dM &&
  1100. !(fl & FL_STYLED) &&
  1101. !(fl & FL_DONT_DO_HALF_FLIP))
  1102. {
  1103. // Do a half flip! Remember that we may doing this on the
  1104. // same line multiple times for complex clipping (meaning the
  1105. // affected variables should be reset for every clip run):
  1106. fl |= FL_FLIP_HALF;
  1107. llBeta = llGamma - (LONGLONG) ((LONG) dM);
  1108. dN = dM - dN;
  1109. y0 = x0 - y0; // Note this may overflow, but that's okay
  1110. }
  1111. // Now, run the DDA starting at (ptlStart.x, ptlStart.y)!
  1112. strip.flFlips = fl;
  1113. pfn = apfn[(fl & FL_STRIP_MASK) >> FL_STRIP_SHIFT];
  1114. // Now calculate the DDA variables needed to figure out how many pixels
  1115. // go in the very first strip:
  1116. {
  1117. register LONG i;
  1118. register ULONG dI;
  1119. register ULONG dR;
  1120. ULONG r;
  1121. if (dN == 0)
  1122. i = 0x7fffffff;
  1123. else
  1124. {
  1125. dl = Int32x32To64(y0 + 1, dM) + llBeta;
  1126. ASSERTDD(dl >= 0, "Oops!");
  1127. i = UInt64Div32To32(dl, dN);
  1128. r = UInt64Mod32To32(dl, dN);
  1129. i = i - x0 + 1;
  1130. dI = dM / dN;
  1131. dR = dM % dN; // 0 <= dR < dN
  1132. ASSERTDD(dI > 0, "Weird dI");
  1133. }
  1134. ASSERTDD(i > 0 && i <= 0x7fffffff, "Weird initial strip length");
  1135. ASSERTDD(cPels > 0, "Zero pel line");
  1136. //
  1137. // Run the DDA! *
  1138. //
  1139. while (TRUE)
  1140. {
  1141. cPels -= i;
  1142. if (cPels <= 0)
  1143. break;
  1144. *plStrip++ = i;
  1145. if (plStrip == plStripEnd)
  1146. {
  1147. strip.cStrips = (LONG)(plStrip - &strip.alStrips[0]);
  1148. (*pfn)(ppdev, &strip, pls);
  1149. plStrip = &strip.alStrips[0];
  1150. }
  1151. i = dI;
  1152. r += dR;
  1153. if (r >= dN)
  1154. {
  1155. r -= dN;
  1156. i++;
  1157. }
  1158. }
  1159. *plStrip++ = cPels + i;
  1160. strip.cStrips = (LONG)(plStrip - &strip.alStrips[0]);
  1161. (*pfn)(ppdev, &strip, pls);
  1162. }
  1163. Next_Line:
  1164. if (fl & FL_COMPLEX_CLIP)
  1165. {
  1166. cptfx--;
  1167. if (cptfx != 0)
  1168. goto Continue_Complex_Clipping;
  1169. break;
  1170. }
  1171. else
  1172. {
  1173. pptfxFirst = pptfxBuf;
  1174. pptfxBuf++;
  1175. }
  1176. } while (pptfxBuf <= pptfxBufEnd);
  1177. return(TRUE);
  1178. }// bLines()