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.

1373 lines
49 KiB

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