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.

514 lines
13 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: Strips.c
  3. *
  4. * All the line code in this driver amounts to a big bag of dirt. Someday,
  5. * I'm going to rewrite it all. Not today, though (sigh)...
  6. *
  7. * Copyright (c) 1992-1995 Microsoft Corporation
  8. *
  9. * $Workfile: STRIPS.C $
  10. *
  11. * $Log: X:/log/laguna/nt35/displays/cl546x/STRIPS.C $
  12. *
  13. * Rev 1.4 Mar 04 1998 15:35:14 frido
  14. * Added new shadow macros.
  15. *
  16. * Rev 1.3 Nov 03 1997 10:50:06 frido
  17. * Added REQUIRE macros.
  18. *
  19. * Rev 1.2 20 Aug 1996 11:04:28 noelv
  20. * Bugfix release from Frido 8-19-96
  21. *
  22. * Rev 1.0 14 Aug 1996 17:16:32 frido
  23. * Initial revision.
  24. *
  25. * Rev 1.1 28 Mar 1996 08:58:40 noelv
  26. * Frido bug fix release 22
  27. *
  28. * Rev 1.1 27 Mar 1996 13:57:28 frido
  29. * Fixed line drawing.
  30. *
  31. \**************************************************************************/
  32. #include "precomp.h"
  33. #define STARTBLT()
  34. /******************************Public*Routine******************************\
  35. * VOID vrlSolidHorizontal
  36. *
  37. * Draws left-to-right x-major near-horizontal lines using radial lines.
  38. *
  39. \**************************************************************************/
  40. VOID vrlSolidHorizontal(
  41. PDEV* ppdev,
  42. STRIP* pStrip,
  43. LINESTATE* pLineState)
  44. {
  45. LONG cStrips;
  46. LONG i, yDir, x, y;
  47. PLONG pStrips;
  48. LONG xPels;
  49. cStrips = pStrip->cStrips;
  50. pStrips = pStrip->alStrips;
  51. // Get the starting coordinates and adjust for device bitmaps.
  52. x = pStrip->ptlStart.x + ppdev->ptlOffset.x;
  53. y = pStrip->ptlStart.y + ppdev->ptlOffset.y;
  54. // Determine y-direction.
  55. if (pStrip->flFlips & FL_FLIP_V)
  56. {
  57. yDir = -1;
  58. ppdev->uBLTDEF |= BD_YDIR;
  59. }
  60. else
  61. {
  62. yDir = 1;
  63. ppdev->uBLTDEF &= ~BD_YDIR;
  64. }
  65. // Start the BitBlt.
  66. STARTBLT();
  67. // Here is where we will setup DrawDef and BlitDef
  68. REQUIRE(2);
  69. LL_DRAWBLTDEF((ppdev->uBLTDEF << 16) | ppdev->uRop, 2);
  70. // Loop through all the strips.
  71. for (i = 0; i < cStrips; i++)
  72. {
  73. // Get the width of this stripe.
  74. xPels = *pStrips++;
  75. // Draw it.
  76. REQUIRE(5);
  77. LL_OP0(x, y);
  78. LL_BLTEXT(xPels, 1);
  79. // Advance to next strip.
  80. x += xPels;
  81. y += yDir;
  82. }
  83. // Store the current coordinates back.
  84. pStrip->ptlStart.x = x - ppdev->ptlOffset.x;
  85. pStrip->ptlStart.y = y - ppdev->ptlOffset.y;
  86. }
  87. /******************************Public*Routine******************************\
  88. * VOID vrlSolidVertical
  89. *
  90. * Draws left-to-right y-major near-vertical lines using radial lines.
  91. *
  92. \**************************************************************************/
  93. VOID vrlSolidVertical(
  94. PDEV* ppdev,
  95. STRIP* pStrip,
  96. LINESTATE* pLineState)
  97. {
  98. LONG cStrips;
  99. LONG i, x, y, yDir;
  100. PLONG pStrips;
  101. LONG yPels;
  102. cStrips = pStrip->cStrips;
  103. pStrips = pStrip->alStrips;
  104. // Get the starting coordinates and adjust for device bitmaps.
  105. x = pStrip->ptlStart.x + ppdev->ptlOffset.x;
  106. y = pStrip->ptlStart.y + ppdev->ptlOffset.y;
  107. // Determine y-direction.
  108. if (pStrip->flFlips & FL_FLIP_V)
  109. {
  110. ppdev->uBLTDEF |= BD_YDIR;
  111. yDir = -1;
  112. }
  113. else
  114. {
  115. yDir = 1;
  116. ppdev->uBLTDEF &= ~BD_YDIR;
  117. }
  118. // Start the BitBlt.
  119. STARTBLT();
  120. // Here is where we will setup DrawDef and BlitDef
  121. REQUIRE(2);
  122. LL_DRAWBLTDEF((ppdev->uBLTDEF << 16) | ppdev->uRop, 2);
  123. // Loop through all the strips.
  124. for (i = 0; i < cStrips; i++)
  125. {
  126. // Get the height of this stripe.
  127. yPels = *pStrips++;
  128. // Draw it.
  129. REQUIRE(5);
  130. LL_OP0(x, y);
  131. LL_BLTEXT(1, yPels);
  132. // Advance to next strip.
  133. x++;
  134. y += yDir * yPels;
  135. }
  136. // Store the current coordinates back.
  137. pStrip->ptlStart.x = x - ppdev->ptlOffset.x;
  138. pStrip->ptlStart.y = y - ppdev->ptlOffset.y;
  139. }
  140. /******************************Public*Routine******************************\
  141. * VOID vStripStyledHorizontal
  142. *
  143. * Takes the list of strips that define the pixels that would be lit for
  144. * a solid line, and breaks them into styling chunks according to the
  145. * styling information that is passed in.
  146. *
  147. * This particular routine handles x-major lines that run left-to-right,
  148. * and are comprised of horizontal strips. It draws the dashes using
  149. * short-stroke vectors.
  150. *
  151. * The performance of this routine could be improved significantly if
  152. * anyone cared enough about styled lines improve it.
  153. *
  154. \**************************************************************************/
  155. VOID vStripStyledHorizontal(
  156. PDEV* ppdev,
  157. STRIP* pstrip,
  158. LINESTATE* pls)
  159. {
  160. LONG x, y, dy;
  161. PLONG plStrip;
  162. LONG cStrips;
  163. LONG cStyle;
  164. LONG cStrip;
  165. LONG cThis;
  166. ULONG bIsGap;
  167. // Determine y-direction.
  168. if (pstrip->flFlips & FL_FLIP_V)
  169. {
  170. dy = -1;
  171. ppdev->uBLTDEF |= BD_YDIR;
  172. }
  173. else
  174. {
  175. ppdev->uBLTDEF &= ~BD_YDIR;
  176. dy = 1;
  177. }
  178. cStrips = pstrip->cStrips; // Total number of strips we'll do
  179. plStrip = pstrip->alStrips; // Points to current strip
  180. // Get the starting coordinates and adjust for device bitmaps.
  181. x = pstrip->ptlStart.x + ppdev->ptlOffset.x;
  182. y = pstrip->ptlStart.y + ppdev->ptlOffset.y;
  183. // Start the BitBlt.
  184. STARTBLT();
  185. // Here is where we will setup DrawDef and BlitDef.
  186. REQUIRE(2);
  187. LL_DRAWBLTDEF((ppdev->uBLTDEF << 16) | ppdev->uRop, 2);
  188. cStrip = *plStrip; // Number of pels in first strip
  189. cStyle = pls->spRemaining; // Number of pels in first 'gap' or 'dash'
  190. bIsGap = pls->ulStyleMask; // Tells whether in a 'gap' or a 'dash'
  191. // ulStyleMask is non-zero if we're in the middle of a 'gap',
  192. // and zero if we're in the middle of a 'dash':
  193. if (bIsGap)
  194. goto SkipAGap;
  195. else
  196. goto OutputADash;
  197. PrepareToSkipAGap:
  198. // Advance in the style-state array, so that we can find the next
  199. // 'dot' that we'll have to display:
  200. bIsGap = ~bIsGap;
  201. pls->psp++;
  202. if (pls->psp > pls->pspEnd)
  203. pls->psp = pls->pspStart;
  204. cStyle = *pls->psp;
  205. // If 'cStrip' is zero, we also need a new strip:
  206. if (cStrip != 0)
  207. goto SkipAGap;
  208. // Here, we're in the middle of a 'gap' where we don't have to
  209. // display anything. We simply cycle through all the strips
  210. // we can, keeping track of the current position, until we run
  211. // out of 'gap':
  212. while (TRUE)
  213. {
  214. // Each time we loop, we move to a new scan and need a new strip:
  215. y += dy;
  216. plStrip++;
  217. cStrips--;
  218. if (cStrips == 0)
  219. goto AllDone;
  220. cStrip = *plStrip;
  221. SkipAGap:
  222. cThis = min(cStrip, cStyle);
  223. cStyle -= cThis;
  224. cStrip -= cThis;
  225. x += cThis;
  226. if (cStyle == 0)
  227. goto PrepareToOutputADash;
  228. }
  229. PrepareToOutputADash:
  230. // Advance in the style-state array, so that we can find the next
  231. // 'dot' that we'll have to display:
  232. bIsGap = ~bIsGap;
  233. pls->psp++;
  234. if (pls->psp > pls->pspEnd)
  235. pls->psp = pls->pspStart;
  236. cStyle = *pls->psp;
  237. // If 'cStrip' is zero, we also need a new strip.
  238. if (cStrip != 0)
  239. {
  240. goto OutputADash;
  241. }
  242. while (TRUE)
  243. {
  244. // Each time we loop, we move to a new scan and need a new strip:
  245. y += dy;
  246. plStrip++;
  247. cStrips--;
  248. if (cStrips == 0)
  249. goto AllDone;
  250. cStrip = *plStrip;
  251. OutputADash:
  252. cThis = min(cStrip, cStyle);
  253. cStyle -= cThis;
  254. cStrip -= cThis;
  255. // Draw the stripe.
  256. REQUIRE(5);
  257. LL_OP0(x, y);
  258. LL_BLTEXT(cThis, 1);
  259. x += cThis;
  260. if (cStyle == 0)
  261. goto PrepareToSkipAGap;
  262. }
  263. AllDone:
  264. // Update our state variables so that the next line can continue
  265. // where we left off:
  266. pls->spRemaining = cStyle;
  267. pls->ulStyleMask = bIsGap;
  268. pstrip->ptlStart.x = x - ppdev->ptlOffset.x;
  269. pstrip->ptlStart.y = y - ppdev->ptlOffset.y;
  270. }
  271. /******************************Public*Routine******************************\
  272. * VOID vStripStyledVertical
  273. *
  274. * Takes the list of strips that define the pixels that would be lit for
  275. * a solid line, and breaks them into styling chunks according to the
  276. * styling information that is passed in.
  277. *
  278. * This particular routine handles y-major lines that run left-to-right,
  279. * and are comprised of vertical strips. It draws the dashes using
  280. * short-stroke vectors.
  281. *
  282. * The performance of this routine could be improved significantly if
  283. * anyone cared enough about styled lines improve it.
  284. *
  285. \**************************************************************************/
  286. VOID vStripStyledVertical(
  287. PDEV* ppdev,
  288. STRIP* pstrip,
  289. LINESTATE* pls)
  290. {
  291. LONG x, y, dy;
  292. PLONG plStrip;
  293. LONG cStrips;
  294. LONG cStyle;
  295. LONG cStrip;
  296. LONG cThis;
  297. ULONG bIsGap;
  298. // Determine the y-direction.
  299. if (pstrip->flFlips & FL_FLIP_V)
  300. {
  301. dy = -1;
  302. ppdev->uBLTDEF |= BD_YDIR;
  303. }
  304. else
  305. {
  306. dy = 1;
  307. ppdev->uBLTDEF &= ~BD_YDIR;
  308. }
  309. cStrips = pstrip->cStrips; // Total number of strips we'll do
  310. plStrip = pstrip->alStrips; // Points to current strip
  311. // Get the starting coordinates and adjust for device bitmaps.
  312. x = pstrip->ptlStart.x + ppdev->ptlOffset.x;
  313. y = pstrip->ptlStart.y + ppdev->ptlOffset.y;
  314. // Start the BitBlt.
  315. STARTBLT();
  316. // Here is where we will setup DrawDef and BlitDef.
  317. REQUIRE(2);
  318. LL_DRAWBLTDEF((ppdev->uBLTDEF << 16) | ppdev->uRop, 2);
  319. cStrip = *plStrip; // Number of pels in first strip
  320. cStyle = pls->spRemaining; // Number of pels in first 'gap' or 'dash'
  321. bIsGap = pls->ulStyleMask; // Tells whether in a 'gap' or a 'dash'
  322. // ulStyleMask is non-zero if we're in the middle of a 'gap',
  323. // and zero if we're in the middle of a 'dash':
  324. if (bIsGap)
  325. goto SkipAGap;
  326. else
  327. goto OutputADash;
  328. PrepareToSkipAGap:
  329. // Advance in the style-state array, so that we can find the next
  330. // 'dot' that we'll have to display:
  331. bIsGap = ~bIsGap;
  332. pls->psp++;
  333. if (pls->psp > pls->pspEnd)
  334. pls->psp = pls->pspStart;
  335. cStyle = *pls->psp;
  336. // If 'cStrip' is zero, we also need a new strip:
  337. if (cStrip != 0)
  338. goto SkipAGap;
  339. // Here, we're in the middle of a 'gap' where we don't have to
  340. // display anything. We simply cycle through all the strips
  341. // we can, keeping track of the current position, until we run
  342. // out of 'gap':
  343. while (TRUE)
  344. {
  345. // Each time we loop, we move to a new column and need a new strip:
  346. x++;
  347. plStrip++;
  348. cStrips--;
  349. if (cStrips == 0)
  350. goto AllDone;
  351. cStrip = *plStrip;
  352. SkipAGap:
  353. cThis = min(cStrip, cStyle);
  354. cStyle -= cThis;
  355. cStrip -= cThis;
  356. y += (dy > 0) ? cThis : -cThis;
  357. if (cStyle == 0)
  358. goto PrepareToOutputADash;
  359. }
  360. PrepareToOutputADash:
  361. // Advance in the style-state array, so that we can find the next
  362. // 'dot' that we'll have to display:
  363. bIsGap = ~bIsGap;
  364. pls->psp++;
  365. if (pls->psp > pls->pspEnd)
  366. pls->psp = pls->pspStart;
  367. cStyle = *pls->psp;
  368. // If 'cStrip' is zero, we also need a new strip.
  369. if (cStrip != 0)
  370. {
  371. goto OutputADash;
  372. }
  373. while (TRUE)
  374. {
  375. // Each time we loop, we move to a new column and need a new strip:
  376. x++;
  377. plStrip++;
  378. cStrips--;
  379. if (cStrips == 0)
  380. goto AllDone;
  381. cStrip = *plStrip;
  382. OutputADash:
  383. cThis = min(cStrip, cStyle);
  384. cStyle -= cThis;
  385. cStrip -= cThis;
  386. // Draw the stripe.
  387. REQUIRE(5);
  388. LL_OP0(x, y);
  389. LL_BLTEXT(1, cThis);
  390. y += dy * cThis;
  391. if (cStyle == 0)
  392. goto PrepareToSkipAGap;
  393. }
  394. AllDone:
  395. // Update our state variables so that the next line can continue
  396. // where we left off:
  397. pls->spRemaining = cStyle;
  398. pls->ulStyleMask = bIsGap;
  399. pstrip->ptlStart.x = x - ppdev->ptlOffset.x;
  400. pstrip->ptlStart.y = y - ppdev->ptlOffset.y;
  401. }