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.

348 lines
11 KiB

  1. /******************************************************************************\
  2. *
  3. * $Workfile: lineto.c $
  4. *
  5. * Contents:
  6. * This file contains the DrvLineTo function and line drawing code for the
  7. * CL-GD546x chips.
  8. *
  9. * Copyright (c) 1996 Cirrus Logic, Inc.
  10. *
  11. * $Log: X:/log/laguna/nt35/displays/cl546x/lineto.c $
  12. *
  13. * Rev 1.19 Mar 04 1998 15:27:54 frido
  14. * Added new shadow macros.
  15. *
  16. * Rev 1.18 Feb 27 1998 15:43:14 frido
  17. * Roll back of 1.16.
  18. * Removed sloped lines.
  19. *
  20. * Rev 1.17 Feb 26 1998 17:16:32 frido
  21. * Removed diagonal line drawing.
  22. * Optimized horizontal and vertical line drawing.
  23. *
  24. * Rev 1.16 Jan 26 1998 09:59:12 frido
  25. * A complete rewrite. Ported most code from Alpine NT driver (I already did
  26. * most of the work for that driver) and fixed all bugs in it.
  27. *
  28. * Rev 1.15 Nov 03 1997 15:46:04 frido
  29. * Added REQUIRE macros.
  30. *
  31. * Rev 1.14 08 Apr 1997 12:25:36 einkauf
  32. *
  33. * add SYNC_W_3D to coordinat MCD/2D hw access
  34. *
  35. *
  36. * Rev 1.13 21 Mar 1997 11:43:20 noelv
  37. *
  38. * Combined 'do_flag' and 'sw_test_flag' together into 'pointer_switch'
  39. *
  40. * Rev 1.12 04 Feb 1997 10:38:34 SueS
  41. * Added another ifdef to the punt condition, because there's a hardware
  42. * bug in the 2D clip engine.
  43. *
  44. * Rev 1.11 27 Jan 1997 13:08:36 noelv
  45. * Don't compile hardware clipping for 5464 chip.
  46. *
  47. * Rev 1.10 27 Jan 1997 07:58:06 SueS
  48. * Punt for the 5462/64. There was a problem with clipping on the 62.
  49. *
  50. * Rev 1.9 23 Jan 1997 15:25:34 SueS
  51. * Added support for hardware clipping in the 5465. For all 546x family,
  52. * punt on complex clipping.
  53. *
  54. * Rev 1.8 10 Jan 1997 17:23:48 SueS
  55. * Reenabled DrvLineTo. Modified clipping function. Added boundary
  56. * condition tests.
  57. *
  58. * Rev 1.7 08 Jan 1997 14:40:48 SueS
  59. * Temporarily punt on all DrvLineTo calls.
  60. *
  61. * Rev 1.6 08 Jan 1997 09:33:24 SueS
  62. * Punt in DrvLineTo for complex clipping.
  63. *
  64. * Rev 1.5 06 Jan 1997 10:32:06 SueS
  65. * Modified line drawing functions so that clipping is applied properly, and
  66. * so that pixels for lines with y as the driving axis drawn from top to
  67. * bottom will now be calculated correctly. Changed debug statements to hex.
  68. *
  69. * Rev 1.4 26 Nov 1996 10:43:02 noelv
  70. * Changed debug level.
  71. *
  72. * Rev 1.3 26 Nov 1996 10:01:22 noelv
  73. *
  74. * Changed Debug prints.
  75. *
  76. * Rev 1.2 06 Sep 1996 15:16:26 noelv
  77. * Updated NULL driver for 4.0
  78. *
  79. * Rev 1.1 28 Aug 1996 17:25:04 noelv
  80. * Added #IFDEF to prevent this file from being compiled into 3.51 driver.
  81. *
  82. * Rev 1.0 20 Aug 1996 11:38:46 noelv
  83. * Initial revision.
  84. *
  85. * Rev 1.0 18 Aug 1996 22:52:18 frido
  86. * Ported from CL-GD5446 code.
  87. *
  88. \******************************************************************************/
  89. #include "PreComp.h"
  90. #define LINETO_DBG_LEVEL 1
  91. #define LEFT 0x01
  92. #define RIGHT 0x02
  93. #define TOP 0x04
  94. #define BOTTOM 0x08
  95. extern BYTE Rop2ToRop3[];
  96. extern USHORT mixToBLTDEF[];
  97. //
  98. // This file isn't used in NT 3.51
  99. //
  100. #ifndef WINNT_VER35
  101. /******************************************************************************\
  102. *
  103. * Function: DrvLineTo
  104. *
  105. * This function draws a line between any two points. This function only draws
  106. * lines in solid colors and are just 1 pixel wide. The end-point is not drawn.
  107. *
  108. * Parameters: pso Pointer to surface.
  109. * pco Pointer to CLIPOBJ.
  110. * pbo Pointer to BRUSHOBJ.
  111. * x1 Starting x-coordinate.
  112. * y1 Starting y-coordinate.
  113. * x2 Ending x-coordinate.
  114. * y2 Ending y-coordinate.
  115. * prclBounds Pointer to an unclipped bounding rectangle.
  116. * mix Mix to perform on the destination.
  117. *
  118. * Returns: TRUE if the line has been drawn, FALSE otherwise.
  119. *
  120. \******************************************************************************/
  121. BOOL DrvLineTo(
  122. SURFOBJ* pso,
  123. CLIPOBJ* pco,
  124. BRUSHOBJ* pbo,
  125. LONG x1,
  126. LONG y1,
  127. LONG x2,
  128. LONG y2,
  129. RECTL* prclBounds,
  130. MIX mix)
  131. {
  132. PDEV* ppdev;
  133. ULONG ulColor;
  134. BYTE iDComplexity;
  135. LONG dx, dy;
  136. BYTE bCode1 = 0, bCode2 = 0;
  137. RECTL rclClip1, rclClip2;
  138. #if NULL_LINETO
  139. {
  140. if (pointer_switch)
  141. {
  142. return(TRUE);
  143. }
  144. }
  145. #endif
  146. DISPDBG((LINETO_DBG_LEVEL, "DrvLineTo: %x,%x - %x,%x\n", x1, y1, x2, y2));
  147. ppdev = (PDEV*) pso->dhpdev;
  148. SYNC_W_3D(ppdev);
  149. if (pso->iType == STYPE_DEVBITMAP)
  150. {
  151. DSURF* pdsurf = (DSURF*) pso->dhsurf;
  152. // If the device bitmap is located in memory, try copying it back to
  153. // off-screen.
  154. if ( pdsurf->pso && !bCreateScreenFromDib(ppdev, pdsurf) )
  155. {
  156. return(EngLineTo(pdsurf->pso, pco, pbo, x1, y1, x2, y2, prclBounds,
  157. mix));
  158. }
  159. ppdev->ptlOffset = pdsurf->ptl;
  160. }
  161. else
  162. {
  163. ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
  164. }
  165. // Punt complex clipping.
  166. iDComplexity = (pco == NULL) ? DC_TRIVIAL : pco->iDComplexity;
  167. if (iDComplexity == DC_COMPLEX)
  168. {
  169. DISPDBG((LINETO_DBG_LEVEL, " Complex clipping: punt\n"));
  170. return(FALSE);
  171. }
  172. // Set line deltas.
  173. dx = x2 - x1;
  174. dy = y2 - y1;
  175. // We only handle horizontal and vertical lines.
  176. if ( (dx != 0) && (dy != 0) )
  177. {
  178. return(FALSE);
  179. }
  180. // Test for zero deltas.
  181. if ( (dx == 0) && (dy == 0) )
  182. {
  183. return(TRUE);
  184. }
  185. // Clip the coordinates.
  186. if (iDComplexity == DC_RECT)
  187. {
  188. // Set clipping rectangles.
  189. rclClip1.left = pco->rclBounds.left;
  190. rclClip1.top = pco->rclBounds.top;
  191. rclClip1.right = pco->rclBounds.right - 1;
  192. rclClip1.bottom = pco->rclBounds.bottom - 1;
  193. rclClip2.left = pco->rclBounds.left - 1;
  194. rclClip2.top = pco->rclBounds.top - 1;
  195. rclClip2.right = pco->rclBounds.right;
  196. rclClip2.bottom = pco->rclBounds.bottom;
  197. // Set line flags.
  198. if (x1 < rclClip1.left) bCode1 |= LEFT;
  199. if (y1 < rclClip1.top) bCode1 |= TOP;
  200. if (x1 > rclClip1.right) bCode1 |= RIGHT;
  201. if (y1 > rclClip1.bottom) bCode1 |= BOTTOM;
  202. if (x2 < rclClip2.left) bCode2 |= LEFT;
  203. if (y2 < rclClip2.top) bCode2 |= TOP;
  204. if (x2 > rclClip2.right) bCode2 |= RIGHT;
  205. if (y2 > rclClip2.bottom) bCode2 |= BOTTOM;
  206. if ((bCode1 & bCode2) != 0)
  207. {
  208. // The line is completely clipped.
  209. return(TRUE);
  210. }
  211. // Vertical line.
  212. if (dx == 0)
  213. {
  214. if (bCode1 & TOP)
  215. {
  216. y1 = rclClip1.top;
  217. }
  218. else if (bCode1 & BOTTOM)
  219. {
  220. y1 = rclClip1.bottom;
  221. }
  222. if (bCode2 & TOP)
  223. {
  224. y2 = rclClip2.top;
  225. }
  226. else if (bCode2 & BOTTOM)
  227. {
  228. y2 = rclClip2.bottom;
  229. }
  230. }
  231. // Horizontal line.
  232. else
  233. {
  234. if (bCode1 & LEFT)
  235. {
  236. x1 = rclClip1.left;
  237. }
  238. else if (bCode1 & RIGHT)
  239. {
  240. x1 = rclClip1.right;
  241. }
  242. if (bCode2 & LEFT)
  243. {
  244. x2 = rclClip2.left;
  245. }
  246. else if (bCode2 & RIGHT)
  247. {
  248. x2 = rclClip2.right;
  249. }
  250. }
  251. if (bCode1 | bCode2)
  252. {
  253. // Recalculate line deltas.
  254. dx = x2 - x1;
  255. dy = y2 - y1;
  256. }
  257. }
  258. // Get the color from the brush.
  259. ASSERTMSG(pbo, "Null brush in DrvLineTo!\n");
  260. ulColor = pbo->iSolidColor;
  261. REQUIRE(9);
  262. // If we have a color here we need to setup the hardware.
  263. if (ulColor != 0xFFFFFFFF)
  264. {
  265. // Expand the color.
  266. switch (ppdev->ulBitCount)
  267. {
  268. case 8:
  269. ulColor |= ulColor << 8;
  270. case 16:
  271. ulColor |= ulColor << 16;
  272. }
  273. LL_BGCOLOR(ulColor, 2);
  274. // Convert mix to ternary ROP.
  275. ppdev->uRop = Rop2ToRop3[mix & 0xF];
  276. ppdev->uBLTDEF = mixToBLTDEF[mix & 0xF];
  277. }
  278. LL_DRAWBLTDEF((ppdev->uBLTDEF << 16) | ppdev->uRop, 2);
  279. // Horizontal line.
  280. if (dy == 0)
  281. {
  282. if (dx > 0)
  283. {
  284. // From left to right.
  285. //above REQUIRE(5);
  286. LL_OP0(x1 + ppdev->ptlOffset.x, y1 + ppdev->ptlOffset.y);
  287. LL_BLTEXT(dx, 1);
  288. }
  289. else
  290. {
  291. // From right to left.
  292. //above REQUIRE(5);
  293. LL_OP0(x2 + 1 + ppdev->ptlOffset.x, y2 + ppdev->ptlOffset.y);
  294. LL_BLTEXT(-dx, 1);
  295. }
  296. }
  297. // Vertical line.
  298. else
  299. {
  300. if (dy > 0)
  301. {
  302. // From top to bottom.
  303. //above REQUIRE(5);
  304. LL_OP0(x1 + ppdev->ptlOffset.x, y1 + ppdev->ptlOffset.y);
  305. LL_BLTEXT(1, dy);
  306. }
  307. else
  308. {
  309. // From bottom to top.
  310. //above REQUIRE(5);
  311. LL_OP0(x2 + ppdev->ptlOffset.x, y2 + 1 + ppdev->ptlOffset.y);
  312. LL_BLTEXT(1, -dy);
  313. }
  314. }
  315. return(TRUE);
  316. }
  317. #endif // !WINNT_VER35