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
15 KiB

  1. /******************************Module*Header*******************************\
  2. *
  3. * $Workfile: STROKE.C $
  4. *
  5. * Handle DrvStrokePath routine.
  6. *
  7. * Copyright (c) 1992-1995 Microsoft Corporation
  8. * Copyright (c) 1997 Cirrus Logic, Inc.
  9. *
  10. * $Log: X:/log/laguna/nt35/displays/cl546x/STROKE.C $
  11. *
  12. * Rev 1.17 Mar 04 1998 15:35:34 frido
  13. * Added new shadow macros.
  14. *
  15. * Rev 1.16 Nov 03 1997 10:20:44 frido
  16. * Added REQUIRE macros.
  17. *
  18. \**************************************************************************/
  19. #include "precomp.h"
  20. #define STROKE_DBG_LEVEL 1
  21. #if LOG_CALLS
  22. void LogStrokePath(
  23. ULONG acc,
  24. PPDEV ppdev,
  25. CLIPOBJ* pco,
  26. BRUSHOBJ* pbo,
  27. MIX mix,
  28. LINEATTRS* pla,
  29. PATHOBJ* ppo
  30. );
  31. #else
  32. #define LogStrokePath(acc, ppdev, pco, pbo, mix, pla, ppo)
  33. #endif
  34. VOID (*gapfnStrip[])(PDEV*, STRIP*, LINESTATE*) = {
  35. vrlSolidHorizontal,
  36. vrlSolidVertical,
  37. NULL,
  38. NULL,
  39. // Should be NUM_STRIP_DRAW_DIRECTIONS = 4 strip drawers in every group
  40. vrlSolidHorizontal,
  41. vrlSolidVertical,
  42. NULL,
  43. NULL,
  44. // Should be NUM_STRIP_DRAW_STYLES = 8 strip drawers in total for doing
  45. // solid lines, and the same number for non-solid lines:
  46. vStripStyledHorizontal,
  47. vStripStyledVertical,
  48. NULL, // Diagonal goes here
  49. NULL, // Diagonal goes here
  50. vStripStyledHorizontal,
  51. vStripStyledVertical,
  52. NULL, // Diagonal goes here
  53. NULL, // Diagonal goes here
  54. };
  55. // Style array for alternate style (alternates one pixel on, one pixel off):
  56. STYLEPOS gaspAlternateStyle[] = { 1 };
  57. extern BYTE Rop2ToRop3[];
  58. USHORT mixToBLTDEF[] =
  59. {
  60. 0x1000, //0 R2_WHITE 1
  61. 0x1000, //1 R2_BLACK 0
  62. 0x1107, //2 DPon
  63. 0x1107, //3 DPna
  64. 0x1007, //4 PN
  65. 0x1107, //5 PDna
  66. 0x1100, //6 Dn
  67. 0x1107, //7 DPx
  68. 0x1107, //8 DPan
  69. 0x1107, //9 DPa
  70. 0x1107, //A DPxn
  71. 0x1100, //B D
  72. 0x1107, //C DPno
  73. 0x1007, //D P
  74. 0x1107, //E PDno
  75. 0x1107, //F DPo
  76. };
  77. /******************************Public*Routine******************************\
  78. * BOOL DrvStrokePath(pso, ppo, pco, pxo, pbo, pptlBrush, pla, mix)
  79. *
  80. * Strokes the path.
  81. *
  82. \**************************************************************************/
  83. BOOL DrvStrokePath(
  84. SURFOBJ* pso,
  85. PATHOBJ* ppo,
  86. CLIPOBJ* pco,
  87. XFORMOBJ* pxo,
  88. BRUSHOBJ* pbo,
  89. POINTL* pptlBrush,
  90. LINEATTRS* pla,
  91. MIX mix)
  92. {
  93. STYLEPOS aspLtoR[STYLE_MAX_COUNT];
  94. STYLEPOS aspRtoL[STYLE_MAX_COUNT];
  95. LINESTATE ls;
  96. PFNSTRIP* apfn;
  97. FLONG fl;
  98. PDEV* ppdev;
  99. RECTL arclClip[4]; // For rectangular clipping
  100. DWORD color;
  101. #if NULL_STROKE
  102. {
  103. if (pointer_switch) return(TRUE);
  104. }
  105. #endif
  106. DISPDBG((STROKE_DBG_LEVEL,"DrvStrokePath: Entry %x.\n", mix));
  107. ppdev = (PDEV*) pso->dhpdev;
  108. SYNC_W_3D(ppdev);
  109. if (pso->iType == STYPE_DEVBITMAP)
  110. {
  111. PDSURF pdsurf = (PDSURF) pso->dhsurf;
  112. if ( pdsurf->pso && !bCreateScreenFromDib(ppdev, pdsurf) )
  113. {
  114. LogStrokePath(4,ppdev, pco, pbo, mix, pla, ppo);
  115. return(EngStrokePath(pdsurf->pso, ppo, pco, pxo, pbo,
  116. pptlBrush, pla, mix));
  117. }
  118. ppdev->ptlOffset = pdsurf->ptl;
  119. }
  120. else
  121. {
  122. ppdev->ptlOffset.x = ppdev->ptlOffset.y = 0;
  123. }
  124. // Convert to 3 OP ROP
  125. ppdev->uRop = Rop2ToRop3[mix & 0xF];
  126. ppdev->uBLTDEF = mixToBLTDEF[mix & 0x0F];
  127. //
  128. // Get the device ready:
  129. //
  130. ASSERTMSG(pbo,"Null brush in SrvStrokePath!\n");
  131. color = pbo->iSolidColor; // & 0x00000000FF; // Clear upper 24 bits.
  132. ASSERTMSG((color !=0xFFFFFFFF),"DrvStrokePath got a Pattern!\n");
  133. switch (ppdev->ulBitCount)
  134. {
  135. case 8: // For 8 bpp duplicate byte 0 into bytes 1,2,3.
  136. color = (color << 8) | (color & 0xFF);
  137. case 16: // For 16 bpp, duplicate the low word into the high word.
  138. color = ((color << 16) | (color & 0xFFFF));
  139. default:
  140. break;
  141. }
  142. DISPDBG((STROKE_DBG_LEVEL,"DrvStrokePath: Set Color %x.\n", color));
  143. REQUIRE(2);
  144. LL_BGCOLOR(color, 2);
  145. fl = 0;
  146. // Check line style.
  147. if (pla->fl & LA_ALTERNATE)
  148. {
  149. ls.cStyle = 1;
  150. ls.spTotal = 1;
  151. ls.spTotal2 = 2;
  152. ls.spRemaining = 1;
  153. ls.aspRtoL = &gaspAlternateStyle[0];
  154. ls.aspLtoR = &gaspAlternateStyle[0];
  155. ls.spNext = HIWORD(pla->elStyleState.l);
  156. ls.xyDensity = 1;
  157. fl |= FL_STYLED;
  158. ls.ulStartMask = 0L;
  159. }
  160. // Is it styled or solid?
  161. else if (pla->pstyle != (FLOAT_LONG*) NULL)
  162. {
  163. // Styled.
  164. PFLOAT_LONG pstyle;
  165. STYLEPOS* pspDown;
  166. STYLEPOS* pspUp;
  167. pstyle = &pla->pstyle[pla->cstyle];
  168. ls.xyDensity = STYLE_DENSITY;
  169. ls.spTotal = 0;
  170. while (pstyle-- > pla->pstyle)
  171. {
  172. ls.spTotal += pstyle->l;
  173. }
  174. ls.spTotal *= STYLE_DENSITY;
  175. ls.spTotal2 = 2 * ls.spTotal;
  176. // Compute starting style position
  177. // (this is guaranteed not to overflow):
  178. ls.spNext = HIWORD(pla->elStyleState.l) * STYLE_DENSITY +
  179. LOWORD(pla->elStyleState.l);
  180. fl |= FL_STYLED;
  181. ls.cStyle = pla->cstyle;
  182. ls.aspRtoL = aspRtoL;
  183. ls.aspLtoR = aspLtoR;
  184. if (pla->fl & LA_STARTGAP)
  185. ls.ulStartMask = 0xffffffffL;
  186. else
  187. ls.ulStartMask = 0L;
  188. pstyle = pla->pstyle;
  189. pspDown = &ls.aspRtoL[ls.cStyle - 1];
  190. pspUp = &ls.aspLtoR[0];
  191. while (pspDown >= &ls.aspRtoL[0])
  192. {
  193. *pspDown = pstyle->l * STYLE_DENSITY;
  194. *pspUp = *pspDown;
  195. pspUp++;
  196. pspDown--;
  197. pstyle++;
  198. }
  199. }
  200. apfn = &gapfnStrip[NUM_STRIP_DRAW_STYLES *
  201. ((fl & FL_STYLE_MASK) >> FL_STYLE_SHIFT)];
  202. // Set up to enumerate the path:
  203. if (pco->iDComplexity != DC_COMPLEX)
  204. {
  205. PATHDATA pd;
  206. RECTL* prclClip = (RECTL*) NULL;
  207. BOOL bMore;
  208. ULONG cptfx;
  209. POINTFIX ptfxStartFigure;
  210. POINTFIX ptfxLast;
  211. POINTFIX* pptfxFirst;
  212. POINTFIX* pptfxBuf;
  213. if (pco->iDComplexity == DC_RECT)
  214. {
  215. fl |= FL_SIMPLE_CLIP;
  216. arclClip[0] = pco->rclBounds;
  217. // FL_FLIP_D:
  218. arclClip[1].top = pco->rclBounds.left;
  219. arclClip[1].left = pco->rclBounds.top;
  220. arclClip[1].bottom = pco->rclBounds.right;
  221. arclClip[1].right = pco->rclBounds.bottom;
  222. // FL_FLIP_V:
  223. arclClip[2].top = -pco->rclBounds.bottom + 1;
  224. arclClip[2].left = pco->rclBounds.left;
  225. arclClip[2].bottom = -pco->rclBounds.top + 1;
  226. arclClip[2].right = pco->rclBounds.right;
  227. // FL_FLIP_V | FL_FLIP_D:
  228. arclClip[3].top = pco->rclBounds.left;
  229. arclClip[3].left = -pco->rclBounds.bottom + 1;
  230. arclClip[3].bottom = pco->rclBounds.right;
  231. arclClip[3].right = -pco->rclBounds.top + 1;
  232. prclClip = arclClip;
  233. } // End DC_RECT
  234. pd.flags = 0;
  235. do {
  236. bMore = PATHOBJ_bEnum(ppo, &pd);
  237. cptfx = pd.count;
  238. if (cptfx == 0)
  239. {
  240. break;
  241. }
  242. if (pd.flags & PD_BEGINSUBPATH)
  243. {
  244. ptfxStartFigure = *pd.pptfx;
  245. pptfxFirst = pd.pptfx;
  246. pptfxBuf = pd.pptfx + 1;
  247. cptfx--;
  248. }
  249. else
  250. {
  251. pptfxFirst = &ptfxLast;
  252. pptfxBuf = pd.pptfx;
  253. }
  254. if (pd.flags & PD_RESETSTYLE)
  255. ls.spNext = 0;
  256. if (cptfx > 0)
  257. {
  258. if (!bLines(ppdev,
  259. pptfxFirst,
  260. pptfxBuf,
  261. (RUN*) NULL,
  262. cptfx,
  263. &ls,
  264. prclClip,
  265. apfn,
  266. fl))
  267. {
  268. LogStrokePath(2, ppdev, pco, pbo, mix, pla, ppo);
  269. return(FALSE);
  270. }
  271. }
  272. ptfxLast = pd.pptfx[pd.count - 1];
  273. if (pd.flags & PD_CLOSEFIGURE)
  274. {
  275. if (!bLines(ppdev,
  276. &ptfxLast,
  277. &ptfxStartFigure,
  278. (RUN*) NULL,
  279. 1,
  280. &ls,
  281. prclClip,
  282. apfn,
  283. fl))
  284. {
  285. LogStrokePath(2, ppdev, pco, pbo, mix, pla, ppo);
  286. return(FALSE);
  287. }
  288. }
  289. } while (bMore);
  290. if (fl & FL_STYLED)
  291. {
  292. // Save the style state:
  293. ULONG ulHigh;
  294. ULONG ulLow;
  295. // Masked styles don't normalize the style state. It's a good
  296. // thing to do, so let's do it now:
  297. if ((ULONG) ls.spNext >= (ULONG) ls.spTotal2)
  298. ls.spNext = (ULONG) ls.spNext % (ULONG) ls.spTotal2;
  299. ulHigh = ls.spNext / ls.xyDensity;
  300. ulLow = ls.spNext % ls.xyDensity;
  301. pla->elStyleState.l = MAKELONG(ulLow, ulHigh);
  302. }
  303. } // End non complex clipping.
  304. else // clipping is DC_COMPLEX
  305. {
  306. // Local state for path enumeration:
  307. BOOL bMore;
  308. union {
  309. BYTE aj[offsetof(CLIPLINE, arun) + RUN_MAX * sizeof(RUN)];
  310. CLIPLINE cl;
  311. } cl;
  312. fl |= FL_COMPLEX_CLIP;
  313. // We use the clip object when non-simple clipping is involved:
  314. PATHOBJ_vEnumStartClipLines(ppo, pco, pso, pla);
  315. do {
  316. bMore = PATHOBJ_bEnumClipLines(ppo, sizeof(cl), &cl.cl);
  317. if (cl.cl.c != 0)
  318. {
  319. if (fl & FL_STYLED)
  320. {
  321. ls.spComplex = HIWORD(cl.cl.lStyleState) * ls.xyDensity
  322. + LOWORD(cl.cl.lStyleState);
  323. }
  324. if (!bLines(ppdev,
  325. &cl.cl.ptfxA,
  326. &cl.cl.ptfxB,
  327. &cl.cl.arun[0],
  328. cl.cl.c,
  329. &ls,
  330. (RECTL*) NULL,
  331. apfn,
  332. fl))
  333. {
  334. LogStrokePath(2, ppdev, pco, pbo, mix, pla, ppo);
  335. return(FALSE);
  336. }
  337. }
  338. } while (bMore);
  339. }
  340. DISPDBG((STROKE_DBG_LEVEL,"DrvStrokePath: Exit.\n"));
  341. LogStrokePath(0, ppdev, pco, pbo, mix, pla, ppo);
  342. return(TRUE);
  343. }
  344. #if LOG_CALLS
  345. extern long lg_i;
  346. extern char lg_buf[256];
  347. void LogStrokePath(
  348. ULONG acc,
  349. PPDEV ppdev,
  350. CLIPOBJ* pco,
  351. BRUSHOBJ* pbo,
  352. MIX mix,
  353. LINEATTRS* pla,
  354. PATHOBJ* ppo
  355. )
  356. {
  357. BYTE iDComplexity;
  358. #if ENABLE_LOG_SWITCH
  359. if (pointer_switch == 0) return;
  360. #endif
  361. lg_i = sprintf(lg_buf,"DSP: ");
  362. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  363. // Did we realize it? If not, why?
  364. switch (acc)
  365. {
  366. case 0: lg_i = sprintf(lg_buf,"(ACCL) "); break;
  367. case 2: lg_i = sprintf(lg_buf,"(Punt - bLines failed) "); break;
  368. case 3: lg_i = sprintf(lg_buf,"(Punt - S3) "); break;
  369. case 4: lg_i = sprintf(lg_buf,"(Punt - DevBmp on host) "); break;
  370. default: lg_i = sprintf(lg_buf,"(STATUS UNKNOWN) "); break;
  371. }
  372. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  373. //
  374. // Check the type of clipping.
  375. //
  376. iDComplexity = (pco ? pco->iDComplexity : DC_TRIVIAL);
  377. lg_i = sprintf(lg_buf,"C=%s ",
  378. (iDComplexity==DC_TRIVIAL ? "T":
  379. (iDComplexity == DC_RECT ? "R" : "C" )));
  380. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  381. //
  382. // Check the brush
  383. //
  384. if (pbo)
  385. if (pbo->iSolidColor == 0xFFFFFFFF )
  386. lg_i = sprintf(lg_buf,"BR=P ");
  387. else
  388. lg_i = sprintf(lg_buf,"BR=0x%X ",(pbo->iSolidColor));
  389. else
  390. lg_i = sprintf(lg_buf,"BR=N ");
  391. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  392. //
  393. // Check the MIX
  394. //
  395. lg_i = sprintf(lg_buf,"MIX = 0x%04X ", mix);
  396. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  397. //
  398. // Check the Line Attrs
  399. //
  400. if (pla->fl & LA_GEOMETRIC) lg_i = sprintf(lg_buf,"LA=G ");
  401. else if (pla->fl & LA_ALTERNATE) lg_i = sprintf(lg_buf,"LA=A ");
  402. else if (pla->fl & LA_STARTGAP) lg_i = sprintf(lg_buf,"LA=S ");
  403. else lg_i = sprintf(lg_buf,"LA=U ");
  404. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  405. if (pla->iJoin == JOIN_ROUND) lg_i = sprintf(lg_buf,"J=R ");
  406. else if (pla->iJoin == JOIN_BEVEL) lg_i = sprintf(lg_buf,"J=B ");
  407. else if (pla->iJoin == JOIN_MITER) lg_i = sprintf(lg_buf,"J=M ");
  408. else lg_i = sprintf(lg_buf,"J=U ");
  409. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  410. if (pla->iEndCap == ENDCAP_ROUND) lg_i = sprintf(lg_buf,"E=R ");
  411. else if (pla->iEndCap == ENDCAP_SQUARE) lg_i = sprintf(lg_buf,"E=S ");
  412. else if (pla->iEndCap == ENDCAP_BUTT) lg_i = sprintf(lg_buf,"E=B ");
  413. else lg_i = sprintf(lg_buf,"E=U ");
  414. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  415. if (pla->pstyle == NULL) lg_i = sprintf(lg_buf,"SOLID ");
  416. else lg_i = sprintf(lg_buf,"STYLED ");
  417. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  418. lg_i = sprintf(lg_buf,"\r\n");
  419. WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex);
  420. }
  421. #endif