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.

266 lines
8.3 KiB

  1. /*
  2. ** Copyright (c) 1991 Microsoft Corporation
  3. */
  4. //===========================================================================
  5. // FILE RPGEN.C
  6. //
  7. // MODULE Host Resource Executor
  8. //
  9. // PURPOSE Rendering primitives, generic,
  10. //
  11. // DESCRIBED IN Resource Executor design spec.
  12. //
  13. //
  14. // MNEMONICS n/a
  15. //
  16. // HISTORY Bert Douglas 5/1/91 Initial coding started
  17. // mslin/dstseng 01/17/92 revise for HRE
  18. // dstseng 03/06/92 <1> RP_FillScanRow
  19. // ->RP_FILLSCANROW for asm. version.
  20. // dstseng 03/19/92 <2> comment out unnecessary code.
  21. // which was implemented for frac. version of
  22. // slicing algorithm.
  23. //
  24. //===========================================================================
  25. #include <windows.h>
  26. #include "constant.h"
  27. #include "jtypes.h"
  28. #include "jres.h"
  29. #include "frame.h" // driver header file, resource block format
  30. #include "hretype.h" // define data structure used by hre.c and rpgen.c
  31. //---------------------------------------------------------------------------
  32. void RP_SliceLine
  33. (
  34. SHORT s_x1, SHORT s_y1, // endpoint 1
  35. SHORT s_x2, SHORT s_y2, // endpoint 2
  36. RP_SLICE_DESC FAR* psd, // output slice form of line
  37. UBYTE fb_keep_order // keep drawing order on styled lines/
  38. )
  39. // PURPOSE
  40. // Convert a line from endpoint form to slice form
  41. //
  42. // Slices will run from left to right
  43. //
  44. // The generated slices are of maximal length and are in a horizontal,
  45. // vertical or diagonal direction. Most frame buffer hardware can be
  46. // accessed with particular efficiency in these directions. All slices
  47. // of a line are in the same direction.
  48. //
  49. // Clipping must be performed by caller. All coordinates will be non-negative.
  50. //
  51. // Basic algorithm is taken from :
  52. // Bresenham, J. E. Run length slice algorithms for incremental lines.
  53. // In "Fundamental Algorithms for Computer Graphics", R. A. Earnshaw, Ed.
  54. // NATO ASI Series, Springer Verlag, New York, 1985, 59-104.
  55. //
  56. // Modifications have been made to the above algorithm for:
  57. // - sub-pixel endpoint coordinates
  58. // - equal error rounding rules
  59. // - GIQ (grid intersect quantization) rules
  60. // - first/last pixel exclusion
  61. //
  62. // The line is sliced in four steps:
  63. //
  64. // STEP 1: Find the pixel center cooridnates of the first and
  65. // last pixels in the line. This is done according to the GIQ conventions.
  66. //
  67. // STEP 2: Use these integer pixel center endpoint coordinates
  68. // to produce the Bresenham slices for the line. The equal error rounding
  69. // rule is used, when the first and last slices are not of equal length, to
  70. // decide which end gets the short slice.
  71. //
  72. // STEP 3: Adjust the length of the first and last slices for the
  73. // effect of the sub-pixel endpoint coordinates. Note that the sub-pixel
  74. // part of the coordinates can only effect the first and last slices and
  75. // has no effect on the intermediate slices.
  76. //
  77. // STEP 4: Perform the conditional exclusion of the first and
  78. // last pixels from the line.
  79. //
  80. //
  81. // ASSUMPTIONS & ASSERTIONS none.
  82. //
  83. // INTERNAL STRUCTURES none.
  84. //
  85. // UNRESOLVED ISSUES programmer development notes
  86. //---------------------------------------------------------------------------
  87. {
  88. SHORT s_q,s_r; /* defined in Bresenhams paper */
  89. SHORT s_m,s_n; /* " */
  90. SHORT s_dx,s_dy; /* " */
  91. SHORT s_da,s_db; /* " */
  92. SHORT s_del_b; /* " */
  93. SHORT s_abs_dy; /* absolute value of s_dy */
  94. SHORT s_sy; /* 1 or -1 , sign of s_dy */
  95. SHORT s_dx_oct,s_dy_oct; /* octant dir xy= 0/1 1/1 1/0 1/-1 0/-1 */
  96. SHORT s_dx_axial,s_dy_axial; /* 1/2 octant axial dir xy= 0/1 1/0 -1/0 */
  97. SHORT s_dx_diag, s_dy_diag; /* 1/2 octant diagonal dir xy= 1/1 1/-1 */
  98. SHORT s_t; /* temporary */
  99. FBYTE fb_short_end_last; /* 0=first end short, 1=last end short */
  100. UBYTE fb_unswap; /* need to un-swap endpoints at return */
  101. fb_unswap = FALSE;
  102. /*------------------------------------------------------------*/
  103. /* STEP 1: Find pixel center coordinates of first/last pixels */
  104. /*------------------------------------------------------------*/
  105. /* always draw left to right, normalize to semicircle with x >= 0 */
  106. s_dx = s_x2 - s_x1;
  107. if ( s_dx < 0 )
  108. {
  109. fb_unswap = fb_keep_order;
  110. s_dx = -s_dx;
  111. s_t = s_x2;
  112. s_x2 = s_x1;
  113. s_x1 = s_t;
  114. s_t = s_y2;
  115. s_y2 = s_y1;
  116. s_y1 = s_t;
  117. }
  118. s_dy = s_y2 - s_y1;
  119. /*------------------------------------------------------------*/
  120. /* STEP 2: Produce slices using the Bresenham algorithm */
  121. /*------------------------------------------------------------*/
  122. if ( s_dy < 0 )
  123. {
  124. s_abs_dy = -s_dy;
  125. s_sy = -1;
  126. fb_short_end_last = 1;
  127. }
  128. else
  129. {
  130. s_abs_dy = s_dy;
  131. s_sy = 1;
  132. fb_short_end_last = 0;
  133. }
  134. /* normalize to octant */
  135. if ( s_dx >= s_abs_dy )
  136. {
  137. s_da = s_dx;
  138. s_db = s_abs_dy;
  139. s_dx_oct = 1;
  140. s_dy_oct = 0;
  141. }
  142. else
  143. {
  144. s_da = s_abs_dy;
  145. s_db = s_dx;
  146. s_dx_oct = 0;
  147. s_dy_oct = s_sy;
  148. fb_short_end_last = 1;
  149. }
  150. /* normalize to half octant */
  151. s_del_b = s_db;
  152. s_t = s_da - s_db;
  153. if ( s_del_b > s_t )
  154. {
  155. s_del_b = s_t;
  156. fb_short_end_last ^= 1;
  157. }
  158. /* handle special case of slope of 2 */
  159. s_dx_axial = s_dx_oct;
  160. s_dy_axial = s_dy_oct;
  161. s_dx_diag = 1;
  162. s_dy_diag = s_sy;
  163. if ( ( s_da == (2 * s_del_b) )
  164. && ( s_dy < 0 )
  165. )
  166. { s_dx_axial = 1;
  167. s_dy_axial = s_sy;
  168. s_dx_diag = s_dx_oct;
  169. s_dy_diag = s_dy_oct;
  170. fb_short_end_last ^= 1;
  171. }
  172. /* determine slice movement and skip directions */
  173. if ( s_db == s_del_b )
  174. {
  175. /* slice direction is axial, skip direction is diagonal */
  176. psd->s_dx_draw = s_dx_axial;
  177. psd->s_dy_draw = s_dy_axial;
  178. psd->s_dx_skip = s_dx_diag - s_dx_axial;
  179. psd->s_dy_skip = s_dy_diag - s_dy_axial;
  180. }
  181. else
  182. {
  183. /* slice direction is diagonal, skip direction is axial */
  184. psd->s_dx_draw = s_dx_diag;
  185. psd->s_dy_draw = s_dy_diag;
  186. psd->s_dx_skip = s_dx_axial - s_dx_diag;
  187. psd->s_dy_skip = s_dy_axial - s_dy_diag;
  188. }
  189. /* handle zero slope lines with special case */
  190. if ( s_del_b == 0 )
  191. {
  192. psd->us_first = s_da + 1;
  193. psd->us_n_slices = 0;
  194. psd->us_last = 0;
  195. }
  196. else
  197. /* general case, non-zero slope lines */
  198. {
  199. /* basic Bresenham parameters */
  200. s_q = s_da / s_del_b;
  201. s_r = s_da % s_del_b;
  202. s_m = s_q / 2;
  203. s_n = s_r;
  204. if ( s_q & 1 ) s_n += s_del_b;
  205. /* first and last slice length */
  206. psd->us_first = psd->us_last = s_m + 1;
  207. if ( s_n == 0 )
  208. {
  209. if ( fb_short_end_last )
  210. psd->us_last -= 1;
  211. else
  212. psd->us_first -= 1;
  213. }
  214. /* remaining line slice parameters */
  215. psd->us_small = s_q;
  216. psd->s_dis_sm = 2*s_r;
  217. psd->s_dis_lg = psd->s_dis_sm - (2*s_del_b);
  218. psd->s_dis = s_n + psd->s_dis_lg;
  219. if ( s_dy < 0 ) psd->s_dis -= 1;
  220. psd->us_n_slices = s_del_b - 1;
  221. }
  222. /* output endpoints */
  223. psd->us_x1 = s_x1;
  224. psd->us_y1 = s_y1;
  225. psd->us_x2 = s_x2;
  226. psd->us_y2 = s_y2;
  227. if ( fb_unswap )
  228. {
  229. psd->us_x1 = s_x2;
  230. psd->us_y1 = s_y2;
  231. psd->us_x2 = s_x1;
  232. psd->us_y2 = s_y1;
  233. psd->s_dx_draw = -psd->s_dx_draw;
  234. psd->s_dy_draw = -psd->s_dy_draw;
  235. psd->s_dx_skip = -psd->s_dx_skip;
  236. psd->s_dy_skip = -psd->s_dy_skip;
  237. s_t = psd->us_first;
  238. psd->us_first = psd->us_last;
  239. psd->us_last = s_t;
  240. }
  241. }