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.

661 lines
17 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. bmpdload.c
  5. Abstract:
  6. Implementation of True Type Download as Bitmap routines.
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. 06/06/97 -ganeshp-
  11. Created
  12. --*/
  13. //
  14. //This line should be before the line including font.h.
  15. //Comment out this line to disable FTRC and FTST macroes.
  16. //
  17. //#define FILETRACE
  18. #include "font.h"
  19. BOOL
  20. BFreeTrueTypeBMPPFM(
  21. PFONTMAP pfm
  22. )
  23. /*++
  24. Routine Description:
  25. Frees a downloded font's PFM.
  26. Arguments:
  27. pfm Pointer to Fontmap
  28. Return Value:
  29. TRUE for success and FALSE for failure
  30. Note:
  31. 6/6/1997 -ganeshp-
  32. Created it.
  33. --*/
  34. {
  35. if (pfm)
  36. {
  37. MemFree(pfm);
  38. return TRUE;
  39. }
  40. else
  41. {
  42. return FALSE;
  43. }
  44. }
  45. DWORD
  46. DwTrueTypeBMPGlyphOut(
  47. TO_DATA *pTod
  48. )
  49. /*++
  50. Routine Description:
  51. This functions outputs the downloaded glyphs. All the information is stored
  52. in TOD
  53. Arguments:
  54. pTod TextOut Data.
  55. Return Value:
  56. Number of Glyph outputed. O for ERROR.
  57. Note:
  58. 6/9/1997 -ganeshp-
  59. Created it.
  60. --*/
  61. {
  62. DWORD dwNumGlyphsPrinted; // Glyphs Printed
  63. DWORD dwCurrGlyphIndex; // Current Glyph to print.
  64. DWORD dwGlyphsToPrint; // Number of Glyphs to print.
  65. DWORD dwCopyOfGlyphsToPrint; // Copy of dwGlyphsToPrint
  66. GLYPHPOS *pgp; // Glyph position array.
  67. PDEV *pPDev; // Our PDEV.
  68. PDLGLYPH pdlGlyph; // Download Glyph information
  69. INT iX, iY; // X and Y position of Glyphs.
  70. POINTL ptlRem; // Remainder of XoveTo and YMoveTo.
  71. BOOL bSetCursorForEachGlyph; // X and Y position should be set if TRUE
  72. //
  73. // Local Initialization.
  74. //
  75. dwCurrGlyphIndex = pTod->dwCurrGlyph;
  76. dwCopyOfGlyphsToPrint =
  77. dwGlyphsToPrint = pTod->cGlyphsToPrint;
  78. dwNumGlyphsPrinted = 0;
  79. pgp = pTod->pgp;
  80. pPDev = pTod->pPDev;
  81. iX = pTod->pgp->ptl.x;
  82. iY = pTod->pgp->ptl.y;
  83. FTRC(\n********TRACING DwTrueTypeBMPGlyphOut ***********\n);
  84. FTST(dwCurrGlyphIndex,%d);
  85. FTST(dwGlyphsToPrint,%d);
  86. //
  87. // Set the cursor to first glyph if not already set.
  88. //
  89. if ( !(pTod->flFlags & TODFL_FIRST_GLYPH_POS_SET) )
  90. {
  91. VSetCursor( pPDev, iX, iY, MOVE_ABSOLUTE, &ptlRem);
  92. //
  93. // We need to handle the return value. Devices with resoloutions finer
  94. // than their movement capability (like LBP-8 IV) get into a knot here,
  95. // attempting to y-move on each glyph. We pretend we got where we
  96. // wanted to be.
  97. //
  98. pPDev->ctl.ptCursor.x += ptlRem.x;
  99. pPDev->ctl.ptCursor.y += ptlRem.y ;
  100. //
  101. // Now set the flag.
  102. //
  103. pTod->flFlags |= TODFL_FIRST_GLYPH_POS_SET;
  104. }
  105. //
  106. // Now start printing. The printing should be optimised for default
  107. // placement. In this case we assume that GDI has placed the glyphs
  108. // based upon their width and we don't need to update our cursor pos
  109. // after every glyph. we print all the glyphs and then move the cursor
  110. // to the last glyph position. If we know the width of the downloaded
  111. // glyph then we will update position the cursor at the end of the
  112. // glyphs box else we will just move to the last glyph cursor position.
  113. //
  114. // If the default placement is not set then we print a glyph and move. If
  115. // we know the width we do some optimization. we find out the new cursor
  116. // position, by adding the glyph width. If the new position matches that of
  117. // the next glyph we just update our cursor position else we move to the
  118. // the next glyph position.
  119. //
  120. bSetCursorForEachGlyph = SET_CURSOR_FOR_EACH_GLYPH(pTod->flAccel);
  121. while (dwGlyphsToPrint)
  122. {
  123. pdlGlyph = pTod->apdlGlyph[dwCurrGlyphIndex];
  124. if (bSetCursorForEachGlyph)
  125. {
  126. //
  127. // If we are printing top to down or right to left we need to
  128. // set the position.
  129. //
  130. if( pTod->flAccel & SO_VERTICAL )
  131. {
  132. //
  133. // When we are printing veritcal, only Y changes.X position is
  134. // same for all glyphs.
  135. //
  136. iX = pTod->ptlFirstGlyph.x;
  137. iY = pgp[dwNumGlyphsPrinted].ptl.y;
  138. }
  139. else if ( (pTod->flAccel & SO_HORIZONTAL) &&
  140. (pTod->flAccel & SO_REVERSED) )
  141. {
  142. //
  143. // This is the Horizental reversed case(Right to Left). In this
  144. // case only x position changes.Y is set to first glyph's Y.
  145. //
  146. iX = pgp[dwNumGlyphsPrinted].ptl.x;
  147. iY = pTod->ptlFirstGlyph.y;
  148. }
  149. else
  150. {
  151. //
  152. // The Glyphs are not placed at default positions.Each glyph has
  153. // explicit X and Y.So we need to move.
  154. //
  155. iX = pgp[dwNumGlyphsPrinted].ptl.x;
  156. iY = pgp[dwNumGlyphsPrinted].ptl.y;
  157. }
  158. VSetCursor( pPDev, iX, iY, MOVE_ABSOLUTE, &ptlRem);
  159. }
  160. //
  161. // Default placement or we have moved to the correct position. Now Just
  162. // print the Glyph.
  163. //
  164. if ( !BPrintADLGlyph(pPDev, pTod, pdlGlyph) )
  165. {
  166. ERR(("UniFont:DwTrueTypeBMPGlyphOut:BPrintADLGlyph Failed\n"));
  167. goto ErrorExit;
  168. }
  169. //
  170. // If for each glyph, cursor has to be set, then update cursor position.
  171. // This may result in fewer Movement command, because if the next
  172. // glyph's position is at the updated cursor, we will not send any
  173. // Movement command.
  174. //
  175. if( pTod->flAccel & SO_VERTICAL )
  176. iY += pdlGlyph->wWidth;
  177. else
  178. iX += pdlGlyph->wWidth;
  179. if (bSetCursorForEachGlyph)
  180. {
  181. //
  182. // If for each glyph, the cursor position has to be set, then iX
  183. // and iY are already updated. So just use them.
  184. //
  185. VSetCursor( pPDev, iX, iY, MOVE_ABSOLUTE | MOVE_UPDATE, &ptlRem);
  186. }
  187. else if (dwGlyphsToPrint == 1) //Last Glyph
  188. {
  189. //
  190. // Set the cursor to the end of the last glyph. Only the X position
  191. // has to be updated. This has to be done only for default
  192. // placement, as for non default placement case, we update cursor
  193. // position after printing the glyph.For default placement use the
  194. // cursor position of the last glyph.In TextOut Call, for default
  195. // placement, we have already computed the position for each glyph.
  196. //
  197. VSetCursor( pPDev, iX, iY, MOVE_ABSOLUTE | MOVE_UPDATE, &ptlRem);
  198. }
  199. //
  200. // Update the counters.
  201. //
  202. dwGlyphsToPrint--;
  203. dwNumGlyphsPrinted++;
  204. dwCurrGlyphIndex++;
  205. }
  206. //
  207. // If no failure then we would have printed all the glyphs.
  208. //
  209. ASSERTMSG( (dwNumGlyphsPrinted == dwCopyOfGlyphsToPrint),
  210. ("UniFont:DwTrueTypeBMPGlyphOut: All glyphs are not printed"));
  211. FTRC(After Printing The values are:\n);
  212. FTST(dwGlyphsToPrint,%d);
  213. FTST(dwNumGlyphsPrinted,%d);
  214. FTST(dwCopyOfGlyphsToPrint,%d);
  215. FTST(dwCurrGlyphIndex,%d);
  216. ErrorExit:
  217. FTRC(********END TRACING DwTrueTypeBMPGlyphOut ***********\n);
  218. return dwNumGlyphsPrinted;
  219. }
  220. BOOL
  221. BSelectTrueTypeBMP(
  222. PDEV *pPDev,
  223. PFONTMAP pFM,
  224. POINTL* pptl
  225. )
  226. /*++
  227. Routine Description:
  228. To Select a TrueType Downloaded as Bitmap Font.
  229. Arguments:
  230. pPDev Pointer to PDEV
  231. pDM fontmap pointer.
  232. pptl Point Size of the font, Not used.
  233. Return Value:
  234. TRUE for success and FALSE for failure
  235. Note:
  236. 6/9/1997 -ganeshp-
  237. Created it.
  238. --*/
  239. {
  240. BOOL bRet;
  241. //
  242. // Local Initialization.
  243. //
  244. bRet = FALSE;
  245. if( pFM->flFlags & FM_SOFTFONT )
  246. {
  247. /*
  248. * Call BSendFont to download the installed softfont.
  249. */
  250. if( !BSendDLFont( pPDev, pFM ) )
  251. return FALSE;
  252. /*
  253. * Can now select the font: this is done using a specific
  254. * ID. The ID is stored in the FONTMAP structure. The calling
  255. * function has updated the standard variable so just send
  256. * CMD_SELECTFONTID command.
  257. */
  258. BUpdateStandardVar(pPDev, pFM, 0, 0, STD_CFID );
  259. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SELECTFONTID));
  260. bRet = TRUE;
  261. }
  262. return bRet;
  263. }
  264. BOOL
  265. BDeselectTrueTypeBMP(
  266. PDEV *pPDev,
  267. PFONTMAP pFM
  268. )
  269. /*++
  270. Routine Description:
  271. Arguments:
  272. pPDev Pointer to PDEV
  273. Return Value:
  274. TRUE for success and FALSE for failure
  275. Note:
  276. 6/9/1997 -ganeshp-
  277. Created it.
  278. --*/
  279. {
  280. BOOL bRet;
  281. COMMAND *pCmd;
  282. //
  283. // Local Initialization.
  284. //
  285. bRet = FALSE;
  286. if( pFM->flFlags & FM_SOFTFONT )
  287. {
  288. /*
  289. * Can now select the font: this is done using a specific
  290. * ID. The ID is stored in the FONTMAP structure. The calling
  291. * function has updated the standard variable so just send
  292. * CMD_SELECTFONTID command.
  293. */
  294. pCmd = COMMANDPTR(pPDev->pDriverInfo, CMD_DESELECTFONTID);
  295. if (pCmd)
  296. {
  297. BUpdateStandardVar(pPDev, pFM, 0, 0, STD_CFID);
  298. WriteChannel(pPDev,pCmd );
  299. }
  300. bRet = TRUE;
  301. }
  302. return bRet;
  303. }
  304. DWORD
  305. DwDLTrueTypeBMPHeader(
  306. PDEV *pPDev,
  307. PFONTMAP pFM
  308. )
  309. /*++
  310. Routine Description:
  311. Arguments:
  312. pPDev Pointer to PDEV
  313. pFM FontMap for All Font information
  314. Return Value:
  315. This function returns the memory used to download this font.
  316. If this function fails, this function has to return 0,
  317. Note:
  318. 6/9/1997 -ganeshp-
  319. Created it.
  320. --*/
  321. {
  322. DWORD dwMem;
  323. //
  324. // Local Initialization.
  325. //
  326. dwMem = DwDLPCLHeader(pPDev, pFM->pIFIMet, pFM->ulDLIndex );
  327. return dwMem;
  328. }
  329. DWORD
  330. DwDLTrueTypeBMPGlyph(
  331. PDEV *pPDev,
  332. PFONTMAP pFM,
  333. HGLYPH hGlyph,
  334. WORD wDLGlyphId,
  335. WORD *pwWidth
  336. )
  337. /*++
  338. Routine Description:
  339. Arguments:
  340. pPDev Pointer to PDEV
  341. pFM FontMap data
  342. hGlyph Handle to the Glyph.
  343. wDLGlyphId Downloaded Glyph Id.
  344. pwWidth Width of the Glyph. Update this parameter.
  345. Return Value:
  346. The memory used to download thsi glyph.
  347. Note:
  348. 6/9/1997 -ganeshp-
  349. Created it.
  350. --*/
  351. {
  352. DWORD dwMem;
  353. TO_DATA *pTod;
  354. GLYPHDATA *pgd;
  355. PFONTMAP_TTB pFMTB;
  356. DL_MAP *pdm;
  357. //
  358. // Initialize Local Variables
  359. //
  360. dwMem = 0;
  361. pTod = PFDV->ptod;
  362. pgd = NULL;
  363. pFMTB = pFM->pSubFM;
  364. pdm = pFMTB->u.pvDLData;;
  365. //
  366. // Check the Set FontID flag. If this flag is set that means the
  367. // CMD_SETFONTID command is send and we don't need to set it again.
  368. // Else we should send this command as PCL glyph downloding needs this
  369. // command to be sent, before we download any glyph.
  370. //
  371. if (!(PFDV->flFlags & FDV_SET_FONTID))
  372. {
  373. pFM->ulDLIndex = pdm->wCurrFontId;
  374. BUpdateStandardVar(pPDev, pFM, 0, 0, STD_STD | STD_NFID);
  375. WriteChannel(pPDev, COMMANDPTR(pPDev->pDriverInfo, CMD_SETFONTID));
  376. PFDV->flFlags |= FDV_SET_FONTID;
  377. }
  378. BUpdateStandardVar(pPDev, pFM, wDLGlyphId, 0, STD_GL);
  379. if( !FONTOBJ_cGetGlyphs( pTod->pfo, FO_GLYPHBITS, (ULONG)1,
  380. &hGlyph, &pgd ) ||
  381. !(*pwWidth = (WORD)IDLGlyph( pPDev, wDLGlyphId, pgd, &dwMem )) )
  382. {
  383. ERR(("Unifont!DwDLTrueTypeBMPGlyph: Downloading Glyph Failed\n"));
  384. return 0;
  385. }
  386. //
  387. // Update memory consumption usage
  388. //
  389. ((PFONTMAP_TTB)pFM->pSubFM)->dwDLSize += dwMem;
  390. return dwMem;
  391. }
  392. BOOL
  393. BCheckCondTrueTypeBMP(
  394. PDEV *pPDev,
  395. FONTOBJ *pfo,
  396. STROBJ *pso,
  397. IFIMETRICS *pifi
  398. )
  399. /*++
  400. Routine Description:
  401. Arguments:
  402. pPDev Pointer to PDEV
  403. pfo FONTOBJ to download
  404. pso StringObj
  405. pifi IFI mertics.
  406. Return Value:
  407. TRUE for success and FALSE for failure
  408. Note:
  409. 6/9/1997 -ganeshp-
  410. Created it.
  411. --*/
  412. {
  413. INT iFontIndex;
  414. DL_MAP *pdm;
  415. PFONTPDEV pFontPDev;
  416. INT iGlyphsDL;
  417. DWORD cjMemUsed;
  418. BOOL bRet;
  419. //
  420. // Local variables initialization.
  421. //
  422. iFontIndex = PtrToLong(pfo->pvConsumer) - 1;
  423. pFontPDev = PFDV;
  424. bRet = FALSE;
  425. if (pdm = PGetDLMapFromIdx (pFontPDev, iFontIndex))
  426. {
  427. //
  428. // Trunction may have happened.We won't download if the number glyphs
  429. // or Glyph max size are == MAXWORD.
  430. //
  431. if ( (pdm->cTotalGlyphs != MAXWORD) &&
  432. (pdm->wMaxGlyphSize != MAXWORD) &&
  433. (pdm->wFirstDLGId != MAXWORD) &&
  434. (pdm->wLastDLGId != MAXWORD) )
  435. {
  436. /*
  437. * Must now decide whether to download this font or not. This is
  438. * a guess work. We should try to findout the memory consumption.
  439. * Check on memory usage. Assume all glyphs are the largest size:
  440. * this is pessimistic for a proportional font, but safe, given
  441. * the vaguaries of tracking memory usage.
  442. */
  443. ASSERTMSG((pdm->cTotalGlyphs && pdm->wMaxGlyphSize),\
  444. ("pdm->cTotalGlyphs = %d, pdm->wGlyphMaxSize = %d\n",\
  445. pdm->cTotalGlyphs,pdm->wMaxGlyphSize));
  446. iGlyphsDL = min( (pdm->wLastDLGId - pdm->wFirstDLGId),
  447. pdm->cTotalGlyphs );
  448. cjMemUsed = iGlyphsDL * pdm->wMaxGlyphSize;
  449. if( !(pifi->flInfo & FM_INFO_CONSTANT_WIDTH) )
  450. {
  451. /*
  452. * If this is a proportionally spaced font, we should reduce
  453. * the estimate of memory size for this font. The reason is
  454. * that the above estimate is the size of the biggest glyph
  455. * in the font. There will (for Latin fonts, anyway) be many
  456. * smaller glyphs, some much smaller.
  457. */
  458. cjMemUsed /= PCL_PITCH_ADJ;
  459. }
  460. /*
  461. * We only download if the memory used for this font is less than
  462. * available memory.
  463. */
  464. if( (pFontPDev->dwFontMemUsed + cjMemUsed) > pFontPDev->dwFontMem )
  465. {
  466. WARNING(("UniFont!BCheckCondTrueTypeBMP:Not Downloading the font:TOO BIG for download\n"));
  467. }
  468. else
  469. bRet = TRUE;
  470. }
  471. }
  472. return bRet;
  473. }
  474. FONTMAP *
  475. InitPFMTTBitmap(
  476. PDEV *pPDev,
  477. FONTOBJ *pFontObj
  478. )
  479. /*++
  480. Routine Description:
  481. This routine initializes the True Type downloaded(as bitmap) font's PFM.
  482. Arguments:
  483. pPDev Pointer to PDEV
  484. pFontObj FontObj pointer.
  485. Return Value:
  486. Pointer to FONTMAP for success and NULL for failure.
  487. Note:
  488. 6/6/1997 -ganeshp-
  489. Created it.
  490. --*/
  491. {
  492. PFONTMAP pfm;
  493. DWORD dwSize;
  494. dwSize = sizeof(FONTMAP) + sizeof(FONTMAP_TTB);
  495. if ( pfm = MemAlloc( dwSize ) )
  496. {
  497. ZeroMemory(pfm, dwSize);
  498. pfm->dwSignature = FONTMAP_ID;
  499. pfm->dwSize = sizeof(FONTMAP);
  500. pfm->dwFontType = FMTYPE_TTBITMAP;
  501. pfm->pSubFM = (PVOID)(pfm+1);
  502. pfm->ulDLIndex = (ULONG)-1;
  503. //
  504. // These two entries are meaningless.
  505. //
  506. pfm->wFirstChar = 0;
  507. pfm->wLastChar = 0xffff;
  508. pfm->pfnGlyphOut = DwTrueTypeBMPGlyphOut;
  509. pfm->pfnSelectFont = BSelectTrueTypeBMP;
  510. pfm->pfnDeSelectFont = BDeselectTrueTypeBMP;
  511. pfm->pfnDownloadFontHeader = DwDLTrueTypeBMPHeader;
  512. pfm->pfnDownloadGlyph = DwDLTrueTypeBMPGlyph;
  513. pfm->pfnCheckCondition = BCheckCondTrueTypeBMP;
  514. pfm->pfnFreePFM = BFreeTrueTypeBMPPFM;
  515. }
  516. return pfm;
  517. }
  518. #undef FILETRACE