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.

371 lines
11 KiB

  1. /******************************Module*Header**********************************\
  2. *
  3. * *******************
  4. * * GDI SAMPLE CODE *
  5. * *******************
  6. *
  7. * Module Name: Stroke.c
  8. *
  9. * Content: DrvStrokePath support
  10. *
  11. * Copyright (c) 1994-1999 3Dlabs Inc. Ltd. All rights reserved.
  12. * Copyright (c) 1995-2003 Microsoft Corporation. All rights reserved.
  13. \*****************************************************************************/
  14. #include "precomp.h"
  15. #include "glint.h"
  16. typedef VOID (* GAPFNstripFunc)(PPDEV, STRIP*, LINESTATE*);
  17. GAPFNstripFunc gapfnStripPXRX[] =
  18. {
  19. vPXRXSolidHorizontalLine,
  20. vPXRXSolidVerticalLine,
  21. vPXRXSolidDiagonalHorizontalLine,
  22. vPXRXSolidDiagonalVerticalLine,
  23. // Should be NUM_STRIP_DRAW_DIRECTIONS = 4 strip drawers in every group
  24. vPXRXSolidHorizontalLine,
  25. vPXRXSolidVerticalLine,
  26. vPXRXSolidDiagonalHorizontalLine,
  27. vPXRXSolidDiagonalVerticalLine,
  28. // Should be NUM_STRIP_DRAW_STYLES = 8 strip drawers in total for doing
  29. // solid lines, and the same number for non-solid lines:
  30. vPXRXStyledHorizontalLine,
  31. vPXRXStyledVerticalLine,
  32. vPXRXStyledVerticalLine, // Diagonal goes here
  33. vPXRXStyledVerticalLine, // Diagonal goes here
  34. vPXRXStyledHorizontalLine,
  35. vPXRXStyledVerticalLine,
  36. vPXRXStyledVerticalLine, // Diagonal goes here
  37. vPXRXStyledVerticalLine, // Diagonal goes here
  38. };
  39. // Style array for alternate style (alternates one pixel on, one pixel off):
  40. STYLEPOS gaspAlternateStyle[] = { 1 };
  41. /******************************Public*Routine******************************\
  42. * BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrush, pla, mix)
  43. *
  44. * Strokes the path.
  45. *
  46. \**************************************************************************/
  47. BOOL DrvStrokePath(
  48. SURFOBJ* pso,
  49. PATHOBJ* ppo,
  50. CLIPOBJ* pco,
  51. XFORMOBJ* pxo,
  52. BRUSHOBJ* pbo,
  53. POINTL* pptlBrush,
  54. LINEATTRS* pla,
  55. MIX mix)
  56. {
  57. STYLEPOS aspLtoR[STYLE_MAX_COUNT];
  58. STYLEPOS aspRtoL[STYLE_MAX_COUNT];
  59. LINESTATE ls;
  60. PFNSTRIP* apfn;
  61. FLONG fl;
  62. PDEV* ppdev;
  63. DSURF* pdsurf;
  64. OH* poh;
  65. RECTL arclClip[4]; // For rectangular clipping
  66. BOOL ResetGLINT; // Does GLINT need resetting?
  67. BOOL bRet;
  68. DWORD logicOp;
  69. GLINT_DECL_VARS;
  70. // Pass the surface off to GDI if it's a device bitmap that we've
  71. // converted to a DIB or if Glint Line debugging has been turned off.
  72. pdsurf = (DSURF*) pso->dhsurf;
  73. if (pdsurf->dt & DT_DIB)
  74. {
  75. return(EngStrokePath(pdsurf->pso, ppo, pco, pxo, pbo, pptlBrush,
  76. pla, mix));
  77. }
  78. ppdev = (PDEV*) pso->dhpdev;
  79. GLINT_DECL_INIT;
  80. REMOVE_SWPOINTER(pso);
  81. DISPDBG((DBGLVL, "Drawing Lines through GLINT"));
  82. // We'll be drawing to the screen or an off-screen DFB; copy the surface's
  83. // offset now so that we won't need to refer to the DSURF again:
  84. SETUP_PPDEV_OFFSETS(ppdev, pdsurf);
  85. fl = 0;
  86. // Look after styling initialization:
  87. if (pla->fl & LA_ALTERNATE)
  88. {
  89. ls.cStyle = 1;
  90. ls.spTotal = 1;
  91. ls.spTotal2 = 2;
  92. ls.spRemaining = 1;
  93. ls.aspRtoL = &gaspAlternateStyle[0];
  94. ls.aspLtoR = &gaspAlternateStyle[0];
  95. ls.spNext = HIWORD(pla->elStyleState.l);
  96. ls.xyDensity = 1;
  97. fl |= FL_ARBITRARYSTYLED;
  98. ls.ulStartMask = 0L;
  99. }
  100. else if (pla->pstyle != (FLOAT_LONG*) NULL)
  101. {
  102. PFLOAT_LONG pstyle;
  103. STYLEPOS* pspDown;
  104. STYLEPOS* pspUp;
  105. pstyle = &pla->pstyle[pla->cstyle];
  106. ls.xyDensity = STYLE_DENSITY;
  107. ls.spTotal = 0;
  108. while (pstyle-- > pla->pstyle)
  109. {
  110. ls.spTotal += pstyle->l;
  111. }
  112. ls.spTotal *= STYLE_DENSITY;
  113. ls.spTotal2 = 2 * ls.spTotal;
  114. // Compute starting style position (this is guaranteed not to overflow):
  115. ls.spNext = HIWORD(pla->elStyleState.l) * STYLE_DENSITY +
  116. LOWORD(pla->elStyleState.l);
  117. fl |= FL_ARBITRARYSTYLED;
  118. ls.cStyle = pla->cstyle;
  119. ls.aspRtoL = aspRtoL;
  120. ls.aspLtoR = aspLtoR;
  121. if (pla->fl & LA_STARTGAP)
  122. ls.ulStartMask = 0xffffffffL;
  123. else
  124. ls.ulStartMask = 0L;
  125. pstyle = pla->pstyle;
  126. pspDown = &ls.aspRtoL[ls.cStyle - 1];
  127. pspUp = &ls.aspLtoR[0];
  128. while (pspDown >= &ls.aspRtoL[0])
  129. {
  130. *pspDown = pstyle->l * STYLE_DENSITY;
  131. *pspUp = *pspDown;
  132. pspUp++;
  133. pspDown--;
  134. pstyle++;
  135. }
  136. }
  137. bRet = TRUE;
  138. apfn = &ppdev->gapfnStrip[NUM_STRIP_DRAW_STYLES * ((fl & FL_STYLE_MASK) >> FL_STYLE_SHIFT)];
  139. // Set up to enumerate the path:
  140. if (pco->iDComplexity != DC_COMPLEX)
  141. {
  142. PATHDATA pd;
  143. RECTL* prclClip = (RECTL*) NULL;
  144. BOOL bMore;
  145. ULONG cptfx;
  146. POINTFIX ptfxStartFigure;
  147. POINTFIX ptfxLast;
  148. POINTFIX* pptfxFirst;
  149. POINTFIX* pptfxBuf;
  150. if (pco->iDComplexity == DC_RECT)
  151. {
  152. fl |= FL_SIMPLE_CLIP;
  153. // This is the only clip region of importance to GLINT
  154. arclClip[0] = pco->rclBounds;
  155. // FL_FLIP_D:
  156. arclClip[1].top = pco->rclBounds.left;
  157. arclClip[1].left = pco->rclBounds.top;
  158. arclClip[1].bottom = pco->rclBounds.right;
  159. arclClip[1].right = pco->rclBounds.bottom;
  160. // FL_FLIP_V:
  161. arclClip[2].top = -pco->rclBounds.bottom + 1;
  162. arclClip[2].left = pco->rclBounds.left;
  163. arclClip[2].bottom = -pco->rclBounds.top + 1;
  164. arclClip[2].right = pco->rclBounds.right;
  165. // FL_FLIP_V | FL_FLIP_D:
  166. arclClip[3].top = pco->rclBounds.left;
  167. arclClip[3].left = -pco->rclBounds.bottom + 1;
  168. arclClip[3].bottom = pco->rclBounds.right;
  169. arclClip[3].right = -pco->rclBounds.top + 1;
  170. prclClip = arclClip;
  171. }
  172. pd.flags = 0;
  173. // Get the logic op and set up the flag to indicate reads from
  174. // the frame buffer will occur.
  175. logicOp = GlintLogicOpsFromR2[mix & 0xff];
  176. if (LogicopReadDest[logicOp])
  177. fl |= FL_READ;
  178. // Need to set up Glint modes and colors appropriately for the lines.
  179. ResetGLINT = (*ppdev->pgfnInitStrips)(ppdev, pbo->iSolidColor,
  180. logicOp, prclClip);
  181. PATHOBJ_vEnumStart(ppo);
  182. do {
  183. bMore = PATHOBJ_bEnum(ppo, &pd);
  184. cptfx = pd.count;
  185. if (cptfx == 0)
  186. {
  187. break;
  188. }
  189. if (pd.flags & PD_BEGINSUBPATH)
  190. {
  191. ptfxStartFigure = *pd.pptfx;
  192. pptfxFirst = pd.pptfx;
  193. pptfxBuf = pd.pptfx + 1;
  194. cptfx--;
  195. }
  196. else
  197. {
  198. pptfxFirst = &ptfxLast;
  199. pptfxBuf = pd.pptfx;
  200. }
  201. if (pd.flags & PD_RESETSTYLE)
  202. {
  203. ls.spNext = 0;
  204. }
  205. if (cptfx > 0)
  206. {
  207. if (!bLines(ppdev,
  208. pptfxFirst,
  209. pptfxBuf,
  210. (RUN*) NULL,
  211. cptfx,
  212. &ls,
  213. prclClip,
  214. apfn,
  215. fl)) {
  216. bRet = FALSE;
  217. goto ResetReturn;
  218. }
  219. }
  220. ptfxLast = pd.pptfx[pd.count - 1];
  221. if (pd.flags & PD_CLOSEFIGURE)
  222. {
  223. if (!bLines(ppdev,
  224. &ptfxLast,
  225. &ptfxStartFigure,
  226. (RUN*) NULL,
  227. 1,
  228. &ls,
  229. prclClip,
  230. apfn,
  231. fl)) {
  232. bRet = FALSE;
  233. goto ResetReturn;
  234. }
  235. }
  236. } while (bMore);
  237. if (fl & FL_STYLED)
  238. {
  239. // Save the style state:
  240. ULONG ulHigh;
  241. ULONG ulLow;
  242. // Masked styles don't normalize the style state. It's a good
  243. // thing to do, so let's do it now:
  244. if ((ULONG) ls.spNext >= (ULONG) ls.spTotal2)
  245. {
  246. ls.spNext = (ULONG) ls.spNext % (ULONG) ls.spTotal2;
  247. }
  248. ulHigh = ls.spNext / ls.xyDensity;
  249. ulLow = ls.spNext % ls.xyDensity;
  250. pla->elStyleState.l = MAKELONG(ulLow, ulHigh);
  251. }
  252. }
  253. else
  254. {
  255. // Local state for path enumeration:
  256. BOOL bMore;
  257. union {
  258. BYTE aj[FIELD_OFFSET(CLIPLINE, arun) + RUN_MAX * sizeof(RUN)];
  259. CLIPLINE cl;
  260. } cl;
  261. fl |= FL_COMPLEX_CLIP;
  262. // Need to set up Glint modes and colors appropriately for the lines.
  263. // NOTE, with a complex clip, we can not yet use GLINT for fast lines
  264. ResetGLINT = (*ppdev->pgfnInitStrips)(ppdev, pbo->iSolidColor,
  265. GlintLogicOpsFromR2[mix & 0xff], NULL);
  266. // We use the clip object when non-simple clipping is involved:
  267. PATHOBJ_vEnumStartClipLines(ppo, pco, pso, pla);
  268. do {
  269. bMore = PATHOBJ_bEnumClipLines(ppo, sizeof(cl), &cl.cl);
  270. if (cl.cl.c != 0)
  271. {
  272. if (fl & FL_STYLED)
  273. {
  274. ls.spComplex = HIWORD(cl.cl.lStyleState) * ls.xyDensity
  275. + LOWORD(cl.cl.lStyleState);
  276. }
  277. if (!bLines(ppdev,
  278. &cl.cl.ptfxA,
  279. &cl.cl.ptfxB,
  280. &cl.cl.arun[0],
  281. cl.cl.c,
  282. &ls,
  283. (RECTL*) NULL,
  284. apfn,
  285. fl))
  286. {
  287. bRet = FALSE;
  288. goto ResetReturn;
  289. }
  290. }
  291. } while (bMore);
  292. }
  293. ResetReturn:
  294. if (ResetGLINT)
  295. {
  296. (*ppdev->pgfnResetStrips)(ppdev);
  297. }
  298. return(bRet);
  299. }