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.

2221 lines
77 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-1998 Microsoft Corporation
  9. COPYRIGHT (C) 1997-1998 SEIKO EPSON CORP.
  10. Module Name:
  11. epageres.c
  12. Abstract:
  13. ESC/Page specific font metrics resource
  14. This file contains code for downloading bitmap TrueType fonts
  15. on Epson ESC/Page printers.
  16. Environment:
  17. Windows NT Unidrv driver
  18. Revision History:
  19. 04/07/97 -zhanw-
  20. Created it.
  21. 07/../97 Epson
  22. Modofied to support ESC/Page
  23. .....
  24. 02/26/98 Epson
  25. Font downloading memory usage legal calculation implemented
  26. TTF download range reduced
  27. Some cleanups
  28. 03/04/02 Epson v-satois
  29. Changed "sprintf" to the function, which is defined strsafe.h, for security.
  30. (For the above purpose, EP_StringCbPrintf_with_int1, EP_StringCbPrintf_with_int2
  31. EP_StringCbPrintf_with_String are made.)
  32. Fixed and verified warnings of PREFAST and buffy.pl and MUNGE.EXE.
  33. 03/11/02 Epson v-satois
  34. For security issues, addition null-checking of pointer.
  35. OEMSendFontCmd : Addition of checking remaining bytes of "pubCmd".
  36. --*/
  37. #include "pdev.h"
  38. // DEBUG
  39. // #define DBGMSGBOX 1 // UNDEF:No MsgBox, 1:level=1, 2:level=2
  40. #ifdef DBGMSGBOX
  41. #include "stdarg.h"
  42. #endif
  43. // DEBUG
  44. //
  45. // ---- M A C R O D E F I N E ----
  46. //
  47. #define CCHMAXCMDLEN 128
  48. #define MAX_GLYPHSTRLEN 256 // maximum glyph string length can be passed from Unidrv
  49. #define FONT_HEADER_SIZE 0x86 // format type 2
  50. #define DOWNLOAD_HEADER_MEMUSG (56 + 256)
  51. #define DOWNLOAD_HDRTBL_MEMUSG 134
  52. #define DOWNLOAD_FNTHDR_MEMUSG 32
  53. #define DOWNLOAD_FONT_MEMUSG(w,h) (((((DWORD)(w) + 31)/32)*4)*(DWORD)(h))
  54. #define DOWNLOAD_MIN_FONT_ID 512
  55. #define DOWNLOAD_NO_DBCS_OFFSET 1024
  56. #define DOWNLOAD_MIN_FONT_ID_NO_DBCS (DOWNLOAD_MIN_FONT_ID + DOWNLOAD_NO_DBCS_OFFSET)
  57. #define DOWNLOAD_MIN_GLYPH_ID 32
  58. #define DOWNLOAD_MAX_GLYPH_ID_J (DOWNLOAD_MIN_GLYPH_ID + 512 - 1)
  59. #define DOWNLOAD_MAX_GLYPH_ID_C (DOWNLOAD_MIN_GLYPH_ID + 512 - 1)
  60. #define DOWNLOAD_MAX_GLYPH_ID_K (DOWNLOAD_MIN_GLYPH_ID + 512 - 1)
  61. #define DOWNLOAD_MAX_GLYPH_ID_H (DOWNLOAD_MIN_GLYPH_ID + 256 - 1)
  62. #define DOWNLOAD_MAX_FONTS 24
  63. #define DOWNLOAD_MAX_HEIGHT 600 // in 600 dpi
  64. #define MASTER_X_UNIT 1200
  65. #define MASTER_Y_UNIT 1200
  66. #define MIN_X_UNIT_DIV 2 // 600 dpi
  67. #define MIN_Y_UNIT_DIV 2 // 600 dpi
  68. #define VERT_PRINT_REL_X 125
  69. #define VERT_PRINT_REL_Y 125
  70. // Make acess to the 2 byte character in a RISC portable manner.
  71. // Note we treat the 2 byte data as BIG-endian short ingeger for
  72. // convenience.
  73. #define SWAPW(x) \
  74. ((WORD)(((WORD)(x) << 8) | ((WORD)(x) >> 8)))
  75. #define GETWORD(p) \
  76. ((WORD)(((WORD)(*((PBYTE)(p))) << 8) + *((PBYTE)(p) + 1)))
  77. #define PUTWORD(p,w) \
  78. (*((PBYTE)(p)) = HIBYTE(w), *((PBYTE)(p) + 1) = LOBYTE(w))
  79. #define PUTWORDINDIRECT(p,pw) \
  80. (*((PBYTE)(p)) = *((PBYTE)(pw) + 1), *((PBYTE)(p) + 1) = *((PBYTE)(pw)))
  81. #define WRITESPOOLBUF(p,s,n) \
  82. ((p)->pDrvProcs->DrvWriteSpoolBuf((p), (s), (n)))
  83. // Internal Locale ID
  84. #define LCID_JPN 0x00000000 // Japan; default
  85. #define LCID_CHT 0x00010000 // Taiwan (ChineseTraditional)
  86. #define LCID_CHS 0x00020000 // PRC (ChineseSimplified)
  87. #define LCID_KOR 0x00030000 // Korea
  88. #define LCID_USA 0x01000000 // US
  89. // OEMCommandCallback callback function ordinal
  90. #define SET_LCID 10 // ()
  91. #define SET_LCID_J (10 + LCID_JPN) // ()
  92. #define SET_LCID_C (10 + LCID_CHT) // ()
  93. #define SET_LCID_K (10 + LCID_CHS) // ()
  94. #define SET_LCID_H (10 + LCID_KOR) // ()
  95. #define SET_LCID_U (10 + LCID_USA) // ()
  96. #define TEXT_PRN_DIRECTION 20 // (PrintDirInCCDegrees)
  97. #define TEXT_SINGLE_BYTE 21 // (FontBold,FontItalic)
  98. #define TEXT_DOUBLE_BYTE 22 // (FontBold,FontItalic)
  99. #define TEXT_BOLD 23 // (FontBold)
  100. #define TEXT_ITALIC 24 // (FontItalic)
  101. #define TEXT_HORIZONTAL 25 // ()
  102. #define TEXT_VERTICAL 26 // ()
  103. #define TEXT_NO_VPADJUST 27 // ()
  104. #define DOWNLOAD_SELECT_FONT_ID 30 // (CurrentFontID)
  105. #define DOWNLOAD_DELETE_FONT 31 // (CurrentFontID)
  106. #define DOWNLOAD_DELETE_ALLFONT 32 // ()
  107. #define DOWNLOAD_SET_FONT_ID 33 // (CurrentFontID)
  108. #define DOWNLOAD_SET_CHAR_CODE 34 // (NextGlyph)
  109. #define EP_FONT_EXPLICITE_ITALIC_FONT (1 << 0)
  110. //
  111. // ---- S T R U C T U R E D E F I N E ----
  112. //
  113. typedef struct tagHEIGHTLIST {
  114. short id; // DWORD aligned for access optimization
  115. WORD Height;
  116. WORD fGeneral; // DWORD aligned for access optimization
  117. WORD Width;
  118. } HEIGHTLIST, *LPHEIGHTLIST;
  119. typedef struct tagEPAGEMDV {
  120. WORD fGeneral;
  121. WORD wListNum;
  122. HEIGHTLIST HeightL[DOWNLOAD_MAX_FONTS];
  123. DWORD dwTextYRes;
  124. DWORD dwTextXRes;
  125. DWORD dwLCID;
  126. DWORD dwMemAvailable;
  127. DWORD dwMaxGlyph;
  128. DWORD dwNextGlyph;
  129. DWORD flAttribute; // 2001/3/1 sid. To save italic attribute of some device font.
  130. int iParamForFSweF;
  131. int iCurrentDLFontID;
  132. int iDevCharOffset;
  133. int iSBCSX;
  134. int iDBCSX;
  135. int iSBCSXMove;
  136. int iSBCSYMove;
  137. int iDBCSXMove;
  138. int iDBCSYMove;
  139. int iEscapement;
  140. } EPAGEMDV, *LPEPAGEMDV;
  141. // fGeneral flags
  142. #define FLAG_DBCS 0x0001
  143. #define FLAG_VERT 0x0002
  144. #define FLAG_PROP 0x0004
  145. #define FLAG_DOUBLE 0x0008
  146. #define FLAG_VERTPRN 0x0010
  147. #define FLAG_NOVPADJ 0x0020
  148. // DEBUG
  149. #ifdef DBGMSGBOX
  150. #define FLAG_SKIPMSG 0x8000
  151. #endif
  152. // DEBUG
  153. typedef struct {
  154. BYTE bFormat;
  155. BYTE bDataDir;
  156. WORD wCharCode;
  157. WORD wBitmapWidth;
  158. WORD wBitmapHeight;
  159. WORD wLeftOffset;
  160. WORD wAscent;
  161. DWORD CharWidth;
  162. } ESCPAGECHAR;
  163. typedef struct {
  164. WORD Integer;
  165. WORD Fraction;
  166. } FRAC;
  167. typedef struct {
  168. WORD wFormatType;
  169. WORD wDataSize;
  170. WORD wSymbolSet;
  171. WORD wCharSpace;
  172. FRAC CharWidth;
  173. FRAC CharHeight;
  174. WORD wFontID;
  175. WORD wWeight; // Line Width
  176. WORD wEscapement; // Rotation
  177. WORD wItalic; // Slant
  178. WORD wLast;
  179. WORD wFirst;
  180. WORD wUnderline;
  181. WORD wUnderlineWidth;
  182. WORD wOverline;
  183. WORD wOverlineWidth;
  184. WORD wStrikeOut;
  185. WORD wStrikeOutWidth;
  186. WORD wCellWidth;
  187. WORD wCellHeight;
  188. WORD wCellLeftOffset;
  189. WORD wCellAscender;
  190. FRAC FixPitchWidth;
  191. } ESCPAGEHEADER, *LPESCPAGEHEADER;
  192. //
  193. // ----- S T A T I C D A T A ---
  194. //
  195. const int ESin[4] = { 0, 1, 0, -1 };
  196. const int ECos[4] = { 1, 0, -1, 0 };
  197. const char DLI_DNLD_HDR[] = "\x1D%d;%ddh{F";
  198. const char DLI_SELECT_FONT_ID[] = "\x1D%ddcF\x1D" "0;0coP";
  199. const char DLI_DELETE_FONT[] = "\x1D%dddcF";
  200. const char DLI_FONTNAME[] = "________________________EPSON_ESC_PAGE_DOWNLOAD_FONT%02d";
  201. const char DLI_SYMBOLSET[] = "ESC_PAGE_DOWNLOAD_FONT_INDEX";
  202. #define SYMBOLSET_LEN (sizeof(DLI_SYMBOLSET) - 1) // adjust for terminating NULL
  203. const char DLI_DNLD1CHAR_H[] = "\x1D%d;";
  204. const char DLI_DNLD1CHAR_P[] = "%d;";
  205. const char DLI_DNLD1CHAR_F[] = "%dsc{F";
  206. const char SET_SINGLE_BYTE[] = "\x1D" "1;0mcF\x1D%d;%dpP";
  207. const char SET_DOUBLE_BYTE[] = "\x1D" "1;1mcF\x1D%d;%dpP";
  208. const char CHAR_PITCH[] = "\x1D" "0spF\x1D%d;%dpP";
  209. const char PRNDIR_POSMOV[] = "\x1D%dpmP";
  210. const char PRN_DIRECTION[] = "\x1D%droF";
  211. const char SET_CHAR_OFFSET[] = "\x1D" "0;%dcoP";
  212. const char SET_CHAR_OFFSET_S[] = "\x1D" "0;%scoP";
  213. const char SET_CHAR_OFFSET_XY[] = "\x1D%d;%dcoP";
  214. const char SET_VERT_PRINT[] = "\x1D%dvpC";
  215. const char SET_BOLD[] = "\x1D%dweF";
  216. const char SET_ITALIC[] = "\x1D%dslF";
  217. const char SET_ITALIC_SINGLEBYTE[] = "\x1D%dstF";
  218. const char SET_REL_X[] = "\x1D%dH";
  219. const char SET_REL_Y[] = "\x1D%dV";
  220. //
  221. // ---- I N T E R N A L F U N C T I O N P R O T O T Y P E ----
  222. //
  223. BOOL PASCAL BInsertHeightList(LPEPAGEMDV lpEpage, int id, WORD wHeight, WORD wWidth, BYTE fProp, BYTE fDBCS);
  224. int PASCAL IGetHLIndex(LPEPAGEMDV lpEpage, int id);
  225. //BYTE PASCAL BTGetProp(LPEPAGEMDV lpEpage, int id);
  226. //BYTE PASCAL BTGetDBCS(LPEPAGEMDV lpEpage, int id);
  227. //WORD PASCAL WGetWidth(LPEPAGEMDV lpEpage, int id);
  228. //WORD PASCAL WGetHeight(LPEPAGEMDV lpEpage, int id);
  229. LONG LConvertFontSizeToStr(LONG size, PSTR pStr, DWORD len);
  230. WORD WConvDBCSCharCode(WORD cc, DWORD LCID);
  231. BOOL BConvPrint(PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, DWORD dwType, DWORD dwCount, PVOID pGlyph);
  232. DWORD CheckAvailableMem(LPEPAGEMDV lpEpage, PUNIFONTOBJ pUFObj);
  233. // These function are substitutes of "sprintf" for security.
  234. size_t EP_StringCbPrintf_with_int1(char *lpBuff, size_t buff_length, const char *pszFormat, int Arg_int1);
  235. size_t EP_StringCbPrintf_with_int2(char *lpBuff, size_t buff_length, const char *pszFormat,
  236. int Arg_int1, int Arg_int2);
  237. size_t EP_StringCbPrintf_with_String(char *lpBuff, size_t buff_length, const char *pszFormat, char *pArgS);
  238. // DEBUG
  239. #ifdef DBGMSGBOX
  240. int DbgMsg(LPEPAGEMDV lpEpage, UINT mbicon, LPCTSTR msgfmt, ...);
  241. int MsgBox(LPEPAGEMDV lpEpage, LPCTSTR msg, UINT mbicon);
  242. #endif
  243. // DEBUG
  244. //
  245. // ---- F U N C T I O N S ----
  246. //
  247. //////////////////////////////////////////////////////////////////////////
  248. // Function: OEMEnablePDEV
  249. //
  250. // Description: OEM callback for DrvEnablePDEV;
  251. // allocate OEM specific memory block
  252. //
  253. // Parameters:
  254. //
  255. // pdevobj Pointer to the DEVOBJ. pdevobj->pdevOEM is undefined.
  256. // pPrinterName name of the current printer.
  257. // cPatterns, phsurfPatterns, cjGdiInfo, pGdiInfo, cjDevInfo, pDevInfo:
  258. // These parameters are identical to what's passed
  259. // into DrvEnablePDEV.
  260. // pded points to a function table which contains the
  261. // system driver's implementation of DDI entrypoints.
  262. //
  263. // Returns:
  264. // Pointer to the PDEVOEM
  265. //
  266. // Comments:
  267. //
  268. //
  269. // History:
  270. // 07/15/97 Created. Epson
  271. //
  272. //////////////////////////////////////////////////////////////////////////
  273. PDEVOEM APIENTRY OEMEnablePDEV(PDEVOBJ pdevobj, PWSTR pPrinterName, ULONG cPatterns, HSURF* phsurfPatterns, ULONG cjGdiInfo, GDIINFO* pGdiInfo, ULONG cjDevInfo, DEVINFO* pDevInfo, DRVENABLEDATA * pded)
  274. {
  275. LPEPAGEMDV lpEpage;
  276. if (pGdiInfo == NULL || pdevobj == NULL) // Checking null-pointer.
  277. {
  278. return NULL;
  279. }
  280. // allocate private data structure
  281. lpEpage = MemAllocZ(sizeof(EPAGEMDV));
  282. if (lpEpage)
  283. {
  284. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMEnablePDEV() entry. PDEVOEM = %x, ulAspectX = %d, ulAspectY = %d\r\n"),
  285. // lpEpage, pGdiInfo->ulAspectX, pGdiInfo->ulAspectX));
  286. // save text resolution
  287. lpEpage->dwTextYRes = pGdiInfo->ulAspectY;
  288. lpEpage->dwTextXRes = pGdiInfo->ulAspectX;
  289. // save pointer to the data structure
  290. lpEpage->flAttribute = 0;
  291. pdevobj->pdevOEM = (PDEVOEM)lpEpage;
  292. }
  293. return (PDEVOEM)lpEpage;
  294. }
  295. //////////////////////////////////////////////////////////////////////////
  296. // Function: OEMDisablePDEV
  297. //
  298. // Description: OEM callback for DrvDisablePDEV;
  299. // free all allocated OEM specific memory block(s)
  300. //
  301. // Parameters:
  302. //
  303. // pdevobj Pointer to the DEVOBJ.
  304. //
  305. // Returns:
  306. // None
  307. //
  308. // Comments:
  309. //
  310. //
  311. // History:
  312. // 07/15/97 Created. Epson
  313. //
  314. //////////////////////////////////////////////////////////////////////////
  315. VOID APIENTRY OEMDisablePDEV(PDEVOBJ pdevobj)
  316. {
  317. LPEPAGEMDV lpEpage;
  318. if (pdevobj == NULL) // Checking null-pointer.
  319. {
  320. return;
  321. }
  322. lpEpage = (LPEPAGEMDV)(pdevobj->pdevOEM);
  323. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMDisablePDEV() entry. PDEVOEM = %x\r\n"), lpEpage));
  324. if (lpEpage)
  325. {
  326. // free private data structure
  327. MemFree(lpEpage);
  328. pdevobj->pdevOEM = NULL;
  329. }
  330. }
  331. BOOL APIENTRY OEMResetPDEV(
  332. PDEVOBJ pdevobjOld,
  333. PDEVOBJ pdevobjNew)
  334. {
  335. LPEPAGEMDV lpEpageOld, lpEpageNew;
  336. if (pdevobjOld == NULL || pdevobjNew == NULL) // Checking null-pointer.
  337. {
  338. return FALSE;
  339. }
  340. lpEpageOld = (LPEPAGEMDV)pdevobjOld->pdevOEM;
  341. lpEpageNew = (LPEPAGEMDV)pdevobjNew->pdevOEM;
  342. if (lpEpageOld != NULL && lpEpageNew != NULL)
  343. *lpEpageNew = *lpEpageOld;
  344. return TRUE;
  345. }
  346. //////////////////////////////////////////////////////////////////////////
  347. // Function: OEMCommandCallback
  348. //
  349. // Description: process Command Callback specified by GPD file
  350. //
  351. //
  352. // Parameters:
  353. //
  354. // pdevobj Pointer to the DEVOBJ.
  355. // dwCmdCbID CallbackID specified in GPD file
  356. // dwCount Parameter count
  357. // pdwParams Pointer to the parameters
  358. //
  359. //
  360. // Returns: 0 : Success, -1 : Error
  361. //
  362. //
  363. // Comments:
  364. //
  365. //
  366. // History:
  367. // 07/../97 Created. -Epson-
  368. //
  369. //////////////////////////////////////////////////////////////////////////
  370. INT APIENTRY OEMCommandCallback(PDEVOBJ pdevobj, DWORD dwCmdCbID, DWORD dwCount, PDWORD pdwParams)
  371. {
  372. LPEPAGEMDV lpEpage;
  373. INT i;
  374. size_t cbCmd;
  375. int id;
  376. int hlx;
  377. BYTE Cmd[256];
  378. // <buffy.pl, strsafe.h>
  379. size_t Cmd_Size = sizeof(Cmd);
  380. if (pdevobj == NULL) // Checking null-pointer.
  381. {
  382. return -1;
  383. }
  384. lpEpage = (LPEPAGEMDV)(pdevobj->pdevOEM);
  385. if (lpEpage == NULL) // Checking null-pointer.
  386. {
  387. return -1;
  388. }
  389. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMCommandCallback(,%d,%d,) entry.\r\n"), dwCmdCbID, dwCount));
  390. //
  391. // verify pdevobj okay
  392. //
  393. ASSERT(VALID_PDEVOBJ(pdevobj));
  394. //
  395. // fill in printer commands
  396. //
  397. cbCmd = 0;
  398. switch (dwCmdCbID & 0xFFFF)
  399. {
  400. case SET_LCID: // 10:()
  401. // set LCID for this job
  402. lpEpage->dwLCID = dwCmdCbID & 0xFFFF0000;
  403. break;
  404. case TEXT_PRN_DIRECTION: // 20:(PrintDirInCCDegrees)
  405. if (dwCount >= 1)
  406. {
  407. int iEsc90;
  408. if (pdwParams == NULL) // Checking null-pointer.
  409. {
  410. return -1;
  411. }
  412. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMCommandCallback(,TEXT_PRN_DIRECTION,%d,[%d]) entry.\r\n"), dwCount, *pdwParams));
  413. lpEpage->iEscapement = (int)*pdwParams;
  414. iEsc90 = lpEpage->iEscapement/90;
  415. cbCmd = EP_StringCbPrintf_with_int1(Cmd, Cmd_Size, PRNDIR_POSMOV, iEsc90 ? 1 : 0);
  416. lpEpage->iSBCSXMove = lpEpage->iSBCSX * ECos[iEsc90];
  417. lpEpage->iSBCSYMove = -lpEpage->iSBCSX * ESin[iEsc90];
  418. if (lpEpage->fGeneral & FLAG_DBCS)
  419. {
  420. lpEpage->iDBCSXMove = lpEpage->iDBCSX * ECos[iEsc90];
  421. lpEpage->iDBCSYMove = -lpEpage->iDBCSX * ESin[iEsc90];
  422. cbCmd += EP_StringCbPrintf_with_int2(&Cmd[cbCmd], Cmd_Size - cbCmd,
  423. SET_CHAR_OFFSET_XY,
  424. lpEpage->iDevCharOffset * ESin[iEsc90],
  425. lpEpage->iDevCharOffset * ECos[iEsc90]);
  426. }
  427. else if (lpEpage->iCurrentDLFontID > 0 && lpEpage->iEscapement)
  428. {
  429. WORD wHeight;
  430. short sXMove, sYMove;
  431. hlx = IGetHLIndex(lpEpage, lpEpage->iCurrentDLFontID);
  432. if (hlx < 0) // Checking the return value.
  433. {
  434. return -1;
  435. }
  436. wHeight = (hlx >= 0) ? lpEpage->HeightL[hlx].Height : 0;
  437. sXMove = -(short)wHeight * ESin[iEsc90];
  438. sYMove = -(short)wHeight * ECos[iEsc90];
  439. cbCmd += EP_StringCbPrintf_with_int2(&Cmd[cbCmd], Cmd_Size - cbCmd,
  440. SET_CHAR_OFFSET_XY, (int)sXMove, (int)sYMove);
  441. }
  442. else
  443. {
  444. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  445. SET_CHAR_OFFSET, 0);
  446. }
  447. if (!(lpEpage->fGeneral & (FLAG_DBCS | FLAG_PROP)) ||
  448. ((lpEpage->fGeneral & FLAG_DBCS) &&
  449. !(lpEpage->fGeneral & FLAG_DOUBLE)))
  450. {
  451. cbCmd += EP_StringCbPrintf_with_int2(&Cmd[cbCmd], Cmd_Size - cbCmd, CHAR_PITCH,
  452. lpEpage->iSBCSXMove, lpEpage->iSBCSYMove);
  453. }
  454. else if ((FLAG_DBCS | FLAG_DOUBLE) ==
  455. (lpEpage->fGeneral & (FLAG_DBCS | FLAG_DOUBLE)))
  456. {
  457. cbCmd += EP_StringCbPrintf_with_int2(&Cmd[cbCmd], Cmd_Size - cbCmd, CHAR_PITCH,
  458. lpEpage->iDBCSXMove, lpEpage->iDBCSYMove);
  459. }
  460. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  461. PRN_DIRECTION, lpEpage->iEscapement);
  462. }
  463. break;
  464. case TEXT_SINGLE_BYTE: // 21:(FontBold,FontItalic)
  465. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMCommandCallback(,TEXT_SINGLE_BYTE,%d,) entry.\r\n"), dwCount));
  466. cbCmd = EP_StringCbPrintf_with_int2(Cmd, Cmd_Size, SET_SINGLE_BYTE,
  467. lpEpage->iSBCSXMove, lpEpage->iSBCSYMove);
  468. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  469. PRN_DIRECTION, lpEpage->iEscapement);
  470. if (lpEpage->fGeneral & FLAG_VERT)
  471. {
  472. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd, SET_VERT_PRINT, 0);
  473. }
  474. lpEpage->fGeneral &= ~FLAG_DOUBLE;
  475. goto SetBoldItalic;
  476. case TEXT_DOUBLE_BYTE: // 22:(FontBold,FontItalic)
  477. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMCommandCallback(,TEXT_DOUBLE_BYTE,%d,) entry.\r\n"), dwCount));
  478. cbCmd = EP_StringCbPrintf_with_int2(Cmd, Cmd_Size, SET_DOUBLE_BYTE,
  479. lpEpage->iDBCSXMove, lpEpage->iDBCSYMove);
  480. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  481. PRN_DIRECTION, lpEpage->iEscapement);
  482. if (lpEpage->fGeneral & FLAG_VERT)
  483. {
  484. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  485. SET_VERT_PRINT, 1);
  486. }
  487. else
  488. {
  489. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  490. SET_VERT_PRINT, 0);
  491. }
  492. lpEpage->fGeneral |= FLAG_DOUBLE;
  493. SetBoldItalic:
  494. if (dwCount >= 2)
  495. {
  496. // DBGPRINT(DBG_WARNING, (DLLTEXT(" Bold = %d, Italic = %d\r\n"), pdwParams[0], pdwParams[1]));
  497. if (pdwParams == NULL) // Checking null-pointer.
  498. {
  499. return -1;
  500. }
  501. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd, SET_BOLD,
  502. pdwParams[0] ? lpEpage->iParamForFSweF + 3 :
  503. lpEpage->iParamForFSweF);
  504. // #517722: PREFAST
  505. if (!(lpEpage->flAttribute & EP_FONT_EXPLICITE_ITALIC_FONT))
  506. {
  507. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd, SET_ITALIC,
  508. pdwParams[1] ? 346 : 0);
  509. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  510. SET_ITALIC_SINGLEBYTE, pdwParams[1] ? 1 : 0);
  511. }
  512. }
  513. break;
  514. case TEXT_BOLD: // 23:(FontBold)
  515. if (dwCount >= 1)
  516. {
  517. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMCommandCallback(,TEXT_BOLD,%d,%d) entry.\r\n"), dwCount, *pdwParams));
  518. if (pdwParams == NULL) // Checking null-pointer.
  519. {
  520. return -1;
  521. }
  522. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd, SET_BOLD,
  523. (*pdwParams) ? lpEpage->iParamForFSweF + 3 :
  524. lpEpage->iParamForFSweF);
  525. }
  526. break;
  527. case TEXT_ITALIC: // 24:(FontItalic)
  528. if (dwCount >= 1)
  529. {
  530. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMCommandCallback(,TEXT_ITALIC,%d,%d) entry.\r\n"), dwCount, *pdwParams));
  531. if (!(lpEpage->flAttribute & EP_FONT_EXPLICITE_ITALIC_FONT))
  532. {
  533. if (pdwParams == NULL) // Checking null-pointer.
  534. {
  535. return -1;
  536. }
  537. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd, SET_ITALIC,
  538. (*pdwParams) ? 346 : 0);
  539. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  540. SET_ITALIC_SINGLEBYTE, (*pdwParams) ? 1 : 0);
  541. }
  542. }
  543. break;
  544. case TEXT_HORIZONTAL: // 25:()
  545. // DEBUG
  546. #ifdef DBGMSGBOX
  547. DbgMsg(lpEpage, MB_OK, L"VertPrn = Off");
  548. #endif
  549. // DEBUG
  550. cbCmd = EP_StringCbPrintf_with_int1(Cmd, Cmd_Size, SET_VERT_PRINT, 0);
  551. lpEpage->fGeneral &= ~FLAG_VERTPRN;
  552. break;
  553. case TEXT_VERTICAL: // 26:()
  554. // DEBUG
  555. #ifdef DBGMSGBOX
  556. DbgMsg(lpEpage, MB_OK, L"VertPrn = On");
  557. #endif
  558. // DEBUG
  559. cbCmd = EP_StringCbPrintf_with_int1(Cmd, Cmd_Size, SET_VERT_PRINT, 1);
  560. lpEpage->fGeneral |= FLAG_VERTPRN;
  561. break;
  562. case TEXT_NO_VPADJUST: // 27:()
  563. lpEpage->fGeneral |= FLAG_NOVPADJ;
  564. break;
  565. case DOWNLOAD_SELECT_FONT_ID: // 30:(CurrentFontID)
  566. if (dwCount >= 1)
  567. {
  568. if (pdwParams == NULL) // Checking null-pointer.
  569. {
  570. return -1;
  571. }
  572. id = (int)*pdwParams;
  573. // adjust FontID by DOWNLOAD_NO_DBCS_OFFSET if needed
  574. if (id >= DOWNLOAD_MIN_FONT_ID_NO_DBCS)
  575. {
  576. id -= DOWNLOAD_NO_DBCS_OFFSET;
  577. }
  578. hlx = IGetHLIndex(lpEpage, id);
  579. if (hlx >= 0)
  580. { // FontID registered
  581. // DBGPRINT(DBG_WARNING, (DLLTEXT("DOWNLOAD_SELECT_FONT_ID:FontID=%d\r\n"), id));
  582. lpEpage->iCurrentDLFontID = id;
  583. lpEpage->fGeneral &= ~(FLAG_DBCS | FLAG_VERT | FLAG_DOUBLE);
  584. if (lpEpage->HeightL[hlx].fGeneral & FLAG_PROP)
  585. lpEpage->fGeneral |= FLAG_PROP;
  586. else
  587. lpEpage->fGeneral &= ~FLAG_PROP;
  588. lpEpage->iParamForFSweF = 0;
  589. lpEpage->iSBCSX = lpEpage->HeightL[hlx].Width;
  590. lpEpage->iDBCSX = 0;
  591. cbCmd = EP_StringCbPrintf_with_int1(Cmd, Cmd_Size,
  592. DLI_SELECT_FONT_ID, id - DOWNLOAD_MIN_FONT_ID);
  593. }
  594. else // Checking the return value.
  595. {
  596. return -1;
  597. }
  598. }
  599. break;
  600. case DOWNLOAD_DELETE_FONT: // 31:(CurrentFontID)
  601. if (dwCount >= 1)
  602. {
  603. if (pdwParams == NULL) // Checking null-pointer.
  604. {
  605. return -1;
  606. }
  607. id = (int)*pdwParams;
  608. // adjust FontID by DOWNLOAD_NO_DBCS_OFFSET if needed
  609. if (id >= DOWNLOAD_MIN_FONT_ID_NO_DBCS)
  610. {
  611. id -= DOWNLOAD_NO_DBCS_OFFSET;
  612. }
  613. hlx = IGetHLIndex(lpEpage, id);
  614. if (hlx >= 0)
  615. { // FontID registered
  616. // set up font delete command
  617. cbCmd = EP_StringCbPrintf_with_int1(Cmd, Cmd_Size,
  618. DLI_DELETE_FONT, id - DOWNLOAD_MIN_FONT_ID);
  619. // move HeightList table contents
  620. for (i = hlx; i + 1 < lpEpage->wListNum; i++)
  621. {
  622. lpEpage->HeightL[i].id = lpEpage->HeightL[i + 1].id;
  623. lpEpage->HeightL[i].fGeneral = lpEpage->HeightL[i + 1].fGeneral;
  624. lpEpage->HeightL[i].Height = lpEpage->HeightL[i + 1].Height;
  625. lpEpage->HeightL[i].Width = lpEpage->HeightL[i + 1].Width;
  626. }
  627. // decrease the total number
  628. lpEpage->wListNum--;
  629. }
  630. else // Checking the return value.
  631. {
  632. return -1;
  633. }
  634. }
  635. break;
  636. case DOWNLOAD_DELETE_ALLFONT: // 32:()
  637. for (i = 0; i < (int)lpEpage->wListNum ; i++)
  638. {
  639. cbCmd += EP_StringCbPrintf_with_int1(&Cmd[cbCmd], Cmd_Size - cbCmd,
  640. DLI_DELETE_FONT, (WORD)lpEpage->HeightL[i].id - DOWNLOAD_MIN_FONT_ID);
  641. lpEpage->HeightL[i].id = 0;
  642. }
  643. lpEpage->wListNum = 0;
  644. break;
  645. case DOWNLOAD_SET_FONT_ID: // 33:(CurrentFontID)
  646. if (dwCount >= 1)
  647. {
  648. if (pdwParams == NULL) // Checking null-pointer.
  649. {
  650. return -1;
  651. }
  652. id = (int)*pdwParams;
  653. // adjust FontID by DOWNLOAD_NO_DBCS_OFFSET if needed
  654. if (id >= DOWNLOAD_MIN_FONT_ID_NO_DBCS)
  655. {
  656. id -= DOWNLOAD_NO_DBCS_OFFSET;
  657. }
  658. hlx = IGetHLIndex(lpEpage, id);
  659. if (hlx >= 0 && lpEpage->iCurrentDLFontID != id)
  660. { // FontID registered && not active
  661. // DBGPRINT(DBG_WARNING, (DLLTEXT("DOWNLOAD_SET_FONT_ID:FontID=%d\r\n"), id));
  662. cbCmd = EP_StringCbPrintf_with_int1(Cmd, Cmd_Size,
  663. DLI_SELECT_FONT_ID, id - DOWNLOAD_MIN_FONT_ID);
  664. lpEpage->iParamForFSweF = 0;
  665. lpEpage->iCurrentDLFontID = id;
  666. }
  667. else if (hlx < 0) // Checking the return value.
  668. {
  669. return -1;
  670. }
  671. }
  672. break;
  673. case DOWNLOAD_SET_CHAR_CODE: // 34:(NextGlyph)
  674. if (dwCount >= 1)
  675. {
  676. if (pdwParams == NULL) // Checking null-pointer.
  677. {
  678. return -1;
  679. }
  680. // DBGPRINT(DBG_WARNING, (DLLTEXT("DOWNLOAD_SET_CHAR_CODE:NextGlyph=%Xh\r\n"), pdwParams[0]));
  681. // save next glyph
  682. lpEpage->dwNextGlyph = pdwParams[0];
  683. }
  684. break;
  685. default:
  686. ERR(("Unexpected OEMCommandCallback(,%d,%d,%.8lX)\r\n", dwCmdCbID, dwCount, pdwParams));
  687. break;
  688. }
  689. if (cbCmd)
  690. {
  691. WRITESPOOLBUF(pdevobj, Cmd, cbCmd);
  692. }
  693. return 0;
  694. }
  695. //////////////////////////////////////////////////////////////////////////
  696. // Function: OEMDownloadFontHeader
  697. //
  698. // Description: download font header of ESC/Page
  699. //
  700. //
  701. // Parameters:
  702. //
  703. // pdevobj Pointer to the DEVOBJ.
  704. //
  705. // pUFObj Pointer to the UNIFONTOBJ.
  706. //
  707. //
  708. // Returns:
  709. // required amount of memory
  710. //
  711. // Comments:
  712. //
  713. //
  714. // History:
  715. // 07/../97 Created. -Epson-
  716. //
  717. //////////////////////////////////////////////////////////////////////////
  718. DWORD APIENTRY OEMDownloadFontHeader(PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj)
  719. {
  720. ESCPAGEHEADER FontHeader;
  721. BYTE Buff[64]; // buffy.pl : Increasing the size of "Buff"(56->64bytes).
  722. int iSizeOfBuf;
  723. LPEPAGEMDV lpEpage;
  724. PIFIMETRICS pIFI;
  725. int id;
  726. int idx;
  727. BYTE bPS;
  728. BYTE bDBCS;
  729. DWORD adwStdVariable[2 + 2 * 2];
  730. PGETINFO_STDVAR pSV = (PGETINFO_STDVAR)adwStdVariable;
  731. DWORD height, width, dwTemp;
  732. DWORD MemAvailable;
  733. if (pdevobj == NULL || pUFObj == NULL) // Checking null-pointer.
  734. {
  735. return 0;
  736. }
  737. lpEpage = (LPEPAGEMDV)(pdevobj->pdevOEM);
  738. if (lpEpage == NULL) // Checking null-pointer.
  739. {
  740. return 0;
  741. }
  742. pIFI = pUFObj->pIFIMetrics;
  743. if (pIFI == NULL) // Checking null-pointer.
  744. {
  745. return 0;
  746. }
  747. id = (int)(pUFObj->ulFontID);
  748. idx = id - DOWNLOAD_MIN_FONT_ID;
  749. bPS = (BYTE)((pIFI->jWinPitchAndFamily & 0x03) == VARIABLE_PITCH);
  750. bDBCS = (BYTE)IS_DBCSCHARSET(pIFI->jWinCharSet);
  751. // check FontID
  752. if (idx < 0)
  753. return 0; // error for invalid FontID
  754. // special check for avoiding DBCS TTF downloading
  755. if (id >= DOWNLOAD_MIN_FONT_ID_NO_DBCS)
  756. {
  757. if (bDBCS)
  758. return 0; // treat as error for DBCS
  759. // adjust FontID by DOWNLOAD_NO_DBCS_OFFSET for SBCS
  760. id -= DOWNLOAD_NO_DBCS_OFFSET;
  761. idx -= DOWNLOAD_NO_DBCS_OFFSET;
  762. }
  763. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMDownloadFontHeader(%S) entry. ulFontID=%d, bPS=%d, bDBCS=%d\r\n"),
  764. // ((pIFI->dpwszFaceName) ? (LPWSTR)((LPBYTE)pIFI + pIFI->dpwszFaceName) : L"?"), id, bPS, bDBCS));
  765. pSV->dwSize = sizeof(GETINFO_STDVAR) + 2 * sizeof(DWORD) * (2 - 1);
  766. pSV->dwNumOfVariable = 2;
  767. pSV->StdVar[0].dwStdVarID = FNT_INFO_FONTHEIGHT;
  768. pSV->StdVar[1].dwStdVarID = FNT_INFO_FONTWIDTH;
  769. if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_STDVARIABLE, pSV, 0, NULL))
  770. {
  771. ERR(("UFO_GETINFO_STDVARIABLE failed.\r\n"));
  772. return 0; // error
  773. }
  774. // LConvertFontSizeToStr((pSV->StdVar[0].lStdVariable * 2540L) / MASTER_Y_UNIT, Buff);
  775. // DBGPRINT(DBG_WARNING, (DLLTEXT(" FontHeight: %d (%s mm)\r\n"), pSV->StdVar[0].lStdVariable, Buff));
  776. // LConvertFontSizeToStr((pSV->StdVar[1].lStdVariable * 2540L) / MASTER_X_UNIT, Buff);
  777. // DBGPRINT(DBG_WARNING, (DLLTEXT(" FontWidth: %d (%s mm)\r\n"), pSV->StdVar[1].lStdVariable, Buff));
  778. // preset character size
  779. // FontHeight, FontWidth set in Minimum Unit for ESC/Page
  780. height = pSV->StdVar[0].lStdVariable / MIN_Y_UNIT_DIV;
  781. width = pSV->StdVar[1].lStdVariable / MIN_X_UNIT_DIV;
  782. // get memory information
  783. MemAvailable = CheckAvailableMem(lpEpage, pUFObj);
  784. // DBGPRINT(DBG_WARNING, (DLLTEXT("Available memory = %d bytes\r\n"), MemAvailable));
  785. if (MemAvailable < DOWNLOAD_HEADER_MEMUSG)
  786. {
  787. ERR(("Insufficient memory for TTF download.\r\n"));
  788. return 0; // error
  789. }
  790. // set dwMaxGlyph according to the dwRemainingMemory
  791. if (bDBCS &&
  792. ((long)MemAvailable >= 256 * (long)(DOWNLOAD_FNTHDR_MEMUSG +
  793. DOWNLOAD_FONT_MEMUSG(width, height))))
  794. {
  795. switch (lpEpage->dwLCID)
  796. {
  797. case LCID_JPN:
  798. lpEpage->dwMaxGlyph = DOWNLOAD_MAX_GLYPH_ID_J;
  799. break;
  800. case LCID_CHS:
  801. lpEpage->dwMaxGlyph = DOWNLOAD_MAX_GLYPH_ID_K;
  802. break;
  803. case LCID_CHT:
  804. lpEpage->dwMaxGlyph = DOWNLOAD_MAX_GLYPH_ID_C;
  805. break;
  806. case LCID_KOR:
  807. lpEpage->dwMaxGlyph = DOWNLOAD_MAX_GLYPH_ID_H;
  808. break;
  809. }
  810. }
  811. else
  812. lpEpage->dwMaxGlyph = 255;
  813. // fill FontHeader w/ 0 to optimize setting 0s
  814. ZeroMemory(&FontHeader, sizeof(ESCPAGEHEADER));
  815. if (bPS) // VARIABLE_PITCH
  816. lpEpage->fGeneral |= FLAG_PROP;
  817. else
  818. lpEpage->fGeneral &= ~FLAG_PROP;
  819. if (!BInsertHeightList(lpEpage, id, (WORD)height, (WORD)width, bPS, bDBCS))
  820. {
  821. ERR(("Can't register download font.\r\n"));
  822. return 0; // error
  823. }
  824. lpEpage->iParamForFSweF = 0;
  825. lpEpage->iSBCSX = width;
  826. lpEpage->iDBCSX = 0;
  827. FontHeader.wFormatType = SWAPW(0x0002);
  828. FontHeader.wDataSize = SWAPW(FONT_HEADER_SIZE);
  829. //
  830. // ALWAYS PROPORTINAL SPACING REQUIRED
  831. //
  832. // This resolves the following problems:
  833. // o The width of Half-width DBCS fonts are doubled
  834. // o Fixed picth fonts are shifted gradually
  835. //
  836. // proportional spacing
  837. FontHeader.wCharSpace = SWAPW(1);
  838. FontHeader.CharWidth.Integer = (WORD)SWAPW(0x100);
  839. //OK FontHeader.CharWidth.Fraction = 0;
  840. FontHeader.CharHeight.Integer = SWAPW(height);
  841. //OK FontHeader.CharHeight.Fraction = 0;
  842. // in the range 128 - 255
  843. FontHeader.wFontID = SWAPW(idx + (idx < 0x80 ? 0x80 : 0x00));
  844. //OK FontHeader.wWeight = 0;
  845. //OK FontHeader.wEscapement = 0;
  846. //OK FontHeader.wItalic = 0;
  847. if (bDBCS)
  848. {
  849. FontHeader.wSymbolSet = SWAPW(idx + 0xC000); // idx + C000h for DBCS
  850. if (lpEpage->dwLCID == LCID_KOR)
  851. {
  852. FontHeader.wFirst = SWAPW(0xA1A1);
  853. FontHeader.wLast = SWAPW(0xA3FE); // less than or equal to 282 chars
  854. }
  855. else
  856. {
  857. FontHeader.wFirst = SWAPW(0x2121);
  858. FontHeader.wLast = SWAPW((lpEpage->dwMaxGlyph > 255) ? 0x267E : 0x237E);
  859. }
  860. }
  861. else
  862. {
  863. FontHeader.wSymbolSet = SWAPW(idx + 0x4000); // idx + 4000h for SBCS
  864. FontHeader.wFirst = SWAPW(32);
  865. FontHeader.wLast = SWAPW(255);
  866. }
  867. //OK FontHeader.wUnderline = 0;
  868. FontHeader.wUnderlineWidth = SWAPW(10);
  869. //OK FontHeader.wOverline = 0;
  870. //OK FontHeader.wOverlineWidth = 0;
  871. //OK FontHeader.wStrikeOut = 0;
  872. //OK FontHeader.wStrikeOutWidth = 0;
  873. FontHeader.wCellWidth = SWAPW(width);
  874. FontHeader.wCellHeight = SWAPW(height);
  875. //OK FontHeader.wCellLeftOffset = 0;
  876. dwTemp = height * pIFI->fwdWinAscender / (pIFI->fwdWinAscender + pIFI->fwdWinDescender);
  877. FontHeader.wCellAscender = SWAPW(dwTemp);
  878. FontHeader.FixPitchWidth.Integer = SWAPW(width);
  879. //OK FontHeader.FixPitchWidth.Fraction = 0;
  880. iSizeOfBuf = EP_StringCbPrintf_with_int2(Buff, sizeof(Buff),
  881. DLI_DNLD_HDR, FONT_HEADER_SIZE, idx);
  882. WRITESPOOLBUF(pdevobj, Buff, iSizeOfBuf);
  883. WRITESPOOLBUF(pdevobj, &FontHeader, sizeof(ESCPAGEHEADER));
  884. iSizeOfBuf = EP_StringCbPrintf_with_int1(Buff, sizeof(Buff), DLI_FONTNAME, idx);
  885. WRITESPOOLBUF(pdevobj, Buff, iSizeOfBuf);
  886. WRITESPOOLBUF(pdevobj, (LPBYTE)DLI_SYMBOLSET, SYMBOLSET_LEN);
  887. iSizeOfBuf = EP_StringCbPrintf_with_int1(Buff, sizeof(Buff), DLI_SELECT_FONT_ID, idx);
  888. WRITESPOOLBUF(pdevobj, Buff, iSizeOfBuf);
  889. lpEpage->iCurrentDLFontID = id;
  890. dwTemp = DOWNLOAD_HEADER_MEMUSG;
  891. // management area required for every 32 header registration
  892. if ((lpEpage->wListNum & 0x1F) == 0x01)
  893. dwTemp += DOWNLOAD_HDRTBL_MEMUSG;
  894. return dwTemp;
  895. }
  896. //////////////////////////////////////////////////////////////////////////
  897. // Function: OEMDownloadCharGlyph
  898. //
  899. // Description: download character glyph
  900. //
  901. //
  902. // Parameters:
  903. //
  904. // pdevobj Pointer to the DEVOBJ.
  905. // pUFObj Pointer to the UNIFONTOBJ.
  906. // hGlyph Glyph handle to download
  907. // pdwWidth Pointer to DWORD width buffer.
  908. // Minidirer has to set the width of downloaded glyph data.
  909. //
  910. // Returns:
  911. // Necessary amount of memory to download this character glyph in the printer.
  912. // If returning 0, UNIDRV assumes that this function failed.
  913. //
  914. // Comments:
  915. //
  916. //
  917. // History:
  918. // 07/../97 Created. -Epson-
  919. //
  920. //////////////////////////////////////////////////////////////////////////
  921. DWORD APIENTRY OEMDownloadCharGlyph(PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, HGLYPH hGlyph, PDWORD pdwWidth)
  922. {
  923. GETINFO_GLYPHBITMAP GBmp;
  924. GLYPHBITS *pgb;
  925. ESCPAGECHAR ESCPageChar;
  926. int iSizeOfBuf;
  927. int hlx;
  928. DWORD dwSize;
  929. LPEPAGEMDV lpEpage;
  930. BYTE Buff[32];
  931. int id;
  932. WORD cp;
  933. DWORD CharIncX;
  934. DWORD dwMemUsg;
  935. BYTE bDBCS;
  936. if (pdevobj == NULL || pUFObj == NULL) // Checking null-pointer.
  937. {
  938. return 0;
  939. }
  940. lpEpage = (LPEPAGEMDV)(pdevobj->pdevOEM);
  941. if (lpEpage == NULL) // Checking null-pointer.
  942. {
  943. return 0;
  944. }
  945. id = (int)(pUFObj->ulFontID);
  946. // check FontID
  947. if (id < DOWNLOAD_MIN_FONT_ID)
  948. return 0; // error for invalid FontID
  949. // validate Download FontID
  950. hlx = IGetHLIndex(lpEpage, id);
  951. if (hlx < 0)
  952. {
  953. ERR(("Invalid Download FontID(%d).\r\n", id));
  954. return 0; // error
  955. }
  956. // cache DBCS flag
  957. bDBCS = lpEpage->HeightL[hlx].fGeneral & FLAG_DBCS;
  958. // special check for avoiding DBCS TTF downloading
  959. if (id >= DOWNLOAD_MIN_FONT_ID_NO_DBCS)
  960. {
  961. if (bDBCS)
  962. return 0; // treat as error for DBCS
  963. // adjust FontID by DOWNLOAD_NO_DBCS_OFFSET for SBCS
  964. id -= DOWNLOAD_NO_DBCS_OFFSET;
  965. }
  966. // check GlyphID range
  967. if (lpEpage->dwNextGlyph > lpEpage->dwMaxGlyph)
  968. {
  969. ERR(("No more TTF downloading allowed (GlyphID=%d).\r\n", lpEpage->dwNextGlyph));
  970. return 0; // error
  971. }
  972. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMDownloadCharGlyph() entry. ulFontID = %d, hGlyph = %d\r\n"), id, hGlyph));
  973. //
  974. // Get the character information.
  975. //
  976. // Get Glyph Bitmap
  977. GBmp.dwSize = sizeof(GETINFO_GLYPHBITMAP);
  978. GBmp.hGlyph = hGlyph;
  979. GBmp.pGlyphData = NULL;
  980. if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_GLYPHBITMAP, &GBmp, 0, NULL))
  981. {
  982. ERR(("UNIFONTOBJ_GetInfo:UFO_GETINFO_GLYPHBITMAP failed.\r\n"));
  983. return 0;
  984. }
  985. pgb = GBmp.pGlyphData->gdf.pgb;
  986. if (pgb == NULL) // Checking null-pointer.
  987. {
  988. return 0;
  989. }
  990. // Note that ptqD.{x|y}.HighPart is 28.4 format;
  991. // i.e. device coord. multiplied by 16.
  992. CharIncX = (GBmp.pGlyphData->ptqD.x.HighPart + 15) >> 4;
  993. // DBGPRINT(DBG_WARNING, (DLLTEXT("Origin.x = %d\n"), pgb->ptlOrigin.x));
  994. // DBGPRINT(DBG_WARNING, (DLLTEXT("Origin.y = %d\n"), pgb->ptlOrigin.y));
  995. // DBGPRINT(DBG_WARNING, (DLLTEXT("Extent.cx = %d\n"), pgb->sizlBitmap.cx));
  996. // DBGPRINT(DBG_WARNING, (DLLTEXT("Extent.cy = %d\n"), pgb->sizlBitmap.cy));
  997. // DBGPRINT(DBG_WARNING, (DLLTEXT("CharInc.x = %d\n"), CharIncX));
  998. // DBGPRINT(DBG_WARNING, (DLLTEXT("CharInc.y = %d\n"), (GBmp.pGlyphData->ptqD.y.HighPart + 15) >> 4));
  999. dwMemUsg = DOWNLOAD_FNTHDR_MEMUSG + DOWNLOAD_FONT_MEMUSG(CharIncX, (GBmp.pGlyphData->ptqD.y.HighPart + 15) >> 4);
  1000. if (CheckAvailableMem(lpEpage, pUFObj) < dwMemUsg)
  1001. {
  1002. ERR(("Insufficient memory for OEMDownloadCharGlyph.\r\n"));
  1003. return 0; // error
  1004. }
  1005. // retrieve NextGlyph
  1006. cp = (WORD)lpEpage->dwNextGlyph;
  1007. // for DBCS, modify cp to printable char code
  1008. if (bDBCS)
  1009. {
  1010. cp = WConvDBCSCharCode(cp, lpEpage->dwLCID);
  1011. }
  1012. //
  1013. // Fill character header.
  1014. //
  1015. ZeroMemory(&ESCPageChar, sizeof(ESCPAGECHAR)); // Safe initial values
  1016. // fill in the charcter header information.
  1017. ESCPageChar.bFormat = 0x01;
  1018. ESCPageChar.bDataDir = 0x10;
  1019. ESCPageChar.wCharCode = (bDBCS) ? SWAPW(cp) : LOBYTE(cp);
  1020. ESCPageChar.wBitmapWidth = SWAPW(pgb->sizlBitmap.cx);
  1021. ESCPageChar.wBitmapHeight = SWAPW(pgb->sizlBitmap.cy);
  1022. ESCPageChar.wLeftOffset = SWAPW(pgb->ptlOrigin.x);
  1023. ESCPageChar.wAscent = SWAPW(-pgb->ptlOrigin.y); // negate (to be positive)
  1024. ESCPageChar.CharWidth = MAKELONG(SWAPW(CharIncX), 0);
  1025. dwSize = pgb->sizlBitmap.cy * ((pgb->sizlBitmap.cx + 7) >> 3);
  1026. iSizeOfBuf = EP_StringCbPrintf_with_int1(Buff, sizeof(Buff),
  1027. DLI_DNLD1CHAR_H, dwSize + sizeof(ESCPAGECHAR));
  1028. if (bDBCS) // for DBCS, set additional high byte
  1029. iSizeOfBuf += EP_StringCbPrintf_with_int1(&Buff[iSizeOfBuf], sizeof(Buff) - iSizeOfBuf,
  1030. DLI_DNLD1CHAR_P, HIBYTE(cp));
  1031. iSizeOfBuf += EP_StringCbPrintf_with_int1(&Buff[iSizeOfBuf], sizeof(Buff) - iSizeOfBuf,
  1032. DLI_DNLD1CHAR_F, LOBYTE(cp));
  1033. WRITESPOOLBUF(pdevobj, Buff, iSizeOfBuf);
  1034. WRITESPOOLBUF(pdevobj, &ESCPageChar, sizeof(ESCPAGECHAR));
  1035. WRITESPOOLBUF(pdevobj, pgb->aj, dwSize);
  1036. if (pdwWidth)
  1037. *pdwWidth = CharIncX;
  1038. return dwMemUsg;
  1039. }
  1040. //////////////////////////////////////////////////////////////////////////
  1041. // Function: OEMTTDownloadMethod
  1042. //
  1043. // Description: determines TT font downloading method
  1044. //
  1045. //
  1046. // Parameters:
  1047. //
  1048. // pdevobj Pointer to the DEVOBJ.
  1049. //
  1050. // pFontObj Pointer to the FONTOBJ.
  1051. //
  1052. //
  1053. // Returns: TTDOWNLOAD_???? flag: one of these
  1054. // TTDOWNLOAD_DONTCARE Minidriver doesn't care how this font is handled.
  1055. // TTDOWNLOAD_GRAPHICS Minidriver prefers printing this TT font as graphics.
  1056. // TTDOWNLOAD_BITMAP Minidriver prefers download this TT font as bitmap soft font.
  1057. // TTDOWNLOAD_TTOUTLINE Minidriver prefers downloading this TT fonta as TT outline soft font. This printer must have TT rasterizer support. UNIDRV will provide pointer to the memory mapped TT file, through callback. The minidriver has to parser the TT file by itself.
  1058. //
  1059. //
  1060. // Comments:
  1061. // The judgement is very unreliable !!!
  1062. //
  1063. // History:
  1064. // 07/../97 Created. -Epson-
  1065. //
  1066. //////////////////////////////////////////////////////////////////////////
  1067. DWORD APIENTRY OEMTTDownloadMethod(PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj)
  1068. {
  1069. DWORD ttdlf = TTDOWNLOAD_GRAPHICS;
  1070. // LPEPAGEMDV lpEpage; // (Delete) This variable is not used anywhere .
  1071. DWORD adwStdVariable[2 + 2 * 1];
  1072. PGETINFO_STDVAR pSV = (PGETINFO_STDVAR)adwStdVariable;
  1073. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMTTDownloadMethod entry. jWinCharSet = %d\r\n"), pUFObj->pIFIMetrics->jWinCharSet));
  1074. // lpEpage = (LPEPAGEMDV)(pdevobj->pdevOEM);
  1075. pSV->dwSize = sizeof(GETINFO_STDVAR) + 2 * sizeof(DWORD) * (1 - 1);
  1076. pSV->dwNumOfVariable = 1;
  1077. pSV->StdVar[0].dwStdVarID = FNT_INFO_FONTHEIGHT;
  1078. if (pUFObj == NULL) // Checking null-pointer.
  1079. {
  1080. return ttdlf;
  1081. }
  1082. if (pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_STDVARIABLE, pSV, 0, NULL) &&
  1083. pSV->StdVar[0].lStdVariable < DOWNLOAD_MAX_HEIGHT * MIN_Y_UNIT_DIV)
  1084. { // not so big font size
  1085. ttdlf = TTDOWNLOAD_BITMAP; // download bitmap font
  1086. }
  1087. else
  1088. {
  1089. WARNING(("OEMTTDownloadMethod returns TTDOWNLOAD_GRAPHICS. width = %d\n",
  1090. pSV->StdVar[0].lStdVariable));
  1091. }
  1092. return ttdlf;
  1093. }
  1094. //////////////////////////////////////////////////////////////////////////
  1095. // Function: OEMOutputCharStr
  1096. //
  1097. // Description: convert character code
  1098. //
  1099. //
  1100. // Parameters:
  1101. //
  1102. // pdevobj Pointer to the DEVOBJ.
  1103. //
  1104. // pUFObj Pointer to the UNIFONTOBJ.
  1105. //
  1106. // dwType Type of pglyph string. One of following is specified by UNIDRV.
  1107. // TYPE_GLYPHHANDLE TYPE_GLYPHID
  1108. //
  1109. // dwCount Number of the glyph store in pGlyph
  1110. //
  1111. // pGlyph Pointer to glyph string to HGLYPH* (TYPE_GLYPHHANDLE)
  1112. // Glyph handle that GDI passes.
  1113. // DWORD* (TYPE_GLYPHID). Glyph ID that UNIDRV creates from
  1114. // Glyph Handle. In case of TrueType font, string type is HGLYPH*.
  1115. // For Device font, string type is DWORD*
  1116. //
  1117. //
  1118. // Returns:
  1119. // None
  1120. //
  1121. // Comments:
  1122. //
  1123. //
  1124. // History:
  1125. // 07/../97 Created. -Epson-
  1126. //
  1127. //////////////////////////////////////////////////////////////////////////
  1128. VOID APIENTRY OEMOutputCharStr(PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, DWORD dwType, DWORD dwCount, PVOID pGlyph)
  1129. {
  1130. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMOutputCharStr(,,%s,%d,) entry.\r\n")),
  1131. // (dwType == TYPE_GLYPHHANDLE) ? "TYPE_GLYPHHANDLE" : "TYPE_GLYPHID", dwCount);
  1132. // DEBUG
  1133. // CheckAvailableMem((LPEPAGEMDV)(pdevobj->pdevOEM), pUFObj);
  1134. // DEBUG
  1135. switch (dwType)
  1136. {
  1137. case TYPE_GLYPHHANDLE:
  1138. // DBGPRINT(DBG_WARNING, (DLLTEXT("dwType = TYPE_GLYPHHANDLE\n")));
  1139. // pdwGlyphID = (PDWORD)pGlyph;
  1140. // for (dwI = 0; dwI < dwCount; dwI++)
  1141. // DBGPRINT(DBG_WARNING, (DLLTEXT("hGlyph[%d] = %x\r\n"), dwI, pdwGlyphID[dwI]));
  1142. if (!BConvPrint(pdevobj, pUFObj, dwType, dwCount, pGlyph))
  1143. { // Checking the return value.
  1144. return;
  1145. }
  1146. break;
  1147. case TYPE_GLYPHID:
  1148. // DBGPRINT(DBG_WARNING, (DLLTEXT("dwType = TYPE_GLYPHID\n")));
  1149. {
  1150. LPEPAGEMDV lpEpage;
  1151. int hlx;
  1152. if (pdevobj == NULL) // Checking null-pointer.
  1153. {
  1154. return;
  1155. }
  1156. lpEpage = (LPEPAGEMDV)(pdevobj->pdevOEM);
  1157. if (lpEpage == NULL) // Checking null-pointer.
  1158. {
  1159. return;
  1160. }
  1161. hlx = IGetHLIndex(lpEpage, lpEpage->iCurrentDLFontID);
  1162. if (hlx >= 0)
  1163. { // TTF downloaded
  1164. BYTE bDBCS = lpEpage->HeightL[hlx].fGeneral & FLAG_DBCS;
  1165. PDWORD pdwGlyphID;
  1166. DWORD dwI;
  1167. if (pGlyph == NULL) // Checking null-pointer.
  1168. {
  1169. return;
  1170. }
  1171. for (dwI = 0, pdwGlyphID = pGlyph; dwI < dwCount; dwI++, pdwGlyphID++)
  1172. {
  1173. if (bDBCS)
  1174. {
  1175. // for DBCS, modify cp to printable char code
  1176. WORD cc = WConvDBCSCharCode((WORD)*pdwGlyphID, lpEpage->dwLCID);
  1177. WORD cp = SWAPW(cc);
  1178. // DBGPRINT(DBG_WARNING, (DLLTEXT("pGlyph[%d] = 0x%X, 0x%X (%.4X)\n"), dwI, LOBYTE(cp), HIBYTE(cp), (WORD)*pdwGlyphID));
  1179. WRITESPOOLBUF(pdevobj, (PBYTE)&cp, 2);
  1180. }
  1181. else
  1182. {
  1183. // DBGPRINT(DBG_WARNING, (DLLTEXT("pGlyph[%d] = 0x%.4lX\n"), dwI, (WORD)*pdwGlyphID));
  1184. WRITESPOOLBUF(pdevobj, (PBYTE)pdwGlyphID, 1);
  1185. }
  1186. }
  1187. }
  1188. else
  1189. { // download font not active
  1190. if (!BConvPrint(pdevobj, pUFObj, dwType, dwCount, pGlyph))
  1191. {
  1192. ERR(("TYPE_GLYPHID specified for device font.\r\n"));
  1193. return; // Checking the return value.
  1194. }
  1195. }
  1196. }
  1197. break;
  1198. }
  1199. }
  1200. //////////////////////////////////////////////////////////////////////////
  1201. // Function: OEMSendFontCmd
  1202. //
  1203. // Description: Send scalable font download command
  1204. //
  1205. //
  1206. // Parameters:
  1207. //
  1208. // pdevobj Pointer to the DEVOBJ.
  1209. //
  1210. // pUFObj Pointer to the UNIFONTOBJ.
  1211. //
  1212. // pFInv Pointer to the FINVOCATION
  1213. // Command string template has been extracted from UFM file,
  1214. // which may contain "#V" and/or "#H[S|D]"
  1215. //
  1216. // Returns:
  1217. // None
  1218. //
  1219. // Comments:
  1220. //
  1221. //
  1222. // History:
  1223. // 07/../97 Created. -Epson-
  1224. //
  1225. //////////////////////////////////////////////////////////////////////////
  1226. VOID APIENTRY OEMSendFontCmd(PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, PFINVOCATION pFInv)
  1227. {
  1228. DWORD adwStdVariable[2 + 2 * 2];
  1229. PGETINFO_STDVAR pSV = (PGETINFO_STDVAR)adwStdVariable;
  1230. DWORD dwIn, dwOut;
  1231. PBYTE pubCmd;
  1232. BYTE aubCmd[CCHMAXCMDLEN];
  1233. // GETINFO_FONTOBJ FO;
  1234. PIFIMETRICS pIFI;
  1235. DWORD height100, width, charoff;
  1236. LPEPAGEMDV lpEpage;
  1237. BYTE Buff[16];
  1238. LONG ret; // buffy.pl : Addition for checking the return value of "LConvertFontSizeToStr".
  1239. // DBGPRINT(DBG_WARNING, (DLLTEXT("OEMSendFontCmd() entry. Font = %S\r\n"), (LPWSTR)((BYTE*)pIFI + pIFI->dpwszFaceName)));
  1240. if (pdevobj == NULL || pUFObj == NULL) // Checking null-pointer.
  1241. {
  1242. return;
  1243. }
  1244. pIFI = pUFObj->pIFIMetrics;
  1245. if (pIFI == NULL) // Checking null-pointer.
  1246. {
  1247. return;
  1248. }
  1249. lpEpage = (LPEPAGEMDV)(pdevobj->pdevOEM);
  1250. if (lpEpage == NULL) // Checking null-pointer.
  1251. {
  1252. return;
  1253. }
  1254. pubCmd = pFInv->pubCommand;
  1255. if (pubCmd == NULL) // Checking null-pointer.
  1256. {
  1257. return;
  1258. }
  1259. // //
  1260. // // GETINFO_FONTOBJ
  1261. // //
  1262. // FO.dwSize = sizeof(GETINFO_FONTOBJ);
  1263. // FO.pFontObj = NULL;
  1264. //
  1265. // if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_FONTOBJ, &FO, 0, NULL))
  1266. // {
  1267. // ERR(("UFO_GETINFO_FONTOBJ failed.\r\n"));
  1268. // return;
  1269. // }
  1270. //
  1271. // Get standard variables.
  1272. //
  1273. pSV->dwSize = sizeof(GETINFO_STDVAR) + 2 * sizeof(DWORD) * (2 - 1);
  1274. pSV->dwNumOfVariable = 2;
  1275. pSV->StdVar[0].dwStdVarID = FNT_INFO_FONTHEIGHT;
  1276. pSV->StdVar[1].dwStdVarID = FNT_INFO_FONTWIDTH;
  1277. if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_STDVARIABLE, pSV, 0, NULL))
  1278. {
  1279. ERR(("UFO_GETINFO_STDVARIABLE failed.\r\n"));
  1280. return;
  1281. }
  1282. // LConvertFontSizeToStr((pSV->StdVar[0].lStdVariable * 2540L) / MASTER_Y_UNIT, Buff);
  1283. // DBGPRINT(DBG_WARNING, (DLLTEXT(" FontHeight: %d (%s mm)\r\n"), pSV->StdVar[0].lStdVariable, Buff));
  1284. // LConvertFontSizeToStr((pSV->StdVar[1].lStdVariable * 2540L) / MASTER_X_UNIT, Buff);
  1285. // DBGPRINT(DBG_WARNING, (DLLTEXT(" FontWidth: %d (%s mm)\r\n"), pSV->StdVar[1].lStdVariable, Buff));
  1286. // Initialize lpEpage
  1287. // DBGPRINT(DBG_WARNING, (DLLTEXT(" fGeneral = ")));
  1288. if (IS_DBCSCHARSET(pIFI->jWinCharSet))
  1289. {
  1290. lpEpage->fGeneral |= FLAG_DOUBLE;
  1291. // DBGPRINT(DBG_WARNING, ("FLAG_DOUBLE "));
  1292. }
  1293. else
  1294. lpEpage->fGeneral &= ~FLAG_DOUBLE;
  1295. if (L'@' == *((LPWSTR)((BYTE*)pIFI + pIFI->dpwszFaceName)))
  1296. {
  1297. lpEpage->fGeneral |= FLAG_VERT;
  1298. // DBGPRINT(DBG_WARNING, ("FLAG_VERT "));
  1299. }
  1300. else
  1301. lpEpage->fGeneral &= ~FLAG_VERT;
  1302. if ((pIFI->jWinPitchAndFamily & 0x03) == VARIABLE_PITCH)
  1303. {
  1304. lpEpage->fGeneral |= FLAG_PROP;
  1305. // DBGPRINT(DBG_WARNING, ("FLAG_PROP"));
  1306. }
  1307. else
  1308. lpEpage->fGeneral &= ~FLAG_PROP;
  1309. // DBGPRINT(DBG_WARNING, ("\r\n"));
  1310. dwOut = 0;
  1311. lpEpage->fGeneral &= ~FLAG_DBCS;
  1312. // preset character height in Minimum Unit for ESC/Page
  1313. height100 = (pSV->StdVar[0].lStdVariable * 100L) / MIN_Y_UNIT_DIV;
  1314. // DBGPRINT(DBG_WARNING, (DLLTEXT(" Height = %d\r\n"), height100));
  1315. for (dwIn = 0; dwIn < pFInv->dwCount && dwOut < CCHMAXCMDLEN; )
  1316. {
  1317. // check for FS_n1_weF command
  1318. // Addition of checking remaining bytes of "pubCmd".
  1319. if ((dwIn + 3) < pFInv->dwCount && pubCmd[dwIn] == '\x1D' &&
  1320. (!strncmp(&pubCmd[dwIn + 2], "weF", 3) ||
  1321. !strncmp(&pubCmd[dwIn + 3], "weF", 3)))
  1322. {
  1323. // save n1 for the FS_n1_weF command
  1324. // PREFAST : warning 31: Return value ignored: 'sscanf' could fail.
  1325. // If sscanf do not succeed, it set the default value to "lpEpage->iParamForFSweF"
  1326. if(1 != sscanf(&pubCmd[dwIn + 1], "%d", &lpEpage->iParamForFSweF)) {
  1327. lpEpage->iParamForFSweF = 0; // use default value.
  1328. }
  1329. }
  1330. else if ((pubCmd[dwIn] == '\x1D') && ((dwIn + 5) <= pFInv->dwCount)
  1331. && (pubCmd[dwIn+2] == 's') && (pubCmd[dwIn+3] == 't') && (pubCmd[dwIn+4] == 'F'))
  1332. {
  1333. if (pubCmd[dwIn+1] == '1') // This font is italic font like "Arial Italic"
  1334. {
  1335. lpEpage->flAttribute |= EP_FONT_EXPLICITE_ITALIC_FONT;
  1336. }
  1337. else { // Normal font
  1338. lpEpage->flAttribute &= ~EP_FONT_EXPLICITE_ITALIC_FONT;
  1339. }
  1340. }
  1341. // Addition of checking remaining bytes of "pubCmd".
  1342. if ((dwIn + 1) < pFInv->dwCount && pubCmd[dwIn] == '#' && pubCmd[dwIn + 1] == 'V')
  1343. {
  1344. // buffy.pl : Addition of checking the return value of "LConvertFontSizeToStr".
  1345. ret = LConvertFontSizeToStr(height100, &aubCmd[dwOut], sizeof(aubCmd) - dwOut);
  1346. if(ret < 0)
  1347. break;
  1348. dwOut += ret;
  1349. dwIn += 2;
  1350. }
  1351. // Addition of checking remaining bytes of "pubCmd".
  1352. else if ((dwIn + 2) < pFInv->dwCount && pubCmd[dwIn] == '#' && pubCmd[dwIn + 1] == 'H')
  1353. {
  1354. // get width in MASTER_X_UNIT; no adjustment needed
  1355. width = pSV->StdVar[1].lStdVariable;
  1356. if (pubCmd[dwIn + 2] == 'S')
  1357. {
  1358. dwIn += 3;
  1359. lpEpage->fGeneral |= FLAG_DBCS;
  1360. // DBGPRINT(DBG_WARNING, (DLLTEXT(" WidthS = ")));
  1361. }
  1362. else if (pubCmd[dwIn + 2] == 'D')
  1363. {
  1364. width *= 2;
  1365. dwIn += 3;
  1366. lpEpage->fGeneral |= FLAG_DBCS;
  1367. // DBGPRINT(DBG_WARNING, (DLLTEXT(" WidthD = ")));
  1368. }
  1369. else if (pubCmd[dwIn + 2] == 'K')
  1370. { // PAGE-C/K/H
  1371. width *= 2;
  1372. dwIn += 3;
  1373. lpEpage->fGeneral |= FLAG_DBCS;
  1374. // DBGPRINT(DBG_WARNING, (DLLTEXT(" WidthK = ")));
  1375. }
  1376. else
  1377. {
  1378. dwIn += 2;
  1379. // DBGPRINT(DBG_WARNING, (DLLTEXT(" Width = ")));
  1380. }
  1381. // DBGPRINT(DBG_WARNING, ("%d\r\n", width));
  1382. #if 1 // <FS> n1 wmF
  1383. // use width in minimum unit
  1384. width = (width * 100L) / MIN_Y_UNIT_DIV;
  1385. #else // <FS> n1 wcF
  1386. // get CPI (Char# per Inch)
  1387. width = (MASTER_X_UNIT * 100L) / width;
  1388. #endif
  1389. // DBGPRINT(DBG_WARNING, (DLLTEXT("Width=%d\r\n"), width));
  1390. // buffy.pl : Addition of checking the return value of "LConvertFontSizeToStr".
  1391. ret = LConvertFontSizeToStr(width, &aubCmd[dwOut], sizeof(aubCmd) - dwOut);
  1392. if(ret < 0)
  1393. break;
  1394. dwOut += ret;
  1395. }
  1396. else
  1397. {
  1398. aubCmd[dwOut++] = pubCmd[dwIn++];
  1399. }
  1400. }
  1401. // DBGPRINT(DBG_WARNING, (DLLTEXT(" iParamForFSweF = %d\r\n"), lpEpage->iParamForFSweF));
  1402. // buffy.pl : Addition of checking if making the command string succeed or not.
  1403. if(pFInv->dwCount <= dwIn)
  1404. {
  1405. WRITESPOOLBUF(pdevobj, aubCmd, dwOut);
  1406. }
  1407. lpEpage->iDevCharOffset = (height100 * pIFI->fwdWinDescender /
  1408. (pIFI->fwdWinAscender + pIFI->fwdWinDescender));
  1409. // Checking the return value.
  1410. ret = LConvertFontSizeToStr((lpEpage->fGeneral & FLAG_DBCS) ? lpEpage->iDevCharOffset : 0,
  1411. Buff, sizeof(Buff));
  1412. if (ret >= 0)
  1413. {
  1414. dwOut = EP_StringCbPrintf_with_String(aubCmd, sizeof(aubCmd), SET_CHAR_OFFSET_S, Buff);
  1415. }
  1416. // DBGPRINT(DBG_WARNING, (DLLTEXT(" iDevCharOffset = %s\r\n"), Buff));
  1417. if (lpEpage->fGeneral & FLAG_VERT)
  1418. {
  1419. int dx = (lpEpage->fGeneral & FLAG_DOUBLE) ? 1 : 0;
  1420. dwOut += EP_StringCbPrintf_with_int1(&aubCmd[dwOut], sizeof(aubCmd) - dwOut,
  1421. SET_VERT_PRINT, dx);
  1422. }
  1423. WRITESPOOLBUF(pdevobj, aubCmd, dwOut);
  1424. lpEpage->iCurrentDLFontID = -1; // mark device font
  1425. // save for SET_SINGLE_BYTE and SET_DOUBLE_BYTE
  1426. // get width in Minimum Unit for ESC/Page
  1427. width = pSV->StdVar[1].lStdVariable / MIN_X_UNIT_DIV;
  1428. if (lpEpage->fGeneral & FLAG_DBCS)
  1429. {
  1430. lpEpage->iSBCSX = lpEpage->iSBCSXMove = width;
  1431. lpEpage->iDBCSX = lpEpage->iDBCSXMove = width * 2;
  1432. }
  1433. else
  1434. {
  1435. lpEpage->iSBCSX = lpEpage->iSBCSXMove = width;
  1436. lpEpage->iDBCSX = lpEpage->iDBCSXMove = 0;
  1437. }
  1438. lpEpage->iSBCSYMove = lpEpage->iDBCSYMove = 0;
  1439. }
  1440. // buffy.pl : Addition of checking the size of "pStr".
  1441. //
  1442. // LConvertFontSizeToStr : converts font size to string
  1443. // params
  1444. // size : font size (magnified by 100 times)
  1445. // pStr : points string buffer
  1446. // len : length of pStr buffer in byte
  1447. // return
  1448. // converted string length. If it failed converting, it returns negative value.
  1449. // spec
  1450. // converting format = "xx.yy"
  1451. //
  1452. LONG LConvertFontSizeToStr(LONG size, PSTR pStr, DWORD len)
  1453. {
  1454. DWORD figure = 1;
  1455. LONG rank = 10;
  1456. LONG n = size;
  1457. if (pStr == NULL) // Checking null-pointer.
  1458. {
  1459. return -1;
  1460. }
  1461. while (n / rank)
  1462. {
  1463. figure ++;
  1464. rank *= 10;
  1465. }
  1466. if (figure < 3) figure = 3; // at least 3 figures exit.
  1467. // adjust figure number to required size.
  1468. if (size < 0) figure ++; // for sign.
  1469. figure += 2; // for point and NULL termination
  1470. if (len < figure) return (-1); // error.
  1471. return (LONG)EP_StringCbPrintf_with_int2(pStr, len, "%d.%02d", size / 100, size % 100);
  1472. }
  1473. //
  1474. // BInsertHeightList : inserts HeightList data for id (FontID) in *lpEpage
  1475. // params
  1476. // lpEpage : points EPAGEMDV
  1477. // id : target font ID
  1478. // wHeight : font height
  1479. // wWidth : font width
  1480. // fProp : proportional spacing font flag
  1481. // fDBCS : DBCS font flag
  1482. // return
  1483. // TRUE when succeeded, FALSE if failed (no more space)
  1484. //
  1485. BOOL PASCAL BInsertHeightList(LPEPAGEMDV lpEpage, int id, WORD wHeight, WORD wWidth, BYTE fProp, BYTE fDBCS)
  1486. {
  1487. // DBGPRINT(DBG_WARNING, (DLLTEXT("Registering download font (%d):\r\n"), id));
  1488. // DBGPRINT(DBG_WARNING, (DLLTEXT(" wHeight = %d\r\n"), (int)wHeight));
  1489. // DBGPRINT(DBG_WARNING, (DLLTEXT(" wWidth = %d\r\n"), (int)wWidth));
  1490. // DBGPRINT(DBG_WARNING, (DLLTEXT(" fProp = %d\r\n"), (int)fProp));
  1491. // DBGPRINT(DBG_WARNING, (DLLTEXT(" fDBCS = %d\r\n"), (int)fDBCS));
  1492. if (lpEpage == NULL) // Checking null-pointer.
  1493. {
  1494. return FALSE;
  1495. }
  1496. if (lpEpage->wListNum < DOWNLOAD_MAX_FONTS)
  1497. {
  1498. LPHEIGHTLIST lpHeightList = lpEpage->HeightL;
  1499. lpHeightList += lpEpage->wListNum;
  1500. lpHeightList->id = (short)id;
  1501. lpHeightList->Height = wHeight;
  1502. lpHeightList->Width = wWidth;
  1503. lpHeightList->fGeneral = ((fProp) ? FLAG_PROP : 0) | ((fDBCS) ? FLAG_DBCS : 0);
  1504. lpEpage->wListNum++;
  1505. return TRUE;
  1506. }
  1507. else
  1508. {
  1509. return FALSE;
  1510. }
  1511. }
  1512. //
  1513. // IGetHLIndex : gets HeightList index for id (FontID) in *lpEpage
  1514. // params
  1515. // lpEpage : points EPAGEMDV
  1516. // id : target font ID
  1517. // return
  1518. // the HeghtList index if found, else -1 will be returned
  1519. //
  1520. int PASCAL IGetHLIndex(LPEPAGEMDV lpEpage, int id)
  1521. {
  1522. int iRet;
  1523. if (lpEpage == NULL) // Checking null-pointer.
  1524. {
  1525. return -1;
  1526. }
  1527. for (iRet = lpEpage->wListNum - 1;
  1528. iRet >= 0 && (int)lpEpage->HeightL[iRet].id != id;
  1529. iRet--)
  1530. ;
  1531. return iRet;
  1532. }
  1533. //BYTE PASCAL BTGetProp(LPEPAGEMDV lpEpage, int id)
  1534. //{
  1535. // int i = IGetHLIndex(lpEpage, id);
  1536. // return (i >= 0) ? (lpEpage->HeightL[i].fGeneral & FLAG_PROP) : 0;
  1537. //}
  1538. //BYTE PASCAL BTGetDBCS(LPEPAGEMDV lpEpage, int id)
  1539. //{
  1540. // int i = IGetHLIndex(lpEpage, id);
  1541. // return (i >= 0) ? (lpEpage->HeightL[i].fGeneral & FLAG_DBCS) : 0;
  1542. //}
  1543. //WORD PASCAL WGetWidth(LPEPAGEMDV lpEpage, int id)
  1544. //{
  1545. // int i = IGetHLIndex(lpEpage, id);
  1546. // return (i >= 0) ? lpEpage->HeightL[i].Width : 0;
  1547. //}
  1548. //WORD PASCAL WGetHeight(LPEPAGEMDV lpEpage, int id)
  1549. //{
  1550. // int i = IGetHLIndex(lpEpage, id);
  1551. // return (i >= 0) ? lpEpage->HeightL[i].Height : 0;
  1552. //}
  1553. //
  1554. // WConvDBCSCharCode : converts linear character code to printable range
  1555. // params
  1556. // cc : linear character code started at DOWNLOAD_MIN_GLYPH_ID
  1557. // LCID : locale ID
  1558. // return
  1559. // WORD character code in printable range
  1560. //
  1561. // Conversion spec:
  1562. // cc return
  1563. // LCID = LCID_KOR:
  1564. // 0x20..0x7D -> 0xA1A1..0xA1FE (char count = 0xA1FE - 0xA1A1 + 1 = 0x5E)
  1565. // 0x7E..0xDB -> 0xA2A1..0xA2FE (char count = 0x5E)
  1566. // 0xDC..0x139 -> 0xA3A1..0xA3FE (char count = 0x5E)
  1567. // ... ...
  1568. // LCID != LCID_KOR:
  1569. // 0x20..0x7D -> 0x2121..0x207E (char count = 0x217E - 0x2121 + 1 = 0x5E)
  1570. // 0x7E..0xDB -> 0x2221..0x227E (char count = 0x5E)
  1571. // 0xDC..0x139 -> 0x2321..0x237E (char count = 0x5E)
  1572. // ... ...
  1573. //
  1574. WORD WConvDBCSCharCode(WORD cc, DWORD LCID)
  1575. {
  1576. WORD nPad, cc2;
  1577. cc2 = cc - DOWNLOAD_MIN_GLYPH_ID; // adjust to base 0
  1578. nPad = cc2 / 0x5E; // get gap count
  1579. cc2 += nPad * (0x100 - 0x5E); // adjust for padding gaps
  1580. // set the base code for the LCID
  1581. switch (LCID)
  1582. {
  1583. case LCID_KOR:
  1584. cc2 += (WORD)0xA1A1;
  1585. break;
  1586. default:
  1587. cc2 += (WORD)0x2121;
  1588. break;
  1589. }
  1590. // DBGPRINT(DBG_WARNING, (DLLTEXT("WConvDBCSCharCode(%.4x,%d) = %.4x\r\n"), cc, LCID, cc2));
  1591. return cc2;
  1592. }
  1593. //
  1594. // BConvPrint : converts glyph string and prints it
  1595. // params
  1596. // pdevobj : Pointer to the DEVOBJ.
  1597. // pUFObj : Pointer to the UNIFONTOBJ.
  1598. // dwType : Type of pglyph string. One of following is specified by UNIDRV.
  1599. // TYPE_GLYPHHANDLE TYPE_GLYPHID
  1600. // dwCount : Number of the glyph store in pGlyph
  1601. // pGlyph : Pointer to glyph string to HGLYPH* (TYPE_GLYPHHANDLE)
  1602. // Glyph handle that GDI passes.
  1603. // DWORD* (TYPE_GLYPHID). Glyph ID that UNIDRV creates from
  1604. // Glyph Handle. In case of TrueType font, string type is HGLYPH*.
  1605. // For Device font, string type is DWORD*
  1606. // return
  1607. // TRUE when succeeded, FALSE if failed
  1608. //
  1609. BOOL BConvPrint(PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, DWORD dwType, DWORD dwCount, PVOID pGlyph)
  1610. {
  1611. TRANSDATA *aTrans;
  1612. GETINFO_GLYPHSTRING GStr;
  1613. LPEPAGEMDV lpEpage;
  1614. DWORD dwI;
  1615. DWORD adwStdVariable[2 + 2 * 2];
  1616. PGETINFO_STDVAR pSV;
  1617. BOOL bGotStdVar;
  1618. DWORD dwFontSim[2];
  1619. BYTE jType, *pTemp;
  1620. WORD wLen;
  1621. BOOL bRet;
  1622. if (pdevobj == NULL || pUFObj == NULL) // Checking null-pointer.
  1623. {
  1624. return FALSE;
  1625. }
  1626. lpEpage = (LPEPAGEMDV)(pdevobj->pdevOEM);
  1627. if (lpEpage == NULL) // Checking null-pointer.
  1628. {
  1629. return FALSE;
  1630. }
  1631. // setup GETINFO_GLYPHSTRING
  1632. GStr.dwSize = sizeof(GETINFO_GLYPHSTRING);
  1633. GStr.dwCount = dwCount;
  1634. GStr.dwTypeIn = dwType;
  1635. GStr.pGlyphIn = pGlyph;
  1636. GStr.pGlyphOut = NULL;
  1637. GStr.dwTypeOut = TYPE_TRANSDATA;
  1638. GStr.dwGlyphOutSize = 0;
  1639. GStr.pGlyphOut = NULL;
  1640. if ((FALSE != (bRet = pUFObj->pfnGetInfo(pUFObj,
  1641. UFO_GETINFO_GLYPHSTRING, &GStr, 0, NULL)))
  1642. || 0 == GStr.dwGlyphOutSize)
  1643. {
  1644. ERR(("UFO_GETINFO_GRYPHSTRING faild - %d, %d.\n",
  1645. bRet, GStr.dwGlyphOutSize));
  1646. return FALSE;
  1647. }
  1648. aTrans = (TRANSDATA *)MemAlloc(GStr.dwGlyphOutSize);
  1649. if (NULL == aTrans)
  1650. {
  1651. ERR(("MemAlloc faild.\n"));
  1652. return FALSE;
  1653. }
  1654. GStr.pGlyphOut = aTrans;
  1655. // convert glyph string to TRANSDATA
  1656. if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_GLYPHSTRING, &GStr, 0, NULL))
  1657. {
  1658. ERR(("UNIFONTOBJ_GetInfo:UFO_GETINFO_GLYPHSTRING failed.\r\n"));
  1659. return FALSE;
  1660. }
  1661. // Only LCID_JPN == 0, other LCIDs are not 0
  1662. // if (lpEpage->dwLCID == LCID_CHT ||
  1663. // lpEpage->dwLCID == LCID_CHS ||
  1664. // lpEpage->dwLCID == LCID_KOR)
  1665. // if (lpEpage->dwLCID && lpEpage->dwLCID != LCID_USA)
  1666. if (lpEpage->dwLCID != LCID_USA) //99/02/04
  1667. {
  1668. // prepare GETINFO_STDVAR
  1669. pSV = (PGETINFO_STDVAR)adwStdVariable;
  1670. pSV->dwSize = sizeof(GETINFO_STDVAR) + 2 * sizeof(DWORD) * (2 - 1);
  1671. pSV->dwNumOfVariable = 2;
  1672. pSV->StdVar[0].dwStdVarID = FNT_INFO_FONTBOLD;
  1673. pSV->StdVar[1].dwStdVarID = FNT_INFO_FONTITALIC;
  1674. bGotStdVar = FALSE;
  1675. // preset 0 to dwFontSim[]
  1676. dwFontSim[0] = dwFontSim[1] = 0;
  1677. }
  1678. // #441440: PREFIX: "bGotStdVar" does not initialized if dwLCID == LCID_USA
  1679. // #441441: PREFIX: "pSV" does not initialized if dwLCID == LCID_USA
  1680. else {
  1681. pSV = (PGETINFO_STDVAR)adwStdVariable;
  1682. bGotStdVar = TRUE;
  1683. }
  1684. for (dwI = 0; dwI < dwCount; dwI++)
  1685. {
  1686. // DBGPRINT(DBG_WARNING, (DLLTEXT("TYPE_TRANSDATA:ubCodePageID:0x%x\n"),aTrans[dwI].ubCodePageID));
  1687. // DBGPRINT(DBG_WARNING, (DLLTEXT("TYPE_TRANSDATA:ubType:0x%x\n"),aTrans[dwI].ubType));
  1688. jType = (aTrans[dwI].ubType & MTYPE_FORMAT_MASK);
  1689. switch (jType)
  1690. {
  1691. case MTYPE_DIRECT:
  1692. case MTYPE_COMPOSE:
  1693. // DBGPRINT(DBG_WARNING, (DLLTEXT("TYPE_TRANSDATA:ubCode:0x%.2X\n"),aTrans[dwI].uCode.ubCode));
  1694. // Only LCID_JPN == 0, other LCIDs are not 0
  1695. // if (lpEpage->dwLCID == LCID_CHT ||
  1696. // lpEpage->dwLCID == LCID_CHS ||
  1697. // lpEpage->dwLCID == LCID_KOR)
  1698. if (lpEpage->dwLCID)
  1699. {
  1700. // #441440: PREFIX: "bGotStdVar" does not initialized if dwLCID == LCID_USA
  1701. // if (lpEpage->fGeneral & FLAG_DOUBLE)
  1702. if ((lpEpage->fGeneral & FLAG_DOUBLE) &&
  1703. lpEpage->dwLCID != LCID_USA)
  1704. {
  1705. if (!bGotStdVar)
  1706. { // dwFontSim[] not initialized
  1707. // get FontBold/FontItalic
  1708. if (pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_STDVARIABLE, pSV, 0, NULL))
  1709. {
  1710. bGotStdVar = TRUE;
  1711. // update FontBold/FontItalic
  1712. dwFontSim[0] = pSV->StdVar[0].lStdVariable;
  1713. dwFontSim[1] = pSV->StdVar[1].lStdVariable;
  1714. }
  1715. else
  1716. {
  1717. ERR(("UFO_GETINFO_STDVARIABLE failed.\r\n"));
  1718. }
  1719. }
  1720. // invoke CmdSelectSingleByteMode
  1721. OEMCommandCallback(pdevobj, TEXT_SINGLE_BYTE, 2, dwFontSim);
  1722. }
  1723. }
  1724. switch(jType)
  1725. {
  1726. case MTYPE_DIRECT:
  1727. WRITESPOOLBUF(pdevobj, &aTrans[dwI].uCode.ubCode, 1);
  1728. break;
  1729. case MTYPE_COMPOSE:
  1730. pTemp = (BYTE *)(aTrans) + aTrans[dwI].uCode.sCode;
  1731. // first two bytes are the length of the string
  1732. wLen = *pTemp + (*(pTemp + 1) << 8);
  1733. pTemp += 2;
  1734. WRITESPOOLBUF(pdevobj, pTemp, wLen);
  1735. break;
  1736. }
  1737. break;
  1738. case MTYPE_PAIRED:
  1739. // Only LCID_JPN == 0, other LCIDs are not 0
  1740. // if (lpEpage->dwLCID == LCID_CHT ||
  1741. // lpEpage->dwLCID == LCID_CHS ||
  1742. // lpEpage->dwLCID == LCID_KOR)
  1743. if (lpEpage->dwLCID)
  1744. {
  1745. if (!(lpEpage->fGeneral & FLAG_DOUBLE) &&
  1746. lpEpage->dwLCID != LCID_USA)
  1747. {
  1748. if (!bGotStdVar)
  1749. { // dwFontSim[] not initialized
  1750. // get FontBold/FontItalic
  1751. if (pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_STDVARIABLE, pSV, 0, NULL))
  1752. {
  1753. bGotStdVar = TRUE;
  1754. // update FontBold/FontItalic
  1755. dwFontSim[0] = pSV->StdVar[0].lStdVariable;
  1756. dwFontSim[1] = pSV->StdVar[1].lStdVariable;
  1757. }
  1758. else
  1759. {
  1760. ERR(("UFO_GETINFO_STDVARIABLE failed.\r\n"));
  1761. }
  1762. }
  1763. // invoke CmdSelectDoubleByteMode
  1764. OEMCommandCallback(pdevobj, TEXT_DOUBLE_BYTE, 2, dwFontSim);
  1765. }
  1766. // DBGPRINT(DBG_WARNING, (DLLTEXT("TYPE_TRANSDATA:ubPairs:(0x%.2X,0x%.2X)\n"), aTrans[dwI].uCode.ubPairs[0], aTrans[dwI].uCode.ubPairs[1]));
  1767. WRITESPOOLBUF(pdevobj, aTrans[dwI].uCode.ubPairs, 2);
  1768. }
  1769. else
  1770. { // Jpn
  1771. // DBGPRINT(DBG_WARNING, (DLLTEXT("TYPE_TRANSDATA:ubPairs:(0x%.2X,0x%.2X)\n"), aTrans[dwI].uCode.ubPairs[0], aTrans[dwI].uCode.ubPairs[1]));
  1772. // EPSON specific
  1773. // vertical period and comma must be shifted to upper right.
  1774. BOOL AdjPos;
  1775. int adjx, adjy;
  1776. BYTE buf[32];
  1777. DWORD cb;
  1778. // DEBUG
  1779. #ifdef DBGMSGBOX
  1780. DbgMsg(lpEpage, MB_OK, L"Code = %.4x, Vertical = %d.\r\n",
  1781. *((PWORD)aTrans[dwI].uCode.ubPairs), !!(lpEpage->fGeneral & (FLAG_VERT|FLAG_VERTPRN)));
  1782. #endif
  1783. // DEBUG
  1784. // #441440: PREFIX: "bGotStdVar" does not initialized if dwLCID == LCID_USA
  1785. // 99/02/04
  1786. // if ((lpEpage->fGeneral & FLAG_DOUBLE) && (aTrans[dwI].ubType & MTYPE_SINGLE))
  1787. if (lpEpage->dwLCID != LCID_USA && (lpEpage->fGeneral & FLAG_DOUBLE) && (aTrans[dwI].ubType & MTYPE_SINGLE))
  1788. {
  1789. if (!bGotStdVar)
  1790. { // dwFontSim[] not initialized
  1791. // get FontBold/FontItalic
  1792. if (pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_STDVARIABLE, pSV, 0, NULL))
  1793. {
  1794. bGotStdVar = TRUE;
  1795. // update FontBold/FontItalic
  1796. dwFontSim[0] = pSV->StdVar[0].lStdVariable;
  1797. dwFontSim[1] = pSV->StdVar[1].lStdVariable;
  1798. }
  1799. else
  1800. {
  1801. ERR(("UFO_GETINFO_STDVARIABLE failed.\r\n"));
  1802. }
  1803. }
  1804. // invoke CmdSelectSingleByteMode
  1805. OEMCommandCallback(pdevobj, TEXT_SINGLE_BYTE, 2, dwFontSim);
  1806. }
  1807. AdjPos = (*((PWORD)aTrans[dwI].uCode.ubPairs) == 0x2421 || // comma
  1808. *((PWORD)aTrans[dwI].uCode.ubPairs) == 0x2521) && // period
  1809. (lpEpage->fGeneral & (FLAG_VERT|FLAG_VERTPRN)) &&
  1810. !(lpEpage->fGeneral & FLAG_NOVPADJ);
  1811. if (AdjPos)
  1812. {
  1813. adjx = lpEpage->iSBCSX * VERT_PRINT_REL_X / 100;
  1814. adjy = lpEpage->iSBCSX * VERT_PRINT_REL_Y / 100;
  1815. // DEBUG
  1816. #ifdef DBGMSGBOX
  1817. DbgMsg(lpEpage, MB_ICONINFORMATION, L"adjx = %d, adjy = %d.\r\n", adjx, adjy);
  1818. #endif
  1819. // DEBUG
  1820. cb = EP_StringCbPrintf_with_int1(buf, sizeof(buf), SET_REL_X, -adjx);
  1821. cb += EP_StringCbPrintf_with_int1(buf + cb, sizeof(buf) - cb, SET_REL_Y, -adjy);
  1822. WRITESPOOLBUF(pdevobj, buf, cb);
  1823. }
  1824. WRITESPOOLBUF(pdevobj, aTrans[dwI].uCode.ubPairs, 2);
  1825. if (AdjPos)
  1826. {
  1827. cb = EP_StringCbPrintf_with_int1(buf, sizeof(buf), SET_REL_X, adjx);
  1828. cb += EP_StringCbPrintf_with_int1(buf + cb, sizeof(buf) - cb, SET_REL_Y, adjy);
  1829. WRITESPOOLBUF(pdevobj, buf, cb);
  1830. }
  1831. }
  1832. break;
  1833. default:
  1834. WARNING(("Unsupported TRANSDATA data type passed.\n"));
  1835. WARNING(("jType=%02x, sCode=%x\n", aTrans[dwI].uCode.sCode, jType));
  1836. }
  1837. }
  1838. if (NULL != aTrans)
  1839. {
  1840. MemFree(aTrans);
  1841. }
  1842. return TRUE;
  1843. }
  1844. //
  1845. // CheckAvailableMem : check available memory size
  1846. // params
  1847. // lpEpage : Pointer to the EPAGEMDV.
  1848. // pUFObj : Pointer to the UNIFONTOBJ.
  1849. // return
  1850. // available memory size in bytes
  1851. //
  1852. DWORD CheckAvailableMem(LPEPAGEMDV lpEpage, PUNIFONTOBJ pUFObj)
  1853. {
  1854. GETINFO_MEMORY meminfo;
  1855. if (lpEpage == NULL || pUFObj == NULL) // Checking null-pointer.
  1856. {
  1857. return 0;
  1858. }
  1859. // get memory information
  1860. meminfo.dwSize = sizeof(GETINFO_MEMORY);
  1861. if (!pUFObj->pfnGetInfo(pUFObj, UFO_GETINFO_MEMORY, &meminfo, 0, NULL))
  1862. {
  1863. ERR(("UFO_GETINFO_MEMORY failed.\r\n"));
  1864. return 0; // error
  1865. }
  1866. // DCR: Unidrv might return NEGATIVE value
  1867. if ((long)meminfo.dwRemainingMemory < 0)
  1868. meminfo.dwRemainingMemory = 0;
  1869. if (lpEpage->dwMemAvailable != meminfo.dwRemainingMemory)
  1870. {
  1871. lpEpage->dwMemAvailable = meminfo.dwRemainingMemory;
  1872. // DBGPRINT(DBG_WARNING, (DLLTEXT("Available memory = %d bytes\r\n"), meminfo.dwRemainingMemory));
  1873. }
  1874. return meminfo.dwRemainingMemory;
  1875. }
  1876. // ----- These following functions are substitutes of "sprintf". -----
  1877. //
  1878. // EP_StringCbPrintf_with_int1 : The substitute of "sprintf" for using functions in "strsafe.h."
  1879. // This function has a parameter of int for formated string.
  1880. // params
  1881. // lpBuff : Storage location for output.
  1882. // buff_length : Size of lpBuff.
  1883. // pszFormat : Format-control string.
  1884. // Arg_int1 : Parameter of the type of "int" for pszFormat.
  1885. // return
  1886. // the written size(bytes) in lpBuff.
  1887. //
  1888. size_t EP_StringCbPrintf_with_int1(char *lpBuff, size_t buff_length, const char *pszFormat, int Arg_int1)
  1889. {
  1890. size_t remain_size;
  1891. size_t written_size = 0;
  1892. HRESULT hr;
  1893. hr = StringCbPrintfExA(lpBuff, buff_length, NULL, &remain_size,
  1894. STRSAFE_FILL_ON_FAILURE, pszFormat, Arg_int1);
  1895. if(SUCCEEDED(hr)) {
  1896. written_size = buff_length - remain_size;
  1897. }
  1898. return written_size;
  1899. }
  1900. //
  1901. // EP_StringCbPrintf_with_int2 : The substitute of "sprintf" for using functions in "strsafe.h."
  1902. // This function has two parameters of int for formated string.
  1903. // params
  1904. // lpBuff : Storage location for output.
  1905. // buff_length : Size of lpBuff.
  1906. // pszFormat : Format-control string.
  1907. // Arg_int1 : Parameter1 of the type of "int" for pszFormat.
  1908. // Arg_int2 : Parameter2 of the type of "int" for pszFormat.
  1909. // return
  1910. // the written size(bytes) in lpBuff.
  1911. //
  1912. size_t EP_StringCbPrintf_with_int2(char *lpBuff, size_t buff_length, const char *pszFormat,
  1913. int Arg_int1, int Arg_int2)
  1914. {
  1915. size_t remain_size;
  1916. size_t written_size = 0;
  1917. HRESULT hr;
  1918. hr = StringCbPrintfExA(lpBuff, buff_length, NULL, &remain_size,
  1919. STRSAFE_FILL_ON_FAILURE, pszFormat, Arg_int1, Arg_int2);
  1920. if(SUCCEEDED(hr)) {
  1921. written_size = buff_length - remain_size;
  1922. }
  1923. return written_size;
  1924. }
  1925. //
  1926. // EP_StringCbPrintf_with_int2 : The substitute of "sprintf" for using functions in "strsafe.h."
  1927. // This function has a parameter of string for formated string.
  1928. // params
  1929. // lpBuff : Storage location for output.
  1930. // buff_length : Size of lpBuff.
  1931. // pszFormat : Format-control string.
  1932. // pArgS : Parameter of the type of char-string for pszFormat.
  1933. // return
  1934. // the written size(bytes) in lpBuff.
  1935. //
  1936. size_t EP_StringCbPrintf_with_String(char *lpBuff, size_t buff_length, const char *pszFormat, char *pArgS)
  1937. {
  1938. size_t remain_size;
  1939. size_t written_size = 0;
  1940. HRESULT hr;
  1941. if(pArgS == NULL)
  1942. return 0;
  1943. hr = StringCbPrintfExA(lpBuff, buff_length, NULL, &remain_size,
  1944. STRSAFE_FILL_ON_FAILURE, pszFormat, pArgS);
  1945. if(SUCCEEDED(hr)) {
  1946. written_size = buff_length - remain_size;
  1947. }
  1948. return written_size;
  1949. }
  1950. // DEBUG
  1951. #ifdef DBGMSGBOX
  1952. #if defined(KERNEL_MODE) && !defined(USERMODE_DRIVER)
  1953. int DbgMsg(LPEPAGEMDV lpEpage, UINT mbicon, LPCTSTR msgfmt, ...)
  1954. {
  1955. // can't do anything against GUI
  1956. return 0;
  1957. }
  1958. int MsgBox(LPEPAGEMDV lpEpage, LPCTSTR msg, UINT mbicon)
  1959. {
  1960. // can't do anything against GUI
  1961. return 0;
  1962. }
  1963. #else // Usermode
  1964. int DbgMsg(LPEPAGEMDV lpEpage, UINT mbicon, LPCTSTR msgfmt, ...)
  1965. {
  1966. TCHAR buf[256];
  1967. va_list va;
  1968. va_start(va, msgfmt);
  1969. StringCbVPrintfW(buf, msgfmt, va);
  1970. va_end(va);
  1971. return MsgBox(lpEpage, buf, mbicon);
  1972. }
  1973. int MsgBox(LPEPAGEMDV lpEpage, LPCTSTR msg, UINT mbicon)
  1974. {
  1975. int rc = IDOK;
  1976. if (mbicon != MB_OK)
  1977. lpEpage->fGeneral &= ~FLAG_SKIPMSG;
  1978. if (!(lpEpage->fGeneral & FLAG_SKIPMSG))
  1979. {
  1980. if (IDCANCEL ==
  1981. (rc = MessageBox(GetDesktopWindow(), msg, L"EPAGCRES", mbicon|MB_OKCANCEL)))
  1982. {
  1983. lpEpage->fGeneral |= FLAG_SKIPMSG;
  1984. }
  1985. }
  1986. return rc;
  1987. }
  1988. #endif
  1989. #endif // #ifdef DBGMSGBOX
  1990. // DEBUG