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.

2056 lines
64 KiB

  1. //-----------------------------------------------------------------------------
  2. // This files contains the module name for this mini driver. Each mini driver
  3. // must have a unique module name. The module name is used to obtain the
  4. // module handle of this Mini Driver. The module handle is used by the
  5. // generic library to load in tables from the Mini Driver.
  6. //-----------------------------------------------------------------------------
  7. /*++
  8. Copyright (c) 1996-1999 Microsoft Corporation
  9. Module Name:
  10. fxartres.c
  11. Abstract:
  12. Implementation of GPD command callback for "test.gpd":
  13. OEMCommandCallback
  14. Environment:
  15. Windows NT Unidrv driver
  16. Revision History:
  17. 04/07/97 -zhanw-
  18. Created it.
  19. --*/
  20. // NTRAID#NTBUG9-552017-2002/03/12-yasuho-: Use strsafe.h/PREFAST/buffy
  21. // NTRAID#NTBUG9-572151-2002/03/12-yasuho-: Possible buffer overrun.
  22. // NTRAID#NTBUG9-572152-2002/03/12-yasuho-: Remove the dead code.
  23. #include "pdev.h"
  24. #define FX_VERBOSE VERBOSE
  25. // NTRAID#NTBUG9-493148-2002/03/12-yasuho-:
  26. // Stress break: PDEV resetting via OEMDevMode().
  27. /*
  28. * OEMEnablePDEV
  29. */
  30. PDEVOEM APIENTRY
  31. OEMEnablePDEV(
  32. PDEVOBJ pdevobj,
  33. PWSTR pPrinterName,
  34. ULONG cPatterns,
  35. HSURF *phsurfPatterns,
  36. ULONG cjGdiInfo,
  37. GDIINFO *pGdiInfo,
  38. ULONG cjDevInfo,
  39. DEVINFO *pDevInfo,
  40. DRVENABLEDATA *pded)
  41. {
  42. PFXPDEV pOEM;
  43. if(!pdevobj->pdevOEM)
  44. {
  45. if(!(pdevobj->pdevOEM = MemAllocZ(sizeof(FXPDEV))))
  46. {
  47. ERR(("Failed to allocate pdev"));
  48. return NULL;
  49. }
  50. }
  51. pOEM = (PFXPDEV)pdevobj->pdevOEM;
  52. // Initialize private data
  53. pOEM->ptlOrg.x = 0;
  54. pOEM->ptlOrg.y = 0;
  55. pOEM->sizlRes.cx = 0;
  56. pOEM->sizlRes.cy = 0;
  57. pOEM->sizlUnit.cx = 1;
  58. pOEM->sizlUnit.cy = 1;
  59. pOEM->iCopies = 0;
  60. pOEM->bString = FALSE;
  61. pOEM->cFontId = 0;
  62. pOEM->iFontId = 0;
  63. pOEM->iFontHeight = 0;
  64. pOEM->iFontWidth = 0;
  65. pOEM->iFontWidth2 = 0;
  66. pOEM->ptlTextCur.x = 0;
  67. pOEM->ptlTextCur.y = 0;
  68. pOEM->iTextFontId = 0;
  69. pOEM->iTextFontHeight = 0;
  70. pOEM->iTextFontWidth = 0;
  71. pOEM->iTextFontWidth2 = 0;
  72. pOEM->cTextBuf = 0;
  73. pOEM->fFontSim = 0;
  74. pOEM->fCallback = FALSE;
  75. pOEM->fPositionReset = TRUE;
  76. pOEM->fSort = FALSE;
  77. pOEM->iCurFontId = 0;
  78. // NTRAID#NTBUG9-365649-2002/03/12-yasuho-: Invalid font size
  79. pOEM->iCurFontHeight = 0;
  80. pOEM->iCurFontWidth = 0;
  81. // For internal calculation of X-pos.
  82. pOEM->lInternalXAdd = 0;
  83. // For TIFF compression in fxartres
  84. if( !(pOEM->pTiffCompressBuf =(PBYTE)MemAllocZ(TIFFCOMPRESSBUFSIZE)) )
  85. {
  86. ERR(("MemAlloc failed.\n"));
  87. return NULL;
  88. }
  89. pOEM->dwTiffCompressBufSize = TIFFCOMPRESSBUFSIZE;
  90. // Intialize another private buffers
  91. ZeroMemory(pOEM->widBuf, sizeof(pOEM->widBuf));
  92. ZeroMemory(pOEM->ajTextBuf, sizeof(pOEM->ajTextBuf));
  93. ZeroMemory(pOEM->aFontId, sizeof(pOEM->aFontId));
  94. // NTRAID#NTBUG9-208433-2002/03/12-yasuho-:
  95. // Output images are broken on ART2/3 models.
  96. pOEM->bART3 = FALSE;
  97. return pdevobj->pdevOEM;
  98. }
  99. /*
  100. * OEMDisablePDEV
  101. */
  102. VOID APIENTRY
  103. OEMDisablePDEV(
  104. PDEVOBJ pdevobj)
  105. {
  106. PFXPDEV pOEM;
  107. if(pOEM = (PFXPDEV)pdevobj->pdevOEM)
  108. {
  109. if (pOEM->pTiffCompressBuf) {
  110. MemFree(pOEM->pTiffCompressBuf);
  111. pOEM->pTiffCompressBuf = NULL;
  112. pOEM->dwTiffCompressBufSize = 0;
  113. }
  114. MemFree(pdevobj->pdevOEM);
  115. pdevobj->pdevOEM = NULL;
  116. }
  117. }
  118. /*
  119. * OEMResetPDEV
  120. */
  121. BOOL APIENTRY OEMResetPDEV(
  122. PDEVOBJ pdevobjOld,
  123. PDEVOBJ pdevobjNew)
  124. {
  125. PFXPDEV pOEMOld = (PFXPDEV)pdevobjOld->pdevOEM;
  126. PFXPDEV pOEMNew = (PFXPDEV)pdevobjNew->pdevOEM;
  127. if (pOEMOld != NULL && pOEMNew != NULL) {
  128. //
  129. // copy over the private fields, if they are valid
  130. //
  131. // Copy private data
  132. pOEMNew->ptlOrg.x = pOEMOld->ptlOrg.x;
  133. pOEMNew->ptlOrg.y = pOEMOld->ptlOrg.y;
  134. pOEMNew->sizlRes.cx = pOEMOld->sizlRes.cx;
  135. pOEMNew->sizlRes.cy = pOEMOld->sizlRes.cy;
  136. pOEMNew->sizlUnit.cx = pOEMOld->sizlUnit.cx;
  137. pOEMNew->sizlUnit.cy = pOEMOld->sizlUnit.cy;
  138. pOEMNew->iCopies = pOEMOld->iCopies;
  139. pOEMNew->bString = pOEMOld->bString;
  140. pOEMNew->cFontId = pOEMOld->cFontId;
  141. pOEMNew->iFontId = pOEMOld->iFontId;
  142. pOEMNew->iFontHeight = pOEMOld->iFontHeight;
  143. pOEMNew->iFontWidth = pOEMOld->iFontWidth;
  144. pOEMNew->iFontWidth2 = pOEMOld->iFontWidth2;
  145. pOEMNew->ptlTextCur.x = pOEMOld->ptlTextCur.x;
  146. pOEMNew->ptlTextCur.y = pOEMOld->ptlTextCur.y;
  147. pOEMNew->iTextFontId = pOEMOld->iTextFontId;
  148. pOEMNew->iTextFontHeight = pOEMOld->iTextFontHeight;
  149. pOEMNew->iTextFontWidth = pOEMOld->iTextFontWidth;
  150. pOEMNew->iTextFontWidth2 = pOEMOld->iTextFontWidth2;
  151. pOEMNew->cTextBuf = pOEMOld->cTextBuf;
  152. pOEMNew->fFontSim = pOEMOld->fFontSim;
  153. pOEMNew->fCallback = pOEMOld->fCallback;
  154. pOEMNew->fPositionReset = pOEMOld->fPositionReset;
  155. pOEMNew->fSort = pOEMOld->fSort;
  156. pOEMNew->iCurFontId = pOEMOld->iCurFontId;
  157. // NTRAID#NTBUG9-365649-2002/03/12-yasuho-: Invalid font size
  158. pOEMNew->iCurFontHeight = pOEMOld->iCurFontHeight;
  159. pOEMNew->iCurFontWidth = pOEMOld->iCurFontWidth;
  160. // For internal calculation of X-pos.
  161. pOEMNew->lInternalXAdd = pOEMOld->lInternalXAdd;
  162. memcpy((PBYTE)pOEMNew->widBuf, (PBYTE)pOEMOld->widBuf, sizeof(pOEMNew->widBuf));
  163. // Copy private buffer
  164. pOEMNew->chOrient = pOEMOld->chOrient;
  165. pOEMNew->chSize = pOEMOld->chSize;
  166. memcpy((PBYTE)pOEMNew->aFontId, (PBYTE)pOEMOld->aFontId, sizeof(pOEMNew->aFontId));
  167. memcpy((PBYTE)pOEMNew->ajTextBuf, (PBYTE)pOEMOld->ajTextBuf, sizeof(pOEMNew->ajTextBuf));
  168. }
  169. return TRUE;
  170. }
  171. // #######
  172. #define WRITESPOOLBUF(p, s, n) \
  173. ((p)->pDrvProcs->DrvWriteSpoolBuf(p, s, n))
  174. #define PARAM(p,n) \
  175. (*((p)+(n)))
  176. #define DEVICE_MASTER_UNIT 7200
  177. #define DRIVER_MASTER_UNIT 1200
  178. // @Aug/31/98 ->
  179. #define MAX_COPIES_VALUE 99
  180. // @Aug/31/98 <-
  181. #define MAX_COPIES_VALUE_450 999
  182. #define FONT_SIM_ITALIC 1
  183. #define FONT_SIM_BOLD 2
  184. #define FONT_SIM_WHITE 4
  185. // to get physical paper sizes.
  186. typedef struct tagMYFORMS {
  187. CHAR *id;
  188. LONG x;
  189. LONG y;
  190. } MYFORMS, *LPMYFORMS;
  191. // font name to font id mappnig
  192. typedef struct tagMYFONTS {
  193. LONG id;
  194. BYTE *fid1;
  195. BYTE *fid2;
  196. } MYFONTS, *LPMYFONTS;
  197. //
  198. // Load necessary information for specified paper size.
  199. // Make sure PC_OCD_LANDSCAPE and PC_OCD_PORTRAIT are
  200. // called.
  201. //
  202. MYFORMS gForms[] = {
  203. "a3", 13608, 19422,
  204. "a4", 9498, 13608,
  205. "a5", 6570, 9498,
  206. "a6", 4515, 6570,
  207. "b4", 11718, 16776,
  208. "b5", 8178, 11718,
  209. "b6", 5648, 8178,
  210. "pc", 4302, 6570, // Postcard
  211. "o0", 12780, 19980, // Tabloid
  212. "o1", 9780, 12780, // Letter
  213. "o2", 9780, 15180, // German Legal Fanfold
  214. "o3", 9780, 16380, // Legal
  215. "s1", 4530, 10962, // (Env) Comm 10
  216. "s2", 4224, 8580, // (Env) Monarch
  217. "s3", 4776, 9972, // (Env) DL
  218. "s4", 7230, 10398, // (Env) C5
  219. "hl", 6390, 9780, // Statement
  220. NULL, 0, 0
  221. };
  222. MYFONTS gFonts[MAX_FONTS] = {
  223. 150, "fid 150 1 0 0 960 480\n", "fid 151 2 4 0 960 960\n", // Mincho
  224. 156, "fid 156 1 0 0 960 480\n", "fid 157 2 5 0 960 960\n", // @Mincho
  225. 152, "fid 152 1 0 1 960 480\n", "fid 153 2 4 1 960 960\n", // Gothic
  226. 158, "fid 158 1 0 1 960 480\n", "fid 159 2 5 1 960 960\n", // @Gothic
  227. 154, "fid 154 1 0 8 960 480\n", "fid 155 2 4 2 960 960\n", // Maru-Gothic
  228. 160, "fid 160 1 0 8 960 480\n", "fid 161 2 5 2 960 960\n", // @Maru-Gothic
  229. 162, "fid 162 1 130 108 0 0\n", "fid 163 1 128 108 0 0\n", // CS Courier
  230. 164, "fid 164 1 130 109 0 0\n", "fid 165 1 128 109 0 0\n", // CS Courier Italic
  231. 166, "fid 166 1 130 110 0 0\n", "fid 167 1 128 110 0 0\n", // CS Courier Bold
  232. 168, "fid 168 1 130 111 0 0\n", "fid 169 1 128 111 0 0\n", // CS Courier Bold Italic
  233. 172, "fid 172 1 130 100 0 0\n", "fid 173 1 128 100 0 0\n", // CS Times
  234. 174, "fid 174 1 130 102 0 0\n", "fid 175 1 128 102 0 0\n", // CS Times Bold
  235. 176, "fid 176 1 130 101 0 0\n", "fid 177 1 128 101 0 0\n", // CS Times Italic
  236. 178, "fid 178 1 130 103 0 0\n", "fid 179 1 128 103 0 0\n", // CS Times Bold Italic
  237. 180, "fid 180 1 130 104 0 0\n", "fid 181 1 128 104 0 0\n", // CS Triumvirate
  238. 182, "fid 182 1 130 106 0 0\n", "fid 183 1 128 106 0 0\n", // CS Triumvirate Bold
  239. 184, "fid 184 1 130 105 0 0\n", "fid 185 1 128 105 0 0\n", // CS Triumvirate Italic
  240. 186, "fid 186 1 130 107 0 0\n", "fid 187 1 128 107 0 0\n", // CS Triumvirate Bold Italic
  241. 188, "fid 188 1 129 112 0 0\n", NULL, // CS Symbols
  242. 189, "fid 189 1 2 6 0 0\n", NULL, // Enhanced Classic
  243. 190, "fid 190 1 2 7 0 0\n", NULL, // Enhanced Modern
  244. // Assume there is no device which has both Typebank and Heisei
  245. // typefaces, we re-use FID #s here.
  246. 150, "fid 150 1 0 0 960 480\n", "fid 151 2 4 0 960 960\n", // (Heisei) Mincho
  247. 156, "fid 156 1 0 0 960 480\n", "fid 157 2 5 0 960 960\n", // (Heisei) @Mincho
  248. 152, "fid 152 1 0 1 960 480\n", "fid 153 2 4 1 960 960\n", // (Heisei) Gothic
  249. 158, "fid 158 1 0 1 960 480\n", "fid 159 2 5 1 960 960\n", // (Heisei) @Gothic
  250. };
  251. #define ISDBCSFONT(i) ((i) < 162)
  252. #define ISVERTFONT(i) ((i) >= 156 && (i) < 162)
  253. #define ISPROPFONT(i) ((i) >= 172 && (i) < 190)
  254. #define MARK_ALT_GSET 0x01
  255. #define BISMARKSBCS(i) ((i) >= 0 && (i) < 0x20)
  256. BOOL
  257. LoadPaperInfo(
  258. PFXPDEV pOEM,
  259. CHAR *id ) {
  260. LPMYFORMS ptmp;
  261. for ( ptmp = gForms; ptmp->id; ptmp++ ) {
  262. if ( strcmp( id, ptmp->id) == 0 )
  263. break;
  264. }
  265. if ( ptmp->id == NULL )
  266. return FALSE;
  267. FX_VERBOSE(("PI: %s->%s\n", id, ptmp->id ));
  268. pOEM->chSize = ptmp->id;
  269. pOEM->ptlOrg.x = 0;
  270. if ( strcmp( pOEM->chOrient, "l") == 0 ){
  271. pOEM->ptlOrg.y = ptmp->x;
  272. }
  273. else {
  274. pOEM->ptlOrg.y = ptmp->y;
  275. }
  276. pOEM->ptlOrg.x += 210;
  277. pOEM->ptlOrg.y += 210;
  278. return TRUE;
  279. }
  280. #define TOHEX(j) ((j) < 10 ? ((j) + '0') : ((j) - 10 + 'a'))
  281. BOOL
  282. HexOutput(
  283. PDEVOBJ pdevobj,
  284. PBYTE pBuf,
  285. DWORD dwLen)
  286. {
  287. BYTE Buf[STRBUFSIZE];
  288. BYTE *pSrc, *pSrcMax;
  289. LONG iRet, j;
  290. pSrc = (BYTE *)pBuf;
  291. pSrcMax = pSrc + dwLen;
  292. iRet = 0;
  293. while ( pSrc < pSrcMax ) {
  294. for ( j = 0; j < sizeof(Buf)-1 && pSrc < pSrcMax; pSrc++ ) {
  295. BYTE c1, c2;
  296. c1 = (((*pSrc) >> 4) & 0x0f);
  297. c2 = (*pSrc & 0x0f);
  298. Buf[ j++ ] = TOHEX( c1 );
  299. Buf[ j++ ] = TOHEX( c2 );
  300. }
  301. if (WRITESPOOLBUF( pdevobj, Buf, j ) == 0)
  302. break;
  303. iRet += j;
  304. }
  305. return TRUE;
  306. }
  307. BOOL
  308. BeginString(
  309. PDEVOBJ pdevobj,
  310. BOOL bReset )
  311. {
  312. BYTE buf[512];
  313. PFXPDEV pOEM;
  314. BYTE *pbuf;
  315. size_t rem;
  316. pOEM = (PFXPDEV)pdevobj->pdevOEM;
  317. if (pOEM->bString)
  318. return TRUE;
  319. pbuf = buf;
  320. rem = sizeof buf;
  321. if ( bReset ) {
  322. FX_VERBOSE(("BS: %d(%d),%d(%d)\n",
  323. ( pOEM->ptlOrg.x + pOEM->ptlTextCur.x ),
  324. pOEM->ptlTextCur.x,
  325. ( pOEM->ptlOrg.y - pOEM->ptlTextCur.y ),
  326. pOEM->ptlTextCur.y));
  327. if (FAILED(StringCchPrintfExA(pbuf, rem, &pbuf, &rem, 0,
  328. "scp %d %d\n",
  329. ( pOEM->ptlOrg.x + pOEM->ptlTextCur.x ),
  330. ( pOEM->ptlOrg.y - pOEM->ptlTextCur.y ))))
  331. return FALSE;
  332. }
  333. if (FAILED(StringCchPrintfExA(pbuf, rem, &pbuf, &rem, 0,
  334. "sh <" )))
  335. return FALSE;
  336. if ( (pbuf - buf) > 0 ) {
  337. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  338. }
  339. pOEM->bString = TRUE;
  340. return TRUE;
  341. }
  342. BOOL
  343. EndString(
  344. PDEVOBJ pdevobj )
  345. {
  346. BYTE buf[512];
  347. PFXPDEV pOEM;
  348. PBYTE pbuf;
  349. pOEM = (PFXPDEV)pdevobj->pdevOEM;
  350. if (!pOEM->bString)
  351. return TRUE;
  352. pbuf = buf;
  353. if (FAILED(StringCchPrintfExA(pbuf, sizeof buf, &pbuf, NULL, 0,
  354. ">\n" )))
  355. return FALSE;
  356. if ( (DWORD)(pbuf - buf) > 0 ) {
  357. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  358. }
  359. pOEM->bString = FALSE;
  360. return TRUE;
  361. }
  362. BOOL
  363. BeginVertWrite(
  364. PDEVOBJ pdevobj )
  365. {
  366. BYTE buf[512];
  367. PFXPDEV pOEM;
  368. BYTE *pbuf;
  369. size_t rem;
  370. pOEM = (PFXPDEV)pdevobj->pdevOEM;
  371. pbuf = buf;
  372. rem = sizeof buf;
  373. if (FAILED(StringCchPrintfExA(pbuf, rem, &pbuf, &rem, 0,
  374. "fo 90\nsrcp %d 0\n", pOEM->iFontHeight)))
  375. return FALSE;
  376. if (pOEM->fFontSim & FONT_SIM_ITALIC) {
  377. if (FAILED(StringCchPrintfExA(pbuf, rem, &pbuf, &rem, 0,
  378. "trf -18 y\n" )))
  379. return FALSE;
  380. }
  381. pOEM->ptlTextCur.x += pOEM->iFontHeight;
  382. if ( pbuf > buf ) {
  383. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  384. }
  385. return TRUE;
  386. }
  387. BOOL
  388. EndVertWrite(
  389. PDEVOBJ pdevobj )
  390. {
  391. BYTE buf[512];
  392. PFXPDEV pOEM;
  393. BYTE *pbuf;
  394. size_t rem;
  395. pOEM = (PFXPDEV)pdevobj->pdevOEM;
  396. pbuf = buf;
  397. rem = sizeof buf;
  398. if (FAILED(StringCchPrintfExA(pbuf, rem, &pbuf, &rem, 0,
  399. "fo 0\nsrcp %d 0\n", -(pOEM->iFontHeight) )))
  400. return FALSE;
  401. if (pOEM->fFontSim & FONT_SIM_ITALIC) {
  402. if (FAILED(StringCchPrintfExA(pbuf, rem, &pbuf, &rem, 0,
  403. "trf x -18\n" )))
  404. return FALSE;
  405. }
  406. if ( pbuf > buf ) {
  407. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  408. }
  409. return TRUE;
  410. }
  411. //
  412. // Save the current poistion as the begining position of text output.
  413. // We will cache string output so that we need to remember this.
  414. //
  415. VOID
  416. SaveTextCur(
  417. PDEVOBJ pdevobj )
  418. {
  419. PFXPDEV pOEM;
  420. pOEM = (PFXPDEV)pdevobj->pdevOEM;
  421. pOEM->ptlTextCur.x = pOEM->ptlCur.x;
  422. pOEM->ptlTextCur.y = pOEM->ptlCur.y;
  423. pOEM->iTextFontId = pOEM->iFontId;
  424. pOEM->iTextFontHeight = pOEM->iFontHeight;
  425. pOEM->iTextFontWidth = pOEM->iFontWidth;
  426. pOEM->iTextFontWidth2 = pOEM->iFontWidth2;
  427. pOEM->fPositionReset = TRUE;
  428. }
  429. //
  430. // Flush out the cached text. We switch between single byte font and
  431. // double byte font if necesary.
  432. //
  433. BOOL
  434. FlushText(
  435. PDEVOBJ pdevobj )
  436. {
  437. INT i;
  438. BYTE *pStr, *pStrSav, *pStrMax, *pStrSav2;
  439. BYTE buf[512];
  440. BOOL bReset;
  441. PFXPDEV pOEM;
  442. INT iMark;
  443. BOOL bSkipEndString = FALSE;
  444. PBYTE pbuf;
  445. pOEM = (PFXPDEV)pdevobj->pdevOEM;
  446. bReset = pOEM->fPositionReset;
  447. pStr = pOEM->ajTextBuf;
  448. pStrMax = &pStr[min(pOEM->cTextBuf, sizeof(pOEM->ajTextBuf))];
  449. pStrSav = pStr;
  450. if(!pOEM->cTextBuf)
  451. return TRUE;
  452. while(pStr < pStrMax)
  453. {
  454. if(ISDBCSFONT(pOEM->iTextFontId))
  455. {
  456. // DBCS font case
  457. for(pStrSav = pStr; pStr < pStrMax; pStr += 2)
  458. {
  459. // Search for next SBCS character
  460. if ( BISMARKSBCS(*pStr) )
  461. break;
  462. }
  463. if(pStrSav < pStr)
  464. {
  465. FX_VERBOSE(("FT: h,w=%d,%d\n",
  466. pOEM->iFontHeight, pOEM->iFontWidth));
  467. // Send DBCS font select command
  468. // NTRAID#NTBUG9-365649-2002/03/12-yasuho-: Invalid font size
  469. if (pOEM->iCurFontId != (pOEM->iTextFontId + 1) ||
  470. pOEM->iCurFontHeight != pOEM->iTextFontHeight ||
  471. pOEM->iCurFontWidth != pOEM->iTextFontWidth)
  472. {
  473. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  474. "sfi %d\nfs %d %d\n",
  475. (pOEM->iTextFontId + 1),
  476. pOEM->iFontHeight, pOEM->iFontWidth2 )))
  477. return FALSE;
  478. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  479. pOEM->iCurFontId = (pOEM->iTextFontId + 1);
  480. pOEM->iCurFontHeight = pOEM->iTextFontHeight;
  481. pOEM->iCurFontWidth = pOEM->iTextFontWidth;
  482. }
  483. // If vertical font, send its command
  484. if( ISVERTFONT(pOEM->iTextFontId) ) {
  485. if (!BeginVertWrite(pdevobj)) return FALSE;
  486. // Output string: code from BeginString func.
  487. if ( bReset ) {
  488. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  489. "scp %d %d\n",
  490. ( pOEM->ptlOrg.x + pOEM->ptlTextCur.x ),
  491. ( pOEM->ptlOrg.y - pOEM->ptlTextCur.y ))))
  492. return FALSE;
  493. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  494. }
  495. if( 0 == memcmp( pStrSav, "\x21\x25", 2)) { // 0x2125 = dot character
  496. // start with dot character
  497. WRITESPOOLBUF( pdevobj, "gs 3\n", 5 );
  498. // grset command resets font size, so we have to resend it.
  499. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  500. "fs %d %d\n", pOEM->iFontHeight, pOEM->iFontWidth2 )))
  501. return FALSE;
  502. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  503. }
  504. WRITESPOOLBUF( pdevobj, "sh <", 4 );
  505. pOEM->bString = TRUE; // no need BeginString
  506. for( pStrSav2 = pStrSav ; pStrSav2 < pStr ; pStrSav2 += 2 ) {
  507. if( 0 == memcmp( pStrSav2, "\x21\x25", 2)) { // 0x2125 = dot character
  508. // special dot printing mode
  509. if( pStrSav2 != pStrSav ) {
  510. // change glyph set
  511. // If pStrSav2 == pStrSav, gs 3 command has already sent.
  512. WRITESPOOLBUF( pdevobj, ">\ngs 3\n", 7 );
  513. // grset command resets font size, so we have to resend it.
  514. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  515. "fs %d %d\n", pOEM->iFontHeight, pOEM->iFontWidth2 )))
  516. return FALSE;
  517. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  518. WRITESPOOLBUF( pdevobj, "sh <", 4 );
  519. pOEM->bString = TRUE; // no need BeginString
  520. }
  521. while( 0 == memcmp( pStrSav2, "\x21\x25", 2) ) {
  522. // output a dot character directly
  523. WRITESPOOLBUF( pdevobj, "2125", 4 );
  524. pStrSav2 += 2;
  525. }
  526. WRITESPOOLBUF( pdevobj, ">\ngs 5\n", 7 );
  527. // Next character exist?
  528. if( pStrSav2 < pStr ) {
  529. // remain string exists
  530. // grset command resets font size, so we have to resend it.
  531. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  532. "fs %d %d\nsh <", pOEM->iFontHeight, pOEM->iFontWidth2 )))
  533. return FALSE;
  534. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  535. pOEM->bString = TRUE; // no need BeginString
  536. bSkipEndString = FALSE;
  537. } else {
  538. // no remain string
  539. // grset command resets font size, so we have to resend it.
  540. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  541. "fs %d %d\n", pOEM->iFontHeight, pOEM->iFontWidth2 )))
  542. return FALSE;
  543. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  544. pOEM->bString = FALSE; // need BeginString
  545. bSkipEndString = TRUE;
  546. }
  547. } else {
  548. HexOutput(pdevobj, pStrSav2, (WORD)2);
  549. bSkipEndString = FALSE;
  550. }
  551. }
  552. if( bSkipEndString == FALSE ) {
  553. if (!EndString(pdevobj)) return FALSE;
  554. }
  555. // send revert command
  556. if (!EndVertWrite(pdevobj)) return FALSE;
  557. } else {
  558. // Horizontal font or no need to change glyph set
  559. // Output string
  560. if (!BeginString(pdevobj, bReset)) return FALSE;
  561. HexOutput(pdevobj, pStrSav, (WORD)(pStr - pStrSav));
  562. if (!EndString(pdevobj)) return FALSE;
  563. }
  564. bReset = FALSE;
  565. }
  566. for(pStrSav = pStr; pStr < pStrMax; pStr += 2)
  567. {
  568. // Search for DBCS character
  569. if (!BISMARKSBCS(*pStr))
  570. break;
  571. }
  572. if(pStrSav < pStr)
  573. {
  574. // Send DBCS font select command
  575. // NTRAID#NTBUG9-365649-2002/03/12-yasuho-: Invalid font size
  576. if (pOEM->iCurFontId != pOEM->iTextFontId ||
  577. pOEM->iCurFontHeight != pOEM->iTextFontHeight ||
  578. pOEM->iCurFontWidth != pOEM->iTextFontWidth)
  579. {
  580. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  581. "sfi %d\nfs %d %d\n",
  582. pOEM->iTextFontId,
  583. pOEM->iFontHeight, pOEM->iFontWidth )))
  584. return FALSE;
  585. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  586. pOEM->iCurFontId = pOEM->iTextFontId;
  587. pOEM->iCurFontHeight = pOEM->iTextFontHeight;
  588. pOEM->iCurFontWidth = pOEM->iTextFontWidth;
  589. }
  590. // String output
  591. if (!BeginString(pdevobj, bReset)) return FALSE;
  592. for( ; pStrSav < pStr; pStrSav++)
  593. {
  594. if (BISMARKSBCS(*pStrSav))
  595. pStrSav++;
  596. HexOutput(pdevobj, pStrSav, (WORD)1);
  597. }
  598. if (!EndString(pdevobj)) return FALSE;
  599. bReset = FALSE;
  600. }
  601. } else {
  602. // SBCS font case
  603. // Send Select Font command
  604. iMark = *pStr;
  605. // NTRAID#NTBUG9-365649-2002/03/12-yasuho-: Invalid font size
  606. if (pOEM->iCurFontId != (pOEM->iTextFontId + iMark) ||
  607. pOEM->iCurFontHeight != pOEM->iTextFontHeight ||
  608. pOEM->iCurFontWidth != pOEM->iTextFontWidth)
  609. {
  610. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  611. "sfi %d\nfs %d %d\n",
  612. (pOEM->iTextFontId + iMark),
  613. pOEM->iFontHeight, pOEM->iFontWidth )))
  614. return FALSE;
  615. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  616. pOEM->iCurFontId = (pOEM->iTextFontId + iMark);
  617. pOEM->iCurFontHeight = pOEM->iTextFontHeight;
  618. pOEM->iCurFontWidth = pOEM->iTextFontWidth;
  619. }
  620. // String Output
  621. if (!BeginString(pdevobj, bReset)) return FALSE;
  622. for(i = 0; i < pOEM->cTextBuf; pStr++)
  623. {
  624. if (*pStr != iMark)
  625. break;
  626. // Skip marker character
  627. pStr++;
  628. HexOutput(pdevobj, pStr, (WORD)1 );
  629. i += 2;
  630. }
  631. if (!EndString(pdevobj)) return FALSE;
  632. bReset = FALSE;
  633. pOEM->cTextBuf -= (WORD)i;
  634. }
  635. }
  636. pOEM->cTextBuf = 0;
  637. pOEM->fPositionReset = FALSE;
  638. return TRUE;
  639. }
  640. //*************************************************************
  641. int
  642. iCompTIFF(
  643. BYTE *pbOBuf,
  644. int iBCntO,
  645. BYTE *pbIBuf,
  646. int iBCnt
  647. )
  648. /*++
  649. Routine Description:
  650. This function is called to compress a scan line of data using
  651. TIFF v4 compression.
  652. Arguments:
  653. pbOBuf Pointer to output buffer PRESUMED LARGE ENOUGH
  654. iBCntO Size of output buffer
  655. pbIBuf Pointer to data buffer to compress
  656. iBCnt Number of bytes to compress
  657. Return Value:
  658. Number of compressed bytes
  659. Note:
  660. The output buffer is presumed large enough to hold the output.
  661. In the worst case (NO REPETITIONS IN DATA) there is an extra
  662. byte added every 128 bytes of input data. So, you should make
  663. the output buffer at least 1% larger than the input buffer.
  664. This routine is copied form UNIDRV.
  665. --*/
  666. {
  667. BYTE *pbOut; /* Output byte location */
  668. BYTE *pbStart; /* Start of current input stream */
  669. BYTE *pb; /* Miscellaneous usage */
  670. BYTE *pbEnd; /* The last byte of input */
  671. BYTE jLast; /* Last byte, for match purposes */
  672. BYTE bLast;
  673. BYTE *pbOEnd; /* The last byte of output */
  674. int iSize; /* Bytes in the current length */
  675. int iSend; /* Number to send in this command */
  676. pbOut = pbOBuf;
  677. pbStart = pbIBuf;
  678. pbEnd = pbIBuf + iBCnt; /* The last byte */
  679. pbOEnd = pbOBuf + iBCntO; /* The last buffer */
  680. #if (TIFF_MIN_RUN >= 4)
  681. // this is a faster algorithm for calculating TIFF compression
  682. // that assumes a minimum RUN of at least 4 bytes. If the
  683. // third and fourth byte don't equal then the first/second bytes are
  684. // irrelevant. This means we can determine non-run data three times
  685. // as fast since we only check every third byte pair.
  686. if (iBCnt > TIFF_MIN_RUN)
  687. {
  688. // make sure the last two bytes aren't equal so we don't have to check
  689. // for the buffer end when looking for runs
  690. bLast = pbEnd[-1];
  691. pbEnd[-1] = ~pbEnd[-2];
  692. while( (pbIBuf += 3) < pbEnd )
  693. {
  694. if (*pbIBuf == pbIBuf[-1])
  695. {
  696. // save the run start pointer, pb, and check whether the first
  697. // bytes are also part of the run
  698. //
  699. pb = pbIBuf-1;
  700. if (*pbIBuf == pbIBuf[-2])
  701. {
  702. pb--;
  703. if (*pbIBuf == pbIBuf[-3])
  704. pb--;
  705. }
  706. // Find out how long this run is
  707. jLast = *pb;
  708. do {
  709. pbIBuf++;
  710. } while (*pbIBuf == jLast);
  711. // test whether last byte is also part of the run
  712. //
  713. if (jLast == bLast && pbIBuf == (pbEnd-1))
  714. pbIBuf++;
  715. // Determine if the run is longer that the required
  716. // minimum run size.
  717. //
  718. if ((iSend = (int)(pbIBuf - pb)) >= (TIFF_MIN_RUN))
  719. {
  720. /*
  721. * Worth recording as a run, so first set the literal
  722. * data which may have already been scanned before recording
  723. * this run.
  724. */
  725. if( (iSize = (int)(pb - pbStart)) > 0 )
  726. {
  727. /* There is literal data, so record it now */
  728. while (iSize > TIFF_MAX_LITERAL)
  729. {
  730. // Buffer over run check
  731. if ((pbOut+TIFF_MAX_LITERAL) <= pbOEnd) {
  732. iSize -= TIFF_MAX_LITERAL;
  733. *pbOut++ = TIFF_MAX_LITERAL-1;
  734. CopyMemory(pbOut, pbStart, TIFF_MAX_LITERAL);
  735. pbStart += TIFF_MAX_LITERAL;
  736. pbOut += TIFF_MAX_LITERAL;
  737. } else {
  738. return 0;
  739. }
  740. }
  741. // Buffer over run check
  742. if ((pbOut+iSize) <= pbOEnd) {
  743. *pbOut++ = iSize - 1;
  744. CopyMemory(pbOut, pbStart, iSize);
  745. pbOut += iSize;
  746. } else {
  747. return 0;
  748. }
  749. }
  750. /*
  751. * Now for the repeat pattern. Same logic, but only
  752. * one byte is needed per entry.
  753. */
  754. iSize = iSend;
  755. while (iSize > TIFF_MAX_RUN)
  756. {
  757. // Buffer over run check
  758. if ((pbOut+2) <= pbOEnd) {
  759. *((char *)pbOut)++ = 1 - TIFF_MAX_RUN;
  760. *pbOut++ = jLast;
  761. iSize -= TIFF_MAX_RUN;
  762. } else {
  763. return 0;
  764. }
  765. }
  766. // Buffer over run check
  767. if ((pbOut+2) <= pbOEnd) {
  768. *pbOut++ = 1 - iSize;
  769. *pbOut++ = jLast;
  770. } else {
  771. return 0;
  772. }
  773. pbStart = pbIBuf; /* Ready for the next one! */
  774. }
  775. }
  776. }
  777. pbEnd[-1] = bLast;
  778. }
  779. #else
  780. jLast = *pbIBuf++;
  781. while( pbIBuf < pbEnd )
  782. {
  783. if( jLast == *pbIBuf )
  784. {
  785. /* Find out how long this run is. Then decide on using it */
  786. pb = pbIBuf;
  787. do {
  788. pbIBuf++;
  789. } while (pbIBuf < pbEnd && *pbIBuf == jLast);
  790. /*
  791. * Note that pb points at the SECOND byte of the pattern!
  792. * AND also that pbIBuf points at the first byte AFTER the run.
  793. */
  794. if ((iSend = pbIBuf - pb) >= (TIFF_MIN_RUN - 1))
  795. {
  796. /*
  797. * Worth recording as a run, so first set the literal
  798. * data which may have already been scanned before recording
  799. * this run.
  800. */
  801. if( (iSize = pb - pbStart - 1) > 0 )
  802. {
  803. /* There is literal data, so record it now */
  804. while (iSize > TIFF_MAX_LITERAL)
  805. {
  806. // Buffer over run check
  807. if ((pbOut+TIFF_MAX_LITERAL) <= pbOEnd) {
  808. iSize -= TIFF_MAX_LITERAL;
  809. *pbOut++ = TIFF_MAX_LITERAL-1;
  810. CopyMemory(pbOut, pbStart, TIFF_MAX_LITERAL);
  811. pbStart += TIFF_MAX_LITERAL;
  812. pbOut += TIFF_MAX_LITERAL;
  813. } else {
  814. return 0;
  815. }
  816. }
  817. // Buffer over run check
  818. if ((pbOut+iSize) <= pbOEnd) {
  819. *pbOut++ = iSize - 1;
  820. CopyMemory(pbOut, pbStart, iSize);
  821. pbOut += iSize;
  822. } else {
  823. return 0;
  824. }
  825. }
  826. /*
  827. * Now for the repeat pattern. Same logic, but only
  828. * one byte is needed per entry.
  829. */
  830. iSize = iSend + 1;
  831. while (iSize > TIFF_MAX_RUN)
  832. {
  833. // Buffer over run check
  834. if ((pbOut+2) <= pbOEnd) {
  835. *((char *)pbOut)++ = 1 - TIFF_MAX_RUN;
  836. *pbOut++ = jLast;
  837. iSize -= TIFF_MAX_RUN;
  838. } else {
  839. return 0;
  840. }
  841. }
  842. // Buffer over run check
  843. if ((pbOut+2) <= pbOEnd) {
  844. *pbOut++ = 1 - iSize;
  845. *pbOut++ = jLast;
  846. } else {
  847. return 0;
  848. }
  849. pbStart = pbIBuf; /* Ready for the next one! */
  850. }
  851. if (pbIBuf == pbEnd)
  852. break;
  853. }
  854. jLast = *pbIBuf++; /* Onto the next byte */
  855. }
  856. #endif
  857. if ((iSize = (int)(pbEnd - pbStart)) > 0)
  858. {
  859. /* Left some dangling. This can only be literal data. */
  860. while( (iSend = min( iSize, TIFF_MAX_LITERAL )) > 0 )
  861. {
  862. // Buffer over run check
  863. if ((pbOut+iSend) <= pbOEnd) {
  864. *pbOut++ = iSend - 1;
  865. CopyMemory( pbOut, pbStart, iSend );
  866. pbOut += iSend;
  867. pbStart += iSend;
  868. iSize -= iSend;
  869. } else {
  870. return 0;
  871. }
  872. }
  873. }
  874. return (int)(pbOut - pbOBuf);
  875. }
  876. BOOL
  877. APIENTRY
  878. OEMFilterGraphics(
  879. PDEVOBJ pdevobj,
  880. PBYTE pBuf,
  881. DWORD dwLen)
  882. {
  883. PFXPDEV pOEM = (PFXPDEV)(pdevobj->pdevOEM);
  884. PBYTE pNewBufPtr;
  885. DWORD dwNewBufSize;
  886. INT nCompressedSize;
  887. if(!pOEM->fCallback)
  888. {
  889. // NTRAID#NTBUG9-208433-2002/03/12-yasuho-:
  890. // Output images are broken on ART2/3 models.
  891. if (pOEM->bART3) { // ART2/3 can't support TIFF compression
  892. WRITESPOOLBUF(pdevobj, pBuf, dwLen);
  893. return TRUE;
  894. }
  895. // For TIFF compression in fxartres
  896. dwNewBufSize = NEEDSIZE4TIFF(dwLen);
  897. if( dwNewBufSize > pOEM->dwTiffCompressBufSize)
  898. {
  899. if(!(pNewBufPtr = (PBYTE)MemAlloc(dwNewBufSize)))
  900. {
  901. ERR(("Re-MemAlloc failed.\n"));
  902. return TRUE;
  903. }else {
  904. // Prepare new buffer
  905. MemFree(pOEM->pTiffCompressBuf);
  906. pOEM->pTiffCompressBuf = pNewBufPtr;
  907. pOEM->dwTiffCompressBufSize = dwNewBufSize;
  908. }
  909. }
  910. // Do TIFF compression
  911. nCompressedSize = iCompTIFF( pOEM->pTiffCompressBuf,
  912. pOEM->dwTiffCompressBufSize,
  913. pBuf, dwLen );
  914. WRITESPOOLBUF(pdevobj, pOEM->pTiffCompressBuf, nCompressedSize);
  915. return TRUE;
  916. }
  917. return HexOutput(pdevobj, pBuf, dwLen);
  918. }
  919. //-------------------------------------------------------------------
  920. // OEMOutputCmd
  921. // Action :
  922. //-------------------------------------------------------------------
  923. #define CBID_CM_OCD_XM_ABS 1
  924. #define CBID_CM_OCD_YM_ABS 2
  925. #define CBID_CM_OCD_XM_REL 3
  926. #define CBID_CM_OCD_YM_REL 4
  927. #define CBID_CM_OCD_XM_RELLEFT 5
  928. #define CBID_CM_OCD_YM_RELUP 6
  929. #define CBID_CM_CR 7
  930. #define CBID_CM_FF 8
  931. #define CBID_CM_LF 9
  932. #define CBID_PC_OCD_BEGINDOC_ART 11
  933. #define CBID_PC_OCD_BEGINDOC_ART3 12
  934. #define CBID_PC_OCD_BEGINDOC_ART4 13
  935. #define CBID_PC_OCD_BEGINPAGE 14
  936. #define CBID_PC_OCD_ENDPAGE 15
  937. #define CBID_PC_OCD_MULT_COPIES 16
  938. #define CBID_PC_OCD_PORTRAIT 17
  939. #define CBID_PC_OCD_LANDSCAPE 18
  940. #define CBID_PC_OCD_BEGINDOC_ART4_JCL 19
  941. #define CBID_PC_OCD_MULT_COPIES_450 20
  942. #define CBID_RES_OCD_SELECTRES_240DPI 21
  943. #define CBID_RES_OCD_SELECTRES_300DPI 22
  944. #define CBID_RES_OCD_SELECTRES_400DPI 23
  945. #define CBID_RES_OCD_SELECTRES_600DPI 24
  946. #define CBID_RES_OCD_SENDBLOCK_ASCII 25
  947. #define CBID_RES_OCD_SENDBLOCK 26
  948. #define CBID_RES_OCD_SELECTRES_240DPI_ART3_ART 27
  949. #define CBID_RES_OCD_SELECTRES_300DPI_ART3_ART 28
  950. #define CBID_RES_OCD_SELECTRES_450 29
  951. #define CBID_PSZ_OCD_SELECT_A3 30
  952. #define CBID_PSZ_OCD_SELECT_A4 31
  953. #define CBID_PSZ_OCD_SELECT_A5 32
  954. #define CBID_PSZ_OCD_SELECT_B4 33
  955. #define CBID_PSZ_OCD_SELECT_B5 34
  956. #define CBID_PSZ_OCD_SELECT_PC 35
  957. #define CBID_PSZ_OCD_SELECT_DL 36
  958. #define CBID_PSZ_OCD_SELECT_LT 37
  959. #define CBID_PSZ_OCD_SELECT_GG 38
  960. #define CBID_PSZ_OCD_SELECT_LG 39
  961. #define CBID_PSZ_OCD_SELECT_S1 40
  962. #define CBID_PSZ_OCD_SELECT_S2 41
  963. #define CBID_PSZ_OCD_SELECT_S3 42
  964. #define CBID_PSZ_OCD_SELECT_S4 43
  965. #define CBID_PSZ_OCD_SELECT_A6 44
  966. #define CBID_PSZ_OCD_SELECT_B6 45
  967. #define CBID_PSZ_OCD_SELECT_ST 46
  968. #define CBID_FS_OCD_BOLD_ON 51
  969. #define CBID_FS_OCD_BOLD_OFF 52
  970. #define CBID_FS_OCD_ITALIC_ON 53
  971. #define CBID_FS_OCD_ITALIC_OFF 54
  972. #define CBID_FS_OCD_SINGLE_BYTE 55
  973. #define CBID_FS_OCD_DOUBLE_BYTE 56
  974. #define CBID_FS_OCD_WHITE_TEXT_ON 57
  975. #define CBID_FS_OCD_WHITE_TEXT_OFF 58
  976. #define CBID_SRT_OCD_SORTER_ON 59
  977. #define CBID_SRT_OCD_SORTER_OFF 60
  978. #define CBID_PC_OCD_ENDDOC 70
  979. #define CBID_FONT_SELECT_OUTLINE 101
  980. static
  981. BOOL
  982. XYMoveUpdate(
  983. PDEVOBJ pdevobj)
  984. {
  985. PFXPDEV pOEM;
  986. pOEM = (PFXPDEV)(pdevobj->pdevOEM);
  987. FX_VERBOSE(("XYMoveFlush: %d,%d\n",
  988. pOEM->ptlCur.x, pOEM->ptlCur.y ));
  989. if(pOEM->cTextBuf)
  990. if (!FlushText( pdevobj )) return FALSE;
  991. SaveTextCur( pdevobj );
  992. return TRUE;
  993. }
  994. static BOOL
  995. XMoveAbs(PDEVOBJ p, INT i)
  996. {
  997. ((PFXPDEV)((p)->pdevOEM))->ptlCur.x = (i);
  998. return XYMoveUpdate(p);
  999. }
  1000. // For internal calculation of X-pos.
  1001. #define RATE_FONTWIDTH2XPOS 1000
  1002. #define VALUE_FONTWIDTH2XPOS_ROUNDUP5 500
  1003. static BOOL
  1004. YMoveAbs(PDEVOBJ p, INT i)
  1005. {
  1006. PFXPDEV pOEM = p->pdevOEM;
  1007. pOEM->ptlCur.y = (i);
  1008. pOEM->ptlCur.x += ((pOEM->lInternalXAdd + VALUE_FONTWIDTH2XPOS_ROUNDUP5) /
  1009. RATE_FONTWIDTH2XPOS);
  1010. pOEM->lInternalXAdd = 0;
  1011. ZeroMemory(pOEM->widBuf, sizeof(pOEM->widBuf));
  1012. return XYMoveUpdate(p);
  1013. }
  1014. //
  1015. // FreedBuffersInPDEV
  1016. //
  1017. VOID
  1018. FreeCompressBuffers( PDEVOBJ pdevobj )
  1019. {
  1020. PFXPDEV pOEM;
  1021. pOEM = (PFXPDEV)(pdevobj->pdevOEM);
  1022. if( pOEM->pTiffCompressBuf != NULL )
  1023. {
  1024. MemFree(pOEM->pTiffCompressBuf);
  1025. pOEM->pTiffCompressBuf = NULL;
  1026. pOEM->dwTiffCompressBufSize = 0;
  1027. }
  1028. return;
  1029. }
  1030. /*****************************************************************************/
  1031. /* */
  1032. /* INT APIENTRY OEMCommandCallback( */
  1033. /* PDEVOBJ pdevobj */
  1034. /* DWORD dwCmdCbId */
  1035. /* DWORD dwCount */
  1036. /* PDWORD pdwParams */
  1037. /* */
  1038. /*****************************************************************************/
  1039. INT APIENTRY
  1040. OEMCommandCallback(
  1041. PDEVOBJ pdevobj, // Points to private data required by the Unidriver.dll
  1042. DWORD dwCmdCbID, // Callback ID
  1043. DWORD dwCount, // Counts of command parameter
  1044. PDWORD pdwParams ) // points to values of command params
  1045. {
  1046. BYTE buf[512];
  1047. PFXPDEV pOEM;
  1048. LONG x, y;
  1049. BOOL bAscii;
  1050. CHAR *pStr;
  1051. INT iRet;
  1052. PBYTE pbuf;
  1053. size_t iLen;
  1054. VERBOSE(("OEMCommandCallback entry.\n"));
  1055. ASSERT(VALID_PDEVOBJ(pdevobj));
  1056. pOEM = (PFXPDEV)(pdevobj->pdevOEM);
  1057. bAscii = FALSE;
  1058. iRet = 0;
  1059. pbuf = buf;
  1060. switch( dwCmdCbID )
  1061. {
  1062. // PAPERSIZE
  1063. case CBID_PSZ_OCD_SELECT_A3:
  1064. LoadPaperInfo( pOEM, "a3" );
  1065. break;
  1066. case CBID_PSZ_OCD_SELECT_A4:
  1067. LoadPaperInfo( pOEM, "a4" );
  1068. break;
  1069. case CBID_PSZ_OCD_SELECT_A5:
  1070. LoadPaperInfo( pOEM, "a5" );
  1071. break;
  1072. case CBID_PSZ_OCD_SELECT_A6:
  1073. LoadPaperInfo( pOEM, "a6" );
  1074. break;
  1075. case CBID_PSZ_OCD_SELECT_B4:
  1076. LoadPaperInfo( pOEM, "b4" );
  1077. break;
  1078. case CBID_PSZ_OCD_SELECT_B5:
  1079. LoadPaperInfo( pOEM, "b5" );
  1080. break;
  1081. case CBID_PSZ_OCD_SELECT_B6:
  1082. LoadPaperInfo( pOEM, "b6" );
  1083. break;
  1084. case CBID_PSZ_OCD_SELECT_PC:
  1085. LoadPaperInfo( pOEM, "pc" );
  1086. break;
  1087. case CBID_PSZ_OCD_SELECT_DL:
  1088. LoadPaperInfo( pOEM, "o0" );
  1089. break;
  1090. case CBID_PSZ_OCD_SELECT_LT:
  1091. LoadPaperInfo( pOEM, "o1" );
  1092. break;
  1093. case CBID_PSZ_OCD_SELECT_GG:
  1094. LoadPaperInfo( pOEM, "o2" );
  1095. break;
  1096. case CBID_PSZ_OCD_SELECT_LG:
  1097. LoadPaperInfo( pOEM, "o3" );
  1098. break;
  1099. case CBID_PSZ_OCD_SELECT_ST:
  1100. LoadPaperInfo( pOEM, "hl" );
  1101. break;
  1102. case CBID_PSZ_OCD_SELECT_S1:
  1103. LoadPaperInfo( pOEM, "s1" );
  1104. break;
  1105. case CBID_PSZ_OCD_SELECT_S2:
  1106. LoadPaperInfo( pOEM, "s2" );
  1107. break;
  1108. case CBID_PSZ_OCD_SELECT_S3:
  1109. LoadPaperInfo( pOEM, "s3" );
  1110. break;
  1111. case CBID_PSZ_OCD_SELECT_S4:
  1112. LoadPaperInfo( pOEM, "s4" );
  1113. break;
  1114. case CBID_PC_OCD_PORTRAIT:
  1115. pOEM->chOrient = "p";
  1116. break;
  1117. case CBID_PC_OCD_LANDSCAPE:
  1118. pOEM->chOrient = "l";
  1119. break;
  1120. // PAGECONTROL
  1121. case CBID_PC_OCD_BEGINDOC_ART:
  1122. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1123. "stj c\n" ))) {
  1124. iRet = -1;
  1125. break;
  1126. }
  1127. break;
  1128. case CBID_PC_OCD_BEGINDOC_ART3:
  1129. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1130. "srl %d %d\nstj c\n", pOEM->sizlRes.cx, pOEM->sizlRes.cy ))) {
  1131. iRet = -1;
  1132. break;
  1133. }
  1134. break;
  1135. case CBID_PC_OCD_BEGINDOC_ART4:
  1136. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1137. "\x1b%%-12345X" ))) {
  1138. iRet = -1;
  1139. break;
  1140. }
  1141. break;
  1142. case CBID_PC_OCD_BEGINDOC_ART4_JCL:
  1143. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1144. "\x1b%%-12345X\x0d\x0a@JOMO=PRINTER\x0d\x0a"))) {
  1145. iRet = -1;
  1146. break;
  1147. }
  1148. break;
  1149. case CBID_PC_OCD_BEGINPAGE:
  1150. // NTRAID#NTBUG9-493148-2002/03/12-yasuho-:
  1151. // Stress break: PDEV resetting via OEMDevMode().
  1152. // bold-simulation width: res / 50
  1153. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1154. "stp %s %s\nud i\nscl %d %d\nsb %d\n",
  1155. pOEM->chOrient,
  1156. pOEM->chSize,
  1157. (DEVICE_MASTER_UNIT / DRIVER_MASTER_UNIT),
  1158. (DEVICE_MASTER_UNIT / DRIVER_MASTER_UNIT),
  1159. (pOEM->sizlRes.cy * 2 / 100)))) {
  1160. iRet = -1;
  1161. break;
  1162. }
  1163. pOEM->ptlCur.x = 0;
  1164. pOEM->ptlCur.y = 0;
  1165. break;
  1166. case CBID_PC_OCD_ENDPAGE:
  1167. if(pOEM->fSort == FALSE){
  1168. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1169. "ep %d\n", pOEM->iCopies ))) {
  1170. iRet = -1;
  1171. break;
  1172. }
  1173. }else if(pOEM->fSort == TRUE){
  1174. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1175. "ep 1\n"))) {
  1176. iRet = -1;
  1177. break;
  1178. }
  1179. }
  1180. if (!FlushText( pdevobj )) {
  1181. iRet = -1;
  1182. break;
  1183. }
  1184. pOEM->cFontId = 0;
  1185. pOEM->iCurFontId = 0;
  1186. // NTRAID#NTBUG9-365649-2002/03/12-yasuho-: Invalid font size
  1187. pOEM->iCurFontHeight = 0;
  1188. pOEM->iCurFontWidth = 0;
  1189. FreeCompressBuffers( pdevobj ); // If the buffer is need after, it will be alloced again.
  1190. break;
  1191. case CBID_PC_OCD_ENDDOC:
  1192. WRITESPOOLBUF( pdevobj, "ej\n", 3 ); // Output endjob command
  1193. FreeCompressBuffers( pdevobj );
  1194. break;
  1195. case CBID_PC_OCD_MULT_COPIES:
  1196. if (dwCount < 1 || !pdwParams)
  1197. return -1;
  1198. // @Aug/31/98 ->
  1199. if(MAX_COPIES_VALUE < PARAM(pdwParams, 0)) {
  1200. pOEM->iCopies = MAX_COPIES_VALUE;
  1201. }
  1202. else if(1 > PARAM(pdwParams, 0)) {
  1203. pOEM->iCopies = 1;
  1204. }
  1205. else {
  1206. pOEM->iCopies = (WORD)PARAM(pdwParams, 0);
  1207. }
  1208. // @Aug/31/98 <-
  1209. break;
  1210. case CBID_PC_OCD_MULT_COPIES_450:
  1211. if (dwCount < 1 || !pdwParams)
  1212. return -1;
  1213. if(MAX_COPIES_VALUE_450 < PARAM(pdwParams, 0)) {
  1214. pOEM->iCopies = MAX_COPIES_VALUE;
  1215. }
  1216. else if(1 > PARAM(pdwParams, 0)) {
  1217. pOEM->iCopies = 1;
  1218. }
  1219. else {
  1220. pOEM->iCopies = (WORD)PARAM(pdwParams, 0);
  1221. }
  1222. break;
  1223. // Cursor Move
  1224. case CBID_CM_OCD_XM_ABS:
  1225. case CBID_CM_OCD_YM_ABS:
  1226. FX_VERBOSE(("CB: XM/YM_ABS %d\n",
  1227. PARAM(pdwParams, 0)));
  1228. if (dwCount < 1 || !pdwParams)
  1229. return -1;
  1230. iRet = (WORD)PARAM(pdwParams, 0);
  1231. if (CBID_CM_OCD_YM_ABS == dwCmdCbID) {
  1232. if (!YMoveAbs(pdevobj, iRet)) {
  1233. iRet = -1;
  1234. break;
  1235. }
  1236. }
  1237. else {
  1238. if (!XMoveAbs(pdevobj, iRet)) {
  1239. iRet = -1;
  1240. break;
  1241. }
  1242. }
  1243. break;
  1244. // RESOLUTION
  1245. case CBID_RES_OCD_SELECTRES_240DPI:
  1246. pOEM->sizlRes.cx = 240;
  1247. pOEM->sizlRes.cy = 240;
  1248. pOEM->sizlUnit.cx = DRIVER_MASTER_UNIT / 240;
  1249. pOEM->sizlUnit.cy = DRIVER_MASTER_UNIT / 240;
  1250. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1251. "@PL > ART\x0D\x0Asrl 240 240\x0D\x0A\nccode j\nstj c\n"))) {
  1252. iRet = -1;
  1253. break;
  1254. }
  1255. break;
  1256. case CBID_RES_OCD_SELECTRES_300DPI:
  1257. pOEM->sizlRes.cx = 300;
  1258. pOEM->sizlRes.cy = 300;
  1259. pOEM->sizlUnit.cx = DRIVER_MASTER_UNIT / 300;
  1260. pOEM->sizlUnit.cy = DRIVER_MASTER_UNIT / 300;
  1261. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1262. "@PL > ART\x0D\x0Asrl 300 300\x0D\x0A\nccode j\nstj c\n"))) {
  1263. iRet = -1;
  1264. break;
  1265. }
  1266. break;
  1267. case CBID_RES_OCD_SELECTRES_400DPI:
  1268. pOEM->sizlRes.cx = 400;
  1269. pOEM->sizlRes.cy = 400;
  1270. pOEM->sizlUnit.cx = DRIVER_MASTER_UNIT / 400;
  1271. pOEM->sizlUnit.cy = DRIVER_MASTER_UNIT / 400;
  1272. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1273. "@PL > ART\x0D\x0Asrl 400 400\x0D\x0A\nccode j\nstj c\n"))) {
  1274. iRet = -1;
  1275. break;
  1276. }
  1277. break;
  1278. case CBID_RES_OCD_SELECTRES_600DPI:
  1279. pOEM->sizlRes.cx = 600;
  1280. pOEM->sizlRes.cy = 600;
  1281. pOEM->sizlUnit.cx = DRIVER_MASTER_UNIT / 600;
  1282. pOEM->sizlUnit.cy = DRIVER_MASTER_UNIT / 600;
  1283. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1284. "@PL > ART\x0D\x0Asrl 600 600\x0D\x0A\nccode j\nstj c\n"))) {
  1285. iRet = -1;
  1286. break;
  1287. }
  1288. break;
  1289. case CBID_RES_OCD_SELECTRES_450:
  1290. pOEM->sizlRes.cx = 600;
  1291. pOEM->sizlRes.cy = 600;
  1292. pOEM->sizlUnit.cx = DRIVER_MASTER_UNIT / 600;
  1293. pOEM->sizlUnit.cy = DRIVER_MASTER_UNIT / 600;
  1294. if(pOEM->fSort == FALSE){
  1295. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1296. "@JOOF=OFF\x0D\x0A@PL > ART\x0D\x0Asrl 600 600\x0D\x0A\nccode j\nstj c\n"))) {
  1297. iRet = -1;
  1298. break;
  1299. }
  1300. }else{
  1301. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1302. "@JOOF=OFF\x0D\x0A@PL > ART\x0D\x0Asrl 600 600\x0D\x0A\nccode j\nstj c\nstp jog 0\n"))) {
  1303. iRet = -1;
  1304. break;
  1305. }
  1306. }
  1307. break;
  1308. case CBID_RES_OCD_SELECTRES_240DPI_ART3_ART:
  1309. pOEM->sizlRes.cx = 240;
  1310. pOEM->sizlRes.cy = 240;
  1311. pOEM->sizlUnit.cx = DRIVER_MASTER_UNIT / 240;
  1312. pOEM->sizlUnit.cy = DRIVER_MASTER_UNIT / 240;
  1313. // NTRAID#NTBUG9-208433-2002/03/12-yasuho-:
  1314. // Output images are broken on ART2/3 models.
  1315. pOEM->bART3 = TRUE;
  1316. break;
  1317. case CBID_RES_OCD_SELECTRES_300DPI_ART3_ART:
  1318. pOEM->sizlRes.cx = 300;
  1319. pOEM->sizlRes.cy = 300;
  1320. pOEM->sizlUnit.cx = DRIVER_MASTER_UNIT / 300;
  1321. pOEM->sizlUnit.cy = DRIVER_MASTER_UNIT / 300;
  1322. // NTRAID#NTBUG9-208433-2002/03/12-yasuho-:
  1323. // Output images are broken on ART2/3 models.
  1324. pOEM->bART3 = TRUE;
  1325. break;
  1326. case CBID_RES_OCD_SENDBLOCK_ASCII:
  1327. bAscii = TRUE;
  1328. pOEM->fCallback = TRUE;
  1329. /* FALLTHROUGH */
  1330. case CBID_RES_OCD_SENDBLOCK:
  1331. if (dwCount < 3 || !pdwParams)
  1332. return -1;
  1333. //
  1334. // image x y psx psy pcy pcy [string]
  1335. //
  1336. {
  1337. LONG iPsx, iPsy, iPcx, iPcy;
  1338. // NTRAID#NTBUG9-493148-2002/03/12-yasuho-:
  1339. // Stress break: PDEV resetting via OEMDevMode().
  1340. iPsx = pOEM->sizlUnit.cx;
  1341. iPsy = pOEM->sizlUnit.cy;
  1342. iPcx = PARAM(pdwParams, 2) * 8;
  1343. iPcy = PARAM(pdwParams, 1);
  1344. FX_VERBOSE(("CB: SB %d(%d) %d(%d) %d %d %d %d\n",
  1345. ( pOEM->ptlOrg.x + pOEM->ptlCur.x ),
  1346. pOEM->ptlCur.x,
  1347. ( pOEM->ptlOrg.y - pOEM->ptlCur.y ),
  1348. pOEM->ptlCur.y,
  1349. iPsx,
  1350. iPsy,
  1351. iPcx,
  1352. (- iPcy)));
  1353. // NTRAID#NTBUG9-208433-2002/03/12-yasuho-:
  1354. // Output images are broken on ART2/3 models.
  1355. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1356. "%s%d %d %d %d %d %d %s",
  1357. ((bAscii || pOEM->bART3) ? "im " : "scm 5\nim "),
  1358. ( pOEM->ptlOrg.x + pOEM->ptlCur.x ),
  1359. ( pOEM->ptlOrg.y - pOEM->ptlCur.y ),
  1360. iPsx,
  1361. iPsy,
  1362. iPcx,
  1363. (- iPcy),
  1364. (bAscii ? "<" : "[")
  1365. ))) {
  1366. iRet = -1;
  1367. break;
  1368. }
  1369. }
  1370. break;
  1371. case CBID_FS_OCD_BOLD_ON:
  1372. case CBID_FS_OCD_BOLD_OFF:
  1373. case CBID_FS_OCD_ITALIC_ON:
  1374. case CBID_FS_OCD_ITALIC_OFF:
  1375. case CBID_FS_OCD_SINGLE_BYTE:
  1376. case CBID_FS_OCD_DOUBLE_BYTE:
  1377. case CBID_FS_OCD_WHITE_TEXT_ON:
  1378. case CBID_FS_OCD_WHITE_TEXT_OFF:
  1379. pStr = NULL;
  1380. switch ( dwCmdCbID ) {
  1381. case CBID_FS_OCD_WHITE_TEXT_ON:
  1382. if(!(pOEM->fFontSim & FONT_SIM_WHITE))
  1383. {
  1384. pStr = "pm i c\n";
  1385. pOEM->fFontSim |= FONT_SIM_WHITE;
  1386. }
  1387. break;
  1388. case CBID_FS_OCD_WHITE_TEXT_OFF:
  1389. if(pOEM->fFontSim & FONT_SIM_WHITE)
  1390. {
  1391. pStr = "pm n o\n";
  1392. pOEM->fFontSim &= ~FONT_SIM_WHITE;
  1393. }
  1394. break;
  1395. case CBID_FS_OCD_BOLD_ON:
  1396. if(!(pOEM->fFontSim & FONT_SIM_BOLD))
  1397. {
  1398. pStr = "bb\n";
  1399. pOEM->fFontSim |= FONT_SIM_BOLD;
  1400. }
  1401. break;
  1402. case CBID_FS_OCD_BOLD_OFF:
  1403. if(pOEM->fFontSim & FONT_SIM_BOLD)
  1404. {
  1405. pStr = "eb\net\n"; // DCR: Do we need "et\n"(Transform off)?
  1406. pOEM->fFontSim &= ~FONT_SIM_BOLD;
  1407. }
  1408. break;
  1409. case CBID_FS_OCD_ITALIC_ON:
  1410. if(!(pOEM->fFontSim & FONT_SIM_ITALIC))
  1411. {
  1412. pStr = "trf x -18\nbt\n";
  1413. pOEM->fFontSim |= FONT_SIM_ITALIC;
  1414. }
  1415. break;
  1416. case CBID_FS_OCD_ITALIC_OFF:
  1417. if(pOEM->fFontSim & FONT_SIM_ITALIC)
  1418. {
  1419. pStr = "eb\net\n"; // DCR: Do we need "et\n"(Transform off)?
  1420. pOEM->fFontSim &= ~FONT_SIM_ITALIC;
  1421. }
  1422. break;
  1423. }
  1424. if ( pStr )
  1425. {
  1426. if (!FlushText( pdevobj )) {
  1427. iRet = -1;
  1428. break;
  1429. }
  1430. if (FAILED(StringCchLengthA(pStr, sizeof buf, &iLen))) {
  1431. iRet = -1;
  1432. break;
  1433. }
  1434. WRITESPOOLBUF( pdevobj, pStr, iLen );
  1435. }
  1436. break;
  1437. case CBID_CM_CR:
  1438. if (!XMoveAbs(pdevobj, 0)) {
  1439. iRet = -1;
  1440. break;
  1441. }
  1442. iRet = 0;
  1443. break;
  1444. case CBID_CM_FF:
  1445. case CBID_CM_LF:
  1446. break;
  1447. case CBID_SRT_OCD_SORTER_OFF:
  1448. pOEM->fSort = FALSE ;
  1449. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1450. "@CLLT=OFF\x0D\x0A"))) {
  1451. iRet = -1;
  1452. break;
  1453. }
  1454. break;
  1455. case CBID_SRT_OCD_SORTER_ON:
  1456. pOEM->fSort = TRUE ;
  1457. if (FAILED(StringCchPrintfExA(buf, sizeof buf, &pbuf, NULL, 0,
  1458. "@CLLT=ON\x0D\x0A@JOCO=%d\x0D\x0A", pOEM->iCopies))) {
  1459. iRet = -1;
  1460. break;
  1461. }
  1462. break;
  1463. default:
  1464. break;
  1465. }
  1466. if ( (DWORD)(pbuf - buf) > 0 ) {
  1467. WRITESPOOLBUF( pdevobj, buf, (DWORD)(pbuf - buf) );
  1468. }
  1469. return iRet;
  1470. }
  1471. //---------------------------*bOEMSendFontCmd*----------------------------------
  1472. // Action: send Pages-style font selection command.
  1473. //-----------------------------------------------------------------------------
  1474. BOOL APIENTRY bOEMSendFontCmd(pdevobj, pUFObj, pFInv)
  1475. PDEVOBJ pdevobj;
  1476. PUNIFONTOBJ pUFObj; // offset to the command heap
  1477. PFINVOCATION pFInv;
  1478. {
  1479. PFXPDEV pOEM;
  1480. GETINFO_STDVAR *pSV;
  1481. DWORD adwSV[2 + 2 * 2];
  1482. INT iFontId, iMaxId;
  1483. INT i, j;
  1484. BYTE buf[512], *pbuf;
  1485. PIFIMETRICS pIFI = pUFObj->pIFIMetrics;
  1486. size_t rem;
  1487. #define SV_HEIGHT (pSV->StdVar[0].lStdVariable)
  1488. #define SV_WIDTH (pSV->StdVar[1].lStdVariable)
  1489. #define COEF_FIXPITCH_MUL 8
  1490. #define COEF_FIXPITCH_DEV 10
  1491. #define COEF_ROUNDUP5_VAL 5
  1492. VERBOSE(("OEMSendFontCmd entry.\n"));
  1493. ASSERT(VALID_PDEVOBJ(pdevobj));
  1494. if(!pUFObj || !pFInv)
  1495. {
  1496. ERR(("OEMSendFontCmd: parameter is invalid."));
  1497. return FALSE;
  1498. }
  1499. // NTRAID#NTBUG9-498278-2002/03/12-yasuho-: Device font !print
  1500. if(pUFObj->ulFontID < 1 || pUFObj->ulFontID > MAX_FONTS)
  1501. {
  1502. ERR(("OEMSendFontCmd: ulFontID is invalid.\n"));
  1503. return FALSE;
  1504. }
  1505. pbuf = buf;
  1506. rem = sizeof buf;
  1507. pOEM = (PFXPDEV)pdevobj->pdevOEM;
  1508. j = pUFObj->ulFontID - 1;
  1509. iFontId = gFonts[ j ].id;
  1510. if(pOEM->cTextBuf)
  1511. if (!FlushText(pdevobj)) {
  1512. ERR(("OEMSendFontCmd: FlushText failed.\n"));
  1513. return FALSE;
  1514. }
  1515. iMaxId = min(pOEM->cFontId, MAX_FONTS);
  1516. for ( i = 0; i < iMaxId; i++ )
  1517. {
  1518. if( iFontId == pOEM->aFontId[ i ] )
  1519. break;
  1520. }
  1521. if (i >= MAX_FONTS) // No room!
  1522. return FALSE;
  1523. if ( i >= pOEM->cFontId ) {
  1524. // not declared yet within this page, so let us declare
  1525. // it here.
  1526. if (pOEM->cFontId >= MAX_FONTS)
  1527. return FALSE;
  1528. pOEM->aFontId[ pOEM->cFontId++ ] = (BYTE)iFontId;
  1529. if ( gFonts[ j ].fid2 ) {
  1530. if (FAILED(StringCchPrintfExA(pbuf, rem, &pbuf, &rem, 0,
  1531. "std\n%s%sed\n",
  1532. gFonts[ j ].fid1,
  1533. gFonts[ j ].fid2 ))) {
  1534. ERR(("OEMSendFontCmd: StringCchPrintfExA failed.\n"));
  1535. return FALSE;
  1536. }
  1537. }
  1538. else {
  1539. if (FAILED(StringCchPrintfExA(pbuf, rem, &pbuf, &rem, 0,
  1540. "std\n%sed\n",
  1541. gFonts[ j ].fid1 ))) {
  1542. ERR(("OEMSendFontCmd: StringCchPrintfExA failed.\n"));
  1543. return FALSE;
  1544. }
  1545. }
  1546. }
  1547. pSV = (GETINFO_STDVAR *)&adwSV[0];
  1548. pSV->dwSize = sizeof(adwSV);
  1549. pSV->dwNumOfVariable = 2;
  1550. pSV->StdVar[0].dwStdVarID = FNT_INFO_FONTHEIGHT;
  1551. pSV->StdVar[1].dwStdVarID = FNT_INFO_FONTWIDTH;
  1552. if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_STDVARIABLE, pSV, 0, NULL))
  1553. {
  1554. ERR(("UFO_GETINFO_STDVARIABLE failed.\n"));
  1555. return FALSE;
  1556. }
  1557. FX_VERBOSE(("SendFontCmd: SV_FH,SV_FW=%d,%d\n",
  1558. pSV->StdVar[0].lStdVariable,
  1559. pSV->StdVar[1].lStdVariable));
  1560. pOEM->iFontId = (WORD)iFontId;
  1561. pOEM->iFontHeight = (WORD)SV_HEIGHT;
  1562. // Support non-square scaling only when the
  1563. // font is non-proportional. (The w parameter
  1564. // of "fontsize" ART command only valid with
  1565. // non-proportional fonts)
  1566. if (!ISPROPFONT(iFontId)) {
  1567. if (ISDBCSFONT(iFontId)) {
  1568. pOEM->iFontWidth = (WORD)SV_WIDTH;
  1569. pOEM->iFontWidth2 = (WORD)(SV_WIDTH * 2);
  1570. pOEM->wSBCSFontWidth = (WORD)SV_WIDTH;
  1571. }
  1572. else {
  1573. pOEM->iFontWidth = (WORD)SV_WIDTH;
  1574. // If fixed pitch font, real width of device font is 80% of SV_WIDTH
  1575. pOEM->wSBCSFontWidth = (WORD)((SV_WIDTH * COEF_FIXPITCH_MUL + COEF_ROUNDUP5_VAL ) / COEF_FIXPITCH_DEV);
  1576. }
  1577. }
  1578. else {
  1579. // Default.
  1580. pOEM->iFontWidth = 0;
  1581. }
  1582. if ( pbuf > buf )
  1583. WRITESPOOLBUF( pdevobj, buf, (INT)(pbuf - buf));
  1584. // Need set iFontId to iTextFontId
  1585. pOEM->iTextFontId = pOEM->iFontId;
  1586. pOEM->iTextFontHeight = pOEM->iFontHeight;
  1587. pOEM->iTextFontWidth = pOEM->iFontWidth;
  1588. pOEM->iTextFontWidth2 = pOEM->iFontWidth2;
  1589. return TRUE;
  1590. }
  1591. BOOL APIENTRY
  1592. bOEMOutputCharStr(
  1593. PDEVOBJ pdevobj,
  1594. PUNIFONTOBJ pUFObj,
  1595. DWORD dwType,
  1596. DWORD dwCount,
  1597. PVOID pGlyph )
  1598. {
  1599. GETINFO_GLYPHSTRING GStr;
  1600. PBYTE aubBuff = NULL;
  1601. PBYTE aubBEnd;
  1602. PTRANSDATA pTrans;
  1603. DWORD dwI;
  1604. PFXPDEV pOEM;
  1605. BOOL ret = FALSE;
  1606. BYTE *pTemp;
  1607. WORD wLen;
  1608. INT iMark = 0;
  1609. // For internal calculation of X-pos.
  1610. DWORD dwGetInfo;
  1611. GETINFO_GLYPHWIDTH GWidth;
  1612. VERBOSE(("OEMOutputCharStr() entry.\n"));
  1613. ASSERT(VALID_PDEVOBJ(pdevobj));
  1614. if(!pdevobj || !pUFObj || !pGlyph)
  1615. {
  1616. ERR(("OEMOutputCharStr: Invalid parameter.\n"));
  1617. goto out;
  1618. }
  1619. // NTRAID#NTBUG9-498278-2002/03/12-yasuho-: Device font !print
  1620. if(dwType == TYPE_GLYPHHANDLE &&
  1621. (pUFObj->ulFontID < 1 || pUFObj->ulFontID > MAX_FONTS) )
  1622. {
  1623. ERR(("OEMOutputCharStr: ulFontID is invalid.\n"));
  1624. goto out;
  1625. }
  1626. pOEM = (PFXPDEV)(pdevobj->pdevOEM);
  1627. switch (dwType)
  1628. {
  1629. case TYPE_GLYPHHANDLE:
  1630. if (dwCount > STRBUFSIZE)
  1631. goto out;
  1632. GStr.dwSize = sizeof (GETINFO_GLYPHSTRING);
  1633. GStr.dwCount = dwCount;
  1634. GStr.dwTypeIn = TYPE_GLYPHHANDLE;
  1635. GStr.pGlyphIn = pGlyph;
  1636. GStr.dwTypeOut = TYPE_TRANSDATA;
  1637. GStr.pGlyphOut = NULL;
  1638. GStr.dwGlyphOutSize = 0;
  1639. /* Get TRANSDATA buffer size */
  1640. if (FALSE != pUFObj->pfnGetInfo(pUFObj,
  1641. UFO_GETINFO_GLYPHSTRING, &GStr, 0, NULL)
  1642. || 0 == GStr.dwGlyphOutSize)
  1643. {
  1644. ERR(("UNIFONTOBJ_GetInfo:UFO_GETINFO_GLYPHSTRING failed.\n"));
  1645. goto out;
  1646. }
  1647. /* Alloc TRANSDATA buffer size */
  1648. if(!(aubBuff = (PBYTE)MemAllocZ(GStr.dwGlyphOutSize)) )
  1649. {
  1650. ERR(("MemAlloc failed.\n"));
  1651. goto out;
  1652. }
  1653. aubBEnd = &aubBuff[GStr.dwGlyphOutSize];
  1654. /* Get actual TRANSDATA */
  1655. GStr.pGlyphOut = (PTRANSDATA)aubBuff;
  1656. if (!pUFObj->pfnGetInfo(pUFObj,
  1657. UFO_GETINFO_GLYPHSTRING, &GStr, 0, NULL))
  1658. {
  1659. ERR(("GetInfo failed.\n"));
  1660. goto out;
  1661. }
  1662. // For internal calculation of X-pos.
  1663. GWidth.dwSize = sizeof(GETINFO_GLYPHWIDTH);
  1664. GWidth.dwCount = dwCount;
  1665. GWidth.dwType = TYPE_GLYPHHANDLE;
  1666. GWidth.pGlyph = pGlyph;
  1667. GWidth.plWidth = pOEM->widBuf;
  1668. if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_GLYPHWIDTH, &GWidth,
  1669. dwGetInfo, &dwGetInfo)) {
  1670. ERR(("UFO_GETINFO_GLYPHWIDTH failed.\n"));
  1671. goto out;
  1672. }
  1673. pTrans = GStr.pGlyphOut;
  1674. for (dwI = 0; dwI < dwCount; dwI ++, pTrans++)
  1675. {
  1676. if ( pOEM->cTextBuf >= sizeof ( pOEM->ajTextBuf ))
  1677. if (!FlushText( pdevobj )) {
  1678. ERR(("OEMOutputCharStr: FlushText failed.\n"));
  1679. goto out;
  1680. }
  1681. if (pOEM->cTextBuf+2 > sizeof (pOEM->ajTextBuf))
  1682. goto out;
  1683. switch (pTrans->ubType & MTYPE_FORMAT_MASK)
  1684. {
  1685. case MTYPE_DIRECT:
  1686. pOEM->ajTextBuf[ pOEM->cTextBuf++ ] = 0;
  1687. pOEM->ajTextBuf[ pOEM->cTextBuf++ ] =
  1688. (BYTE)pTrans->uCode.ubCode;
  1689. break;
  1690. case MTYPE_PAIRED:
  1691. pOEM->ajTextBuf[ pOEM->cTextBuf++ ] =
  1692. (BYTE)pTrans->uCode.ubPairs[0];
  1693. pOEM->ajTextBuf[ pOEM->cTextBuf++ ] =
  1694. (BYTE)pTrans->uCode.ubPairs[1];
  1695. break;
  1696. case MTYPE_COMPOSE:
  1697. pTemp = (BYTE *)(GStr.pGlyphOut) + pTrans->uCode.sCode;
  1698. if (&pTemp[3] > aubBEnd) // length(WORD) + MARK
  1699. goto out;
  1700. // first two bytes are the length of the string
  1701. wLen = *pTemp + (*(pTemp + 1) << 8);
  1702. pTemp += 2;
  1703. switch (*pTemp)
  1704. {
  1705. case MARK_ALT_GSET:
  1706. iMark = MARK_ALT_GSET;
  1707. pTemp++;
  1708. wLen--;
  1709. break;
  1710. }
  1711. if (&pTemp[wLen] > aubBEnd ||
  1712. (pOEM->cTextBuf + wLen * 2) > sizeof(pOEM->ajTextBuf))
  1713. goto out;
  1714. while (wLen--)
  1715. {
  1716. pOEM->ajTextBuf[ pOEM->cTextBuf++ ] = (BYTE)iMark;
  1717. pOEM->ajTextBuf[ pOEM->cTextBuf++ ] = *pTemp++;
  1718. }
  1719. }
  1720. // For internal calculation of X-pos.
  1721. pOEM->lInternalXAdd += (LONG)((LONG)pOEM->widBuf[dwI] * ((LONG)pOEM->wSBCSFontWidth));
  1722. }
  1723. ret = TRUE;
  1724. break;
  1725. }
  1726. // NTRAID#NTBUG9-574495-2002/04/09-yasuho-: Possible memory leak.
  1727. out:
  1728. if (aubBuff) MemFree(aubBuff);
  1729. return ret;
  1730. }