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.

1744 lines
51 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. download.c
  5. Abstract:
  6. Functions associated with downloading fonts to printers. This
  7. specifically applies to LaserJet style printers. There are really
  8. two sets of functions here: those for downloading fonts supplied
  9. by the user (and installed with the font installer), and those
  10. we generate internally to cache TT style fonts in the printer.
  11. Environment:
  12. Windows NT Unidrv driver
  13. Revision History:
  14. 01/11/97 -ganeshp-
  15. Created
  16. --*/
  17. #include "font.h"
  18. #define DL_BUF_SZ 4096 /* Size of data chunks for download */
  19. //
  20. // Local function prototypes.
  21. //
  22. IFIMETRICS*
  23. pGetIFI(
  24. PDEV *pPDev,
  25. FONTOBJ *pfo,
  26. BOOL bScale
  27. );
  28. BOOL
  29. BDownLoadAsTT(
  30. PDEV *pPDev,
  31. FONTOBJ *pfo,
  32. STROBJ *pstro,
  33. DL_MAP *pdm,
  34. INT iMode
  35. );
  36. BOOL
  37. BDownLoadAsBmp(
  38. PDEV *pPDev,
  39. FONTOBJ *pfo,
  40. STROBJ *pstro,
  41. DL_MAP *pdm,
  42. INT iMode
  43. );
  44. BOOL
  45. BDownLoadOEM(
  46. PDEV *pPDev,
  47. FONTOBJ *pfo,
  48. STROBJ *pstro,
  49. DL_MAP *pdm,
  50. INT iMode
  51. );
  52. //
  53. // Macro Definition.
  54. //
  55. #ifdef WINNT_40
  56. #else
  57. #endif //WINNT_40
  58. #define GETWIDTH(pPtqD) ((pPtqD->x.HighPart + 8) / 16)
  59. //
  60. // Main functions
  61. //
  62. BOOL
  63. BDLSecondarySoftFont(
  64. PDEV *pPDev,
  65. FONTOBJ *pfo,
  66. STROBJ *pstro,
  67. DL_MAP *pdm
  68. )
  69. /*++
  70. Routine Description:
  71. This routine download the secondary soft font. If the True type font has
  72. more Glyphs that what we can download in soft font then we download a
  73. secondary font after we use all the glyphs in the current soft font. This
  74. function also sets the new soft font index(pFM->ulDLIndex) to be used.
  75. Arguments:
  76. pPDev Pointer to PDEV
  77. pfo The font of interest.
  78. pdm Individual download font map element
  79. Return Value:
  80. TRUE for success and FALSE for failure
  81. Note:
  82. 6/11/1997 -ganeshp-
  83. Created it.
  84. --*/
  85. {
  86. BOOL bRet;
  87. FONTMAP *pFM;
  88. //
  89. // Initialization of Locals .
  90. //
  91. bRet = FALSE;
  92. pFM = pdm->pfm;
  93. //
  94. // PFM->ulDLIndex is used to download new soft font and is set in following
  95. // download functions.
  96. //
  97. if (pFM->dwFontType == FMTYPE_TTBITMAP)
  98. {
  99. if (!BDownLoadAsBmp(pPDev, pfo, pstro,pdm,DL_SECONDARY_SOFT_FONT) )
  100. {
  101. ERR(("UniFont!BDLSecondarySoftFont:BDownLoadAsBmp Failed\n"));
  102. goto ErrorExit;
  103. }
  104. }
  105. else if (pFM->dwFontType == FMTYPE_TTOUTLINE)
  106. {
  107. if (!BDownLoadAsTT(pPDev, pfo, pstro,pdm,DL_SECONDARY_SOFT_FONT) )
  108. {
  109. ERR(("UniFont!BDLSecondarySoftFont:BDownLoadAsTT Failed\n"));
  110. goto ErrorExit;
  111. }
  112. }
  113. else if (pFM->dwFontType == FMTYPE_TTOEM)
  114. {
  115. if (!BDownLoadOEM(pPDev, pfo, pstro,pdm,DL_SECONDARY_SOFT_FONT) )
  116. {
  117. ERR(("UniFont!BDLSecondarySoftFont:BDownLoadAsOEM Failed\n"));
  118. goto ErrorExit;
  119. }
  120. }
  121. //
  122. // Reset the iSoftfont to -1, so that we send select font command, before
  123. // outputting the Character.
  124. //
  125. PFDV->ctl.iSoftFont = -1;
  126. bRet = TRUE;
  127. ErrorExit:
  128. return bRet;
  129. }
  130. BOOL
  131. BDownloadGlyphs(
  132. TO_DATA *ptod,
  133. STROBJ *pstro,
  134. DL_MAP *pdm
  135. )
  136. /*++
  137. Routine Description:
  138. Arguments:
  139. pPDev Pointer to PDEV
  140. pdm DL_MAP struct, all about downloading is in this structure.
  141. Return Value:
  142. TRUE for success and FALSE for failure
  143. Note:
  144. 6/9/1997 -ganeshp-
  145. Created it.
  146. --*/
  147. {
  148. PDEV *pPDev; // Our PDevice
  149. FONTOBJ *pfo; // Font OBJ
  150. GLYPHPOS *pgp; // Value passed from gre
  151. FONTMAP *pFM; // Font's details
  152. ULONG cGlyphs; // Number of glyphs to process
  153. ULONG cGlyphIndex; // Index to the current glyph.
  154. WORD wWidth; // Width of the Glyph.
  155. BOOL bMore; // Getting glyphs from engine loop
  156. PDLGLYPH *ppdlGlyph; // array of DLGLYPHs pointers.
  157. DWORD dwMem; // Memory require to download the glyph.
  158. DWORD dwTotalEnumGlyphs;
  159. POINTQF *pPtqD; // Advance Width Array.
  160. BOOL bRet; // Return Value
  161. PWCHAR pwchUnicode;
  162. //
  163. // Initialize Local variables.
  164. //
  165. pPDev = ptod->pPDev;
  166. pfo = ptod->pfo;
  167. pFM = ptod->pfm;
  168. dwTotalEnumGlyphs =
  169. cGlyphs =
  170. cGlyphIndex =
  171. dwMem = 0;
  172. pPtqD = NULL;
  173. ASSERTMSG((pPDev && pfo && pstro && pFM),\
  174. ("\nUniFont!BDownloadGlyphs: Wrong values in ptod.\n"));
  175. bRet = FALSE;
  176. //
  177. // Allocate the array for DLGLYPHs.
  178. //
  179. if (!( ppdlGlyph = MemAllocZ( pstro->cGlyphs * sizeof(DLGLYPH *)) ))
  180. {
  181. ERR(("UniFont:BDownloadGlyphs: MemAlloc for ppdlGlyph failed\n"));
  182. goto ErrorExit;
  183. }
  184. ptod->apdlGlyph = ppdlGlyph;
  185. //
  186. // First Job is to do the enumeration of the glyphs. and then
  187. // start downloading.
  188. //
  189. #ifndef WINNT_40 // NT 5.0
  190. if (pPtqD = MemAllocZ( pstro->cGlyphs * sizeof(POINTQF)) )
  191. {
  192. //
  193. // Memory Allocation succeded for width array. So call GDI to get
  194. // the width.
  195. //
  196. if (!STROBJ_bGetAdvanceWidths(pstro, 0, pstro->cGlyphs, pPtqD))
  197. {
  198. ERR(("UniFont:BDownloadGlyphs: STROBJ_bGetAdvanceWidths failed\n"));
  199. goto ErrorExit;
  200. }
  201. }
  202. else
  203. {
  204. ERR(("UniFont:BDownloadGlyphs:Memory allocation for width array failed\n"));
  205. goto ErrorExit;
  206. }
  207. #endif //!WINNT_40
  208. pwchUnicode = pstro->pwszOrg;
  209. STROBJ_vEnumStart(pstro);
  210. do
  211. {
  212. #ifndef WINNT_40 // NT 5.0
  213. bMore = STROBJ_bEnumPositionsOnly( pstro, &cGlyphs, &pgp );
  214. #else // NT 4.0
  215. bMore = STROBJ_bEnum( pstro, &cGlyphs, &pgp );
  216. #endif //!WINNT_40
  217. dwTotalEnumGlyphs += cGlyphs;
  218. while ( cGlyphs )
  219. {
  220. PDLGLYPH pdlg;
  221. HGLYPH hTTGlyph;
  222. #ifdef WINNT_40 // NT 4.0
  223. GLYPHDATA *pgd;
  224. if( !FONTOBJ_cGetGlyphs( ptod->pfo, FO_GLYPHBITS, (ULONG)1,
  225. &pgp->hg, &pgd ) )
  226. {
  227. ERR(( "UniFont:BDownloadGlyphs:FONTOBJ_cGetGlyphs fails\n" ))
  228. goto ErrorExit;
  229. }
  230. pPtqD = &(pgd->ptqD);
  231. #endif //WINNT_40
  232. hTTGlyph = pgp->hg;
  233. //
  234. // search the Glyph in hash table.
  235. //
  236. pdlg = *ppdlGlyph = PDLGHashGlyph (pdm,hTTGlyph );
  237. if (pdlg)
  238. {
  239. //
  240. // We have got a valid Glyph. Check if this is already
  241. // downloaded or not.
  242. //
  243. if (!GLYPHDOWNLOADED(pdlg))
  244. {
  245. //
  246. // If the glyph is not downloaded,then fill Glyph structure
  247. // and download the Glyph.
  248. //
  249. if (pdm->wFlags & DLM_UNBOUNDED)
  250. {
  251. //
  252. // Unbounded font. We just have to make sure that
  253. // download glyphID is valid. If it's not valid then
  254. // we fail the call.
  255. //
  256. if (pdm->wNextDLGId > pdm->wLastDLGId)
  257. {
  258. ERR(("UniFont:BDownloadGlyphs:Unbounded Font,no more Glyph Ids\n"));
  259. goto ErrorExit;
  260. }
  261. //
  262. // Fill in the Glyph structure. We only set wDLGlyphID.
  263. // The new Glyph definition has FontId also. So set that
  264. // one also.
  265. //
  266. pdlg->wDLGlyphID = pdm->wNextDLGId;
  267. pdlg->wDLFontId = pdm->wBaseDLFontid;
  268. }
  269. else
  270. {
  271. //
  272. // Bounded font. It's a bit tricky. We have to do the
  273. // same test for avaiable Glyph IDs. If there is no more
  274. // glyph Ids, then we have to download a secondary
  275. // soft font and reset the cGlyphs and wNextDlGId.
  276. //
  277. if (pdm->wNextDLGId > pdm->wLastDLGId)
  278. {
  279. if ( BDLSecondarySoftFont(pPDev, pfo, pstro,pdm) )
  280. {
  281. //
  282. // Reset the Glyph Ids values.
  283. //
  284. pdm->wNextDLGId = pdm->wFirstDLGId;
  285. pdm->wCurrFontId = (WORD)pdm->pfm->ulDLIndex;
  286. }
  287. else
  288. {
  289. //
  290. // Failure case. Fail the Call.
  291. //
  292. ERR(("UniFont:BDownloadGlyphs:Bounded Font,Sec. Font DL failed\n"));
  293. goto ErrorExit;
  294. }
  295. }
  296. //
  297. // Set the Glyph ID and Font ID in the DLGLYPH.
  298. //
  299. pdlg->wDLFontId = pdm->wCurrFontId;
  300. pdlg->wDLGlyphID = pdm->wNextDLGId;
  301. }
  302. //
  303. // All error checkings are done, so download now. Set the
  304. // width to zero and then pass the address to downloading
  305. // function. The downloading function should fill a width
  306. // value else it remains zero.
  307. //
  308. if (pFM->ulDLIndex == -1)
  309. {
  310. ASSERTMSG(FALSE, ("pFM->ulDLIndex == -1") );
  311. goto ErrorExit;
  312. }
  313. pdlg->wWidth = 0;
  314. pdlg->wchUnicode = *(pwchUnicode + cGlyphIndex);
  315. wWidth = 0;
  316. dwMem = pFM->pfnDownloadGlyph(pPDev, pFM, hTTGlyph,
  317. pdlg->wDLGlyphID, &wWidth);
  318. if (dwMem)
  319. {
  320. //
  321. // All success in downloading the glyph.Mark it
  322. // downloaded. This is done by setting the hTTGlyph to
  323. // True Type Glyph Handle.
  324. //
  325. pdlg->hTTGlyph = hTTGlyph;
  326. //
  327. // If the download function returns the width use it,
  328. // else use the width from GDI.
  329. //
  330. if (wWidth)
  331. pdlg->wWidth = wWidth;
  332. else
  333. {
  334. #ifndef WINNT_40 //NT 5.0
  335. pdlg->wWidth = (WORD)GETWIDTH((pPtqD + cGlyphIndex));
  336. #else // NT 4.0
  337. pdlg->wWidth = GETWIDTH(pPtqD);
  338. #endif //!WINNT_40
  339. }
  340. pdm->cGlyphs++;
  341. pdm->wNextDLGId++;
  342. //
  343. // Update memory consumption before return.
  344. //
  345. PFDV->dwFontMemUsed += dwMem;
  346. }
  347. else
  348. {
  349. //
  350. // Failure case. Fail the Call.
  351. //
  352. ERR(("UniFont:BDownloadGlyphs:Glyph Download failed\n"));
  353. goto ErrorExit;
  354. }
  355. }
  356. else // Glyph is already downloaded.
  357. {
  358. //
  359. // If Glyph is already downloaded and we are downloading as
  360. // TT outline we need to update the width to current point
  361. // size.
  362. //
  363. if( (pFM->dwFontType == FMTYPE_TTOUTLINE) ||
  364. ( (pFM->dwFontType == FMTYPE_TTOEM) &&
  365. (((PFONTMAP_TTOEM)(pFM->pSubFM))->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
  366. )
  367. )
  368. {
  369. #ifndef WINNT_40 //NT 5.0
  370. pdlg->wWidth = (WORD)GETWIDTH((pPtqD + cGlyphIndex));
  371. #else // NT 4.0
  372. pdlg->wWidth = GETWIDTH(pPtqD);
  373. #endif //!WINNT_40
  374. }
  375. }
  376. pgp++;
  377. ppdlGlyph++;
  378. cGlyphIndex++;
  379. cGlyphs --;
  380. }
  381. else
  382. {
  383. ERR(("UniFont:BDownloadGlyphs: PDLGHashGlyph failed\n"));
  384. goto ErrorExit;
  385. }
  386. }
  387. } while( bMore );
  388. if (dwTotalEnumGlyphs != pstro->cGlyphs)
  389. {
  390. ERR(("UniFont:BDownloadGlyphs: STROBJ_bEnum failed to enumurate all glyphs\n"));
  391. goto ErrorExit;
  392. }
  393. bRet = TRUE;
  394. //
  395. // ReSet the pFM->ulDLIndex to first Glyph's softfont ID.
  396. //
  397. pFM->ulDLIndex = (pdm->wFlags & DLM_UNBOUNDED)?
  398. (pdm->wBaseDLFontid):
  399. (ptod->apdlGlyph[0]->wDLFontId);
  400. ErrorExit:
  401. //
  402. // If there is a failure then free the DLGLYPH array.
  403. //
  404. if (!bRet && ptod->apdlGlyph)
  405. {
  406. MEMFREEANDRESET(ptod->apdlGlyph );
  407. }
  408. #ifndef WINNT_40 // NT 5.0
  409. MEMFREEANDRESET(pPtqD );
  410. #endif //!WINNT_40
  411. return bRet;
  412. }
  413. BOOL
  414. BDownLoadOEM(
  415. PDEV *pPDev,
  416. FONTOBJ *pfo,
  417. STROBJ *pstro,
  418. DL_MAP *pdm,
  419. INT iMode
  420. )
  421. /*++
  422. Routine Description:
  423. Arguments:
  424. pPDev Pointer to PDEV
  425. pfo The font of interest.
  426. pstro The "width" of fixed pitch font glyphs.
  427. pdm Individual download font map element
  428. Return Value:
  429. TRUE for success and FALSE for failure
  430. Note:
  431. 6/11/1997 -ganeshp-
  432. Created it.
  433. --*/
  434. {
  435. PI_UNIFONTOBJ pUFObj;
  436. PFONTMAP_TTOEM pfmTTOEM; // Bitmap download fontmap.
  437. IFIMETRICS *pIFI;
  438. PFONTPDEV pFontPDev;
  439. PFONTMAP pfm;
  440. DWORD dwMem;
  441. //
  442. // Initialize local variables.
  443. //
  444. pFontPDev = pPDev->pFontPDev;
  445. pUFObj = pFontPDev->pUFObj;
  446. dwMem = 0;
  447. //
  448. // Get FONTMAP
  449. //
  450. if (iMode == DL_BASE_SOFT_FONT)
  451. {
  452. pdm->pfm =
  453. pfm = PfmInitPFMOEMCallback(pPDev, pfo);
  454. }
  455. else
  456. {
  457. pfm = pdm->pfm;
  458. ASSERTMSG((pfm),("NULL pFM for Secondary Font"));
  459. }
  460. if (!pUFObj || !pfm)
  461. {
  462. return FALSE;
  463. }
  464. if (pfm)
  465. {
  466. if (iMode == DL_BASE_SOFT_FONT)
  467. {
  468. pfm->pIFIMet =
  469. pIFI = pGetIFI(pPDev, pfo, TRUE);
  470. }
  471. else
  472. {
  473. pIFI = pfm->pIFIMet;
  474. }
  475. if (pUFObj->dwFlags & (UFOFLAG_TTDOWNLOAD_BITMAP|
  476. UFOFLAG_TTDOWNLOAD_TTOUTLINE) &&
  477. pIFI)
  478. {
  479. if (iMode == DL_BASE_SOFT_FONT)
  480. {
  481. pdm->cGlyphs = -1;
  482. if (pIFI->flInfo & FM_INFO_CONSTANT_WIDTH)
  483. {
  484. if (pstro->ulCharInc == 0)
  485. {
  486. return FALSE;
  487. }
  488. pIFI->fwdMaxCharInc =
  489. pIFI->fwdAveCharWidth = (FWORD)pstro->ulCharInc;
  490. }
  491. pfm->wFirstChar = 0;
  492. pfm->wLastChar = 0xffff;
  493. pfm->wXRes = (WORD)pPDev->ptGrxRes.x;
  494. pfm->wYRes = (WORD)pPDev->ptGrxRes.y;
  495. if (!(pFontPDev->flFlags & FDV_ALIGN_BASELINE))
  496. pfm->syAdj = pIFI->fwdWinAscender;
  497. pfm->flFlags = FM_SENT | FM_SOFTFONT | FM_GEN_SFONT;
  498. if (pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
  499. pfm->flFlags |= FM_SCALABLE;
  500. pfm->ulDLIndex = pdm->wCurrFontId = pdm->wBaseDLFontid;
  501. pfmTTOEM = pfm->pSubFM;
  502. pfmTTOEM->u.pvDLData = pdm;
  503. }
  504. else
  505. {
  506. //
  507. // Things are different for Secondary Download.Get a new ID.
  508. //
  509. if( (pfm->ulDLIndex = IGetDL_ID( pPDev )) == -1 )
  510. {
  511. ERR(( "UniFont!BDownLoadAsBmp:Out of Soft Font Limit,- FONT NOT DOWNLOADED\n"));
  512. return FALSE;
  513. }
  514. }
  515. //
  516. // Send the SETFONTID command. This commands assigns the id to the
  517. // font being downloaded.
  518. //
  519. if( (dwMem = pfm->pfnDownloadFontHeader( pPDev, pfm)) == 0 )
  520. {
  521. //
  522. // Failed to download font header.
  523. //
  524. ERR(("UniFont!BDownloadAsOEM:pfnDownloadFontHeader failed.\n"));
  525. return FALSE;
  526. }
  527. else
  528. {
  529. //
  530. // Adjust the Memory
  531. //
  532. pFontPDev->dwFontMemUsed += dwMem;
  533. if (iMode == DL_BASE_SOFT_FONT)
  534. {
  535. pfm->dwFontType = FMTYPE_TTOEM;
  536. pdm->cGlyphs = 0;
  537. pfmTTOEM->dwDLSize = dwMem;
  538. }
  539. }
  540. }
  541. }
  542. return TRUE;
  543. }
  544. BOOL
  545. BDownLoadAsTT(
  546. PDEV *pPDev,
  547. FONTOBJ *pfo,
  548. STROBJ *pstro,
  549. DL_MAP *pdm,
  550. INT iMode
  551. )
  552. /*++
  553. Routine Description:
  554. Arguments:
  555. pPDev Pointer to PDEV
  556. pfo The font of interest.
  557. pstro The "width" of fixed pitch font glyphs.
  558. pdm Individual download font map element
  559. iMode Mode of downloading, primary or secondary.
  560. Return Value:
  561. TRUE for success and FALSE for failure
  562. Note:
  563. 6/11/1997 -ganeshp-
  564. Created it.
  565. --*/
  566. {
  567. FONTMAP *pFM; // The FONTMAP structure we build up
  568. BOOL bRet; // The value we return
  569. PFONTPDEV pFontPDev; // Font Modules's PDEV
  570. IFIMETRICS *pIFI; // IFI metrics for this font.
  571. PFONTMAP_TTO pfmTTO; // Bitmap download fontmap.
  572. DWORD dwMem; // For recording memory consumption
  573. //
  574. // Initialize the Local Variables.
  575. //
  576. pFontPDev = pPDev->pFontPDev;
  577. bRet = FALSE;
  578. dwMem = 0;
  579. //
  580. // First Initialize the FontMap.
  581. //
  582. if (iMode == DL_BASE_SOFT_FONT)
  583. {
  584. pFM = InitPFMTTOutline(pPDev,pfo);
  585. pdm->pfm = pFM;
  586. }
  587. else
  588. {
  589. pFM = pdm->pfm;
  590. ASSERTMSG((pFM),("\nUniFont!BDownLoadAsTT:NULL pFM for Secondary Font"));
  591. }
  592. if ( pFM )
  593. {
  594. //
  595. // Check if we can download the font or not, using the present available
  596. // memory.
  597. //
  598. if (iMode == DL_BASE_SOFT_FONT)
  599. {
  600. pFM->pIFIMet =
  601. pIFI = pGetIFI( pPDev, pfo, FALSE );
  602. }
  603. else
  604. {
  605. pIFI = pFM->pIFIMet;
  606. }
  607. if ( pIFI && pFM->pfnCheckCondition(pPDev,pfo,pstro,pIFI) )
  608. {
  609. //
  610. // There is enough memory to download. So prepare to download.
  611. // The first step is to get the IFIMETRICS and validate it.
  612. //
  613. if (iMode == DL_BASE_SOFT_FONT)
  614. {
  615. //
  616. // Initialize to not download.After successful download we
  617. // set cGlyphs to 0.
  618. //
  619. pdm->cGlyphs = -1;
  620. if( pIFI->flInfo & FM_INFO_CONSTANT_WIDTH )
  621. {
  622. //
  623. // Fixed pitch fonts are not handled.Fixed
  624. // pitch fonts should be downloaded as bitmap only.
  625. // So return Error.
  626. //
  627. WARNING(( "UniFont!BDownLoadAsTT:Fixded Pitch Font are not downloaded as Outlie.\n"));
  628. goto ErrorExit;
  629. }
  630. pFM->wFirstChar = 0;
  631. pFM->wLastChar = 0xffff;
  632. pFM->wXRes = (WORD)pPDev->ptGrxRes.x;
  633. pFM->wYRes = (WORD)pPDev->ptGrxRes.y;
  634. if( !(pFontPDev->flFlags & FDV_ALIGN_BASELINE) )
  635. pFM->syAdj = pIFI->fwdWinAscender;
  636. pFM->flFlags = FM_SENT | FM_SOFTFONT |
  637. FM_GEN_SFONT | FM_SCALABLE;
  638. //
  639. // wBaseDLFontid is already initialized by BInitDLMap function.
  640. //
  641. pFM->ulDLIndex = pdm->wCurrFontId = pdm->wBaseDLFontid;
  642. //
  643. // Initialize the TT Outline specific fields.
  644. //
  645. pfmTTO = pFM->pSubFM;
  646. pfmTTO->pvDLData = pdm;
  647. }
  648. else
  649. {
  650. //
  651. // Things are different for Secondary Download. We have to get
  652. // a new fontID.
  653. //
  654. if( (pFM->ulDLIndex = IGetDL_ID( pPDev )) == -1 )
  655. {
  656. ERR(( "UniFont!BDownLoadAsTT:Out of Soft Font Limit,- FONT NOT DOWNLOADED\n"));
  657. goto ErrorExit;
  658. }
  659. }
  660. //
  661. // Send the SETFONTID command. This commands assigns the id to the
  662. // font being downloaded. And set the flag that this command is
  663. // already sent. We need to send this command while downloading
  664. // glyphs also. The download glyph code will check this flag, and
  665. // send the command only if not sent ( which will happen next time,
  666. // when same font is used).
  667. //
  668. BUpdateStandardVar(pPDev, pFM, 0, 0, STD_NFID);
  669. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID));
  670. pFontPDev->flFlags |= FDV_SET_FONTID;
  671. if( (dwMem = pFM->pfnDownloadFontHeader( pPDev, pFM)) == 0 )
  672. {
  673. //
  674. // Some sort of hiccup while downloading the header.So fail.
  675. //
  676. ERR(("UniFont!BDownLoadAsBmp:Err while downloading header,- FONT NOT DOWNLOADED\n"));
  677. goto ErrorExit;
  678. }
  679. //
  680. // Update memory consumption before return.
  681. //
  682. pFontPDev->dwFontMemUsed += dwMem;
  683. if (iMode == DL_BASE_SOFT_FONT)
  684. {
  685. //
  686. // Successful download.So mark it current.
  687. //
  688. pFM->dwFontType = FMTYPE_TTOUTLINE;
  689. //
  690. // Set cGlyphs to 0 to mark that font is Downloaded OK.
  691. //
  692. pdm->cGlyphs = 0;
  693. }
  694. }
  695. else
  696. {
  697. ERR(( "UniFont!BDownLoadAsTT:NULL IFI or pfnCheckCondition failed.\n") );
  698. goto ErrorExit;
  699. }
  700. }
  701. else
  702. {
  703. //
  704. // The PFM could not be found or created for this truetype font.
  705. // Return FALSE to allow some other rendering method to occur.
  706. //
  707. WARNING(( "UniFont!BDownLoadAsTT:Fontmap couldn't be created or found.\n") );
  708. goto ErrorExit;
  709. }
  710. //
  711. // All success, so return TRUE;
  712. //
  713. bRet = TRUE;
  714. ErrorExit:
  715. return bRet;
  716. }
  717. BOOL
  718. BDownLoadAsBmp(
  719. PDEV *pPDev,
  720. FONTOBJ *pfo,
  721. STROBJ *pstro,
  722. DL_MAP *pdm,
  723. INT iMode
  724. )
  725. /*++
  726. Routine Description:
  727. Arguments:
  728. pPDev Pointer to PDEV
  729. pfo The font of interest.
  730. pstro The "width" of fixed pitch font glyphs.
  731. pdm Individual download font map element
  732. iMode Mode of downloading, primary or secondary.
  733. Return Value:
  734. TRUE for success and FALSE for failure
  735. Note:
  736. 6/11/1997 -ganeshp-
  737. Created it.
  738. --*/
  739. {
  740. FONTMAP *pFM; // The FONTMAP structure we build up
  741. BOOL bRet; // The value we return
  742. PFONTPDEV pFontPDev; // Font Modules's PDEV
  743. IFIMETRICS *pIFI; // IFI metrics for this font.
  744. PFONTMAP_TTB pfmTTB; // Bitmap download fontmap.
  745. DWORD dwMem; // For recording memory consumption
  746. //
  747. // Initialize the Local Variables.
  748. //
  749. pFontPDev = pPDev->pFontPDev;
  750. bRet = FALSE;
  751. dwMem = 0;
  752. //
  753. // First Initialize the FontMap.
  754. //
  755. if (iMode == DL_BASE_SOFT_FONT)
  756. {
  757. pFM = InitPFMTTBitmap(pPDev,pfo);
  758. pdm->pfm = pFM;
  759. }
  760. else
  761. {
  762. pFM = pdm->pfm;
  763. ASSERTMSG((pFM),("\nUniFont!BDownLoadAsBmp:NULL pFM for Secondary Font"));
  764. }
  765. if ( pFM )
  766. {
  767. //
  768. // Check if we can download the font or not, using the present available
  769. // memory.
  770. //
  771. if (iMode == DL_BASE_SOFT_FONT)
  772. {
  773. pFM->pIFIMet =
  774. pIFI = pGetIFI( pPDev, pfo, TRUE );
  775. }
  776. else
  777. {
  778. pIFI = pFM->pIFIMet;
  779. }
  780. if ( pIFI && pFM->pfnCheckCondition(pPDev,pfo,pstro,pIFI) )
  781. {
  782. //
  783. // There is enough memory to download. So prepare to download.
  784. // The first step is to get the IFIMETRICS and validate it.
  785. //
  786. if (iMode == DL_BASE_SOFT_FONT)
  787. {
  788. //
  789. // Initialize to not download.After successful download we
  790. // set cGlyphs to 0.
  791. //
  792. pdm->cGlyphs = -1;
  793. if( pIFI->flInfo & FM_INFO_CONSTANT_WIDTH )
  794. {
  795. //
  796. // Fixed pitch fonts are handled a little differently.Fixed
  797. // pitch fonts should be downloaded as bitmap only.
  798. //
  799. if( pstro->ulCharInc == 0 )
  800. {
  801. ERR(( "UniFont!BDownLoadAsBmp:Fixed pitch font,ulCharInc == 0 - FONT NOT DOWNLOADED\n"));
  802. goto ErrorExit;
  803. }
  804. pIFI->fwdMaxCharInc = (FWORD)pstro->ulCharInc;
  805. pIFI->fwdAveCharWidth = (FWORD)pstro->ulCharInc;
  806. }
  807. pFM->wFirstChar = 0;
  808. pFM->wLastChar = 0xffff;
  809. pFM->wXRes = (WORD)pPDev->ptGrxRes.x;
  810. pFM->wYRes = (WORD)pPDev->ptGrxRes.y;
  811. if( !(pFontPDev->flFlags & FDV_ALIGN_BASELINE) )
  812. pFM->syAdj = pIFI->fwdWinAscender;
  813. pFM->flFlags = FM_SENT | FM_SOFTFONT | FM_GEN_SFONT;
  814. //
  815. // wBaseDLFontid is already initialized by BInitDLMap function.
  816. //
  817. pFM->ulDLIndex = pdm->wCurrFontId = pdm->wBaseDLFontid;
  818. //
  819. // Initialize the TT Bitmap specific fields.
  820. //
  821. pfmTTB = pFM->pSubFM;
  822. pfmTTB->u.pvDLData = pdm;
  823. }
  824. else
  825. {
  826. INT iID = IGetDL_ID( pPDev );
  827. //
  828. // Things are different for Secondary Download.Get a new ID.
  829. //
  830. if( iID < 0 )
  831. {
  832. ERR(( "UniFont!BDownLoadAsBmp:Out of Soft Font Limit,- FONT NOT DOWNLOADED\n"));
  833. goto ErrorExit;
  834. }
  835. pFM->ulDLIndex = iID;
  836. }
  837. //
  838. // Send the SETFONTID command. This commands assigns the id to the
  839. // font being downloaded. And set the flag that this command is
  840. // already sent. We need to send this command while downloading
  841. // glyphs also. The download glyph code will check this flag, and
  842. // send the command only if not sent ( which will happen next time,
  843. // when same font is used).
  844. //
  845. BUpdateStandardVar(pPDev, pFM, 0, 0, STD_NFID);
  846. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID));
  847. pFontPDev->flFlags |= FDV_SET_FONTID;
  848. if( (dwMem = pFM->pfnDownloadFontHeader( pPDev, pFM)) == 0 )
  849. {
  850. //
  851. // Some sort of hiccup while downloading the header.So fail.
  852. //
  853. ERR(( "UniFont!BDownLoadAsBmp:Err while downloading header,- FONT NOT DOWNLOADED\n") );
  854. goto ErrorExit;
  855. }
  856. //
  857. // Update memory consumption before return.
  858. //
  859. pFontPDev->dwFontMemUsed += dwMem;
  860. if (iMode == DL_BASE_SOFT_FONT)
  861. {
  862. //
  863. // Successful download.So mark it current.
  864. //
  865. pFM->dwFontType = FMTYPE_TTBITMAP;
  866. //
  867. // Set cGlyphs to 0 to mark that font is Downloaded OK.
  868. //
  869. pdm->cGlyphs = 0;
  870. pfmTTB->dwDLSize = dwMem;
  871. }
  872. }
  873. else
  874. {
  875. ERR(( "UniFont!BDownLoadAsBmp:NULL IFI or pfnCheckCondition failed.\n") );
  876. goto ErrorExit;
  877. }
  878. }
  879. //
  880. // All success. So return TRUE
  881. //
  882. bRet = TRUE;
  883. ErrorExit:
  884. return bRet;
  885. }
  886. INT
  887. IDownloadFont(
  888. TO_DATA *ptod,
  889. STROBJ *pstro,
  890. INT *piRot
  891. )
  892. /*++
  893. Routine Description:
  894. This function downloads the font and the glyphs. If the font is
  895. already downloaded, it uses that. It goes through all the glyphs
  896. and downloads the new one. This function also intializes pfm, iFace
  897. and apdlGlyph members of TO_DATA.
  898. Arguments:
  899. ptod TextOut Data pointer to fill the DLGLYPH array.
  900. pstro The "width" of fixed pitch font glyphs.
  901. piRot Rotation angle in multiple 90 degree.This is output param
  902. and used by textout call to set the text rotation.
  903. Return Value:
  904. Download font index if font is/can be downloaded; else < 0.
  905. The index is 0 based, i.e first downloaded font has index 0.
  906. Note:
  907. 6/9/1997 -ganeshp-
  908. Created it.
  909. --*/
  910. {
  911. DL_MAP *pdm; // Individual download font map element
  912. INT iRet; // The value we return: # of entry
  913. PFONTPDEV pFontPDev; // Font Modules's PDEV
  914. BOOL bError; // Set if we have an error.
  915. PDEV *pPDev; // Pdev
  916. FONTOBJ *pfo; // FontOBJ to be used
  917. //
  918. // Initialization of Local Variables.
  919. // Default for iRet is Failure set to -1.
  920. //
  921. iRet = -1;
  922. bError = FALSE;
  923. pPDev = ptod->pPDev;
  924. pfo = ptod->pfo;
  925. pFontPDev = pPDev->pFontPDev;
  926. /*
  927. * FIRST test is to check for font rotations. If there is any,
  928. * we do NOT download this font, as the complications of keeping
  929. * track with how (or if) the printer allows it are far too great,
  930. * and, in any event, it is not likely to gain us much, given the
  931. * relative infrequency of this event. Also check to see if the
  932. * printer can rotate fonts or not.
  933. *
  934. */
  935. //
  936. // Use &pFontPDev->ctl to set correct font size. Also check the rotation.
  937. //
  938. *piRot = ISetScale( &pFontPDev->ctl, FONTOBJ_pxoGetXform( pfo ), FALSE , (pFontPDev->flText & TC_CR_ANY)?TRUE:FALSE);
  939. if(!(pFontPDev->dwSelBits & FDH_PORTRAIT) )
  940. return -1;
  941. //
  942. // Printer can't rotate text
  943. //
  944. if ((!(pFontPDev->flText & (TC_CR_ANY|TC_CR_90)) ||
  945. (NULL == COMMANDPTR(pPDev->pDriverInfo, CMD_SETSIMPLEROTATION) &&
  946. NULL == COMMANDPTR(pPDev->pDriverInfo, CMD_SETANYROTATION)))
  947. && *piRot)
  948. return -1;
  949. //
  950. // Printer can rotate 90 rotation
  951. //
  952. if ((!(pFontPDev->flText & TC_CR_90) ||
  953. NULL == COMMANDPTR(pPDev->pDriverInfo, CMD_SETSIMPLEROTATION))
  954. && *piRot / 5 != 0)
  955. return -1;
  956. //
  957. // Get the DL_MAP for this FONTOBJ. The functions sets pvConsumer to
  958. // 1 based the font index.
  959. //
  960. if (pdm = PGetDLMap (pFontPDev,pfo))
  961. {
  962. //
  963. // Given a DL_MAP, Check if it is downloaded or not. If the
  964. // DL_MAP.cGlyphs > 0 and DL_MAP.pfm is not NULL then this
  965. // font is downloaded.
  966. // If This font is Downloaded, return the index. The index
  967. // is saved in pvConsumer, which is one based. We convert it
  968. // to zero based.
  969. //
  970. iRet = (INT)PtrToLong(pfo->pvConsumer) - 1;
  971. if (! (FONTDOWNLOADED(pdm)) )
  972. {
  973. //
  974. // Font is a not downloaded. So start the process of downloading.
  975. // The first job is to fill the DL_MAP structure.
  976. //
  977. if (BInitDLMap(pPDev,pfo,pdm))
  978. {
  979. //
  980. // Check what method is preferred to download the font. Try the
  981. // preferred method first and then the other method.If OEM
  982. // handles the download then call the OEM download routine.
  983. //
  984. if (pFontPDev->flFlags & FDV_DLTT_OEMCALLBACK)
  985. {
  986. //
  987. // OEM download.
  988. //
  989. if (!BDownLoadOEM(pPDev, pfo, pstro, pdm, DL_BASE_SOFT_FONT))
  990. {
  991. ERR(("UniFont!IDownloadFont:BDownLoadOEM Failed!!\n"));
  992. bError = TRUE;
  993. iRet = -1;
  994. VFreeDLMAP(pdm);
  995. pdm->cGlyphs = 0;
  996. }
  997. }
  998. else
  999. {
  1000. if (pFontPDev->flFlags & FDV_DLTT_ASTT_PREF)
  1001. {
  1002. //
  1003. // Try downloading the Bitmap as True Type Outline.
  1004. //
  1005. //
  1006. if (!BDownLoadAsTT(pPDev,pfo,pstro,pdm,DL_BASE_SOFT_FONT))
  1007. {
  1008. //
  1009. // If download as TT fails, we should try to download as
  1010. // Bitmap. So we free the allocated buffers and then
  1011. // mark the DL_MAP as new, by setting cGlyphs to 0.
  1012. //
  1013. WARNING(("UniFont!IDownloadFont:BDownLoadAsTT Failed\n"));
  1014. iRet = -1;
  1015. VFreeDLMAP( pdm );
  1016. pdm->cGlyphs = 0;
  1017. //
  1018. // Decrement the Font id as we haven't downloaded the
  1019. // font yet. So reuse it.
  1020. //
  1021. pFontPDev->iUsedSoftFonts--;
  1022. pFontPDev->iNextSFIndex--;
  1023. }
  1024. }
  1025. if ((pFontPDev->flFlags & FDV_DLTT_BITM_PREF) ||
  1026. ((pFontPDev->flFlags & FDV_DLTT_ASTT_PREF) && (iRet < 0)) )
  1027. {
  1028. //
  1029. // If Downlaod as TT Ouline failed, then try to download as
  1030. // bitmap. So initialize the DL_MAP again.
  1031. //
  1032. if (iRet == -1)
  1033. {
  1034. if (!BInitDLMap(pPDev,pfo,pdm))
  1035. {
  1036. //
  1037. // BInitDLMap Failed
  1038. //
  1039. ERR(("UniFont!IDownloadFont:BInitDLMap Failed for Bitmap Download\n"));
  1040. bError = TRUE;
  1041. }
  1042. }
  1043. if (!bError)
  1044. {
  1045. //
  1046. // If the preffered format is Bitmap or we have incountered
  1047. // an error while downloading as TT outline; then we try to
  1048. // download as Bitmap. Reset iRet to Font Index.
  1049. //
  1050. iRet = (INT)PtrToLong(pfo->pvConsumer) - 1;
  1051. if (!BDownLoadAsBmp(pPDev,pfo,pstro,pdm,DL_BASE_SOFT_FONT))
  1052. {
  1053. ERR(("UniFont!IDownloadFont:BDownLoadAsBmp Failed\n"));
  1054. bError = TRUE;
  1055. }
  1056. }
  1057. }
  1058. //
  1059. // 300 dpi mode. We disabled TT downloading if text and graphics
  1060. // resolutions are not same in intrface.c.
  1061. //
  1062. if (!(pFontPDev->flFlags & FDV_DLTT_BITM_PREF) &&
  1063. !(pFontPDev->flFlags & FDV_DLTT_ASTT_PREF) )
  1064. bError = TRUE;
  1065. }
  1066. }
  1067. else
  1068. {
  1069. //
  1070. // BInitDLMap Failed
  1071. //
  1072. ERR(("UniFont!IDownloadFont:BInitDLMap Failed\n"));
  1073. bError = TRUE;
  1074. }
  1075. }
  1076. if ( pdm != NULL &&
  1077. pdm->pfm != NULL &&
  1078. pdm->pfm->dwFontType == FMTYPE_TTOUTLINE &&
  1079. NONSQUARE_FONT(pFontPDev->pxform))
  1080. {
  1081. //
  1082. // There could be one font, which is scaled differently.
  1083. // PCL5e can't scale x and y independently.
  1084. // Need to print as graphics.
  1085. // So we only set iRet.
  1086. //
  1087. WARNING(("UniFont!IDownloadFont:Err in downloading Glyphs\n"));
  1088. iRet = -1;
  1089. }
  1090. //
  1091. // Now we are done with downloading. if iRet is >= 0 (successful
  1092. // downloading), then try downloading all the glyphs.
  1093. // bDownloadGlyphs will also set download glyph array, apdlGlyph.
  1094. //
  1095. if ((iRet >= 0) && !bError )
  1096. {
  1097. VERBOSE(("\nUniFont!IDownloadFont:Font downloaded successfully\n"));
  1098. ptod->pfm = pdm->pfm;
  1099. //
  1100. // iFace is -ve to identify that this is a TT SoftFont.
  1101. //
  1102. ptod->iFace = -iRet;
  1103. //
  1104. // OEM callback initialization
  1105. //
  1106. if (pFontPDev->pUFObj)
  1107. {
  1108. PFONTMAP_TTOEM pFMOEM;
  1109. //
  1110. // Make sure that this PFM is for OEM.
  1111. //
  1112. if (ptod->pfm->dwFontType == FMTYPE_TTOEM)
  1113. {
  1114. pFMOEM = (PFONTMAP_TTOEM) ptod->pfm->pSubFM;
  1115. pFMOEM->flFontType = pfo->flFontType;
  1116. }
  1117. pFontPDev->pUFObj->ulFontID = ptod->pfm->ulDLIndex;
  1118. //
  1119. // Initialize UFOBJ TrueType font bold/italic simulation
  1120. //
  1121. if (pFontPDev->pUFObj->dwFlags & UFOFLAG_TTDOWNLOAD_TTOUTLINE)
  1122. {
  1123. if (pfo->flFontType & FO_SIM_BOLD)
  1124. pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_BOLD_SIM;
  1125. if (pfo->flFontType & FO_SIM_ITALIC)
  1126. pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_ITALIC_SIM;
  1127. if (NULL != pFontPDev->pIFI &&
  1128. '@' == *((PBYTE)pFontPDev->pIFI + pFontPDev->pIFI->dpwszFamilyName))
  1129. {
  1130. pFontPDev->pUFObj->dwFlags |= UFOFLAG_TTOUTLINE_VERTICAL;
  1131. }
  1132. }
  1133. }
  1134. //
  1135. // Now we are downloading the glyphs, So select the font. This is
  1136. // done by calling BNewFont.
  1137. //
  1138. BNewFont(pPDev, ptod->iFace, ptod->pfm, 0);
  1139. if ( !BDownloadGlyphs(ptod, pstro, pdm ))
  1140. {
  1141. //
  1142. // There is some error in downloading Glyphcs. So don't
  1143. // download. But this not an error. So we only set iRet.
  1144. //
  1145. WARNING(("UniFont!IDownloadFont:Err in downloading Glyphs\n"));
  1146. iRet = -1;
  1147. }
  1148. }
  1149. }
  1150. if (bError)
  1151. {
  1152. //
  1153. // There is some error. So free everything. If pvConsumer is positive
  1154. // then make it negative, to mark it bad.
  1155. //
  1156. if (pfo->pvConsumer > 0)
  1157. {
  1158. pfo->pvConsumer = (PINT_PTR)(-(INT_PTR)pfo->pvConsumer);
  1159. }
  1160. VFreeDLMAP( pdm );
  1161. iRet = -1;
  1162. }
  1163. //
  1164. // Clear the Set Font ID flag. This flag is set per textout
  1165. //
  1166. pFontPDev->flFlags &= ~FDV_SET_FONTID;
  1167. return iRet;
  1168. }
  1169. #define CONVERT_COUNT 7
  1170. IFIMETRICS *
  1171. pGetIFI(
  1172. PDEV *pPDev,
  1173. FONTOBJ *pfo,
  1174. BOOL bScale
  1175. )
  1176. /*++
  1177. Routine Description:
  1178. Given a pointer to a FONTOBJ, return a pointer to the IFIMETRICS
  1179. of the font. If this is a TT font, the metrics will be converted
  1180. with current scaling information. The IFIMETRICS data is allocated
  1181. on the heap, and it is the caller's repsonsibility to free it.
  1182. Arguments:
  1183. pPDev pointer to PDEVICE
  1184. pfo FONTOBJ,The font of interest
  1185. bScale TRUE for scaling IFIMETRICS else FALSE
  1186. Return Value:
  1187. address of IFIMETRICS, else NULL for failure.
  1188. Note:
  1189. 3/5/1997 -ganeshp-
  1190. Created it.
  1191. --*/
  1192. {
  1193. IFIMETRICS *pIFI; /* Obtained from engine */
  1194. IFIMETRICS *pIFIRet; /* Returned to caller */
  1195. XFORMOBJ *pxo; /* For adjusting scalable font metrics */
  1196. POINTL aptlIn[ CONVERT_COUNT ]; /* Input values to xform */
  1197. POINTL aptlOut[ CONVERT_COUNT ]; /* Output values from xform */
  1198. pIFI = ((FONTPDEV*)pPDev->pFontPDev)->pIFI;
  1199. if( pIFI == NULL )
  1200. return NULL; /* May happen when journalling is in progress */
  1201. /*
  1202. * We need to make a copy of this, since we are going to clobber it.
  1203. * This may not be required if we are dealing with a bitmap font, but
  1204. * it is presumed most likely to be a TrueType font.
  1205. */
  1206. if( pIFIRet = (IFIMETRICS *)MemAllocZ(pIFI->cjThis ) )
  1207. {
  1208. /*
  1209. * First copy the IFIMETRICS as is. Then, if a scalable font,
  1210. * we need to adjust the various sizes with the appropriate
  1211. * transform.
  1212. */
  1213. CopyMemory( pIFIRet, pIFI, pIFI->cjThis );
  1214. if( bScale &&
  1215. (pIFIRet->flInfo &
  1216. (FM_INFO_ISOTROPIC_SCALING_ONLY |
  1217. FM_INFO_ANISOTROPIC_SCALING_ONLY |
  1218. FM_INFO_ARB_XFORMS)) &&
  1219. (pxo = FONTOBJ_pxoGetXform( pfo )))
  1220. {
  1221. /*
  1222. * Scalable, and transform available, so go do the
  1223. * transformations to get the font size in device pels.
  1224. *
  1225. ***********************************************************
  1226. * ONLY SOME FIELDS ARE TRANSFORMED, AS WE USE ONLY A FEW.
  1227. ***********************************************************
  1228. */
  1229. ZeroMemory( aptlIn, sizeof( aptlIn ) ); /* Zero default */
  1230. aptlIn[ 0 ].y = pIFI->fwdTypoAscender;
  1231. aptlIn[ 1 ].y = pIFI->fwdTypoDescender;
  1232. aptlIn[ 2 ].y = pIFI->fwdTypoLineGap;
  1233. aptlIn[ 3 ].x = pIFI->fwdMaxCharInc;
  1234. aptlIn[ 4 ].x = pIFI->rclFontBox.left;
  1235. aptlIn[ 4 ].y = pIFI->rclFontBox.top;
  1236. aptlIn[ 5 ].x = pIFI->rclFontBox.right;
  1237. aptlIn[ 5 ].y = pIFI->rclFontBox.bottom;
  1238. aptlIn[ 6 ].x = pIFI->fwdAveCharWidth;
  1239. /*
  1240. * Perform the transform, and verify that there is no
  1241. * rotation component. Return NULL (failure) if any of
  1242. * this fails.
  1243. */
  1244. if( !XFORMOBJ_bApplyXform( pxo, XF_LTOL, CONVERT_COUNT,
  1245. aptlIn, aptlOut )
  1246. #if 0
  1247. ||
  1248. aptlOut[ 0 ].x || aptlOut[ 1 ].x ||
  1249. aptlOut[ 2 ].x || aptlOut[ 3 ].y
  1250. #endif
  1251. )
  1252. {
  1253. MemFree((LPSTR)pIFIRet );
  1254. return NULL;
  1255. }
  1256. /* Simply install the new values into the output IFIMETRICS */
  1257. pIFIRet->fwdTypoAscender = (FWORD) aptlOut[0].y;
  1258. pIFIRet->fwdTypoDescender = (FWORD) aptlOut[1].y;
  1259. pIFIRet->fwdTypoLineGap = (FWORD) aptlOut[2].y;
  1260. pIFIRet->fwdWinAscender = pIFIRet->fwdTypoAscender;
  1261. pIFIRet->fwdWinDescender = -pIFIRet->fwdTypoDescender;
  1262. pIFIRet->fwdMacAscender = pIFIRet->fwdTypoAscender;
  1263. pIFIRet->fwdMacDescender = pIFIRet->fwdTypoDescender;
  1264. pIFIRet->fwdMacLineGap = pIFIRet->fwdTypoLineGap;
  1265. pIFIRet->fwdMaxCharInc = (FWORD)aptlOut[3].x;
  1266. /*
  1267. * PCL is fussy about the limits of the character cell.
  1268. * We allow some slop here by expanding the rclFontBox by
  1269. * one pel on each corner.
  1270. */
  1271. pIFIRet->rclFontBox.left = aptlOut[ 4 ].x - 1;
  1272. pIFIRet->rclFontBox.top = aptlOut[ 4 ].y + 1;
  1273. pIFIRet->rclFontBox.right = aptlOut[ 5 ].x + 1;
  1274. pIFIRet->rclFontBox.bottom = aptlOut[ 5 ].y - 1;
  1275. pIFIRet->fwdAveCharWidth = (FWORD)aptlOut[ 6 ].x;
  1276. VERBOSE(("\n UniFont!pGetIFI:pIFI->fwdTypoAscender = %d,pIFI->fwdTypoDescender = %d\n",pIFI->fwdTypoAscender,pIFI->fwdTypoDescender));
  1277. VERBOSE(("UniFont!pGetIFI:pIFI->fwdWinAscender = %d, pIFI->fwdWinDescender = %d\n", pIFI->fwdWinAscender,pIFI->fwdWinDescender ));
  1278. VERBOSE(("UniFont!pGetIFI:pIFI->rclFontBox.top = %d,pIFI->rclFontBox.bottom = %d\n", pIFI->rclFontBox.top, pIFI->rclFontBox.bottom));
  1279. VERBOSE(("UniFont!pGetIFI: AFTER SCALING THE FONT\n"));
  1280. VERBOSE(("UniFont!pGetIFI:pIFIRet->fwdTypoAscender = %d,pIFIRet->fwdTypoDescender = %d\n",pIFIRet->fwdTypoAscender,pIFIRet->fwdTypoDescender));
  1281. VERBOSE(("UniFont!pGetIFI:pIFIRet->fwdWinAscender = %d, pIFIRet->fwdWinDescender = %d\n", pIFIRet->fwdWinAscender,pIFIRet->fwdWinDescender ));
  1282. VERBOSE(("UniFont!pGetIFI:pIFIRet->rclFontBox.top = %d,pIFIRet->rclFontBox.bottom = %d\n", pIFIRet->rclFontBox.top, pIFIRet->rclFontBox.bottom));
  1283. }
  1284. }
  1285. return pIFIRet;
  1286. }
  1287. #undef CONVERT_COUNT
  1288. BOOL
  1289. BSendDLFont(
  1290. PDEV *pPDev,
  1291. FONTMAP *pFM
  1292. )
  1293. /*++
  1294. Routine Description:
  1295. Called to download an existing softfont. Checks to see if the
  1296. font has been downloaded, and if so, does nothing. Otherwise
  1297. goes through the motions of downloading.
  1298. Arguments:
  1299. pPDev Pointer to PDEV
  1300. pFM The particular font of interest.
  1301. Return Value:
  1302. TRUE/FALSE; FALSE only if there is a problem during the load.
  1303. Note:
  1304. 3/4/1997 -ganeshp-
  1305. Created it.
  1306. --*/
  1307. {
  1308. FONTMAP_DEV *pFMDev;
  1309. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  1310. PDATA_HEADER pDataHeader;
  1311. PBYTE pDownloadData;
  1312. DWORD dwLeft; // Bytes remaining to send
  1313. /*
  1314. * First see if it has already been downloaded!
  1315. */
  1316. if( pFM->flFlags & (FM_SENT | FM_GEN_SFONT) )
  1317. return TRUE;
  1318. pFMDev = (PFONTMAP_DEV)pFM->pSubFM;
  1319. if (!(pDataHeader = FIGetVarData( pFontPDev->hUFFFile, pFMDev->dwResID)) ||
  1320. pDataHeader->dwSignature != DATA_VAR_SIG ||
  1321. pDataHeader->dwDataSize == 0 )
  1322. return FALSE;
  1323. dwLeft = pDataHeader->dwDataSize;
  1324. pDownloadData = ((PBYTE)pDataHeader + pDataHeader->wSize);
  1325. /*
  1326. * Check if there is memory to fit this font. These are all
  1327. * approximations, but it is better than running out of memory
  1328. * in the printer.
  1329. */
  1330. if( (pFontPDev->dwFontMemUsed + PCL_FONT_OH + dwLeft) > pFontPDev->dwFontMem )
  1331. return FALSE;
  1332. /*
  1333. * Time to be serious about downloading. UniDrive provides some
  1334. * of the control stuff we need. As well, we need to select an ID.
  1335. * The font itself is memory mapped, so we need only to shuffle it
  1336. * off to WriteSpoolBuf().
  1337. */
  1338. pFM->ulDLIndex = IGetDL_ID( pPDev ); /* Down load index to use */
  1339. if( pFM->ulDLIndex == -1 )
  1340. return FALSE; /* Have run out of slots! */
  1341. /*
  1342. * Downloading is quite simple. First send an identifying command
  1343. * (to label the font for future selection) and then copy the font
  1344. * data (in the *.fi_ file) to the printer.
  1345. */
  1346. BUpdateStandardVar(pPDev, pFM, 0, 0, STD_STD|STD_NFID);
  1347. WriteChannel( pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID) );
  1348. while( dwLeft )
  1349. {
  1350. DWORD cjSize; /* Number of bytes to send */
  1351. cjSize = min( dwLeft, DL_BUF_SZ );
  1352. if( WriteSpoolBuf( pPDev, pDownloadData, cjSize ) != (int)cjSize )
  1353. {
  1354. break;
  1355. }
  1356. if( pPDev->fMode & PF_ABORTED )
  1357. break;
  1358. dwLeft -= cjSize;
  1359. pDownloadData += cjSize;
  1360. }
  1361. /*
  1362. * If dwLeft is 0, then everything completed as expected. Under these
  1363. * conditions, we flag the data as having been sent, and thus available
  1364. * for use. Even if we failed, we should assume we have consumed
  1365. * all the font's memory and adjust our records accordingly.
  1366. */
  1367. if( dwLeft == 0 )
  1368. pFM->flFlags |= FM_SENT; /* Now done */
  1369. /*
  1370. * Account for memory used by this font.
  1371. */
  1372. pFontPDev->dwFontMemUsed += PCL_FONT_OH + pDataHeader->dwDataSize;
  1373. return dwLeft == 0;
  1374. }
  1375. DWORD
  1376. DwGetTTGlyphWidth(
  1377. FONTPDEV *pFontPDev,
  1378. FONTOBJ *pfo,
  1379. HGLYPH hTTGlyph)
  1380. /*++
  1381. Routine Description:
  1382. Arguments:
  1383. pFontPDev Font PDevice
  1384. pfo Fontobj
  1385. hTTGlyph Glyph handle
  1386. Return Value:
  1387. Character width
  1388. Note:
  1389. --*/
  1390. {
  1391. DLGLYPH *pdlg;
  1392. DL_MAP *pdm;
  1393. DWORD dwRet;
  1394. if (!pfo || !pFontPDev)
  1395. return 0;
  1396. if (!(pdm = PGetDLMap (pFontPDev,pfo)) ||
  1397. !(pdlg = PDLGHashGlyph (pdm, hTTGlyph)))
  1398. {
  1399. dwRet = 0;
  1400. }
  1401. else
  1402. {
  1403. dwRet = pdlg->wWidth;
  1404. }
  1405. return dwRet;
  1406. }