Source code of Windows XP (NT5)
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.

1580 lines
49 KiB

  1. /*
  2. ** Copyright 1991,1992,1993, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. */
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. #include "genline.h"
  20. #include "devlock.h"
  21. /******************************Public*Routine******************************\
  22. * __fastGenLineSetupDisplay
  23. *
  24. * Initializes the accelerated line-rendering state machine for display surfaces.
  25. * There are basically 4 levels in the state machine:
  26. * 1. lineBegin
  27. * This function initializes the initial states of the lower levels.
  28. *
  29. * 2. lineVertex
  30. * This function adds vertices to the path
  31. *
  32. * 3. lineEnd
  33. * This function calls the routine to stroke the path.
  34. *
  35. * History:
  36. * 09-Jan-1996 -by- Drew Bliss [drewb]
  37. * Totally rewrote fast line support
  38. * 29-Mar-1994 [v-eddier]
  39. * Changed name when __fastGenLineSetupDIB was added.
  40. * 22-Mar-1994 -by- Eddie Robinson [v-eddier]
  41. * Wrote it.
  42. \**************************************************************************/
  43. BOOL FASTCALL __fastGenLineSetupDisplay(__GLcontext *gc)
  44. {
  45. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  46. GENACCEL *genAccel = (GENACCEL *) gengc->pPrivateArea;
  47. GLuint modeFlags = gc->polygon.shader.modeFlags;
  48. // allocate line buffer
  49. if (!genAccel->pFastLineBuffer) {
  50. if (!(genAccel->pFastLineBuffer =
  51. (BYTE *) GCALLOC(gc, __FAST_LINE_BUFFER_SIZE)))
  52. return FALSE;
  53. }
  54. // Set the line rasterization function pointers
  55. gc->procs.lineBegin = __fastGenLineBegin;
  56. gc->procs.lineEnd = __fastGenLineEnd;
  57. if (gc->state.line.aliasedWidth > 1)
  58. {
  59. gc->procs.renderLine = __fastGenLineWide;
  60. }
  61. else
  62. {
  63. gc->procs.renderLine = __fastGenLine;
  64. }
  65. return TRUE;
  66. }
  67. /******************************Public*Routine******************************\
  68. *
  69. * __fastLineComputeOffsets
  70. *
  71. * Precomputes static offsets for fast line drawing
  72. *
  73. * History:
  74. * Tue Aug 15 18:10:29 1995 -by- Drew Bliss [drewb]
  75. * Created
  76. *
  77. \**************************************************************************/
  78. void FASTCALL __fastLineComputeOffsets(__GLGENcontext *gengc)
  79. {
  80. GENACCEL *genAccel;
  81. genAccel = (GENACCEL *)gengc->pPrivateArea;
  82. ASSERTOPENGL(genAccel != NULL,
  83. "ComputeFastLineOffsets with no genaccel\n");
  84. // If acceleration is wired-in, set the offsets for line drawing.
  85. // These offsets include the following:
  86. // subtraction of the viewport bias
  87. // addition of the client window origin
  88. // subtraction of .5 to align GL pixel centers with GDI's pixel centers
  89. // addition of 1/32 to round the value which will be converted to
  90. // 28.4 fixed point
  91. #ifdef _CLIENTSIDE_
  92. // Window-relative coordinates
  93. genAccel->fastLineOffsetX = 0 -
  94. gengc->gc.constants.viewportXAdjust - (__GLfloat) (0.5 - 0.03125);
  95. genAccel->fastLineOffsetY = 0 -
  96. gengc->gc.constants.viewportYAdjust - (__GLfloat) (0.5 - 0.03125);
  97. #else
  98. // Screen-relative coordinates
  99. genAccel->fastLineOffsetX = gengc->gc.drawBuffer->buf.xOrigin -
  100. gengc->gc.constants.viewportXAdjust - (__GLfloat) (0.5 - 0.03125);
  101. genAccel->fastLineOffsetY = gengc->gc.drawBuffer->buf.yOrigin -
  102. gengc->gc.constants.viewportYAdjust - (__GLfloat) (0.5 - 0.03125);
  103. #endif
  104. }
  105. /******************************Public*Routine******************************\
  106. * __fastLineComputeColor*
  107. *
  108. * Computes the color index to use for line drawing. These functions are
  109. * called through a function pointer whenever the vertex color changes.
  110. *
  111. * History:
  112. * 22-Mar-1994 -by- Eddie Robinson [v-eddier]
  113. * Wrote it.
  114. \**************************************************************************/
  115. GLubyte vujRGBtoVGA[8] = {
  116. 0x0, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf
  117. };
  118. ULONG FASTCALL __fastLineComputeColorRGB4(__GLcontext *gc, __GLcolor *color)
  119. {
  120. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  121. PIXELFORMATDESCRIPTOR *pfmt = &gengc->gsurf.pfd;
  122. int ir, ig, ib;
  123. ir = (int) color->r;
  124. ig = (int) color->g;
  125. ib = (int) color->b;
  126. return (ULONG) vujRGBtoVGA[(ir << pfmt->cRedShift) |
  127. (ig << pfmt->cGreenShift) |
  128. (ib << pfmt->cBlueShift)];
  129. }
  130. ULONG FASTCALL __fastLineComputeColorRGB8(__GLcontext *gc, __GLcolor *color)
  131. {
  132. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  133. PIXELFORMATDESCRIPTOR *pfmt = &gengc->gsurf.pfd;
  134. int ir, ig, ib;
  135. ir = (int) color->r;
  136. ig = (int) color->g;
  137. ib = (int) color->b;
  138. return (ULONG) gengc->pajTranslateVector[(ir << pfmt->cRedShift) |
  139. (ig << pfmt->cGreenShift) |
  140. (ib << pfmt->cBlueShift)];
  141. }
  142. ULONG FASTCALL __fastLineComputeColorRGB(__GLcontext *gc, __GLcolor *color)
  143. {
  144. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  145. PIXELFORMATDESCRIPTOR *pfmt = &gengc->gsurf.pfd;
  146. int ir, ig, ib;
  147. ir = (int) color->r;
  148. ig = (int) color->g;
  149. ib = (int) color->b;
  150. return (ULONG) ((ir << pfmt->cRedShift) |
  151. (ig << pfmt->cGreenShift) |
  152. (ib << pfmt->cBlueShift));
  153. }
  154. ULONG FASTCALL __fastLineComputeColorCI4and8(__GLcontext *gc, __GLcolor *color)
  155. {
  156. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  157. return (ULONG) gengc->pajTranslateVector[(int)color->r];
  158. }
  159. ULONG FASTCALL __fastLineComputeColorCI(__GLcontext *gc, __GLcolor *color)
  160. {
  161. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  162. GLuint *pTrans = (GLuint *) gengc->pajTranslateVector;
  163. return (ULONG) pTrans[(int)(color->r)+1];
  164. }
  165. /******************************Public*Routine******************************\
  166. * __glQueryLineAcceleration
  167. *
  168. * Determines if lines are accelerated through the DDI and performs some
  169. * initialization. Currently, this routine only checks for acceleration via
  170. * the standard DDI. Eventually, it could support checking for acceleration
  171. * via the extended DDI.
  172. *
  173. * History:
  174. * 22-Mar-1994 -by- Eddie Robinson [v-eddier]
  175. * Wrote it.
  176. \**************************************************************************/
  177. void FASTCALL __glQueryLineAcceleration(__GLcontext *gc)
  178. {
  179. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  180. GENACCEL *genAccel = (GENACCEL *) gengc->pPrivateArea;
  181. PIXELFORMATDESCRIPTOR *pfmt;
  182. pfmt = &gengc->gsurf.pfd;
  183. // On the client side we can draw into any surface with GDI
  184. // and (presumably) get the best possible plain 2D line drawing
  185. // performance
  186. genAccel->bFastLineDIBAccel = TRUE;
  187. //XXX eventually, check rxcaps and set appropriate mode bits
  188. genAccel->bFastLineDispAccel = TRUE;
  189. // set modes supported by hardware. These are equivalent to the
  190. // gc->polygon.shader.modeFlags checked in the pick function
  191. genAccel->flLineAccelModes = 0;
  192. // Set the color computation function
  193. if (pfmt->iPixelType == PFD_TYPE_RGBA) {
  194. switch (pfmt->cColorBits) {
  195. case 4:
  196. genAccel->fastLineComputeColor = __fastLineComputeColorRGB4;
  197. break;
  198. case 8:
  199. genAccel->fastLineComputeColor = __fastLineComputeColorRGB8;
  200. break;
  201. case 16:
  202. case 24:
  203. case 32:
  204. genAccel->fastLineComputeColor = __fastLineComputeColorRGB;
  205. break;
  206. default:
  207. genAccel->bFastLineDispAccel = FALSE;
  208. return;
  209. }
  210. } else {
  211. switch (pfmt->cColorBits) {
  212. case 4:
  213. case 8:
  214. genAccel->fastLineComputeColor = __fastLineComputeColorCI4and8;
  215. break;
  216. case 16:
  217. case 24:
  218. case 32:
  219. genAccel->fastLineComputeColor = __fastLineComputeColorCI;
  220. break;
  221. default:
  222. genAccel->bFastLineDispAccel = FALSE;
  223. return;
  224. }
  225. }
  226. }
  227. /**************************************************************************/
  228. // Macros to hide how the single pFastLineBuffer is divided into two
  229. // sections, one for points and one for counts
  230. #define FAST_LINE_FIRST_POINT(genAccel) \
  231. ((POINT *)(genAccel)->pFastLineBuffer)
  232. #define FAST_LINE_FIRST_COUNT(genAccel) \
  233. ((DWORD *)((genAccel)->pFastLineBuffer+__FAST_LINE_BUFFER_SIZE)- \
  234. __FAST_LINE_BUFFER_COUNTS)
  235. #define FAST_LINE_LAST_POINT(genAccel) \
  236. ((POINT *)FAST_LINE_FIRST_COUNT(genAccel)-1)
  237. #define FAST_LINE_LAST_COUNT(genAccel) \
  238. ((DWORD *)((genAccel)->pFastLineBuffer+__FAST_LINE_BUFFER_SIZE)-1)
  239. /******************************Public*Routine******************************\
  240. *
  241. * __fastGenLineBegin
  242. *
  243. * Initializes fast line state
  244. *
  245. * History:
  246. * Mon Jan 08 19:22:32 1996 -by- Drew Bliss [drewb]
  247. * Created
  248. *
  249. \**************************************************************************/
  250. void FASTCALL __fastGenLineBegin(__GLcontext *gc)
  251. {
  252. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  253. GENACCEL *genAccel = &gengc->genAccel;
  254. genAccel->pFastLinePoint = FAST_LINE_FIRST_POINT(genAccel)-1;
  255. genAccel->pFastLineCount = FAST_LINE_FIRST_COUNT(genAccel)-1;
  256. genAccel->fastLineCounts = 0;
  257. }
  258. /******************************Public*Routine******************************\
  259. *
  260. * __fastGenLineEnd
  261. *
  262. * Renders any current lines in the fast line buffer and
  263. * then resets the fast line state
  264. *
  265. * History:
  266. * Mon Jan 08 19:22:52 1996 -by- Drew Bliss [drewb]
  267. * Created
  268. *
  269. \**************************************************************************/
  270. void FASTCALL __fastGenLineEnd(__GLcontext *gc)
  271. {
  272. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  273. GENACCEL *genAccel = &gengc->genAccel;
  274. ULONG ulSolidColor;
  275. HDC hdc;
  276. HPEN hpen;
  277. if (genAccel->fastLineCounts == 0)
  278. {
  279. return;
  280. }
  281. // If there is no lock, we must have failed to reacquire the lock
  282. // from the previous call to wglStrokePath. This is an error condition
  283. // and we should not continue.
  284. if (gengc->fsLocks == 0)
  285. {
  286. WARNING("fastGenLineEnd: no lock\n");
  287. return;
  288. }
  289. // We need to sychronize with GDI before making GDI calls
  290. glsrvSynchronizeWithGdi(gengc, gengc->pwndLocked,
  291. COLOR_LOCK_FLAGS | DEPTH_LOCK_FLAGS);
  292. // If this color is the same as the one we've cached, use the
  293. // cached information
  294. hdc = CURRENT_DC_GC(gc);
  295. if (!gengc->fStrokeInvalid && hdc == gengc->hdcStroke)
  296. {
  297. hpen = gengc->hpenStroke;
  298. ASSERTOPENGL(hpen != NULL, "Cached stroke pen is null\n");
  299. }
  300. else
  301. {
  302. if (gengc->hpenStroke != NULL)
  303. {
  304. // Deselect the object before deletion
  305. if (gengc->hdcStroke != NULL)
  306. {
  307. SelectObject(gengc->hdcStroke, GetStockObject(BLACK_PEN));
  308. gengc->hdcStroke = NULL;
  309. }
  310. DeleteObject(gengc->hpenStroke);
  311. }
  312. ulSolidColor = wglTranslateColor(gengc->crStroke, hdc,
  313. gengc, &gengc->gsurf.pfd);
  314. hpen = CreatePen(PS_SOLID, 0, ulSolidColor);
  315. gengc->hpenStroke = hpen;
  316. if (hpen == NULL ||
  317. SelectObject(hdc, hpen) == NULL)
  318. {
  319. if (hpen != NULL)
  320. {
  321. DeleteObject(hpen);
  322. gengc->hpenStroke = NULL;
  323. }
  324. gengc->cStroke.r = -1.0f;
  325. gengc->fStrokeInvalid = TRUE;
  326. goto Exit;
  327. }
  328. gengc->hdcStroke = hdc;
  329. gengc->fStrokeInvalid = FALSE;
  330. }
  331. #ifdef DBG_VERBOSE
  332. {
  333. DWORD i;
  334. DWORD *count;
  335. POINT *pt;
  336. count = FAST_LINE_FIRST_COUNT(genAccel);
  337. pt = FAST_LINE_FIRST_POINT(genAccel);
  338. for (i = 0; i < genAccel->fastLineCounts; i++)
  339. {
  340. DbgPrint("Polyline with %d points at %d\n",
  341. *count, pt-FAST_LINE_FIRST_POINT(genAccel));
  342. pt += *count;
  343. count++;
  344. }
  345. }
  346. #endif
  347. PolyPolyline(hdc,
  348. FAST_LINE_FIRST_POINT(genAccel),
  349. FAST_LINE_FIRST_COUNT(genAccel),
  350. genAccel->fastLineCounts);
  351. Exit:
  352. // No more need for GDI operations
  353. glsrvDecoupleFromGdi(gengc, gengc->pwndLocked,
  354. COLOR_LOCK_FLAGS | DEPTH_LOCK_FLAGS);
  355. // Reset
  356. __fastGenLineBegin(gc);
  357. }
  358. /******************************Public*Routine******************************\
  359. *
  360. * __fastGenLineSetStrokeColor
  361. *
  362. * Updates cached pen with current color if necessary
  363. *
  364. * History:
  365. * Wed Jan 17 20:37:15 1996 -by- Drew Bliss [drewb]
  366. * Created
  367. *
  368. \**************************************************************************/
  369. BOOL __fastGenLineSetStrokeColor(__GLGENcontext *gengc, __GLcolor *color)
  370. {
  371. if (__GL_FLOAT_NE(color->r, gengc->cStroke.r) ||
  372. (gengc->gsurf.pfd.iPixelType == PFD_TYPE_RGBA
  373. && (__GL_FLOAT_NE(color->g, gengc->cStroke.g) ||
  374. __GL_FLOAT_NE(color->b, gengc->cStroke.b))))
  375. {
  376. ASSERTOPENGL(color->r >= 0.0f, "Invalid color\n");
  377. #ifdef DBG_VERBOSE
  378. if (gengc->cStroke.r >= 0.0f)
  379. {
  380. DbgPrint("Color change\n");
  381. }
  382. #endif
  383. // Flush whatever we have so far
  384. __fastGenLineEnd(&gengc->gc);
  385. // Set current color
  386. if (gengc->gsurf.pfd.iPixelType == PFD_TYPE_RGBA)
  387. gengc->cStroke = *color;
  388. else
  389. gengc->cStroke.r = color->r;
  390. gengc->crStroke =
  391. gengc->genAccel.fastLineComputeColor((__GLcontext *)gengc,
  392. &gengc->cStroke);
  393. // Invalidate cached pen
  394. gengc->fStrokeInvalid = TRUE;
  395. return TRUE;
  396. }
  397. else
  398. {
  399. return FALSE;
  400. }
  401. }
  402. /******************************Public*Routine******************************\
  403. *
  404. * __fastGenLine
  405. *
  406. * Accumulates incoming vertices in the fast line buffer
  407. * Thin line version
  408. *
  409. * History:
  410. * Mon Jan 08 19:23:19 1996 -by- Drew Bliss [drewb]
  411. * Created
  412. *
  413. \**************************************************************************/
  414. void FASTCALL __fastGenLine(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1,
  415. GLuint flags)
  416. {
  417. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  418. GENACCEL *genAccel = &gengc->genAccel;
  419. POINT pt;
  420. #ifdef DBG_VERBOSE
  421. DbgPrint("Counts %d, count %d, flags %X\n",
  422. genAccel->fastLineCounts,
  423. genAccel->pFastLineCount >= FAST_LINE_FIRST_COUNT(genAccel) ?
  424. *genAccel->pFastLineCount : -1,
  425. flags);
  426. #endif
  427. // Check for flushing conditions. We flush if:
  428. // The provoking vertex's color is different from the current color
  429. // This is the first vertex of a line and we don't have space for
  430. // a new count and two vertices
  431. // This is not the first vertex of a line and we don't have space for
  432. // a new vertex
  433. //
  434. // According to spec we have to use color form a second vertex for flat
  435. // shaded case
  436. //
  437. if (__fastGenLineSetStrokeColor(gengc, v1->color))
  438. {
  439. // Since we flushed, the current vertex is now the beginning
  440. // of a polyline
  441. flags |= __GL_LVERT_FIRST;
  442. }
  443. if (((flags & __GL_LVERT_FIRST) != 0 &&
  444. (genAccel->pFastLinePoint+1 >= FAST_LINE_LAST_POINT(genAccel) ||
  445. genAccel->pFastLineCount >= FAST_LINE_LAST_COUNT(genAccel))) ||
  446. ((flags & __GL_LVERT_FIRST) == 0 &&
  447. genAccel->pFastLinePoint >= FAST_LINE_LAST_POINT(genAccel)))
  448. {
  449. #ifdef DBG_VERBOSE
  450. DbgPrint("Overflow\n");
  451. #endif
  452. __fastGenLineEnd(gc);
  453. // Since we flushed, the current vertex is now the beginning
  454. // of a polyline
  455. flags |= __GL_LVERT_FIRST;
  456. }
  457. // If we're starting a polyline, update the counts and add
  458. // the vertex data
  459. if (flags & __GL_LVERT_FIRST)
  460. {
  461. #ifdef DBG_VERBOSE
  462. if (genAccel->pFastLineCount >= FAST_LINE_FIRST_COUNT(genAccel))
  463. {
  464. DbgPrint("First ended polyline with %d points\n",
  465. *genAccel->pFastLineCount);
  466. }
  467. #endif
  468. // Check to make sure we don't ever create segments with only
  469. // one vertex
  470. ASSERTOPENGL(genAccel->pFastLineCount <
  471. FAST_LINE_FIRST_COUNT(genAccel) ||
  472. *genAccel->pFastLineCount > 1,
  473. "Line segment with only one vertex\n");
  474. genAccel->fastLineCounts++;
  475. genAccel->pFastLineCount++;
  476. *genAccel->pFastLineCount = 1;
  477. // Compute device coordinates
  478. pt.x = __FAST_LINE_FLTTODEV(v0->window.x + genAccel->fastLineOffsetX);
  479. pt.y = __FAST_LINE_FLTTODEV(v0->window.y + genAccel->fastLineOffsetY);
  480. *(++genAccel->pFastLinePoint) = pt;
  481. }
  482. ASSERTOPENGL(genAccel->pFastLineCount >=
  483. FAST_LINE_FIRST_COUNT(genAccel) &&
  484. *genAccel->pFastLineCount > 0,
  485. "Added fast point without count\n");
  486. // Compute device coordinates
  487. pt.x = __FAST_LINE_FLTTODEV(v1->window.x + genAccel->fastLineOffsetX);
  488. pt.y = __FAST_LINE_FLTTODEV(v1->window.y + genAccel->fastLineOffsetY);
  489. (*genAccel->pFastLineCount)++;
  490. *(++genAccel->pFastLinePoint) = pt;
  491. // Check on counts also
  492. ASSERTOPENGL(genAccel->pFastLineCount <= FAST_LINE_LAST_COUNT(genAccel),
  493. "Fast line count buffer overflow\n");
  494. ASSERTOPENGL(genAccel->pFastLinePoint <= FAST_LINE_LAST_POINT(genAccel),
  495. "Fast line point buffer overflow\n");
  496. // Make sure the current color is being maintained properly
  497. ASSERTOPENGL((v1->color->r == gengc->cStroke.r) &&
  498. (gengc->gsurf.pfd.iPixelType == PFD_TYPE_COLORINDEX ||
  499. (v1->color->g == gengc->cStroke.g &&
  500. v1->color->b == gengc->cStroke.b)),
  501. "Fast line color mismatch\n");
  502. }
  503. /******************************Public*Routine******************************\
  504. *
  505. * __fastGenLineWide
  506. *
  507. * Accumulates incoming vertices in the fast line buffer
  508. * Wide line version
  509. * For wide lines we can't maintain connectivity because of the
  510. * way OpenGL wide lines are defined. Instead, each segment
  511. * of a wide line is decomposed into aliasedWidth unconnected
  512. * line segments
  513. *
  514. * History:
  515. * Tue Jan 09 11:32:10 1996 -by- Drew Bliss [drewb]
  516. * Created
  517. *
  518. \**************************************************************************/
  519. void FASTCALL __fastGenLineWide(__GLcontext *gc, __GLvertex *v0,
  520. __GLvertex *v1, GLuint flags)
  521. {
  522. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  523. GENACCEL *genAccel = &gengc->genAccel;
  524. POINT pt1, pt2;
  525. GLint width;
  526. long adjust;
  527. GLfloat dx, dy;
  528. // Set the current pen color
  529. // According to spec we have to use color form a second vertex for flat
  530. // shaded case
  531. //
  532. __fastGenLineSetStrokeColor(gengc, v1->color);
  533. // We have a wide line segment from v0 to v1
  534. // Compute its width and add an appropriate number of
  535. // side-by-side thin segments to create the wide form
  536. // Compute device coordinates
  537. pt1.x = __FAST_LINE_FLTTODEV(v0->window.x +
  538. genAccel->fastLineOffsetX);
  539. pt1.y = __FAST_LINE_FLTTODEV(v0->window.y +
  540. genAccel->fastLineOffsetY);
  541. pt2.x = __FAST_LINE_FLTTODEV(v1->window.x +
  542. genAccel->fastLineOffsetX);
  543. pt2.y = __FAST_LINE_FLTTODEV(v1->window.y +
  544. genAccel->fastLineOffsetY);
  545. width = gc->state.line.aliasedWidth;
  546. /*
  547. ** Compute the minor-axis adjustment for the first line segment
  548. ** this can be a fixed point value with 4 fractional bits
  549. */
  550. adjust = ((width - 1) * __FAST_LINE_UNIT_VALUE) / 2;
  551. // Determine the major axis
  552. dx = v0->window.x - v1->window.x;
  553. if (dx < 0.0)
  554. {
  555. dx = -dx;
  556. }
  557. dy = v0->window.y - v1->window.y;
  558. if (dy < 0.0)
  559. {
  560. dy = -dy;
  561. }
  562. if (dx > dy)
  563. {
  564. pt1.y -= adjust;
  565. pt2.y -= adjust;
  566. while (width-- > 0)
  567. {
  568. // Make sure we have room for another count and two more
  569. // vertices
  570. if (genAccel->pFastLinePoint+1 >= FAST_LINE_LAST_POINT(genAccel) ||
  571. genAccel->pFastLineCount >= FAST_LINE_LAST_COUNT(genAccel))
  572. {
  573. __fastGenLineEnd(gc);
  574. }
  575. genAccel->fastLineCounts++;
  576. genAccel->pFastLineCount++;
  577. *genAccel->pFastLineCount = 2;
  578. *(++genAccel->pFastLinePoint) = pt1;
  579. *(++genAccel->pFastLinePoint) = pt2;
  580. pt1.y++;
  581. pt2.y++;
  582. }
  583. }
  584. else
  585. {
  586. pt1.x -= adjust;
  587. pt2.x -= adjust;
  588. while (width-- > 0)
  589. {
  590. // Make sure we have room for another count and two more
  591. // vertices
  592. if (genAccel->pFastLinePoint+1 >= FAST_LINE_LAST_POINT(genAccel) ||
  593. genAccel->pFastLineCount >= FAST_LINE_LAST_COUNT(genAccel))
  594. {
  595. __fastGenLineEnd(gc);
  596. }
  597. genAccel->fastLineCounts++;
  598. genAccel->pFastLineCount++;
  599. *genAccel->pFastLineCount = 2;
  600. *(++genAccel->pFastLinePoint) = pt1;
  601. *(++genAccel->pFastLinePoint) = pt2;
  602. pt1.x++;
  603. pt2.x++;
  604. }
  605. }
  606. }
  607. #if NT_NO_BUFFER_INVARIANCE
  608. PFN_RENDER_LINE __fastGenRenderLineDIBFuncs[32] = {
  609. __fastGenRenderLineDIBCI8,
  610. __fastGenRenderLineDIBCI16,
  611. __fastGenRenderLineDIBCIRGB,
  612. __fastGenRenderLineDIBCIBGR,
  613. __fastGenRenderLineDIBCI32,
  614. NULL,
  615. NULL,
  616. NULL,
  617. __fastGenRenderLineDIBRGB8,
  618. __fastGenRenderLineDIBRGB16,
  619. __fastGenRenderLineDIBRGB,
  620. __fastGenRenderLineDIBBGR,
  621. __fastGenRenderLineDIBRGB32,
  622. NULL,
  623. NULL,
  624. NULL,
  625. __fastGenRenderLineWideDIBCI8,
  626. __fastGenRenderLineWideDIBCI16,
  627. __fastGenRenderLineWideDIBCIRGB,
  628. __fastGenRenderLineWideDIBCIBGR,
  629. __fastGenRenderLineWideDIBCI32,
  630. NULL,
  631. NULL,
  632. NULL,
  633. __fastGenRenderLineWideDIBRGB8,
  634. __fastGenRenderLineWideDIBRGB16,
  635. __fastGenRenderLineWideDIBRGB,
  636. __fastGenRenderLineWideDIBBGR,
  637. __fastGenRenderLineWideDIBRGB32,
  638. NULL,
  639. NULL,
  640. NULL
  641. };
  642. /******************************Public*Routine******************************\
  643. * __fastGenLineSetupDIB
  644. *
  645. * Initializes the accelerated line-rendering function pointer for bitmap
  646. * surfaces. All accelerated lines drawn to bitmaps are drawn by the
  647. * gc->procs.renderLine funtion pointer.
  648. *
  649. * History:
  650. * 29-Mar-1994 -by- Eddie Robinson [v-eddier]
  651. * Wrote it.
  652. \**************************************************************************/
  653. BOOL FASTCALL __fastGenLineSetupDIB(__GLcontext *gc)
  654. {
  655. __GLGENcontext *gengc = (__GLGENcontext *) gc;
  656. PIXELFORMATDESCRIPTOR *pfmt = &gengc->gsurf.pfd;
  657. GLint index;
  658. switch (pfmt->cColorBits) {
  659. case 8:
  660. index = 0;
  661. break;
  662. case 16:
  663. index = 1;
  664. break;
  665. case 24:
  666. if (pfmt->cRedShift == 0)
  667. index = 2;
  668. else
  669. index = 3;
  670. break;
  671. case 32:
  672. index = 4;
  673. break;
  674. }
  675. if (gc->polygon.shader.modeFlags & __GL_SHADE_RGB)
  676. index |= 0x08;
  677. if (gc->state.line.aliasedWidth > 1)
  678. index |= 0x10;
  679. gc->procs.renderLine = __fastGenRenderLineDIBFuncs[index];
  680. return TRUE;
  681. }
  682. void FASTCALL __fastGenRenderLineDIBRGB8(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  683. {
  684. GLint len, fraction, dfraction;
  685. __GLcolorBuffer *cfb;
  686. GLint addrBig, addrLittle;
  687. unsigned char *addr, pixel;
  688. GLint x, y;
  689. GLboolean init;
  690. CHOP_ROUND_ON();
  691. init = __glInitLineData(gc, v0, v1);
  692. CHOP_ROUND_OFF();
  693. if (!init) return;
  694. pixel = (unsigned char) __fastLineComputeColorRGB8(gc, v1->color);
  695. cfb = gc->drawBuffer;
  696. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  697. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  698. addr = (unsigned char *) ((GLint)cfb->buf.base + x +
  699. (y * cfb->buf.outerWidth));
  700. addrLittle = gc->line.options.xLittle +
  701. (gc->line.options.yLittle * cfb->buf.outerWidth);
  702. addrBig = gc->line.options.xBig +
  703. (gc->line.options.yBig * cfb->buf.outerWidth);
  704. __FAST_LINE_STROKE_DIB
  705. }
  706. void FASTCALL __fastGenRenderLineDIBRGB16(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  707. {
  708. GLint len, fraction, dfraction;
  709. __GLcolorBuffer *cfb;
  710. GLint addrBig, addrLittle;
  711. unsigned short *addr, pixel;
  712. GLint x, y, outerWidth_2;
  713. GLboolean init;
  714. CHOP_ROUND_ON();
  715. init = __glInitLineData(gc, v0, v1);
  716. CHOP_ROUND_OFF();
  717. if (!init) return;
  718. pixel = (unsigned short) __fastLineComputeColorRGB(gc, v1->color);
  719. cfb = gc->drawBuffer;
  720. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  721. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  722. addr = (unsigned short *) ((GLint)cfb->buf.base + (x << 1) +
  723. (y * cfb->buf.outerWidth));
  724. outerWidth_2 = cfb->buf.outerWidth >> 1;
  725. addrLittle = gc->line.options.xLittle +
  726. (gc->line.options.yLittle * outerWidth_2);
  727. addrBig = gc->line.options.xBig +
  728. (gc->line.options.yBig * outerWidth_2);
  729. __FAST_LINE_STROKE_DIB
  730. }
  731. void FASTCALL __fastGenRenderLineDIBRGB(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  732. {
  733. GLint len, fraction, dfraction;
  734. __GLcolor *cp;
  735. __GLcolorBuffer *cfb;
  736. GLint addrBig, addrLittle;
  737. unsigned char *addr, ir, ig, ib;
  738. GLint x, y;
  739. GLboolean init;
  740. CHOP_ROUND_ON();
  741. init = __glInitLineData(gc, v0, v1);
  742. CHOP_ROUND_OFF();
  743. if (!init) return;
  744. cp = v1->color;
  745. ir = (unsigned char) cp->r;
  746. ig = (unsigned char) cp->g;
  747. ib = (unsigned char) cp->b;
  748. cfb = gc->drawBuffer;
  749. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  750. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  751. addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
  752. (y * cfb->buf.outerWidth));
  753. addrLittle = (gc->line.options.xLittle * 3) +
  754. (gc->line.options.yLittle * cfb->buf.outerWidth);
  755. addrBig = (gc->line.options.xBig * 3) +
  756. (gc->line.options.yBig * cfb->buf.outerWidth);
  757. __FAST_LINE_STROKE_DIB24
  758. }
  759. void FASTCALL __fastGenRenderLineDIBBGR(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  760. {
  761. GLint len, fraction, dfraction;
  762. __GLcolor *cp;
  763. __GLcolorBuffer *cfb;
  764. GLint addrBig, addrLittle;
  765. unsigned char *addr, ir, ig, ib;
  766. GLint x, y;
  767. GLboolean init;
  768. CHOP_ROUND_ON();
  769. init = __glInitLineData(gc, v0, v1);
  770. CHOP_ROUND_OFF();
  771. if (!init) return;
  772. cp = v1->color;
  773. ir = (unsigned char) cp->b;
  774. ig = (unsigned char) cp->g;
  775. ib = (unsigned char) cp->r;
  776. cfb = gc->drawBuffer;
  777. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  778. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  779. addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
  780. (y * cfb->buf.outerWidth));
  781. addrLittle = (gc->line.options.xLittle * 3) +
  782. (gc->line.options.yLittle * cfb->buf.outerWidth);
  783. addrBig = (gc->line.options.xBig * 3) +
  784. (gc->line.options.yBig * cfb->buf.outerWidth);
  785. __FAST_LINE_STROKE_DIB24
  786. }
  787. void FASTCALL __fastGenRenderLineDIBRGB32(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  788. {
  789. GLint len, fraction, dfraction;
  790. __GLcolorBuffer *cfb;
  791. GLint addrBig, addrLittle;
  792. unsigned long *addr, pixel;
  793. GLint x, y, outerWidth_4;
  794. GLboolean init;
  795. CHOP_ROUND_ON();
  796. init = __glInitLineData(gc, v0, v1);
  797. CHOP_ROUND_OFF();
  798. if (!init) return;
  799. pixel = __fastLineComputeColorRGB(gc, v1->color);
  800. cfb = gc->drawBuffer;
  801. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  802. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  803. addr = (unsigned long *) ((GLint)cfb->buf.base + (x << 2) +
  804. (y * cfb->buf.outerWidth));
  805. outerWidth_4 = cfb->buf.outerWidth >> 2;
  806. addrLittle = gc->line.options.xLittle +
  807. (gc->line.options.yLittle * outerWidth_4);
  808. addrBig = gc->line.options.xBig +
  809. (gc->line.options.yBig * outerWidth_4);
  810. __FAST_LINE_STROKE_DIB
  811. }
  812. void FASTCALL __fastGenRenderLineDIBCI8(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  813. {
  814. GLint len, fraction, dfraction;
  815. __GLcolorBuffer *cfb;
  816. GLint addrBig, addrLittle;
  817. unsigned char *addr, pixel;
  818. GLint x, y;
  819. GLboolean init;
  820. CHOP_ROUND_ON();
  821. init = __glInitLineData(gc, v0, v1);
  822. CHOP_ROUND_OFF();
  823. if (!init) return;
  824. pixel = (unsigned char) __fastLineComputeColorCI4and8(gc, v1->color);
  825. cfb = gc->drawBuffer;
  826. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  827. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  828. addr = (unsigned char *) ((GLint)cfb->buf.base + x +
  829. (y * cfb->buf.outerWidth));
  830. addrLittle = gc->line.options.xLittle +
  831. (gc->line.options.yLittle * cfb->buf.outerWidth);
  832. addrBig = gc->line.options.xBig +
  833. (gc->line.options.yBig * cfb->buf.outerWidth);
  834. __FAST_LINE_STROKE_DIB
  835. }
  836. void FASTCALL __fastGenRenderLineDIBCI16(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  837. {
  838. GLint len, fraction, dfraction;
  839. __GLcolorBuffer *cfb;
  840. GLint addrBig, addrLittle;
  841. unsigned short *addr, pixel;
  842. GLint x, y, outerWidth_2;
  843. GLboolean init;
  844. CHOP_ROUND_ON();
  845. init = __glInitLineData(gc, v0, v1);
  846. CHOP_ROUND_OFF();
  847. if (!init) return;
  848. pixel = (unsigned short) __fastLineComputeColorCI(gc, v1->color);
  849. cfb = gc->drawBuffer;
  850. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  851. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  852. addr = (unsigned short *) ((GLint)cfb->buf.base + (x << 1) +
  853. (y * cfb->buf.outerWidth));
  854. outerWidth_2 = cfb->buf.outerWidth >> 1;
  855. addrLittle = gc->line.options.xLittle +
  856. (gc->line.options.yLittle * outerWidth_2);
  857. addrBig = gc->line.options.xBig +
  858. (gc->line.options.yBig * outerWidth_2);
  859. __FAST_LINE_STROKE_DIB
  860. }
  861. /*
  862. ** XXX GRE swabs bytes in palette, DIBCIRGB & DIBCIBGR are identical now
  863. */
  864. void FASTCALL __fastGenRenderLineDIBCIRGB(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  865. {
  866. GLint len, fraction, dfraction;
  867. __GLcolorBuffer *cfb;
  868. GLint addrBig, addrLittle;
  869. unsigned char *addr, ir, ig, ib;
  870. unsigned long pixel;
  871. GLint x, y;
  872. GLboolean init;
  873. CHOP_ROUND_ON();
  874. init = __glInitLineData(gc, v0, v1);
  875. CHOP_ROUND_OFF();
  876. if (!init) return;
  877. // Red is lsb of pixel
  878. pixel = __fastLineComputeColorCI(gc, v1->color);
  879. ir = (unsigned char) (pixel & 0xff);
  880. ig = (unsigned char) ((pixel >> 8) & 0xff);
  881. ib = (unsigned char) ((pixel >> 16) & 0xff);
  882. cfb = gc->drawBuffer;
  883. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  884. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  885. addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
  886. (y * cfb->buf.outerWidth));
  887. addrLittle = (gc->line.options.xLittle * 3) +
  888. (gc->line.options.yLittle * cfb->buf.outerWidth);
  889. addrBig = (gc->line.options.xBig * 3) +
  890. (gc->line.options.yBig * cfb->buf.outerWidth);
  891. __FAST_LINE_STROKE_DIB24
  892. }
  893. void FASTCALL __fastGenRenderLineDIBCIBGR(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  894. {
  895. GLint len, fraction, dfraction;
  896. __GLcolorBuffer *cfb;
  897. GLint addrBig, addrLittle;
  898. unsigned char *addr, ir, ig, ib;
  899. unsigned long pixel;
  900. GLint x, y;
  901. GLboolean init;
  902. CHOP_ROUND_ON();
  903. init = __glInitLineData(gc, v0, v1);
  904. CHOP_ROUND_OFF();
  905. if (!init) return;
  906. // Blue is lsb of pixel
  907. pixel = __fastLineComputeColorCI(gc, v1->color);
  908. // Swap blue and red
  909. ir = (unsigned char) (pixel & 0xff);
  910. ig = (unsigned char) ((pixel >> 8) & 0xff);
  911. ib = (unsigned char) ((pixel >> 16) & 0xff);
  912. cfb = gc->drawBuffer;
  913. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  914. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  915. addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
  916. (y * cfb->buf.outerWidth));
  917. addrLittle = (gc->line.options.xLittle * 3) +
  918. (gc->line.options.yLittle * cfb->buf.outerWidth);
  919. addrBig = (gc->line.options.xBig * 3) +
  920. (gc->line.options.yBig * cfb->buf.outerWidth);
  921. __FAST_LINE_STROKE_DIB24
  922. }
  923. void FASTCALL __fastGenRenderLineDIBCI32(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  924. {
  925. GLint len, fraction, dfraction;
  926. __GLcolorBuffer *cfb;
  927. GLint addrBig, addrLittle;
  928. unsigned long *addr, pixel;
  929. GLint x, y, outerWidth_4;
  930. GLboolean init;
  931. CHOP_ROUND_ON();
  932. init = __glInitLineData(gc, v0, v1);
  933. CHOP_ROUND_OFF();
  934. if (!init) return;
  935. pixel = __fastLineComputeColorCI(gc, v1->color);
  936. cfb = gc->drawBuffer;
  937. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  938. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  939. addr = (unsigned long *) ((GLint)cfb->buf.base + (x << 2) +
  940. (y * cfb->buf.outerWidth));
  941. outerWidth_4 = cfb->buf.outerWidth >> 2;
  942. addrLittle = gc->line.options.xLittle +
  943. (gc->line.options.yLittle * outerWidth_4);
  944. addrBig = gc->line.options.xBig +
  945. (gc->line.options.yBig * outerWidth_4);
  946. __FAST_LINE_STROKE_DIB
  947. }
  948. void FASTCALL __fastGenRenderLineWideDIBRGB8(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  949. {
  950. GLint len, fraction, dfraction, width, w;
  951. __GLcolorBuffer *cfb;
  952. GLint addrBig, addrLittle, addrMinor;
  953. unsigned char *addr, pixel;
  954. GLint x, y;
  955. GLboolean init;
  956. CHOP_ROUND_ON();
  957. init = __glInitLineData(gc, v0, v1);
  958. CHOP_ROUND_OFF();
  959. if (!init) return;
  960. pixel = (unsigned char) __fastLineComputeColorRGB8(gc, v1->color);
  961. cfb = gc->drawBuffer;
  962. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  963. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  964. addr = (unsigned char *) ((GLint)cfb->buf.base + x +
  965. (y * cfb->buf.outerWidth));
  966. width = gc->line.options.width;
  967. if (gc->line.options.axis == __GL_X_MAJOR) {
  968. addrMinor = cfb->buf.outerWidth;
  969. addrLittle = gc->line.options.xLittle +
  970. ((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
  971. addrBig = gc->line.options.xBig +
  972. ((gc->line.options.yBig - width) * cfb->buf.outerWidth);
  973. } else {
  974. addrMinor = 1;
  975. addrLittle = gc->line.options.xLittle - width +
  976. (gc->line.options.yLittle * cfb->buf.outerWidth);
  977. addrBig = gc->line.options.xBig - width +
  978. (gc->line.options.yBig * cfb->buf.outerWidth);
  979. }
  980. __FAST_LINE_STROKE_DIB_WIDE
  981. }
  982. void FASTCALL __fastGenRenderLineWideDIBRGB16(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  983. {
  984. GLint len, fraction, dfraction, width, w;
  985. __GLcolorBuffer *cfb;
  986. GLint addrBig, addrLittle, addrMinor;
  987. unsigned short *addr, pixel;
  988. GLint x, y, outerWidth_2;
  989. GLboolean init;
  990. CHOP_ROUND_ON();
  991. init = __glInitLineData(gc, v0, v1);
  992. CHOP_ROUND_OFF();
  993. if (!init) return;
  994. pixel = (unsigned short) __fastLineComputeColorRGB(gc, v1->color);
  995. cfb = gc->drawBuffer;
  996. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  997. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  998. addr = (unsigned short *) ((GLint)cfb->buf.base + (x << 1) +
  999. (y * cfb->buf.outerWidth));
  1000. width = gc->line.options.width;
  1001. outerWidth_2 = cfb->buf.outerWidth >> 1;
  1002. if (gc->line.options.axis == __GL_X_MAJOR) {
  1003. addrMinor = outerWidth_2;
  1004. addrLittle = gc->line.options.xLittle +
  1005. ((gc->line.options.yLittle - width) * outerWidth_2);
  1006. addrBig = gc->line.options.xBig +
  1007. ((gc->line.options.yBig - width) * outerWidth_2);
  1008. } else {
  1009. addrMinor = 1;
  1010. addrLittle = gc->line.options.xLittle - width +
  1011. (gc->line.options.yLittle * outerWidth_2);
  1012. addrBig = gc->line.options.xBig - width +
  1013. (gc->line.options.yBig * outerWidth_2);
  1014. }
  1015. __FAST_LINE_STROKE_DIB_WIDE
  1016. }
  1017. void FASTCALL __fastGenRenderLineWideDIBRGB(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  1018. {
  1019. GLint len, fraction, dfraction, width, w;
  1020. __GLcolor *cp;
  1021. __GLcolorBuffer *cfb;
  1022. GLint addrBig, addrLittle, addrMinor;
  1023. unsigned char *addr, ir, ig, ib;
  1024. GLint x, y;
  1025. GLboolean init;
  1026. CHOP_ROUND_ON();
  1027. init = __glInitLineData(gc, v0, v1);
  1028. CHOP_ROUND_OFF();
  1029. if (!init) return;
  1030. cp = v1->color;
  1031. ir = (unsigned char) cp->r;
  1032. ig = (unsigned char) cp->g;
  1033. ib = (unsigned char) cp->b;
  1034. cfb = gc->drawBuffer;
  1035. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  1036. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  1037. addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
  1038. (y * cfb->buf.outerWidth));
  1039. width = gc->line.options.width;
  1040. if (gc->line.options.axis == __GL_X_MAJOR) {
  1041. addrMinor = cfb->buf.outerWidth;
  1042. addrLittle = (gc->line.options.xLittle * 3) +
  1043. ((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
  1044. addrBig = (gc->line.options.xBig * 3) +
  1045. ((gc->line.options.yBig - width) * cfb->buf.outerWidth);
  1046. } else {
  1047. addrMinor = 3;
  1048. addrLittle = ((gc->line.options.xLittle - width) * 3) +
  1049. (gc->line.options.yLittle * cfb->buf.outerWidth);
  1050. addrBig = ((gc->line.options.xBig - width) * 3) +
  1051. (gc->line.options.yBig * cfb->buf.outerWidth);
  1052. }
  1053. __FAST_LINE_STROKE_DIB24_WIDE
  1054. }
  1055. void FASTCALL __fastGenRenderLineWideDIBBGR(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  1056. {
  1057. GLint len, fraction, dfraction, width, w;
  1058. __GLcolor *cp;
  1059. __GLcolorBuffer *cfb;
  1060. GLint addrBig, addrLittle, addrMinor;
  1061. unsigned char *addr, ir, ig, ib;
  1062. GLint x, y;
  1063. GLboolean init;
  1064. CHOP_ROUND_ON();
  1065. init = __glInitLineData(gc, v0, v1);
  1066. CHOP_ROUND_OFF();
  1067. if (!init) return;
  1068. cp = v1->color;
  1069. ir = (unsigned char) cp->b;
  1070. ig = (unsigned char) cp->g;
  1071. ib = (unsigned char) cp->r;
  1072. cfb = gc->drawBuffer;
  1073. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  1074. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  1075. addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
  1076. (y * cfb->buf.outerWidth));
  1077. width = gc->line.options.width;
  1078. if (gc->line.options.axis == __GL_X_MAJOR) {
  1079. addrMinor = cfb->buf.outerWidth;
  1080. addrLittle = (gc->line.options.xLittle * 3) +
  1081. ((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
  1082. addrBig = (gc->line.options.xBig * 3) +
  1083. ((gc->line.options.yBig - width) * cfb->buf.outerWidth);
  1084. } else {
  1085. addrMinor = 3;
  1086. addrLittle = ((gc->line.options.xLittle - width) * 3) +
  1087. (gc->line.options.yLittle * cfb->buf.outerWidth);
  1088. addrBig = ((gc->line.options.xBig - width) * 3) +
  1089. (gc->line.options.yBig * cfb->buf.outerWidth);
  1090. }
  1091. __FAST_LINE_STROKE_DIB24_WIDE
  1092. }
  1093. void FASTCALL __fastGenRenderLineWideDIBRGB32(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  1094. {
  1095. GLint len, fraction, dfraction, width, w;
  1096. __GLcolorBuffer *cfb;
  1097. GLint addrBig, addrLittle, addrMinor;
  1098. unsigned long *addr, pixel;
  1099. GLint x, y, outerWidth_4;
  1100. GLboolean init;
  1101. CHOP_ROUND_ON();
  1102. init = __glInitLineData(gc, v0, v1);
  1103. CHOP_ROUND_OFF();
  1104. if (!init) return;
  1105. pixel = __fastLineComputeColorRGB(gc, v1->color);
  1106. cfb = gc->drawBuffer;
  1107. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  1108. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  1109. addr = (unsigned long *) ((GLint)cfb->buf.base + (x << 2) +
  1110. (y * cfb->buf.outerWidth));
  1111. width = gc->line.options.width;
  1112. outerWidth_4 = cfb->buf.outerWidth >> 2;
  1113. if (gc->line.options.axis == __GL_X_MAJOR) {
  1114. addrMinor = outerWidth_4;
  1115. addrLittle = gc->line.options.xLittle +
  1116. ((gc->line.options.yLittle - width) * outerWidth_4);
  1117. addrBig = gc->line.options.xBig +
  1118. ((gc->line.options.yBig - width) * outerWidth_4);
  1119. } else {
  1120. addrMinor = 1;
  1121. addrLittle = gc->line.options.xLittle - width +
  1122. (gc->line.options.yLittle * outerWidth_4);
  1123. addrBig = gc->line.options.xBig - width +
  1124. (gc->line.options.yBig * outerWidth_4);
  1125. }
  1126. __FAST_LINE_STROKE_DIB_WIDE
  1127. }
  1128. void FASTCALL __fastGenRenderLineWideDIBCI8(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  1129. {
  1130. GLint len, fraction, dfraction, width, w;
  1131. __GLcolorBuffer *cfb;
  1132. GLint addrBig, addrLittle, addrMinor;
  1133. unsigned char *addr, pixel;
  1134. GLint x, y;
  1135. GLboolean init;
  1136. CHOP_ROUND_ON();
  1137. init = __glInitLineData(gc, v0, v1);
  1138. CHOP_ROUND_OFF();
  1139. if (!init) return;
  1140. pixel = (unsigned char) __fastLineComputeColorCI4and8(gc, v1->color);
  1141. cfb = gc->drawBuffer;
  1142. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  1143. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  1144. addr = (unsigned char *) ((GLint)cfb->buf.base + x +
  1145. (y * cfb->buf.outerWidth));
  1146. width = gc->line.options.width;
  1147. if (gc->line.options.axis == __GL_X_MAJOR) {
  1148. addrMinor = cfb->buf.outerWidth;
  1149. addrLittle = gc->line.options.xLittle +
  1150. ((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
  1151. addrBig = gc->line.options.xBig +
  1152. ((gc->line.options.yBig - width) * cfb->buf.outerWidth);
  1153. } else {
  1154. addrMinor = 1;
  1155. addrLittle = gc->line.options.xLittle - width +
  1156. (gc->line.options.yLittle * cfb->buf.outerWidth);
  1157. addrBig = gc->line.options.xBig - width +
  1158. (gc->line.options.yBig * cfb->buf.outerWidth);
  1159. }
  1160. __FAST_LINE_STROKE_DIB_WIDE
  1161. }
  1162. void FASTCALL __fastGenRenderLineWideDIBCI16(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  1163. {
  1164. GLint len, fraction, dfraction, width, w;
  1165. __GLcolorBuffer *cfb;
  1166. GLint addrBig, addrLittle, addrMinor;
  1167. unsigned short *addr, pixel;
  1168. GLint x, y, outerWidth_2;
  1169. GLboolean init;
  1170. CHOP_ROUND_ON();
  1171. init = __glInitLineData(gc, v0, v1);
  1172. CHOP_ROUND_OFF();
  1173. if (!init) return;
  1174. pixel = (unsigned short) __fastLineComputeColorCI(gc, v1->color);
  1175. cfb = gc->drawBuffer;
  1176. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  1177. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  1178. addr = (unsigned short *) ((GLint)cfb->buf.base + (x << 1) +
  1179. (y * cfb->buf.outerWidth));
  1180. width = gc->line.options.width;
  1181. outerWidth_2 = cfb->buf.outerWidth >> 1;
  1182. if (gc->line.options.axis == __GL_X_MAJOR) {
  1183. addrMinor = outerWidth_2;
  1184. addrLittle = gc->line.options.xLittle +
  1185. ((gc->line.options.yLittle - width) * outerWidth_2);
  1186. addrBig = gc->line.options.xBig +
  1187. ((gc->line.options.yBig - width) * outerWidth_2);
  1188. } else {
  1189. addrMinor = 1;
  1190. addrLittle = gc->line.options.xLittle - width +
  1191. (gc->line.options.yLittle * outerWidth_2);
  1192. addrBig = gc->line.options.xBig - width +
  1193. (gc->line.options.yBig * outerWidth_2);
  1194. }
  1195. __FAST_LINE_STROKE_DIB_WIDE
  1196. }
  1197. void FASTCALL __fastGenRenderLineWideDIBCIRGB(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  1198. {
  1199. GLint len, fraction, dfraction, width, w;
  1200. __GLcolorBuffer *cfb;
  1201. GLint addrBig, addrLittle, addrMinor;
  1202. unsigned char *addr, ir, ig, ib;
  1203. unsigned long pixel;
  1204. GLint x, y;
  1205. GLboolean init;
  1206. CHOP_ROUND_ON();
  1207. init = __glInitLineData(gc, v0, v1);
  1208. CHOP_ROUND_OFF();
  1209. if (!init) return;
  1210. // Red is lsb of pixel
  1211. pixel = __fastLineComputeColorCI(gc, v1->color);
  1212. ir = (unsigned char) (pixel & 0xff);
  1213. ig = (unsigned char) ((pixel >> 8) & 0xff);
  1214. ib = (unsigned char) ((pixel >> 16) & 0xff);
  1215. cfb = gc->drawBuffer;
  1216. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  1217. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  1218. addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
  1219. (y * cfb->buf.outerWidth));
  1220. width = gc->line.options.width;
  1221. if (gc->line.options.axis == __GL_X_MAJOR) {
  1222. addrMinor = cfb->buf.outerWidth;
  1223. addrLittle = (gc->line.options.xLittle * 3) +
  1224. ((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
  1225. addrBig = (gc->line.options.xBig * 3) +
  1226. ((gc->line.options.yBig - width) * cfb->buf.outerWidth);
  1227. } else {
  1228. addrMinor = 3;
  1229. addrLittle = ((gc->line.options.xLittle - width) * 3) +
  1230. (gc->line.options.yLittle * cfb->buf.outerWidth);
  1231. addrBig = ((gc->line.options.xBig - width) * 3) +
  1232. (gc->line.options.yBig * cfb->buf.outerWidth);
  1233. }
  1234. __FAST_LINE_STROKE_DIB24_WIDE
  1235. }
  1236. void FASTCALL __fastGenRenderLineWideDIBCIBGR(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  1237. {
  1238. GLint len, fraction, dfraction, width, w;
  1239. __GLcolorBuffer *cfb;
  1240. GLint addrBig, addrLittle, addrMinor;
  1241. unsigned char *addr, ir, ig, ib;
  1242. unsigned long pixel;
  1243. GLint x, y;
  1244. GLboolean init;
  1245. CHOP_ROUND_ON();
  1246. init = __glInitLineData(gc, v0, v1);
  1247. CHOP_ROUND_OFF();
  1248. if (!init) return;
  1249. // Blue is lsb of pixel
  1250. pixel = __fastLineComputeColorCI(gc, v1->color);
  1251. // Swap blue and red
  1252. ir = (unsigned char) (pixel & 0xff);
  1253. ig = (unsigned char) ((pixel >> 8) & 0xff);
  1254. ib = (unsigned char) ((pixel >> 16) & 0xff);
  1255. cfb = gc->drawBuffer;
  1256. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  1257. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  1258. addr = (unsigned char *) ((GLint)cfb->buf.base + (x * 3) +
  1259. (y * cfb->buf.outerWidth));
  1260. width = gc->line.options.width;
  1261. if (gc->line.options.axis == __GL_X_MAJOR) {
  1262. addrMinor = cfb->buf.outerWidth;
  1263. addrLittle = (gc->line.options.xLittle * 3) +
  1264. ((gc->line.options.yLittle - width) * cfb->buf.outerWidth);
  1265. addrBig = (gc->line.options.xBig * 3) +
  1266. ((gc->line.options.yBig - width) * cfb->buf.outerWidth);
  1267. } else {
  1268. addrMinor = 3;
  1269. addrLittle = ((gc->line.options.xLittle - width) * 3) +
  1270. (gc->line.options.yLittle * cfb->buf.outerWidth);
  1271. addrBig = ((gc->line.options.xBig - width) * 3) +
  1272. (gc->line.options.yBig * cfb->buf.outerWidth);
  1273. }
  1274. __FAST_LINE_STROKE_DIB24_WIDE
  1275. }
  1276. void FASTCALL __fastGenRenderLineWideDIBCI32(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  1277. {
  1278. GLint len, fraction, dfraction, width, w;
  1279. __GLcolorBuffer *cfb;
  1280. GLint addrBig, addrLittle, addrMinor;
  1281. unsigned long *addr, pixel;
  1282. GLint x, y, outerWidth_4;
  1283. GLboolean init;
  1284. CHOP_ROUND_ON();
  1285. init = __glInitLineData(gc, v0, v1);
  1286. CHOP_ROUND_OFF();
  1287. if (!init) return;
  1288. pixel = __fastLineComputeColorCI(gc, v1->color);
  1289. cfb = gc->drawBuffer;
  1290. x = __GL_UNBIAS_X(gc, gc->line.options.xStart) + cfb->buf.xOrigin;
  1291. y = __GL_UNBIAS_Y(gc, gc->line.options.yStart) + cfb->buf.yOrigin;
  1292. addr = (unsigned long *) ((GLint)cfb->buf.base + (x << 2) +
  1293. (y * cfb->buf.outerWidth));
  1294. width = gc->line.options.width;
  1295. outerWidth_4 = cfb->buf.outerWidth >> 2;
  1296. if (gc->line.options.axis == __GL_X_MAJOR) {
  1297. addrMinor = outerWidth_4;
  1298. addrLittle = gc->line.options.xLittle +
  1299. ((gc->line.options.yLittle - width) * outerWidth_4);
  1300. addrBig = gc->line.options.xBig +
  1301. ((gc->line.options.yBig - width) * outerWidth_4);
  1302. } else {
  1303. addrMinor = 1;
  1304. addrLittle = gc->line.options.xLittle - width +
  1305. (gc->line.options.yLittle * outerWidth_4);
  1306. addrBig = gc->line.options.xBig - width +
  1307. (gc->line.options.yBig * outerWidth_4);
  1308. }
  1309. __FAST_LINE_STROKE_DIB_WIDE
  1310. }
  1311. #endif //NT_NO_BUFFER_INVARIANCE