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.

2062 lines
46 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. pclxl.cpp
  5. Abstract:
  6. PCL-XL command output high level function implementation
  7. Environment:
  8. Windows Whistler
  9. Revision History:
  10. 08/23/99
  11. Created initial framework.
  12. --*/
  13. #include "xlpdev.h"
  14. #include "pclxlcmd.h"
  15. #include "pclxle.h"
  16. #include "xldebug.h"
  17. #include "xlgstate.h"
  18. #include "xloutput.h"
  19. #include "xlbmpcvt.h"
  20. //
  21. // Hatch brush raster pattern
  22. //
  23. const BYTE gubSizeOfHatchBrush = 32 * 32 / 8;
  24. const USHORT gusWidthOfHatchBrush = 32;
  25. const USHORT gusHeightOfHatchBrush = 32;
  26. const BYTE gubHatchBrush[6][gubSizeOfHatchBrush] =
  27. { {0x00, 0x00, 0x00, 0x00,
  28. 0x00, 0x00, 0x00, 0x00,
  29. 0x00, 0x00, 0x00, 0x00,
  30. 0x00, 0x00, 0x00, 0x00,
  31. 0x00, 0x00, 0x00, 0x00,
  32. 0x00, 0x00, 0x00, 0x00,
  33. 0x00, 0x00, 0x00, 0x00,
  34. 0x00, 0x00, 0x00, 0x00,
  35. 0x00, 0x00, 0x00, 0x00,
  36. 0x00, 0x00, 0x00, 0x00,
  37. 0x00, 0x00, 0x00, 0x00,
  38. 0x00, 0x00, 0x00, 0x00,
  39. 0x00, 0x00, 0x00, 0x00,
  40. 0x00, 0x00, 0x00, 0x00,
  41. 0x00, 0x00, 0x00, 0x00,
  42. 0x00, 0x00, 0x00, 0x00,
  43. 0x00, 0x00, 0x00, 0x00,
  44. 0x00, 0x00, 0x00, 0x00,
  45. 0x00, 0x00, 0x00, 0x00,
  46. 0x00, 0x00, 0x00, 0x00,
  47. 0x00, 0x00, 0x00, 0x00,
  48. 0x00, 0x00, 0x00, 0x00,
  49. 0x00, 0x00, 0x00, 0x00,
  50. 0x00, 0x00, 0x00, 0x00,
  51. 0x00, 0x00, 0x00, 0x00,
  52. 0x00, 0x00, 0x00, 0x00,
  53. 0x00, 0x00, 0x00, 0x00,
  54. 0x00, 0x00, 0x00, 0x00,
  55. 0x00, 0x00, 0x00, 0x00,
  56. 0x00, 0x00, 0x00, 0x00,
  57. 0x00, 0x00, 0x00, 0x00,
  58. 0xff, 0xff, 0xff, 0xff},
  59. {0x00, 0x00, 0x00, 0x01,
  60. 0x00, 0x00, 0x00, 0x01,
  61. 0x00, 0x00, 0x00, 0x01,
  62. 0x00, 0x00, 0x00, 0x01,
  63. 0x00, 0x00, 0x00, 0x01,
  64. 0x00, 0x00, 0x00, 0x01,
  65. 0x00, 0x00, 0x00, 0x01,
  66. 0x00, 0x00, 0x00, 0x01,
  67. 0x00, 0x00, 0x00, 0x01,
  68. 0x00, 0x00, 0x00, 0x01,
  69. 0x00, 0x00, 0x00, 0x01,
  70. 0x00, 0x00, 0x00, 0x01,
  71. 0x00, 0x00, 0x00, 0x01,
  72. 0x00, 0x00, 0x00, 0x01,
  73. 0x00, 0x00, 0x00, 0x01,
  74. 0x00, 0x00, 0x00, 0x01,
  75. 0x00, 0x00, 0x00, 0x01,
  76. 0x00, 0x00, 0x00, 0x01,
  77. 0x00, 0x00, 0x00, 0x01,
  78. 0x00, 0x00, 0x00, 0x01,
  79. 0x00, 0x00, 0x00, 0x01,
  80. 0x00, 0x00, 0x00, 0x01,
  81. 0x00, 0x00, 0x00, 0x01,
  82. 0x00, 0x00, 0x00, 0x01,
  83. 0x00, 0x00, 0x00, 0x01,
  84. 0x00, 0x00, 0x00, 0x01,
  85. 0x00, 0x00, 0x00, 0x01,
  86. 0x00, 0x00, 0x00, 0x01,
  87. 0x00, 0x00, 0x00, 0x01,
  88. 0x00, 0x00, 0x00, 0x01,
  89. 0x00, 0x00, 0x00, 0x01,
  90. 0x00, 0x00, 0x00, 0x01},
  91. {0x80, 0x00, 0x00, 0x00,
  92. 0x40, 0x00, 0x00, 0x00,
  93. 0x20, 0x00, 0x00, 0x00,
  94. 0x10, 0x00, 0x00, 0x00,
  95. 0x08, 0x00, 0x00, 0x00,
  96. 0x04, 0x00, 0x00, 0x00,
  97. 0x02, 0x00, 0x00, 0x00,
  98. 0x01, 0x00, 0x00, 0x00,
  99. 0x00, 0x80, 0x00, 0x00,
  100. 0x00, 0x40, 0x00, 0x00,
  101. 0x00, 0x20, 0x00, 0x00,
  102. 0x00, 0x10, 0x00, 0x00,
  103. 0x00, 0x08, 0x00, 0x00,
  104. 0x00, 0x04, 0x00, 0x00,
  105. 0x00, 0x02, 0x00, 0x00,
  106. 0x00, 0x01, 0x00, 0x00,
  107. 0x00, 0x00, 0x80, 0x00,
  108. 0x00, 0x00, 0x40, 0x00,
  109. 0x00, 0x00, 0x20, 0x00,
  110. 0x00, 0x00, 0x10, 0x00,
  111. 0x00, 0x00, 0x08, 0x00,
  112. 0x00, 0x00, 0x04, 0x00,
  113. 0x00, 0x00, 0x02, 0x00,
  114. 0x00, 0x00, 0x01, 0x00,
  115. 0x00, 0x00, 0x00, 0x80,
  116. 0x00, 0x00, 0x00, 0x40,
  117. 0x00, 0x00, 0x00, 0x20,
  118. 0x00, 0x00, 0x00, 0x10,
  119. 0x00, 0x00, 0x00, 0x08,
  120. 0x00, 0x00, 0x00, 0x04,
  121. 0x00, 0x00, 0x00, 0x02,
  122. 0x00, 0x00, 0x00, 0x01},
  123. {
  124. 0x00, 0x00, 0x00, 0x01,
  125. 0x00, 0x00, 0x00, 0x02,
  126. 0x00, 0x00, 0x00, 0x04,
  127. 0x00, 0x00, 0x00, 0x08,
  128. 0x00, 0x00, 0x00, 0x10,
  129. 0x00, 0x00, 0x00, 0x20,
  130. 0x00, 0x00, 0x00, 0x40,
  131. 0x00, 0x00, 0x00, 0x80,
  132. 0x00, 0x00, 0x01, 0x00,
  133. 0x00, 0x00, 0x02, 0x00,
  134. 0x00, 0x00, 0x04, 0x00,
  135. 0x00, 0x00, 0x08, 0x00,
  136. 0x00, 0x00, 0x10, 0x00,
  137. 0x00, 0x00, 0x20, 0x00,
  138. 0x00, 0x00, 0x40, 0x00,
  139. 0x00, 0x00, 0x80, 0x00,
  140. 0x00, 0x01, 0x00, 0x00,
  141. 0x00, 0x02, 0x00, 0x00,
  142. 0x00, 0x04, 0x00, 0x00,
  143. 0x00, 0x08, 0x00, 0x00,
  144. 0x00, 0x10, 0x00, 0x00,
  145. 0x00, 0x20, 0x00, 0x00,
  146. 0x00, 0x40, 0x00, 0x00,
  147. 0x00, 0x80, 0x00, 0x00,
  148. 0x01, 0x00, 0x00, 0x00,
  149. 0x02, 0x00, 0x00, 0x00,
  150. 0x04, 0x00, 0x00, 0x00,
  151. 0x08, 0x00, 0x00, 0x00,
  152. 0x10, 0x00, 0x00, 0x00,
  153. 0x20, 0x00, 0x00, 0x00,
  154. 0x40, 0x00, 0x00, 0x00,
  155. 0x80, 0x00, 0x00, 0x00},
  156. {0xff, 0xff, 0xff, 0xff,
  157. 0x00, 0x00, 0x00, 0x01,
  158. 0x00, 0x00, 0x00, 0x01,
  159. 0x00, 0x00, 0x00, 0x01,
  160. 0x00, 0x00, 0x00, 0x01,
  161. 0x00, 0x00, 0x00, 0x01,
  162. 0x00, 0x00, 0x00, 0x01,
  163. 0x00, 0x00, 0x00, 0x01,
  164. 0x00, 0x00, 0x00, 0x01,
  165. 0x00, 0x00, 0x00, 0x01,
  166. 0x00, 0x00, 0x00, 0x01,
  167. 0x00, 0x00, 0x00, 0x01,
  168. 0x00, 0x00, 0x00, 0x01,
  169. 0x00, 0x00, 0x00, 0x01,
  170. 0x00, 0x00, 0x00, 0x01,
  171. 0x00, 0x00, 0x00, 0x01,
  172. 0x00, 0x00, 0x00, 0x01,
  173. 0x00, 0x00, 0x00, 0x01,
  174. 0x00, 0x00, 0x00, 0x01,
  175. 0x00, 0x00, 0x00, 0x01,
  176. 0x00, 0x00, 0x00, 0x01,
  177. 0x00, 0x00, 0x00, 0x01,
  178. 0x00, 0x00, 0x00, 0x01,
  179. 0x00, 0x00, 0x00, 0x01,
  180. 0x00, 0x00, 0x00, 0x01,
  181. 0x00, 0x00, 0x00, 0x01,
  182. 0x00, 0x00, 0x00, 0x01,
  183. 0x00, 0x00, 0x00, 0x01,
  184. 0x00, 0x00, 0x00, 0x01,
  185. 0x00, 0x00, 0x00, 0x01,
  186. 0x00, 0x00, 0x00, 0x01,
  187. 0x00, 0x00, 0x00, 0x01},
  188. {0x80, 0x00, 0x00, 0x01,
  189. 0x40, 0x00, 0x00, 0x02,
  190. 0x20, 0x00, 0x00, 0x04,
  191. 0x10, 0x00, 0x00, 0x08,
  192. 0x08, 0x00, 0x00, 0x10,
  193. 0x04, 0x00, 0x00, 0x20,
  194. 0x02, 0x00, 0x00, 0x40,
  195. 0x01, 0x00, 0x00, 0x80,
  196. 0x00, 0x80, 0x01, 0x00,
  197. 0x00, 0x40, 0x02, 0x00,
  198. 0x00, 0x20, 0x04, 0x00,
  199. 0x00, 0x10, 0x08, 0x00,
  200. 0x00, 0x08, 0x10, 0x00,
  201. 0x00, 0x04, 0x20, 0x00,
  202. 0x00, 0x02, 0x40, 0x00,
  203. 0x00, 0x01, 0x80, 0x00,
  204. 0x00, 0x01, 0x80, 0x00,
  205. 0x00, 0x02, 0x40, 0x00,
  206. 0x00, 0x04, 0x20, 0x00,
  207. 0x00, 0x08, 0x10, 0x00,
  208. 0x00, 0x10, 0x08, 0x00,
  209. 0x00, 0x20, 0x04, 0x00,
  210. 0x00, 0x40, 0x02, 0x00,
  211. 0x00, 0x80, 0x01, 0x00,
  212. 0x01, 0x00, 0x00, 0x80,
  213. 0x02, 0x00, 0x00, 0x40,
  214. 0x04, 0x00, 0x00, 0x20,
  215. 0x08, 0x00, 0x00, 0x10,
  216. 0x10, 0x00, 0x00, 0x08,
  217. 0x20, 0x00, 0x00, 0x04,
  218. 0x40, 0x00, 0x00, 0x02,
  219. 0x80, 0x00, 0x00, 0x01}
  220. };
  221. //
  222. // High level output functions
  223. //
  224. HRESULT
  225. XLOutput::
  226. BeginImage(
  227. ColorMapping CMapping,
  228. ULONG ulOutputBPP,
  229. ULONG ulSrcWidth,
  230. ULONG ulSrcHeight,
  231. ULONG ulDestWidth,
  232. ULONG ulDestHeight)
  233. /*++
  234. Routine Description:
  235. Sends BeginImage operator.
  236. Arguments:
  237. Return Value:
  238. Note:
  239. --*/
  240. {
  241. DWORD dwI = 0;
  242. XL_VERBOSE(("XLOutput::BeginImage:SrcW=%d, SrcH=%d, DstH=%d, DstW=%d\n",
  243. ulSrcWidth, ulSrcHeight, ulDestHeight, ulDestWidth));
  244. SetOutputBPP(CMapping, ulOutputBPP);
  245. SetSourceWidth((uint16)ulSrcWidth);
  246. SetSourceHeight((uint16)ulSrcHeight);
  247. SetDestinationSize((uint16)ulDestWidth, (uint16)ulDestHeight);
  248. Send_cmd(eBeginImage);
  249. return S_OK;
  250. }
  251. HRESULT
  252. XLOutput::
  253. SetOutputBPP(
  254. ColorMapping CMapping,
  255. ULONG ulOutputBPP)
  256. /*++
  257. Routine Description:
  258. Sends Color mapping and output depth.
  259. Arguments:
  260. Return Value:
  261. Note:
  262. --*/
  263. {
  264. switch (CMapping)
  265. {
  266. case eDirectPixel:
  267. SetColorMapping(eDirectPixel);
  268. break;
  269. case eIndexedPixel:
  270. SetColorMapping(eIndexedPixel);
  271. break;
  272. default:
  273. SetColorMapping(eDirectPixel);
  274. }
  275. switch (ulOutputBPP)
  276. {
  277. case 1:
  278. SetColorDepth(e1Bit);
  279. break;
  280. case 4:
  281. SetColorDepth(e4Bit);
  282. break;
  283. case 8:
  284. case 24:
  285. SetColorDepth(e8Bit);
  286. break;
  287. default:
  288. XL_ERR(("ulOutputBPP = %d is not supported\n", ulOutputBPP));
  289. //
  290. // Send color depth anyway to avoid XL error.
  291. //
  292. SetColorDepth(e8Bit);
  293. }
  294. return S_OK;
  295. }
  296. HRESULT
  297. XLOutput::
  298. SetPalette(
  299. ULONG ulOutputBPP,
  300. DWORD dwCEntries,
  301. DWORD *pdwColor)
  302. /*++
  303. Routine Description:
  304. Arguments:
  305. Return Value:
  306. Note:
  307. --*/
  308. {
  309. HRESULT hResult;
  310. if (dwCEntries != 0 && pdwColor != NULL)
  311. {
  312. SetPaletteDepth(e8Bit);
  313. SetPaletteData(m_DeviceColorDepth, dwCEntries, pdwColor);
  314. hResult = S_OK;
  315. }
  316. else
  317. {
  318. XL_ERR(("XLOutput::SetPalette pxlo = NULL\n"));
  319. hResult = S_FALSE;
  320. }
  321. return hResult;
  322. }
  323. HRESULT
  324. XLOutput::
  325. SetClip(
  326. CLIPOBJ *pco)
  327. /*++
  328. Routine Description:
  329. Sends clip object.
  330. Arguments:
  331. Return Value:
  332. Note:
  333. --*/
  334. {
  335. PATHOBJ *ppo;
  336. XLGState *pGState = this;
  337. HRESULT hResult;
  338. if (S_OK == pGState->CheckClip(pco))
  339. return S_OK;
  340. if ( NULL == pco )
  341. {
  342. XL_VERBOSE(("XLOutput::SetClip pco = NULL.\n"));
  343. Send_cmd(eSetClipToPage);
  344. pGState->ClearClip();
  345. return S_OK;
  346. }
  347. XL_VERBOSE(("XLOutput::SetClip: pco->iDComplexity=%d\n", pco->iDComplexity));
  348. switch(pco->iDComplexity)
  349. {
  350. case DC_RECT:
  351. SetClipMode(eClipEvenOdd);
  352. Send_cmd(eNewPath);
  353. RectanglePath(&(pco->rclBounds));
  354. SetClipRegion(eInterior);
  355. Send_cmd(eSetClipReplace);
  356. pGState->SetClip(pco);
  357. hResult = S_OK;
  358. break;
  359. case DC_COMPLEX:
  360. ppo = CLIPOBJ_ppoGetPath(pco);
  361. if (NULL == ppo)
  362. {
  363. XL_ERR(("XLOutput::SetClip ppo = NULL.\n"));
  364. Send_cmd(eSetClipToPage);
  365. pGState->ClearClip();
  366. hResult = S_FALSE;
  367. break;
  368. }
  369. SetClipMode(eClipEvenOdd);
  370. Path(ppo);
  371. SetClipRegion(eInterior);
  372. Send_cmd(eSetClipReplace);
  373. pGState->SetClip(pco);
  374. hResult = S_OK;
  375. break;
  376. case DC_TRIVIAL:
  377. default:
  378. Send_cmd(eSetClipToPage);
  379. pGState->ClearClip();
  380. hResult = S_OK;
  381. break;
  382. }
  383. return hResult;
  384. }
  385. HRESULT
  386. XLOutput::
  387. RoundRectanglePath(
  388. RECTL *prclBounds)
  389. /*++
  390. Routine Description:
  391. Arguments:
  392. Return Value:
  393. Note:
  394. --*/
  395. {
  396. RECTL Rectl;
  397. if ( NULL == prclBounds )
  398. {
  399. XL_ERR(("XLOutput::RoundRectangle prclBounds = NULL.\n"));
  400. return E_UNEXPECTED;
  401. }
  402. XL_VERBOSE(("XLOutput::RoundRectanglePath:left=%d, top=%d, right=%d, bottom=%d\n",
  403. prclBounds->left,
  404. prclBounds->top,
  405. prclBounds->right,
  406. prclBounds->bottom));
  407. //
  408. // BoundingBox can handle only positive numbers.
  409. //
  410. Rectl = *prclBounds;
  411. if (Rectl.left < 0)
  412. {
  413. Rectl.left = 0;
  414. }
  415. if (Rectl.top < 0)
  416. {
  417. Rectl.top = 0;
  418. }
  419. if (Rectl.right < 0)
  420. {
  421. Rectl.right = 0;
  422. }
  423. if (Rectl.bottom < 0)
  424. {
  425. Rectl.bottom = 0;
  426. }
  427. //
  428. // DCR: Round value needs to be sent!
  429. //
  430. if (S_OK == SetBoundingBox((uint16)Rectl.left,
  431. (uint16)Rectl.top,
  432. (uint16)Rectl.right,
  433. (uint16)Rectl.bottom) &&
  434. S_OK == Send_uint16_xy(0, 0) &&
  435. S_OK == Send_attr_ubyte(eEllipseDimension) &&
  436. S_OK == Send_cmd(eRoundRectanglePath))
  437. return S_OK;
  438. else
  439. return S_FALSE;
  440. }
  441. HRESULT
  442. XLOutput::
  443. SetCursor(
  444. LONG lX,
  445. LONG lY)
  446. /*++
  447. Routine Description:
  448. Set cursor.
  449. Arguments:
  450. Return Value:
  451. Note:
  452. --*/
  453. {
  454. XL_VERBOSE(("XLOutput::SetCursor:X=%d, Y=%d\n", lX, lY));
  455. Send_sint16_xy((sint16)lX, (sint16)lY);
  456. Send_attr_ubyte(ePoint);
  457. Send_cmd(eSetCursor);
  458. m_lX = lX;
  459. m_lY = lY;
  460. return S_OK;
  461. }
  462. HRESULT
  463. XLOutput::
  464. GetCursorPos(
  465. PLONG plX,
  466. PLONG plY)
  467. /*++
  468. Routine Description:
  469. Arguments:
  470. Return Value:
  471. Note:
  472. --*/
  473. {
  474. XL_VERBOSE(("XLOutput::GetCursor:X=%d, Y=%d\n", *plX, *plY));
  475. if (plX == NULL || plY == NULL)
  476. return E_UNEXPECTED;
  477. *plX = m_lX;
  478. *plY = m_lY;
  479. return S_OK;
  480. }
  481. HRESULT
  482. XLOutput::
  483. ReadImage(
  484. DWORD dwBlockHeight,
  485. CompressMode CMode)
  486. /*++
  487. Routine Description:
  488. Sends ReadImage operator
  489. Arguments:
  490. Return Value:
  491. Note:
  492. --*/
  493. {
  494. XL_VERBOSE(("XLOutput::ReadImage:dwBlockHeight=%d\n", dwBlockHeight));
  495. Send_uint16((uint16)0);
  496. Send_attr_ubyte(eStartLine);
  497. Send_uint16((uint16)dwBlockHeight);
  498. Send_attr_ubyte(eBlockHeight);
  499. //
  500. // DCR: Need to support JPEG
  501. //
  502. SetCompressMode(CMode);
  503. Send_cmd(eReadImage);
  504. return S_OK;
  505. }
  506. HRESULT
  507. XLOutput::
  508. ReadImage(
  509. DWORD dwStart,
  510. DWORD dwBlockHeight,
  511. CompressMode CMode)
  512. /*++
  513. Routine Description:
  514. Sends ReadImage operator
  515. Arguments:
  516. Return Value:
  517. Note:
  518. --*/
  519. {
  520. XL_VERBOSE(("XLOutput::ReadImage:dwBlockHeight=%d\n", dwBlockHeight));
  521. Send_uint16((uint16)dwStart);
  522. Send_attr_ubyte(eStartLine);
  523. Send_uint16((uint16)dwBlockHeight);
  524. Send_attr_ubyte(eBlockHeight);
  525. //
  526. // DCR: Need to support JPEG
  527. //
  528. SetCompressMode(CMode);
  529. Send_cmd(eReadImage);
  530. return S_OK;
  531. }
  532. HRESULT
  533. XLOutput::
  534. ReadRasterPattern(
  535. DWORD dwBlockHeight,
  536. CompressMode CMode)
  537. /*++
  538. Routine Description:
  539. Sends ReadRasterPattern operator.
  540. Arguments:
  541. Return Value:
  542. Note:
  543. --*/
  544. {
  545. XL_VERBOSE(("XLOutput::ReadRasterPattern:dwBlockHeight=%d\n", dwBlockHeight));
  546. Send_uint16((uint16)0);
  547. Send_attr_ubyte(eStartLine);
  548. Send_uint16((uint16)dwBlockHeight);
  549. Send_attr_ubyte(eBlockHeight);
  550. //
  551. // DCR: Need to support JPEG
  552. //
  553. SetCompressMode(CMode);
  554. Send_cmd(eReadRastPattern);
  555. return S_OK;
  556. }
  557. HRESULT
  558. XLOutput::
  559. SetRGBColor(
  560. uint32 uint32_RGB)
  561. /*++
  562. Routine Description:
  563. Sends SetGrayLevel attribute.
  564. Arguments:
  565. Return Value:
  566. Note:
  567. --*/
  568. {
  569. //
  570. // RGB color 3 bytes
  571. //
  572. Send_ubyte_array_header(3);
  573. WriteByte(RED(uint32_RGB));
  574. WriteByte(GREEN(uint32_RGB));
  575. WriteByte(BLUE(uint32_RGB));
  576. Send_attr_ubyte(eRGBColor);
  577. return S_OK;
  578. }
  579. HRESULT
  580. XLOutput::
  581. SetGrayLevel(
  582. ubyte ubyte_gray)
  583. /*++
  584. Routine Description:
  585. Sends SetGrayLevel attribute.
  586. Arguments:
  587. Return Value:
  588. Note:
  589. --*/
  590. {
  591. Send_ubyte(ubyte_gray);
  592. Send_attr_ubyte(eGrayLevel);
  593. return S_OK;
  594. }
  595. HRESULT
  596. XLOutput::
  597. RectanglePath(
  598. RECTL *prclRect)
  599. /*++
  600. Routine Description:
  601. Sends Rectangle Path
  602. Arguments:
  603. Return Value:
  604. Note:
  605. --*/
  606. {
  607. RECTL Rectl;
  608. if (NULL == prclRect)
  609. {
  610. XL_ERR(("XLOutput::RectanglePath: prclRect == NULL\n"));
  611. return E_UNEXPECTED;
  612. }
  613. XL_VERBOSE(("XLOutput::RectanglePath:left=%d, top=%d, right=%d, bottom=%d\n",
  614. prclRect->left,
  615. prclRect->top,
  616. prclRect->right,
  617. prclRect->bottom));
  618. Rectl = *prclRect;
  619. if (prclRect->left < 0)
  620. {
  621. Rectl.left = 0;
  622. }
  623. if (prclRect->top < 0)
  624. {
  625. Rectl.top = 0;
  626. }
  627. if (prclRect->right < 0)
  628. {
  629. Rectl.right = 0;
  630. }
  631. if (prclRect->bottom < 0)
  632. {
  633. Rectl.bottom = 0;
  634. }
  635. if (S_OK == SetBoundingBox((uint16)Rectl.left,
  636. (uint16)Rectl.top,
  637. (uint16)Rectl.right,
  638. (uint16)Rectl.bottom) &&
  639. S_OK == Send_cmd(eRectanglePath) )
  640. return S_OK;
  641. else
  642. return S_FALSE;
  643. }
  644. HRESULT
  645. XLOutput::
  646. Path(
  647. PATHOBJ *ppo)
  648. /*++
  649. Routine Description:
  650. Sends path.
  651. Arguments:
  652. Return Value:
  653. Note:
  654. --*/
  655. {
  656. POINTFIX* pptfx;
  657. PATHDATA PathData;
  658. LONG lPoints;
  659. HRESULT hResult;
  660. BOOL bMore;
  661. XL_VERBOSE(("XLOutput::Path\n"));
  662. if (ppo == NULL)
  663. {
  664. XL_ERR(("XLOutput::Path ppo = NULL.\n"));
  665. return E_UNEXPECTED;
  666. }
  667. //
  668. // Emit newpath operator
  669. // Don't do it if we're between path escapes
  670. //
  671. hResult = Send_cmd(eNewPath);
  672. //
  673. // Path object case
  674. //
  675. PATHOBJ_vEnumStart(ppo);
  676. do
  677. {
  678. bMore = PATHOBJ_bEnum(ppo, &PathData);
  679. pptfx = PathData.pptfx;
  680. if ( 0 == (lPoints = PathData.count))
  681. {
  682. XL_VERBOSE(("XLOutput::Path PathData.Count == 0\n"));
  683. hResult = S_FALSE;
  684. continue;
  685. }
  686. //
  687. // Begin new sub path
  688. //
  689. if (PathData.flags & PD_BEGINSUBPATH)
  690. {
  691. //
  692. // start new path
  693. //
  694. if (hResult == S_OK)
  695. hResult = SetCursor(FXTOL(pptfx->x), FXTOL(pptfx->y));;
  696. pptfx++;
  697. lPoints--;
  698. }
  699. if (lPoints > 0)
  700. {
  701. if (PathData.flags & PD_BEZIERS)
  702. {
  703. //
  704. // Output a Bezier curve segment
  705. //
  706. ASSERTMSG((lPoints % 3) == 0,
  707. ("Incorrect number of points for a Bezier curve: %d\n", lPoints));
  708. if (hResult == S_OK)
  709. hResult = BezierPath(pptfx, lPoints);
  710. }
  711. else
  712. {
  713. //
  714. // Draw straight line segment
  715. //
  716. if (hResult == S_OK)
  717. hResult = LinePath(pptfx, lPoints);
  718. }
  719. }
  720. //
  721. // Close subpath
  722. //
  723. if (PathData.flags & PD_CLOSEFIGURE)
  724. {
  725. if (hResult == S_OK)
  726. hResult = Send_cmd(eCloseSubPath);
  727. }
  728. }
  729. while (bMore);
  730. return hResult;
  731. }
  732. HRESULT
  733. XLOutput::
  734. BezierPath(
  735. POINTFIX* pptfx,
  736. LONG lPoints)
  737. /*++
  738. Routine Description:
  739. Sends bezier path
  740. Arguments:
  741. Return Value:
  742. Note:
  743. --*/
  744. {
  745. LONG lValue, lI;
  746. DWORD dwDataLength;
  747. if (NULL == pptfx)
  748. {
  749. XL_ERR(("XLOutput::BezierPath: pptfx == NULL\n"));
  750. return E_UNEXPECTED;
  751. }
  752. XL_VERBOSE(("XLOutput::BezierPath(lPoints=%d)\n",lPoints));
  753. Send_uint16((uint16)lPoints);
  754. Send_attr_ubyte(eNumberOfPoints);
  755. Send_ubyte(eSint16);
  756. Send_attr_ubyte(ePointType);
  757. Send_cmd(eBezierPath);
  758. dwDataLength = lPoints * 2 * sizeof(sint16);
  759. if (dwDataLength > 0xff)
  760. {
  761. WriteByte(PCLXL_dataLength);
  762. Write((PBYTE)&dwDataLength, sizeof(DWORD));
  763. }
  764. else
  765. {
  766. WriteByte(PCLXL_dataLengthByte);
  767. WriteByte((ubyte)dwDataLength);
  768. }
  769. for (lI = 0; lI < lPoints; lI++)
  770. {
  771. lValue = FXTOL(pptfx->x);
  772. Write((PBYTE)&lValue, sizeof(sint16));
  773. lValue = FXTOL(pptfx->y);
  774. Write((PBYTE)&lValue, sizeof(sint16));
  775. pptfx++;
  776. }
  777. //
  778. // Update the last coordinate.
  779. // Make sure that there are some points.
  780. if (lPoints > 0)
  781. {
  782. pptfx--;
  783. m_lX = FXTOL(pptfx->x);
  784. m_lY = FXTOL(pptfx->y);
  785. }
  786. else
  787. {
  788. m_lX = 0;
  789. m_lY = 0;
  790. }
  791. return S_OK;
  792. }
  793. HRESULT
  794. XLOutput::
  795. LinePath(
  796. POINTFIX* pptfx,
  797. LONG lPoints)
  798. /*++
  799. Routine Description:
  800. Sends line path.
  801. Arguments:
  802. Return Value:
  803. Note:
  804. --*/
  805. {
  806. LONG lValueX, lValueY, lI, lJ;
  807. LONG lx, ly;
  808. DWORD dwDataLength;
  809. if (NULL == pptfx)
  810. {
  811. XL_ERR(("XLOutput::LinePath: pptfx == NULL\n"));
  812. return E_UNEXPECTED;
  813. }
  814. XL_VERBOSE(("XLOutput::LinePath(lPoints=%d)\n", lPoints));
  815. //
  816. // Optimization. Use byte relpath to minimize the output size
  817. // First, check if the difference from the previous position is in a byte.
  818. //
  819. BOOL bModeChange;
  820. enum { eMode_SByte, eMode_SInt, eMode_None} Mode;
  821. LONG lStart, lEnd, lNumOfSByte;
  822. LONG lStartX, lStartY;
  823. POINTFIX *pptfx_tmp = pptfx;
  824. //
  825. // Get current cursor position
  826. //
  827. lStartX = lx = m_lX;
  828. lStartY = ly = m_lY;
  829. //
  830. // Reset
  831. //
  832. lStart = 0;
  833. Mode = eMode_None;
  834. bModeChange = FALSE;
  835. lNumOfSByte = 0;
  836. for (lI = 0; lI < lPoints; )
  837. {
  838. XL_VERBOSE(("XLOutput::LinePath: (%d)=(%d,%d)\n",lI, lx, ly));
  839. lValueX = FXTOL(pptfx_tmp->x) - (LONG)lx;
  840. lValueY = FXTOL(pptfx_tmp->y) - (LONG)ly;
  841. //
  842. // Mode needs to be in SByte or SInt?
  843. //
  844. if ( -128 <= lValueX && lValueX <= 127
  845. && -128 <= lValueY && lValueY <= 127 )
  846. {
  847. if (Mode == eMode_SInt)
  848. {
  849. //
  850. // Optimization
  851. //
  852. // To switch mode between SInt and SByte, it needs 7 bytes.
  853. //
  854. // uint16 XX NumberOfPoints
  855. // ubyte eSByte PointType
  856. // LineRelPath
  857. //
  858. // 4 points with SInt consumes 2 x 4 = 8 bytes extra data.
  859. // 3 points with SInt consumes 2 x 3 = 6 bytes extra data.
  860. //
  861. // 4 points is the threshold to swith mode to SInt.
  862. //
  863. // Number of points: lEnd - lStart + 1
  864. // if (lI - 1 - lStartSByte + 1 >= 4)
  865. //
  866. // If SByte continues more than 4 points, switch mode from
  867. // SByte to SInt.
  868. //
  869. if (lNumOfSByte >= 4)
  870. {
  871. bModeChange = TRUE;
  872. lI -= lNumOfSByte;
  873. pptfx_tmp -= lNumOfSByte;
  874. lEnd = (lI - 1);
  875. lNumOfSByte = 0;
  876. }
  877. //
  878. // Reset starting point of SByte
  879. //
  880. lNumOfSByte ++;
  881. }
  882. else
  883. {
  884. Mode = eMode_SByte;
  885. }
  886. XL_VERBOSE(("XLOutput::LinePath: (SByte) lx1=%d, lx2=%d\n", lx, FXTOL(pptfx_tmp->x)));
  887. }
  888. else
  889. {
  890. if (Mode == eMode_SByte)
  891. {
  892. bModeChange = TRUE;
  893. lEnd = lI - 1;
  894. }
  895. else
  896. {
  897. Mode = eMode_SInt;
  898. lNumOfSByte = 0;
  899. }
  900. XL_VERBOSE(("XLOutput::LinePath: (SInt) lx1=%d, lx2=%d\n", lx, FXTOL(pptfx_tmp->x)));
  901. }
  902. if (!bModeChange && lI + 1 == lPoints)
  903. {
  904. bModeChange = TRUE;
  905. lEnd = lI;
  906. lI ++;
  907. }
  908. if (bModeChange)
  909. {
  910. XL_VERBOSE(("XLOutput::LinePath: Draw\n"));
  911. //
  912. // Get start cursor position
  913. //
  914. lx = lStartX;
  915. ly = lStartY;
  916. if (Mode == eMode_SByte)
  917. {
  918. //
  919. // SByte
  920. //
  921. Send_uint16((uint16)(lEnd - lStart + 1));
  922. Send_attr_ubyte(eNumberOfPoints);
  923. Send_ubyte(eSByte);
  924. Send_attr_ubyte(ePointType);
  925. Send_cmd(eLineRelPath);
  926. dwDataLength = (lEnd - lStart + 1) * 2 * sizeof(ubyte);
  927. if (dwDataLength <= 0xFF)
  928. {
  929. WriteByte(PCLXL_dataLengthByte);
  930. WriteByte((ubyte)dwDataLength);
  931. }
  932. else
  933. {
  934. WriteByte(PCLXL_dataLength);
  935. Write((PBYTE)&dwDataLength, sizeof(DWORD));
  936. }
  937. for (lJ = 0; lJ <= (lEnd - lStart); lJ++)
  938. {
  939. lValueX = FXTOL(pptfx->x) - (LONG)lx;
  940. lValueY = FXTOL(pptfx->y) - (LONG)ly;
  941. Write((PBYTE)&lValueX, sizeof(ubyte));
  942. Write((PBYTE)&lValueY, sizeof(ubyte));
  943. lx = FXTOL(pptfx->x);
  944. ly = FXTOL(pptfx->y);
  945. pptfx++;
  946. }
  947. Mode = eMode_SInt;
  948. }
  949. else if (Mode == eMode_SInt)
  950. {
  951. //
  952. // SInt16
  953. //
  954. Send_uint16((uint16)(lEnd - lStart + 1));
  955. Send_attr_ubyte(eNumberOfPoints);
  956. Send_ubyte(eSint16);
  957. Send_attr_ubyte(ePointType);
  958. Send_cmd(eLineRelPath);
  959. dwDataLength = (lEnd - lStart + 1) * 2 * sizeof(uint16);
  960. if (dwDataLength <= 0xFF)
  961. {
  962. WriteByte(PCLXL_dataLengthByte);
  963. WriteByte((ubyte)dwDataLength);
  964. }
  965. else
  966. {
  967. WriteByte(PCLXL_dataLength);
  968. Write((PBYTE)&dwDataLength, sizeof(DWORD));
  969. }
  970. for (lJ = 0; lJ <= (lEnd - lStart); lJ++)
  971. {
  972. lValueX = FXTOL(pptfx->x) - (LONG)lx;
  973. lValueY = FXTOL(pptfx->y) - (LONG)ly;
  974. Write((PBYTE)&lValueX, sizeof(sint16));
  975. Write((PBYTE)&lValueY, sizeof(sint16));
  976. lx = FXTOL(pptfx->x);
  977. ly = FXTOL(pptfx->y);
  978. pptfx++;
  979. }
  980. Mode = eMode_SByte;
  981. }
  982. bModeChange = FALSE;
  983. lStartX = lx = FXTOL((pptfx_tmp-1)->x);
  984. lStartY = ly = FXTOL((pptfx_tmp-1)->y);
  985. lStart = lI;
  986. }
  987. else
  988. {
  989. lx = FXTOL((pptfx_tmp)->x);
  990. ly = FXTOL((pptfx_tmp)->y);
  991. pptfx_tmp ++;
  992. lI ++;
  993. }
  994. }
  995. //
  996. // Update cursor position
  997. //
  998. m_lX = FXTOL((pptfx_tmp)->x);
  999. m_lY = FXTOL((pptfx_tmp)->y);
  1000. return S_OK;
  1001. }
  1002. inline
  1003. VOID
  1004. XLOutput::
  1005. SetupBrush(
  1006. BRUSHOBJ *pbo,
  1007. POINTL *pptlBrushOrg,
  1008. CMNBRUSH *pcmnbrush)
  1009. /*++
  1010. Routine Description:
  1011. Arguments:
  1012. Return Value:
  1013. Note:
  1014. --*/
  1015. {
  1016. DWORD dwHatchID;
  1017. XLBRUSH *pBrush;
  1018. if (NULL == pcmnbrush)
  1019. {
  1020. //
  1021. // Make sure that pcmnbrush is valid.
  1022. //
  1023. XL_ERR(("SetupBrush:pcmnbrush is invalid.\n"));
  1024. return;
  1025. }
  1026. //
  1027. // Initialize CMNBRUSH
  1028. //
  1029. pcmnbrush->dwSig = BRUSH_SIGNATURE;
  1030. pcmnbrush->BrushType = kNoBrush;
  1031. pcmnbrush->ulHatch = 0XFFFFFFFF;
  1032. pcmnbrush->dwColor = 0x00FFFFFF;
  1033. pcmnbrush->dwCEntries = 0;
  1034. pcmnbrush->dwPatternBrushID = 0xFFFFFFFF;
  1035. XL_VERBOSE(("XLOutput::SetupBrush\n"));
  1036. if (NULL == pbo)
  1037. {
  1038. XL_VERBOSE(("XLOutput::SetupBrush: pbo == NULL, set NULL brush\n"));
  1039. }
  1040. else
  1041. {
  1042. #ifndef WINNT_40
  1043. if ( !(pbo->flColorType & BR_CMYKCOLOR) &&
  1044. (pbo->iSolidColor == NOT_SOLID_COLOR) )
  1045. #else
  1046. if (pbo->iSolidColor == NOT_SOLID_COLOR)
  1047. #endif
  1048. {
  1049. pcmnbrush->ulSolidColor = BRUSHOBJ_ulGetBrushColor(pbo);
  1050. pBrush = (XLBRUSH*)BRUSHOBJ_pvGetRbrush(pbo);
  1051. if (NULL == pBrush)
  1052. {
  1053. XL_ERR(("SetupBrush:BRUSHOBJ_pvGetRbrush failed.\n"));
  1054. dwHatchID = HS_DDI_MAX;
  1055. }
  1056. else
  1057. {
  1058. dwHatchID = pBrush->dwHatch;
  1059. }
  1060. }
  1061. else
  1062. {
  1063. dwHatchID = HS_DDI_MAX;
  1064. pcmnbrush->ulSolidColor = pbo->iSolidColor;
  1065. pBrush = NULL;
  1066. }
  1067. pcmnbrush->ulHatch = dwHatchID;
  1068. switch (dwHatchID)
  1069. {
  1070. case HS_HORIZONTAL:
  1071. case HS_VERTICAL:
  1072. case HS_BDIAGONAL:
  1073. case HS_FDIAGONAL:
  1074. case HS_CROSS:
  1075. case HS_DIAGCROSS:
  1076. XL_VERBOSE(("XLOutput::SetupBrush(uiSolidColor=%d,dwHatchID=%d)\n",
  1077. pbo->iSolidColor,
  1078. dwHatchID));
  1079. pcmnbrush->BrushType = kBrushTypeHatch;
  1080. pcmnbrush->dwPatternBrushID = dwHatchID;
  1081. if (pBrush)
  1082. {
  1083. pcmnbrush->dwColor = pBrush->dwColor;
  1084. }
  1085. if (GetDeviceColorDepth() == e24Bit)
  1086. {
  1087. SetColorSpace(eRGB);
  1088. }
  1089. else
  1090. {
  1091. SetColorSpace(eGray);
  1092. }
  1093. SetPaletteDepth(e8Bit);
  1094. if (pBrush->dwCEntries)
  1095. {
  1096. SetPaletteData(m_DeviceColorDepth, pBrush->dwCEntries, pBrush->adwColor);
  1097. }
  1098. else
  1099. {
  1100. DWORD dwColorTableTmp[2] = {0x00ffffff, 0x00ffffff};
  1101. dwColorTableTmp[1] = pBrush->dwColor;
  1102. SetPaletteData(m_DeviceColorDepth, 2, dwColorTableTmp);
  1103. }
  1104. Send_cmd(eSetColorSpace);
  1105. if (!(m_dwHatchBrushAvailability & (HORIZONTAL_AVAILABLE << dwHatchID)))
  1106. {
  1107. SetColorMapping(eIndexedPixel);
  1108. SetColorDepth(e1Bit);
  1109. SetSourceWidth((uint16)gusWidthOfHatchBrush);
  1110. SetSourceHeight((uint16)gusHeightOfHatchBrush);
  1111. //
  1112. // Pattern scaling factor
  1113. // 160 is an experimentally introduced number.
  1114. //
  1115. WORD wScale = (WORD)(160 * m_dwResolution / 1200);
  1116. SetDestinationSize((uint16)wScale, (uint16)wScale);
  1117. SetPatternPersistence(eSessionPattern);
  1118. SetPatternDefineID((sint16)dwHatchID);
  1119. Send_cmd(eBeginRastPattern);
  1120. Send_uint16((uint16)0);
  1121. Send_attr_ubyte(eStartLine);
  1122. Send_uint16((uint16)gusHeightOfHatchBrush);
  1123. Send_attr_ubyte(eBlockHeight);
  1124. SetCompressMode(eNoCompression);
  1125. Send_cmd(eReadRastPattern);
  1126. WriteByte(PCLXL_dataLengthByte);
  1127. WriteByte(gubSizeOfHatchBrush);
  1128. Write((PBYTE)gubHatchBrush[dwHatchID], gubSizeOfHatchBrush);
  1129. Send_cmd(eEndRastPattern);
  1130. m_dwHatchBrushAvailability |= HORIZONTAL_AVAILABLE << dwHatchID;
  1131. }
  1132. //
  1133. //SendPatternSelectID();
  1134. //
  1135. Send_sint16((sint16)dwHatchID);
  1136. Send_attr_ubyte(ePatternSelectID);
  1137. break;
  1138. case HS_DDI_MAX:
  1139. pcmnbrush->BrushType = kBrushTypeSolid;
  1140. //pcmnbrush->dwColor = BRUSHOBJ_ulGetBrushColor(pbo);
  1141. pcmnbrush->dwColor = pcmnbrush->ulSolidColor;
  1142. XL_VERBOSE(("XLOutput::SetupBrush(RGB=0x%x)\n", pcmnbrush->dwColor));
  1143. if (e24Bit == GetDeviceColorDepth())
  1144. {
  1145. SetRGBColor(pcmnbrush->dwColor);
  1146. }
  1147. else
  1148. {
  1149. ubyte ubyte_gray = (ubyte) DWORD2GRAY(pcmnbrush->dwColor);
  1150. SetGrayLevel(ubyte_gray);
  1151. }
  1152. break;
  1153. default:
  1154. if (NULL == pBrush)
  1155. {
  1156. XL_ERR(("XLOutput:SetupBrush: invalid pBrush\n"));
  1157. return;
  1158. }
  1159. XL_VERBOSE(("XLOutput::SetupBrush(PatternID=%d)\n", pBrush->dwPatternID));
  1160. pcmnbrush->dwColor = pBrush->dwColor;
  1161. pcmnbrush->dwPatternBrushID = pBrush->dwPatternID;
  1162. pcmnbrush->BrushType = kBrushTypePattern;
  1163. if (e24Bit == GetDeviceColorDepth())
  1164. {
  1165. SetColorSpace(eRGB);
  1166. }
  1167. else
  1168. {
  1169. SetColorSpace(eGray);
  1170. }
  1171. if (pBrush->dwCEntries)
  1172. {
  1173. SetPaletteDepth(e8Bit);
  1174. SetPaletteData(m_DeviceColorDepth, pBrush->dwCEntries, pBrush->adwColor);
  1175. }
  1176. Send_cmd(eSetColorSpace);
  1177. //SendPatternSelectID();
  1178. Send_sint16((sint16)pBrush->dwPatternID);
  1179. Send_attr_ubyte(ePatternSelectID);
  1180. }
  1181. }
  1182. return;
  1183. }
  1184. HRESULT
  1185. XLOutput::
  1186. SetPenColor(
  1187. BRUSHOBJ *pbo,
  1188. POINTL *pptlBrushOrg)
  1189. /*++
  1190. Routine Description:
  1191. Arguments:
  1192. Return Value:
  1193. Note:
  1194. --*/
  1195. {
  1196. XL_VERBOSE(("XLOutput::SetPenColor\n"));
  1197. XLPen *pPen = this;
  1198. CMNBRUSH cmnbrush;
  1199. if (S_OK == pPen->CheckCurrentBrush(pbo))
  1200. return S_OK;
  1201. if (NULL == pbo)
  1202. {
  1203. Send_ubyte(0);
  1204. Send_attr_ubyte(eNullPen);
  1205. }
  1206. SetupBrush(pbo, pptlBrushOrg, &cmnbrush);
  1207. Send_cmd(eSetPenSource);
  1208. pPen->SetBrush(&cmnbrush);
  1209. return S_OK;
  1210. }
  1211. HRESULT
  1212. XLOutput::
  1213. SetPen(
  1214. LINEATTRS *plineattrs,
  1215. XFORMOBJ *pxo)
  1216. /*++
  1217. Routine Description:
  1218. Arguments:
  1219. Return Value:
  1220. Note:
  1221. --*/
  1222. {
  1223. LineCap linecap;
  1224. XLLineEndCap xllinecap;
  1225. LineJoin linejoin;
  1226. XLLineJoin xllinejoin;
  1227. FLOATOBJ fLineWidth;
  1228. uint16 uint16_linewidth;
  1229. XL_VERBOSE(("XLOutput::SetPen\n"));
  1230. if (NULL == plineattrs)
  1231. {
  1232. XL_ERR(("XLOutput:SetPen: invalid parameters\n"));
  1233. return E_UNEXPECTED;
  1234. }
  1235. XLGState *pGState = this;
  1236. DWORD dwLine = pGState->GetDifferentAttribute(plineattrs);
  1237. //
  1238. // DCR: need to check each attribute.
  1239. //
  1240. if (XLLINE_NONE == dwLine)
  1241. return S_OK;
  1242. if (plineattrs->fl & LA_GEOMETRIC)
  1243. {
  1244. //
  1245. // Line joint
  1246. //
  1247. switch(plineattrs->iJoin)
  1248. {
  1249. case JOIN_ROUND:
  1250. linejoin = eRoundJoin;
  1251. xllinejoin = kXLLineJoin_Round;
  1252. break;
  1253. case JOIN_BEVEL:
  1254. linejoin = eBevelJoin;
  1255. xllinejoin = kXLLineJoin_Bevel;
  1256. break;
  1257. case JOIN_MITER:
  1258. linejoin = eMiterJoin;
  1259. xllinejoin = kXLLineJoin_Miter;
  1260. break;
  1261. default:
  1262. linejoin = eRoundJoin;
  1263. xllinejoin = kXLLineJoin_Round;
  1264. break;
  1265. }
  1266. //
  1267. // Line endcap
  1268. //
  1269. switch(plineattrs->iEndCap)
  1270. {
  1271. case ENDCAP_ROUND:
  1272. linecap = eRoundCap;
  1273. xllinecap = kXLLineEndCapRound;
  1274. break;
  1275. case ENDCAP_SQUARE:
  1276. linecap = eSquareCap;
  1277. xllinecap = kXLLineEndCapSquare;
  1278. break;
  1279. case ENDCAP_BUTT:
  1280. linecap = eButtCap;
  1281. xllinecap = kXLLineEndCapButt;
  1282. break;
  1283. default:
  1284. linecap = eRoundCap;
  1285. xllinecap = kXLLineEndCapRound;
  1286. break;
  1287. }
  1288. //
  1289. // Line width
  1290. //
  1291. fLineWidth = plineattrs->elWidth.e;
  1292. }
  1293. else
  1294. {
  1295. linejoin = eRoundJoin;
  1296. linecap = eRoundCap;
  1297. FLOATOBJ_SetLong(&fLineWidth, plineattrs->elWidth.l);
  1298. }
  1299. if (dwLine & XLLINE_WIDTH)
  1300. {
  1301. uint16_linewidth = (uint16)FLOATOBJ_GetLong(&fLineWidth);
  1302. SetPenWidth(uint16_linewidth);
  1303. pGState->SetLineWidth(plineattrs->elWidth);
  1304. }
  1305. if (dwLine & XLLINE_ENDCAP)
  1306. {
  1307. SetLineCap(linecap);
  1308. pGState->SetLineEndCap(xllinecap);
  1309. }
  1310. if (dwLine & XLLINE_JOIN)
  1311. {
  1312. SetLineJoin(linejoin);
  1313. pGState->SetLineJoin(xllinejoin);
  1314. }
  1315. //
  1316. // Line style
  1317. //
  1318. if (dwLine & XLLINE_STYLE)
  1319. {
  1320. if (plineattrs->cstyle == 0)
  1321. {
  1322. Send_ubyte((ubyte)0);
  1323. Send_attr_ubyte(eSolidLine);
  1324. Send_cmd(eSetLineDash);
  1325. }
  1326. else
  1327. {
  1328. DWORD dwI, dwSegCount;
  1329. PFLOAT_LONG plSize;
  1330. FLOAT_LONG lSize[2];
  1331. FLOATOBJ fSize;
  1332. uint16 uint16_linesize;
  1333. if (plineattrs->fl & LA_ALTERNATE)
  1334. {
  1335. if (plineattrs->fl & LA_GEOMETRIC)
  1336. {
  1337. FLOATOBJ_SetLong(&lSize[0].e, 1);
  1338. FLOATOBJ_SetLong(&lSize[1].e, 1);
  1339. }
  1340. else
  1341. {
  1342. lSize[0].l = 1;
  1343. lSize[1].l = 1;
  1344. }
  1345. dwSegCount = 2;
  1346. plSize = lSize;
  1347. }
  1348. else
  1349. {
  1350. dwSegCount = plineattrs->cstyle;
  1351. plSize = plineattrs->pstyle;
  1352. }
  1353. if (plSize)
  1354. {
  1355. Send_uint16_array_header(dwSegCount);
  1356. for (dwI = 0; dwI < dwSegCount; dwI ++, plSize ++)
  1357. {
  1358. if (plineattrs->fl & LA_GEOMETRIC)
  1359. {
  1360. fSize = plSize->e;
  1361. }
  1362. else
  1363. {
  1364. FLOATOBJ_SetLong(&fSize, plSize->l);
  1365. //
  1366. // It is necessary to scale the line pattern. The number
  1367. // 24 on 1200 dpi was introduced experimentally.
  1368. // Here is an assumption. Resolution could be 300, 600,
  1369. // or 1200.
  1370. //
  1371. if (m_dwResolution > 50)
  1372. {
  1373. FLOATOBJ_MulLong(&fSize, m_dwResolution / 50);
  1374. }
  1375. }
  1376. uint16_linesize = (uint16)FLOATOBJ_GetLong(&fSize);
  1377. Write((PBYTE)&uint16_linesize, sizeof(uint16_linesize));
  1378. }
  1379. Send_attr_ubyte(eLineDashStyle);
  1380. Send_cmd(eSetLineDash);
  1381. }
  1382. }
  1383. pGState->SetLineStyle(plineattrs->cstyle,
  1384. plineattrs->pstyle,
  1385. plineattrs->elStyleState);
  1386. }
  1387. if (dwLine & XLLINE_MITERLIMIT)
  1388. {
  1389. FLOATOBJ fMiter;
  1390. FLOATOBJ_SetFloat(&fMiter, plineattrs->eMiterLimit);
  1391. uint16 uint16_miter = (uint16)FLOATOBJ_GetLong(&fMiter);
  1392. //
  1393. // PCLXL interpreter doesn't accept miterlimiter less than 1.
  1394. // If it is less than 1, it replaces the value with 10.
  1395. // We'd better set 1 instead.
  1396. //
  1397. // Actuall less than 1 means 0 here, though.
  1398. //
  1399. if (uint16_miter < 1)
  1400. {
  1401. uint16_miter = 1;
  1402. }
  1403. SetMiterLimit(uint16_miter);
  1404. pGState->SetMiterLimit(plineattrs->eMiterLimit);
  1405. }
  1406. pGState->SetLineType((XLLineType)plineattrs->fl);
  1407. return S_OK;
  1408. }
  1409. HRESULT
  1410. XLOutput::
  1411. SetBrush(
  1412. BRUSHOBJ *pbo,
  1413. POINTL *pptlBrushOrg)
  1414. /*++
  1415. Routine Description:
  1416. Arguments:
  1417. Return Value:
  1418. Note:
  1419. --*/
  1420. {
  1421. XL_VERBOSE(("XLOutput::SetBrush\n"));
  1422. XLBrush *pBrush = this;
  1423. CMNBRUSH cmnbrush;
  1424. if (S_OK == pBrush->CheckCurrentBrush(pbo))
  1425. return S_OK;
  1426. if (NULL == pbo)
  1427. {
  1428. Send_ubyte(0);
  1429. Send_attr_ubyte(eNullBrush);
  1430. }
  1431. SetupBrush(pbo, pptlBrushOrg, &cmnbrush);
  1432. Send_cmd(eSetBrushSource);
  1433. pBrush->SetBrush(&cmnbrush);
  1434. return S_OK;
  1435. }
  1436. HRESULT
  1437. XLOutput::
  1438. Paint(
  1439. VOID)
  1440. /*++
  1441. Routine Description:
  1442. Arguments:
  1443. Return Value:
  1444. Note:
  1445. --*/
  1446. {
  1447. XL_VERBOSE(("XLOutput::Paint\n"));
  1448. return Send_cmd(ePaintPath);
  1449. }
  1450. HRESULT
  1451. XLOutput::
  1452. SetPaletteData(
  1453. ColorDepth value,
  1454. DWORD dwPaletteNum,
  1455. DWORD *pdwColorTable)
  1456. /*++
  1457. Routine Description:
  1458. Arguments:
  1459. Return Value:
  1460. Note:
  1461. --*/
  1462. {
  1463. DWORD dwI;
  1464. if (NULL == pdwColorTable)
  1465. {
  1466. XL_ERR(("XLOutput::SetPaletteData pdwColorTable == NULL\n"));
  1467. return E_UNEXPECTED;
  1468. }
  1469. switch (value)
  1470. {
  1471. case e8Bit:
  1472. WriteByte(PCLXL_ubyte_array);
  1473. Send_uint16((uint16)dwPaletteNum);
  1474. for (dwI = 0; dwI < dwPaletteNum; dwI ++)
  1475. WriteByte((ubyte)DWORD2GRAY(*(pdwColorTable+dwI)));
  1476. Send_attr_ubyte(ePaletteData);
  1477. break;
  1478. case e24Bit:
  1479. WriteByte(PCLXL_ubyte_array);
  1480. Send_uint16((uint16)dwPaletteNum * 3);
  1481. for (dwI = 0; dwI < dwPaletteNum; dwI ++)
  1482. {
  1483. Write((PBYTE)(pdwColorTable+dwI), 3);
  1484. }
  1485. Send_attr_ubyte(ePaletteData);
  1486. break;
  1487. default:
  1488. //
  1489. // DCR: only supports 8bits gray scale
  1490. //
  1491. XL_ERR(("XLOutput::SetPaletteData: unsupported ColorDepth:%d\n", value));
  1492. }
  1493. return S_OK;
  1494. }
  1495. HRESULT
  1496. XLOutput::
  1497. SetFont(
  1498. FontType fonttype,
  1499. PBYTE pFontName,
  1500. DWORD dwFontHeight,
  1501. DWORD dwFontWidth,
  1502. DWORD dwSymbolSet,
  1503. DWORD dwFontSimulation)
  1504. /*++
  1505. Routine Description:
  1506. Arguments:
  1507. Return Value:
  1508. Note:
  1509. --*/
  1510. {
  1511. FLOATOBJ fSize;
  1512. LONG lvalue;
  1513. if (NULL == pFontName)
  1514. {
  1515. XL_ERR(("XLOutput::SetFont: Invalie pFontName parameter\n"));
  1516. return E_UNEXPECTED;
  1517. }
  1518. XLGState *pGState = this;
  1519. if (S_OK == pGState->CheckCurrentFont(fonttype,
  1520. pFontName,
  1521. dwFontHeight,
  1522. dwFontWidth,
  1523. dwSymbolSet,
  1524. dwFontSimulation))
  1525. return S_OK;
  1526. FLOATOBJ_SetLong(&fSize, dwFontHeight);
  1527. lvalue = FLOATOBJ_GetFloat(&fSize);
  1528. //
  1529. // Select font
  1530. //
  1531. Send_ubyte_array_header(PCLXL_FONTNAME_SIZE);
  1532. Write(pFontName, PCLXL_FONTNAME_SIZE);
  1533. Send_attr_ubyte(eFontName);
  1534. Send_real32(lvalue);
  1535. Send_attr_ubyte(eCharSize);
  1536. Send_uint16((uint16)dwSymbolSet);
  1537. Send_attr_ubyte(eSymbolSet);
  1538. Send_cmd(eSetFont);
  1539. //
  1540. // TrueType font outline or device font
  1541. // Font Scale
  1542. // Font bold/italic simulaiton
  1543. //
  1544. if (fonttype == kFontTypeTTOutline ||
  1545. fonttype == kFontTypeDevice )
  1546. {
  1547. if (dwFontWidth != pGState->GetFontWidth() ||
  1548. dwFontHeight != pGState->GetFontHeight() )
  1549. {
  1550. //
  1551. // Scale X and Y
  1552. //
  1553. if (dwFontWidth != 0 && dwFontHeight != dwFontWidth)
  1554. {
  1555. FLOATOBJ fTemp;
  1556. FLOATOBJ_SetLong(&fTemp, dwFontWidth);
  1557. FLOATOBJ_DivFloat(&fTemp, fSize);
  1558. lvalue = FLOATOBJ_GetFloat(&fTemp);
  1559. Send_real32_xy((real32)lvalue, (real32)real32_IEEE_1_0F);
  1560. Send_attr_ubyte(eCharScale);
  1561. Send_cmd(eSetCharScale);
  1562. }
  1563. else
  1564. {
  1565. Send_real32_xy((real32)real32_IEEE_1_0F, (real32)real32_IEEE_1_0F);
  1566. Send_attr_ubyte(eCharScale);
  1567. Send_cmd(eSetCharScale);
  1568. }
  1569. }
  1570. DWORD dwCurrentFontSim = pGState->GetFontSimulation();
  1571. //
  1572. // Bold simulation
  1573. //
  1574. if ((dwFontSimulation & XLOUTPUT_FONTSIM_BOLD) !=
  1575. (dwCurrentFontSim& XLOUTPUT_FONTSIM_BOLD))
  1576. {
  1577. if (dwFontSimulation & XLOUTPUT_FONTSIM_BOLD)
  1578. {
  1579. //
  1580. // Hardcoded bold value 0.01500
  1581. //
  1582. #define XL_BOLD_VALUE 0x3c75c28f
  1583. Send_real32((real32)XL_BOLD_VALUE);
  1584. }
  1585. else
  1586. Send_real32((real32)0);
  1587. Send_attr_ubyte(eCharBoldValue);
  1588. Send_cmd(eSetCharBoldValue);
  1589. }
  1590. //
  1591. // Italic simulation
  1592. //
  1593. if ((dwFontSimulation & XLOUTPUT_FONTSIM_ITALIC) !=
  1594. (dwCurrentFontSim & XLOUTPUT_FONTSIM_ITALIC))
  1595. {
  1596. if (dwFontSimulation & XLOUTPUT_FONTSIM_ITALIC)
  1597. {
  1598. //
  1599. // Hardcoded italic value 0.316200
  1600. //
  1601. #define XL_ITALIC_VALUE 0x3ea1e4f7
  1602. Send_real32_xy((real32)XL_ITALIC_VALUE, (real32)0);
  1603. }
  1604. else
  1605. Send_real32_xy((real32)0, (real32)0);
  1606. Send_attr_ubyte(eCharShear);
  1607. Send_cmd(eSetCharShear);
  1608. }
  1609. //
  1610. // Vertical font simulation
  1611. //
  1612. if ((dwFontSimulation & XLOUTPUT_FONTSIM_VERTICAL) !=
  1613. (dwCurrentFontSim & XLOUTPUT_FONTSIM_VERTICAL))
  1614. {
  1615. if (dwFontSimulation & XLOUTPUT_FONTSIM_VERTICAL)
  1616. {
  1617. Send_ubyte(eVertical);
  1618. }
  1619. else
  1620. {
  1621. Send_ubyte(eHorizontal);
  1622. }
  1623. Send_attr_ubyte(eWritingMode);
  1624. Send_cmd(eSetCharAttributes);
  1625. }
  1626. }
  1627. else
  1628. {
  1629. if (kFontTypeTTBitmap != pGState->GetFontType())
  1630. {
  1631. //
  1632. // Bitmap font can't be scaled x and y. Need to set 1 : 1.
  1633. //
  1634. Send_real32_xy((real32)real32_IEEE_1_0F, (real32)real32_IEEE_1_0F);
  1635. Send_attr_ubyte(eCharScale);
  1636. Send_cmd(eSetCharScale);
  1637. }
  1638. }
  1639. //
  1640. // Change GState to set current selected font.
  1641. //
  1642. pGState->SetFont(fonttype,
  1643. pFontName,
  1644. dwFontHeight,
  1645. dwFontWidth,
  1646. dwSymbolSet,
  1647. dwFontSimulation);
  1648. return S_OK;
  1649. }
  1650. HRESULT
  1651. XLOutput::
  1652. SetSourceTxMode(
  1653. TxMode SrcTxMode)
  1654. /*++
  1655. Routine Description:
  1656. Arguments:
  1657. Return Value:
  1658. Note:
  1659. --*/
  1660. {
  1661. XLGState *pGState = this;
  1662. if (SrcTxMode == pGState->GetSourceTxMode())
  1663. {
  1664. return S_OK;
  1665. }
  1666. if (S_OK == SetTxMode(SrcTxMode) &&
  1667. S_OK == Send_cmd(eSetSourceTxMode))
  1668. {
  1669. pGState->SetSourceTxMode(SrcTxMode);
  1670. return S_OK;
  1671. }
  1672. else
  1673. {
  1674. return S_FALSE;
  1675. }
  1676. }
  1677. HRESULT
  1678. XLOutput::
  1679. SetPaintTxMode(
  1680. TxMode PaintTxMode)
  1681. /*++
  1682. Routine Description:
  1683. Arguments:
  1684. Return Value:
  1685. Note:
  1686. --*/
  1687. {
  1688. XLGState *pGState = this;
  1689. if (PaintTxMode == pGState->GetPaintTxMode())
  1690. {
  1691. return S_OK;
  1692. }
  1693. if (S_OK == SetTxMode(PaintTxMode) &&
  1694. S_OK == Send_cmd(eSetPatternTxMode))
  1695. {
  1696. pGState->SetPaintTxMode(PaintTxMode);
  1697. return S_OK;
  1698. }
  1699. else
  1700. {
  1701. return S_FALSE;
  1702. }
  1703. }