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.

5150 lines
146 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: output.c *
  3. * *
  4. * Client side stubs for graphics output calls. *
  5. * *
  6. * Created: 05-Jun-1991 01:41:18 *
  7. * Author: Charles Whitmer [chuckwh] *
  8. * *
  9. * Copyright (c) 1991-1999 Microsoft Corporation *
  10. \**************************************************************************/
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. // 2 seconds is way way too long for either non-preemptive wow apps or
  14. // an input-synchronized journal situation (like w/mstest). 1/20 a second
  15. // is much better - scottlu
  16. //#define CALLBACK_INTERVAL 2000
  17. // Even better - 1/4 a second
  18. // scottlu
  19. #define CALLBACK_INTERVAL 250
  20. extern BOOL MF_WriteEscape(HDC hdc, int nEscape, int nCount, LPCSTR lpInData, int type );
  21. //
  22. // WINBUG #82877 2-7-2000 bhouse Need to move definition of ETO_NULL_PRCL
  23. //
  24. #define ETO_NULL_PRCL 0x80000000
  25. ULONG GdiBatchLimit = 20;
  26. const XFORM xformIdentity = { 1.00000000f, 0.00000000f, 0.00000000f, 1.00000000f,
  27. 0.00000000f, 0.00000000f };
  28. /******************************Public*Routine******************************\
  29. * AngleArc *
  30. * *
  31. * Client side stub. Copies all LDC attributes into the message. *
  32. * *
  33. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  34. * Wrote it. *
  35. \**************************************************************************/
  36. BOOL META WINAPI AngleArc(
  37. HDC hdc,
  38. int x,
  39. int y,
  40. DWORD r,
  41. FLOAT eA,
  42. FLOAT eB
  43. )
  44. {
  45. BOOL bRet = FALSE;
  46. FIXUP_HANDLE(hdc);
  47. if (IS_ALTDC_TYPE(hdc))
  48. {
  49. PLDC pldc;
  50. if (IS_METADC16_TYPE(hdc))
  51. return(bRet);
  52. DC_PLDC(hdc,pldc,bRet);
  53. if ((pldc->iType == LO_METADC) &&
  54. !MF_AngleArc(hdc,x,y,r,eA,eB)
  55. )
  56. return(bRet);
  57. if (pldc->fl & LDC_SAP_CALLBACK)
  58. vSAPCallback(pldc);
  59. if (pldc->fl & LDC_DOC_CANCELLED)
  60. return(bRet);
  61. if (pldc->fl & LDC_CALL_STARTPAGE)
  62. StartPage(hdc);
  63. }
  64. RESETUSERPOLLCOUNT();
  65. return(NtGdiAngleArc(hdc,x,y,r,FLOATARG(eA),FLOATARG(eB)));
  66. }
  67. /******************************Public*Routine******************************\
  68. * Arc *
  69. * *
  70. * Client side stub. Copies all LDC attributes into the message. *
  71. * *
  72. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  73. * Wrote it. *
  74. \**************************************************************************/
  75. BOOL META WINAPI Arc
  76. (
  77. HDC hdc,
  78. int x1,
  79. int y1,
  80. int x2,
  81. int y2,
  82. int x3,
  83. int y3,
  84. int x4,
  85. int y4
  86. )
  87. {
  88. BOOL bRet = FALSE;
  89. FIXUP_HANDLE(hdc);
  90. if (IS_ALTDC_TYPE(hdc))
  91. {
  92. PLDC pldc;
  93. if (IS_METADC16_TYPE(hdc))
  94. return (MF16_RecordParms9(hdc,x1,y1,x2,y2,x3,y3,x4,y4,META_ARC));
  95. DC_PLDC(hdc,pldc,bRet);
  96. if (pldc->iType == LO_METADC)
  97. {
  98. if (!MF_ArcChordPie(hdc,x1,y1,x2,y2,x3,y3,x4,y4,EMR_ARC))
  99. return(bRet);
  100. }
  101. if (pldc->fl & LDC_SAP_CALLBACK)
  102. vSAPCallback(pldc);
  103. if (pldc->fl & LDC_DOC_CANCELLED)
  104. return(bRet);
  105. if (pldc->fl & LDC_CALL_STARTPAGE)
  106. StartPage(hdc);
  107. }
  108. RESETUSERPOLLCOUNT();
  109. return(NtGdiArcInternal(ARCTYPE_ARC,hdc,x1,y1,x2,y2,x3,y3,x4,y4));
  110. }
  111. /******************************Public*Routine******************************\
  112. * ArcTo *
  113. * *
  114. * Client side stub. Copies all LDC attributes into the message. *
  115. * *
  116. * 12-Sep-1991 -by- J. Andrew Goossen [andrewgo] *
  117. * Wrote it. Cloned it from Arc. *
  118. \**************************************************************************/
  119. BOOL META WINAPI ArcTo(
  120. HDC hdc,
  121. int x1,
  122. int y1,
  123. int x2,
  124. int y2,
  125. int x3,
  126. int y3,
  127. int x4,
  128. int y4
  129. )
  130. {
  131. BOOL bRet = FALSE;
  132. FIXUP_HANDLE(hdc);
  133. if (IS_ALTDC_TYPE(hdc))
  134. {
  135. PLDC pldc;
  136. if (IS_METADC16_TYPE(hdc))
  137. return(bRet);
  138. DC_PLDC(hdc,pldc,bRet);
  139. if ((pldc->iType == LO_METADC) &&
  140. !MF_ArcChordPie(hdc,x1,y1,x2,y2,x3,y3,x4,y4,EMR_ARCTO))
  141. {
  142. return(bRet);
  143. }
  144. if (pldc->fl & LDC_SAP_CALLBACK)
  145. vSAPCallback(pldc);
  146. if (pldc->fl & LDC_DOC_CANCELLED)
  147. return(bRet);
  148. if (pldc->fl & LDC_CALL_STARTPAGE)
  149. StartPage(hdc);
  150. }
  151. RESETUSERPOLLCOUNT();
  152. return(NtGdiArcInternal(ARCTYPE_ARCTO,hdc,x1,y1,x2,y2,x3,y3,x4,y4));
  153. }
  154. /******************************Public*Routine******************************\
  155. * LineTo *
  156. * *
  157. * Client side stub. Copies all LDC attributes into the message. *
  158. * *
  159. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  160. * Wrote it. *
  161. \**************************************************************************/
  162. BOOL META WINAPI LineTo(HDC hdc,int x,int y)
  163. {
  164. BOOL bRet = FALSE;
  165. FIXUP_HANDLE(hdc);
  166. if (IS_ALTDC_TYPE(hdc))
  167. {
  168. PLDC pldc;
  169. if (IS_METADC16_TYPE(hdc))
  170. return (MF16_RecordParms3(hdc,x,y,META_LINETO));
  171. DC_PLDC(hdc,pldc,bRet);
  172. if (pldc->iType == LO_METADC)
  173. {
  174. if (!MF_SetDD(hdc,(DWORD)x,(DWORD)y,EMR_LINETO))
  175. return(bRet);
  176. }
  177. if (pldc->fl & LDC_SAP_CALLBACK)
  178. vSAPCallback(pldc);
  179. if (pldc->fl & LDC_DOC_CANCELLED)
  180. return(bRet);
  181. if (pldc->fl & LDC_CALL_STARTPAGE)
  182. StartPage(hdc);
  183. }
  184. RESETUSERPOLLCOUNT();
  185. return(NtGdiLineTo(hdc,x,y));
  186. }
  187. /******************************Public*Routine******************************\
  188. * Chord *
  189. * *
  190. * Client side stub. Copies all LDC attributes into the message. *
  191. * *
  192. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  193. * Wrote it. *
  194. \**************************************************************************/
  195. BOOL META WINAPI Chord(
  196. HDC hdc,
  197. int x1,
  198. int y1,
  199. int x2,
  200. int y2,
  201. int x3,
  202. int y3,
  203. int x4,
  204. int y4
  205. )
  206. {
  207. BOOL bRet = FALSE;
  208. FIXUP_HANDLE(hdc);
  209. if (IS_ALTDC_TYPE(hdc))
  210. {
  211. PLDC pldc;
  212. if (IS_METADC16_TYPE(hdc))
  213. return (MF16_RecordParms9(hdc,x1,y1,x2,y2,x3,y3,x4,y4,META_CHORD));
  214. DC_PLDC(hdc,pldc,bRet);
  215. if (pldc->iType == LO_METADC)
  216. {
  217. if (!MF_ArcChordPie(hdc,x1,y1,x2,y2,x3,y3,x4,y4,EMR_CHORD))
  218. return(bRet);
  219. }
  220. if (pldc->fl & LDC_SAP_CALLBACK)
  221. vSAPCallback(pldc);
  222. if (pldc->fl & LDC_DOC_CANCELLED)
  223. return(bRet);
  224. if (pldc->fl & LDC_CALL_STARTPAGE)
  225. StartPage(hdc);
  226. }
  227. RESETUSERPOLLCOUNT();
  228. return(NtGdiArcInternal(ARCTYPE_CHORD,hdc,x1,y1,x2,y2,x3,y3,x4,y4));
  229. }
  230. /******************************Public*Routine******************************\
  231. * Ellipse *
  232. * *
  233. * Client side stub. Copies all LDC attributes into the message. *
  234. * *
  235. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  236. * Wrote it. *
  237. \**************************************************************************/
  238. BOOL META WINAPI Ellipse(HDC hdc,int x1,int y1,int x2,int y2)
  239. {
  240. BOOL bRet = FALSE;
  241. FIXUP_HANDLE(hdc);
  242. if (IS_ALTDC_TYPE(hdc))
  243. {
  244. PLDC pldc;
  245. if (IS_METADC16_TYPE(hdc))
  246. return (MF16_RecordParms5(hdc,x1,y1,x2,y2,META_ELLIPSE));
  247. DC_PLDC(hdc,pldc,bRet);
  248. if (pldc->iType == LO_METADC)
  249. {
  250. if (!MF_EllipseRect(hdc,x1,y1,x2,y2,EMR_ELLIPSE))
  251. return(bRet);
  252. }
  253. if (pldc->fl & LDC_SAP_CALLBACK)
  254. vSAPCallback(pldc);
  255. if (pldc->fl & LDC_DOC_CANCELLED)
  256. return(bRet);
  257. if (pldc->fl & LDC_CALL_STARTPAGE)
  258. StartPage(hdc);
  259. }
  260. RESETUSERPOLLCOUNT();
  261. return(NtGdiEllipse(hdc,x1,y1,x2,y2));
  262. }
  263. /******************************Public*Routine******************************\
  264. * Pie *
  265. * *
  266. * Client side stub. Copies all LDC attributes into the message. *
  267. * *
  268. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  269. * Wrote it. *
  270. \**************************************************************************/
  271. BOOL META WINAPI Pie(
  272. HDC hdc,
  273. int x1,
  274. int y1,
  275. int x2,
  276. int y2,
  277. int x3,
  278. int y3,
  279. int x4,
  280. int y4
  281. )
  282. {
  283. BOOL bRet = FALSE;
  284. FIXUP_HANDLE(hdc);
  285. if (IS_ALTDC_TYPE(hdc))
  286. {
  287. PLDC pldc;
  288. if (IS_METADC16_TYPE(hdc))
  289. return (MF16_RecordParms9(hdc,x1,y1,x2,y2,x3,y3,x4,y4,META_PIE));
  290. DC_PLDC(hdc,pldc,bRet);
  291. if (pldc->iType == LO_METADC)
  292. {
  293. if (!MF_ArcChordPie(hdc,x1,y1,x2,y2,x3,y3,x4,y4,EMR_PIE))
  294. return(bRet);
  295. }
  296. if (pldc->fl & LDC_SAP_CALLBACK)
  297. vSAPCallback(pldc);
  298. if (pldc->fl & LDC_DOC_CANCELLED)
  299. return(bRet);
  300. if (pldc->fl & LDC_CALL_STARTPAGE)
  301. StartPage(hdc);
  302. }
  303. RESETUSERPOLLCOUNT();
  304. return(NtGdiArcInternal(ARCTYPE_PIE,hdc,x1,y1,x2,y2,x3,y3,x4,y4));
  305. }
  306. /******************************Public*Routine******************************\
  307. * Rectangle *
  308. * *
  309. * Client side stub. Copies all LDC attributes into the message. *
  310. * *
  311. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  312. * Wrote it. *
  313. \**************************************************************************/
  314. BOOL META WINAPI Rectangle(HDC hdc,int x1,int y1,int x2,int y2)
  315. {
  316. BOOL bRet = FALSE;
  317. FIXUP_HANDLE(hdc);
  318. if (IS_ALTDC_TYPE(hdc))
  319. {
  320. PLDC pldc;
  321. if (IS_METADC16_TYPE(hdc))
  322. return (MF16_RecordParms5(hdc,x1,y1,x2,y2,META_RECTANGLE));
  323. DC_PLDC(hdc,pldc,bRet);
  324. if (pldc->iType == LO_METADC)
  325. {
  326. if (!MF_EllipseRect(hdc,x1,y1,x2,y2,EMR_RECTANGLE))
  327. return(bRet);
  328. }
  329. if (pldc->fl & LDC_SAP_CALLBACK)
  330. vSAPCallback(pldc);
  331. if (pldc->fl & LDC_DOC_CANCELLED)
  332. return(bRet);
  333. if (pldc->fl & LDC_CALL_STARTPAGE)
  334. StartPage(hdc);
  335. }
  336. RESETUSERPOLLCOUNT();
  337. return(NtGdiRectangle(hdc,x1,y1,x2,y2));
  338. }
  339. /******************************Public*Routine******************************\
  340. * RoundRect *
  341. * *
  342. * Client side stub. Copies all LDC attributes into the message. *
  343. * *
  344. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  345. * Wrote it. *
  346. \**************************************************************************/
  347. BOOL META WINAPI RoundRect(
  348. HDC hdc,
  349. int x1,
  350. int y1,
  351. int x2,
  352. int y2,
  353. int x3,
  354. int y3
  355. )
  356. {
  357. BOOL bRet = FALSE;
  358. FIXUP_HANDLE(hdc);
  359. if (IS_ALTDC_TYPE(hdc))
  360. {
  361. PLDC pldc;
  362. if (IS_METADC16_TYPE(hdc))
  363. return (MF16_RecordParms7(hdc,x1,y1,x2,y2,x3,y3,META_ROUNDRECT));
  364. DC_PLDC(hdc,pldc,bRet);
  365. if (pldc->iType == LO_METADC)
  366. {
  367. if (!MF_RoundRect(hdc,x1,y1,x2,y2,x3,y3))
  368. return(bRet);
  369. }
  370. if (pldc->fl & LDC_SAP_CALLBACK)
  371. vSAPCallback(pldc);
  372. if (pldc->fl & LDC_DOC_CANCELLED)
  373. return(bRet);
  374. if (pldc->fl & LDC_CALL_STARTPAGE)
  375. StartPage(hdc);
  376. }
  377. RESETUSERPOLLCOUNT();
  378. return(NtGdiRoundRect(hdc,x1,y1,x2,y2,x3,y3));
  379. }
  380. /******************************Public*Routine******************************\
  381. * PatBlt *
  382. * *
  383. * Client side stub. Copies all LDC attributes into the message. *
  384. * *
  385. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  386. * Wrote it. *
  387. \**************************************************************************/
  388. BOOL META WINAPI PatBlt(
  389. HDC hdc,
  390. int x,
  391. int y,
  392. int cx,
  393. int cy,
  394. DWORD rop
  395. )
  396. {
  397. BOOL bRet = FALSE;
  398. PDC_ATTR pdca;
  399. FIXUP_HANDLE(hdc);
  400. if (IS_ALTDC_TYPE(hdc))
  401. {
  402. PLDC pldc;
  403. if (IS_METADC16_TYPE(hdc))
  404. return(MF16_RecordParmsWWWWD(hdc,(WORD)x,(WORD)y,(WORD)cx,(WORD)cy,rop,META_PATBLT));
  405. DC_PLDC(hdc,pldc,bRet);
  406. if (pldc->iType == LO_METADC)
  407. {
  408. if (!MF_AnyBitBlt(hdc,x,y,cx,cy,(LPPOINT)NULL,(HDC)NULL,0,0,0,0,(HBITMAP)NULL,0,0,rop,EMR_BITBLT))
  409. return(bRet);
  410. }
  411. if (pldc->fl & LDC_SAP_CALLBACK)
  412. vSAPCallback(pldc);
  413. if (pldc->fl & LDC_DOC_CANCELLED)
  414. return(bRet);
  415. if (pldc->fl & LDC_CALL_STARTPAGE)
  416. StartPage(hdc);
  417. }
  418. RESETUSERPOLLCOUNT();
  419. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  420. BEGIN_BATCH_HDC(hdc,pdca,BatchTypePatBlt,BATCHPATBLT);
  421. //
  422. // check DC to see if call can be batched, all DCs in use
  423. // by the client must have a valid dc_attr
  424. //
  425. pBatch->rop4 = rop;
  426. pBatch->x = x;
  427. pBatch->y = y;
  428. pBatch->cx = cx;
  429. pBatch->cy = cy;
  430. pBatch->hbr = pdca->hbrush;
  431. pBatch->TextColor = (ULONG)pdca->crForegroundClr;
  432. pBatch->BackColor = (ULONG)pdca->crBackgroundClr;
  433. pBatch->DCBrushColor = (ULONG)pdca->crDCBrushClr;
  434. pBatch->IcmBrushColor = (ULONG)pdca->IcmBrushColor;
  435. pBatch->ptlViewportOrg = pdca->ptlViewportOrg;
  436. pBatch->ulTextColor = pdca->ulForegroundClr;
  437. pBatch->ulBackColor = pdca->ulBackgroundClr;
  438. pBatch->ulDCBrushColor = pdca->ulDCBrushClr;
  439. COMPLETE_BATCH_COMMAND();
  440. return(TRUE);
  441. UNBATCHED_COMMAND:
  442. return(NtGdiPatBlt(hdc,x,y,cx,cy,rop));
  443. }
  444. /******************************Public*Routine******************************\
  445. * PolyPatBlt
  446. *
  447. * Arguments:
  448. *
  449. * hdc - dest DC
  450. * rop - ROP for all patblt elements
  451. * pPoly - pointer to array of PPOLYPATBLT structures
  452. * Count - number of polypatblts
  453. * Mode - mode for all polypatblts
  454. *
  455. * Return Value:
  456. *
  457. * BOOL Status
  458. *
  459. \**************************************************************************/
  460. BOOL
  461. META WINAPI
  462. PolyPatBlt(
  463. HDC hdc,
  464. DWORD rop,
  465. PPOLYPATBLT pPoly,
  466. DWORD Count,
  467. DWORD Mode
  468. )
  469. {
  470. BOOL bRet = FALSE;
  471. PDC_ATTR pdca;
  472. FIXUP_HANDLE(hdc);
  473. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  474. // If ICM is enabled, we need to select the brush onto the DC in
  475. // client side, so that ICM can translate brush color to DC color
  476. // space. thus we can not use Batch, here. because Batch will selet
  477. // the brush onto the DC in kernel side. so, there is no chance to
  478. // ICM will be invoked.
  479. if (IS_ALTDC_TYPE(hdc) || (pdca && IS_ICM_INSIDEDC(pdca->lIcmMode)))
  480. {
  481. ULONG Index;
  482. HBRUSH hOld = 0;
  483. for (Index=0;Index<Count;Index++)
  484. {
  485. //
  486. // select brush, save first to restore
  487. //
  488. if (Index == 0)
  489. {
  490. hOld = SelectObject(hdc,(HBRUSH)pPoly[0].BrClr.hbr);
  491. }
  492. else
  493. {
  494. SelectObject(hdc,(HBRUSH)pPoly[Index].BrClr.hbr);
  495. }
  496. bRet = PatBlt(hdc,
  497. pPoly[Index].x,
  498. pPoly[Index].y,
  499. pPoly[Index].cx,
  500. pPoly[Index].cy,
  501. rop
  502. );
  503. }
  504. //
  505. // restore brush if needed
  506. //
  507. if (hOld)
  508. {
  509. SelectObject(hdc,hOld);
  510. }
  511. }
  512. else
  513. {
  514. RESETUSERPOLLCOUNT();
  515. if ((Count != 0) && (pPoly != NULL) && (Mode == PPB_BRUSH))
  516. {
  517. USHORT uSize;
  518. if (Count > (MAXUSHORT / sizeof(POLYPATBLT)))
  519. goto UNBATCHED_COMMAND;
  520. //
  521. // size of batched structure
  522. //
  523. uSize = (USHORT)(Count * sizeof(POLYPATBLT));
  524. uSize += (USHORT)sizeof(BATCHPOLYPATBLT);
  525. if (uSize < (USHORT)sizeof(BATCHPOLYPATBLT))
  526. goto UNBATCHED_COMMAND;
  527. BEGIN_BATCH_HDC_SIZE(hdc,pdca,BatchTypePolyPatBlt,BATCHPOLYPATBLT,uSize);
  528. pBatch->rop4 = rop;
  529. pBatch->Count = Count;
  530. pBatch->Mode = Mode;
  531. pBatch->TextColor = (ULONG)pdca->crForegroundClr;
  532. pBatch->BackColor = (ULONG)pdca->crBackgroundClr;
  533. pBatch->DCBrushColor = (ULONG)pdca->crDCBrushClr;
  534. pBatch->ptlViewportOrg = pdca->ptlViewportOrg;
  535. pBatch->ulTextColor = pdca->ulForegroundClr;
  536. pBatch->ulBackColor = pdca->ulBackgroundClr;
  537. pBatch->ulDCBrushColor = pdca->ulDCBrushClr;
  538. memcpy(&pBatch->ulBuffer[0],pPoly,Count*sizeof(POLYPATBLT));
  539. //
  540. // if the first hbr entry is NULL, copy in current hbr so
  541. // it is remembered.
  542. //
  543. if (((PPOLYPATBLT)(&pBatch->ulBuffer[0]))->BrClr.hbr == NULL)
  544. {
  545. ((PPOLYPATBLT)(&pBatch->ulBuffer[0]))->BrClr.hbr = pdca->hbrush;
  546. }
  547. bRet = TRUE;
  548. COMPLETE_BATCH_COMMAND();
  549. UNBATCHED_COMMAND:
  550. if (!bRet)
  551. {
  552. bRet = NtGdiPolyPatBlt(hdc,rop,pPoly,Count,Mode);
  553. }
  554. }
  555. }
  556. return(bRet);
  557. }
  558. /******************************Public*Routine******************************\
  559. * BitBlt *
  560. * *
  561. * Client side stub. Copies all LDC attributes into the message. *
  562. * *
  563. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  564. * Wrote it. *
  565. \**************************************************************************/
  566. BOOL META WINAPI BitBlt(
  567. HDC hdc,
  568. int x,
  569. int y,
  570. int cx,
  571. int cy,
  572. HDC hdcSrc,
  573. int x1,
  574. int y1,
  575. DWORD rop
  576. )
  577. {
  578. BOOL bRet = FALSE;
  579. //
  580. // if this call redueces to PatBlt, then let PatBlt
  581. // do the metafile and/or output.
  582. //
  583. if ((((rop << 2) ^ rop) & 0x00CC0000) == 0)
  584. {
  585. return(PatBlt(hdc,x,y,cx,cy,rop));
  586. }
  587. //
  588. // Src is required by ROP, do bitblt
  589. //
  590. FIXUP_HANDLE(hdc);
  591. FIXUP_HANDLE(hdcSrc);
  592. if (gbICMEnabledOnceBefore)
  593. {
  594. PDC_ATTR pdcattr, pdcattrSrc;
  595. PSHARED_GET_VALIDATE(pdcattr,hdc,DC_TYPE);
  596. PSHARED_GET_VALIDATE(pdcattrSrc,hdcSrc,DC_TYPE);
  597. //
  598. // if source DC has DIB section, and destination DC is ICM turned on
  599. // do ICM-aware BitBlt.
  600. //
  601. if (pdcattr && pdcattrSrc)
  602. {
  603. if (IS_ICM_INSIDEDC(pdcattr->lIcmMode) &&
  604. (bDIBSectionSelected(pdcattrSrc) ||
  605. (IS_ICM_LAZY_CORRECTION(pdcattrSrc->lIcmMode) && (GetDCDWord(hdc,DDW_ISMEMDC,FALSE) == FALSE))))
  606. {
  607. if (IcmStretchBlt(hdc,x,y,cx,cy,hdcSrc,x1,y1,cx,cy,rop,pdcattr,pdcattrSrc))
  608. {
  609. return (TRUE);
  610. }
  611. }
  612. }
  613. }
  614. if (IS_ALTDC_TYPE(hdc))
  615. {
  616. PLDC pldc;
  617. if (IS_METADC16_TYPE(hdc))
  618. return (MF16_BitBlt(hdc,x,y,cx,cy,hdcSrc,x1,y1,rop));
  619. DC_PLDC(hdc,pldc,bRet);
  620. if (pldc->iType == LO_METADC)
  621. {
  622. if (!MF_AnyBitBlt(hdc,x,y,cx,cy,(LPPOINT)NULL,hdcSrc,x1,y1,cx,cy,(HBITMAP)NULL,0,0,rop,EMR_BITBLT))
  623. return(bRet);
  624. }
  625. if (pldc->fl & LDC_SAP_CALLBACK)
  626. vSAPCallback(pldc);
  627. if (pldc->fl & LDC_DOC_CANCELLED)
  628. return(bRet);
  629. if (pldc->fl & LDC_CALL_STARTPAGE)
  630. StartPage(hdc);
  631. }
  632. RESETUSERPOLLCOUNT();
  633. //
  634. // Define _WINDOWBLT_NOTIFICATION_ to turn on Window BLT notification.
  635. // This notification will set a special flag in the SURFOBJ passed to
  636. // drivers when the DrvCopyBits operation is called to move a window.
  637. //
  638. // See also:
  639. // ntgdi\gre\maskblt.cxx
  640. //
  641. #ifdef _WINDOWBLT_NOTIFICATION_
  642. return(NtGdiBitBlt(hdc,x,y,cx,cy,hdcSrc,x1,y1,rop,(COLORREF)-1,0));
  643. #else
  644. return(NtGdiBitBlt(hdc,x,y,cx,cy,hdcSrc,x1,y1,rop,(COLORREF)-1));
  645. #endif
  646. }
  647. /******************************Public*Routine******************************\
  648. * StretchBlt *
  649. * *
  650. * Client side stub. Copies all LDC attributes into the message. *
  651. * *
  652. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  653. * Wrote it. *
  654. \**************************************************************************/
  655. BOOL META WINAPI StretchBlt(
  656. HDC hdc,
  657. int x,
  658. int y,
  659. int cx,
  660. int cy,
  661. HDC hdcSrc,
  662. int x1,
  663. int y1,
  664. int cx1,
  665. int cy1,
  666. DWORD rop
  667. )
  668. {
  669. BOOL bRet = FALSE;
  670. FIXUP_HANDLE(hdc);
  671. FIXUP_HANDLEZ(hdcSrc);
  672. if (gbICMEnabledOnceBefore)
  673. {
  674. PDC_ATTR pdcattr, pdcattrSrc;
  675. PSHARED_GET_VALIDATE(pdcattr,hdc,DC_TYPE);
  676. PSHARED_GET_VALIDATE(pdcattrSrc,hdcSrc,DC_TYPE);
  677. //
  678. // if source DC has DIB section, and destination DC is ICM turned on
  679. // do ICM-aware BitBlt.
  680. //
  681. if (pdcattr && pdcattrSrc)
  682. {
  683. if (IS_ICM_INSIDEDC(pdcattr->lIcmMode) &&
  684. (bDIBSectionSelected(pdcattrSrc) ||
  685. (IS_ICM_LAZY_CORRECTION(pdcattrSrc->lIcmMode) && (GetDCDWord(hdc,DDW_ISMEMDC,FALSE) == FALSE))))
  686. {
  687. if (IcmStretchBlt(hdc,x,y,cx,cy,hdcSrc,x1,y1,cx1,cy1,rop,pdcattr,pdcattrSrc))
  688. {
  689. return (TRUE);
  690. }
  691. }
  692. }
  693. }
  694. if (IS_ALTDC_TYPE(hdc))
  695. {
  696. PLDC pldc;
  697. if (IS_METADC16_TYPE(hdc))
  698. return (MF16_StretchBlt(hdc,x,y,cx,cy,hdcSrc,x1,y1,cx1,cy1,rop));
  699. DC_PLDC(hdc,pldc,bRet);
  700. if (pldc->iType == LO_METADC)
  701. {
  702. if (!MF_AnyBitBlt(hdc,x,y,cx,cy,(LPPOINT)NULL,hdcSrc,x1,y1,cx1,cy1,(HBITMAP)NULL,0,0,rop,EMR_STRETCHBLT))
  703. return(bRet);
  704. }
  705. if (pldc->fl & LDC_SAP_CALLBACK)
  706. vSAPCallback(pldc);
  707. if (pldc->fl & LDC_DOC_CANCELLED)
  708. return(bRet);
  709. if (pldc->fl & LDC_CALL_STARTPAGE)
  710. StartPage(hdc);
  711. }
  712. RESETUSERPOLLCOUNT();
  713. return(NtGdiStretchBlt(hdc,x,y,cx,cy,hdcSrc,x1,y1,cx1,cy1,rop,(COLORREF)-1));
  714. }
  715. /******************************Public*Routine******************************\
  716. * PlgBlt *
  717. * *
  718. * Client side stub. Copies all LDC attributes into the message. *
  719. * *
  720. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  721. * Wrote it. *
  722. \**************************************************************************/
  723. BOOL META WINAPI PlgBlt(
  724. HDC hdc,
  725. CONST POINT *pptl,
  726. HDC hdcSrc,
  727. int x1,
  728. int y1,
  729. int x2,
  730. int y2,
  731. HBITMAP hbm,
  732. int xMask,
  733. int yMask
  734. )
  735. {
  736. BOOL bRet = FALSE;
  737. FIXUP_HANDLE(hdc);
  738. FIXUP_HANDLEZ(hdcSrc);
  739. FIXUP_HANDLEZ(hbm);
  740. // Check out the source DC and the mask(OPTIONAL).
  741. if (!hdcSrc || IS_METADC16_TYPE(hdcSrc))
  742. return(FALSE);
  743. if (IS_ALTDC_TYPE(hdc))
  744. {
  745. PLDC pldc;
  746. if (IS_METADC16_TYPE(hdc))
  747. return(FALSE);
  748. DC_PLDC(hdc,pldc,bRet);
  749. if ((pldc->iType == LO_METADC) &&
  750. !MF_AnyBitBlt(hdc,0,0,0,0,pptl,hdcSrc,x1,y1,x2,y2,hbm,xMask,yMask,0xCCAA0000,EMR_PLGBLT))
  751. {
  752. return(bRet);
  753. }
  754. if (pldc->fl & LDC_SAP_CALLBACK)
  755. vSAPCallback(pldc);
  756. if (pldc->fl & LDC_DOC_CANCELLED)
  757. return(bRet);
  758. if (pldc->fl & LDC_CALL_STARTPAGE)
  759. StartPage(hdc);
  760. }
  761. RESETUSERPOLLCOUNT();
  762. return(NtGdiPlgBlt(hdc,(POINT *)pptl,hdcSrc,x1,y1,x2,y2,hbm,xMask,yMask,
  763. GetBkColor(hdcSrc)));
  764. }
  765. /******************************Public*Routine******************************\
  766. * MaskBlt *
  767. * *
  768. * Client side stub. Copies all LDC attributes into the message. *
  769. * *
  770. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  771. * Wrote it. *
  772. \**************************************************************************/
  773. BOOL META WINAPI MaskBlt(
  774. HDC hdc,
  775. int x,
  776. int y,
  777. int cx,
  778. int cy,
  779. HDC hdcSrc,
  780. int x1,
  781. int y1,
  782. HBITMAP hbm,
  783. int x2,
  784. int y2,
  785. DWORD rop
  786. )
  787. {
  788. BOOL bRet = FALSE;
  789. ULONG crBackColor;
  790. FIXUP_HANDLE(hdc);
  791. FIXUP_HANDLEZ(hdcSrc);
  792. FIXUP_HANDLEZ(hbm);
  793. // Check out the source DC and the mask(OPTIONAL).
  794. if (!hdcSrc || IS_METADC16_TYPE(hdcSrc))
  795. return(FALSE);
  796. if (IS_ALTDC_TYPE(hdc))
  797. {
  798. PLDC pldc;
  799. if (IS_METADC16_TYPE(hdc))
  800. return(FALSE);
  801. DC_PLDC(hdc,pldc,bRet);
  802. if ((pldc->iType == LO_METADC) &&
  803. !MF_AnyBitBlt(hdc,x,y,cx,cy,(LPPOINT)NULL,hdcSrc,x1,y1,cx,cy,hbm,x2,y2,rop,EMR_MASKBLT))
  804. {
  805. return(bRet);
  806. }
  807. if (pldc->fl & LDC_SAP_CALLBACK)
  808. vSAPCallback(pldc);
  809. if (pldc->fl & LDC_DOC_CANCELLED)
  810. return(bRet);
  811. if (pldc->fl & LDC_CALL_STARTPAGE)
  812. StartPage(hdc);
  813. }
  814. crBackColor = GetBkColor(hdcSrc);
  815. RESETUSERPOLLCOUNT();
  816. // WINBUG #82879 2-7-2000 bhouse Possible bug in MaskBlt
  817. // Old Comment:
  818. // - GetBkColor should be performed in the kernel
  819. // Not a problem. GetBkColor() picks up the color from the PEB DCattr cache.
  820. return(NtGdiMaskBlt(hdc,x,y,cx,cy,hdcSrc,x1,y1,hbm,x2,y2,rop,crBackColor));
  821. }
  822. /******************************Public*Routine******************************\
  823. * ExtFloodFill *
  824. * *
  825. * Client side stub. Copies all LDC attributes into the message. *
  826. * *
  827. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  828. * Wrote it. *
  829. \**************************************************************************/
  830. BOOL META WINAPI ExtFloodFill(
  831. HDC hdc,
  832. int x,
  833. int y,
  834. COLORREF color,
  835. UINT iMode
  836. )
  837. {
  838. BOOL bRet = FALSE;
  839. FIXUP_HANDLE(hdc);
  840. if (IS_ALTDC_TYPE(hdc))
  841. {
  842. PLDC pldc;
  843. if (IS_METADC16_TYPE(hdc))
  844. return(MF16_RecordParmsWWDW(hdc,(WORD)x,(WORD)y,(DWORD)color,(WORD)iMode,META_EXTFLOODFILL));
  845. DC_PLDC(hdc,pldc,bRet);
  846. if (pldc->iType == LO_METADC)
  847. {
  848. if (!MF_ExtFloodFill(hdc,x,y,color,iMode))
  849. return(bRet);
  850. }
  851. if (pldc->fl & LDC_SAP_CALLBACK)
  852. vSAPCallback(pldc);
  853. if (pldc->fl & LDC_DOC_CANCELLED)
  854. return(bRet);
  855. if (pldc->fl & LDC_CALL_STARTPAGE)
  856. StartPage(hdc);
  857. }
  858. RESETUSERPOLLCOUNT();
  859. //
  860. // if the specified COLORREF is not palette index,
  861. // we need to do color conversion, when ICM is enabled.
  862. //
  863. if (!(color & 0x01000000))
  864. {
  865. PDC_ATTR pdcattr;
  866. PSHARED_GET_VALIDATE(pdcattr,hdc,DC_TYPE);
  867. if (pdcattr && bNeedTranslateColor(pdcattr))
  868. {
  869. COLORREF NewColor;
  870. if (IcmTranslateCOLORREF(hdc,pdcattr,color,&NewColor,ICM_FORWARD))
  871. {
  872. color = NewColor;
  873. }
  874. }
  875. }
  876. return(NtGdiExtFloodFill(hdc,x,y,color,iMode));
  877. }
  878. /******************************Public*Routine******************************\
  879. * FloodFill *
  880. * *
  881. * Just passes the call to the more general ExtFloodFill. *
  882. * *
  883. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  884. * Wrote it. *
  885. \**************************************************************************/
  886. BOOL WINAPI FloodFill(HDC hdc,int x,int y,COLORREF color)
  887. {
  888. return(ExtFloodFill(hdc,x,y,color,FLOODFILLBORDER));
  889. }
  890. /******************************Public*Routine******************************\
  891. * PaintRgn *
  892. * *
  893. * Client side stub. Copies all LDC attributes into the message. *
  894. * *
  895. * 23-11-94 -by- Lingyun Wang [lingyunw]
  896. * Now hrgn is server side handle
  897. *
  898. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  899. * Wrote it. *
  900. \**************************************************************************/
  901. BOOL META WINAPI PaintRgn(HDC hdc,HRGN hrgn)
  902. {
  903. BOOL bRet = FALSE;
  904. FIXUP_HANDLE(hdc);
  905. FIXUP_HANDLE(hrgn);
  906. if (IS_ALTDC_TYPE(hdc))
  907. {
  908. PLDC pldc;
  909. if (IS_METADC16_TYPE(hdc))
  910. return(MF16_DrawRgn(hdc,hrgn,(HBRUSH)0,0,0,META_PAINTREGION));
  911. DC_PLDC(hdc,pldc,bRet);
  912. if (pldc->iType == LO_METADC)
  913. {
  914. if (!MF_InvertPaintRgn(hdc,hrgn,EMR_PAINTRGN))
  915. return(bRet);
  916. }
  917. if (pldc->fl & LDC_SAP_CALLBACK)
  918. vSAPCallback(pldc);
  919. if (pldc->fl & LDC_DOC_CANCELLED)
  920. return(bRet);
  921. if (pldc->fl & LDC_CALL_STARTPAGE)
  922. StartPage(hdc);
  923. }
  924. RESETUSERPOLLCOUNT();
  925. return(NtGdiFillRgn(hdc,hrgn,(HBRUSH)GetDCObject(hdc,LO_BRUSH_TYPE)));
  926. }
  927. /******************************Public*Routine******************************\
  928. * bBatchTextOut
  929. *
  930. * Attempt to batch a textout call on TEB
  931. *
  932. * Arguments:
  933. *
  934. *
  935. *
  936. * Return Value:
  937. *
  938. * TRUE means call is batched, FALSE means call could not be batched
  939. *
  940. * 18-Oct-1995 -by- Mark Enstrom [marke]
  941. *
  942. \**************************************************************************/
  943. //
  944. // full DWORDS!
  945. //
  946. #define MAX_BATCH_CCHAR ((GDI_BATCH_SIZE - sizeof(BATCHTEXTOUT)) & 0xfffffff0)
  947. #define MAX_BATCH_WCHAR MAX_BATCH_CCHAR / 2
  948. BOOL
  949. bBatchTextOut(
  950. HDC hdc,
  951. LONG x,
  952. LONG y,
  953. UINT fl,
  954. CONST RECT *prcl,
  955. LPCWSTR pwsz,
  956. CONST INT *pdx,
  957. UINT UnicodeCharCount,
  958. UINT ByteCount,
  959. DWORD dwCodePage
  960. )
  961. {
  962. BOOL bRet = FALSE;
  963. ULONG AlignedByteCount;
  964. USHORT usSize;
  965. ULONG cjPdx;
  966. PDC_ATTR pdca;
  967. AlignedByteCount =
  968. (ByteCount + sizeof(PVOID) - 1) & ~(sizeof(PVOID)-1);
  969. if( AlignedByteCount < ByteCount )
  970. goto UNBATCHED_COMMAND; // arithmetic overflow
  971. //
  972. // account for pdx space if needed
  973. //
  974. if (pdx != NULL)
  975. {
  976. cjPdx = UnicodeCharCount * sizeof(INT);
  977. if (fl & ETO_PDY)
  978. cjPdx *= 2;
  979. if ((AlignedByteCount+cjPdx) < AlignedByteCount
  980. || BALLOC_OVERFLOW1(UnicodeCharCount,INT))
  981. goto UNBATCHED_COMMAND; // arithmetic overflow
  982. AlignedByteCount += cjPdx;
  983. }
  984. usSize = (USHORT)(sizeof(BATCHTEXTOUT) + AlignedByteCount);
  985. if (usSize < AlignedByteCount)
  986. goto UNBATCHED_COMMAND; // arithmetic overflow
  987. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  988. BEGIN_BATCH_HDC_SIZE(hdc,pdca,BatchTypeTextOut,BATCHTEXTOUT,usSize);
  989. if (pdca->lTextAlign & TA_UPDATECP)
  990. {
  991. goto UNBATCHED_COMMAND;
  992. }
  993. pBatch->TextColor = (ULONG)pdca->crForegroundClr;
  994. pBatch->BackColor = (ULONG)pdca->crBackgroundClr;
  995. pBatch->BackMode = (ULONG)((pdca->lBkMode == OPAQUE) ? OPAQUE : TRANSPARENT);
  996. pBatch->ulTextColor = pdca->ulForegroundClr;
  997. pBatch->ulBackColor = pdca->ulBackgroundClr;
  998. pBatch->x = x;
  999. pBatch->y = y;
  1000. pBatch->fl = fl;
  1001. pBatch->cChar = UnicodeCharCount;
  1002. pBatch->PdxOffset = 0;
  1003. pBatch->dwCodePage = dwCodePage;
  1004. pBatch->hlfntNew = pdca->hlfntNew;
  1005. pBatch->flTextAlign = pdca->flTextAlign;
  1006. pBatch->ptlViewportOrg = pdca->ptlViewportOrg;
  1007. //
  1008. // copy output RECT if needed
  1009. //
  1010. if (prcl != NULL)
  1011. {
  1012. pBatch->rcl.left = prcl->left;
  1013. pBatch->rcl.top = prcl->top;
  1014. pBatch->rcl.right = prcl->right;
  1015. pBatch->rcl.bottom = prcl->bottom;
  1016. }
  1017. else
  1018. {
  1019. pBatch->fl |= ETO_NULL_PRCL;
  1020. }
  1021. //
  1022. // copy characters
  1023. //
  1024. if (ByteCount)
  1025. {
  1026. RtlCopyMemory((PUCHAR)&pBatch->ulBuffer[0],(PUCHAR)pwsz,ByteCount);
  1027. }
  1028. //
  1029. // copy pdx array
  1030. //
  1031. if (pdx != NULL)
  1032. {
  1033. //
  1034. // start pdx at INT aligned offset after WCAHR data
  1035. //
  1036. pBatch->PdxOffset = (ByteCount + 3) & 0xfffffffc;
  1037. RtlCopyMemory((PUCHAR)&pBatch->ulBuffer[0] + pBatch->PdxOffset,
  1038. (PUCHAR)pdx,
  1039. cjPdx);
  1040. }
  1041. bRet = TRUE;
  1042. COMPLETE_BATCH_COMMAND();
  1043. UNBATCHED_COMMAND:
  1044. return(bRet);
  1045. }
  1046. /******************************Public*Routine******************************\
  1047. *
  1048. * BOOL META WINAPI ExtTextOutW
  1049. *
  1050. * similar to traditional ExtTextOut, except that it takes UNICODE string
  1051. *
  1052. * History:
  1053. * Thu 28-Apr-1994 -by- Patrick Haluptzok [patrickh]
  1054. * Special Case 0 char case for Winbench4.0
  1055. *
  1056. * 05-Aug-1991 -by- Bodin Dresevic [BodinD]
  1057. * Wrote it.
  1058. \**************************************************************************/
  1059. BOOL META WINAPI ExtTextOutW(
  1060. HDC hdc,
  1061. int x,
  1062. int y,
  1063. UINT fl,
  1064. CONST RECT *prcl,
  1065. LPCWSTR pwsz,
  1066. UINT c, // count of bytes = 2 * (# of WCHAR's)
  1067. CONST INT *pdx
  1068. )
  1069. {
  1070. BOOL bRet = FALSE;
  1071. BOOL bEMFDriverComment = FALSE;
  1072. if ((fl & ETO_PDY) && !pdx)
  1073. return FALSE;
  1074. // if we do not know what to do with the rectangle, ignore it.
  1075. if (prcl && !(fl & (ETO_OPAQUE | ETO_CLIPPED)))
  1076. {
  1077. prcl = NULL;
  1078. }
  1079. if (!prcl)
  1080. {
  1081. fl &= ~(ETO_CLIPPED | ETO_OPAQUE); // ignore flags if no rect, win95 compat
  1082. }
  1083. FIXUP_HANDLE(hdc);
  1084. if (IS_ALTDC_TYPE(hdc))
  1085. {
  1086. PLDC pldc;
  1087. if (IS_METADC16_TYPE(hdc))
  1088. return (MF16_ExtTextOut(hdc,x,y,fl,prcl,(LPCSTR)pwsz,c,pdx,TRUE));
  1089. DC_PLDC(hdc,pldc,bRet);
  1090. // if we are EMF spooling then metafile glyph index calls, otherwise don't
  1091. // if we are EMF spooling then metafile glyph index calls, otherwise don't
  1092. /*
  1093. LDC_META_PRINT ETO_GLYPH_INDEX ETO_IGNORELANGUAGE gbLpk MetaFileTheCall
  1094. 0 0 0 0 1
  1095. 0 0 0 1 1
  1096. 0 0 1 0 1
  1097. Case1 0 0 1 1 0
  1098. Case2 0 1 0 0 0
  1099. 0 1 0 1 1 <-Win95 Compatability
  1100. Case2 0 1 1 0 0
  1101. 0 1 1 1 1 <-Win95 Compatability
  1102. 1 0 0 0 1
  1103. Case3 1 0 0 1 0
  1104. 1 0 1 0 1
  1105. 1 0 1 1 1
  1106. 1 1 0 0 1
  1107. 1 1 0 1 1
  1108. 1 1 1 0 1
  1109. 1 1 1 1 1
  1110. */
  1111. // Now we will metafile the glyph index call (i.e. with ETO_GLYPH_INDEX) for ExtTextOutW.
  1112. // This is to support MS OutLook-97/BiDi, since it DEPENDS on this feature!!. Win95/BiDi allowed
  1113. // metafiling of GIs on ETOW, but rejects GIs metafiling calls to ETOA.
  1114. // This is not neat, but we have to do it to support our Apps.
  1115. if (pldc->iType == LO_METADC)
  1116. {
  1117. BOOL bPrintToEMFDriver = pldc->pUMPD ? pldc->pUMPD->dwFlags & UMPDFLAG_METAFILE_DRIVER : FALSE;
  1118. BOOL bLpkEmfCase1 = !(pldc->fl & LDC_META_PRINT) &&
  1119. !(fl & ETO_GLYPH_INDEX) &&
  1120. (fl & ETO_IGNORELANGUAGE) &&
  1121. gbLpk;
  1122. BOOL bLpkEmfCase2 = !(pldc->fl & LDC_META_PRINT) &&
  1123. (fl & ETO_GLYPH_INDEX) &&
  1124. !gbLpk;
  1125. BOOL bLpkEmfCase3 = (pldc->fl & LDC_META_PRINT) &&
  1126. !(fl & ETO_GLYPH_INDEX) &&
  1127. !(fl & ETO_IGNORELANGUAGE) &&
  1128. gbLpk;
  1129. // Record a special comment containing the original
  1130. // Unicode string for the ExtTextOutW call
  1131. if (bLpkEmfCase3 && bPrintToEMFDriver)
  1132. {
  1133. ULONG nSize = 3*sizeof(DWORD) + c*sizeof(WCHAR);
  1134. DWORD *lpData;
  1135. // double check that we didn't have an arithmetic overflow
  1136. // in the calculation of nSize -- if so, lpData can have
  1137. // a buffer overflow
  1138. if( c >= (MAXIMUM_POOL_ALLOC - 3*sizeof(DWORD) - 3)/sizeof(WCHAR))
  1139. {
  1140. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1141. return FALSE;
  1142. }
  1143. lpData = LOCALALLOC(ROUNDUP_DWORDALIGN(nSize));
  1144. if (lpData)
  1145. {
  1146. lpData[0] = GDICOMMENT_IDENTIFIER;
  1147. lpData[1] = GDICOMMENT_UNICODE_STRING;
  1148. lpData[2] = c; // number of wchars in the unicode string
  1149. RtlCopyMemory((PBYTE)(lpData+3), pwsz, c*sizeof(WCHAR));
  1150. if (!MF_GdiComment(hdc,nSize,(PBYTE)lpData))
  1151. {
  1152. LOCALFREE(lpData);
  1153. return bRet;
  1154. }
  1155. LOCALFREE(lpData);
  1156. bEMFDriverComment = TRUE;
  1157. }
  1158. }
  1159. if (!bLpkEmfCase1 && !bLpkEmfCase2 && !bLpkEmfCase3 &&
  1160. !MF_ExtTextOut(hdc,x,y,fl,prcl,(LPCSTR) pwsz,c,pdx,EMR_EXTTEXTOUTW))
  1161. {
  1162. return(bRet);
  1163. }
  1164. }
  1165. if (pldc->fl & LDC_SAP_CALLBACK)
  1166. vSAPCallback(pldc);
  1167. if (pldc->fl & LDC_DOC_CANCELLED)
  1168. return(bRet);
  1169. if (pldc->fl & LDC_CALL_STARTPAGE)
  1170. StartPage(hdc);
  1171. }
  1172. RESETUSERPOLLCOUNT();
  1173. #ifdef LANGPACK
  1174. if(gbLpk && !(fl & ETO_GLYPH_INDEX) && !(fl & ETO_IGNORELANGUAGE))
  1175. {
  1176. bRet = ((*fpLpkExtTextOut)(hdc, x, y, fl, prcl, pwsz, c, pdx, -1));
  1177. if (bEMFDriverComment)
  1178. {
  1179. DWORD lpData[2];
  1180. lpData[0] = GDICOMMENT_IDENTIFIER;
  1181. lpData[1] = GDICOMMENT_UNICODE_END;
  1182. bRet = MF_GdiComment(hdc,2*sizeof(DWORD),(PBYTE)lpData);
  1183. ASSERTGDI(bRet, "failed to write the GDICOMMENT_UNICODE_END comment\n");
  1184. }
  1185. return(bRet);
  1186. }
  1187. #endif
  1188. bRet = FALSE;
  1189. if (c <= MAX_BATCH_WCHAR)
  1190. {
  1191. if ((c == 0) && (prcl != NULL))
  1192. {
  1193. if (fl & ETO_OPAQUE)
  1194. {
  1195. //
  1196. // attempt to batch the text out rect
  1197. //
  1198. PDC_ATTR pdca;
  1199. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  1200. if ((pdca != NULL) && !(pdca->lTextAlign & TA_UPDATECP))
  1201. {
  1202. BEGIN_BATCH_HDC(hdc,pdca,BatchTypeTextOutRect,BATCHTEXTOUTRECT);
  1203. pBatch->BackColor = pdca->crBackgroundClr;
  1204. pBatch->fl = fl;
  1205. pBatch->rcl.left = prcl->left;
  1206. pBatch->rcl.top = prcl->top;
  1207. pBatch->rcl.right = prcl->right;
  1208. pBatch->rcl.bottom = prcl->bottom;
  1209. pBatch->ptlViewportOrg = pdca->ptlViewportOrg;
  1210. pBatch->ulBackColor = pdca->ulBackgroundClr;
  1211. bRet = TRUE;
  1212. COMPLETE_BATCH_COMMAND();
  1213. }
  1214. }
  1215. else
  1216. {
  1217. bRet = TRUE;
  1218. }
  1219. }
  1220. else
  1221. {
  1222. bRet = bBatchTextOut(hdc,
  1223. x,
  1224. y,
  1225. fl,
  1226. (LPRECT)prcl,
  1227. (LPWSTR)pwsz,
  1228. pdx,
  1229. c,
  1230. 2 * c,
  1231. 0);
  1232. }
  1233. }
  1234. UNBATCHED_COMMAND:
  1235. if (!bRet)
  1236. {
  1237. bRet = NtGdiExtTextOutW(hdc,
  1238. x,
  1239. y,
  1240. fl,
  1241. (LPRECT)prcl,
  1242. (LPWSTR)pwsz,
  1243. c,
  1244. (LPINT)pdx,
  1245. 0);
  1246. }
  1247. return(bRet);
  1248. }
  1249. /******************************Public*Routine******************************\
  1250. * PolyTextOutW
  1251. *
  1252. * Arguments:
  1253. *
  1254. * hdc - handle to device context
  1255. * ppt - pointer to array of POLYTEXTW
  1256. * nstrings - length of POLYTEXTW array
  1257. *
  1258. * Return Value:
  1259. *
  1260. * status
  1261. *
  1262. * History:
  1263. * 7/31/92 -by- Paul Butzi and Eric Kutter
  1264. *
  1265. \**************************************************************************/
  1266. BOOL META WINAPI PolyTextOutW(HDC hdc,CONST POLYTEXTW *ppt,INT nstrings)
  1267. {
  1268. BOOL bRet = FALSE;
  1269. CONST POLYTEXTW *pp;
  1270. FIXUP_HANDLE(hdc);
  1271. if (nstrings == 0)
  1272. {
  1273. bRet = TRUE;
  1274. }
  1275. else if (nstrings < 0)
  1276. {
  1277. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1278. bRet = FALSE;
  1279. }
  1280. else
  1281. {
  1282. //
  1283. // Search for error case with string with non-0 length but sting == NULL
  1284. //
  1285. for ( pp = ppt; pp < (ppt + nstrings); pp += 1 )
  1286. {
  1287. if ( pp->lpstr == NULL)
  1288. {
  1289. //
  1290. // return failure if they have a non 0 length string with NULL
  1291. //
  1292. if (pp->n != 0)
  1293. {
  1294. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1295. return(FALSE);
  1296. }
  1297. }
  1298. }
  1299. //
  1300. // If we need to metafile, or print
  1301. //
  1302. if (IS_ALTDC_TYPE(hdc))
  1303. {
  1304. PLDC pldc;
  1305. if (IS_METADC16_TYPE(hdc))
  1306. {
  1307. return (
  1308. MF16_PolyTextOut(
  1309. hdc,
  1310. (CONST POLYTEXTA*) ppt,
  1311. nstrings,
  1312. TRUE // mrType == EMR_POLYTEXTOUTW
  1313. )
  1314. );
  1315. }
  1316. DC_PLDC(hdc,pldc,bRet);
  1317. if (pldc->iType == LO_METADC)
  1318. {
  1319. if
  1320. (
  1321. !MF_PolyTextOut(
  1322. hdc,
  1323. (CONST POLYTEXTA*) ppt,
  1324. nstrings,
  1325. EMR_POLYTEXTOUTW
  1326. )
  1327. )
  1328. return(bRet);
  1329. }
  1330. if (pldc->fl & LDC_SAP_CALLBACK)
  1331. {
  1332. vSAPCallback(pldc);
  1333. }
  1334. if (pldc->fl & LDC_DOC_CANCELLED)
  1335. {
  1336. return(bRet);
  1337. }
  1338. if (pldc->fl & LDC_CALL_STARTPAGE)
  1339. {
  1340. StartPage(hdc);
  1341. }
  1342. }
  1343. bRet = NtGdiPolyTextOutW(hdc,(POLYTEXTW *)ppt,nstrings, 0);
  1344. }
  1345. return(bRet);
  1346. }
  1347. /******************************Public*Routine******************************\
  1348. * PolyTextOutA
  1349. *
  1350. * Arguments:
  1351. *
  1352. * hdc - handle to device context
  1353. * ppt - pointer to array of POLYTEXTA
  1354. * nstrings - length of POLYTEXTA array
  1355. *
  1356. * Return Value:
  1357. *
  1358. * status
  1359. *
  1360. * History:
  1361. * 7/31/92 -by- Paul Butzi and Eric Kutter
  1362. *
  1363. \**************************************************************************/
  1364. BOOL META WINAPI PolyTextOutA(HDC hdc, CONST POLYTEXTA *ppt, INT nstrings)
  1365. {
  1366. //
  1367. // Convert text to UNICODE and make call
  1368. //
  1369. POLYTEXTW *pp, *pPolyTextW;
  1370. UINT szTotal = 0;
  1371. INT cjdx;
  1372. BOOL bRet = FALSE;
  1373. BOOL bDBCSCodePage;
  1374. int i;
  1375. PVOID pCharBuffer;
  1376. PBYTE pj;
  1377. DWORD dwCodePage;
  1378. FIXUP_HANDLE(hdc);
  1379. if (nstrings == 0)
  1380. {
  1381. return(TRUE);
  1382. }
  1383. if (nstrings < 0)
  1384. {
  1385. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1386. return(FALSE);
  1387. }
  1388. //
  1389. // Figure out the size needed
  1390. //
  1391. pPolyTextW = (POLYTEXTW*) ppt;
  1392. if( BALLOC_OVERFLOW1(nstrings,POLYTEXTW) )
  1393. {
  1394. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1395. return FALSE;
  1396. }
  1397. szTotal = sizeof(POLYTEXTW) * nstrings;
  1398. for ( pp = pPolyTextW; pp < (pPolyTextW + nstrings); pp ++)
  1399. {
  1400. if (pp->lpstr != NULL)
  1401. {
  1402. if( BALLOC_OVERFLOW1(pp->n,WCHAR)
  1403. || (szTotal + pp->n*sizeof(WCHAR)) < szTotal )
  1404. {
  1405. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1406. return FALSE;
  1407. }
  1408. szTotal += pp->n * sizeof(WCHAR);
  1409. if ( pp->pdx != NULL )
  1410. {
  1411. cjdx = pp->n * sizeof(int);
  1412. if (pp->uiFlags & ETO_PDY)
  1413. cjdx *= 2;
  1414. if( (szTotal + cjdx) < szTotal )
  1415. {
  1416. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1417. return FALSE;
  1418. }
  1419. szTotal += cjdx;
  1420. }
  1421. }
  1422. else
  1423. {
  1424. //
  1425. // return failure if they have a non 0 length string with NULL
  1426. //
  1427. if (pp->n != 0)
  1428. {
  1429. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1430. return(FALSE);
  1431. }
  1432. }
  1433. }
  1434. //
  1435. // If we need to metafile, or print
  1436. //
  1437. if (IS_ALTDC_TYPE(hdc))
  1438. {
  1439. PLDC pldc;
  1440. if (IS_METADC16_TYPE(hdc))
  1441. {
  1442. return (
  1443. MF16_PolyTextOut(
  1444. hdc,
  1445. (CONST POLYTEXTA*) pPolyTextW,
  1446. nstrings,
  1447. FALSE
  1448. )
  1449. );
  1450. }
  1451. DC_PLDC(hdc,pldc,bRet);
  1452. if (pldc->iType == LO_METADC)
  1453. {
  1454. if
  1455. (
  1456. !MF_PolyTextOut(
  1457. hdc,
  1458. (CONST POLYTEXTA*) pPolyTextW,
  1459. nstrings,
  1460. EMR_POLYTEXTOUTA
  1461. )
  1462. )
  1463. return(bRet);
  1464. }
  1465. if (pldc->fl & LDC_SAP_CALLBACK)
  1466. {
  1467. vSAPCallback(pldc);
  1468. }
  1469. if (pldc->fl & LDC_DOC_CANCELLED)
  1470. {
  1471. return(bRet);
  1472. }
  1473. if (pldc->fl & LDC_CALL_STARTPAGE)
  1474. {
  1475. StartPage(hdc);
  1476. }
  1477. }
  1478. //
  1479. // alloc memory for WHCAR structures
  1480. //
  1481. pCharBuffer = LOCALALLOC(szTotal);
  1482. if (pCharBuffer == NULL)
  1483. {
  1484. return(FALSE);
  1485. }
  1486. RtlCopyMemory(pCharBuffer, (PBYTE) pPolyTextW, nstrings*sizeof(POLYTEXTW));
  1487. pp = (POLYTEXTW *)pCharBuffer;
  1488. //
  1489. // now copy the stuff into the buffer
  1490. //
  1491. pj = (PBYTE)pCharBuffer + nstrings*sizeof(POLYTEXTW);
  1492. dwCodePage = GetCodePage(hdc);
  1493. bDBCSCodePage = IS_ANY_DBCS_CODEPAGE(dwCodePage);
  1494. for ( i = 0; i < nstrings; i += 1 )
  1495. {
  1496. if ((pp[i].pdx != NULL) && (pp[i].lpstr != NULL))
  1497. {
  1498. // patch pdx
  1499. cjdx = pp[i].n * sizeof(INT);
  1500. if (pp[i].uiFlags & ETO_PDY)
  1501. cjdx *= 2;
  1502. if(bDBCSCodePage)
  1503. {
  1504. ConvertDxArray(dwCodePage,
  1505. (char*) pp[i].lpstr,
  1506. pp[i].pdx,
  1507. pp[i].n,
  1508. (int*) pj,
  1509. pp[i].uiFlags & ETO_PDY
  1510. );
  1511. }
  1512. else
  1513. {
  1514. RtlCopyMemory(pj,pp[i].pdx,cjdx);
  1515. }
  1516. pp[i].pdx = (int *)pj;
  1517. pj += cjdx;
  1518. }
  1519. }
  1520. for ( i = 0; i < nstrings; i += 1 )
  1521. {
  1522. if ( pp[i].lpstr != NULL )
  1523. {
  1524. pp[i].n = MultiByteToWideChar(dwCodePage,
  1525. 0,
  1526. (LPSTR) pp[i].lpstr,
  1527. pp[i].n, (LPWSTR) pj,
  1528. pp[i].n*sizeof(WCHAR));
  1529. // patch lpstr
  1530. pp[i].lpstr = (LPWSTR)pj;
  1531. pj += pp[i].n * sizeof(WCHAR);
  1532. }
  1533. }
  1534. //
  1535. // send off the message and cleanup
  1536. //
  1537. bRet = NtGdiPolyTextOutW(hdc,(POLYTEXTW *)pCharBuffer,nstrings,dwCodePage);
  1538. LOCALFREE(pCharBuffer);
  1539. return(bRet);
  1540. }
  1541. /******************************Public*Routine******************************\
  1542. *
  1543. * BOOL META WINAPI TextOutW
  1544. *
  1545. *
  1546. *
  1547. * History:
  1548. * 07-Aug-1991 -by- Bodin Dresevic [BodinD]
  1549. * Wrote it.
  1550. \**************************************************************************/
  1551. BOOL META WINAPI TextOutW(
  1552. HDC hdc,
  1553. int x,
  1554. int y,
  1555. LPCWSTR pwsz,
  1556. int c
  1557. )
  1558. {
  1559. BOOL bRet = FALSE;
  1560. FIXUP_HANDLE(hdc);
  1561. if ((c <= 0) || (pwsz == (LPCWSTR) NULL))
  1562. {
  1563. if (c == 0)
  1564. return(TRUE);
  1565. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1566. return(FALSE);
  1567. }
  1568. if (IS_ALTDC_TYPE(hdc))
  1569. {
  1570. PLDC pldc;
  1571. if (IS_METADC16_TYPE(hdc))
  1572. return(MF16_TextOut(hdc,x,y,(LPCSTR) pwsz,c,TRUE));
  1573. DC_PLDC(hdc,pldc,bRet);
  1574. if((pldc->iType == LO_METADC) &&
  1575. (!(pldc->fl & LDC_META_PRINT) || !gbLpk))
  1576. {
  1577. if (!MF_ExtTextOut(hdc,x,y,0,(LPRECT)NULL,(LPCSTR) pwsz,c,(LPINT)NULL,EMR_EXTTEXTOUTW))
  1578. return(bRet);
  1579. }
  1580. if (pldc->fl & LDC_SAP_CALLBACK)
  1581. vSAPCallback(pldc);
  1582. if (pldc->fl & LDC_DOC_CANCELLED)
  1583. return(bRet);
  1584. if (pldc->fl & LDC_CALL_STARTPAGE)
  1585. StartPage(hdc);
  1586. }
  1587. RESETUSERPOLLCOUNT();
  1588. #ifdef LANGPACK
  1589. if(gbLpk)
  1590. {
  1591. return((*fpLpkExtTextOut)(hdc, x, y, 0, NULL, pwsz, c, 0, -1));
  1592. }
  1593. #endif
  1594. if ((c <= MAX_BATCH_WCHAR) && (GdiBatchLimit > 1))
  1595. {
  1596. bRet = bBatchTextOut(hdc,
  1597. x,
  1598. y,
  1599. 0,
  1600. (LPRECT)NULL,
  1601. (LPWSTR)pwsz,
  1602. NULL,
  1603. c,
  1604. 2 *c,
  1605. 0);
  1606. }
  1607. if (!bRet)
  1608. {
  1609. bRet = NtGdiExtTextOutW(hdc,
  1610. x,
  1611. y,
  1612. 0,
  1613. 0,
  1614. (LPWSTR)pwsz,
  1615. c,
  1616. 0,
  1617. 0);
  1618. }
  1619. return(bRet);
  1620. }
  1621. /******************************Public*Routine******************************\
  1622. *
  1623. * DWORD GetCodePage(HDC hdc)
  1624. *
  1625. * Effects: returns the code page of the font selected in the dc
  1626. *
  1627. * History:
  1628. * 23-May-1995 -by- Bodin Dresevic [BodinD]
  1629. * Wrote it.
  1630. \**************************************************************************/
  1631. DWORD GetCodePage(HDC hdc)
  1632. {
  1633. PDC_ATTR pDcAttr;
  1634. FIXUP_HANDLE(hdc);
  1635. PSHARED_GET_VALIDATE(pDcAttr,hdc,DC_TYPE);
  1636. if (pDcAttr)
  1637. {
  1638. if (!(pDcAttr->ulDirty_ & DIRTY_CHARSET))
  1639. return (0x0000ffff & pDcAttr->iCS_CP); // mask charset
  1640. }
  1641. else
  1642. {
  1643. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1644. return guintAcp; // reasonable default;
  1645. }
  1646. // we end up here if the code page attributes are dirty so that
  1647. // we have to call to the kernel, force the mapping and retrieve
  1648. // the code page and char set of the font selected in the dc:
  1649. return (0x0000ffff & NtGdiGetCharSet(hdc)); // mask charset
  1650. }
  1651. /******************************Public*Routine******************************\
  1652. *
  1653. * BOOL META WINAPI ExtTextOutA
  1654. * History:
  1655. * 07-Aug-1991 -by- Bodin Dresevic [BodinD]
  1656. * Wrote it.
  1657. \**************************************************************************/
  1658. #define CAPTURE_STRING_SIZE 130
  1659. // not in kernel, it is ok to do this much on the stack
  1660. BOOL META WINAPI ExtTextOutInternalA(
  1661. HDC hdc,
  1662. int x,
  1663. int y,
  1664. UINT fl,
  1665. CONST RECT *prcl,
  1666. LPCSTR psz,
  1667. UINT c,
  1668. CONST INT *pdx,
  1669. BOOL bFromTextOut
  1670. )
  1671. {
  1672. BOOL bRet = FALSE;
  1673. DWORD dwCodePage;
  1674. BOOL bDBCSCodePage;
  1675. if ((fl & ETO_PDY) && !pdx)
  1676. return FALSE;
  1677. // if we do not know what to do with the rectangle, ignore it.
  1678. if (prcl && !(fl & (ETO_OPAQUE | ETO_CLIPPED)))
  1679. {
  1680. prcl = NULL;
  1681. }
  1682. if (!prcl)
  1683. {
  1684. fl &= ~(ETO_CLIPPED | ETO_OPAQUE); // ignore flags if no rect, win95 compat
  1685. }
  1686. FIXUP_HANDLE(hdc);
  1687. if (IS_ALTDC_TYPE(hdc))
  1688. {
  1689. PLDC pldc;
  1690. if (IS_METADC16_TYPE(hdc))
  1691. {
  1692. if(bFromTextOut)
  1693. {
  1694. // yes this matters, some apps rely on TextOutA being metafiled at
  1695. // TextOut and not ExtTextOutA
  1696. return(MF16_TextOut(hdc,x,y,psz,c,FALSE));
  1697. }
  1698. else
  1699. {
  1700. return (MF16_ExtTextOut(hdc,x,y,fl,prcl,psz,c,pdx,FALSE));
  1701. }
  1702. }
  1703. DC_PLDC(hdc,pldc,bRet);
  1704. // if we are EMF spooling then metafile glyph index calls, otherwise don't
  1705. if((pldc->iType == LO_METADC) &&
  1706. (!((!(pldc->fl & LDC_META_PRINT) && (fl & ETO_GLYPH_INDEX)) ||
  1707. ((pldc->fl & LDC_META_PRINT) && !(fl & ETO_GLYPH_INDEX) && (gbLpk) && !(fl & ETO_IGNORELANGUAGE) && c)) ||
  1708. (!(pldc->fl & LDC_META_PRINT) && (!(fl & ETO_GLYPH_INDEX)) && (fl & ETO_IGNORELANGUAGE) && (gbLpk))
  1709. )
  1710. )
  1711. {
  1712. DWORD mrType = (fl & ETO_GLYPH_INDEX) ?
  1713. EMR_EXTTEXTOUTW :
  1714. EMR_EXTTEXTOUTA ;
  1715. if (!MF_ExtTextOut(hdc,x,y,fl,prcl,psz,c, pdx, mrType))
  1716. return(bRet);
  1717. }
  1718. if (pldc->fl & LDC_SAP_CALLBACK)
  1719. vSAPCallback(pldc);
  1720. if (pldc->fl & LDC_DOC_CANCELLED)
  1721. return(bRet);
  1722. if (pldc->fl & LDC_CALL_STARTPAGE)
  1723. StartPage(hdc);
  1724. }
  1725. RESETUSERPOLLCOUNT();
  1726. if (fl & ETO_GLYPH_INDEX)
  1727. {
  1728. bRet = FALSE;
  1729. if ((c <= MAX_BATCH_WCHAR) && (GdiBatchLimit > 1))
  1730. {
  1731. bRet = bBatchTextOut(hdc,
  1732. x,
  1733. y,
  1734. fl,
  1735. (LPRECT)prcl,
  1736. (LPWSTR)psz,
  1737. pdx,
  1738. c,
  1739. 2*c,
  1740. 0);
  1741. }
  1742. if (!bRet)
  1743. {
  1744. bRet = NtGdiExtTextOutW(hdc,
  1745. x,y,
  1746. fl, (LPRECT)prcl,
  1747. (LPWSTR)psz, (int)c,
  1748. (LPINT)pdx, 0);
  1749. }
  1750. return(bRet);
  1751. }
  1752. // Get code page
  1753. dwCodePage = GetCodePage(hdc);
  1754. if(fFontAssocStatus)
  1755. {
  1756. dwCodePage = FontAssocHack(dwCodePage,(char*)psz,c);
  1757. }
  1758. bDBCSCodePage = IS_ANY_DBCS_CODEPAGE(dwCodePage);
  1759. if (c)
  1760. {
  1761. // get the code page of the font selected in the dc
  1762. WCHAR awcCaptureBuffer[CAPTURE_STRING_SIZE];
  1763. PWSZ pwszCapt;
  1764. INT aiDxCaptureBuffer[CAPTURE_STRING_SIZE*2]; // times 2 for pdy
  1765. INT *pDxCapture;
  1766. // Allocate the string buffer
  1767. if (c <= CAPTURE_STRING_SIZE)
  1768. {
  1769. pwszCapt = awcCaptureBuffer;
  1770. }
  1771. else
  1772. {
  1773. if(bDBCSCodePage)
  1774. {
  1775. pwszCapt =
  1776. ((c+1) >= MAXIMUM_POOL_ALLOC/(sizeof(WCHAR)+2*sizeof(INT)))
  1777. ? (PWSZ) 0
  1778. : LOCALALLOC((c+1) * (sizeof(WCHAR)+ 2 * sizeof(INT)));
  1779. pDxCapture = (INT*) &pwszCapt[(c+1)&~1]; // ^
  1780. } // |
  1781. else // for pdy, just in case
  1782. {
  1783. pwszCapt = BALLOC_OVERFLOW1(c,WCHAR)
  1784. ? ((PWSZ) 0) : LOCALALLOC(c * sizeof(WCHAR));
  1785. }
  1786. }
  1787. if (pwszCapt)
  1788. {
  1789. UINT u;
  1790. if(bDBCSCodePage && pdx)
  1791. {
  1792. if(c <= CAPTURE_STRING_SIZE)
  1793. {
  1794. pDxCapture = aiDxCaptureBuffer;
  1795. }
  1796. ConvertDxArray(dwCodePage,(char*) psz,(int*) pdx,c,pDxCapture, fl & ETO_PDY);
  1797. }
  1798. else
  1799. {
  1800. pDxCapture = (int*) pdx;
  1801. }
  1802. u = MultiByteToWideChar(
  1803. dwCodePage, 0,
  1804. psz,c,
  1805. pwszCapt, c*sizeof(WCHAR));
  1806. if (u)
  1807. {
  1808. bRet = FALSE;
  1809. #ifdef LANGPACK
  1810. if (gbLpk && !(fl & ETO_IGNORELANGUAGE))
  1811. {
  1812. bRet = ((*fpLpkExtTextOut)(hdc, x, y, fl, prcl, pwszCapt,
  1813. u, pDxCapture, 0));
  1814. if (pwszCapt != awcCaptureBuffer)
  1815. LOCALFREE(pwszCapt);
  1816. return bRet;
  1817. }
  1818. #endif
  1819. if ((c <= MAX_BATCH_WCHAR) && (GdiBatchLimit > 1))
  1820. {
  1821. bRet = bBatchTextOut(hdc,
  1822. x,
  1823. y,
  1824. fl,
  1825. (LPRECT)prcl,
  1826. (LPWSTR)pwszCapt,
  1827. pDxCapture,
  1828. u,
  1829. 2 * u,
  1830. dwCodePage
  1831. );
  1832. }
  1833. if (!bRet)
  1834. {
  1835. bRet = NtGdiExtTextOutW(
  1836. hdc,
  1837. x,y,
  1838. fl, (LPRECT)prcl,
  1839. (LPWSTR)pwszCapt,(int)u,
  1840. pDxCapture,
  1841. dwCodePage);
  1842. }
  1843. }
  1844. if (pwszCapt != awcCaptureBuffer)
  1845. LOCALFREE(pwszCapt);
  1846. }
  1847. else
  1848. {
  1849. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  1850. }
  1851. }
  1852. else
  1853. {
  1854. bRet = FALSE;
  1855. if ((prcl != NULL) && (fl & ETO_OPAQUE))
  1856. {
  1857. //
  1858. // try to batch text out rect
  1859. //
  1860. PDC_ATTR pdca;
  1861. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  1862. if ((pdca != NULL) && !(pdca->lTextAlign & TA_UPDATECP))
  1863. {
  1864. BEGIN_BATCH_HDC(hdc,pdca,BatchTypeTextOutRect,BATCHTEXTOUTRECT);
  1865. pBatch->BackColor = pdca->crBackgroundClr;
  1866. pBatch->fl = fl;
  1867. pBatch->rcl.left = prcl->left;
  1868. pBatch->rcl.top = prcl->top;
  1869. pBatch->rcl.right = prcl->right;
  1870. pBatch->rcl.bottom = prcl->bottom;
  1871. pBatch->ptlViewportOrg = pdca->ptlViewportOrg;
  1872. bRet = TRUE;
  1873. COMPLETE_BATCH_COMMAND();
  1874. }
  1875. }
  1876. UNBATCHED_COMMAND:
  1877. if (!bRet)
  1878. {
  1879. bRet = NtGdiExtTextOutW(hdc,
  1880. x,y,
  1881. fl,
  1882. (LPRECT)prcl,
  1883. NULL,0,NULL,dwCodePage);
  1884. }
  1885. }
  1886. return(bRet);
  1887. }
  1888. BOOL META WINAPI ExtTextOutA(
  1889. HDC hdc,
  1890. int x,
  1891. int y,
  1892. UINT fl,
  1893. CONST RECT *prcl,
  1894. LPCSTR psz,
  1895. UINT c,
  1896. CONST INT *pdx
  1897. )
  1898. {
  1899. return(ExtTextOutInternalA(hdc,x,y,fl,prcl,psz,c,pdx,FALSE));
  1900. }
  1901. /******************************Public*Routine******************************\
  1902. *
  1903. * BOOL META WINAPI TextOut
  1904. *
  1905. * History:
  1906. * 07-Aug-1991 -by- Bodin Dresevic [BodinD]
  1907. * Wrote it.
  1908. \**************************************************************************/
  1909. BOOL META WINAPI TextOutA(
  1910. HDC hdc,
  1911. int x,
  1912. int y,
  1913. LPCSTR psz,
  1914. int c
  1915. )
  1916. {
  1917. BOOL bRet = FALSE;
  1918. if ((c <= 0) || (psz == (LPCSTR) NULL))
  1919. {
  1920. if (c == 0)
  1921. return(TRUE);
  1922. GdiSetLastError(ERROR_INVALID_PARAMETER);
  1923. return(FALSE);
  1924. }
  1925. return ExtTextOutInternalA(hdc, x, y, 0, NULL, psz, c, NULL, TRUE);
  1926. }
  1927. /******************************Public*Routine******************************\
  1928. * FillRgn *
  1929. * *
  1930. * Client side stub. Copies all LDC attributes into the message. *
  1931. *
  1932. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  1933. * Wrote it. *
  1934. \**************************************************************************/
  1935. BOOL META WINAPI FillRgn(HDC hdc,HRGN hrgn,HBRUSH hbrush)
  1936. {
  1937. BOOL bRet = FALSE;
  1938. FIXUP_HANDLE(hdc);
  1939. FIXUP_HANDLE(hrgn);
  1940. FIXUP_HANDLE(hbrush);
  1941. // validate the region and brush.
  1942. if (!hrgn || !hbrush)
  1943. return(bRet);
  1944. if (IS_ALTDC_TYPE(hdc))
  1945. {
  1946. PLDC pldc;
  1947. if (IS_METADC16_TYPE(hdc))
  1948. return(MF16_DrawRgn(hdc,hrgn,hbrush,0,0,META_FILLREGION));
  1949. DC_PLDC(hdc,pldc,bRet);
  1950. if (pldc->iType == LO_METADC)
  1951. {
  1952. if (!MF_FillRgn(hdc,hrgn,hbrush))
  1953. return(bRet);
  1954. }
  1955. if (pldc->fl & LDC_SAP_CALLBACK)
  1956. vSAPCallback(pldc);
  1957. if (pldc->fl & LDC_DOC_CANCELLED)
  1958. return(bRet);
  1959. if (pldc->fl & LDC_CALL_STARTPAGE)
  1960. StartPage(hdc);
  1961. }
  1962. RESETUSERPOLLCOUNT();
  1963. return(NtGdiFillRgn(hdc,hrgn,hbrush));
  1964. }
  1965. /******************************Public*Routine******************************\
  1966. * FrameRgn *
  1967. * *
  1968. * Client side stub. Copies all LDC attributes into the message. *
  1969. *
  1970. * 23-11-94 -by- Lingyun Wang [lingyunw]
  1971. * Now hrgn and hbrush are server side handles
  1972. *
  1973. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  1974. * Wrote it. *
  1975. \**************************************************************************/
  1976. BOOL META WINAPI FrameRgn(
  1977. HDC hdc,
  1978. HRGN hrgn,
  1979. HBRUSH hbrush,
  1980. int cx,
  1981. int cy
  1982. )
  1983. {
  1984. BOOL bRet = FALSE;
  1985. FIXUP_HANDLE(hdc);
  1986. FIXUP_HANDLE(hrgn);
  1987. FIXUP_HANDLE(hbrush);
  1988. if (!hrgn || !hbrush)
  1989. return(FALSE);
  1990. if (IS_ALTDC_TYPE(hdc))
  1991. {
  1992. PLDC pldc;
  1993. if (IS_METADC16_TYPE(hdc))
  1994. return(MF16_DrawRgn(hdc,hrgn,hbrush,cx,cy,META_FRAMEREGION));
  1995. DC_PLDC(hdc,pldc,bRet);
  1996. if (pldc->iType == LO_METADC)
  1997. {
  1998. if (!MF_FrameRgn(hdc,hrgn,hbrush,cx,cy))
  1999. return(bRet);
  2000. }
  2001. if (pldc->fl & LDC_SAP_CALLBACK)
  2002. vSAPCallback(pldc);
  2003. if (pldc->fl & LDC_DOC_CANCELLED)
  2004. return(bRet);
  2005. if (pldc->fl & LDC_CALL_STARTPAGE)
  2006. StartPage(hdc);
  2007. }
  2008. RESETUSERPOLLCOUNT();
  2009. return(NtGdiFrameRgn(hdc,hrgn,hbrush,cx,cy));
  2010. }
  2011. /******************************Public*Routine******************************\
  2012. * InvertRgn *
  2013. * *
  2014. * Client side stub. *
  2015. *
  2016. * 23-11-94 -by- Lingyun Wang [lingyunw]
  2017. * Now hrgn is server side handle
  2018. *
  2019. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  2020. * Wrote it. *
  2021. \**************************************************************************/
  2022. BOOL META WINAPI InvertRgn(HDC hdc,HRGN hrgn)
  2023. {
  2024. BOOL bRet = FALSE;
  2025. FIXUP_HANDLE(hdc);
  2026. FIXUP_HANDLE(hrgn);
  2027. if (!hrgn)
  2028. return(FALSE);
  2029. if (IS_ALTDC_TYPE(hdc))
  2030. {
  2031. PLDC pldc;
  2032. if (IS_METADC16_TYPE(hdc))
  2033. return(MF16_DrawRgn(hdc,hrgn,(HBRUSH)0,0,0,META_INVERTREGION));
  2034. DC_PLDC(hdc,pldc,bRet);
  2035. if (pldc->iType == LO_METADC)
  2036. {
  2037. if (!MF_InvertPaintRgn(hdc,hrgn,EMR_INVERTRGN))
  2038. return(bRet);
  2039. }
  2040. if (pldc->fl & LDC_SAP_CALLBACK)
  2041. vSAPCallback(pldc);
  2042. if (pldc->fl & LDC_DOC_CANCELLED)
  2043. return(bRet);
  2044. if (pldc->fl & LDC_CALL_STARTPAGE)
  2045. StartPage(hdc);
  2046. }
  2047. RESETUSERPOLLCOUNT();
  2048. return(NtGdiInvertRgn(hdc,hrgn));
  2049. }
  2050. /******************************Public*Routine******************************\
  2051. * SetPixelV *
  2052. * *
  2053. * Client side stub. This is a version of SetPixel that does not return a *
  2054. * value. This one can be batched for better performance. *
  2055. * *
  2056. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  2057. * Wrote it. *
  2058. \**************************************************************************/
  2059. BOOL META WINAPI SetPixelV(HDC hdc,int x,int y,COLORREF color)
  2060. {
  2061. BOOL bRet = FALSE;
  2062. FIXUP_HANDLE(hdc);
  2063. if (IS_ALTDC_TYPE(hdc))
  2064. {
  2065. PLDC pldc;
  2066. if (IS_METADC16_TYPE(hdc))
  2067. return(MF16_RecordParmsWWD(hdc,(WORD)x,(WORD)y,(DWORD)color,META_SETPIXEL));
  2068. DC_PLDC(hdc,pldc,bRet);
  2069. if (pldc->iType == LO_METADC)
  2070. {
  2071. if (!MF_SetPixelV(hdc,x,y,color))
  2072. return(bRet);
  2073. }
  2074. if (pldc->fl & LDC_SAP_CALLBACK)
  2075. vSAPCallback(pldc);
  2076. if (pldc->fl & LDC_DOC_CANCELLED)
  2077. return(bRet);
  2078. if (pldc->fl & LDC_CALL_STARTPAGE)
  2079. StartPage(hdc);
  2080. }
  2081. RESETUSERPOLLCOUNT();
  2082. //
  2083. // ICM conversion (only happen for non-palette index color)
  2084. //
  2085. if (!(color & 0x01000000))
  2086. {
  2087. PDC_ATTR pdca;
  2088. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  2089. if (pdca && bNeedTranslateColor(pdca))
  2090. {
  2091. COLORREF NewColor;
  2092. if (IcmTranslateCOLORREF(hdc,pdca,color,&NewColor,ICM_FORWARD))
  2093. {
  2094. color = NewColor;
  2095. }
  2096. }
  2097. }
  2098. return(NtGdiSetPixel(hdc,x,y,color) != CLR_INVALID);
  2099. }
  2100. /******************************Public*Routine******************************\
  2101. * SetPixel *
  2102. * *
  2103. * Client side stub. *
  2104. * *
  2105. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  2106. * Wrote it. *
  2107. \**************************************************************************/
  2108. COLORREF META WINAPI SetPixel(HDC hdc,int x,int y,COLORREF color)
  2109. {
  2110. ULONG iRet = CLR_INVALID;
  2111. COLORREF ColorRet = CLR_INVALID;
  2112. COLORREF NewColor;
  2113. BOOL bStatus;
  2114. PDC_ATTR pdca;
  2115. FIXUP_HANDLE(hdc);
  2116. if (IS_ALTDC_TYPE(hdc))
  2117. {
  2118. PLDC pldc;
  2119. if (IS_METADC16_TYPE(hdc))
  2120. return(MF16_RecordParmsWWD(hdc,(WORD)x,(WORD)y,(DWORD)color,META_SETPIXEL));
  2121. DC_PLDC(hdc,pldc,iRet);
  2122. if (pldc->iType == LO_METADC)
  2123. {
  2124. if (!MF_SetPixelV(hdc,x,y,color))
  2125. return(iRet);
  2126. }
  2127. if (pldc->fl & LDC_SAP_CALLBACK)
  2128. vSAPCallback(pldc);
  2129. if (pldc->fl & LDC_DOC_CANCELLED)
  2130. return(iRet);
  2131. if (pldc->fl & LDC_CALL_STARTPAGE)
  2132. StartPage(hdc);
  2133. }
  2134. RESETUSERPOLLCOUNT();
  2135. PSHARED_GET_VALIDATE(pdca,hdc,DC_TYPE);
  2136. if (pdca)
  2137. {
  2138. //
  2139. // if the color is not a PaletteIndex and ICM is on then translate
  2140. //
  2141. if (!(color & 0x01000000) && bNeedTranslateColor(pdca))
  2142. {
  2143. bStatus = IcmTranslateCOLORREF(hdc,
  2144. pdca,
  2145. color,
  2146. &NewColor,
  2147. ICM_FORWARD);
  2148. if (bStatus)
  2149. {
  2150. color = NewColor;
  2151. }
  2152. }
  2153. ColorRet = NtGdiSetPixel(hdc,x,y,color);
  2154. if ( bNeedTranslateColor(pdca)
  2155. &&
  2156. ( IS_32BITS_COLOR(pdca->lIcmMode)
  2157. ||
  2158. ((ColorRet != CLR_INVALID) &&
  2159. !(ColorRet & 0x01000000))
  2160. )
  2161. )
  2162. {
  2163. //
  2164. // Translate back to original color
  2165. //
  2166. bStatus = IcmTranslateCOLORREF(hdc,
  2167. pdca,
  2168. ColorRet,
  2169. &NewColor,
  2170. ICM_BACKWARD);
  2171. if (bStatus)
  2172. {
  2173. ColorRet = NewColor;
  2174. }
  2175. }
  2176. }
  2177. else
  2178. {
  2179. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2180. }
  2181. return(ColorRet);
  2182. }
  2183. /******************************Public*Routine******************************\
  2184. * UpdateColors *
  2185. * *
  2186. * Client side stub. *
  2187. * *
  2188. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh] *
  2189. * Wrote it. *
  2190. \**************************************************************************/
  2191. BOOL WINAPI UpdateColors(HDC hdc)
  2192. {
  2193. BOOL bRet = FALSE;
  2194. FIXUP_HANDLE(hdc);
  2195. RESETUSERPOLLCOUNT();
  2196. return(NtGdiUpdateColors(hdc));
  2197. }
  2198. /******************************Public*Routine******************************\
  2199. * GdiFlush *
  2200. * *
  2201. * Client side stub. *
  2202. * *
  2203. * Wed 26-Jun-1991 13:58:00 -by- Charles Whitmer [chuckwh] *
  2204. * Wrote it. *
  2205. \**************************************************************************/
  2206. BOOL WINAPI GdiFlush(VOID)
  2207. {
  2208. NtGdiFlush();
  2209. return(TRUE);
  2210. }
  2211. /******************************Public*Routine******************************\
  2212. * GdiSetBatchLimit
  2213. *
  2214. *
  2215. * History:
  2216. * 31-Jul-1991 -by- Eric Kutter [erick]
  2217. * Wrote it.
  2218. \**************************************************************************/
  2219. DWORD WINAPI
  2220. GdiSetBatchLimit(
  2221. DWORD dwNewBatchLimit
  2222. )
  2223. {
  2224. DWORD OldLimit = 0;
  2225. //
  2226. // set batch limit (as long as it is (1 <= l <= 20))
  2227. // return old limit if successful. A new batch limit of 0
  2228. // means set to default (20)
  2229. //
  2230. if (dwNewBatchLimit == 0)
  2231. {
  2232. dwNewBatchLimit = 20;
  2233. }
  2234. if ((dwNewBatchLimit > 0 ) && (dwNewBatchLimit <= 20))
  2235. {
  2236. GdiFlush();
  2237. OldLimit = GdiBatchLimit;
  2238. GdiBatchLimit = dwNewBatchLimit;
  2239. }
  2240. return(OldLimit);
  2241. }
  2242. /******************************Public*Routine******************************\
  2243. * GdiGetBatchLimit
  2244. *
  2245. * History:
  2246. * 7-Apr-1992 -by- J. Andrew Goossen [andrewgo]
  2247. * Wrote it.
  2248. \**************************************************************************/
  2249. DWORD WINAPI GdiGetBatchLimit()
  2250. {
  2251. return(GdiBatchLimit);
  2252. }
  2253. /******************************Public*Routine******************************\
  2254. * EndPage
  2255. *
  2256. * Client side stub.
  2257. *
  2258. * History:
  2259. * Wed 12-Jun-1991 01:02:25 -by- Charles Whitmer [chuckwh]
  2260. * Wrote it.
  2261. * 9/16/97 - Ramananthan N. Venkatpathy [RamanV]
  2262. * Parameterized End Page to handle Form Pages.
  2263. \**************************************************************************/
  2264. int InternalEndPage(HDC hdc,
  2265. DWORD dwPageType)
  2266. {
  2267. int iRet = SP_ERROR;
  2268. FIXUP_HANDLE(hdc);
  2269. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  2270. {
  2271. PLDC pldc;
  2272. DC_PLDC(hdc,pldc,iRet);
  2273. //
  2274. // If the EndPage() is already called from
  2275. // Escape(NEXTBAND), Just return TRUE here.
  2276. //
  2277. // This will fixed ...
  2278. //
  2279. // + The KB Q118873 "PRB: EndPage() Returns -1 When Banding"
  2280. // + NTRaid #90099 "T1R: Visio 4.1, 16-bit can't print".
  2281. //
  2282. if( pldc->fl & LDC_CALLED_ENDPAGE )
  2283. {
  2284. pldc->fl &= ~LDC_CALLED_ENDPAGE;
  2285. return((int)TRUE);
  2286. }
  2287. if( pldc->fl & LDC_META_PRINT )
  2288. {
  2289. if (dwPageType == NORMAL_PAGE) {
  2290. return(MFP_EndPage( hdc ));
  2291. } else if (dwPageType == FORM_PAGE) {
  2292. return(MFP_EndFormPage( hdc ));;
  2293. }
  2294. }
  2295. if ((pldc->fl & LDC_DOC_CANCELLED) ||
  2296. ((pldc->fl & LDC_PAGE_STARTED) == 0))
  2297. {
  2298. GdiSetLastError(ERROR_INVALID_PARAMETER);
  2299. return(iRet);
  2300. }
  2301. if (pldc->fl & LDC_SAP_CALLBACK)
  2302. vSAPCallback(pldc);
  2303. pldc->fl &= ~LDC_PAGE_STARTED;
  2304. // now call the drivers UI portion
  2305. DocumentEventEx(pldc->pUMPD,
  2306. pldc->hSpooler,
  2307. hdc,
  2308. DOCUMENTEVENT_ENDPAGE,
  2309. 0,
  2310. NULL,
  2311. 0,
  2312. NULL);
  2313. RESETUSERPOLLCOUNT();
  2314. iRet = NtGdiEndPage(hdc);
  2315. // if user mode printer, call EndPagePrinter from user mode
  2316. if (iRet && pldc->pUMPD)
  2317. iRet = EndPagePrinterEx(pldc->pUMPD, pldc->hSpooler);
  2318. // For Win31 compatibility, return SP_ERROR for error.
  2319. if (!iRet)
  2320. iRet = SP_ERROR;
  2321. else
  2322. pldc->fl |= LDC_CALL_STARTPAGE;
  2323. #if PRINT_TIMER
  2324. if( bPrintTimer )
  2325. {
  2326. DWORD tc;
  2327. tc = GetTickCount();
  2328. DbgPrint("Page took %d.%d seconds to print\n",
  2329. (tc - pldc->msStartPage) / 1000,
  2330. (tc - pldc->msStartPage) % 1000 );
  2331. }
  2332. #endif
  2333. }
  2334. else
  2335. {
  2336. GdiSetLastError(ERROR_INVALID_HANDLE);
  2337. }
  2338. return(iRet);
  2339. }
  2340. int WINAPI EndPage(HDC hdc)
  2341. {
  2342. return InternalEndPage(hdc, NORMAL_PAGE);
  2343. }
  2344. int WINAPI EndFormPage(HDC hdc)
  2345. {
  2346. return InternalEndPage(hdc, FORM_PAGE);
  2347. }
  2348. /******************************Public*Routine******************************\
  2349. * StartPage
  2350. *
  2351. * Client side stub.
  2352. *
  2353. * History:
  2354. * 31-Jul-1991 -by- Eric Kutter [erick]
  2355. * Wrote it.
  2356. \**************************************************************************/
  2357. int WINAPI StartPage(HDC hdc)
  2358. {
  2359. int iRet = SP_ERROR;
  2360. FIXUP_HANDLE(hdc);
  2361. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  2362. {
  2363. PLDC pldc;
  2364. DC_PLDC(hdc,pldc,iRet);
  2365. #if PRINT_TIMER
  2366. pldc->msStartPage = GetTickCount();
  2367. #endif
  2368. if( pldc->fl & LDC_META_PRINT )
  2369. return(MFP_StartPage( hdc ));
  2370. pldc->fl &= ~LDC_CALL_STARTPAGE;
  2371. pldc->fl &= ~LDC_CALLED_ENDPAGE;
  2372. // Do nothing if page has already been started.
  2373. if (pldc->fl & LDC_PAGE_STARTED)
  2374. return(1);
  2375. // now call the drivers UI portion
  2376. if (pldc->hSpooler)
  2377. {
  2378. if (DocumentEventEx(pldc->pUMPD,
  2379. pldc->hSpooler,
  2380. hdc,
  2381. DOCUMENTEVENT_STARTPAGE,
  2382. 0,
  2383. NULL,
  2384. 0,
  2385. NULL) == -1)
  2386. {
  2387. return(iRet);
  2388. }
  2389. }
  2390. pldc->fl |= LDC_PAGE_STARTED;
  2391. RESETUSERPOLLCOUNT();
  2392. // If it is UMPD, call StartPagePrinter from user mode
  2393. if (pldc->pUMPD)
  2394. iRet = StartPagePrinterEx(pldc->pUMPD, pldc->hSpooler);
  2395. if (iRet)
  2396. {
  2397. iRet = NtGdiStartPage(hdc);
  2398. }
  2399. // For Win31 compatibility, return SP_ERROR for error.
  2400. if (!iRet)
  2401. {
  2402. pldc->fl &= ~LDC_PAGE_STARTED;
  2403. EndDoc(hdc);
  2404. iRet = SP_ERROR;
  2405. SetLastError(ERROR_INVALID_HANDLE);
  2406. }
  2407. }
  2408. else
  2409. {
  2410. GdiSetLastError(ERROR_INVALID_HANDLE);
  2411. }
  2412. return(iRet);
  2413. }
  2414. /******************************Public*Routine******************************\
  2415. * StartFormPage
  2416. *
  2417. * This interface has been added to support watermarks and forms.
  2418. *
  2419. * History:
  2420. * 7/1/97 -- Ramanathan Venkatapathy [RamanV]
  2421. *
  2422. \**************************************************************************/
  2423. int WINAPI StartFormPage(HDC hdc)
  2424. {
  2425. // Call StartPage. Recording required for watermarks is done in EndFormPage
  2426. return StartPage(hdc);
  2427. }
  2428. /******************************Public*Routine******************************\
  2429. * EndDoc
  2430. *
  2431. * If a thread is created at StartDoc(), terminate it here.
  2432. *
  2433. * History:
  2434. * 31-Jul-1991 -by- Eric Kutter [erick]
  2435. * Wrote it.
  2436. \**************************************************************************/
  2437. int WINAPI EndDoc(HDC hdc)
  2438. {
  2439. int iRet = SP_ERROR;
  2440. FIXUP_HANDLE(hdc);
  2441. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  2442. {
  2443. PLDC pldc;
  2444. DC_PLDC(hdc,pldc,iRet);
  2445. if( pldc->fl & LDC_META_PRINT )
  2446. return(MFP_EndDoc( hdc ));
  2447. #if PRINT_TIMER
  2448. if( bPrintTimer )
  2449. {
  2450. DWORD tc;
  2451. tc = GetTickCount();
  2452. DbgPrint("Document took %d.%d seconds to print\n",
  2453. (tc - pldc->msStartDoc) / 1000,
  2454. (tc - pldc->msStartDoc) % 1000 );
  2455. DbgPrint("Peak temporary spool buffer size: %d\n", PeakTempSpoolBuf);
  2456. }
  2457. #endif
  2458. if ((pldc->fl & LDC_DOC_STARTED) == 0)
  2459. return(1);
  2460. // Call EndPage if the page has been started.
  2461. if (pldc->fl & LDC_PAGE_STARTED)
  2462. EndPage(hdc);
  2463. // now call the drivers UI portion
  2464. DocumentEventEx(pldc->pUMPD,
  2465. pldc->hSpooler,
  2466. hdc,
  2467. DOCUMENTEVENT_ENDDOCPRE,
  2468. 0,
  2469. NULL,
  2470. 0,
  2471. NULL);
  2472. RESETUSERPOLLCOUNT();
  2473. iRet = NtGdiEndDoc(hdc);
  2474. //
  2475. // call EndDocPrinter from user mode if it is a User Mode Printer
  2476. //
  2477. if (pldc->pUMPD)
  2478. iRet = EndDocPrinterEx(pldc->pUMPD, pldc->hSpooler);
  2479. // For Win31 compatibility, return SP_ERROR for error.
  2480. if (!iRet)
  2481. {
  2482. iRet = SP_ERROR;
  2483. }
  2484. else
  2485. {
  2486. DocumentEventEx(pldc->pUMPD,
  2487. pldc->hSpooler,
  2488. hdc,
  2489. DOCUMENTEVENT_ENDDOCPOST,
  2490. 0,
  2491. NULL,
  2492. 0,
  2493. NULL);
  2494. }
  2495. pldc->fl &= ~(LDC_DOC_STARTED | LDC_CALL_STARTPAGE |
  2496. LDC_SAP_CALLBACK | LDC_CALLED_ENDPAGE);
  2497. }
  2498. else
  2499. {
  2500. GdiSetLastError(ERROR_INVALID_HANDLE);
  2501. }
  2502. return(iRet);
  2503. }
  2504. /******************************Public*Routine******************************\
  2505. * AbortDoc
  2506. *
  2507. * Client side stub.
  2508. *
  2509. * History:
  2510. * 02-Apr-1992 -by- Wendy Wu [wendywu]
  2511. * Wrote it.
  2512. \**************************************************************************/
  2513. int WINAPI AbortDoc(HDC hdc)
  2514. {
  2515. int iRet = SP_ERROR;
  2516. FIXUP_HANDLE(hdc);
  2517. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  2518. {
  2519. PLDC pldc;
  2520. DC_PLDC(hdc,pldc,iRet);
  2521. if (!(pldc->fl & LDC_DOC_STARTED))
  2522. return(1);
  2523. // now call the drivers UI portion
  2524. DocumentEventEx(pldc->pUMPD,
  2525. pldc->hSpooler,
  2526. hdc,
  2527. DOCUMENTEVENT_ABORTDOC,
  2528. 0,
  2529. NULL,
  2530. 0,
  2531. NULL);
  2532. RESETUSERPOLLCOUNT();
  2533. if( pldc->fl & LDC_META_PRINT )
  2534. {
  2535. DeleteEnhMetaFile(UnassociateEnhMetaFile( hdc, FALSE ));
  2536. DeleteEMFSpoolData(pldc);
  2537. //
  2538. // bug 150446: calling fpAbortPrinter before deleting the
  2539. // EMF file might cause EMF file leak.
  2540. //
  2541. iRet = (*fpAbortPrinter)( pldc->hSpooler );
  2542. }
  2543. else
  2544. {
  2545. iRet = NtGdiAbortDoc(hdc);
  2546. // call AbortPrinter from user mode if it is UMPD
  2547. if (iRet && pldc->pUMPD)
  2548. iRet = AbortPrinterEx(pldc, FALSE);
  2549. }
  2550. // For Win31 compatibility, return SP_ERROR for error.
  2551. if (!iRet)
  2552. iRet = SP_ERROR;
  2553. // turn off the flags
  2554. pldc->fl &= ~(LDC_DOC_STARTED | LDC_PAGE_STARTED | LDC_CALL_STARTPAGE |
  2555. LDC_SAP_CALLBACK | LDC_META_PRINT | LDC_CALLED_ENDPAGE);
  2556. }
  2557. else
  2558. {
  2559. GdiSetLastError(ERROR_INVALID_HANDLE);
  2560. }
  2561. return(iRet);
  2562. }
  2563. /******************************Public*Routine******************************\
  2564. * StartDocA
  2565. *
  2566. * Client side stub.
  2567. *
  2568. * History:
  2569. *
  2570. * 21-Mar-1995 -by- Mark Enstrom [marke]
  2571. * Change to call StartDocW for kmode
  2572. *
  2573. * 31-Jul-1991 -by- Eric Kutter [erick]
  2574. * Wrote it.
  2575. \**************************************************************************/
  2576. ULONG ulToASCII_N(LPSTR psz, DWORD cbAnsi, LPWSTR pwsz, DWORD c);
  2577. int WINAPI StartDocA(HDC hdc, CONST DOCINFOA * pDocInfo)
  2578. {
  2579. DOCINFOW DocInfoW;
  2580. WCHAR wDocName[MAX_PATH];
  2581. WCHAR wOutput[MAX_PATH];
  2582. WCHAR wDataType[MAX_PATH];
  2583. int Length;
  2584. DocInfoW.cbSize = sizeof(DOCINFOW);
  2585. DocInfoW.lpszDocName = NULL;
  2586. DocInfoW.lpszOutput = NULL;
  2587. DocInfoW.lpszDatatype = NULL;
  2588. DocInfoW.fwType = 0;
  2589. if (pDocInfo)
  2590. {
  2591. if (pDocInfo->lpszDocName)
  2592. {
  2593. Length = strlen(pDocInfo->lpszDocName)+1;
  2594. if (Length > MAX_PATH)
  2595. {
  2596. ERROR_ASSERT(FALSE, "StartDocA lpszDocName Too long");
  2597. GdiSetLastError(ERROR_FILENAME_EXCED_RANGE);
  2598. return(SP_ERROR);
  2599. }
  2600. DocInfoW.lpszDocName = &wDocName[0];
  2601. vToUnicodeN(DocInfoW.lpszDocName,MAX_PATH,pDocInfo->lpszDocName,Length);
  2602. }
  2603. if (pDocInfo->lpszOutput)
  2604. {
  2605. Length = strlen(pDocInfo->lpszOutput)+1;
  2606. if (Length > MAX_PATH)
  2607. {
  2608. ERROR_ASSERT(FALSE, "StartDocA lpszOutput Too long");
  2609. GdiSetLastError(ERROR_FILENAME_EXCED_RANGE);
  2610. return(SP_ERROR);
  2611. }
  2612. DocInfoW.lpszOutput = &wOutput[0];
  2613. vToUnicodeN(DocInfoW.lpszOutput,MAX_PATH,pDocInfo->lpszOutput,Length);
  2614. }
  2615. // if the datatype is specified to be raw, and the size is the size of
  2616. // the new expanded DOCINFO, make it raw.
  2617. // we also verify that the fwType is valid. Otherwise, chances are
  2618. // the app left the two new fields unitialized.
  2619. try
  2620. {
  2621. if ((pDocInfo->cbSize == sizeof(DOCINFO)) &&
  2622. pDocInfo->lpszDatatype &&
  2623. (pDocInfo->fwType <= 1))
  2624. {
  2625. if (!_stricmp("emf",pDocInfo->lpszDatatype))
  2626. {
  2627. DocInfoW.lpszDatatype = L"EMF";
  2628. }
  2629. else
  2630. {
  2631. Length = strlen(pDocInfo->lpszDatatype)+1;
  2632. vToUnicodeN(wDataType,MAX_PATH,pDocInfo->lpszDatatype,Length);
  2633. DocInfoW.lpszDatatype = wDataType;
  2634. }
  2635. }
  2636. }
  2637. except(EXCEPTION_EXECUTE_HANDLER)
  2638. {
  2639. WARNING("StartDocA an app passed a new DOCINFO structure without initializing it\n");
  2640. }
  2641. }
  2642. return(StartDocW(hdc,&DocInfoW));
  2643. }
  2644. /******************************Public*Routine******************************\
  2645. * StartDocW
  2646. *
  2647. * Client side stub.
  2648. *
  2649. * History:
  2650. * 31-Jul-1991 -by- Eric Kutter [erick]
  2651. * Wrote it.
  2652. \**************************************************************************/
  2653. int WINAPI StartDocW(HDC hdc, CONST DOCINFOW * pDocInfo)
  2654. {
  2655. int iRet = SP_ERROR;
  2656. PWSTR pwstr = NULL;
  2657. DOCINFOW dio;
  2658. BOOL bForceRaw = FALSE;
  2659. BOOL bSendStartDocPost = FALSE;
  2660. BOOL bCallAbortPrinter = TRUE;
  2661. BOOL bEMF = FALSE;
  2662. INT iJob;
  2663. FIXUP_HANDLE(hdc);
  2664. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  2665. {
  2666. BOOL bBanding;
  2667. PLDC pldc;
  2668. DC_PLDC(hdc,pldc,iRet);
  2669. // don't allow StartDoc's on info dc's
  2670. if (pldc->fl & LDC_INFO)
  2671. {
  2672. SetLastError(ERROR_INVALID_HANDLE);
  2673. return iRet;
  2674. }
  2675. pldc->fl &= ~LDC_DOC_CANCELLED;
  2676. #if PRINT_TIMER
  2677. {
  2678. DbgPrint("StartDocW: Print Timer is on\n");
  2679. pldc->msStartDoc = GetTickCount();
  2680. }
  2681. #endif
  2682. if( pDocInfo )
  2683. {
  2684. dio = *pDocInfo;
  2685. if (dio.cbSize != offsetof(DOCINFOW,lpszDatatype))
  2686. {
  2687. dio.cbSize = sizeof(DOCINFOW);
  2688. dio.lpszDatatype = NULL;
  2689. dio.fwType = 0;
  2690. try
  2691. {
  2692. // if it is not NULL and not "emf", go raw
  2693. // we also verify that the fwType is valid. Otherwise, chances are
  2694. // the app left the two new fields unitialized.
  2695. if ((pDocInfo->cbSize == sizeof(DOCINFOW)) &&
  2696. pDocInfo->lpszDatatype &&
  2697. (pDocInfo->fwType <= 1) &&
  2698. _wcsicmp(L"emf",pDocInfo->lpszDatatype))
  2699. {
  2700. // the app requested non emf
  2701. bForceRaw = TRUE;
  2702. dio.lpszDatatype = pDocInfo->lpszDatatype;
  2703. }
  2704. }
  2705. except(EXCEPTION_EXECUTE_HANDLER)
  2706. {
  2707. WARNING("StartDocW an app passed a new DOCINFO structure without initializing it\n");
  2708. }
  2709. }
  2710. }
  2711. else
  2712. {
  2713. dio.cbSize = sizeof(DOCINFOW);
  2714. dio.lpszDatatype = NULL;
  2715. dio.lpszOutput = NULL;
  2716. dio.lpszDocName = NULL;
  2717. dio.fwType = 0;
  2718. }
  2719. // if no output port is specified but a port was specified at createDC, use
  2720. // that port now
  2721. if ((dio.lpszOutput == NULL) && (pldc->pwszPort != NULL))
  2722. {
  2723. dio.lpszOutput = pldc->pwszPort;
  2724. }
  2725. // StartDocDlgW returns -1 for error
  2726. // -2 for user cancelled
  2727. // NULL if there is no string to copy (not file port)
  2728. // Non NULL if there is a valid string
  2729. if(pldc->hSpooler != (HANDLE)0)
  2730. {
  2731. ASSERTGDI(ghSpooler,"non null hSpooler with unloaded WINSPOOL W\n");
  2732. pwstr = (*fpStartDocDlgW)(pldc->hSpooler, &dio);
  2733. if((LONG_PTR)pwstr == -2)
  2734. {
  2735. pldc->fl |= LDC_DOC_CANCELLED;
  2736. return(iRet);
  2737. }
  2738. if((LONG_PTR)pwstr == -1)
  2739. return(iRet);
  2740. if(pwstr != NULL)
  2741. {
  2742. dio.lpszOutput = pwstr;
  2743. }
  2744. }
  2745. // now call the drivers UI portion
  2746. if (pldc->hSpooler)
  2747. {
  2748. PVOID pv = (PVOID)&dio;
  2749. iRet = DocumentEventEx(pldc->pUMPD,
  2750. pldc->hSpooler,
  2751. hdc,
  2752. DOCUMENTEVENT_STARTDOCPRE,
  2753. sizeof(pv),
  2754. (PVOID)&pv,
  2755. 0,
  2756. NULL);
  2757. if (iRet == -1)
  2758. {
  2759. bCallAbortPrinter = FALSE;
  2760. goto KMMSGERROR;
  2761. }
  2762. if(iRet == -2)
  2763. {
  2764. pldc->fl |= LDC_DOC_CANCELLED;
  2765. goto MSGEXIT;
  2766. }
  2767. }
  2768. //
  2769. // Check application compatibility
  2770. //
  2771. if (GetAppCompatFlags(NULL) & GACF_NOEMFSPOOLING)
  2772. {
  2773. ULONG InData = POSTSCRIPT_PASSTHROUGH;
  2774. //
  2775. // Disable EMF spooling for postscript printer driver.
  2776. //
  2777. // Several PS-centric application could not work with EMF spooling.
  2778. // This problem is introduced, because application developed for win95
  2779. // reley on that win95 does not do EMF spooling with postscript, but
  2780. // NT does.
  2781. //
  2782. if (ExtEscape(hdc,QUERYESCSUPPORT,sizeof(ULONG),(LPCSTR)&InData,0,NULL))
  2783. {
  2784. bForceRaw = TRUE;
  2785. }
  2786. }
  2787. // Unless the driver has explicitly told us not to spool, we will first try
  2788. // to StartDoc with datatype EMF
  2789. // we also force to go to EMF if METAFILE_DRIVER is supported by the driver
  2790. if ((!bForceRaw && GetDCDWord(hdc, DDW_JOURNAL, 0) &&
  2791. RemoteRasterizerCompatible(pldc->hSpooler)) ||
  2792. ((pldc->pUMPD) && (pldc->pUMPD->dwFlags & UMPDFLAG_METAFILE_DRIVER)))
  2793. {
  2794. DOC_INFO_3W DocInfo;
  2795. DocInfo.pDocName = (LPWSTR) dio.lpszDocName;
  2796. DocInfo.pOutputFile = (LPWSTR) dio.lpszOutput;
  2797. DocInfo.pDatatype = (LPWSTR) L"NT EMF 1.008";
  2798. DocInfo.dwFlags = DI_MEMORYMAP_WRITE;
  2799. iJob = (*fpStartDocPrinterW)(pldc->hSpooler, 3, (LPBYTE) &DocInfo);
  2800. if( iJob <= 0 )
  2801. {
  2802. if( GetLastError() != ERROR_INVALID_DATATYPE )
  2803. {
  2804. WARNING("StartDocW: StartDocPrinter failed w/ error other \
  2805. than INVALID_DATA_TYPE\n");
  2806. bCallAbortPrinter = FALSE;
  2807. goto KMMSGERROR;
  2808. }
  2809. else
  2810. {
  2811. // we are going raw so just fall through
  2812. }
  2813. }
  2814. else
  2815. {
  2816. // the spooler likes the EMF data type so let start metafiling
  2817. MFD1("StartDocW calling MFP_StartDocW to do EMF printing\n");
  2818. if(MFP_StartDocW( hdc, &dio, FALSE))
  2819. {
  2820. iRet = iJob;
  2821. bSendStartDocPost = TRUE;
  2822. goto MSGEXIT;
  2823. }
  2824. else
  2825. {
  2826. WARNING("StartDocW: error calling MFP_StartDocW\n");
  2827. bEMF = TRUE;
  2828. goto KMMSGERROR;
  2829. }
  2830. }
  2831. }
  2832. // if it is a UMPD driver, call StartDocPrinter at the client side
  2833. if (pldc->pUMPD)
  2834. {
  2835. DOC_INFO_1W DocInfo;
  2836. #define MAX_DOCINFO_DATA_TYPE 80
  2837. WCHAR awchDatatype[MAX_DOCINFO_DATA_TYPE];
  2838. PFN pfn;
  2839. DocInfo.pDocName = (LPWSTR) dio.lpszDocName;
  2840. DocInfo.pOutputFile = (LPWSTR) dio.lpszOutput;
  2841. DocInfo.pDatatype = NULL;
  2842. if (pfn = pldc->pUMPD->apfn[INDEX_DrvQuerySpoolType])
  2843. {
  2844. awchDatatype[0] = 0;
  2845. // did the app specify a data type and will it fit in our buffer
  2846. if (dio.lpszDatatype)
  2847. {
  2848. int cjStr = (wcslen(dio.lpszDatatype) + 1) * sizeof(WCHAR);
  2849. if (cjStr < (MAX_DOCINFO_DATA_TYPE * sizeof(WCHAR)))
  2850. {
  2851. RtlCopyMemory((PVOID)awchDatatype,(PVOID)dio.lpszDatatype,cjStr);
  2852. }
  2853. }
  2854. if (pfn(((PUMDHPDEV)pldc->pUMdhpdev)->dhpdev, awchDatatype))
  2855. {
  2856. DocInfo.pDatatype = awchDatatype;
  2857. }
  2858. }
  2859. iJob = StartDocPrinterWEx(pldc->pUMPD, pldc->hSpooler, 1, (LPBYTE) &DocInfo);
  2860. }
  2861. // If we got here it means we are going raw. Mark the DC as type direct
  2862. if (pldc->pUMPD && (pldc->pUMPD->dwFlags & UMPDFLAG_METAFILE_DRIVER))
  2863. {
  2864. // we have to go EMF if METAFILE_DRIVER is on
  2865. WARNING("StartDocW failed because EMF failed and METAFILE_DRIVER is on\n");
  2866. goto KMMSGERROR;
  2867. }
  2868. pldc->fl |= LDC_PRINT_DIRECT;
  2869. iRet = NtGdiStartDoc(hdc,&dio,&bBanding, iJob);
  2870. if (iRet)
  2871. {
  2872. if (pldc->pfnAbort != NULL)
  2873. {
  2874. vSAPCallback(pldc);
  2875. if (pldc->fl & LDC_DOC_CANCELLED)
  2876. goto KMMSGERROR;
  2877. pldc->fl |= LDC_SAP_CALLBACK;
  2878. pldc->ulLastCallBack = GetTickCount();
  2879. }
  2880. pldc->fl |= LDC_DOC_STARTED;
  2881. if (bBanding)
  2882. {
  2883. MFD1("StartDocW calling MFP_StartDocW to do banding\n");
  2884. iRet = MFP_StartDocW( hdc, NULL, TRUE ) ? iRet : SP_ERROR;
  2885. }
  2886. else
  2887. {
  2888. // Only set this when we are not banding since the system will
  2889. // get confused and try to call StartPage while playing the
  2890. // metafile back during banding.
  2891. pldc->fl |= LDC_CALL_STARTPAGE;
  2892. }
  2893. bSendStartDocPost = TRUE;
  2894. }
  2895. else
  2896. {
  2897. KMMSGERROR:
  2898. iRet = SP_ERROR;
  2899. if (bCallAbortPrinter && pldc->pUMPD)
  2900. {
  2901. AbortPrinterEx(pldc, bEMF);
  2902. }
  2903. }
  2904. MSGEXIT:
  2905. if (bSendStartDocPost)
  2906. {
  2907. // now see if we need to call the drivers UI portion
  2908. {
  2909. if (DocumentEventEx(pldc->pUMPD,
  2910. pldc->hSpooler,
  2911. hdc,
  2912. DOCUMENTEVENT_STARTDOCPOST,
  2913. sizeof(iRet),
  2914. (PVOID)&iRet,
  2915. 0,
  2916. NULL) == -1)
  2917. {
  2918. AbortDoc(hdc);
  2919. iRet = SP_ERROR;
  2920. }
  2921. }
  2922. }
  2923. }
  2924. if (pwstr != NULL)
  2925. {
  2926. LocalFree(pwstr);
  2927. }
  2928. return(iRet);
  2929. }
  2930. /******************************Public*Routine******************************\
  2931. * StartDocEMF
  2932. *
  2933. * Special version of StartDoc used by the EMF playback code.
  2934. *
  2935. * History:
  2936. * 31-Jul-1991 -by- Eric Kutter [erick]
  2937. * Wrote it.
  2938. \**************************************************************************/
  2939. int WINAPI StartDocEMF(HDC hdc, CONST DOCINFOW * pDocInfo, BOOL *pbBanding )
  2940. {
  2941. int iRet = SP_ERROR;
  2942. DOCINFOW dio;
  2943. INT iJob = 0;
  2944. FIXUP_HANDLE(hdc);
  2945. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  2946. {
  2947. BOOL bBanding;
  2948. PLDC pldc;
  2949. DC_PLDC(hdc,pldc,iRet);
  2950. #if PRINT_TIMER
  2951. {
  2952. DbgPrint("StartDocW: Print Timer is on\n");
  2953. pldc->msStartDoc = GetTickCount();
  2954. }
  2955. #endif
  2956. // if no output port is specified but a port was specified at createDC, use that port now
  2957. if (pDocInfo)
  2958. {
  2959. dio = *pDocInfo;
  2960. if (dio.lpszOutput == NULL && pldc->pwszPort != NULL)
  2961. dio.lpszOutput = pldc->pwszPort;
  2962. }
  2963. else
  2964. {
  2965. ZeroMemory(&dio, sizeof(dio));
  2966. dio.cbSize = sizeof(dio);
  2967. }
  2968. // if it is a UMPD driver, call StartDocPrinter at the client side
  2969. if (pldc->pUMPD)
  2970. {
  2971. DOC_INFO_3W DocInfo;
  2972. DocInfo.pDocName = (LPWSTR) dio.lpszDocName;
  2973. DocInfo.pOutputFile = (LPWSTR) dio.lpszOutput;
  2974. DocInfo.pDatatype = NULL;
  2975. DocInfo.dwFlags = DI_MEMORYMAP_WRITE;
  2976. iJob = (*fpStartDocPrinterW)( pldc->hSpooler, 3, (LPBYTE) &DocInfo );
  2977. }
  2978. iRet = NtGdiStartDoc(hdc,(DOCINFOW *)&dio, pbBanding, iJob);
  2979. if (iRet)
  2980. {
  2981. pldc->fl |= LDC_DOC_STARTED;
  2982. pldc->fl |= LDC_CALL_STARTPAGE;
  2983. }
  2984. else
  2985. {
  2986. // For Win31 compatibility, return SP_ERROR for error.
  2987. iRet = SP_ERROR;
  2988. if (pldc->pUMPD)
  2989. {
  2990. (*fpAbortPrinter)(pldc->hSpooler);
  2991. }
  2992. }
  2993. }
  2994. return(iRet);
  2995. }
  2996. /******************************Private*Function****************************\
  2997. * vSAPCallback
  2998. *
  2999. * Call back to applications abort proc.
  3000. *
  3001. * History:
  3002. * 02-May-1992 -by- Wendy Wu [wendywu]
  3003. * Wrote it.
  3004. \**************************************************************************/
  3005. VOID vSAPCallback(PLDC pldc)
  3006. {
  3007. ULONG ulCurr = GetTickCount();
  3008. if (ulCurr - pldc->ulLastCallBack >= CALLBACK_INTERVAL)
  3009. {
  3010. pldc->ulLastCallBack = ulCurr;
  3011. if (!(*pldc->pfnAbort)(pldc->hdc, 0))
  3012. {
  3013. CancelDC(pldc->hdc);
  3014. AbortDoc(pldc->hdc);
  3015. }
  3016. }
  3017. }
  3018. /******************************Public*Routine******************************\
  3019. * SetAbortProc
  3020. *
  3021. * Save the application-supplied abort function in the LDC struct.
  3022. *
  3023. * History:
  3024. * 02-Apr-1992 -by- Wendy Wu [wendywu]
  3025. * Wrote it.
  3026. \**************************************************************************/
  3027. int WINAPI SetAbortProc(HDC hdc, ABORTPROC pfnAbort)
  3028. {
  3029. int iRet = SP_ERROR;
  3030. FIXUP_HANDLE(hdc);
  3031. if (IS_ALTDC_TYPE(hdc) && !IS_METADC16_TYPE(hdc))
  3032. {
  3033. PLDC pldc;
  3034. DC_PLDC(hdc,pldc,iRet);
  3035. if (pfnAbort != (ABORTPROC)NULL)
  3036. {
  3037. // PageMaker calls SetAbortProc after StartDoc.
  3038. if (pldc->fl & LDC_DOC_STARTED)
  3039. {
  3040. pldc->fl |= LDC_SAP_CALLBACK;
  3041. pldc->ulLastCallBack = GetTickCount();
  3042. }
  3043. }
  3044. else
  3045. {
  3046. pldc->fl &= ~LDC_SAP_CALLBACK;
  3047. }
  3048. pldc->pfnAbort = pfnAbort;
  3049. iRet = 1;
  3050. }
  3051. return(iRet);
  3052. }
  3053. /******************************Public*Routine******************************\
  3054. *
  3055. * GetPairKernTable
  3056. *
  3057. * support for GETPAIRKERNTABLE escape, basically reroute the call
  3058. * the the regular API
  3059. *
  3060. * History:
  3061. * 17-Jun-1996 -by- Bodin Dresevic [BodinD]
  3062. * Wrote it.
  3063. \**************************************************************************/
  3064. DWORD GetPairKernTable (
  3065. HDC hdc,
  3066. DWORD cjSize, // size of buffer in bytes
  3067. KERNPAIR * pkp
  3068. )
  3069. {
  3070. DWORD dwRet = GetKerningPairsA(hdc, 0, NULL);
  3071. DWORD dwRet1, ikp;
  3072. if (pkp && dwRet)
  3073. {
  3074. // pointer to receiving buffer
  3075. KERNINGPAIR *pKernPair = LOCALALLOC(dwRet * sizeof(KERNINGPAIR));
  3076. if (pKernPair)
  3077. {
  3078. dwRet1 = GetKerningPairsA(hdc, dwRet, pKernPair);
  3079. if (dwRet1 == dwRet) // paranoid check
  3080. {
  3081. // now we can copy the data out, get the number of pairs
  3082. // that the buffer can hold:
  3083. dwRet = cjSize / sizeof (KERNPAIR);
  3084. if (dwRet > dwRet1)
  3085. dwRet = dwRet1;
  3086. for (ikp = 0; ikp < dwRet; ikp++)
  3087. {
  3088. pkp[ikp].sAmount = (SHORT)pKernPair[ikp].iKernAmount;
  3089. pkp[ikp].wBoth = (WORD)
  3090. ((BYTE)pKernPair[ikp].wFirst |
  3091. (BYTE)pKernPair[ikp].wSecond << 8);
  3092. }
  3093. }
  3094. else
  3095. {
  3096. dwRet = 0;
  3097. }
  3098. LOCALFREE(pKernPair);
  3099. }
  3100. else
  3101. {
  3102. dwRet = 0;
  3103. }
  3104. }
  3105. return dwRet;
  3106. }
  3107. /******************************Public*Routine******************************\
  3108. * Escape *
  3109. * *
  3110. * Compatibility support for the old 16 bit Escape call. *
  3111. * *
  3112. * Note that there are some rules to follow here: *
  3113. * *
  3114. * 1) WOW should map a selected set of old Escape calls to ExtEscape. *
  3115. * These should be the calls that we want to support under NT (i.e. the *
  3116. * ones we are forced to support), and that make sense (i.e. have well *
  3117. * defined output structures, where NULL is well defined). In this *
  3118. * mapping, WOW insures 32 bit alignment. It maps directly to ExtEscape *
  3119. * just for efficiency. *
  3120. * *
  3121. * 2) GDI should map ALL the same calls that WOW does. Thus when a 16 bit *
  3122. * app that works under WOW gets ported to 32 bits, it will keep *
  3123. * working, even if it still calls Escape. (I'm basically assuming that *
  3124. * Chicago will also allow this. On the other hand if Chicago forces *
  3125. * apps to migrate to ExtEscape, then we can too. But we can't force *
  3126. * them by ourselves!) *
  3127. * *
  3128. * 3) Any data structures passed to Escape must get passed unchanged to *
  3129. * ExtEscape. This includes the 16 bit WORD in POSTSCRIPT_PASSTHROUGH. *
  3130. * Remember, we *want* Chicago to be able to easily support our *
  3131. * ExtEscapes. If we remove that WORD, it will be hard for then *
  3132. * to put it back. It's pretty easy for our driver to ignore it. *
  3133. * *
  3134. * 4) Our Escape entry point should handle QUERYESCSUPPORT in the *
  3135. * following way. a) It should require an nCount of 2, not the *
  3136. * present 4. b) It should return TRUE for those functions that it *
  3137. * handles by mapping onto APIs. c) For any function that it would pass *
  3138. * on to ExtEscape, it should also pass the QUERYESCSUPPORT on. (For *
  3139. * example, this function can't answer for the support of *
  3140. * POSTSCRIPT_PASSTHROUGH.) However, the QUERYESCSUPPORT in ExtEscape *
  3141. * *should* expect a DWORD. (It is after all a 32 bit function.) This *
  3142. * should not inconvenience Chicago. They can simply reject function *
  3143. * numbers >64K. *
  3144. * [chuckwh - 5/8/93] *
  3145. * *
  3146. * History: *
  3147. * Mon May 17 13:49:32 1993 -by- Hock San Lee [hockl] *
  3148. * Made ENCAPSULATED_POSTSCRIPT call DrawEscape. *
  3149. * *
  3150. * Sat 08-May-1993 00:03:06 -by- Charles Whitmer [chuckwh] *
  3151. * Added support for POSTSCRIPT_PASSTHROUGH, OPENCHANNEL, CLOSECHANNEL, *
  3152. * DOWNLOADHEADER, DOWNLOADFACE, GETFACENAME, ENCAPSULATED_POSTSCRIPT. *
  3153. * Cleaned up the code and conventions a bit. *
  3154. * *
  3155. * 02-Apr-1992 -by- Wendy Wu [wendywu] *
  3156. * Modified to call the client side GDI functions. *
  3157. * *
  3158. * 01-Aug-1991 -by- Eric Kutter [erick] *
  3159. * Wrote it. *
  3160. \**************************************************************************/
  3161. int WINAPI Escape(
  3162. HDC hdc, // Identifies the device context.
  3163. int iEscape, // Specifies the escape function to be performed.
  3164. int cjIn, // Number of bytes of data pointed to by pvIn.
  3165. LPCSTR pvIn, // Points to the input data.
  3166. LPVOID pvOut // Points to the structure to receive output.
  3167. )
  3168. {
  3169. int iRet = 0;
  3170. DOCINFOA DocInfo;
  3171. PLDC pldc;
  3172. ULONG iQuery;
  3173. BOOL bFixUp;
  3174. FIXUP_HANDLE(hdc);
  3175. // Metafile the call.
  3176. if(IS_METADC16_TYPE(hdc))
  3177. return((int) MF16_Escape(hdc,iEscape,cjIn,pvIn,pvOut));
  3178. // handle escapes that don't require a printer
  3179. switch (iEscape)
  3180. {
  3181. case QUERYESCSUPPORT:
  3182. switch(*((UNALIGNED USHORT *) pvIn))
  3183. {
  3184. // Respond OK to the calls we handle inline below.
  3185. case QUERYESCSUPPORT:
  3186. case PASSTHROUGH:
  3187. case STARTDOC:
  3188. case ENDDOC:
  3189. case NEWFRAME:
  3190. case ABORTDOC:
  3191. case SETABORTPROC:
  3192. case GETPHYSPAGESIZE:
  3193. case GETPRINTINGOFFSET:
  3194. case GETSCALINGFACTOR:
  3195. case NEXTBAND:
  3196. case GETCOLORTABLE:
  3197. case OPENCHANNEL:
  3198. case CLOSECHANNEL:
  3199. case DOWNLOADHEADER:
  3200. iRet = (IS_ALTDC_TYPE(hdc) ? 1 : 0);
  3201. break;
  3202. case GETEXTENDEDTEXTMETRICS:
  3203. iRet = 1;
  3204. break;
  3205. // Ask the driver about the few calls we allow to pass through.
  3206. case SETCOPYCOUNT:
  3207. case GETDEVICEUNITS:
  3208. case POSTSCRIPT_PASSTHROUGH:
  3209. case POSTSCRIPT_DATA:
  3210. case POSTSCRIPT_IGNORE:
  3211. case POSTSCRIPT_IDENTIFY:
  3212. case POSTSCRIPT_INJECTION:
  3213. case DOWNLOADFACE:
  3214. case BEGIN_PATH:
  3215. case END_PATH:
  3216. case CLIP_TO_PATH:
  3217. case DRAWPATTERNRECT:
  3218. iQuery = (ULONG) (*((UNALIGNED USHORT *) pvIn));
  3219. iRet =
  3220. (
  3221. ExtEscape
  3222. (
  3223. hdc,
  3224. (ULONG) ((USHORT) iEscape),
  3225. 4,
  3226. (LPCSTR) &iQuery,
  3227. 0,
  3228. (LPSTR) NULL
  3229. )
  3230. );
  3231. break;
  3232. case ENCAPSULATED_POSTSCRIPT:
  3233. iQuery = (ULONG) (*((UNALIGNED USHORT *) pvIn));
  3234. iRet =
  3235. (
  3236. DrawEscape
  3237. (
  3238. hdc,
  3239. (int) (ULONG) ((USHORT) iEscape),
  3240. 4,
  3241. (LPCSTR) &iQuery
  3242. )
  3243. );
  3244. break;
  3245. case QUERYDIBSUPPORT:
  3246. iRet = 1;
  3247. break;
  3248. // Otherwise it's no deal. Sorry. If we answer "yes" to some
  3249. // call we don't know *everything* about, we may find ourselves
  3250. // actually rejecting the call later when the app actually calls
  3251. // with some non-NULL pvOut. This would get the app all excited
  3252. // about our support for no reason. It would take a path that
  3253. // is doomed to failure. [chuckwh]
  3254. default:
  3255. iRet = 0;
  3256. break;
  3257. }
  3258. return(iRet);
  3259. case GETCOLORTABLE:
  3260. iRet = GetSystemPaletteEntries(hdc,*((UNALIGNED SHORT *)pvIn),1,pvOut);
  3261. if (iRet == 0)
  3262. iRet = -1;
  3263. return(iRet);
  3264. case QUERYDIBSUPPORT:
  3265. if ((pvOut != NULL) && (cjIn >= sizeof(BITMAPINFOHEADER)))
  3266. {
  3267. *((UNALIGNED LONG *)pvOut) = 0;
  3268. switch (((UNALIGNED BITMAPINFOHEADER *)pvIn)->biCompression)
  3269. {
  3270. case BI_RGB:
  3271. switch (((UNALIGNED BITMAPINFOHEADER *)pvIn)->biBitCount)
  3272. {
  3273. case 1:
  3274. case 4:
  3275. case 8:
  3276. case 16:
  3277. case 24:
  3278. case 32:
  3279. *((UNALIGNED LONG *)pvOut) = (QDI_SETDIBITS|QDI_GETDIBITS|
  3280. QDI_DIBTOSCREEN|QDI_STRETCHDIB);
  3281. break;
  3282. default:
  3283. break;
  3284. }
  3285. case BI_RLE4:
  3286. if (((UNALIGNED BITMAPINFOHEADER *)pvIn)->biBitCount == 4)
  3287. {
  3288. *((UNALIGNED LONG *)pvOut) = (QDI_SETDIBITS|QDI_GETDIBITS|
  3289. QDI_DIBTOSCREEN|QDI_STRETCHDIB);
  3290. }
  3291. break;
  3292. case BI_RLE8:
  3293. if (((UNALIGNED BITMAPINFOHEADER *)pvIn)->biBitCount == 8)
  3294. {
  3295. *((UNALIGNED LONG *)pvOut) = (QDI_SETDIBITS|QDI_GETDIBITS|
  3296. QDI_DIBTOSCREEN|QDI_STRETCHDIB);
  3297. }
  3298. break;
  3299. case BI_BITFIELDS:
  3300. switch (((UNALIGNED BITMAPINFOHEADER *)pvIn)->biBitCount)
  3301. {
  3302. case 16:
  3303. case 32:
  3304. *((UNALIGNED LONG *)pvOut) = (QDI_SETDIBITS|QDI_GETDIBITS|
  3305. QDI_DIBTOSCREEN|QDI_STRETCHDIB);
  3306. break;
  3307. default:
  3308. break;
  3309. }
  3310. default:
  3311. break;
  3312. }
  3313. return 1;
  3314. }
  3315. case GETEXTENDEDTEXTMETRICS:
  3316. return( GetETM( hdc, pvOut ) ? 1 : 0 );
  3317. }
  3318. // OK, ones that are related to printing and need the LDC
  3319. if (IS_ALTDC_TYPE(hdc))
  3320. {
  3321. BOOL bFixUp = FALSE;
  3322. PLDC pldc;
  3323. DC_PLDC(hdc,pldc,iRet);
  3324. // Call the appropriate client side APIs.
  3325. switch (iEscape)
  3326. {
  3327. case CLOSECHANNEL:
  3328. case ENDDOC:
  3329. iRet = EndDoc(hdc);
  3330. break;
  3331. case ABORTDOC:
  3332. iRet = AbortDoc(hdc);
  3333. break;
  3334. case SETABORTPROC:
  3335. iRet = SetAbortProc(hdc, (ABORTPROC)pvIn);
  3336. break;
  3337. case GETSCALINGFACTOR:
  3338. if (pvOut)
  3339. {
  3340. ((UNALIGNED POINT *)pvOut)->x = GetDeviceCaps(hdc, SCALINGFACTORX);
  3341. ((UNALIGNED POINT *)pvOut)->y = GetDeviceCaps(hdc, SCALINGFACTORY);
  3342. }
  3343. iRet = 1;
  3344. break;
  3345. case SETCOPYCOUNT:
  3346. iRet =
  3347. (
  3348. ExtEscape
  3349. (
  3350. hdc,
  3351. (ULONG) ((USHORT) iEscape),
  3352. cjIn,
  3353. pvIn,
  3354. pvOut ? sizeof(int) : 0,
  3355. (LPSTR) pvOut
  3356. )
  3357. );
  3358. break;
  3359. case GETDEVICEUNITS:
  3360. iRet =
  3361. (
  3362. ExtEscape
  3363. (
  3364. hdc,
  3365. GETDEVICEUNITS,
  3366. cjIn,
  3367. pvIn,
  3368. 16,
  3369. pvOut
  3370. )
  3371. );
  3372. break;
  3373. case POSTSCRIPT_PASSTHROUGH:
  3374. iRet =
  3375. (
  3376. ExtEscape
  3377. (
  3378. hdc,
  3379. POSTSCRIPT_PASSTHROUGH,
  3380. (int) (*((UNALIGNED USHORT *) pvIn))+2,
  3381. pvIn,
  3382. 0,
  3383. (LPSTR) NULL
  3384. )
  3385. );
  3386. break;
  3387. case OPENCHANNEL:
  3388. DocInfo.lpszDocName = (LPSTR) NULL;
  3389. DocInfo.lpszOutput = (LPSTR) NULL;
  3390. DocInfo.lpszDatatype= (LPSTR) "RAW";
  3391. DocInfo.fwType = 0;
  3392. iRet = StartDocA(hdc,&DocInfo);
  3393. break;
  3394. case DOWNLOADHEADER:
  3395. iRet = 1;
  3396. break;
  3397. case POSTSCRIPT_DATA:
  3398. case POSTSCRIPT_IGNORE:
  3399. case POSTSCRIPT_IDENTIFY:
  3400. case POSTSCRIPT_INJECTION:
  3401. case DOWNLOADFACE:
  3402. case BEGIN_PATH:
  3403. case END_PATH:
  3404. case CLIP_TO_PATH:
  3405. case DRAWPATTERNRECT:
  3406. iRet =
  3407. (
  3408. ExtEscape
  3409. (
  3410. hdc,
  3411. (ULONG) ((USHORT) iEscape),
  3412. cjIn,
  3413. pvIn,
  3414. 0,
  3415. (LPSTR) NULL
  3416. )
  3417. );
  3418. break;
  3419. case ENCAPSULATED_POSTSCRIPT:
  3420. iRet =
  3421. (
  3422. DrawEscape
  3423. (
  3424. hdc,
  3425. (int) (ULONG) ((USHORT) iEscape),
  3426. cjIn,
  3427. pvIn
  3428. )
  3429. );
  3430. break;
  3431. case GETPHYSPAGESIZE:
  3432. if (pvOut)
  3433. {
  3434. ((UNALIGNED POINT *)pvOut)->x = GetDeviceCaps(hdc, PHYSICALWIDTH);
  3435. ((UNALIGNED POINT *)pvOut)->y = GetDeviceCaps(hdc, PHYSICALHEIGHT);
  3436. }
  3437. iRet = 1;
  3438. break;
  3439. case GETPRINTINGOFFSET:
  3440. if (pvOut)
  3441. {
  3442. ((UNALIGNED POINT *)pvOut)->x = GetDeviceCaps(hdc, PHYSICALOFFSETX);
  3443. ((UNALIGNED POINT *)pvOut)->y = GetDeviceCaps(hdc, PHYSICALOFFSETY);
  3444. }
  3445. iRet = 1;
  3446. break;
  3447. case STARTDOC:
  3448. DocInfo.lpszDocName = (LPSTR)pvIn;
  3449. DocInfo.lpszOutput = (LPSTR)NULL;
  3450. DocInfo.lpszDatatype= (LPSTR) NULL;
  3451. DocInfo.fwType = 0;
  3452. iRet = StartDocA(hdc, &DocInfo);
  3453. bFixUp = TRUE;
  3454. break;
  3455. case PASSTHROUGH:
  3456. #if (PASSTHROUGH != DEVICEDATA)
  3457. #error PASSTHROUGH != DEVICEDATA
  3458. #endif
  3459. iRet = ExtEscape
  3460. (
  3461. hdc,
  3462. PASSTHROUGH,
  3463. (int) (*((UNALIGNED USHORT *) pvIn))+sizeof(WORD),
  3464. pvIn,
  3465. 0,
  3466. (LPSTR) NULL
  3467. );
  3468. bFixUp = TRUE;
  3469. break;
  3470. case NEWFRAME:
  3471. if (pldc->fl & LDC_CALL_STARTPAGE)
  3472. StartPage(hdc);
  3473. // If no error occured in EndPage, call StartPage next time.
  3474. if ((iRet = EndPage(hdc)) > 0)
  3475. pldc->fl |= LDC_CALL_STARTPAGE;
  3476. bFixUp = TRUE;
  3477. break;
  3478. case NEXTBAND:
  3479. // Win31 compatibility flags.
  3480. // GACF_MULTIPLEBANDS: Freelance thinks the first full-page band is
  3481. // a text-only band. So it ignores it and waits
  3482. // for the next band to print graphics. We'll
  3483. // return the full-page band twice for each page.
  3484. // The first band will be ignored while the second
  3485. // band really contains graphics to print.
  3486. // This flag only affects dotmatrix on win31.
  3487. // GACF_FORCETEXTBAND: World Perfect and Freelance both have assumptions
  3488. // on whether a band is text-only or not. They
  3489. // print text and graphics in different bands.
  3490. // We'll return two full-page bands for each page.
  3491. // One for text and the other for graphics.
  3492. // This flag only affects laser jet on win31.
  3493. if (pldc->fl & LDC_NEXTBAND)
  3494. {
  3495. if (GetAppCompatFlags(NULL) & (GACF_FORCETEXTBAND|GACF_MULTIPLEBANDS))
  3496. {
  3497. if (pldc->fl & LDC_EMPTYBAND)
  3498. {
  3499. pldc->fl &= ~LDC_EMPTYBAND;
  3500. }
  3501. else
  3502. {
  3503. pldc->fl |= LDC_EMPTYBAND;
  3504. goto FULLPAGEBAND;
  3505. }
  3506. }
  3507. ((UNALIGNED RECT *)pvOut)->left = ((UNALIGNED RECT *)pvOut)->top =
  3508. ((UNALIGNED RECT *)pvOut)->right = ((UNALIGNED RECT *)pvOut)->bottom = 0;
  3509. pldc->fl &= ~LDC_NEXTBAND; // Clear NextBand flag.
  3510. if (pldc->fl & LDC_CALL_STARTPAGE)
  3511. StartPage(hdc);
  3512. if ((iRet = EndPage(hdc)) > 0)
  3513. {
  3514. pldc->fl |= LDC_CALL_STARTPAGE;
  3515. //
  3516. // Marks application is doing banding by themselves,
  3517. // then EndPage() is called when there is no more band.
  3518. //
  3519. pldc->fl |= LDC_CALLED_ENDPAGE;
  3520. }
  3521. bFixUp = TRUE;
  3522. }
  3523. else
  3524. {
  3525. FULLPAGEBAND:
  3526. ((UNALIGNED RECT *)pvOut)->left = ((UNALIGNED RECT *)pvOut)->top = 0;
  3527. ((UNALIGNED RECT *)pvOut)->right = GetDeviceCaps(hdc, HORZRES);
  3528. ((UNALIGNED RECT *)pvOut)->bottom = GetDeviceCaps(hdc, VERTRES);
  3529. pldc->fl |= LDC_NEXTBAND; // Set NextBand flag.
  3530. iRet = 1;
  3531. }
  3532. break;
  3533. default:
  3534. iRet = 0;
  3535. break;
  3536. }
  3537. // Fix up the return values for STARTDOC and PASSTHROUGH so we're
  3538. // win31 compatible.
  3539. if (bFixUp && (iRet < 0))
  3540. {
  3541. if (pldc->fl & LDC_DOC_CANCELLED)
  3542. {
  3543. iRet = SP_APPABORT;
  3544. }
  3545. else
  3546. {
  3547. switch(GetLastError())
  3548. {
  3549. case ERROR_PRINT_CANCELLED:
  3550. iRet = SP_USERABORT;
  3551. break;
  3552. case ERROR_NOT_ENOUGH_MEMORY:
  3553. iRet = SP_OUTOFMEMORY;
  3554. break;
  3555. case ERROR_DISK_FULL:
  3556. iRet = SP_OUTOFDISK;
  3557. break;
  3558. default:
  3559. iRet = SP_ERROR;
  3560. break;
  3561. }
  3562. }
  3563. }
  3564. }
  3565. else
  3566. {
  3567. // We don't support this escape on this DC, but CorelDRAW expects
  3568. // some non-random values back anyway. Zero the output buffer to
  3569. // keep it happy.
  3570. if ((iEscape == GETSCALINGFACTOR) && pvOut)
  3571. {
  3572. RtlZeroMemory(pvOut, sizeof(POINT));
  3573. }
  3574. }
  3575. return(iRet);
  3576. }
  3577. /******************************Public*Routine******************************\
  3578. * ExtEscape *
  3579. * *
  3580. * History: *
  3581. * 14-Feb-1992 -by- Dave Snipp [DaveSn] *
  3582. * Wrote it. *
  3583. \**************************************************************************/
  3584. #define BUFSIZE 520
  3585. int WINAPI ExtEscape(
  3586. HDC hdc, // Identifies the device context.
  3587. int iEscape, // Specifies the escape function to be performed.
  3588. int cjInput, // Number of bytes of data pointed to by lpInData
  3589. LPCSTR lpInData, // Points to the input structure required
  3590. int cjOutput, // Number of bytes of data pointed to by lpOutData
  3591. LPSTR lpOutData // Points to the structure to receive output from
  3592. ) // this escape.
  3593. {
  3594. int iRet = 0;
  3595. int cjIn, cjOut, cjData;
  3596. PLDC pldc;
  3597. XFORM xf;
  3598. // We need some extra buffer space for at least one call. I'm going to
  3599. // hard code it here. The slickest thing would be to have a separate
  3600. // routine that knows how to alloc this space out of the memory window,
  3601. // but that would be more complex. I'm rushed. Sorry. [chuckwh]
  3602. BYTE jBuffer[BUFSIZE];
  3603. // We want to make this escape work just like it does in Windows which means
  3604. // that if there is a TrueType font in the DC GDI will compute it otherwise
  3605. // we'll pass the escape to the driver. So we call off to GetETM here because
  3606. // it does just that.
  3607. FIXUP_HANDLE(hdc);
  3608. if( iEscape == GETEXTENDEDTEXTMETRICS )
  3609. {
  3610. if( GetETM( hdc, (EXTTEXTMETRIC*) jBuffer ) )
  3611. {
  3612. RtlCopyMemory( lpOutData, jBuffer, MIN(cjOutput,sizeof(EXTTEXTMETRIC)) );
  3613. return(1);
  3614. }
  3615. else
  3616. {
  3617. return(0);
  3618. }
  3619. }
  3620. else if (iEscape == DRAWPATTERNRECT)
  3621. {
  3622. if (GetAppCompatFlags2(VER40) & GACF2_NODRAWPATRECT)
  3623. {
  3624. // GACF_NODRAWPATRECT -
  3625. //
  3626. // Some of application does not work with DrawPatRect escape,
  3627. // so that we behave as we don't support it.
  3628. //
  3629. return (0);
  3630. }
  3631. if (!cjInput)
  3632. {
  3633. //
  3634. // work around 32 bits Excel (with Ofiice 97) bug.
  3635. //
  3636. cjInput = sizeof(DRAWPATRECT);
  3637. }
  3638. }
  3639. else if (iEscape == QUERYESCSUPPORT)
  3640. {
  3641. if (*(ULONG*)lpInData == GETPAIRKERNTABLE)
  3642. {
  3643. // intercept GETPAIRKERNTABLE escape on the client side where all the work is done
  3644. // It is interesting that this "api" works on win95 not only for device fonts but
  3645. // also for engine fonts. Therefore this needs to be outside of
  3646. // the IS_ALTDC_TYPE(hdc) clause below
  3647. return (1);
  3648. }
  3649. else if (*(ULONG*)lpInData == DRAWPATTERNRECT)
  3650. {
  3651. if (GetAppCompatFlags2(VER40) & GACF2_NODRAWPATRECT)
  3652. {
  3653. // GACF_NODRAWPATRECT -
  3654. //
  3655. // Some of application does not work with DrawPatRect escape,
  3656. // so that we behave as we don't support it.
  3657. //
  3658. return (0);
  3659. }
  3660. }
  3661. }
  3662. else if (iEscape == GETPAIRKERNTABLE)
  3663. {
  3664. return GetPairKernTable(hdc, (DWORD)cjOutput, (KERNPAIR *)lpOutData);
  3665. }
  3666. // printer specific stuff
  3667. if (IS_ALTDC_TYPE(hdc))
  3668. {
  3669. PLDC pldc;
  3670. // don't allow them 16bit metafiles
  3671. if (IS_METADC16_TYPE(hdc))
  3672. return (0);
  3673. DC_PLDC(hdc,pldc,iRet);
  3674. MFD2("ExtEscapeCalled %d\n", iEscape );
  3675. if (pldc->fl & (LDC_DOC_CANCELLED|LDC_SAP_CALLBACK))
  3676. {
  3677. if (pldc->fl & LDC_SAP_CALLBACK)
  3678. vSAPCallback(pldc);
  3679. if (pldc->fl & LDC_DOC_CANCELLED)
  3680. return(0);
  3681. }
  3682. // if it is an output call that requires no return results, better make sure
  3683. // we do a start page.
  3684. if (( iEscape == DOWNLOADFACE ) ||
  3685. ( iEscape == GETFACENAME ) ||
  3686. ( iEscape == POSTSCRIPT_DATA ) ||
  3687. ( iEscape == BEGIN_PATH ) ||
  3688. ( iEscape == END_PATH ) ||
  3689. ( iEscape == CLIP_TO_PATH ) ||
  3690. ( iEscape == PASSTHROUGH ) ||
  3691. ( iEscape == DOWNLOADHEADER ))
  3692. {
  3693. if (pldc->fl & LDC_CALL_STARTPAGE)
  3694. StartPage(hdc);
  3695. }
  3696. if ((pldc->iType == LO_METADC) && (pldc->fl & LDC_META_PRINT))
  3697. {
  3698. // These two escapes should be called *before* StartDoc, any these escape
  3699. // called *after* StartDoc will be failed when EMF is used (see SDK)
  3700. if ((iEscape == POSTSCRIPT_IDENTIFY) || (iEscape == POSTSCRIPT_INJECTION))
  3701. {
  3702. WARNING("GDI32: ExtEscape() PSInjection after StartDoc with EMF, is ignored\n");
  3703. SetLastError(ERROR_INVALID_PARAMETER);
  3704. return (0);
  3705. }
  3706. // These escapes will not be recorded into metafile
  3707. //
  3708. // SETCOPYCOUNT - will be handled in kernel for EMF spooling case.
  3709. // and this will be recorded in DEVMODE.dmCopies.
  3710. //
  3711. // QUERYSUPPORT - will be handled in driver even EMF spooling case,
  3712. // since only driver knows which escape support it.
  3713. // and this is nothing for drawing, so not nessesary
  3714. // to record it.
  3715. //
  3716. // CHECKJPEGFORMAT & CHECKPNGFORMAT
  3717. // - query escapes that do not need to be reocorded
  3718. // into metafile.
  3719. //
  3720. if ((iEscape != SETCOPYCOUNT) && (iEscape != QUERYESCSUPPORT) &&
  3721. (iEscape != CHECKJPEGFORMAT) && (iEscape != CHECKPNGFORMAT))
  3722. {
  3723. BOOL bSetXform = FALSE;
  3724. // Write this escape to metafile.
  3725. //
  3726. // If there's transform set in the hdc by the app
  3727. // at the time of DRAWPATRECT, select identity transform in
  3728. // once the escape is recorded, select back the original transform
  3729. //
  3730. if (GetWorldTransform(hdc, &xf))
  3731. {
  3732. if ((xf.eM11 != 1.0f) || (xf.eM22 != 1.0f) ||
  3733. (xf.eM12 != 0.0f) || (xf.eM21 != 0.0f))
  3734. {
  3735. bSetXform = TRUE;
  3736. MF_ModifyWorldTransform(hdc,&xformIdentity,MWT_SET);
  3737. }
  3738. }
  3739. MF_WriteEscape( hdc, iEscape, cjInput, lpInData, EMR_EXTESCAPE );
  3740. if (bSetXform)
  3741. {
  3742. MF_ModifyWorldTransform(hdc,&xf,MWT_SET);
  3743. }
  3744. if ((lpOutData == (LPSTR) NULL) || (cjOutput == 0))
  3745. {
  3746. if ((iEscape == PASSTHROUGH) ||
  3747. (iEscape == POSTSCRIPT_PASSTHROUGH) ||
  3748. (iEscape == POSTSCRIPT_DATA))
  3749. {
  3750. if ((cjInput < (int)sizeof(WORD)) ||
  3751. (cjInput < (int)sizeof(WORD) + *((LPWORD) lpInData)))
  3752. {
  3753. SetLastError(ERROR_INVALID_PARAMETER);
  3754. return -1;
  3755. }
  3756. cjInput = *((LPWORD) lpInData);
  3757. }
  3758. return(MAX(cjInput,1));
  3759. }
  3760. }
  3761. MFD2("ExtEscape goes to gre/driver Escape(%d) with EMF printing\n", iEscape);
  3762. }
  3763. if ((iEscape == DOWNLOADFACE) || (iEscape == GETFACENAME))
  3764. {
  3765. if (iEscape == DOWNLOADFACE)
  3766. {
  3767. // Adjust the buffer for the DOWNLOADFACE case. Note that lpOutData
  3768. // points at an input word for the mode.
  3769. if ((gpwcANSICharSet == (WCHAR *) NULL) && !bGetANSISetMap())
  3770. {
  3771. return(0);
  3772. }
  3773. RtlMoveMemory
  3774. (
  3775. jBuffer + sizeof(WCHAR),
  3776. (BYTE *) &gpwcANSICharSet[0],
  3777. 256*sizeof(WCHAR)
  3778. );
  3779. if (lpOutData)
  3780. *(WCHAR *) jBuffer = *(UNALIGNED WORD *) lpOutData;
  3781. else
  3782. *(WCHAR *) jBuffer = 0;
  3783. cjInput = 257 * sizeof(WCHAR);
  3784. lpInData = (LPCSTR) jBuffer;
  3785. ASSERTGDI(BUFSIZE >= cjInput,"Buffer too small.\n");
  3786. }
  3787. }
  3788. if ((iEscape == POSTSCRIPT_INJECTION) || (iEscape == POSTSCRIPT_IDENTIFY))
  3789. {
  3790. // Remember escape data for EMF spooling case. (only BEFORE StartDoc)
  3791. if (!(pldc->fl & LDC_DOC_STARTED))
  3792. {
  3793. PPS_INJECTION_DATA pPSInjection;
  3794. ULONG cjCellSize;
  3795. if( BROUNDUP_DWORDALIGN_OVERFLOW(
  3796. (sizeof(PS_INJECTION_DATA)-1)+cjInput) )
  3797. return 0;
  3798. cjCellSize =
  3799. ROUNDUP_DWORDALIGN((sizeof(PS_INJECTION_DATA)-1)+cjInput);
  3800. MFD2("ExtEscape records this Escape(%d) temporary then write EMF later\n",iEscape);
  3801. if ((pPSInjection = LOCALALLOC(cjCellSize)) != NULL)
  3802. {
  3803. cjCellSize -= offsetof(PS_INJECTION_DATA,EmfData);
  3804. // Fill up Injection Data.
  3805. pPSInjection->EmfData.cjSize = cjCellSize;
  3806. pPSInjection->EmfData.nEscape = iEscape;
  3807. pPSInjection->EmfData.cjInput = cjInput;
  3808. RtlCopyMemory(pPSInjection->EmfData.EscapeData,lpInData,cjInput);
  3809. // Put this on list.
  3810. InsertTailList(&(pldc->PSDataList),&(pPSInjection->ListEntry));
  3811. // Update total data size.
  3812. pldc->dwSizeOfPSDataToRecord += cjCellSize;
  3813. }
  3814. else
  3815. {
  3816. WARNING("ExtEscape: Failed on LOCALALLOC for POSTSCRIPT_xxxxx\n");
  3817. GdiSetLastError(ERROR_NOT_ENOUGH_MEMORY);
  3818. return (0);
  3819. }
  3820. }
  3821. }
  3822. // now call the drivers UI portion
  3823. if (pldc->hSpooler)
  3824. {
  3825. DOCEVENT_ESCAPE docEvent;
  3826. docEvent.iEscape = iEscape;
  3827. docEvent.cjInput = cjInput;
  3828. docEvent.pvInData = (PVOID)lpInData;
  3829. DocumentEventEx(pldc->pUMPD,
  3830. pldc->hSpooler,
  3831. hdc,
  3832. DOCUMENTEVENT_ESCAPE,
  3833. sizeof(docEvent),
  3834. (PVOID)&docEvent,
  3835. cjOutput,
  3836. (PVOID)lpOutData);
  3837. }
  3838. }
  3839. cjIn = (lpInData == NULL) ? 0 : cjInput;
  3840. cjOut = (lpOutData == NULL) ? 0 : cjOutput;
  3841. iRet = NtGdiExtEscape(hdc,NULL,0,iEscape,cjIn,(LPSTR)lpInData,cjOut,lpOutData);
  3842. return(iRet);
  3843. }
  3844. /******************************Public*Routine******************************\
  3845. * NamedEscape
  3846. *
  3847. * History:
  3848. * 5-Mar-1996 -by- Gerrit van Wingerden
  3849. * Wrote it.
  3850. \**************************************************************************/
  3851. #define BUFSIZE 520
  3852. int WINAPI NamedEscape(
  3853. HDC hdc, // Identifies the device context for EMF spooling
  3854. LPWSTR pwszDriver, // Identfies the driver
  3855. int iEscape, // Specifies the escape function to be performed.
  3856. int cjInput, // Number of bytes of data pointed to by lpInData
  3857. LPCSTR lpInData, // Points to the input structure required
  3858. int cjOutput, // Number of bytes of data pointed to by lpOutData
  3859. LPSTR lpOutData // Points to the structure to receive output from
  3860. ) // this escape.
  3861. {
  3862. int iRet = 0;
  3863. int cjIn, cjOut, cjData;
  3864. PLDC pldc;
  3865. if(hdc)
  3866. {
  3867. FIXUP_HANDLE(hdc);
  3868. // if we are EMF spooling then we need to record the call here
  3869. if (IS_ALTDC_TYPE(hdc))
  3870. {
  3871. PLDC pldc;
  3872. // don't allow them in 16bit metafiles
  3873. if (IS_METADC16_TYPE(hdc))
  3874. return(0);
  3875. DC_PLDC(hdc,pldc,iRet);
  3876. MFD2("NamedEscapeCalled %d\n", iEscape );
  3877. if (pldc->fl & (LDC_DOC_CANCELLED|LDC_SAP_CALLBACK))
  3878. {
  3879. if (pldc->fl & LDC_SAP_CALLBACK)
  3880. vSAPCallback(pldc);
  3881. if (pldc->fl & LDC_DOC_CANCELLED)
  3882. return(0);
  3883. }
  3884. if (pldc->iType == LO_METADC)
  3885. {
  3886. if(!MF_WriteNamedEscape(hdc,
  3887. pwszDriver,
  3888. iEscape,
  3889. cjInput,
  3890. lpInData))
  3891. {
  3892. WARNING("Error metafiling NameEscape\n");
  3893. return(0);
  3894. }
  3895. }
  3896. }
  3897. }
  3898. cjIn = (lpInData == NULL) ? 0 : cjInput;
  3899. cjOut = (lpOutData == NULL) ? 0 : cjOutput;
  3900. iRet = NtGdiExtEscape((HDC) 0,
  3901. pwszDriver,
  3902. wcslen(pwszDriver),
  3903. iEscape,cjIn,
  3904. (LPSTR)lpInData,
  3905. cjOut,lpOutData);
  3906. return(iRet);
  3907. }
  3908. /******************************Public*Routine******************************\
  3909. * DrawEscape *
  3910. * *
  3911. * Client side stub. *
  3912. * *
  3913. * History: *
  3914. * 02-Apr-1992 -by- Wendy Wu [wendywu] *
  3915. * Wrote it. *
  3916. \**************************************************************************/
  3917. int WINAPI DrawEscape(
  3918. HDC hdc, // Identifies the device context.
  3919. int iEscape, // Specifies the escape function to be performed.
  3920. int cjIn, // Number of bytes of data pointed to by lpIn.
  3921. LPCSTR lpIn // Points to the input data.
  3922. )
  3923. {
  3924. int iRet = 0;
  3925. int cjInput;
  3926. FIXUP_HANDLE(hdc);
  3927. // printer specific stuff
  3928. if (IS_ALTDC_TYPE(hdc))
  3929. {
  3930. PLDC pldc;
  3931. // don't allow them 16bit metafiles
  3932. if (IS_METADC16_TYPE(hdc))
  3933. return(0);
  3934. DC_PLDC(hdc,pldc,iRet);
  3935. MFD2("Calling DrawEscape %d\n", iEscape );
  3936. if( ( pldc->fl & LDC_META_PRINT ) && ( iEscape != QUERYESCSUPPORT ) )
  3937. {
  3938. MF_WriteEscape( hdc, iEscape, cjIn, lpIn, EMR_DRAWESCAPE );
  3939. }
  3940. }
  3941. // Compute the buffer size we need. Since the in and out buffers
  3942. // get rounded up to multiples of 4 bytes, we need to simulate that
  3943. // here.
  3944. cjInput = (lpIn == NULL) ? 0 : ((cjIn+3)&-4);
  3945. iRet = NtGdiDrawEscape(hdc,iEscape,cjIn,(LPSTR)lpIn);
  3946. return(iRet);
  3947. }
  3948. /******************************Public*Routine******************************\
  3949. * DeviceCapabilitiesExA
  3950. *
  3951. * This never got implemented. The spooler suports DeviceCapabilities.
  3952. *
  3953. * History:
  3954. * 01-Aug-1991 -by- Eric Kutter [erick]
  3955. * Wrote it.
  3956. \**************************************************************************/
  3957. int WINAPI DeviceCapabilitiesExA(
  3958. LPCSTR pszDriver,
  3959. LPCSTR pszDevice,
  3960. LPCSTR pszPort,
  3961. int iIndex,
  3962. LPCSTR pb,
  3963. CONST DEVMODEA *pdm)
  3964. {
  3965. return(GDI_ERROR);
  3966. pszDriver;
  3967. pszDevice;
  3968. pszPort;
  3969. iIndex;
  3970. pb;
  3971. pdm;
  3972. }
  3973. /**************************************************************************\
  3974. *
  3975. * New to be implemented Api's for Windows95.
  3976. *
  3977. \**************************************************************************/
  3978. #if 0
  3979. WINGDIAPI int WINAPI GetTextCharsetInfo(
  3980. HDC hdc,
  3981. LPFONTSIGNATURE lpSig,
  3982. DWORD dwFlags)
  3983. {
  3984. return NtGdiGetTextCharsetInfo(hdc, lpSig, dwFlags);
  3985. }
  3986. #endif
  3987. WINGDIAPI int WINAPI GetTextCharset(
  3988. HDC hdc)
  3989. {
  3990. return NtGdiGetTextCharsetInfo(hdc, NULL, 0);
  3991. }
  3992. /******************************Public*Routine******************************\
  3993. *
  3994. * WINGDIAPI BOOL WINAPI TranslateCharsetInfo(
  3995. *
  3996. * client side stub
  3997. *
  3998. * History:
  3999. * 06-Jan-1995 -by- Bodin Dresevic [BodinD]
  4000. * Wrote it
  4001. \**************************************************************************/
  4002. // the definition of this variable is in ntgdi\inc\hmgshare.h
  4003. CHARSET_ARRAYS
  4004. WINGDIAPI BOOL WINAPI TranslateCharsetInfo(
  4005. DWORD *lpSrc,
  4006. LPCHARSETINFO lpCs,
  4007. DWORD dwFlags)
  4008. {
  4009. UINT i;
  4010. int index;
  4011. CHARSETINFO cs;
  4012. BOOL bRet = 0;
  4013. if (!lpCs)
  4014. return 0;
  4015. //
  4016. // zero these out, we dont support them here.
  4017. //
  4018. cs.fs.fsUsb[0] =
  4019. cs.fs.fsUsb[1] =
  4020. cs.fs.fsUsb[2] =
  4021. cs.fs.fsUsb[3] =
  4022. cs.fs.fsCsb[1] = 0;
  4023. switch (dwFlags )
  4024. {
  4025. case TCI_SRCCHARSET :
  4026. {
  4027. WORD src ;
  4028. src = LOWORD(PtrToUlong(lpSrc));
  4029. for ( i=0; i<NCHARSETS; i++ )
  4030. {
  4031. if ( charsets[i] == src )
  4032. {
  4033. cs.ciACP = codepages[i];
  4034. cs.ciCharset = src;
  4035. cs.fs.fsCsb[0] = fs[i];
  4036. bRet = 1;
  4037. break;
  4038. }
  4039. }
  4040. }
  4041. break;
  4042. case TCI_SRCCODEPAGE :
  4043. {
  4044. WORD src ;
  4045. src = LOWORD(PtrToUlong(lpSrc));
  4046. for ( i=0; i<NCHARSETS; i++ )
  4047. {
  4048. if ( codepages[i] == src )
  4049. {
  4050. cs.ciACP = src ;
  4051. cs.ciCharset = charsets[i] ;
  4052. cs.fs.fsCsb[0] = fs[i];
  4053. bRet = 1;
  4054. break;
  4055. }
  4056. }
  4057. }
  4058. break;
  4059. case TCI_SRCLOCALE :
  4060. {
  4061. // should only come from USER. It's used to find the charset of a
  4062. // keyboard layout, and the fonts that it can be used with (fontsigs).
  4063. // It is also used to obtain the fontsignature of the system font.
  4064. // Used in WM_INPUTLANGCHANGE message, and to determine wParam low-bit
  4065. // in WM_INPUTLANGCHANGEREQUEST message.
  4066. LOCALESIGNATURE ls;
  4067. int iRet;
  4068. iRet = GetLocaleInfoW((DWORD)(LOWORD(PtrToUlong(lpSrc))),
  4069. LOCALE_FONTSIGNATURE,
  4070. (LPWSTR)&ls,
  4071. 0);
  4072. if (GetLocaleInfoW((DWORD)(LOWORD(PtrToUlong(lpSrc))),
  4073. LOCALE_FONTSIGNATURE,
  4074. (LPWSTR)&ls,
  4075. iRet)
  4076. )
  4077. {
  4078. for ( i=0; i<NCHARSETS; i++ )
  4079. {
  4080. if (fs[i] == ls.lsCsbDefault[0])
  4081. {
  4082. cs.ciACP = codepages[i];
  4083. cs.ciCharset = charsets[i] ;
  4084. cs.fs.fsCsb[0] = fs[i]; // a single fontsig
  4085. cs.fs.fsCsb[1] = ls.lsCsbSupported[0]; // mask of fontsigs
  4086. bRet = 1;
  4087. break;
  4088. }
  4089. }
  4090. }
  4091. }
  4092. break;
  4093. case TCI_SRCFONTSIG :
  4094. {
  4095. DWORD src;
  4096. //if(IsBadReadPtr(lpSrc, 8))
  4097. // return 0;
  4098. try
  4099. {
  4100. if (!(*(lpSrc+1)))
  4101. {
  4102. // we dont recognise ANY of the OEM code pages here!
  4103. src = *lpSrc;
  4104. for ( i=0; i<NCHARSETS; i++ )
  4105. {
  4106. if ( fs[i] == src )
  4107. {
  4108. cs.ciACP = codepages[i];
  4109. cs.ciCharset = charsets[i] ;
  4110. cs.fs.fsCsb[0] = src;
  4111. bRet = 1;
  4112. break;
  4113. }
  4114. }
  4115. }
  4116. }
  4117. except(EXCEPTION_EXECUTE_HANDLER)
  4118. {
  4119. }
  4120. }
  4121. break;
  4122. default:
  4123. GdiSetLastError(ERROR_INVALID_PARAMETER);
  4124. break;
  4125. }
  4126. if (bRet)
  4127. {
  4128. try
  4129. {
  4130. *lpCs = cs; // copy out
  4131. }
  4132. except(EXCEPTION_EXECUTE_HANDLER)
  4133. {
  4134. }
  4135. }
  4136. return bRet;
  4137. }