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.

1462 lines
98 KiB

  1. /*
  2. ** Macros and externs used by genline.c
  3. */
  4. extern ULONG FASTCALL __fastLineComputeColorRGB4(__GLcontext *gc, __GLcolor *color);
  5. extern ULONG FASTCALL __fastLineComputeColorRGB8(__GLcontext *gc, __GLcolor *color);
  6. extern ULONG FASTCALL __fastLineComputeColorRGB(__GLcontext *gc, __GLcolor *color);
  7. extern ULONG FASTCALL __fastLineComputeColorCI4and8(__GLcontext *gc, __GLcolor *color);
  8. extern ULONG FASTCALL __fastLineComputeColorCI(__GLcontext *gc, __GLcolor *color);
  9. extern void FASTCALL __fastGenLineBegin(__GLcontext *gc);
  10. extern void FASTCALL __fastGenLineEnd(__GLcontext *gc);
  11. extern void FASTCALL __fastGenLine(__GLcontext *gc, __GLvertex *v0,
  12. __GLvertex *v1, GLuint flags);
  13. extern void FASTCALL __fastGenLineWide(__GLcontext *gc, __GLvertex *v0,
  14. __GLvertex *v1, GLuint flags);
  15. BOOL FASTCALL __fastGenLineSetupDisplay(__GLcontext *gc);
  16. void FASTCALL __glQueryLineAcceleration(__GLcontext *gc);
  17. BOOL FASTCALL __glGenSetupEitherLines(__GLcontext *gc);
  18. /*
  19. ** float-to-fix macro converts floats to 28.4
  20. */
  21. #define __FAST_LINE_FLTTOFIX(x) ((long)((x) * 16.0f))
  22. // Converts a floating-point coordinate to an appropriate device coordinate
  23. #ifdef _CLIENTSIDE_
  24. #define __FAST_LINE_FLTTODEV(x) ((long)(x))
  25. #define __FAST_LINE_UNIT_VALUE 1
  26. #else
  27. #define __FAST_LINE_FLTTODEV(x) __FAST_LINE_FLTTOFIX(x)
  28. #define __FAST_LINE_UNIT_VALUE 16
  29. #endif
  30. /*
  31. ** line-stroking macros for DIB surfaces
  32. */
  33. #ifdef NT_NO_BUFFER_INVARIANCE
  34. BOOL FASTCALL __fastGenLineSetupDIB(__GLcontext *gc);
  35. /*
  36. ** __FAST_LINE_STROKE_DIB
  37. **
  38. ** Strokes a thin solid line into a DIB surface. Performs scissoring.
  39. ** Works for 8, 16, and 32 BPP
  40. **
  41. */
  42. #define __FAST_LINE_STROKE_DIB \
  43. { \
  44. len = gc->line.options.numPixels; \
  45. fraction = gc->line.options.fraction; \
  46. dfraction = gc->line.options.dfraction; \
  47. \
  48. if (!gc->transform.reasonableViewport) { \
  49. GLint clipX0, clipX1, clipY0, clipY1; \
  50. GLint xStart, yStart, xEnd, yEnd; \
  51. GLint xLittle, yLittle, xBig, yBig; \
  52. GLint highWord, lowWord, bigs, littles; \
  53. \
  54. clipX0 = gc->transform.clipX0; \
  55. clipX1 = gc->transform.clipX1; \
  56. clipY0 = gc->transform.clipY0; \
  57. clipY1 = gc->transform.clipY1; \
  58. \
  59. xBig = gc->line.options.xBig; \
  60. yBig = gc->line.options.yBig; \
  61. \
  62. xStart = gc->line.options.xStart; \
  63. yStart = gc->line.options.yStart; \
  64. \
  65. /* If the start point is in the scissor region, we attempt to \
  66. ** trivially accept the line. \
  67. */ \
  68. if (xStart >= clipX0 && xStart < clipX1 && \
  69. yStart >= clipY0 && yStart < clipY1) { \
  70. \
  71. len--; /* Makes our math simpler */ \
  72. /* Trivial accept attempt */ \
  73. xEnd = xStart + xBig * len; \
  74. yEnd = yStart + yBig * len; \
  75. if (xEnd >= clipX0 && xEnd < clipX1 && \
  76. yEnd >= clipY0 && yEnd < clipY1) { \
  77. len++; \
  78. goto no_scissor; \
  79. } \
  80. \
  81. xLittle = gc->line.options.xLittle; \
  82. yLittle = gc->line.options.yLittle; \
  83. \
  84. /* \
  85. ** Invert negative minor slopes so we can assume \
  86. ** dfraction > 0 \
  87. */ \
  88. if (dfraction < 0) { \
  89. dfraction = -dfraction; \
  90. fraction = 0x7fffffff - fraction; \
  91. } \
  92. \
  93. /* Now we compute number of littles and bigs in this line */\
  94. \
  95. /* We perform a 16 by 32 bit multiply. Ugh. */ \
  96. highWord = (((GLuint) dfraction) >> 16) * len + \
  97. (((GLuint) fraction) >> 16); \
  98. lowWord = (dfraction & 0xffff) * len + (fraction & 0xffff); \
  99. highWord += (((GLuint) lowWord) >> 16); \
  100. bigs = ((GLuint) highWord) >> 15; \
  101. littles = len - bigs; \
  102. \
  103. /* Second trivial accept attempt */ \
  104. xEnd = xStart + xBig*bigs + xLittle*littles; \
  105. yEnd = yStart + yBig*bigs + yLittle*littles; \
  106. if (xEnd >= clipX0 && xEnd < clipX1 && \
  107. yEnd >= clipY0 && yEnd < clipY1) { \
  108. len++; \
  109. goto no_scissor; \
  110. } \
  111. len++; /* Restore len */ \
  112. } else { \
  113. xLittle = gc->line.options.xLittle; \
  114. yLittle = gc->line.options.yLittle; \
  115. } \
  116. \
  117. /* \
  118. ** The line needs to be scissored. \
  119. ** Well, it should only happen rarely, so we can afford \
  120. ** to make it slow. We achieve this by tediously stippling the \
  121. ** line. (rather than clipping it, of course, which would be \
  122. ** faster but harder). \
  123. */ \
  124. \
  125. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  126. RECTL rcl; \
  127. \
  128. xEnd = x + xBig * (len - 1); \
  129. yEnd = y + yBig * (len - 1); \
  130. \
  131. if (x < xEnd) { \
  132. rcl.left = x; \
  133. rcl.right = xEnd + 1; \
  134. } else { \
  135. rcl.left = xEnd; \
  136. rcl.right = x + 1; \
  137. } \
  138. if (y < yEnd) { \
  139. rcl.top = y; \
  140. rcl.bottom = yEnd + 1; \
  141. } else { \
  142. rcl.top = yEnd; \
  143. rcl.bottom = y + 1; \
  144. } \
  145. switch (wglRectVisible(&rcl)) { \
  146. case WGL_RECT_ALL: \
  147. goto scissor_no_complex; \
  148. break; \
  149. case WGL_RECT_NONE: \
  150. goto no_draw; \
  151. break; \
  152. } \
  153. \
  154. /* Line is partially visible, check each pixel */ \
  155. \
  156. while (--len >= 0) { \
  157. if (wglPixelVisible(x, y) && \
  158. xStart >= clipX0 && xStart < clipX1 && \
  159. yStart >= clipY0 && yStart < clipY1) { \
  160. *addr = pixel; \
  161. } \
  162. fraction += dfraction; \
  163. if (fraction < 0) { \
  164. fraction &= ~0x80000000; \
  165. x += xBig; \
  166. y += yBig; \
  167. xStart += xBig; \
  168. yStart += yBig; \
  169. addr += addrBig; \
  170. } else { \
  171. x += xLittle; \
  172. y += yLittle; \
  173. xStart += xLittle; \
  174. yStart += yLittle; \
  175. addr += addrLittle; \
  176. } \
  177. } \
  178. } else { \
  179. scissor_no_complex: \
  180. while (--len >= 0) { \
  181. if (xStart >= clipX0 && xStart < clipX1 && \
  182. yStart >= clipY0 && yStart < clipY1) { \
  183. *addr = pixel; \
  184. } \
  185. fraction += dfraction; \
  186. if (fraction < 0) { \
  187. fraction &= ~0x80000000; \
  188. xStart += xBig; \
  189. yStart += yBig; \
  190. addr += addrBig; \
  191. } else { \
  192. xStart += xLittle; \
  193. yStart += yLittle; \
  194. addr += addrLittle; \
  195. } \
  196. } \
  197. } \
  198. } else { \
  199. no_scissor: \
  200. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  201. RECTL rcl; \
  202. GLint xEnd, yEnd, xBig, yBig, xLittle, yLittle; \
  203. \
  204. xBig = gc->line.options.xBig; \
  205. yBig = gc->line.options.yBig; \
  206. xLittle = gc->line.options.xLittle; \
  207. yLittle = gc->line.options.yLittle; \
  208. \
  209. xEnd = x + xBig * (len - 1); \
  210. yEnd = y + yBig * (len - 1); \
  211. \
  212. if (x < xEnd) { \
  213. rcl.left = x; \
  214. rcl.right = xEnd + 1; \
  215. } else { \
  216. rcl.left = xEnd; \
  217. rcl.right = x + 1; \
  218. } \
  219. if (y < yEnd) { \
  220. rcl.top = y; \
  221. rcl.bottom = yEnd + 1; \
  222. } else { \
  223. rcl.top = yEnd; \
  224. rcl.bottom = y + 1; \
  225. } \
  226. switch (wglRectVisible(&rcl)) { \
  227. case WGL_RECT_ALL: \
  228. goto no_complex; \
  229. break; \
  230. case WGL_RECT_NONE: \
  231. goto no_draw; \
  232. break; \
  233. } \
  234. \
  235. /* Line is partially visible, check each pixel */ \
  236. \
  237. while (--len >= 0) { \
  238. if (wglPixelVisible(x, y)) \
  239. *addr = pixel; \
  240. \
  241. fraction += dfraction; \
  242. if (fraction < 0) { \
  243. fraction &= ~0x80000000; \
  244. x += xBig; \
  245. y += yBig; \
  246. addr += addrBig; \
  247. } else { \
  248. x += xLittle; \
  249. y += yLittle; \
  250. addr += addrLittle; \
  251. } \
  252. } \
  253. } else { \
  254. no_complex: \
  255. while (--len >= 0) { \
  256. *addr = pixel; \
  257. \
  258. fraction += dfraction; \
  259. if (fraction < 0) { \
  260. fraction &= ~0x80000000; \
  261. addr += addrBig; \
  262. } else { \
  263. addr += addrLittle; \
  264. } \
  265. } \
  266. } \
  267. } \
  268. no_draw:; \
  269. }
  270. /*
  271. ** __FAST_LINE_STROKE_DIB24
  272. **
  273. ** Strokes a thin solid line into a DIB surface. Performs scissoring.
  274. ** Works for 24 BPP
  275. **
  276. */
  277. #define __FAST_LINE_STROKE_DIB24 \
  278. { \
  279. len = gc->line.options.numPixels; \
  280. fraction = gc->line.options.fraction; \
  281. dfraction = gc->line.options.dfraction; \
  282. \
  283. if (!gc->transform.reasonableViewport) { \
  284. GLint clipX0, clipX1, clipY0, clipY1; \
  285. GLint xStart, yStart, xEnd, yEnd; \
  286. GLint xLittle, yLittle, xBig, yBig; \
  287. GLint highWord, lowWord, bigs, littles; \
  288. \
  289. clipX0 = gc->transform.clipX0; \
  290. clipX1 = gc->transform.clipX1; \
  291. clipY0 = gc->transform.clipY0; \
  292. clipY1 = gc->transform.clipY1; \
  293. \
  294. xBig = gc->line.options.xBig; \
  295. yBig = gc->line.options.yBig; \
  296. \
  297. xStart = gc->line.options.xStart; \
  298. yStart = gc->line.options.yStart; \
  299. \
  300. /* If the start point is in the scissor region, we attempt to \
  301. ** trivially accept the line. \
  302. */ \
  303. if (xStart >= clipX0 && xStart < clipX1 && \
  304. yStart >= clipY0 && yStart < clipY1) { \
  305. \
  306. len--; /* Makes our math simpler */ \
  307. /* Trivial accept attempt */ \
  308. xEnd = xStart + xBig * len; \
  309. yEnd = yStart + yBig * len; \
  310. if (xEnd >= clipX0 && xEnd < clipX1 && \
  311. yEnd >= clipY0 && yEnd < clipY1) { \
  312. len++; \
  313. goto no_scissor; \
  314. } \
  315. \
  316. xLittle = gc->line.options.xLittle; \
  317. yLittle = gc->line.options.yLittle; \
  318. \
  319. /* \
  320. ** Invert negative minor slopes so we can assume \
  321. ** dfraction > 0 \
  322. */ \
  323. if (dfraction < 0) { \
  324. dfraction = -dfraction; \
  325. fraction = 0x7fffffff - fraction; \
  326. } \
  327. \
  328. /* Now we compute number of littles and bigs in this line */\
  329. \
  330. /* We perform a 16 by 32 bit multiply. Ugh. */ \
  331. highWord = (((GLuint) dfraction) >> 16) * len + \
  332. (((GLuint) fraction) >> 16); \
  333. lowWord = (dfraction & 0xffff) * len + (fraction & 0xffff); \
  334. highWord += (((GLuint) lowWord) >> 16); \
  335. bigs = ((GLuint) highWord) >> 15; \
  336. littles = len - bigs; \
  337. \
  338. /* Second trivial accept attempt */ \
  339. xEnd = xStart + xBig*bigs + xLittle*littles; \
  340. yEnd = yStart + yBig*bigs + yLittle*littles; \
  341. if (xEnd >= clipX0 && xEnd < clipX1 && \
  342. yEnd >= clipY0 && yEnd < clipY1) { \
  343. len++; \
  344. goto no_scissor; \
  345. } \
  346. len++; /* Restore len */ \
  347. } else { \
  348. xLittle = gc->line.options.xLittle; \
  349. yLittle = gc->line.options.yLittle; \
  350. } \
  351. \
  352. /* \
  353. ** The line needs to be scissored. \
  354. ** Well, it should only happen rarely, so we can afford \
  355. ** to make it slow. We achieve this by tediously stippling the \
  356. ** line. (rather than clipping it, of course, which would be \
  357. ** faster but harder). \
  358. */ \
  359. \
  360. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  361. RECTL rcl; \
  362. \
  363. xEnd = x + xBig * (len - 1); \
  364. yEnd = y + yBig * (len - 1); \
  365. \
  366. if (x < xEnd) { \
  367. rcl.left = x; \
  368. rcl.right = xEnd + 1; \
  369. } else { \
  370. rcl.left = xEnd; \
  371. rcl.right = x + 1; \
  372. } \
  373. if (y < yEnd) { \
  374. rcl.top = y; \
  375. rcl.bottom = yEnd + 1; \
  376. } else { \
  377. rcl.top = yEnd; \
  378. rcl.bottom = y + 1; \
  379. } \
  380. switch (wglRectVisible(&rcl)) { \
  381. case WGL_RECT_ALL: \
  382. goto scissor_no_complex; \
  383. break; \
  384. case WGL_RECT_NONE: \
  385. goto no_draw; \
  386. break; \
  387. } \
  388. \
  389. /* Line is partially visible, check each pixel */ \
  390. \
  391. while (--len >= 0) { \
  392. if (wglPixelVisible(x, y) && \
  393. xStart >= clipX0 && xStart < clipX1 && \
  394. yStart >= clipY0 && yStart < clipY1) { \
  395. addr[0] = ir; \
  396. addr[1] = ig; \
  397. addr[2] = ib; \
  398. } \
  399. fraction += dfraction; \
  400. if (fraction < 0) { \
  401. fraction &= ~0x80000000; \
  402. x += xBig; \
  403. y += yBig; \
  404. xStart += xBig; \
  405. yStart += yBig; \
  406. addr += addrBig; \
  407. } else { \
  408. x += xLittle; \
  409. y += yLittle; \
  410. xStart += xLittle; \
  411. yStart += yLittle; \
  412. addr += addrLittle; \
  413. } \
  414. } \
  415. } else { \
  416. scissor_no_complex: \
  417. while (--len >= 0) { \
  418. if (xStart >= clipX0 && xStart < clipX1 && \
  419. yStart >= clipY0 && yStart < clipY1) { \
  420. addr[0] = ir; \
  421. addr[1] = ig; \
  422. addr[2] = ib; \
  423. } \
  424. fraction += dfraction; \
  425. if (fraction < 0) { \
  426. fraction &= ~0x80000000; \
  427. xStart += xBig; \
  428. yStart += yBig; \
  429. addr += addrBig; \
  430. } else { \
  431. xStart += xLittle; \
  432. yStart += yLittle; \
  433. addr += addrLittle; \
  434. } \
  435. } \
  436. } \
  437. } else { \
  438. no_scissor: \
  439. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  440. RECTL rcl; \
  441. GLint xEnd, yEnd, xBig, yBig, xLittle, yLittle; \
  442. \
  443. xBig = gc->line.options.xBig; \
  444. yBig = gc->line.options.yBig; \
  445. xLittle = gc->line.options.xLittle; \
  446. yLittle = gc->line.options.yLittle; \
  447. \
  448. xEnd = x + xBig * (len - 1); \
  449. yEnd = y + yBig * (len - 1); \
  450. \
  451. if (x < xEnd) { \
  452. rcl.left = x; \
  453. rcl.right = xEnd + 1; \
  454. } else { \
  455. rcl.left = xEnd; \
  456. rcl.right = x + 1; \
  457. } \
  458. if (y < yEnd) { \
  459. rcl.top = y; \
  460. rcl.bottom = yEnd + 1; \
  461. } else { \
  462. rcl.top = yEnd; \
  463. rcl.bottom = y + 1; \
  464. } \
  465. switch (wglRectVisible(&rcl)) { \
  466. case WGL_RECT_ALL: \
  467. goto no_complex; \
  468. break; \
  469. case WGL_RECT_NONE: \
  470. goto no_draw; \
  471. break; \
  472. } \
  473. \
  474. /* Line is partially visible, check each pixel */ \
  475. \
  476. while (--len >= 0) { \
  477. if (wglPixelVisible(x, y)) { \
  478. addr[0] = ir; \
  479. addr[1] = ig; \
  480. addr[2] = ib; \
  481. } \
  482. fraction += dfraction; \
  483. if (fraction < 0) { \
  484. fraction &= ~0x80000000; \
  485. addr += addrBig; \
  486. } else { \
  487. addr += addrLittle; \
  488. } \
  489. } \
  490. } else { \
  491. no_complex: \
  492. while (--len >= 0) { \
  493. addr[0] = ir; \
  494. addr[1] = ig; \
  495. addr[2] = ib; \
  496. fraction += dfraction; \
  497. if (fraction < 0) { \
  498. fraction &= ~0x80000000; \
  499. addr += addrBig; \
  500. } else { \
  501. addr += addrLittle; \
  502. } \
  503. } \
  504. } \
  505. } \
  506. no_draw:; \
  507. }
  508. /*
  509. ** __FAST_LINE_STROKE_DIB_WIDE
  510. **
  511. ** Strokes a wide solid line into a DIB surface. Performs scissoring.
  512. ** Works for 8, 16, and 32 BPP
  513. **
  514. */
  515. #define __FAST_LINE_STROKE_DIB_WIDE \
  516. { \
  517. len = gc->line.options.numPixels; \
  518. fraction = gc->line.options.fraction; \
  519. dfraction = gc->line.options.dfraction; \
  520. \
  521. /* \
  522. ** Since one or more of the strokes of a wide line may lie outside \
  523. ** the viewport, wide lines always go through the scissoring checks \
  524. */ \
  525. { \
  526. GLint clipX0, clipX1, clipY0, clipY1; \
  527. GLint xStart, yStart, xEnd, yEnd; \
  528. GLint xLittle, yLittle, xBig, yBig; \
  529. GLint highWord, lowWord, bigs, littles; \
  530. \
  531. clipX0 = gc->transform.clipX0; \
  532. clipX1 = gc->transform.clipX1; \
  533. clipY0 = gc->transform.clipY0; \
  534. clipY1 = gc->transform.clipY1; \
  535. \
  536. xBig = gc->line.options.xBig; \
  537. yBig = gc->line.options.yBig; \
  538. \
  539. xStart = gc->line.options.xStart; \
  540. yStart = gc->line.options.yStart; \
  541. \
  542. /* If the start point is in the scissor region, we attempt to \
  543. ** trivially accept the line. \
  544. */ \
  545. if (xStart >= clipX0 && xStart < clipX1 && \
  546. yStart >= clipY0 && yStart < clipY1) { \
  547. \
  548. len--; /* Makes our math simpler */ \
  549. width--; \
  550. /* Trivial accept attempt */ \
  551. xEnd = xStart + xBig * len; \
  552. yEnd = yStart + yBig * len; \
  553. if (xEnd >= clipX0 && xEnd < clipX1 && \
  554. yEnd >= clipY0 && yEnd < clipY1) { \
  555. \
  556. if (gc->line.options.axis == __GL_X_MAJOR) { \
  557. if (((yStart + width) >= clipY0) && \
  558. ((yStart + width) < clipY1) && \
  559. ((yEnd + width) >= clipY0) && \
  560. ((yEnd + width) < clipY1)) { \
  561. \
  562. len++; \
  563. width++; \
  564. goto no_scissor; \
  565. } \
  566. } else { \
  567. if (((xStart + width) >= clipX0) && \
  568. ((xStart + width) < clipX1) && \
  569. ((xEnd + width) >= clipX0) && \
  570. ((xEnd + width) < clipX1)) { \
  571. \
  572. len++; \
  573. width++; \
  574. goto no_scissor; \
  575. } \
  576. } \
  577. } \
  578. \
  579. xLittle = gc->line.options.xLittle; \
  580. yLittle = gc->line.options.yLittle; \
  581. \
  582. /* \
  583. ** Invert negative minor slopes so we can assume \
  584. ** dfraction > 0 \
  585. */ \
  586. if (dfraction < 0) { \
  587. dfraction = -dfraction; \
  588. fraction = 0x7fffffff - fraction; \
  589. } \
  590. \
  591. /* Now we compute number of littles and bigs in this line */\
  592. \
  593. /* We perform a 16 by 32 bit multiply. Ugh. */ \
  594. highWord = (((GLuint) dfraction) >> 16) * len + \
  595. (((GLuint) fraction) >> 16); \
  596. lowWord = (dfraction & 0xffff) * len + (fraction & 0xffff); \
  597. highWord += (((GLuint) lowWord) >> 16); \
  598. bigs = ((GLuint) highWord) >> 15; \
  599. littles = len - bigs; \
  600. \
  601. /* Second trivial accept attempt */ \
  602. xEnd = xStart + xBig*bigs + xLittle*littles; \
  603. yEnd = yStart + yBig*bigs + yLittle*littles; \
  604. if (xEnd >= clipX0 && xEnd < clipX1 && \
  605. yEnd >= clipY0 && yEnd < clipY1) { \
  606. \
  607. if (gc->line.options.axis == __GL_X_MAJOR) { \
  608. if (((yStart + width) >= clipY0) && \
  609. ((yStart + width) < clipY1) && \
  610. ((yEnd + width) >= clipY0) && \
  611. ((yEnd + width) < clipY1)) { \
  612. \
  613. len++; \
  614. width++; \
  615. goto no_scissor; \
  616. } \
  617. } else { \
  618. if (((xStart + width) >= clipX0) && \
  619. ((xStart + width) < clipX1) && \
  620. ((xEnd + width) >= clipX0) && \
  621. ((xEnd + width) < clipX1)) { \
  622. \
  623. len++; \
  624. width++; \
  625. goto no_scissor; \
  626. } \
  627. } \
  628. } \
  629. len++; /* Restore len and width */ \
  630. width++; \
  631. } else { \
  632. xLittle = gc->line.options.xLittle; \
  633. yLittle = gc->line.options.yLittle; \
  634. } \
  635. \
  636. /* \
  637. ** The line needs to be scissored. \
  638. ** Well, it should only happen rarely, so we can afford \
  639. ** to make it slow. We achieve this by tediously stippling the \
  640. ** line. (rather than clipping it, of course, which would be \
  641. ** faster but harder). \
  642. */ \
  643. \
  644. if (gc->line.options.axis == __GL_X_MAJOR) { \
  645. GLint yTmp0; \
  646. \
  647. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  648. RECTL rcl; \
  649. GLint yTmp1; \
  650. \
  651. xEnd = x + xBig * (len - 1); \
  652. yEnd = y + yBig * (len - 1); \
  653. \
  654. if (x < xEnd) { \
  655. rcl.left = x; \
  656. rcl.right = xEnd + 1; \
  657. } else { \
  658. rcl.left = xEnd; \
  659. rcl.right = x + 1; \
  660. } \
  661. if (y < yEnd) { \
  662. rcl.top = y; \
  663. rcl.bottom = yEnd + width; \
  664. } else { \
  665. rcl.top = yEnd; \
  666. rcl.bottom = y + width; \
  667. } \
  668. switch (wglRectVisible(&rcl)) { \
  669. case WGL_RECT_ALL: \
  670. goto scissor_x_no_complex; \
  671. break; \
  672. case WGL_RECT_NONE: \
  673. goto no_draw; \
  674. break; \
  675. } \
  676. \
  677. /* Line is partially visible, check each pixel */ \
  678. \
  679. while (--len >= 0) { \
  680. if (xStart >= clipX0 && xStart < clipX1) { \
  681. yTmp0 = yStart; \
  682. yTmp1 = y; \
  683. w = width; \
  684. while (--w >= 0) { \
  685. if (wglPixelVisible(x, yTmp1) && \
  686. yTmp0 >= clipY0 && yTmp0 < clipY1) { \
  687. *addr = pixel; \
  688. } \
  689. addr += addrMinor; \
  690. yTmp0++; \
  691. yTmp1++; \
  692. } \
  693. } else { \
  694. addr += addrMinor * width; \
  695. } \
  696. fraction += dfraction; \
  697. if (fraction < 0) { \
  698. fraction &= ~0x80000000; \
  699. x += xBig; \
  700. y += yBig; \
  701. xStart += xBig; \
  702. yStart += yBig; \
  703. addr += addrBig; \
  704. } else { \
  705. x += xLittle; \
  706. y += yLittle; \
  707. xStart += xLittle; \
  708. yStart += yLittle; \
  709. addr += addrLittle; \
  710. } \
  711. } \
  712. } else { \
  713. scissor_x_no_complex: \
  714. while (--len >= 0) { \
  715. if (xStart >= clipX0 && xStart < clipX1) { \
  716. yTmp0 = yStart; \
  717. w = width; \
  718. while (--w >= 0) { \
  719. if (yTmp0 >= clipY0 && yTmp0 < clipY1) { \
  720. *addr = pixel; \
  721. } \
  722. addr += addrMinor; \
  723. yTmp0++; \
  724. } \
  725. } else { \
  726. addr += addrMinor * width; \
  727. } \
  728. fraction += dfraction; \
  729. if (fraction < 0) { \
  730. fraction &= ~0x80000000; \
  731. xStart += xBig; \
  732. yStart += yBig; \
  733. addr += addrBig; \
  734. } else { \
  735. xStart += xLittle; \
  736. yStart += yLittle; \
  737. addr += addrLittle; \
  738. } \
  739. } \
  740. } \
  741. } else { \
  742. GLint xTmp0; \
  743. \
  744. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  745. RECTL rcl; \
  746. GLint xTmp1; \
  747. \
  748. xEnd = x + xBig * (len - 1); \
  749. yEnd = y + yBig * (len - 1); \
  750. \
  751. if (x < xEnd) { \
  752. rcl.left = x; \
  753. rcl.right = xEnd + width; \
  754. } else { \
  755. rcl.left = xEnd; \
  756. rcl.right = x + width; \
  757. } \
  758. if (y < yEnd) { \
  759. rcl.top = y; \
  760. rcl.bottom = yEnd + 1; \
  761. } else { \
  762. rcl.top = yEnd; \
  763. rcl.bottom = y + 1; \
  764. } \
  765. switch (wglRectVisible(&rcl)) { \
  766. case WGL_RECT_ALL: \
  767. goto scissor_y_no_complex; \
  768. break; \
  769. case WGL_RECT_NONE: \
  770. goto no_draw; \
  771. break; \
  772. } \
  773. \
  774. /* Line is partially visible, check each pixel */ \
  775. \
  776. while (--len >= 0) { \
  777. if (yStart >= clipY0 && yStart < clipY1) { \
  778. xTmp0 = xStart; \
  779. xTmp1 = x; \
  780. w = width; \
  781. while (--w >= 0) { \
  782. if (wglPixelVisible(xTmp1, y) && \
  783. xTmp0 >= clipX0 && xTmp0 < clipX1) { \
  784. *addr = pixel; \
  785. } \
  786. addr += addrMinor; \
  787. xTmp0++; \
  788. xTmp1++; \
  789. } \
  790. } else { \
  791. addr += addrMinor * width; \
  792. } \
  793. fraction += dfraction; \
  794. if (fraction < 0) { \
  795. fraction &= ~0x80000000; \
  796. x += xBig; \
  797. y += yBig; \
  798. xStart += xBig; \
  799. yStart += yBig; \
  800. addr += addrBig; \
  801. } else { \
  802. x += xLittle; \
  803. y += yLittle; \
  804. xStart += xLittle; \
  805. yStart += yLittle; \
  806. addr += addrLittle; \
  807. } \
  808. } \
  809. } else { \
  810. scissor_y_no_complex: \
  811. while (--len >= 0) { \
  812. if (yStart >= clipY0 && yStart < clipY1) { \
  813. xTmp0 = xStart; \
  814. w = width; \
  815. while (--w >= 0) { \
  816. if (xTmp0 >= clipX0 && xTmp0 < clipX1) { \
  817. *addr = pixel; \
  818. } \
  819. addr += addrMinor; \
  820. xTmp0++; \
  821. } \
  822. } else { \
  823. addr += addrMinor * width; \
  824. } \
  825. fraction += dfraction; \
  826. if (fraction < 0) { \
  827. fraction &= ~0x80000000; \
  828. xStart += xBig; \
  829. yStart += yBig; \
  830. addr += addrBig; \
  831. } else { \
  832. xStart += xLittle; \
  833. yStart += yLittle; \
  834. addr += addrLittle; \
  835. } \
  836. } \
  837. } \
  838. } \
  839. goto no_draw; \
  840. no_scissor: \
  841. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  842. RECTL rcl; \
  843. \
  844. xEnd = x + xBig * (len - 1); \
  845. yEnd = y + yBig * (len - 1); \
  846. \
  847. xLittle = gc->line.options.xLittle; \
  848. yLittle = gc->line.options.yLittle; \
  849. \
  850. if (gc->line.options.axis == __GL_X_MAJOR) { \
  851. GLint yTmp; \
  852. \
  853. if (x < xEnd) { \
  854. rcl.left = x; \
  855. rcl.right = xEnd + 1; \
  856. } else { \
  857. rcl.left = xEnd; \
  858. rcl.right = x + 1; \
  859. } \
  860. if (y < yEnd) { \
  861. rcl.top = y; \
  862. rcl.bottom = yEnd + width; \
  863. } else { \
  864. rcl.top = yEnd; \
  865. rcl.bottom = y + width; \
  866. } \
  867. switch (wglRectVisible(&rcl)) { \
  868. case WGL_RECT_ALL: \
  869. goto no_scissor_no_complex; \
  870. break; \
  871. case WGL_RECT_NONE: \
  872. goto no_draw; \
  873. break; \
  874. } \
  875. \
  876. /* Line is partially visible, check each pixel */ \
  877. \
  878. while (--len >= 0) { \
  879. yTmp = y; \
  880. w = width; \
  881. while (--w >= 0) { \
  882. if (wglPixelVisible(x, yTmp)) { \
  883. *addr = pixel; \
  884. } \
  885. addr += addrMinor; \
  886. yTmp++; \
  887. } \
  888. fraction += dfraction; \
  889. if (fraction < 0) { \
  890. fraction &= ~0x80000000; \
  891. x += xBig; \
  892. y += yBig; \
  893. addr += addrBig; \
  894. } else { \
  895. x += xLittle; \
  896. y += yLittle; \
  897. addr += addrLittle; \
  898. } \
  899. } \
  900. } else { \
  901. GLint xTmp; \
  902. \
  903. if (x < xEnd) { \
  904. rcl.left = x; \
  905. rcl.right = xEnd + width; \
  906. } else { \
  907. rcl.left = xEnd; \
  908. rcl.right = x + width; \
  909. } \
  910. if (y < yEnd) { \
  911. rcl.top = y; \
  912. rcl.bottom = yEnd + 1; \
  913. } else { \
  914. rcl.top = yEnd; \
  915. rcl.bottom = y + 1; \
  916. } \
  917. switch (wglRectVisible(&rcl)) { \
  918. case WGL_RECT_ALL: \
  919. goto no_scissor_no_complex; \
  920. break; \
  921. case WGL_RECT_NONE: \
  922. goto no_draw; \
  923. break; \
  924. } \
  925. \
  926. /* Line is partially visible, check each pixel */ \
  927. \
  928. while (--len >= 0) { \
  929. xTmp = x; \
  930. w = width; \
  931. while (--w >= 0) { \
  932. if (wglPixelVisible(xTmp, y)) { \
  933. *addr = pixel; \
  934. } \
  935. addr += addrMinor; \
  936. xTmp++; \
  937. } \
  938. fraction += dfraction; \
  939. if (fraction < 0) { \
  940. fraction &= ~0x80000000; \
  941. x += xBig; \
  942. y += yBig; \
  943. addr += addrBig; \
  944. } else { \
  945. x += xLittle; \
  946. y += yLittle; \
  947. addr += addrLittle; \
  948. } \
  949. } \
  950. } \
  951. } else { \
  952. no_scissor_no_complex: \
  953. while (--len >= 0) { \
  954. w = width; \
  955. while (--w >= 0) { \
  956. *addr = pixel; \
  957. addr += addrMinor; \
  958. } \
  959. fraction += dfraction; \
  960. if (fraction < 0) { \
  961. fraction &= ~0x80000000; \
  962. addr += addrBig; \
  963. } else { \
  964. addr += addrLittle; \
  965. } \
  966. } \
  967. } \
  968. } \
  969. no_draw:; \
  970. }
  971. /*
  972. ** __FAST_LINE_STROKE_DIB24_WIDE
  973. **
  974. ** Strokes a wide solid line into a DIB surface. Performs scissoring.
  975. ** Works for 24 BPP
  976. **
  977. */
  978. #define __FAST_LINE_STROKE_DIB24_WIDE \
  979. { \
  980. len = gc->line.options.numPixels; \
  981. fraction = gc->line.options.fraction; \
  982. dfraction = gc->line.options.dfraction; \
  983. \
  984. /* \
  985. ** Since one or more of the strokes of a wide line may lie outside \
  986. ** the viewport, wide lines always go through the scissoring checks \
  987. */ \
  988. { \
  989. GLint clipX0, clipX1, clipY0, clipY1; \
  990. GLint xStart, yStart, xEnd, yEnd; \
  991. GLint xLittle, yLittle, xBig, yBig; \
  992. GLint highWord, lowWord, bigs, littles; \
  993. \
  994. clipX0 = gc->transform.clipX0; \
  995. clipX1 = gc->transform.clipX1; \
  996. clipY0 = gc->transform.clipY0; \
  997. clipY1 = gc->transform.clipY1; \
  998. \
  999. xBig = gc->line.options.xBig; \
  1000. yBig = gc->line.options.yBig; \
  1001. \
  1002. xStart = gc->line.options.xStart; \
  1003. yStart = gc->line.options.yStart; \
  1004. \
  1005. /* If the start point is in the scissor region, we attempt to \
  1006. ** trivially accept the line. \
  1007. */ \
  1008. if (xStart >= clipX0 && xStart < clipX1 && \
  1009. yStart >= clipY0 && yStart < clipY1) { \
  1010. \
  1011. len--; /* Makes our math simpler */ \
  1012. width--; \
  1013. /* Trivial accept attempt */ \
  1014. xEnd = xStart + xBig * len; \
  1015. yEnd = yStart + yBig * len; \
  1016. if (xEnd >= clipX0 && xEnd < clipX1 && \
  1017. yEnd >= clipY0 && yEnd < clipY1) { \
  1018. \
  1019. if (gc->line.options.axis == __GL_X_MAJOR) { \
  1020. if (((yStart + width) >= clipY0) && \
  1021. ((yStart + width) < clipY1) && \
  1022. ((yEnd + width) >= clipY0) && \
  1023. ((yEnd + width) < clipY1)) { \
  1024. \
  1025. len++; \
  1026. width++; \
  1027. goto no_scissor; \
  1028. } \
  1029. } else { \
  1030. if (((xStart + width) >= clipX0) && \
  1031. ((xStart + width) < clipX1) && \
  1032. ((xEnd + width) >= clipX0) && \
  1033. ((xEnd + width) < clipX1)) { \
  1034. \
  1035. len++; \
  1036. width++; \
  1037. goto no_scissor; \
  1038. } \
  1039. } \
  1040. } \
  1041. \
  1042. xLittle = gc->line.options.xLittle; \
  1043. yLittle = gc->line.options.yLittle; \
  1044. \
  1045. /* \
  1046. ** Invert negative minor slopes so we can assume \
  1047. ** dfraction > 0 \
  1048. */ \
  1049. if (dfraction < 0) { \
  1050. dfraction = -dfraction; \
  1051. fraction = 0x7fffffff - fraction; \
  1052. } \
  1053. \
  1054. /* Now we compute number of littles and bigs in this line */\
  1055. \
  1056. /* We perform a 16 by 32 bit multiply. Ugh. */ \
  1057. highWord = (((GLuint) dfraction) >> 16) * len + \
  1058. (((GLuint) fraction) >> 16); \
  1059. lowWord = (dfraction & 0xffff) * len + (fraction & 0xffff); \
  1060. highWord += (((GLuint) lowWord) >> 16); \
  1061. bigs = ((GLuint) highWord) >> 15; \
  1062. littles = len - bigs; \
  1063. \
  1064. /* Second trivial accept attempt */ \
  1065. xEnd = xStart + xBig*bigs + xLittle*littles; \
  1066. yEnd = yStart + yBig*bigs + yLittle*littles; \
  1067. if (xEnd >= clipX0 && xEnd < clipX1 && \
  1068. yEnd >= clipY0 && yEnd < clipY1) { \
  1069. \
  1070. if (gc->line.options.axis == __GL_X_MAJOR) { \
  1071. if (((yStart + width) >= clipY0) && \
  1072. ((yStart + width) < clipY1) && \
  1073. ((yEnd + width) >= clipY0) && \
  1074. ((yEnd + width) < clipY1)) { \
  1075. \
  1076. len++; \
  1077. width++; \
  1078. goto no_scissor; \
  1079. } \
  1080. } else { \
  1081. if (((xStart + width) >= clipX0) && \
  1082. ((xStart + width) < clipX1) && \
  1083. ((xEnd + width) >= clipX0) && \
  1084. ((xEnd + width) < clipX1)) { \
  1085. \
  1086. len++; \
  1087. width++; \
  1088. goto no_scissor; \
  1089. } \
  1090. } \
  1091. } \
  1092. len++; /* Restore len and width */ \
  1093. width++; \
  1094. } else { \
  1095. xLittle = gc->line.options.xLittle; \
  1096. yLittle = gc->line.options.yLittle; \
  1097. } \
  1098. \
  1099. /* \
  1100. ** The line needs to be scissored. \
  1101. ** Well, it should only happen rarely, so we can afford \
  1102. ** to make it slow. We achieve this by tediously stippling the \
  1103. ** line. (rather than clipping it, of course, which would be \
  1104. ** faster but harder). \
  1105. */ \
  1106. \
  1107. if (gc->line.options.axis == __GL_X_MAJOR) { \
  1108. GLint yTmp0; \
  1109. \
  1110. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  1111. RECTL rcl; \
  1112. GLint yTmp1; \
  1113. \
  1114. xEnd = x + xBig * (len - 1); \
  1115. yEnd = y + yBig * (len - 1); \
  1116. \
  1117. if (x < xEnd) { \
  1118. rcl.left = x; \
  1119. rcl.right = xEnd + 1; \
  1120. } else { \
  1121. rcl.left = xEnd; \
  1122. rcl.right = x + 1; \
  1123. } \
  1124. if (y < yEnd) { \
  1125. rcl.top = y; \
  1126. rcl.bottom = yEnd + width; \
  1127. } else { \
  1128. rcl.top = yEnd; \
  1129. rcl.bottom = y + width; \
  1130. } \
  1131. switch (wglRectVisible(&rcl)) { \
  1132. case WGL_RECT_ALL: \
  1133. goto scissor_x_no_complex; \
  1134. break; \
  1135. case WGL_RECT_NONE: \
  1136. goto no_draw; \
  1137. break; \
  1138. } \
  1139. \
  1140. /* Line is partially visible, check each pixel */ \
  1141. \
  1142. while (--len >= 0) { \
  1143. if (xStart >= clipX0 && xStart < clipX1) { \
  1144. yTmp0 = yStart; \
  1145. yTmp1 = y; \
  1146. w = width; \
  1147. while (--w >= 0) { \
  1148. if (wglPixelVisible(x, yTmp1) && \
  1149. yTmp0 >= clipY0 && yTmp0 < clipY1) { \
  1150. addr[0] = ir; \
  1151. addr[1] = ig; \
  1152. addr[2] = ib; \
  1153. } \
  1154. addr += addrMinor; \
  1155. yTmp0++; \
  1156. yTmp1++; \
  1157. } \
  1158. } else { \
  1159. addr += addrMinor * width; \
  1160. } \
  1161. fraction += dfraction; \
  1162. if (fraction < 0) { \
  1163. fraction &= ~0x80000000; \
  1164. x += xBig; \
  1165. y += yBig; \
  1166. xStart += xBig; \
  1167. yStart += yBig; \
  1168. addr += addrBig; \
  1169. } else { \
  1170. x += xLittle; \
  1171. y += yLittle; \
  1172. xStart += xLittle; \
  1173. yStart += yLittle; \
  1174. addr += addrLittle; \
  1175. } \
  1176. } \
  1177. } else { \
  1178. scissor_x_no_complex: \
  1179. while (--len >= 0) { \
  1180. if (xStart >= clipX0 && xStart < clipX1) { \
  1181. yTmp0 = yStart; \
  1182. w = width; \
  1183. while (--w >= 0) { \
  1184. if (yTmp0 >= clipY0 && yTmp0 < clipY1) { \
  1185. addr[0] = ir; \
  1186. addr[1] = ig; \
  1187. addr[2] = ib; \
  1188. } \
  1189. addr += addrMinor; \
  1190. yTmp0++; \
  1191. } \
  1192. } else { \
  1193. addr += addrMinor * width; \
  1194. } \
  1195. fraction += dfraction; \
  1196. if (fraction < 0) { \
  1197. fraction &= ~0x80000000; \
  1198. xStart += xBig; \
  1199. yStart += yBig; \
  1200. addr += addrBig; \
  1201. } else { \
  1202. xStart += xLittle; \
  1203. yStart += yLittle; \
  1204. addr += addrLittle; \
  1205. } \
  1206. } \
  1207. } \
  1208. } else { \
  1209. GLint xTmp0; \
  1210. \
  1211. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  1212. RECTL rcl; \
  1213. GLint xTmp1; \
  1214. \
  1215. xEnd = x + xBig * (len - 1); \
  1216. yEnd = y + yBig * (len - 1); \
  1217. \
  1218. if (x < xEnd) { \
  1219. rcl.left = x; \
  1220. rcl.right = xEnd + width; \
  1221. } else { \
  1222. rcl.left = xEnd; \
  1223. rcl.right = x + width; \
  1224. } \
  1225. if (y < yEnd) { \
  1226. rcl.top = y; \
  1227. rcl.bottom = yEnd + 1; \
  1228. } else { \
  1229. rcl.top = yEnd; \
  1230. rcl.bottom = y + 1; \
  1231. } \
  1232. switch (wglRectVisible(&rcl)) { \
  1233. case WGL_RECT_ALL: \
  1234. goto scissor_y_no_complex; \
  1235. break; \
  1236. case WGL_RECT_NONE: \
  1237. goto no_draw; \
  1238. break; \
  1239. } \
  1240. \
  1241. /* Line is partially visible, check each pixel */ \
  1242. \
  1243. while (--len >= 0) { \
  1244. if (yStart >= clipY0 && yStart < clipY1) { \
  1245. xTmp0 = xStart; \
  1246. xTmp1 = x; \
  1247. w = width; \
  1248. while (--w >= 0) { \
  1249. if (wglPixelVisible(xTmp1, y) && \
  1250. xTmp0 >= clipX0 && xTmp0 < clipX1) { \
  1251. addr[0] = ir; \
  1252. addr[1] = ig; \
  1253. addr[2] = ib; \
  1254. } \
  1255. addr += addrMinor; \
  1256. xTmp0++; \
  1257. xTmp1++; \
  1258. } \
  1259. } else { \
  1260. addr += addrMinor * width; \
  1261. } \
  1262. fraction += dfraction; \
  1263. if (fraction < 0) { \
  1264. fraction &= ~0x80000000; \
  1265. x += xBig; \
  1266. y += yBig; \
  1267. xStart += xBig; \
  1268. yStart += yBig; \
  1269. addr += addrBig; \
  1270. } else { \
  1271. x += xLittle; \
  1272. y += yLittle; \
  1273. xStart += xLittle; \
  1274. yStart += yLittle; \
  1275. addr += addrLittle; \
  1276. } \
  1277. } \
  1278. } else { \
  1279. scissor_y_no_complex: \
  1280. while (--len >= 0) { \
  1281. if (yStart >= clipY0 && yStart < clipY1) { \
  1282. xTmp0 = xStart; \
  1283. w = width; \
  1284. while (--w >= 0) { \
  1285. if (xTmp0 >= clipX0 && xTmp0 < clipX1) { \
  1286. addr[0] = ir; \
  1287. addr[1] = ig; \
  1288. addr[2] = ib; \
  1289. } \
  1290. addr += addrMinor; \
  1291. xTmp0++; \
  1292. } \
  1293. } else { \
  1294. addr += addrMinor * width; \
  1295. } \
  1296. fraction += dfraction; \
  1297. if (fraction < 0) { \
  1298. fraction &= ~0x80000000; \
  1299. xStart += xBig; \
  1300. yStart += yBig; \
  1301. addr += addrBig; \
  1302. } else { \
  1303. xStart += xLittle; \
  1304. yStart += yLittle; \
  1305. addr += addrLittle; \
  1306. } \
  1307. } \
  1308. } \
  1309. } \
  1310. goto no_draw; \
  1311. no_scissor: \
  1312. if (!((GLuint)cfb->buf.other & NO_CLIP)) { \
  1313. RECTL rcl; \
  1314. \
  1315. xLittle = gc->line.options.xLittle; \
  1316. yLittle = gc->line.options.yLittle; \
  1317. \
  1318. if (gc->line.options.axis == __GL_X_MAJOR) { \
  1319. GLint yTmp; \
  1320. \
  1321. if (x < xEnd) { \
  1322. rcl.left = x; \
  1323. rcl.right = xEnd + 1; \
  1324. } else { \
  1325. rcl.left = xEnd; \
  1326. rcl.right = x + 1; \
  1327. } \
  1328. if (y < yEnd) { \
  1329. rcl.top = y; \
  1330. rcl.bottom = yEnd + width; \
  1331. } else { \
  1332. rcl.top = yEnd; \
  1333. rcl.bottom = y + width; \
  1334. } \
  1335. switch (wglRectVisible(&rcl)) { \
  1336. case WGL_RECT_ALL: \
  1337. goto no_scissor_no_complex; \
  1338. break; \
  1339. case WGL_RECT_NONE: \
  1340. goto no_draw; \
  1341. break; \
  1342. } \
  1343. \
  1344. /* Line is partially visible, check each pixel */ \
  1345. \
  1346. while (--len >= 0) { \
  1347. yTmp = y; \
  1348. w = width; \
  1349. while (--w >= 0) { \
  1350. if (wglPixelVisible(x, yTmp)) { \
  1351. addr[0] = ir; \
  1352. addr[1] = ig; \
  1353. addr[2] = ib; \
  1354. } \
  1355. addr += addrMinor; \
  1356. yTmp++; \
  1357. } \
  1358. fraction += dfraction; \
  1359. if (fraction < 0) { \
  1360. fraction &= ~0x80000000; \
  1361. x += xBig; \
  1362. y += yBig; \
  1363. addr += addrBig; \
  1364. } else { \
  1365. x += xLittle; \
  1366. y += yLittle; \
  1367. addr += addrLittle; \
  1368. } \
  1369. } \
  1370. } else { \
  1371. GLint xTmp; \
  1372. \
  1373. if (x < xEnd) { \
  1374. rcl.left = x; \
  1375. rcl.right = xEnd + width; \
  1376. } else { \
  1377. rcl.left = xEnd; \
  1378. rcl.right = x + width; \
  1379. } \
  1380. if (y < yEnd) { \
  1381. rcl.top = y; \
  1382. rcl.bottom = yEnd + 1; \
  1383. } else { \
  1384. rcl.top = yEnd; \
  1385. rcl.bottom = y + 1; \
  1386. } \
  1387. switch (wglRectVisible(&rcl)) { \
  1388. case WGL_RECT_ALL: \
  1389. goto no_scissor_no_complex; \
  1390. break; \
  1391. case WGL_RECT_NONE: \
  1392. goto no_draw; \
  1393. break; \
  1394. } \
  1395. \
  1396. /* Line is partially visible, check each pixel */ \
  1397. \
  1398. while (--len >= 0) { \
  1399. xTmp = x; \
  1400. w = width; \
  1401. while (--w >= 0) { \
  1402. if (wglPixelVisible(xTmp, y)) { \
  1403. addr[0] = ir; \
  1404. addr[1] = ig; \
  1405. addr[2] = ib; \
  1406. } \
  1407. addr += addrMinor; \
  1408. xTmp++; \
  1409. } \
  1410. fraction += dfraction; \
  1411. if (fraction < 0) { \
  1412. fraction &= ~0x80000000; \
  1413. x += xBig; \
  1414. y += yBig; \
  1415. addr += addrBig; \
  1416. } else { \
  1417. x += xLittle; \
  1418. y += yLittle; \
  1419. addr += addrLittle; \
  1420. } \
  1421. } \
  1422. } \
  1423. } else { \
  1424. no_scissor_no_complex: \
  1425. while (--len >= 0) { \
  1426. w = width; \
  1427. while (--w >= 0) { \
  1428. addr[0] = ir; \
  1429. addr[1] = ig; \
  1430. addr[2] = ib; \
  1431. addr += addrMinor; \
  1432. } \
  1433. fraction += dfraction; \
  1434. if (fraction < 0) { \
  1435. fraction &= ~0x80000000; \
  1436. addr += addrBig; \
  1437. } else { \
  1438. addr += addrLittle; \
  1439. } \
  1440. } \
  1441. } \
  1442. } \
  1443. no_draw:; \
  1444. }
  1445. #endif // NT_NO_BUFFER_INVARIANCE