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.

1880 lines
56 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. fmcallbk.c
  5. Abstract:
  6. The font module callback helper functions
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. 03/31/97 -eigos-
  11. Created
  12. --*/
  13. #include "font.h"
  14. #define CALL_OEMOUTPUTCHARSTR(type, count, startpoint) \
  15. if(bCOMInterface) \
  16. { \
  17. HComOutputCharStr((POEM_PLUGIN_ENTRY)pPDev->pOemEntry, \
  18. &pPDev->devobj, \
  19. (PUNIFONTOBJ)pUFObj, \
  20. (type), \
  21. (count), \
  22. (startpoint)); \
  23. } \
  24. else \
  25. { \
  26. if (pfnOEMOutputCharStr) \
  27. pfnOEMOutputCharStr(&pPDev->devobj, \
  28. (PUNIFONTOBJ)pUFObj, \
  29. (type), \
  30. (count), \
  31. (startpoint)); \
  32. }
  33. #define GET_CHARWIDTH(width, pfontmap, hg) \
  34. if (pfontmap->flFlags & FM_WIDTHRES) \
  35. { \
  36. if (!(width = IGetUFMGlyphWidth(pPDev, pfontmap, hg))) \
  37. width = (INT)pIFIMet->fwdAveCharWidth; \
  38. } \
  39. else \
  40. { \
  41. if (pTrans[hg - 1].ubType & MTYPE_DOUBLE) \
  42. width = pIFIMet->fwdMaxCharInc; \
  43. else \
  44. width = pIFIMet->fwdAveCharWidth; \
  45. } \
  46. if (pfontmap->flFlags & FM_SCALABLE) \
  47. { \
  48. width = LMulFloatLong(&pFontPDev->ctl.eXScale,width); \
  49. }
  50. //
  51. // Local functions' prototype definition
  52. //
  53. WCHAR
  54. WGHtoUnicode(
  55. DWORD dwNumOfRuns,
  56. PGLYPHRUN pGlyphRun,
  57. HGLYPH hg);
  58. //
  59. // UNIFONTOBJ callback interface
  60. //
  61. BOOL
  62. UNIFONTOBJ_GetInfo(
  63. IN PUNIFONTOBJ pUFObj,
  64. IN DWORD dwInfoID,
  65. IN PVOID pData,
  66. IN DWORD dwDataSize,
  67. OUT PDWORD pcbNeeded)
  68. /*++
  69. Routine Description:
  70. Implementation of UNIFONTOBJ GetInfo function
  71. Please refer to DDK
  72. Arguments:
  73. pUFOBj - a pointer to UNIFONTOBJ
  74. dwInfoID - Function ID
  75. pData - a pointer to data structure according to dwInfoID
  76. dwDataSize - size of pData
  77. pcbNeeded - DWORD buffer to return the necessary size of pData
  78. Return Value:
  79. TRUE if successful, otherwise FALSE.
  80. Note:
  81. --*/
  82. {
  83. PI_UNIFONTOBJ pI_UFObj = (PI_UNIFONTOBJ)pUFObj;
  84. GETINFO_GLYPHSTRING* pGlyphString;
  85. GETINFO_GLYPHBITMAP* pGlyphBitmap;
  86. GETINFO_GLYPHWIDTH* pGlyphWidth;
  87. GETINFO_STDVAR* pStdVar;
  88. PFONTPDEV pFontPDev;
  89. PUNI_GLYPHSETDATA pGlyphData;
  90. PTRANSDATA pTrans, pTransOut, pTransOutStart;
  91. PMAPTABLE pMapTable;
  92. PGLYPHRUN pGlyphRun;
  93. HGLYPH *pHGlyph;
  94. PDLGLYPH *apdlGlyph;
  95. PBYTE pbString, pbOutput;
  96. LONG *plWidth, lBuffSize;
  97. DWORD *pGlyphID, dwI, dwJ;
  98. WCHAR *pUnicode;
  99. DWORD dwNumOfVar, dwCount, dwSVID, dwNumOfRuns, dwBuffSize;
  100. BOOL bRet;
  101. static STDVARIABLE FontStdVariable[FNT_INFO_MAX] = {
  102. SV_PRINTDIRECTION,
  103. SV_GRAYPERCENT,
  104. SV_NEXTFONTID,
  105. SV_NEXTGLYPH,
  106. SV_FONTHEIGHT,
  107. SV_FONTWIDTH,
  108. SV_FONTBOLD,
  109. SV_FONTITALIC,
  110. SV_FONTUNDERLINE,
  111. SV_FONTSTRIKETHRU,
  112. SV_CURRENTFONTID,
  113. SV_TEXTYRES,
  114. SV_TEXTXRES,
  115. SV_FONTMAXWIDTH };
  116. //
  117. // Error check
  118. //
  119. if (!pI_UFObj )
  120. {
  121. ERR(("UNIFONTOBJ_GetInfo(): pUFObj is NULL.\n"));
  122. return FALSE;
  123. }
  124. if (!pData)
  125. //
  126. // pData == NULL case
  127. // Return the necessary buffer size
  128. //
  129. {
  130. bRet = TRUE;
  131. if (!pcbNeeded)
  132. {
  133. ERR(("UNIFONTOBJ_GetInfo(): pData and pcbNeed is NULL.\n"));
  134. bRet = FALSE;
  135. }
  136. else
  137. {
  138. switch (dwInfoID)
  139. {
  140. case UFO_GETINFO_FONTOBJ:
  141. *pcbNeeded = sizeof(GETINFO_FONTOBJ);
  142. break;
  143. case UFO_GETINFO_GLYPHSTRING:
  144. *pcbNeeded = sizeof(GETINFO_GLYPHSTRING);
  145. break;
  146. case UFO_GETINFO_GLYPHBITMAP:
  147. *pcbNeeded = sizeof(GETINFO_GLYPHBITMAP);
  148. break;
  149. case UFO_GETINFO_GLYPHWIDTH:
  150. *pcbNeeded = sizeof(GETINFO_GLYPHWIDTH);
  151. break;
  152. case UFO_GETINFO_MEMORY:
  153. *pcbNeeded = sizeof(GETINFO_MEMORY);
  154. break;
  155. case UFO_GETINFO_STDVARIABLE:
  156. *pcbNeeded = sizeof(GETINFO_STDVAR);
  157. break;
  158. default:
  159. *pcbNeeded = 0;
  160. bRet = FALSE;
  161. VERBOSE(("UNIFONTOBJ_GetInfo(): Invalid dwInfoID.\n"));
  162. break;
  163. }
  164. }
  165. }
  166. else
  167. {
  168. bRet = FALSE;
  169. //
  170. // ERROR CHECK LIST
  171. // (A) Data structure size check
  172. // GETINFO_FONTOBJ
  173. // GETINFO_GLYPHYSTRING
  174. // GETINFO_GLYPHBITMAP
  175. // GETINFO_GLYPHWIDTH
  176. // GETINFO_MEORY
  177. // GETNFO_STDVARIABLE
  178. // (B) Necessary data pointer check
  179. // e.g. pI_UFObj->XXXX
  180. //
  181. switch (dwInfoID)
  182. {
  183. case UFO_GETINFO_FONTOBJ:
  184. //
  185. // Return FONTOBJ data in GETINFO_FONTOBJ
  186. // typedef struct _GETINFO_FONTOBJ {
  187. // DWORD dwSize; // Size of this structure
  188. // FONTOBJ *pFontObj; // Pointer to the FONTOBJ
  189. // } GETINFO_FONTOBJ, *PGETINFO_FONTOBJ;
  190. //
  191. // ERROR CHECK
  192. // (A) and (B)
  193. // (B) pI_UFObj->pFontObj
  194. //
  195. if (((GETINFO_FONTOBJ*)pData)->dwSize != sizeof(GETINFO_FONTOBJ) || !pI_UFObj->pFontObj)
  196. {
  197. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_FONTOBJ): pData or pUFObj is invalid.\n"));
  198. break;
  199. }
  200. ((GETINFO_FONTOBJ*)pData)->pFontObj = pI_UFObj->pFontObj;
  201. bRet = TRUE;
  202. break;
  203. case UFO_GETINFO_GLYPHSTRING:
  204. //
  205. // Return glyph string
  206. //
  207. // typedef struct _GETINFO_GLYPHSTRING {
  208. // DWORD dwSize; // Size of this structure
  209. // DWORD dwCount; // Count of glyphs in pGlyphIn
  210. // DWORD dwTypeIn; // Glyph type of pGlyphIn, TYPE_GLYPHID/TYPE_HANDLE.
  211. // PVOID pGlyphIn; // Pointer to the input glyph string
  212. // DWORD dwTypeOut; // Glyph type of pGlyphOut, TYPE_UNICODE/TYPE_TRANSDATA.
  213. // PVOID pGlyphOut; // Pointer to the output glyph string
  214. // DWORD dwGlyphOutSize; // The size of pGlyphOut buffer
  215. // } GETINFO_GLYPHSTRING, *PGETINFO_GLYPHSTRING;
  216. //
  217. //
  218. // OutputGlyph callback function receives
  219. // 1. GLYPH HANLDE for Device font
  220. // 2. GLYPH ID for TrueType font
  221. //
  222. // In TYPE_GLYPHHANDLE (Device font)
  223. // Out TYPE_UNICODE
  224. // TYPE_TRANSDATA
  225. //
  226. // In TYPE_GLYPHID (TrueType font)
  227. // Out TYPE_UNICODE
  228. // Out TYPE_GLYPHHANDLE
  229. //
  230. // <Special case for TYPE_GLYPHHANDLE -> TYPE_TRANSDATA conversion>
  231. // TRANSDATA could have MTYPE_COMPOSE so that UNIDRV doesn't know the size of output buffer.
  232. // At the first call, a minidriver sets 0 to dwGlyphOutSize.
  233. // Then UNIDRV returns necessary buffer size in dwGlyphOutSize.
  234. // At the second call, a minidriver allocates memory, set the pointer of it to pGlyphOut,
  235. // and set the size to dwGlyphOutSize.
  236. //
  237. //
  238. pGlyphString = pData;
  239. dwCount = pGlyphString->dwCount;
  240. if (!dwCount)
  241. {
  242. //
  243. // No operation is necessary.
  244. //
  245. break;
  246. }
  247. //
  248. // ERROR CHECK (A)
  249. // pGlyphString
  250. //
  251. if ( !pGlyphString->pGlyphIn ||
  252. pGlyphString->dwTypeOut != TYPE_TRANSDATA &&
  253. !pGlyphString->pGlyphOut )
  254. {
  255. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_FONTOBJ): pData is invalid.\n"));
  256. break;
  257. }
  258. //
  259. // Now we support type size of GETINFO_GLYPHSTRING.
  260. // This is a bug backward compatibility.
  261. // Before beta 3 GETINFO_GLYPHSTRING didn't have dwGlyphOutSize.
  262. // Now we have new data structure but don't change the name of
  263. // structure.
  264. //
  265. if (!(
  266. (pGlyphString->dwSize == sizeof(GETINFO_GLYPHSTRING)) ||
  267. (pGlyphString->dwSize == sizeof(GETINFO_GLYPHSTRING) - sizeof(DWORD))
  268. )
  269. )
  270. {
  271. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_FONTOBJ): pData is invalid.\n"));
  272. break;
  273. }
  274. //
  275. // ERROR CHECK (B)
  276. // pI_UFObj->pFontMap
  277. // pI_UFObj->pPDev
  278. //
  279. if (!pI_UFObj->pFontMap || !pI_UFObj->pPDev)
  280. {
  281. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_FONTOBJ): pUFObj is invalid.\n"));
  282. break;
  283. }
  284. switch(pGlyphString->dwTypeIn)
  285. {
  286. case TYPE_GLYPHHANDLE:
  287. //
  288. // Device font case
  289. //
  290. if ( pI_UFObj->pFontMap->dwFontType == FMTYPE_DEVICE )
  291. {
  292. pHGlyph = pGlyphString->pGlyphIn;
  293. pGlyphData = ((PFONTMAP_DEV)pI_UFObj->pFontMap->pSubFM)->pvNTGlyph;
  294. dwNumOfRuns = pGlyphData->dwRunCount;
  295. switch(pGlyphString->dwTypeOut)
  296. {
  297. case TYPE_UNICODE:
  298. pUnicode = pGlyphString->pGlyphOut;
  299. pGlyphRun = GET_GLYPHRUN(pGlyphData);
  300. while (dwCount--)
  301. {
  302. *pUnicode++ = WGHtoUnicode(dwNumOfRuns,
  303. pGlyphRun,
  304. *pHGlyph++);
  305. }
  306. bRet = TRUE;
  307. break;
  308. case TYPE_TRANSDATA:
  309. pTransOutStart = pTransOut = pGlyphString->pGlyphOut;
  310. pMapTable = GET_MAPTABLE(pGlyphData);
  311. pTrans = pMapTable->Trans;
  312. dwBuffSize = pGlyphString->dwGlyphOutSize;
  313. //
  314. // New version of GETINFO_GLYPYSTRING
  315. //
  316. if ( pGlyphString->dwSize == sizeof(GETINFO_GLYPHSTRING) )
  317. {
  318. if (0 == dwBuffSize)
  319. {
  320. while (dwCount --)
  321. {
  322. if (!(pTrans[*pHGlyph - 1].ubType & MTYPE_COMPOSE))
  323. {
  324. dwBuffSize += sizeof(TRANSDATA);
  325. }
  326. else
  327. {
  328. pbString = (PBYTE)pMapTable + pTrans[*pHGlyph - 1].uCode.sCode;
  329. dwBuffSize += sizeof(TRANSDATA) + *(PWORD)pbString + sizeof(WORD);
  330. }
  331. pHGlyph++;
  332. }
  333. pGlyphString->dwGlyphOutSize = dwBuffSize;
  334. }
  335. else
  336. {
  337. //
  338. // Initialize the MTYPE_COMPOSE buffer
  339. //
  340. pbOutput = (PBYTE)pTransOutStart + dwCount * sizeof(TRANSDATA);
  341. lBuffSize = dwBuffSize - dwCount * sizeof(TRANSDATA);
  342. if (lBuffSize < 0 || NULL == pTransOut)
  343. {
  344. break;
  345. }
  346. else
  347. {
  348. bRet = TRUE;
  349. while (dwCount --)
  350. {
  351. *pTransOut = pTrans[*pHGlyph - 1];
  352. if (pTrans[*pHGlyph - 1].ubType & MTYPE_COMPOSE)
  353. {
  354. pbString = (PBYTE)pMapTable + pTrans[*pHGlyph - 1].uCode.sCode;
  355. if (lBuffSize >= *(PWORD)pbString)
  356. {
  357. pTransOut->uCode.sCode = (SHORT)(pbOutput - (PBYTE)pTransOutStart);
  358. CopyMemory(pbOutput, pbString, *(PWORD)pbString + sizeof(WORD));
  359. pbOutput += *(PWORD)pbString + sizeof(WORD);
  360. lBuffSize -= *(PWORD)pbString + sizeof(WORD);
  361. }
  362. else
  363. {
  364. bRet = FALSE;
  365. break;
  366. }
  367. }
  368. pTransOut ++;
  369. pHGlyph ++;
  370. }
  371. }
  372. }
  373. }
  374. //
  375. // New version of GETINFO_GLYPYSTRING
  376. //
  377. else if ( pGlyphString->dwSize == sizeof(GETINFO_GLYPHSTRING) - sizeof(DWORD) )
  378. {
  379. pTransOut = pGlyphString->pGlyphOut;
  380. pMapTable = GET_MAPTABLE(pGlyphData);
  381. pTrans = pMapTable->Trans;
  382. while (dwCount --)
  383. {
  384. *pTransOut++ = pTrans[*pHGlyph++ - 1];
  385. }
  386. bRet = TRUE;
  387. }
  388. break;
  389. default:
  390. break;
  391. }
  392. }
  393. break;
  394. case TYPE_GLYPHID:
  395. //
  396. // TrueType font case
  397. //
  398. pGlyphID = (PDWORD)pGlyphString->pGlyphIn;
  399. apdlGlyph = pI_UFObj->apdlGlyph;
  400. if (!apdlGlyph)
  401. {
  402. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_GLYPHSTRING): pUFObj is not correct.\n"));
  403. break;
  404. }
  405. if (pI_UFObj->pFontMap->dwFontType == FMTYPE_TTOEM)
  406. {
  407. switch (pGlyphString->dwTypeOut)
  408. {
  409. case TYPE_UNICODE:
  410. pUnicode = pGlyphString->pGlyphOut;
  411. while (dwCount--)
  412. {
  413. *pUnicode = 0;
  414. for (dwI = 0; dwI < pI_UFObj->dwNumInGlyphTbl; dwI++, apdlGlyph++)
  415. {
  416. if ((*apdlGlyph)->wDLGlyphID == (0x0ffff & *pGlyphID))
  417. {
  418. *pUnicode = (*apdlGlyph)->wchUnicode;
  419. break;
  420. }
  421. }
  422. pGlyphID ++;
  423. pUnicode ++;
  424. }
  425. bRet = TRUE;
  426. break;
  427. case TYPE_GLYPHHANDLE:
  428. pHGlyph = pGlyphString->pGlyphOut;
  429. while (dwCount--)
  430. {
  431. *pHGlyph = 0;
  432. for (dwI = 0; dwI < pI_UFObj->dwNumInGlyphTbl; dwI++, apdlGlyph++)
  433. {
  434. if ((*apdlGlyph)->wDLGlyphID == (0x0ffff & *pGlyphID))
  435. {
  436. *pHGlyph = (*apdlGlyph)->hTTGlyph;
  437. break;
  438. }
  439. }
  440. pGlyphID ++;
  441. pHGlyph ++;
  442. }
  443. bRet = TRUE;
  444. break;
  445. }
  446. }
  447. break;
  448. }
  449. break;
  450. case UFO_GETINFO_GLYPHBITMAP:
  451. //
  452. // Return Glyph Bitmap
  453. //
  454. // typedef struct _GETINFO_GLYPHBITMAP {
  455. // DWORD dwSize; // Size of this structure
  456. // HGLYPH hGlyph; // Glyph hangle passed in OEMDownloadCharGlyph
  457. // GLYPHDATA *pGlyphData; // Pointer to the GLYPHDATA data structure
  458. // } GETINFO_GLYPHBITMAP, *PGETINFO_GLYPHBITMAP;
  459. //
  460. pGlyphBitmap = pData;
  461. //
  462. // Error check (A) and (B)
  463. // (B) pI_UFObj->pFontObj
  464. //
  465. if (!pI_UFObj->pFontObj || pGlyphBitmap->dwSize != sizeof(GETINFO_GLYPHBITMAP))
  466. break;
  467. if (FONTOBJ_cGetGlyphs(pI_UFObj->pFontObj,
  468. FO_GLYPHBITS,
  469. 1,
  470. &pGlyphBitmap->hGlyph,
  471. &pGlyphBitmap->pGlyphData) )
  472. {
  473. bRet = TRUE;
  474. }
  475. break;
  476. case UFO_GETINFO_GLYPHWIDTH:
  477. //
  478. // Return glyph width.
  479. //
  480. // typedef struct _GETINFO_GLYPHWIDTH {
  481. // DWORD dwSize; // Size of this structure
  482. // DWORD dwType; // Type of glyph stirng in pGlyph, TYPE_GLYPHHANDLE/GLYPHID.
  483. // DWORD dwCount; // Count of glyph in pGlyph
  484. // PVOID pGlyph; // Pointer to a glyph string
  485. // PLONG plWidth; // Pointer to the buffer of width table.
  486. // // Minidriver has to prepare this.
  487. // } GETINFO_GLYPHWIDTH, *PGETINFO_GLYPHWIDTH;
  488. //
  489. pGlyphWidth = pData;
  490. //
  491. // Error check (A)
  492. //
  493. if ((pGlyphWidth->dwSize != sizeof(GETINFO_GLYPHWIDTH))||
  494. !(plWidth = pGlyphWidth->plWidth) ||
  495. !(pGlyphID = pGlyphWidth->pGlyph) )
  496. {
  497. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_GLYPHWIDTH): pData is not correct.\n"));
  498. break;
  499. }
  500. //
  501. // Error check (B)
  502. // pI_UFObj->pPDev
  503. // pI_UFObj->pFontObj
  504. //
  505. if (!pI_UFObj->pPDev)
  506. {
  507. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_GLYPHWIDTH): pUFObj is not correct.\n"));
  508. break;
  509. }
  510. switch(pGlyphWidth->dwType)
  511. {
  512. case TYPE_GLYPHID:
  513. if (pUFObj->dwFlags & UFOFLAG_TTFONT)
  514. {
  515. HGLYPH hGlyph;
  516. if (!pI_UFObj->pFontObj)
  517. {
  518. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_GLYPHWIDTH): UNIDRV needs FONTOBJ. This must be white text case!\n"));
  519. break;
  520. }
  521. for (dwI = 0, pGlyphID = pGlyphWidth->pGlyph;
  522. dwI < pGlyphWidth->dwCount;
  523. dwI ++, pGlyphID ++, plWidth++)
  524. {
  525. apdlGlyph = pI_UFObj->apdlGlyph;
  526. for (dwJ = 0;
  527. dwJ < pI_UFObj->dwNumInGlyphTbl;
  528. dwJ++ , apdlGlyph++)
  529. {
  530. if ((*apdlGlyph)->wDLGlyphID == (0x0ffff & *pGlyphID))
  531. {
  532. hGlyph = (*apdlGlyph)->hTTGlyph;
  533. break;
  534. }
  535. }
  536. *plWidth= DwGetTTGlyphWidth(pI_UFObj->pPDev->pFontPDev,
  537. pI_UFObj->pFontObj,
  538. hGlyph);
  539. }
  540. bRet = TRUE;
  541. }
  542. break;
  543. case TYPE_GLYPHHANDLE:
  544. if (!(pUFObj->dwFlags & UFOFLAG_TTFONT))
  545. {
  546. for (dwI = 0,pHGlyph = pGlyphWidth->pGlyph;
  547. dwI < pGlyphWidth->dwCount;
  548. dwI ++, pHGlyph++, plWidth++)
  549. {
  550. *plWidth = IGetUFMGlyphWidthJr(&pI_UFObj->ptGrxRes,
  551. pI_UFObj->pFontMap,
  552. *pHGlyph);
  553. }
  554. bRet = TRUE;
  555. }
  556. break;
  557. }
  558. break;
  559. case UFO_GETINFO_MEMORY:
  560. //
  561. // Retuen available memory on the printer.
  562. //
  563. // typedef struct _GETINFO_MEMORY {
  564. // DWORD dwSize;
  565. // DWORD dwRemainingMemory;
  566. // } GETINFO_MEMORY, PGETINFO_MEMROY;
  567. //
  568. // Error check (A)
  569. //
  570. if (((GETINFO_MEMORY*)pData)->dwSize != sizeof(GETINFO_MEMORY))
  571. {
  572. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_MEMORY): pData is not correct.\n"));
  573. break;
  574. }
  575. //
  576. // Error check (B)
  577. // pI_UFObj->pPDev
  578. // pI_UFObj->pPDev->pFontPDev
  579. //
  580. if (!pI_UFObj->pPDev || !(pFontPDev = pI_UFObj->pPDev->pFontPDev))
  581. {
  582. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_MEMORY): pUFObj is not correct.\n"));
  583. break;
  584. }
  585. ((GETINFO_MEMORY*)pData)->dwRemainingMemory = pFontPDev->dwFontMem;
  586. bRet = TRUE;
  587. break;
  588. case UFO_GETINFO_STDVARIABLE:
  589. //
  590. // Return standard variables
  591. //
  592. //typedef struct _GETINFO_STDVAR {
  593. // DWORD dwSize;
  594. // DWORD dwNumOfVariable;
  595. // struct {
  596. // DWORD dwStdVarID;
  597. // LONG lStdVariable;
  598. // } StdVar[1];
  599. //} GETINFO_STDVAR, *PGETINFO_STDVAR;
  600. //
  601. //
  602. // FNT_INFO_PRINTDIRINCCDEGREES 0 // PrintDirInCCDegrees
  603. // FNT_INFO_GRAYPERCENTAGE 1 // GrayPercentage
  604. // FNT_INFO_NEXTFONTID 2 // NextfontID
  605. // FNT_INFO_NEXTGLYPH 3 // NextGlyph
  606. // FNT_INFO_FONTHEIGHT 4 // FontHeight
  607. // FNT_INFO_FONTWIDTH 5 // FontWidth
  608. // FNT_INFO_FONTBOLD 6 // FontBold
  609. // FNT_INFO_FONTITALIC 7 // FontItalic
  610. // FNT_INFO_FONTUNDERLINE 8 // FontUnderline
  611. // FNT_INFO_FONTSTRIKETHRU 9 // FontStrikeThru
  612. // FNT_INFO_CURRENTFONTID 10 // Current
  613. // FNT_INFO_TEXTYRES 11 // TextYRes
  614. // FNT_INFO_TEXTXRES 12 // TextXRes
  615. // FNT_INFO_FONTMAXWIDTH 13 // FontMaxWidth
  616. //
  617. pStdVar = pData;
  618. //
  619. // Error check (A)
  620. //
  621. if ( (pStdVar->dwSize != sizeof(GETINFO_STDVAR) +
  622. ((dwNumOfVar = pStdVar->dwNumOfVariable) - 1) * 2 * sizeof(DWORD))
  623. )
  624. {
  625. ERR(("UNIFONTOBJ_GetInfo(UFO_GETIFNO_STDVARIABLE): pData is incorrect.\n"));
  626. break;
  627. }
  628. //
  629. // Error check (B)
  630. // pI_UFObj->pPDev
  631. //
  632. if (!pI_UFObj->pPDev)
  633. {
  634. ERR(("UNIFONTOBJ_GetInfo(UFO_GETINFO_STDVARIABLE): pUFObj is not correct.\n"));
  635. break;
  636. }
  637. bRet = TRUE;
  638. while (dwNumOfVar--)
  639. {
  640. dwSVID =
  641. FontStdVariable[pStdVar->StdVar[dwNumOfVar].dwStdVarID];
  642. if (dwSVID > SV_MAX)
  643. {
  644. bRet = FALSE;
  645. ERR(("UFONTOBJ_GetInfo(UFO_GETIFNO_STDVARIABLE): pData is incorrect.\n"));
  646. break;
  647. }
  648. pStdVar->StdVar[dwNumOfVar].lStdVariable = *(pI_UFObj->pPDev->arStdPtrs[dwSVID]);
  649. }
  650. break;
  651. default:
  652. VERBOSE(("UNIFONTOBJ_GetInfo(): Invalid dwInfoID.\n"));
  653. break;
  654. }
  655. }
  656. return bRet;
  657. }
  658. //
  659. // Font module FONTMAP functions
  660. //
  661. DWORD
  662. DwOutputGlyphCallback(
  663. TO_DATA *pTod)
  664. /*++
  665. Routine Description:
  666. Implementation of OEM OutpuotGlyphCallback calling routine for FONTMAP dispatch routine
  667. Arguments:
  668. pTod - a pointer to TO_DATA.
  669. Return Value:
  670. The number of glyph printed.
  671. Note:
  672. --*/
  673. {
  674. PFN_OEMOutputCharStr pfnOEMOutputCharStr;
  675. PI_UNIFONTOBJ pUFObj;
  676. IFIMETRICS *pIFIMet;
  677. PFONTPDEV pFontPDev;
  678. PDEV *pPDev;
  679. PUNI_GLYPHSETDATA pGlyphData;
  680. PTRANSDATA pTrans;
  681. PMAPTABLE pMapTable;
  682. COMMAND *pCmd, *pCmdSingle, *pCmdDouble;
  683. FONTMAP *pFontMap;
  684. GLYPHPOS *pgp;
  685. PDLGLYPH pdlGlyph;
  686. POINTL ptlRem;
  687. DWORD dwI, dwCount;
  688. PDWORD pdwGlyph, pdwGlyphStart;
  689. INT iXInc, iYInc;
  690. BOOL bSetCursorForEachGlyph, bPrint, bNewFontSelect, bCOMInterface;
  691. bCOMInterface = FALSE;
  692. pPDev = pTod->pPDev;
  693. ASSERT(pPDev)
  694. pFontPDev = pPDev->pFontPDev;
  695. ASSERT(pFontPDev)
  696. pFontMap = pTod->pfm;
  697. pUFObj = (PI_UNIFONTOBJ)pFontPDev->pUFObj;
  698. ASSERT(pFontMap && pUFObj)
  699. pIFIMet = pFontMap->pIFIMet;
  700. ASSERT(pIFIMet)
  701. pfnOEMOutputCharStr = NULL;
  702. if ( pPDev->pOemHookInfo &&
  703. (pPDev->pOemHookInfo[EP_OEMOutputCharStr].pfnHook))
  704. {
  705. FIX_DEVOBJ(pPDev, EP_OEMOutputCharStr);
  706. if( pPDev->pOemEntry && ((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem )
  707. {
  708. bCOMInterface = TRUE;
  709. }
  710. else
  711. {
  712. pfnOEMOutputCharStr = (PFN_OEMOutputCharStr)pPDev->pOemHookInfo[EP_OEMOutputCharStr].pfnHook;
  713. }
  714. }
  715. else if (pPDev->ePersonality != kPCLXL)
  716. {
  717. ERR(("DwOutputGlyphCallback: OEMOutputCharStr callback is not supported by a minidriver."));
  718. return 0;
  719. }
  720. //
  721. // Error exit
  722. //
  723. if (pFontMap->flFlags & FM_IFIVER40 || pUFObj->pGlyph == NULL)
  724. {
  725. ERR(("DwOutputGlyphCallback: pUFObj->pGlyph is NULL."));
  726. return 0;
  727. }
  728. //
  729. // OEMOutputCharStr passes two type of glyph string.
  730. // TYPE_GLYPHID for TrueType font
  731. // TYPE_GLYPHHANDLE for Device font
  732. //
  733. bSetCursorForEachGlyph = SET_CURSOR_FOR_EACH_GLYPH(pTod->flAccel);
  734. pdwGlyphStart =
  735. pdwGlyph = (PDWORD)pUFObj->pGlyph;
  736. pgp = pTod->pgp;
  737. pUFObj->pFontMap = pFontMap;
  738. if (pUFObj->dwFlags & UFOFLAG_TTFONT)
  739. {
  740. DWORD dwCurrGlyphIndex = pTod->dwCurrGlyph;
  741. PFONTMAP_TTOEM pFMOEM = (PFONTMAP_TTOEM) pFontMap->pSubFM;
  742. DL_MAP *pdm = pFMOEM->u.pvDLData;
  743. ASSERT(pTod->apdlGlyph);
  744. if (bSetCursorForEachGlyph)
  745. {
  746. for (dwI = 0;
  747. dwI < pTod->cGlyphsToPrint;
  748. dwI++, pgp++, dwCurrGlyphIndex++)
  749. {
  750. pdlGlyph = pTod->apdlGlyph[dwCurrGlyphIndex];
  751. if (!pdlGlyph)
  752. {
  753. //
  754. // pFM->pfnDownloadGlyph could fail by some reason.
  755. // Eventually apdlGlyph is not initialized by download.c
  756. //
  757. ERR(("DwOutputGlyphCallback: pTod->apdlGlyph[dwCurrGlyphIndex] is NULL."));
  758. continue;
  759. }
  760. if (GLYPH_IN_NEW_SOFTFONT(pFontPDev, pdm, pdlGlyph))
  761. {
  762. //
  763. // Need to select the new softfont.
  764. // We do this by setting pfm->ulDLIndex
  765. // to new softfontid.
  766. //
  767. pUFObj->ulFontID =
  768. pFontMap->ulDLIndex = pdlGlyph->wDLFontId;
  769. BNewFont(pPDev, pTod->iFace, pFontMap, 0);
  770. }
  771. VSetCursor( pPDev, pgp->ptl.x, pgp->ptl.y, MOVE_ABSOLUTE, &ptlRem);
  772. HANDLE_VECTORPROCS(pPDev, VMOutputCharStr, ((PDEVOBJ)pPDev,
  773. (PUNIFONTOBJ)pUFObj,
  774. TYPE_GLYPHID,
  775. 1,
  776. &(pdlGlyph->wDLGlyphID)))
  777. else
  778. CALL_OEMOUTPUTCHARSTR(TYPE_GLYPHID, 1, &(pdlGlyph->wDLGlyphID));
  779. //
  780. // Update position
  781. //
  782. VSetCursor( pPDev,
  783. pdlGlyph->wWidth,
  784. 0,
  785. MOVE_RELATIVE|MOVE_UPDATE,
  786. &ptlRem);
  787. }
  788. }
  789. else
  790. {
  791. VSetCursor( pPDev, pgp->ptl.x, pgp->ptl.y, MOVE_ABSOLUTE, &ptlRem);
  792. dwI = 0;
  793. dwCount = 0;
  794. bNewFontSelect = FALSE;
  795. do
  796. {
  797. for (; dwI < pTod->cGlyphsToPrint; pdwGlyph++, dwCount++, pgp++, dwI++, dwCurrGlyphIndex++)
  798. {
  799. pdlGlyph = pTod->apdlGlyph[dwCurrGlyphIndex];
  800. if (0 == pgp->hg)
  801. {
  802. //
  803. // UNIDRV returns 1 for the first glyph handle
  804. // in FD_GLYPHSET.
  805. // However, GDI could pass zero in hg.
  806. // We need to handle this GDI error properly.
  807. continue;
  808. }
  809. if (!pdlGlyph)
  810. {
  811. //
  812. // pFM->pfnDownloadGlyph could fail by some reason.
  813. // Eventually apdlGlyph is not initialized by download.c
  814. //
  815. ERR(("DwOutputGlyphCallback: pTod->apdlGlyph[dwCurrGlyphIndex++] is NULL."));
  816. continue;
  817. }
  818. *pdwGlyph = pdlGlyph->wDLGlyphID;
  819. if (GLYPH_IN_NEW_SOFTFONT(pFontPDev, pdm, pdlGlyph))
  820. {
  821. //
  822. // Need to select the new softfont.
  823. // We do this by setting pfm->ulDLIndex
  824. // to new softfontid.
  825. //
  826. pFontMap->ulDLIndex = pdlGlyph->wDLFontId;
  827. bNewFontSelect = TRUE;
  828. break;
  829. }
  830. }
  831. if (dwCount > 0)
  832. {
  833. HANDLE_VECTORPROCS(pPDev, VMOutputCharStr, ((PDEVOBJ)pPDev,
  834. (PUNIFONTOBJ)pUFObj,
  835. TYPE_GLYPHID,
  836. dwCount,
  837. pdwGlyphStart))
  838. else
  839. CALL_OEMOUTPUTCHARSTR(TYPE_GLYPHID, dwCount, pdwGlyphStart);
  840. //
  841. // Update position
  842. //
  843. pgp --;
  844. VSetCursor( pPDev,
  845. pgp->ptl.x + pdlGlyph->wWidth,
  846. pgp->ptl.y,
  847. MOVE_ABSOLUTE|MOVE_UPDATE,
  848. &ptlRem);
  849. dwCount = 0;
  850. }
  851. if (bNewFontSelect)
  852. {
  853. dwCount = 1;
  854. *pdwGlyphStart = *pdwGlyph;
  855. pdwGlyph = pdwGlyphStart + 1;
  856. pUFObj->ulFontID = pFontMap->ulDLIndex;
  857. BNewFont(pPDev, pTod->iFace, pFontMap, 0);
  858. bNewFontSelect = FALSE;
  859. }
  860. } while (dwCount > 0);
  861. }
  862. pgp --;
  863. if (NULL != pdlGlyph)
  864. {
  865. iXInc = pdlGlyph->wWidth;
  866. }
  867. else
  868. {
  869. iXInc = 0;
  870. }
  871. }
  872. else // Device Font
  873. {
  874. pGlyphData = ((PFONTMAP_DEV)pFontMap->pSubFM)->pvNTGlyph;
  875. pMapTable = GET_MAPTABLE(pGlyphData);
  876. pTrans = pMapTable->Trans;
  877. pCmdSingle = COMMANDPTR(pPDev->pDriverInfo, CMD_SELECTSINGLEBYTEMODE);
  878. pCmdDouble = COMMANDPTR(pPDev->pDriverInfo, CMD_SELECTDOUBLEBYTEMODE);
  879. if (bSetCursorForEachGlyph)
  880. {
  881. for (dwI = 0; dwI < pTod->cGlyphsToPrint; dwI ++, pgp ++)
  882. {
  883. //
  884. // UNIDRV returns 1 for the first glyph handle in FD_GLYPHSET.
  885. // However, GDI could pass zero in hg.
  886. // We need to handle this GDI error properly.
  887. //
  888. if (0 == pgp->hg)
  889. {
  890. continue;
  891. }
  892. VSetCursor( pPDev, pgp->ptl.x, pgp->ptl.y, MOVE_ABSOLUTE, &ptlRem);
  893. if (
  894. (pCmdSingle) &&
  895. (pTrans[pgp->hg - 1].ubType & MTYPE_SINGLE) &&
  896. !(pFontPDev->flFlags & FDV_SINGLE_BYTE)
  897. )
  898. {
  899. WriteChannel( pPDev, pCmdSingle );
  900. pFontPDev->flFlags |= FDV_SINGLE_BYTE;
  901. pFontPDev->flFlags &= ~FDV_DOUBLE_BYTE;
  902. }
  903. else
  904. if (
  905. (pCmdDouble) &&
  906. (pTrans[pgp->hg - 1].ubType & MTYPE_DOUBLE) &&
  907. !(pFontPDev->flFlags & FDV_DOUBLE_BYTE)
  908. )
  909. {
  910. WriteChannel( pPDev, pCmdDouble );
  911. pFontPDev->flFlags |= FDV_DOUBLE_BYTE;
  912. pFontPDev->flFlags &= ~FDV_SINGLE_BYTE;
  913. }
  914. HANDLE_VECTORPROCS(pPDev, VMOutputCharStr, ((PDEVOBJ)pPDev,
  915. (PUNIFONTOBJ)pUFObj,
  916. TYPE_GLYPHHANDLE,
  917. 1,
  918. &(pgp->hg)))
  919. else
  920. CALL_OEMOUTPUTCHARSTR(TYPE_GLYPHHANDLE, 1, &(pgp->hg));
  921. //
  922. // Update position
  923. //
  924. GET_CHARWIDTH(iXInc, pFontMap, pgp->hg);
  925. VSetCursor( pPDev,
  926. iXInc,
  927. 0,
  928. MOVE_RELATIVE|MOVE_UPDATE,
  929. &ptlRem);
  930. }
  931. }
  932. else // Default Placement
  933. {
  934. bPrint = FALSE;
  935. dwCount = 0;
  936. VSetCursor( pPDev, pgp->ptl.x, pgp->ptl.y, MOVE_ABSOLUTE, &ptlRem);
  937. for (dwI = 0; dwI < pTod->cGlyphsToPrint; dwI ++, pgp ++, pdwGlyph ++, dwCount++)
  938. {
  939. *pdwGlyph = pgp->hg;
  940. //
  941. // Single/Double byte mode switch
  942. //
  943. if (pCmdSingle &&
  944. (pTrans[*pdwGlyph - 1].ubType & MTYPE_SINGLE) &&
  945. !(pFontPDev->flFlags & FDV_SINGLE_BYTE) )
  946. {
  947. pFontPDev->flFlags &= ~FDV_DOUBLE_BYTE;
  948. pFontPDev->flFlags |= FDV_SINGLE_BYTE;
  949. pCmd = pCmdSingle;
  950. bPrint = TRUE;
  951. }
  952. else
  953. if (pCmdDouble &&
  954. (pTrans[*pdwGlyph - 1].ubType & MTYPE_DOUBLE) &&
  955. !(pFontPDev->flFlags & FDV_DOUBLE_BYTE) )
  956. {
  957. pFontPDev->flFlags |= FDV_DOUBLE_BYTE;
  958. pFontPDev->flFlags &= ~FDV_SINGLE_BYTE;
  959. pCmd = pCmdDouble;
  960. bPrint = TRUE;
  961. }
  962. if (bPrint)
  963. {
  964. if (dwI != 0)
  965. {
  966. HANDLE_VECTORPROCS(pPDev, VMOutputCharStr, ((PDEVOBJ)pPDev,
  967. (PUNIFONTOBJ)pUFObj,
  968. TYPE_GLYPHHANDLE,
  969. dwCount,
  970. pdwGlyphStart))
  971. else
  972. CALL_OEMOUTPUTCHARSTR(TYPE_GLYPHHANDLE, dwCount, pdwGlyphStart);
  973. //
  974. // Update position
  975. //
  976. GET_CHARWIDTH(iXInc, pFontMap, pgp->hg);
  977. VSetCursor( pPDev,
  978. iXInc,
  979. 0,
  980. MOVE_RELATIVE|MOVE_UPDATE,
  981. &ptlRem);
  982. dwCount = 0;
  983. pdwGlyphStart = pdwGlyph;
  984. }
  985. WriteChannel(pPDev, pCmd);
  986. bPrint = FALSE;
  987. }
  988. }
  989. HANDLE_VECTORPROCS(pPDev, VMOutputCharStr, ((PDEVOBJ)pPDev,
  990. (PUNIFONTOBJ)pUFObj,
  991. TYPE_GLYPHHANDLE,
  992. dwCount,
  993. pdwGlyphStart))
  994. else
  995. CALL_OEMOUTPUTCHARSTR(TYPE_GLYPHHANDLE, dwCount, pdwGlyphStart);
  996. }
  997. //
  998. // Output may have successed, so update the position.
  999. //
  1000. pgp --;
  1001. GET_CHARWIDTH(iXInc, pFontMap, pgp->hg);
  1002. VSetCursor( pPDev,
  1003. pgp->ptl.x + iXInc,
  1004. pgp->ptl.y,
  1005. MOVE_ABSOLUTE|MOVE_UPDATE,
  1006. &ptlRem);
  1007. }
  1008. return pTod->cGlyphsToPrint;
  1009. }
  1010. BOOL
  1011. BFontCmdCallback(
  1012. PDEV *pdev,
  1013. PFONTMAP pFM,
  1014. POINTL *pptl,
  1015. BOOL bSelect)
  1016. /*++
  1017. Routine Description:
  1018. Implementation of OEM SendFontCmd calling sub routine for FONTMAP dispatch routine
  1019. Arguments:
  1020. pdev - a pointer to PDEV
  1021. pFM - a pointer to FONTMAP
  1022. pptl - a pointer to POINTL which has the height and with of font
  1023. bSelect - Boolean to send selection/deselection command
  1024. Return Value:
  1025. TRUE if successful, otherwise FALSE.
  1026. Note:
  1027. --*/
  1028. {
  1029. PFN_OEMSendFontCmd pfnOEMSendFontCmd;
  1030. FONTPDEV *pFontPDev;
  1031. PFONTMAP_DEV pfmdev;
  1032. FINVOCATION FInv;
  1033. ASSERT(pdev && pFM);
  1034. if (pdev->pOemHookInfo &&
  1035. (pfnOEMSendFontCmd = (PFN_OEMSendFontCmd)pdev->pOemHookInfo[EP_OEMSendFontCmd].pfnHook) ||
  1036. (pdev->ePersonality == kPCLXL))
  1037. {
  1038. pFontPDev = pdev->pFontPDev;
  1039. pFontPDev->flFlags &= ~FDV_DOUBLE_BYTE | FDV_SINGLE_BYTE;
  1040. if (pFM->dwFontType == FMTYPE_DEVICE)
  1041. {
  1042. pfmdev = pFM->pSubFM;
  1043. pfmdev->ulCodepageID = (ULONG)-1;
  1044. pFontPDev->pUFObj->pFontMap = pFM;
  1045. if (pFM->flFlags & FM_IFIVER40)
  1046. {
  1047. if (bSelect)
  1048. {
  1049. FInv.dwCount = pfmdev->cmdFontSel.pCD->wLength;
  1050. FInv.pubCommand = pfmdev->cmdFontSel.pCD->rgchCmd;
  1051. }
  1052. else
  1053. {
  1054. FInv.dwCount = pfmdev->cmdFontDesel.pCD->wLength;
  1055. FInv.pubCommand = pfmdev->cmdFontDesel.pCD->rgchCmd;
  1056. }
  1057. }
  1058. else
  1059. {
  1060. if (bSelect)
  1061. {
  1062. FInv.dwCount = pfmdev->cmdFontSel.FInv.dwCount;
  1063. FInv.pubCommand = pfmdev->cmdFontSel.FInv.pubCommand;
  1064. }
  1065. else
  1066. {
  1067. FInv.dwCount = pfmdev->cmdFontDesel.FInv.dwCount;
  1068. FInv.pubCommand = pfmdev->cmdFontDesel.FInv.pubCommand;
  1069. }
  1070. }
  1071. }
  1072. else
  1073. if (pFM->dwFontType == FMTYPE_TTOEM)
  1074. {
  1075. //
  1076. // Initialize UNIFONTOBJ
  1077. //
  1078. pFontPDev->pUFObj->ulFontID = pFM->ulDLIndex;
  1079. pFontPDev->pUFObj->pFontMap = pFM;
  1080. //
  1081. // Initialize FInv
  1082. //
  1083. FInv.dwCount = sizeof(ULONG);
  1084. FInv.pubCommand = (PBYTE)&(pFontPDev->pUFObj->ulFontID);
  1085. }
  1086. HANDLE_VECTORPROCS(pdev, VMSendFontCmd, ((PDEVOBJ)pdev,
  1087. (PUNIFONTOBJ)pFontPDev->pUFObj,
  1088. &FInv))
  1089. else
  1090. {
  1091. FIX_DEVOBJ(pdev, EP_OEMSendFontCmd);
  1092. if (pdev->pOemEntry)
  1093. {
  1094. if(((POEM_PLUGIN_ENTRY)pdev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  1095. {
  1096. HRESULT hr ;
  1097. hr = HComSendFontCmd((POEM_PLUGIN_ENTRY)pdev->pOemEntry,
  1098. &pdev->devobj, (PUNIFONTOBJ)pFontPDev->pUFObj,
  1099. &FInv);
  1100. if(SUCCEEDED(hr))
  1101. ; // cool !
  1102. }
  1103. else
  1104. {
  1105. if (NULL != pfnOEMSendFontCmd)
  1106. {
  1107. pfnOEMSendFontCmd(&pdev->devobj,
  1108. (PUNIFONTOBJ)pFontPDev->pUFObj,
  1109. &FInv);
  1110. }
  1111. }
  1112. }
  1113. }
  1114. }
  1115. return TRUE;
  1116. }
  1117. BOOL
  1118. BSelectFontCallback(
  1119. PDEV *pdev,
  1120. PFONTMAP pFM,
  1121. POINTL *pptl)
  1122. /*++
  1123. Routine Description:
  1124. Implementation of OEM SendFontCMd calling routine for FONTMAP dispatch routine
  1125. Arguments:
  1126. pTod - a pointer to TO_DATA.
  1127. Return Value:
  1128. The number of glyph printed.
  1129. Note:
  1130. --*/
  1131. {
  1132. return BFontCmdCallback(pdev, pFM, pptl, TRUE);
  1133. }
  1134. BOOL
  1135. BDeselectFontCallback(
  1136. PDEV *pdev,
  1137. PFONTMAP pFM)
  1138. /*++
  1139. Routine Description:
  1140. Implementation of OEM SendFontCmd calling routine for FONTMAP dispatch routine
  1141. Arguments:
  1142. pTod - a pointer to TO_DATA.
  1143. Return Value:
  1144. The number of glyph printed.
  1145. Note:
  1146. --*/
  1147. {
  1148. return BFontCmdCallback(pdev, pFM, NULL, FALSE);
  1149. }
  1150. DWORD
  1151. DwDLHeaderOEMCallback(
  1152. PDEV *pPDev,
  1153. PFONTMAP pFM)
  1154. /*++
  1155. Routine Description:
  1156. Implementation of OEM SendFontCmd calling routine for FONTMAP dispatch routine
  1157. Arguments:
  1158. pPDev - a pointer to PDEV
  1159. pFM - a pointer to FONTMAP
  1160. Return Value:
  1161. Note:
  1162. --*/
  1163. {
  1164. PFN_OEMDownloadFontHeader pfnOEMDownloadFontHeader;
  1165. PFONTPDEV pFontPDev;
  1166. DWORD dwMem = 0;
  1167. //
  1168. // Should not be NULL
  1169. //
  1170. ASSERT(pPDev && pFM);
  1171. pFontPDev = pPDev->pFontPDev;
  1172. pfnOEMDownloadFontHeader = NULL;
  1173. if ( pPDev->pOemHookInfo &&
  1174. (pfnOEMDownloadFontHeader = (PFN_OEMDownloadFontHeader)
  1175. pPDev->pOemHookInfo[EP_OEMDownloadFontHeader].pfnHook) ||
  1176. (pPDev->ePersonality == kPCLXL))
  1177. {
  1178. HRESULT hr ;
  1179. if (pFontPDev->pUFObj == NULL)
  1180. {
  1181. //
  1182. // This should not happen. pUFObj must be initialized.
  1183. //
  1184. ERR(("DwDLHeaderOEMCallback: pFontPDev->pUFObj is NULL"));
  1185. return 0;
  1186. }
  1187. pFontPDev->pUFObj->pFontMap = pFM;
  1188. pFontPDev->pUFObj->ulFontID = pFM->ulDLIndex;
  1189. BUpdateStandardVar(pPDev, pFM, 0, 0, STD_STD | STD_NFID);
  1190. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID));
  1191. HANDLE_VECTORPROCS(pPDev, VMDownloadFontHeader, ((PDEVOBJ)pPDev,
  1192. (PUNIFONTOBJ)pFontPDev->pUFObj,
  1193. &dwMem))
  1194. else
  1195. {
  1196. FIX_DEVOBJ(pPDev, EP_OEMDownloadFontHeader);
  1197. if (pPDev->pOemEntry)
  1198. {
  1199. if(((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  1200. {
  1201. hr = HComDownloadFontHeader((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  1202. &pPDev->devobj, (PUNIFONTOBJ)pFontPDev->pUFObj, &dwMem);
  1203. if(SUCCEEDED(hr))
  1204. ; // cool !
  1205. }
  1206. else if (pfnOEMDownloadFontHeader)
  1207. {
  1208. dwMem = pfnOEMDownloadFontHeader(&pPDev->devobj,
  1209. (PUNIFONTOBJ)pFontPDev->pUFObj);
  1210. }
  1211. }
  1212. }
  1213. }
  1214. return dwMem;
  1215. }
  1216. DWORD
  1217. DwDLGlyphOEMCallback(
  1218. PDEV *pPDev,
  1219. PFONTMAP pFM,
  1220. HGLYPH hGlyph,
  1221. WORD wDLGlyphId,
  1222. WORD *pwWidth)
  1223. /*++
  1224. Routine Description:
  1225. Implementation of OEM SendFontCmd calling routine for FONTMAP dispatch routine
  1226. Arguments:
  1227. pPDev - a pointer to PDEV
  1228. pFM - a pointer to FONTMAP
  1229. Return Value:
  1230. Note:
  1231. --*/
  1232. {
  1233. PFN_OEMDownloadCharGlyph pfnOEMDownloadCharGlyph;
  1234. PI_UNIFONTOBJ pUFObj;
  1235. PFONTPDEV pFontPDev;
  1236. DL_MAP *pdm;
  1237. DWORD dwMem;
  1238. INT iWide;
  1239. //
  1240. // There values have to be non-NULL.
  1241. //
  1242. ASSERT(pPDev && pFM);
  1243. dwMem = 0;
  1244. iWide = 0;
  1245. pFontPDev = pPDev->pFontPDev;
  1246. pUFObj = pFontPDev->pUFObj;
  1247. pdm = ((PFONTMAP_TTOEM)pFM->pSubFM)->u.pvDLData;
  1248. pfnOEMDownloadCharGlyph = NULL;
  1249. //
  1250. // There values have to be non-NULL.
  1251. //
  1252. ASSERT(pFontPDev && pUFObj && pdm);
  1253. if ( pPDev->pOemHookInfo &&
  1254. (pfnOEMDownloadCharGlyph = (PFN_OEMDownloadCharGlyph)
  1255. pPDev->pOemHookInfo[EP_OEMDownloadCharGlyph].pfnHook) ||
  1256. (pPDev->ePersonality == kPCLXL))
  1257. {
  1258. HRESULT hr ;
  1259. if (!(PFDV->flFlags & FDV_SET_FONTID))
  1260. {
  1261. pFM->ulDLIndex = pdm->wCurrFontId;
  1262. BUpdateStandardVar(pPDev, pFM, 0, 0, STD_STD | STD_NFID);
  1263. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID));
  1264. PFDV->flFlags |= FDV_SET_FONTID;
  1265. }
  1266. BUpdateStandardVar(pPDev, pFM, wDLGlyphId, 0, STD_GL);
  1267. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETCHARCODE));
  1268. pUFObj->pFontMap = pFM;
  1269. pUFObj->ulFontID = pFM->ulDLIndex;
  1270. HANDLE_VECTORPROCS(pPDev, VMDownloadCharGlyph, ((PDEVOBJ)pPDev,
  1271. (PUNIFONTOBJ)pFontPDev->pUFObj,
  1272. hGlyph,
  1273. (PDWORD)&iWide,
  1274. &dwMem))
  1275. else
  1276. {
  1277. FIX_DEVOBJ(pPDev, EP_OEMDownloadCharGlyph);
  1278. if (pPDev->pOemEntry)
  1279. {
  1280. if(((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  1281. {
  1282. hr = HComDownloadCharGlyph((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  1283. &pPDev->devobj,
  1284. (PUNIFONTOBJ)pFontPDev->pUFObj,
  1285. hGlyph,
  1286. (PDWORD)&iWide, &dwMem);
  1287. if(SUCCEEDED(hr))
  1288. ; // cool !
  1289. }
  1290. else if (pfnOEMDownloadCharGlyph)
  1291. {
  1292. dwMem = pfnOEMDownloadCharGlyph(&pPDev->devobj,
  1293. (PUNIFONTOBJ)pFontPDev->pUFObj,
  1294. hGlyph,
  1295. (PDWORD)&iWide);
  1296. }
  1297. }
  1298. }
  1299. ((PFONTMAP_TTOEM)pFM->pSubFM)->dwDLSize += dwMem;
  1300. *pwWidth = (WORD)iWide;
  1301. }
  1302. return dwMem;
  1303. }
  1304. BOOL
  1305. BCheckCondOEMCallback(
  1306. PDEV *pPDev,
  1307. FONTOBJ *pfo,
  1308. STROBJ *pso,
  1309. IFIMETRICS *pifi
  1310. )
  1311. /*++
  1312. Routine Description:
  1313. Implementation of CheckConditon for FONTMAP dispatch routine
  1314. Arguments:
  1315. pPDev - a pointer to PDEV
  1316. pfo - a pointer to FONTOBJ
  1317. pso - a pointer to STROBJ
  1318. pifi - a pointer to IFIMETRICS
  1319. Return Value:
  1320. Note:
  1321. --*/
  1322. {
  1323. PFONTPDEV pFontPDev;
  1324. PI_UNIFONTOBJ pUFObj;
  1325. ASSERT(pPDev);
  1326. pFontPDev = pPDev->pFontPDev;
  1327. pUFObj = pFontPDev->pUFObj;
  1328. if (pUFObj->dwFlags & UFOFLAG_TTFONT)
  1329. return TRUE;
  1330. else
  1331. return FALSE;
  1332. }
  1333. BOOL
  1334. BSelectTrueTypeOutline(
  1335. PDEV *pPDev,
  1336. PFONTMAP pFM,
  1337. POINTL *pptl)
  1338. {
  1339. BOOL bRet = FALSE;
  1340. if( pFM->flFlags & FM_SOFTFONT )
  1341. {
  1342. if (BUpdateStandardVar(pPDev, pFM, 0, 0, STD_STD | STD_CFID ) &&
  1343. BFontCmdCallback(pPDev, pFM, pptl, TRUE) )
  1344. bRet = TRUE;
  1345. }
  1346. return bRet;
  1347. }
  1348. BOOL
  1349. BDeselectTrueTypeOutline(
  1350. PDEV *pPDev,
  1351. PFONTMAP pFM)
  1352. {
  1353. BOOL bRet = FALSE;
  1354. DWORD dwFlags;
  1355. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  1356. PFONTMAP_TTOEM pFMOEM = (PFONTMAP_TTOEM) pFM->pSubFM;
  1357. //
  1358. // Deselect case. We need to reinitialize UFObj
  1359. //
  1360. dwFlags = ((PI_UNIFONTOBJ)pFontPDev->pUFObj)->dwFlags;
  1361. ((PI_UNIFONTOBJ)pFontPDev->pUFObj)->dwFlags = pFMOEM->dwFlags;
  1362. if( pFM->flFlags & FM_SOFTFONT )
  1363. {
  1364. if (BUpdateStandardVar(pPDev, pFM, 0, 0, STD_STD | STD_CFID ) &&
  1365. BFontCmdCallback(pPDev, pFM, NULL, 0) )
  1366. bRet = TRUE;
  1367. }
  1368. //
  1369. // Restore the current dwFlags in UFOBJ
  1370. //
  1371. ((PI_UNIFONTOBJ)pFontPDev->pUFObj)->dwFlags = dwFlags;
  1372. return bRet;
  1373. }
  1374. BOOL
  1375. BOEMFreePFMCallback(
  1376. PFONTMAP pfm)
  1377. /*++
  1378. Routine Description:
  1379. Implementation of PFM Free function for FONTMAP dispatch routine
  1380. Arguments:
  1381. pFM - a pointer to FONTMAP
  1382. Return Value:
  1383. Note:
  1384. --*/
  1385. {
  1386. ASSERT(pfm);
  1387. if (pfm)
  1388. {
  1389. if (pfm->pIFIMet)
  1390. MemFree(pfm->pIFIMet);
  1391. MemFree(pfm);
  1392. return TRUE;
  1393. }
  1394. else
  1395. return FALSE;
  1396. }
  1397. PFONTMAP
  1398. PfmInitPFMOEMCallback(
  1399. PDEV *pPDev,
  1400. FONTOBJ *pfo)
  1401. /*++
  1402. Routine Description:
  1403. Implementation of PfmInit for FONTMAP dispatch routine
  1404. Arguments:
  1405. pPDev - a pointer to PDEV
  1406. pfo - a pointer to FONTOBJ
  1407. Return Value:
  1408. A pointer to FONTMAP
  1409. Note:
  1410. --*/
  1411. {
  1412. PFONTPDEV pFontPDev;
  1413. PFONTMAP pfm;
  1414. DWORD dwSize;
  1415. ASSERT(pPDev && pfo);
  1416. pFontPDev = pPDev->pFontPDev;
  1417. dwSize = sizeof(FONTMAP) + sizeof(FONTMAP_TTOEM);
  1418. if (pfm = MemAlloc(dwSize))
  1419. {
  1420. PFONTMAP_TTOEM pFMOEM;
  1421. ZeroMemory(pfm, dwSize);
  1422. pfm->dwSignature = FONTMAP_ID;
  1423. pfm->dwSize = sizeof(FONTMAP);
  1424. pfm->dwFontType = FMTYPE_TTOEM;
  1425. pfm->pSubFM = (PVOID)(pfm+1);
  1426. pfm->wFirstChar = 0;
  1427. pfm->wLastChar = 0xffff;
  1428. pfm->wXRes = (WORD)pPDev->ptGrxRes.x;
  1429. pfm->wYRes = (WORD)pPDev->ptGrxRes.y;
  1430. pfm->pIFIMet = pFontPDev->pIFI;
  1431. pfm->ulDLIndex = (ULONG)-1;
  1432. if (!(pFontPDev->flFlags & FDV_ALIGN_BASELINE) )
  1433. {
  1434. pfm->syAdj = ((IFIMETRICS*)pfm->pIFIMet)->fwdWinAscender;
  1435. }
  1436. if (pPDev->pOemHookInfo &&
  1437. pPDev->pOemHookInfo[EP_OEMOutputCharStr].pfnHook ||
  1438. (pPDev->ePersonality == kPCLXL)
  1439. )
  1440. pfm->pfnGlyphOut = DwOutputGlyphCallback;
  1441. else
  1442. pfm->pfnGlyphOut = DwTrueTypeBMPGlyphOut;
  1443. if (pPDev->ePersonality == kPCLXL)
  1444. {
  1445. pfm->pfnSelectFont = BSelectTrueTypeOutline;
  1446. pfm->pfnDeSelectFont = BDeselectTrueTypeOutline;
  1447. }
  1448. else
  1449. if (pFontPDev->pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
  1450. {
  1451. pfm->pfnSelectFont = BSelectTrueTypeOutline;
  1452. pfm->pfnDeSelectFont = BDeselectTrueTypeOutline;
  1453. }
  1454. else
  1455. if (pFontPDev->pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_BITMAP)
  1456. {
  1457. pfm->pfnSelectFont = BSelectTrueTypeBMP;
  1458. pfm->pfnDeSelectFont = BDeselectTrueTypeBMP;
  1459. }
  1460. pfm->pfnDownloadFontHeader = DwDLHeaderOEMCallback;
  1461. pfm->pfnDownloadGlyph = DwDLGlyphOEMCallback;
  1462. pfm->pfnCheckCondition = BCheckCondOEMCallback;
  1463. pfm->pfnFreePFM = BOEMFreePFMCallback;
  1464. pFMOEM = (PFONTMAP_TTOEM) pfm->pSubFM;
  1465. pFMOEM->dwFlags = ((PI_UNIFONTOBJ)pFontPDev->pUFObj)->dwFlags;
  1466. pFMOEM->flFontType = pfo->flFontType;
  1467. if (pFontPDev->pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
  1468. {
  1469. if (pfo->flFontType & FO_SIM_BOLD)
  1470. pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_BOLD_SIM;
  1471. if (pfo->flFontType & FO_SIM_ITALIC)
  1472. pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_ITALIC_SIM;
  1473. if (NULL != pFontPDev->pIFI &&
  1474. '@' == *((PBYTE)pFontPDev->pIFI + pFontPDev->pIFI->dpwszFamilyName))
  1475. {
  1476. pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_VERTICAL;
  1477. }
  1478. }
  1479. }
  1480. else
  1481. {
  1482. ERR(("PfmInitPFMOEMCallback: MemAlloc failed.\n"));
  1483. }
  1484. return pfm;
  1485. }
  1486. //
  1487. // Misc functions
  1488. //
  1489. VOID
  1490. VUFObjFree(
  1491. IN FONTPDEV* pFontPDev)
  1492. /*++
  1493. Routine Description:
  1494. UFObj(UNIFONTOBJ) memory free function
  1495. Arguments:
  1496. pFontPDev - a pointer to FONTPDEV.
  1497. Return Value:
  1498. Note:
  1499. --*/
  1500. {
  1501. PI_UNIFONTOBJ pUFObj = pFontPDev->pUFObj;
  1502. ASSERT(pFontPDev);
  1503. pUFObj = pFontPDev->pUFObj;
  1504. if (pUFObj && pUFObj->pGlyph)
  1505. MemFree(pUFObj->pGlyph);
  1506. pFontPDev->pUFObj = NULL;
  1507. }
  1508. WCHAR
  1509. WGHtoUnicode(
  1510. DWORD dwNumOfRuns,
  1511. PGLYPHRUN pGlyphRun,
  1512. HGLYPH hg)
  1513. /*++
  1514. Routine Description:
  1515. Character coversion function from HGLYPH to Unicode.
  1516. Arguments:
  1517. dwNumOfRuns - number of run in pGlyphRun
  1518. pGlyphRun - a pointer to glyph run
  1519. hd - HGLYPH
  1520. Return Value:
  1521. Unicode character
  1522. Note:
  1523. --*/
  1524. {
  1525. DWORD dwI;
  1526. HGLYPH hCurrent = 1;
  1527. WCHAR wchChar = 0;
  1528. ASSERT(pGlyphRun);
  1529. for( dwI = 0; dwI < dwNumOfRuns; dwI ++, pGlyphRun ++)
  1530. {
  1531. if (hCurrent <= hg && hg < hCurrent + pGlyphRun->wGlyphCount)
  1532. {
  1533. wchChar = (WCHAR)(pGlyphRun->wcLow + hg - hCurrent);
  1534. break;
  1535. }
  1536. hCurrent += pGlyphRun->wGlyphCount;
  1537. }
  1538. return wchChar;
  1539. }