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.

455 lines
12 KiB

  1. /******************************Module*Header*******************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: Lineto.c
  8. *
  9. * DrvLineTo for S3 driver
  10. *
  11. * Copyright (c) 1995-1998 Microsoft Corporation
  12. \**************************************************************************/
  13. #include "precomp.h"
  14. // For the S3, we use the following flags to denote the quadrant, and
  15. // we use this as an index into 'gaiLineBias' to determine the Bresenham
  16. // error bias:
  17. #define QUAD_PLUS_X 1
  18. #define QUAD_MAJOR_Y 2
  19. #define QUAD_PLUS_Y 4
  20. LONG gaiLineBias[] = { 0, 0, 0, 1, 1, 1, 0, 1 };
  21. // We shift these flags by 'QUADRANT_SHIFT' to send the actual
  22. // command to the S3:
  23. #define QUADRANT_SHIFT 5
  24. /******************************Public*Routine******************************\
  25. * VOID vNwLineToTrivial
  26. *
  27. * Draws a single solid integer-only unclipped cosmetic line using
  28. * 'New MM I/O'.
  29. *
  30. * We can't use the point-to-point capabilities of the S3 because its
  31. * tie-breaker convention doesn't match that of NT's in two octants,
  32. * and would cause us to fail HCTs.
  33. *
  34. \**************************************************************************/
  35. VOID vNwLineToTrivial(
  36. PDEV* ppdev,
  37. LONG x, // Passed in x1
  38. LONG y, // Passed in y1
  39. LONG dx, // Passed in x2
  40. LONG dy, // Passed in y2
  41. ULONG iSolidColor, // -1 means hardware is already set up
  42. MIX mix)
  43. {
  44. BYTE* pjMmBase;
  45. FLONG flQuadrant;
  46. pjMmBase = ppdev->pjMmBase;
  47. NW_FIFO_WAIT(ppdev, pjMmBase, 8);
  48. if (iSolidColor != (ULONG) -1)
  49. {
  50. NW_FRGD_COLOR(ppdev, pjMmBase, iSolidColor);
  51. NW_ALT_MIX(ppdev, pjMmBase, FOREGROUND_COLOR |
  52. gajHwMixFromMix[mix & 0xf], 0);
  53. MM_PIX_CNTL(ppdev, pjMmBase, ALL_ONES);
  54. }
  55. NW_ABS_CURXY(ppdev, pjMmBase, x, y);
  56. flQuadrant = (QUAD_PLUS_X | QUAD_PLUS_Y);
  57. dx -= x;
  58. if (dx < 0)
  59. {
  60. dx = -dx;
  61. flQuadrant &= ~QUAD_PLUS_X;
  62. }
  63. dy -= y;
  64. if (dy < 0)
  65. {
  66. dy = -dy;
  67. flQuadrant &= ~QUAD_PLUS_Y;
  68. }
  69. if (dy > dx)
  70. {
  71. register LONG l;
  72. l = dy;
  73. dy = dx;
  74. dx = l; // Swap 'dx' and 'dy'
  75. flQuadrant |= QUAD_MAJOR_Y;
  76. }
  77. NW_ALT_PCNT(ppdev, pjMmBase, dx, 0);
  78. NW_ALT_STEP(ppdev, pjMmBase, dy - dx, dy);
  79. NW_ALT_ERR(ppdev, pjMmBase, 0,
  80. (dy + dy - dx - gaiLineBias[flQuadrant]) >> 1);
  81. NW_ALT_CMD(ppdev, pjMmBase, (flQuadrant << QUADRANT_SHIFT) |
  82. (DRAW_LINE | DRAW | DIR_TYPE_XY |
  83. MULTIPLE_PIXELS | WRITE | LAST_PIXEL_OFF));
  84. }
  85. /******************************Public*Routine******************************\
  86. * VOID vNwLineToClipped
  87. *
  88. * Draws a single solid integer-only clipped cosmetic line using
  89. * 'New MM I/O'.
  90. *
  91. \**************************************************************************/
  92. VOID vNwLineToClipped(
  93. PDEV* ppdev,
  94. LONG x1,
  95. LONG y1,
  96. LONG x2,
  97. LONG y2,
  98. ULONG iSolidColor,
  99. MIX mix,
  100. RECTL* prclClip)
  101. {
  102. BYTE* pjMmBase;
  103. LONG xOffset;
  104. LONG yOffset;
  105. pjMmBase = ppdev->pjMmBase;
  106. xOffset = ppdev->xOffset;
  107. yOffset = ppdev->yOffset;
  108. NW_FIFO_WAIT(ppdev, pjMmBase, 2);
  109. NW_ABS_SCISSORS_LT(ppdev, pjMmBase,
  110. prclClip->left + xOffset,
  111. prclClip->top + yOffset);
  112. NW_ABS_SCISSORS_RB(ppdev, pjMmBase,
  113. prclClip->right + xOffset - 1,
  114. prclClip->bottom + yOffset - 1);
  115. vNwLineToTrivial(ppdev, x1, y1, x2, y2, iSolidColor, mix);
  116. NW_FIFO_WAIT(ppdev, pjMmBase, 2);
  117. NW_ABS_SCISSORS_LT(ppdev, pjMmBase, 0, 0);
  118. NW_ABS_SCISSORS_RB(ppdev, pjMmBase,
  119. ppdev->cxMemory - 1,
  120. ppdev->cyMemory - 1);
  121. }
  122. /******************************Public*Routine******************************\
  123. * VOID vMmLineToTrivial
  124. *
  125. * Draws a single solid integer-only unclipped cosmetic line using
  126. * 'Old MM I/O'.
  127. *
  128. \**************************************************************************/
  129. VOID vMmLineToTrivial(
  130. PDEV* ppdev,
  131. LONG x, // Passed in x1
  132. LONG y, // Passed in y1
  133. LONG dx, // Passed in x2
  134. LONG dy, // Passed in y2
  135. ULONG iSolidColor, // -1 means hardware is already set up
  136. MIX mix)
  137. {
  138. BYTE* pjMmBase;
  139. FLONG flQuadrant;
  140. pjMmBase = ppdev->pjMmBase;
  141. if (iSolidColor != (ULONG) -1)
  142. {
  143. IO_FIFO_WAIT(ppdev, 3);
  144. MM_FRGD_COLOR(ppdev, pjMmBase, iSolidColor);
  145. MM_FRGD_MIX(ppdev, pjMmBase, FOREGROUND_COLOR | gajHwMixFromMix[mix & 0xf]);
  146. MM_PIX_CNTL(ppdev, pjMmBase, ALL_ONES);
  147. }
  148. IO_FIFO_WAIT(ppdev, 7);
  149. MM_ABS_CUR_X(ppdev, pjMmBase, x);
  150. MM_ABS_CUR_Y(ppdev, pjMmBase, y);
  151. flQuadrant = (QUAD_PLUS_X | QUAD_PLUS_Y);
  152. dx -= x;
  153. if (dx < 0)
  154. {
  155. dx = -dx;
  156. flQuadrant &= ~QUAD_PLUS_X;
  157. }
  158. dy -= y;
  159. if (dy < 0)
  160. {
  161. dy = -dy;
  162. flQuadrant &= ~QUAD_PLUS_Y;
  163. }
  164. if (dy > dx)
  165. {
  166. register LONG l;
  167. l = dy;
  168. dy = dx;
  169. dx = l; // Swap 'dx' and 'dy'
  170. flQuadrant |= QUAD_MAJOR_Y;
  171. }
  172. MM_MAJ_AXIS_PCNT(ppdev, pjMmBase, dx);
  173. MM_AXSTP(ppdev, pjMmBase, dy);
  174. MM_DIASTP(ppdev, pjMmBase, dy - dx);
  175. MM_ERR_TERM(ppdev, pjMmBase,
  176. (dy + dy - dx - gaiLineBias[flQuadrant]) >> 1);
  177. MM_CMD(ppdev, pjMmBase, (flQuadrant << QUADRANT_SHIFT) |
  178. (DRAW_LINE | DRAW | DIR_TYPE_XY |
  179. MULTIPLE_PIXELS | WRITE | LAST_PIXEL_OFF));
  180. }
  181. /******************************Public*Routine******************************\
  182. * VOID vMmLineToClipped
  183. *
  184. * Draws a single solid integer-only clipped cosmetic line using
  185. * 'Old MM I/O'.
  186. *
  187. \**************************************************************************/
  188. VOID vMmLineToClipped(
  189. PDEV* ppdev,
  190. LONG x1,
  191. LONG y1,
  192. LONG x2,
  193. LONG y2,
  194. ULONG iSolidColor,
  195. MIX mix,
  196. RECTL* prclClip)
  197. {
  198. BYTE* pjMmBase;
  199. LONG xOffset;
  200. LONG yOffset;
  201. pjMmBase = ppdev->pjMmBase;
  202. xOffset = ppdev->xOffset;
  203. yOffset = ppdev->yOffset;
  204. IO_FIFO_WAIT(ppdev, 4);
  205. MM_ABS_SCISSORS_L(ppdev, pjMmBase, prclClip->left + xOffset);
  206. MM_ABS_SCISSORS_R(ppdev, pjMmBase, prclClip->right + xOffset - 1);
  207. MM_ABS_SCISSORS_T(ppdev, pjMmBase, prclClip->top + yOffset);
  208. MM_ABS_SCISSORS_B(ppdev, pjMmBase, prclClip->bottom + yOffset - 1);
  209. vMmLineToTrivial(ppdev, x1, y1, x2, y2, iSolidColor, mix);
  210. IO_FIFO_WAIT(ppdev, 4);
  211. MM_ABS_SCISSORS_L(ppdev, pjMmBase, 0);
  212. MM_ABS_SCISSORS_T(ppdev, pjMmBase, 0);
  213. MM_ABS_SCISSORS_R(ppdev, pjMmBase, ppdev->cxMemory - 1);
  214. MM_ABS_SCISSORS_B(ppdev, pjMmBase, ppdev->cyMemory - 1);
  215. }
  216. /******************************Public*Routine******************************\
  217. * VOID vIoLineToTrivial
  218. *
  219. * Draws a single solid integer-only unclipped cosmetic line using
  220. * 'Old I/O'.
  221. *
  222. \**************************************************************************/
  223. VOID vIoLineToTrivial(
  224. PDEV* ppdev,
  225. LONG x, // Passed in x1
  226. LONG y, // Passed in y1
  227. LONG dx, // Passed in x2
  228. LONG dy, // Passed in y2
  229. ULONG iSolidColor, // -1 means hardware is already set up
  230. MIX mix)
  231. {
  232. BYTE* pjMmBase;
  233. FLONG flQuadrant;
  234. pjMmBase = ppdev->pjMmBase;
  235. if (iSolidColor != (ULONG) -1)
  236. {
  237. IO_FIFO_WAIT(ppdev, 4);
  238. if (DEPTH32(ppdev))
  239. {
  240. IO_FRGD_COLOR32(ppdev, iSolidColor);
  241. }
  242. else
  243. {
  244. IO_FRGD_COLOR(ppdev, iSolidColor);
  245. }
  246. IO_FRGD_MIX(ppdev, FOREGROUND_COLOR | gajHwMixFromMix[mix & 0xf]);
  247. IO_PIX_CNTL(ppdev, ALL_ONES);
  248. }
  249. IO_FIFO_WAIT(ppdev, 7);
  250. IO_ABS_CUR_X(ppdev, x);
  251. IO_ABS_CUR_Y(ppdev, y);
  252. flQuadrant = (QUAD_PLUS_X | QUAD_PLUS_Y);
  253. dx -= x;
  254. if (dx < 0)
  255. {
  256. dx = -dx;
  257. flQuadrant &= ~QUAD_PLUS_X;
  258. }
  259. dy -= y;
  260. if (dy < 0)
  261. {
  262. dy = -dy;
  263. flQuadrant &= ~QUAD_PLUS_Y;
  264. }
  265. if (dy > dx)
  266. {
  267. register LONG l;
  268. l = dy;
  269. dy = dx;
  270. dx = l; // Swap 'dx' and 'dy'
  271. flQuadrant |= QUAD_MAJOR_Y;
  272. }
  273. IO_MAJ_AXIS_PCNT(ppdev, dx);
  274. IO_AXSTP(ppdev, dy);
  275. IO_DIASTP(ppdev, dy - dx);
  276. IO_ERR_TERM(ppdev, (dy + dy - dx - gaiLineBias[flQuadrant]) >> 1);
  277. IO_CMD(ppdev, (flQuadrant << QUADRANT_SHIFT) |
  278. (DRAW_LINE | DRAW | DIR_TYPE_XY |
  279. MULTIPLE_PIXELS | WRITE | LAST_PIXEL_OFF));
  280. }
  281. /******************************Public*Routine******************************\
  282. * VOID vIoLineToClipped
  283. *
  284. * Draws a single solid integer-only clipped cosmetic line using
  285. * 'Old I/O'.
  286. *
  287. \**************************************************************************/
  288. VOID vIoLineToClipped(
  289. PDEV* ppdev,
  290. LONG x1,
  291. LONG y1,
  292. LONG x2,
  293. LONG y2,
  294. ULONG iSolidColor,
  295. MIX mix,
  296. RECTL* prclClip)
  297. {
  298. BYTE* pjMmBase;
  299. LONG xOffset;
  300. LONG yOffset;
  301. pjMmBase = ppdev->pjMmBase;
  302. xOffset = ppdev->xOffset;
  303. yOffset = ppdev->yOffset;
  304. IO_FIFO_WAIT(ppdev, 4);
  305. IO_ABS_SCISSORS_L(ppdev, prclClip->left + xOffset);
  306. IO_ABS_SCISSORS_R(ppdev, prclClip->right + xOffset - 1);
  307. IO_ABS_SCISSORS_T(ppdev, prclClip->top + yOffset);
  308. IO_ABS_SCISSORS_B(ppdev, prclClip->bottom + yOffset - 1);
  309. vIoLineToTrivial(ppdev, x1, y1, x2, y2, iSolidColor, mix);
  310. IO_FIFO_WAIT(ppdev, 4);
  311. IO_ABS_SCISSORS_L(ppdev, 0);
  312. IO_ABS_SCISSORS_T(ppdev, 0);
  313. IO_ABS_SCISSORS_R(ppdev, ppdev->cxMemory - 1);
  314. IO_ABS_SCISSORS_B(ppdev, ppdev->cyMemory - 1);
  315. }
  316. /******************************Public*Routine******************************\
  317. * BOOL DrvLineTo(pso, pco, pbo, x1, y1, x2, y2, prclBounds, mix)
  318. *
  319. * Draws a single solid integer-only cosmetic line.
  320. *
  321. \**************************************************************************/
  322. BOOL DrvLineTo(
  323. SURFOBJ* pso,
  324. CLIPOBJ* pco,
  325. BRUSHOBJ* pbo,
  326. LONG x1,
  327. LONG y1,
  328. LONG x2,
  329. LONG y2,
  330. RECTL* prclBounds,
  331. MIX mix)
  332. {
  333. PDEV* ppdev;
  334. DSURF* pdsurf;
  335. LONG xOffset;
  336. LONG yOffset;
  337. BOOL bRet;
  338. // Pass the surface off to GDI if it's a device bitmap that we've
  339. // converted to a DIB:
  340. pdsurf = (DSURF*) pso->dhsurf;
  341. ASSERTDD(!(pdsurf->dt & DT_DIB), "Didn't expect DT_DIB");
  342. // We'll be drawing to the screen or an off-screen DFB; copy the surface's
  343. // offset now so that we won't need to refer to the DSURF again:
  344. ppdev = (PDEV*) pso->dhpdev;
  345. xOffset = pdsurf->x;
  346. yOffset = pdsurf->y;
  347. x1 += xOffset;
  348. x2 += xOffset;
  349. y1 += yOffset;
  350. y2 += yOffset;
  351. bRet = TRUE;
  352. if (pco == NULL)
  353. {
  354. ppdev->pfnLineToTrivial(ppdev, x1, y1, x2, y2, pbo->iSolidColor, mix);
  355. }
  356. else if ((pco->iDComplexity <= DC_RECT) &&
  357. (prclBounds->left >= MIN_INTEGER_BOUND) &&
  358. (prclBounds->top >= MIN_INTEGER_BOUND) &&
  359. (prclBounds->right <= MAX_INTEGER_BOUND) &&
  360. (prclBounds->bottom <= MAX_INTEGER_BOUND))
  361. {
  362. // s3 diamond 968 doesn't like negative x coordinates.
  363. if ((ppdev->iBitmapFormat == BMF_24BPP) && (prclBounds->left < 0))
  364. return FALSE;
  365. ppdev->xOffset = xOffset;
  366. ppdev->yOffset = yOffset;
  367. ppdev->pfnLineToClipped(ppdev, x1, y1, x2, y2, pbo->iSolidColor, mix,
  368. &pco->rclBounds);
  369. }
  370. else
  371. {
  372. bRet = FALSE;
  373. }
  374. return(bRet);
  375. }