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.

2042 lines
55 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. intrface.c
  5. Abstract:
  6. Implementation of the interface between Control module and Font module
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. 10/14/96 -amandan-
  11. Created
  12. 11/18/96 -ganeshp-
  13. FMInit implementation.
  14. --*/
  15. #include "font.h"
  16. static FMPROCS UniFMFuncs =
  17. {
  18. FMStartDoc,
  19. FMStartPage,
  20. FMSendPage,
  21. FMEndDoc,
  22. FMNextBand,
  23. FMStartBanding,
  24. FMResetPDEV,
  25. FMEnableSurface,
  26. FMDisableSurface,
  27. FMDisablePDEV,
  28. FMTextOut,
  29. FMQueryFont,
  30. FMQueryFontTree,
  31. FMQueryFontData,
  32. FMFontManagement,
  33. FMQueryAdvanceWidths,
  34. FMGetGlyphMode
  35. };
  36. //
  37. // Local functions Prototype
  38. //
  39. BOOL
  40. BFMInitDevInfo(
  41. DEVINFO *pDevInfo,
  42. PDEV *pPDev
  43. );
  44. BOOL
  45. BInitStandardVariable(
  46. PDEV *pPDev);
  47. BOOL
  48. BCheckFontMemUsage(
  49. PDEV *pPDev);
  50. INT
  51. iMaxFontID(
  52. IN INT iMax,
  53. OUT DWORD *pFontIndex);
  54. VOID
  55. VGetFromBuffer(
  56. IN PWSTR pwstrDest,
  57. IN size_t cchDestStr,
  58. IN OUT PWSTR *ppwstrSrc,
  59. IN OUT PINT piRemBuffSize);
  60. VOID
  61. VSetReselectFontFlags(
  62. PDEV *pPDev
  63. );
  64. LRESULT
  65. PartialClipOn(
  66. PDEV *pPDev);
  67. //
  68. //
  69. // Main initialization function
  70. //
  71. //
  72. BOOL
  73. FMInit (
  74. PDEV *pPDev,
  75. DEVINFO *pDevInfo,
  76. GDIINFO *pGDIInfo
  77. )
  78. /*++
  79. Routine Description:
  80. This function is called to initialize font related information in
  81. pPDev, pDevInfo pGDIInfo and FontPDEV. This module will initialize
  82. various dat structures needed for other modules. For example all
  83. all the font specific resources will be loaded.
  84. The following fields of PDev are intialized:
  85. iFonts : Number of Device Fonts including Cartridge and SoftFonts.
  86. ptDefaultFont: Default Font Width and Height in Device Units.
  87. pFontPDEV: Font Module PDevice.
  88. pFontProcs: Font Module specific DDI callback functions pointers.
  89. Control Module uses this table to call different DDI
  90. entry points specific to Font Module.
  91. fHooks: Set to HOOK_TEXTOUT if the printer has device fonts.
  92. Also standard variables specific to font module will be initialized.
  93. The following fields of pDevInfo are intialized.
  94. lfDefaultFont : Default logical Device Font.
  95. lfAnsiVarFont: Default Logical Variable pitch Device font.
  96. lfAnsiFixFont: Default Logical Fixed pitch Device font.
  97. cFonts: Number of Device Fonts.
  98. The following fields of pGDIInfo will be initialized:
  99. flTextCaps : Text Capability Flags.
  100. Arguments:
  101. pPDev Pointer to PDEV
  102. pDevInfo Pointer to DEVINFO
  103. pGDIInfo Pointer to GDIINFO
  104. Return Value:
  105. TRUE for success and FALSE for failure
  106. Note:
  107. --*/
  108. {
  109. PFONTPDEV pFontPDev;
  110. //
  111. // Validate Input Parameters and ASSERT.
  112. //
  113. ASSERT(pPDev);
  114. ASSERT(pDevInfo);
  115. ASSERT(pGDIInfo);
  116. //
  117. // Allocate and initialize FONTPDEV.
  118. //
  119. // Initialize FONTPDEV
  120. //
  121. // Build the Device Module specific data structures. This involves going
  122. // through Device and cartrige font list building the FONTMAP structure for
  123. // each of them. We also go through the soft font list and add them to the
  124. // list.
  125. //
  126. // Initialize FONTMAP
  127. //
  128. // Build the font map table.The font cartridges are stored as DT_FONTSCART.
  129. // The installed cartrides are stored in Registry. So we need a mapping
  130. // table of font cartridges names to translate the registry information
  131. // into a list of fonts. After buildind the font mapping table we read the
  132. // registry and mark the corresponding Font Cartridges as installed.
  133. //
  134. // Initialize Device font list from GPD.
  135. // Read the GPD data about Device Fonts. The font information is in PDEV.
  136. // The Device fonts are stored as LIST of resource IDs.
  137. //
  138. // Initialize DEVINFO specific fields.
  139. //
  140. // Initialize the GDIINFO specific fileds.
  141. //
  142. // This include text capability flag and other font specific information.
  143. //
  144. if ( !(pFontPDev = MemAllocZ(sizeof(FONTPDEV))) )
  145. {
  146. ERR(("UniFont!FMInit:Can't Allocate FONTPDEV"));
  147. return FALSE;
  148. }
  149. pPDev->pFontPDev = pFontPDev;
  150. //
  151. //Initialize various fields.
  152. //
  153. pFontPDev->dwSignature = FONTPDEV_ID;
  154. pFontPDev->dwSize = sizeof(FONTPDEV);
  155. pFontPDev->pPDev = pPDev;
  156. if (!BBuildFontCartTable(pPDev) ||
  157. !BRegReadFontCarts(pPDev) ||
  158. !BInitFontPDev(pPDev) ||
  159. !BInitDeviceFontsFromGPD(pPDev) ||
  160. !BBuildFontMapTable(pPDev) ||
  161. !BFMInitDevInfo(pDevInfo,pPDev) ||
  162. !BInitGDIInfo(pGDIInfo,pPDev) ||
  163. !BInitStandardVariable(pPDev) )
  164. {
  165. VFontFreeMem(pPDev);
  166. ERR(("Can't Initialize the Font specific data in PDEV"));
  167. return FALSE;
  168. }
  169. //
  170. // Initialze PDEV specific fields.
  171. //
  172. pPDev->pFontProcs = &UniFMFuncs;
  173. #if DO_LATER
  174. //
  175. // if the printer is not a serial printer.
  176. //
  177. if (pPDev->pGlobals->printertype != PT_SERIAL)
  178. {
  179. pPDev->fMode |= PF_FORCE_BANDING;
  180. }
  181. else
  182. {
  183. pPDev->fMode &= ~PF_FORCE_BANDING;
  184. }
  185. #endif //DO_LATER
  186. return TRUE;
  187. }
  188. //
  189. //
  190. // Initialization sub functions
  191. //
  192. // BInitFontPDev
  193. // BBuildFontCartTable
  194. // BRegReadFontCarts
  195. // BInitDeviceFontsFromGPD
  196. // BBuildFontMapTable
  197. // BFMInitDevInfo
  198. // BInitGDIInfo
  199. // BInitStandardVariable
  200. //
  201. BOOL
  202. BInitFontPDev(
  203. PDEV *pPDev
  204. )
  205. /*++
  206. Routine Description:
  207. This routine allocates the FONTPDEV and initializes various fileds.
  208. Arguments:
  209. pPDev - Pointer to PDEV.
  210. Return Value:
  211. TRUE - for success
  212. FALSE - for failure
  213. Note:
  214. 11-18-96: Created it -ganeshp-
  215. --*/
  216. {
  217. PFONTPDEV pFontPDev = PFDV;
  218. GLOBALS *pGlobals = pPDev->pGlobals;
  219. DWORD dwSize;
  220. INT iMaxDeviceFonts;
  221. SHORT sOrient;
  222. BOOL bRet = FALSE;
  223. iMaxDeviceFonts = IGetMaxFonts(pPDev);
  224. //
  225. // Allocate the font list buffer.
  226. //
  227. if ( iMaxDeviceFonts &&
  228. !(pFontPDev->FontList.pdwList =
  229. MemAllocZ(iMaxDeviceFonts * sizeof(DWORD))) )
  230. {
  231. ERREXIT("UniFont!BInitFontPDev:Can't Allocate Device Font List");
  232. }
  233. //
  234. // Set the number of entries
  235. //
  236. pFontPDev->FontList.iEntriesCt = 0;
  237. pFontPDev->FontList.iMaxEntriesCt = iMaxDeviceFonts;
  238. //
  239. // Set differnt General Flags
  240. //
  241. if ( pGlobals->bRotateFont)
  242. pFontPDev->flFlags |= FDV_ROTATE_FONT_ABLE;
  243. if ( pGlobals->charpos == CP_BASELINE)
  244. pFontPDev->flFlags |= FDV_ALIGN_BASELINE;
  245. if ( pGlobals->bTTFSEnabled)
  246. pFontPDev->flFlags |= FDV_TT_FS_ENABLED;
  247. //
  248. // Check if Memory should be tracked for font downloading
  249. //
  250. if ( BCheckFontMemUsage(pPDev) )
  251. pFontPDev->flFlags |= FDV_TRACK_FONT_MEM;
  252. //
  253. // Set the Reselect font Flags.
  254. //
  255. VSetReselectFontFlags(pPDev);
  256. if ( pGlobals->printertype == PT_SERIAL ||
  257. pGlobals->printertype == PT_TTY )
  258. pFontPDev->flFlags |= FDV_MD_SERIAL;
  259. //
  260. // The code assumes that COMMANDPTR macro returns NULL if the
  261. // command doesn't exist.
  262. //
  263. if ( COMMANDPTR(pPDev->pDriverInfo, CMD_WHITETEXTON))
  264. pFontPDev->flFlags |= FDV_WHITE_TEXT;
  265. if ( COMMANDPTR(pPDev->pDriverInfo,CMD_SETSIMPLEROTATION ))
  266. pFontPDev->flFlags |= FDV_90DEG_ROTATION;
  267. if ( COMMANDPTR(pPDev->pDriverInfo, CMD_SETANYROTATION))
  268. pFontPDev->flFlags |= FDV_ANYDEG_ROTATION;
  269. if (pPDev->fMode & PF_ANYCOLOR_BRUSH)
  270. pFontPDev->flFlags |= FDV_SUPPORTS_FGCOLOR;
  271. else // Monochrome case
  272. {
  273. //
  274. // PF_ANYCOLOR_BRUSH is set only for color printers with explicit
  275. // colormode. But Monochrome printers can also support dither color
  276. // using downloadable pattern brush. This is a good optimization because
  277. // we will do substitution or download instead of sending the text as
  278. // graphics. For enabling this mode the printer must support
  279. // CmdSelectBlackBrush so that Resetbrush can rest the color to black
  280. // befroe sending raster. So for a monochrome printer if
  281. // CmdSelectBlackBrush, CmdDownloadPattern and CmdSelectPattern
  282. // are supported then we will set FDV_SUPPORTS_FGCOLOR.
  283. //
  284. if ( (pPDev->arCmdTable[CMD_DOWNLOAD_PATTERN] ) &&
  285. (pPDev->arCmdTable[CMD_SELECT_PATTERN]) &&
  286. (pPDev->arCmdTable[CMD_SELECT_BLACKBRUSH])
  287. )
  288. pFontPDev->flFlags |= FDV_SUPPORTS_FGCOLOR;
  289. }
  290. if ( COMMANDPTR(pPDev->pDriverInfo, CMD_UNDERLINEON))
  291. pFontPDev->flFlags |= FDV_UNDERLINE;
  292. //
  293. // Set dwSelection bits
  294. //
  295. sOrient = (pPDev->pdm->dmFields & DM_ORIENTATION) ?
  296. pPDev->pdm->dmOrientation : (SHORT)DMORIENT_PORTRAIT;
  297. if ( sOrient == DMORIENT_LANDSCAPE )
  298. pFontPDev->dwSelBits |= FDH_LANDSCAPE;
  299. else
  300. pFontPDev->dwSelBits |= FDH_PORTRAIT;
  301. //
  302. // If the printer can rotate fonts, then we don't care about
  303. // the orientation of fonts. Hence, set both selection bits.
  304. //
  305. if( pFontPDev->flFlags & FDV_ROTATE_FONT_ABLE )
  306. pFontPDev->dwSelBits |= FDH_PORTRAIT | FDH_LANDSCAPE;
  307. //
  308. // Presume we can always print bitmap fonts, so now add that
  309. // capability.
  310. //
  311. pFontPDev->dwSelBits |= FDH_BITMAP;
  312. //
  313. // Set the Text Scale Fasctor.
  314. //
  315. pFontPDev->ptTextScale.x = pGlobals->ptMasterUnits.x / pPDev->ptTextRes.x;
  316. pFontPDev->ptTextScale.y = pGlobals->ptMasterUnits.y / pPDev->ptTextRes.y;
  317. if ( pGlobals->dwLookaheadRegion )
  318. {
  319. // !!!TODO pFontPDev->flFlags |= FDV_FONT_PERMUTE;
  320. pPDev->dwLookAhead = pGlobals->dwLookaheadRegion /
  321. pFontPDev->ptTextScale.y;
  322. }
  323. //
  324. // Initialize the Text Flag.
  325. //
  326. if (!BInitTextFlags(pPDev) )
  327. {
  328. ERREXIT(("UniFont!BInitFontPDev:Can't initialize Text Flags\n"));
  329. }
  330. //
  331. // Initalize memory to be used by Font Module. If no memory tracking
  332. // has to be done the set the dwFontMem to a big value.
  333. if( (pFontPDev->flFlags & FDV_TRACK_FONT_MEM) )
  334. pFontPDev->dwFontMem = pPDev->dwFreeMem;
  335. //
  336. // If it is set to zero initialize this item to a big value. */
  337. //
  338. if (pFontPDev->dwFontMem == 0)
  339. pFontPDev->dwFontMem = MAXLONG;
  340. //
  341. // No DL font memory used */
  342. //
  343. pFontPDev->dwFontMemUsed = 0;
  344. //
  345. // Set Download specific information, if printer supports it */
  346. //
  347. if (pGlobals->fontformat != UNUSED_ITEM)
  348. {
  349. BOOL bValidFontIDRange;
  350. BOOL bValidGlyphIDRange;
  351. /* Start index */
  352. pFontPDev->iFirstSFIndex = pFontPDev->iNextSFIndex
  353. = pGlobals->dwMinFontID;
  354. pFontPDev->iLastSFIndex = pGlobals->dwMaxFontID;
  355. /*
  356. * There may also be a limit on the number of softfonts that the
  357. * printer can support. If not, the limit is < 0, so when
  358. * we see this, set the value to a large number.
  359. */
  360. if ((pFontPDev->iMaxSoftFonts = (INT)pGlobals->dwMaxFontUsePerPage) < 0)
  361. pFontPDev->iMaxSoftFonts = pFontPDev->iLastSFIndex + 100;
  362. pFontPDev->flFlags |= FDV_DL_INCREMENTAL; //Always incremental.
  363. /*
  364. * Now varify that the font ID range is less that MAXWORD. This is
  365. * necessary, otherwise trunction will happen. We don't download
  366. * if the values are more than MAXWORD.
  367. */
  368. bValidFontIDRange = ((pFontPDev->iFirstSFIndex <= MAXWORD) &&
  369. (pFontPDev->iLastSFIndex <= MAXWORD));
  370. //
  371. // If the downloaded font in not bound to a symbols set(i.e. dlsymbolset
  372. // is not defined), We don't want to download, if there are less than
  373. // 64 glyphs per downloaded font.
  374. //
  375. bValidGlyphIDRange = (pPDev->pGlobals->dlsymbolset != UNUSED_ITEM) ||
  376. ( (pPDev->pGlobals->dlsymbolset == UNUSED_ITEM) &&
  377. ( pPDev->pGlobals->dwMaxGlyphID -
  378. pPDev->pGlobals->dwMinGlyphID) >=
  379. MIN_GLYPHS_PER_SOFTFONT );
  380. /*
  381. * Consider enabling downloading of TT fonts. This is done only
  382. * if text and graphics resolutions are the same - otherwise
  383. * the TT fonts will come out smaller than expected, since they
  384. * will be generated for the lower graphics resolution yet
  385. * printed at the higher text resolution! LaserJet 4 printers
  386. * can also download fonts digitised at 300dpi when operating
  387. * at 600 dpi, so we also accept that as a valid mode.
  388. *
  389. * Also check if the user wants this: if the no cache flag
  390. * is set in the driver extra part of the DEVMODE structure,
  391. * then we also do not set this flag.
  392. */
  393. VERBOSE(("pPDev->pdm->dmTTOption is %d\n",pPDev->pdm->dmTTOption));
  394. if( ( POINTEQUAL(pPDev->ptGrxRes,pPDev->ptTextRes) ||
  395. (pPDev->ptGrxRes.x >= 300 && pPDev->ptGrxRes.y >= 300))
  396. && (bValidFontIDRange)
  397. && (bValidGlyphIDRange)
  398. && (!(pPDev->fMode2 & PF2_MIRRORING_ENABLED))
  399. && (!(pPDev->pdmPrivate->dwFlags & DXF_TEXTASGRAPHICS ))
  400. )
  401. {
  402. //
  403. // Conditions have been met, so set the flag
  404. // Check the application preference.
  405. //
  406. if( (pPDev->pdm->dmFields & DM_TTOPTION) &&
  407. (pPDev->pdm->dmTTOption != DMTT_BITMAP)
  408. )
  409. {
  410. pFontPDev->flFlags |= FDV_DLTT;
  411. //
  412. // Find Out if Download TT as TT is available or not. We only
  413. // want to do this if text and graphics resolutions are same.
  414. //
  415. if ( POINTEQUAL(pPDev->ptGrxRes,pPDev->ptTextRes) )
  416. {
  417. if (pPDev->ePersonality == kPCLXL)
  418. pFontPDev->flFlags |= FDV_DLTT_OEMCALLBACK;
  419. else
  420. if ( (pGlobals->fontformat == FF_HPPCL_OUTLINE) )
  421. /*!!!TODO Enable after parser add this command &&
  422. (COMMANDPTR(pPDev->pDriverInfo, CMD_SELECTFONTHEIGHT))*/
  423. {
  424. //
  425. // We assume that if the printer support TT as outline,
  426. // then TT as Bitmap format is also supported. We only
  427. // support TrueType outline if font height selection
  428. // command is present, else we assume download as
  429. // bitmap.
  430. //
  431. pFontPDev->flFlags |= FDV_DLTT_ASTT_PREF;
  432. }
  433. else if ( pGlobals->fontformat == FF_OEM_CALLBACK)
  434. pFontPDev->flFlags |= FDV_DLTT_OEMCALLBACK;
  435. else //OEM CallBack
  436. pFontPDev->flFlags |= FDV_DLTT_BITM_PREF;
  437. //
  438. // We also need to check the memory. For printers with
  439. // less than 2MB of free memory, download as TT outline
  440. // will be disabled.
  441. //
  442. if (pFontPDev->flFlags & FDV_DLTT_ASTT_PREF)
  443. {
  444. if (pPDev->dwFreeMem < (2L * ONE_MBYTE))
  445. {
  446. pFontPDev->flFlags &= ~FDV_DLTT_ASTT_PREF;
  447. pFontPDev->flFlags |= FDV_DLTT_BITM_PREF;
  448. }
  449. }
  450. }
  451. }
  452. }
  453. }
  454. //
  455. // Initialize the Font state control structure */
  456. //
  457. pFontPDev->ctl.iSoftFont = -1;
  458. pFontPDev->ctl.iFont = INVALID_FONT;
  459. pFontPDev->ctl.dwAttrFlags = 0;
  460. pFontPDev->ctl.iRotate = 0;
  461. pFontPDev->ctl.pfm = NULL;
  462. //
  463. // Set the White and Black Ref Color
  464. //
  465. pFontPDev->iWhiteIndex = ((PAL_DATA*)(pPDev->pPalData))->iWhiteIndex;
  466. pFontPDev->iBlackIndex = ((PAL_DATA*)(pPDev->pPalData))->iBlackIndex;
  467. //
  468. // Initialize font substitution table from a registry.
  469. //
  470. pFontPDev->pTTFontSubReg = PGetTTSubstTable(pPDev->devobj.hPrinter, &dwSize);
  471. if (pPDev->pGlobals->bTTFSEnabled &&
  472. ( (pFontPDev->pTTFontSubReg &&
  473. *((PDWORD)pFontPDev->pTTFontSubReg) != 0) ||
  474. (!pFontPDev->pTTFontSubReg &&
  475. (INT)pPDev->pDriverInfo->DataType[DT_FONTSUBST].dwCount )
  476. )
  477. )
  478. //
  479. // Check if GPD supports "*TTFSEnableD?: TRUE"
  480. // if there is a substitution table in registry
  481. // if there is a default substitution table in GPD.
  482. //
  483. {
  484. pFontPDev->flFlags |= FDV_SUBSTITUTE_TT;
  485. }
  486. else
  487. {
  488. pFontPDev->flFlags &= ~FDV_SUBSTITUTE_TT;
  489. }
  490. //
  491. // Enable/Disable partial clipping
  492. //
  493. if (S_FALSE != PartialClipOn(pPDev))
  494. pFontPDev->flFlags |= FDV_ENABLE_PARTIALCLIP;
  495. else
  496. pFontPDev->flFlags &= ~FDV_ENABLE_PARTIALCLIP;
  497. //
  498. // store some members of pGlobals to save the memory allocation
  499. //
  500. pFontPDev->sDefCTT = (SHORT)pPDev->pGlobals->dwDefaultCTT;
  501. pFontPDev->dwDefaultFont = pPDev->pGlobals->dwDefaultFont;
  502. //
  503. // For TTY driver ask the minidriver for user selection of code page.
  504. //
  505. if ( pPDev->bTTY )
  506. {
  507. BOOL bOEMinfo;
  508. INT iTTYCodePageInfo;
  509. DWORD cbcNeeded;
  510. PFN_OEMTTYGetInfo pfnOemTTYGetInfo;
  511. iTTYCodePageInfo = 0;
  512. bOEMinfo = FALSE ;
  513. FIX_DEVOBJ(pPDev, EP_OEMTTYGetInfo);
  514. if(pPDev->pOemEntry)
  515. {
  516. if( ((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem ) // OEM plug in uses COM and function is implemented.
  517. {
  518. HRESULT hr ;
  519. hr = HComTTYGetInfo((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  520. (PDEVOBJ)pPDev, OEMTTY_INFO_CODEPAGE, &iTTYCodePageInfo, sizeof(INT), &cbcNeeded);
  521. if( SUCCEEDED(hr))
  522. bOEMinfo = TRUE ;
  523. }
  524. else if((pfnOemTTYGetInfo = (PFN_OEMTTYGetInfo)pPDev->pOemHookInfo[EP_OEMTTYGetInfo].pfnHook) &&
  525. (pfnOemTTYGetInfo((PDEVOBJ)pPDev, OEMTTY_INFO_CODEPAGE, &iTTYCodePageInfo, sizeof(INT), &cbcNeeded)))
  526. bOEMinfo = TRUE ;
  527. }
  528. if(bOEMinfo)
  529. {
  530. //
  531. // predefined GTT ID case
  532. //
  533. if (iTTYCodePageInfo < 0)
  534. {
  535. pFontPDev->sDefCTT = (SHORT)iTTYCodePageInfo;
  536. switch (iTTYCodePageInfo)
  537. {
  538. case CC_CP437:
  539. pFontPDev->dwTTYCodePage = 437;
  540. break;
  541. case CC_CP850:
  542. pFontPDev->dwTTYCodePage = 850;
  543. break;
  544. case CC_CP863:
  545. pFontPDev->dwTTYCodePage = 863;
  546. break;
  547. }
  548. }
  549. else
  550. {
  551. pFontPDev->dwTTYCodePage = iTTYCodePageInfo;
  552. switch (iTTYCodePageInfo)
  553. {
  554. case 936:
  555. pFontPDev->sDefCTT = CC_GB2312;
  556. break;
  557. case 950:
  558. pFontPDev->sDefCTT = CC_BIG5;
  559. break;
  560. case 949:
  561. pFontPDev->sDefCTT = CC_WANSUNG;
  562. break;
  563. case 932:
  564. pFontPDev->sDefCTT = CC_SJIS;
  565. break;
  566. default:
  567. pFontPDev->sDefCTT = 0;
  568. break;
  569. }
  570. }
  571. }
  572. }
  573. //
  574. // All Success
  575. //
  576. bRet = TRUE;
  577. ErrorExit:
  578. return bRet;
  579. }
  580. BOOL
  581. BBuildFontCartTable(
  582. PDEV *pPDev
  583. )
  584. /*++
  585. Routine Description:
  586. Builds the Fontcart Table. It reads the minidriver and get the
  587. FontCart string and the corresponding indexes and put them in the
  588. FontCart Table.
  589. Arguments:
  590. pPDev - Pointer to PDEV.
  591. Return Value:
  592. TRUE - for success
  593. FALSE - for failure
  594. Note:
  595. 11-18-96: Created it -ganeshp-
  596. --*/
  597. {
  598. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  599. INT iNumAllCartridges;
  600. INT iIndex;
  601. PFONTCARTMAP *ppFontCartMap = &(pFontPDev->FontCartInfo.pFontCartMap);
  602. WINRESDATA *pWinResData = &(pPDev->WinResData);
  603. GPDDRIVERINFO *pDriverInfo = pPDev->pDriverInfo; // GPDDRVINFO
  604. FONTCART *pFontCart ;
  605. /* Read the total number of Font Cartridges supported */
  606. iNumAllCartridges = pFontPDev->FontCartInfo.iNumAllFontCarts
  607. = (INT)(pDriverInfo->DataType[DT_FONTSCART].dwCount);
  608. pFontPDev->FontCartInfo.dwFontCartSlots = pPDev->pGlobals->dwFontCartSlots;
  609. /* FONTCARTS are stored as arrayref and are contiguous. Get to the start
  610. * start of the array.
  611. */
  612. pFontCart = GETFONTCARTARRAY(pDriverInfo);
  613. if (iNumAllCartridges)
  614. *ppFontCartMap = MemAllocZ(iNumAllCartridges * sizeof(FONTCARTMAP) );
  615. else
  616. *ppFontCartMap = NULL;
  617. if(*ppFontCartMap)
  618. {
  619. PFONTCARTMAP pTmpFontCartMap = *ppFontCartMap; /* Temp Pointer */
  620. for( iIndex = 0; iIndex < iNumAllCartridges ;
  621. pTmpFontCartMap++, pFontCart++, iIndex++ )
  622. {
  623. if ( !ARF_IS_NULLSTRING(pFontCart->strCartName) )
  624. {
  625. wcsncpy( (PWSTR)(&(pTmpFontCartMap->awchFontCartName)),
  626. GETSTRING(pDriverInfo, (pFontCart->strCartName)),
  627. MAXCARTNAMELEN - 1);
  628. }
  629. else if ((ILoadStringW( pWinResData, pFontCart->dwRCCartNameID,
  630. (PWSTR)(&(pTmpFontCartMap->awchFontCartName)),
  631. (MAXCARTNAMELEN ))) == 0)
  632. {
  633. ERR(("\n UniFont!bBuildFontCartTable:FontCart Name not found\n") );
  634. continue;
  635. }
  636. pTmpFontCartMap->pFontCart = pFontCart;
  637. VERBOSE(("\n UniFont!bBuildFontCartTable:(pTmpFontCartMap->awchFontCartName)= %ws\n", (pTmpFontCartMap->awchFontCartName)));
  638. VERBOSE(("UniFont!bBuildFontCartTable:pTmpFontCartMap->pFontCart= %p\n", (pTmpFontCartMap->pFontCart)));
  639. }
  640. }
  641. else if (iNumAllCartridges)
  642. {
  643. ERR(("UniFont!bBuildFontCartTable:HeapAlloc for FONTCARTMAP table failed!!\n") );
  644. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  645. return FALSE ;
  646. }
  647. return TRUE ;
  648. }
  649. BOOL
  650. BInitDeviceFontsFromGPD(
  651. PDEV *pPDev
  652. )
  653. /*++
  654. Routine Description:
  655. This routine builds the device font list. The list include device resident
  656. fonts and the fonts specific to installed cartridges.
  657. Arguments:
  658. pPDev - Pointer to PDEV.
  659. Return Value:
  660. TRUE - for success
  661. FALSE - for failure
  662. Note:
  663. 11-18-96: Created it -ganeshp-
  664. --*/
  665. {
  666. BOOL bRet = FALSE;
  667. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  668. PDWORD pdwList = pFontPDev->FontList.pdwList;
  669. PLISTNODE pListNode;
  670. PINT piFontCt = &(pFontPDev->FontList.iEntriesCt);
  671. //
  672. // The List of Fonts is stored in PDEV. GLOBALS.dwDeviceFontList is
  673. // Offset to the ListNode. Macro LISTNODEPTR will return a pointer
  674. // to the ListNode. Then we have to traverse the list and build the
  675. // font list. Font module stores the font list as an array of WORDS.
  676. // Each of these is a resource Id of the font. The array is NULL
  677. // terminated.
  678. //
  679. if (pPDev->bTTY)
  680. {
  681. PFN_OEMTTYGetInfo pfnOemTTYGetInfo;
  682. DWORD cbcNeeded, dwNumOfFonts;
  683. //
  684. // TTY driver case
  685. // TTY driver supports 3 fonts. According to the current selected
  686. // codepage, TTY driver returns appropriate font resource IDs.
  687. // UNIDRV stores these IDs in pdwList.
  688. //
  689. if (pPDev->pOemEntry)
  690. {
  691. ASSERT(pdwList);
  692. if (((POEM_PLUGIN_ENTRY)pPDev->pOemEntry)->pIntfOem)
  693. {
  694. HRESULT hr;
  695. hr = HComTTYGetInfo((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  696. (PDEVOBJ)pPDev,
  697. OEMTTY_INFO_NUM_UFMS,
  698. &dwNumOfFonts,
  699. sizeof(DWORD),
  700. &cbcNeeded);
  701. if( SUCCEEDED(hr) && dwNumOfFonts <= MAXDEVFONT)
  702. {
  703. hr = HComTTYGetInfo((POEM_PLUGIN_ENTRY)pPDev->pOemEntry,
  704. (PDEVOBJ)pPDev,
  705. OEMTTY_INFO_UFM_IDS,
  706. pdwList,
  707. sizeof(DWORD) * dwNumOfFonts,
  708. &cbcNeeded);
  709. if( SUCCEEDED(hr))
  710. {
  711. *piFontCt += dwNumOfFonts;
  712. pFontPDev->dwDefaultFont = *pdwList;
  713. }
  714. }
  715. }
  716. else
  717. {
  718. if((pfnOemTTYGetInfo = (PFN_OEMTTYGetInfo)pPDev->pOemHookInfo[EP_OEMTTYGetInfo].pfnHook) &&
  719. (pfnOemTTYGetInfo((PDEVOBJ)pPDev, OEMTTY_INFO_NUM_UFMS, &dwNumOfFonts, sizeof(DWORD), &cbcNeeded)) &&
  720. (dwNumOfFonts <= MAXDEVFONT) &&
  721. (pfnOemTTYGetInfo((PDEVOBJ)pPDev, OEMTTY_INFO_UFM_IDS, pdwList, sizeof(DWORD) * dwNumOfFonts, &cbcNeeded)))
  722. {
  723. *piFontCt += dwNumOfFonts;
  724. pFontPDev->dwDefaultFont = *pdwList;
  725. }
  726. }
  727. }
  728. }
  729. else
  730. {
  731. if (pListNode = LISTNODEPTR(pPDev->pDriverInfo , pPDev->pGlobals->liDeviceFontList ) )
  732. {
  733. ASSERT(pdwList);
  734. while (pListNode)
  735. {
  736. //
  737. // Check the Font Resource ID. It shouldn't be NULL.
  738. //
  739. if (!pListNode->dwData)
  740. {
  741. ERREXIT("Bad Font Resource Id");
  742. }
  743. //
  744. // Store the Font Resource ID in the List Array.
  745. //
  746. *pdwList++ = pListNode->dwData;
  747. (*piFontCt)++;
  748. pListNode = LISTNODEPTR(pPDev->pDriverInfo, pListNode->dwNextItem);
  749. }
  750. }
  751. }
  752. pFontPDev->iDevResFontsCt = *piFontCt;
  753. //
  754. // Add Cartridge Fonts. By this time we have scanned the regitry and know
  755. //
  756. // which fontcartridges has been installed. All we have have to do is
  757. // go through each font cartriges font list and add them to our list.
  758. //
  759. if (pFontPDev->FontCartInfo.iNumInstalledCarts)
  760. {
  761. INT iNumAllCartridges, iI;
  762. FONTCARTMAP *pFontCartMap; /* FontCart Map Pointer */
  763. SHORT sOrient;
  764. pFontCartMap = (pFontPDev->FontCartInfo.pFontCartMap);
  765. iNumAllCartridges = pFontPDev->FontCartInfo.iNumAllFontCarts;
  766. sOrient = (pPDev->pdm->dmFields & DM_ORIENTATION) ?
  767. pPDev->pdm->dmOrientation : (SHORT)DMORIENT_PORTRAIT;
  768. //
  769. // The logic is very simple. Installed font Cartridges are marked in
  770. // the Font Cartridge mapping table. We go through the mapping table
  771. // and for each installed cartridges we get the font list and add them
  772. // to our list.
  773. //
  774. for( iI = 0; iI < iNumAllCartridges ; iI++,pFontCartMap++ )
  775. {
  776. if (pFontCartMap->bInstalled == TRUE )
  777. {
  778. //
  779. // Check for Orientation, as there can be different font list
  780. // for different orientation.
  781. //
  782. if ( sOrient == DMORIENT_LANDSCAPE )
  783. {
  784. pListNode = LISTNODEPTR(pPDev->pDriverInfo ,
  785. pFontCartMap->pFontCart->dwLandFontLst );
  786. }
  787. else
  788. {
  789. pListNode = LISTNODEPTR(pPDev->pDriverInfo ,
  790. pFontCartMap->pFontCart->dwPortFontLst );
  791. }
  792. while (pListNode)
  793. {
  794. //
  795. // Check the Font Resource ID. It shouldn't be NULL.
  796. //
  797. if (!pListNode->dwData)
  798. {
  799. ERREXIT("Bad Font Resource Id");
  800. }
  801. //
  802. //Store the Font Resource ID in the List Array.
  803. //
  804. *pdwList++ = pListNode->dwData;
  805. (*piFontCt)++;
  806. pListNode = LISTNODEPTR(pPDev->pDriverInfo,
  807. pListNode->dwNextItem);
  808. }
  809. }
  810. }
  811. }
  812. //
  813. // Update the count of all device fonts
  814. //
  815. pFontPDev->iDevFontsCt += *piFontCt;
  816. //
  817. // All Success
  818. //
  819. if (pFontPDev->FontCartInfo.pFontCartMap)
  820. MEMFREEANDRESET(pFontPDev->FontCartInfo.pFontCartMap);
  821. bRet = TRUE;
  822. ErrorExit:
  823. return bRet;
  824. }
  825. BOOL
  826. BBuildFontMapTable(
  827. PDEV *pPDev
  828. )
  829. /*++
  830. Routine Description:
  831. Build a table of fonts available on this model.
  832. Each entry in this table is an atom for the facename followed
  833. by TEXTMETRIC structure. This table will accelerate font
  834. enumeration and font realization. This routine is responsible
  835. for allocating the global memory needed to store the table.
  836. It also has 2 OCD's to select/unselect each font
  837. Arguments:
  838. pPDev - Pointer to PDEV.
  839. Return Value: None
  840. Note:
  841. 11-18-96: Created it -ganeshp-
  842. --*/
  843. {
  844. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  845. PDWORD pdwFontList = pFontPDev->FontList.pdwList;
  846. //
  847. // Basic idea here is to generate a bit array indicating which of
  848. // the minidriver fonts are available for this printer in it's
  849. // current mode. This is saved in the UD_PDEV, and will be filled in
  850. // as required later, during DrvQueryFont, if this is required.
  851. //
  852. //
  853. // If no hardware font is available, give up now!
  854. //
  855. if( !(pFontPDev->flText & ~TC_RA_ABLE) )
  856. return TRUE;
  857. // At this point we check for reasons why not to use device fonts.
  858. // We disable device fonts for n-up printing on serial devices because they
  859. // typically can't scale their fonts
  860. //
  861. if( ( !pPDev->bTTY ) &&
  862. ( (pPDev->pdmPrivate->dwFlags & DXF_TEXTASGRAPHICS ) ||
  863. #ifndef WINNT_40
  864. (pPDev->pdmPrivate->iLayout != ONE_UP &&
  865. pPDev->pGlobals->printertype == PT_SERIAL &&
  866. pPDev->pGlobals->bRotateRasterData == FALSE) ||
  867. #endif
  868. (pPDev->fMode2 & PF2_MIRRORING_ENABLED) ||
  869. ((pPDev->pdm->dmFields & DM_TTOPTION) &&
  870. (pPDev->pdm->dmTTOption == DMTT_BITMAP)) ) )
  871. {
  872. return TRUE;
  873. }
  874. /*
  875. * That's all we need do during DrvEnablePDEV time. We now know
  876. * which fonts are available, and there was little effort involved.
  877. * This data is now saved away, and will be acted upon as and when
  878. * GDI comes and asks us about fonts.
  879. */
  880. pPDev->iFonts = (UINT)(-1); /* Tells GDI about lazy evaluation */
  881. IInitDeviceFonts( pPDev );
  882. //
  883. // Initialize font substitution flag.
  884. // Check if this printer supports any device font.
  885. //
  886. if (pPDev->iFonts <= 0 &&
  887. pFontPDev->flFlags & FDV_SUBSTITUTE_TT)
  888. {
  889. pFontPDev->flFlags &= ~FDV_SUBSTITUTE_TT;
  890. }
  891. return TRUE;
  892. }
  893. BOOL
  894. BFMInitDevInfo(
  895. DEVINFO *pDevInfo,
  896. PDEV *pPDev
  897. )
  898. /*++
  899. Routine Description:
  900. This routine intializes the font specific fileds of DevInfo.
  901. Arguments:
  902. pDevInfo - Pointer to DEVINFO to be initialized.
  903. pPDev - Pointer to PDEV.
  904. Return Value:
  905. TRUE - for success
  906. FALSE - for failure
  907. Note:
  908. 12-11-96: Created it -ganeshp-
  909. --*/
  910. {
  911. CHARSETINFO ci;
  912. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  913. FONTMAP *pFMDefault;
  914. BOOL bSetTrueType;
  915. bSetTrueType = TRUE;
  916. pFMDefault = pFontPDev->pFMDefault;
  917. pDevInfo->flGraphicsCaps |= GCAPS_SCREENPRECISION | GCAPS_FONT_RASTERIZER;
  918. if (!PrdTranslateCharsetInfo(PrdGetACP(), &ci, TCI_SRCCODEPAGE))
  919. ci.ciCharset = ANSI_CHARSET;
  920. if( pDevInfo->cFonts = pPDev->iFonts )
  921. {
  922. //
  923. // Device fonts are available, so set the default font data
  924. //
  925. if( pFMDefault &&
  926. ((IFIMETRICS*)pFMDefault->pIFIMet)->jWinCharSet == ci.ciCharset)
  927. {
  928. VLogFont(&pPDev->ptTextRes, &(pDevInfo->lfDefaultFont), pFontPDev->pFMDefault );
  929. bSetTrueType = FALSE;
  930. }
  931. //
  932. //Initialize the Hooks flag.
  933. //
  934. pPDev->fHooks |= HOOK_TEXTOUT;
  935. }
  936. //
  937. // Always switch off TC_RA_ABLE flag
  938. //
  939. pFontPDev->flText &= ~TC_RA_ABLE;
  940. if (bSetTrueType)
  941. {
  942. pDevInfo->lfDefaultFont.lfCharSet = (BYTE)ci.ciCharset;
  943. ZeroMemory( pDevInfo->lfDefaultFont.lfFaceName,
  944. sizeof ( pDevInfo->lfDefaultFont.lfFaceName ));
  945. }
  946. ZeroMemory( &pDevInfo->lfAnsiVarFont, sizeof( LOGFONT ) );
  947. ZeroMemory( &pDevInfo->lfAnsiFixFont, sizeof( LOGFONT ) );
  948. return TRUE ;
  949. }
  950. BOOL
  951. BInitGDIInfo(
  952. GDIINFO *pGDIInfo,
  953. PDEV *pPDev
  954. )
  955. /*++
  956. Routine Description:
  957. This routine intializes the font specific fileds of GdiInfo.
  958. Arguments:
  959. pGDIInfo - Pointer to GDIINFO to be initialized.
  960. pPDev - Pointer to PDEV.
  961. Return Value:
  962. TRUE - for success
  963. FALSE - for failure
  964. Note:
  965. 12-11-96: Created it -ganeshp-
  966. --*/
  967. {
  968. pGDIInfo->flTextCaps = PFDV->flText;
  969. return TRUE;
  970. }
  971. BOOL
  972. BInitStandardVariable(
  973. PDEV *pPDev)
  974. {
  975. //
  976. // Initialize the Standard Variable, Just for sanity
  977. //
  978. pPDev->dwPrintDirection =
  979. pPDev->dwNextFontID =
  980. pPDev->dwNextGlyph =
  981. pPDev->dwFontHeight =
  982. pPDev->dwFontWidth =
  983. pPDev->dwFontBold =
  984. pPDev->dwFontItalic =
  985. pPDev->dwFontUnderline =
  986. pPDev->dwFontStrikeThru =
  987. pPDev->dwCurrentFontID = 0;
  988. return TRUE;
  989. }
  990. //
  991. //
  992. // Misc functions
  993. //
  994. //
  995. VOID
  996. VLogFont(
  997. POINT *pptTextRes,
  998. LOGFONT *pLF,
  999. FONTMAP *pFM
  1000. )
  1001. /*++
  1002. Routine Description:
  1003. Turn an IFIMETRICS structure into a LOGFONT structure, for whatever
  1004. reason this is needed.
  1005. Arguments:
  1006. pLF - Output is a LOGFONT.
  1007. pFM - Input is a FONTMAP.
  1008. Return Value: None
  1009. Note:
  1010. 12-11-96: Created it -ganeshp-
  1011. --*/
  1012. {
  1013. /*
  1014. * Convert from IFIMETRICS to LOGFONT type structure.
  1015. */
  1016. int iLen; /* Loop variable */
  1017. IFIMETRICS *pIFI;
  1018. WCHAR *pwch; /* Address of face name */
  1019. pIFI = pFM->pIFIMet; /* The BIG metrics */
  1020. pLF->lfHeight = pIFI->fwdWinAscender + pIFI->fwdWinDescender;
  1021. pLF->lfWidth = pIFI->fwdAveCharWidth;
  1022. /*
  1023. * Note that this may be a scalable font, in which case we pick a
  1024. * reasonable number!
  1025. */
  1026. if( pIFI->flInfo & (FM_INFO_ISOTROPIC_SCALING_ONLY|FM_INFO_ANISOTROPIC_SCALING_ONLY|FM_INFO_ARB_XFORMS))
  1027. {
  1028. /*
  1029. * Invent an arbitrary size. We choose an approximately 10 point
  1030. * font. The height is achieved easily, as we simply set the
  1031. * height based on the device resolution! For the width, adjust
  1032. * it using the same factor as we used on the height. This
  1033. * assumes that the resolution is the same in both directions,
  1034. * but this is reasonable given laser printers are the most
  1035. * common with scalable fonts.
  1036. */
  1037. //
  1038. // Needs to reflect a current resolution.
  1039. //
  1040. pLF->lfHeight = pptTextRes->x / 7; /* This is about 10 points */
  1041. pLF->lfWidth = (2 * pLF->lfHeight * pptTextRes->y) /
  1042. (3 * pptTextRes->y);
  1043. }
  1044. pLF->lfEscapement = 0;
  1045. pLF->lfOrientation = 0;
  1046. pLF->lfWeight = pIFI->usWinWeight;
  1047. pLF->lfItalic = (BYTE)((pIFI->fsSelection & FM_SEL_ITALIC) ? 1 : 0);
  1048. pLF->lfUnderline = (BYTE)((pIFI->fsSelection & FM_SEL_UNDERSCORE) ? 1 : 0);
  1049. pLF->lfStrikeOut = (BYTE)((pIFI->fsSelection & FM_SEL_STRIKEOUT) ? 1 : 0);
  1050. pLF->lfCharSet = pIFI->jWinCharSet;
  1051. pLF->lfOutPrecision = OUT_DEFAULT_PRECIS;
  1052. pLF->lfClipPrecision = CLIP_DEFAULT_PRECIS;
  1053. pLF->lfQuality = DEFAULT_QUALITY;
  1054. pLF->lfPitchAndFamily = pIFI->jWinPitchAndFamily;
  1055. /*
  1056. * Copy the face name, after figuring out it's address!
  1057. */
  1058. pwch = (WCHAR *)((BYTE *)pIFI + pIFI->dpwszFaceName);
  1059. iLen = min( wcslen( pwch ), LF_FACESIZE - 1 );
  1060. wcsncpy( pLF->lfFaceName, pwch, iLen );
  1061. pLF->lfFaceName[ iLen ] = (WCHAR)0;
  1062. return;
  1063. }
  1064. BOOL
  1065. BInitTextFlags(
  1066. PDEV *pPDev
  1067. )
  1068. /*++
  1069. Routine Description:
  1070. Arguments:
  1071. pPDev Pointer to PDEV
  1072. Return Value:
  1073. TRUE for success and FALSE for failure
  1074. Note:
  1075. 11-18-96: Created it -ganeshp-
  1076. --*/
  1077. {
  1078. BOOL bRet = FALSE;
  1079. PLISTNODE pListNode;
  1080. DWORD flText = 0;
  1081. TRACE(UniFont!BInitTextFlags:START);
  1082. if (pListNode = LISTNODEPTR(pPDev->pDriverInfo ,
  1083. pPDev->pGlobals->liTextCaps ) )
  1084. {
  1085. while (pListNode)
  1086. {
  1087. // Check the Text Flag. It shouldn't be < 0 or greater than 32.
  1088. if ( ((INT)pListNode->dwData < 0) ||
  1089. (pListNode->dwData > DWBITS) )
  1090. ERREXIT("UniFont!BInitTextFlags:Bad FText Flag Value\n");
  1091. //Set the corresponding bit in fText
  1092. flText |= 1 << pListNode->dwData;
  1093. pListNode = LISTNODEPTR(pPDev->pDriverInfo,pListNode->dwNextItem);
  1094. }
  1095. }
  1096. PRINTVAL(flText,0x%x);
  1097. // If there is a TextCAP List, Modify the text flags as needed.
  1098. if (flText)
  1099. {
  1100. /* Switch off TC_RA_ABLE if text resolution is different than graphics
  1101. * resolution. Rasdd code does this.
  1102. */
  1103. if (!POINTEQUAL(pPDev->ptGrxRes,pPDev->ptTextRes))
  1104. flText &= ~TC_RA_ABLE;
  1105. /* NOTE: IF WE DO NOT HAVE RELATIVE MOVE COMMANDS, TURN OF THE
  1106. * TC_CR_90 BIT IN fTextCaps. THE ROTATED TEXT CODE ASSUMES THIS
  1107. * FUNCTIONALITY IS AVAILABLE, SO DISABLE IT IF NOT THERE. This does
  1108. * not usually happen, as the only printers with the TC_CR_90
  1109. * bit set are LJ III and 4 models, which have the relative move
  1110. * commands available.
  1111. */
  1112. if ( (COMMANDPTR(pPDev->pDriverInfo, CMD_XMOVERELLEFT) == NULL) ||
  1113. (COMMANDPTR(pPDev->pDriverInfo, CMD_XMOVERELRIGHT) == NULL) ||
  1114. (COMMANDPTR(pPDev->pDriverInfo, CMD_YMOVERELUP) == NULL) ||
  1115. (COMMANDPTR(pPDev->pDriverInfo, CMD_YMOVERELDOWN) == NULL) ||
  1116. (COMMANDPTR(pPDev->pDriverInfo, CMD_SETSIMPLEROTATION) == NULL) )
  1117. {
  1118. flText &= ~TC_CR_90;
  1119. flText &= ~TC_CR_ANY;
  1120. }
  1121. else if ((COMMANDPTR(pPDev->pDriverInfo, CMD_SETANYROTATION) == NULL))
  1122. {
  1123. flText &= ~TC_CR_ANY;
  1124. }
  1125. //
  1126. // Text rotation hack
  1127. // Disable text rotation except PCL XL driver
  1128. //
  1129. if (pPDev->ePersonality != kPCLXL)
  1130. {
  1131. flText &= ~(TC_CR_ANY|TC_CR_90);
  1132. }
  1133. }
  1134. PFDV->flText = flText;
  1135. bRet = TRUE;
  1136. ErrorExit:
  1137. TRACE(UniFont!BInitTextFlags:END);
  1138. return bRet;
  1139. }
  1140. BOOL
  1141. BRegReadFontCarts(
  1142. PDEV *pPDev /* PDEV to fill in */
  1143. )
  1144. /*++
  1145. Routine Description:
  1146. Read FontCart data form registry and Update the
  1147. it in the in incoming devmode,
  1148. Arguments:
  1149. pPDev - Pointer to PDEV.
  1150. Return Value:
  1151. TRUE - for success
  1152. FALSE - for failure
  1153. Note:
  1154. 11-25-96: Created it -ganeshp-
  1155. --*/
  1156. {
  1157. FONTCARTMAP *pFontCartMap, *pTmpFontCartMap; /* FontCart Map Pointer */
  1158. PFONTPDEV pFontPDev; /* FONTPDEV access */
  1159. int iNumAllCartridges; /* Total Number of Font Carts */
  1160. HANDLE hPrinter; /* Printer Handle */
  1161. int iI; /* Loop index */
  1162. DWORD dwType; /* Registry access information */
  1163. DWORD cbNeeded; /* Extra parameter to GetPrinterData */
  1164. DWORD dwErrCode = 0; /* Error Code from GetPrinterData */
  1165. int iRemBuffSize = 0 ; /* Used size of the Buffer */
  1166. WCHAR *pwchBuffPtr = NULL; /* buffer Pointer */
  1167. WCHAR *pwchCurrBuffPtr = NULL;/* Current position buffer Pointer */
  1168. //Initialize the variables.
  1169. hPrinter = pPDev->devobj.hPrinter;
  1170. pFontPDev = pPDev->pFontPDev;
  1171. pFontCartMap = (pFontPDev->FontCartInfo.pFontCartMap);
  1172. iNumAllCartridges = pFontPDev->FontCartInfo.iNumAllFontCarts;
  1173. pFontPDev->FontCartInfo.iNumInstalledCarts = 0;
  1174. /* If No FontCartriges are supported return TRUE */
  1175. if (!iNumAllCartridges)
  1176. {
  1177. //
  1178. // This is a valid case. Only external cartridges may be supported.
  1179. //
  1180. return(TRUE);
  1181. }
  1182. dwType = REG_MULTI_SZ;
  1183. if( ( dwErrCode = EngGetPrinterData( hPrinter, REGVAL_FONTCART, &dwType,
  1184. NULL, 0, &cbNeeded ) ) != ERROR_SUCCESS )
  1185. {
  1186. if( (dwErrCode != ERROR_INSUFFICIENT_BUFFER) &&
  1187. (dwErrCode != ERROR_MORE_DATA) )
  1188. {
  1189. //
  1190. // Check for the ERROR_FILE_NOT_FOUND. It's OK not to have the key.
  1191. //
  1192. if (dwErrCode != ERROR_FILE_NOT_FOUND)
  1193. {
  1194. WARNING(( "UniFont!bRegReadFontCarts:GetPrinterData(FontCart First Call) fails: Errcode = %ld\n",dwErrCode) );
  1195. EngSetLastError(dwErrCode);
  1196. }
  1197. return(TRUE);
  1198. }
  1199. else
  1200. {
  1201. if( !cbNeeded ||
  1202. !(pwchCurrBuffPtr = pwchBuffPtr =(WCHAR *)MemAllocZ(cbNeeded)) )
  1203. {
  1204. ERR(( "UniFont!MemAllocZ(FontCart) failed, cbNeeded = %d:\n", cbNeeded));
  1205. return(FALSE);
  1206. }
  1207. }
  1208. VERBOSE(("\n UniFont!bRegReadFontCarts:Size of buffer needed (1) = %d\n",cbNeeded));
  1209. if( ( dwErrCode = EngGetPrinterData( hPrinter, REGVAL_FONTCART, &dwType,
  1210. (BYTE *)pwchBuffPtr, cbNeeded,
  1211. &cbNeeded) ) != ERROR_SUCCESS )
  1212. {
  1213. ERR(( "UniFont!bRegReadFontCarts:GetPrinterData(FontCart Second Call) fails: errcode = %ld\n",dwErrCode) );
  1214. ERR(( " :Size of buffer needed (2) = %d\n",cbNeeded));
  1215. /* Free the Heap */
  1216. if( pwchBuffPtr )
  1217. MEMFREEANDRESET( pwchBuffPtr );
  1218. EngSetLastError(dwErrCode);
  1219. return(FALSE);
  1220. }
  1221. }
  1222. else
  1223. {
  1224. //
  1225. // We could not get the FONTCART path.
  1226. //
  1227. return FALSE;
  1228. }
  1229. VERBOSE(("UniFont!bRegReadFontCarts:Size of buffer read = %d\n",cbNeeded));
  1230. /* iRemBuffSize is number of WCHAR */
  1231. iRemBuffSize = cbNeeded / sizeof(WCHAR);
  1232. /* Buffer ends with two consequtive Nulls */
  1233. while( ( pwchCurrBuffPtr[ 0 ] != UNICODE_NULL ) )
  1234. {
  1235. WCHAR achFontCartName[ MAXCARTNAMELEN ]; /* Font Cart Name */
  1236. ZeroMemory(achFontCartName,sizeof(achFontCartName) );
  1237. if( iRemBuffSize)
  1238. {
  1239. VERBOSE(("\nRasdd!bRegReadFontCarts:FontCartName in buffer = %ws\n",pwchCurrBuffPtr));
  1240. VERBOSE(("UniFont!bRegReadFontCarts:iRemBuffSize of buffer (before) = %d\n",iRemBuffSize));
  1241. VGetFromBuffer(achFontCartName, CCHOF(achFontCartName), &pwchCurrBuffPtr,&iRemBuffSize);
  1242. VERBOSE(("UniFont!bRegReadFontCarts:Retrieved FontCartName = %ws\n",achFontCartName));
  1243. VERBOSE(("UniFont!bRegReadFontCarts:iRemBuffSize of buffer (after) = %d\n",iRemBuffSize));
  1244. }
  1245. else
  1246. {
  1247. ERR(("UniFont!bRegReadTrayFormTable: Unexpected End of FontCartTable\n"));
  1248. /* Free the Heap */
  1249. if( pwchBuffPtr )
  1250. MEMFREEANDRESET( pwchBuffPtr );
  1251. return(FALSE);
  1252. }
  1253. pTmpFontCartMap = pFontCartMap;
  1254. for( iI = 0; iI < iNumAllCartridges ; iI++,pTmpFontCartMap++ )
  1255. {
  1256. if (pTmpFontCartMap != NULL)
  1257. {
  1258. if ((wcscmp((PCWSTR)(&(pTmpFontCartMap->awchFontCartName)), (PCWSTR)achFontCartName ) == 0))
  1259. {
  1260. pTmpFontCartMap->bInstalled = TRUE;
  1261. pFontPDev->FontCartInfo.iNumInstalledCarts++;
  1262. break;
  1263. }
  1264. }
  1265. }
  1266. }
  1267. /* Free the Heap */
  1268. if( pwchBuffPtr )
  1269. MEMFREEANDRESET( pwchBuffPtr );
  1270. return(TRUE);
  1271. }
  1272. #ifdef DELETE
  1273. VOID
  1274. VSetFontID(
  1275. DWORD *pdwOut, /* The output area */
  1276. PFONTLIST pFontList
  1277. )
  1278. /*++
  1279. Routine Description:
  1280. Set the bits in the available fonts bit array. We use the 1 based
  1281. values stored in various minidriver structures.
  1282. Arguments:
  1283. pdwOut - Pointer to output Bit Array.
  1284. pFontList - Pointer to FONTLIST structure.
  1285. Return Value: None
  1286. Note:
  1287. 11-27-96: Created it -ganeshp-
  1288. --*/
  1289. {
  1290. int iStart; /* Current value, or start of range */
  1291. int iI; /* Index variable */
  1292. DWORD *pdwList; /* Address font list */
  1293. pdwList = pFontList->pdwList;
  1294. /*
  1295. * The values are all singles.
  1296. */
  1297. for ( iI = 0; iI < pFontList->iEntriesCt; iI++ )
  1298. {
  1299. iStart = *pdwList++;
  1300. pdwOut[ iStart / DWBITS ] |= 1 << (iStart & (DWBITS - 1));
  1301. //VERBOSE(("UniFont!VSetFontID:Setting single font indexes,index is %d\n",iStart));
  1302. //VERBOSE(("UniFont!VSetFontID:Setting Bit number %d in Word num %d\n",\
  1303. //(iStart & (DWBITS - 1)),(iStart / DWBITS)) );
  1304. }
  1305. return;
  1306. }
  1307. #endif //DELETE
  1308. BOOL
  1309. BCheckFontMemUsage(
  1310. PDEV *pPDev
  1311. )
  1312. /*++
  1313. Routine Description:
  1314. This routine goes through the list of MemoryUsage and returns true if
  1315. MEMORY_FONT is found.
  1316. Arguments:
  1317. pPDev Pointer to PDEV
  1318. Return Value:
  1319. TRUE for success and FALSE for failure
  1320. Note:
  1321. 01-16-97: Created it -ganeshp-
  1322. --*/
  1323. {
  1324. BOOL bRet = FALSE;
  1325. PLISTNODE pListNode;
  1326. if (pListNode = LISTNODEPTR(pPDev->pDriverInfo ,
  1327. pPDev->pGlobals->liMemoryUsage ) )
  1328. {
  1329. while (pListNode)
  1330. {
  1331. // Check the MEMORY_FONT value;
  1332. if ( pListNode->dwData == MEMORY_FONT )
  1333. {
  1334. bRet = TRUE;
  1335. break;
  1336. }
  1337. pListNode = LISTNODEPTR(pPDev->pDriverInfo,pListNode->dwNextItem);
  1338. }
  1339. }
  1340. return bRet;
  1341. }
  1342. VOID
  1343. VSetReselectFontFlags(
  1344. PDEV *pPDev
  1345. )
  1346. /*++
  1347. Routine Description:
  1348. This routine goes through the list of Reselect Font flags and sets
  1349. corresponding PDEV PF_ flags.
  1350. Arguments:
  1351. pPDev Pointer to PDEV
  1352. Return Value:
  1353. None
  1354. Note:
  1355. 08-07-97: Created it -ganeshp-
  1356. --*/
  1357. {
  1358. PLISTNODE pListNode;
  1359. if (pListNode = LISTNODEPTR(pPDev->pDriverInfo ,
  1360. pPDev->pGlobals->liReselectFont ) )
  1361. {
  1362. while (pListNode)
  1363. {
  1364. //
  1365. // Check the ReselectFont value;
  1366. //
  1367. FTRC(\nUniFont!VSetReselectFontFlags:ReselectFont Flags Found\n);
  1368. if ( pListNode->dwData == RESELECTFONT_AFTER_GRXDATA )
  1369. {
  1370. pPDev->fMode |= PF_RESELECTFONT_AFTER_GRXDATA;
  1371. FTRC(UniFont!VSetReselectFontFlags:Setting PF_RESELECTFONT_AFTER_GRXDATA\n);
  1372. }
  1373. else if ( pListNode->dwData == RESELECTFONT_AFTER_XMOVE )
  1374. {
  1375. pPDev->fMode |= PF_RESELECTFONT_AFTER_XMOVE;
  1376. FTRC(UniFont!VSetReselectFontFlags:Setting RESELECTFONT_AFTER_XMOVE\n);
  1377. }
  1378. else if ( pListNode->dwData == RESELECTFONT_AFTER_FF )
  1379. {
  1380. pPDev->fMode |= PF_RESELECTFONT_AFTER_FF;
  1381. FTRC(UniFont!VSetReselectFontFlags:Setting RESELECTFONT_AFTER_FF\n);
  1382. }
  1383. pListNode = LISTNODEPTR(pPDev->pDriverInfo,pListNode->dwNextItem);
  1384. }
  1385. }
  1386. else
  1387. {
  1388. FTRC(\nUniFont!VSetReselectFontFlags:ReselectFont Flags Not Found\n);
  1389. }
  1390. return;
  1391. }
  1392. INT
  1393. IGetMaxFonts(
  1394. PDEV *pPDev
  1395. )
  1396. /*++
  1397. Routine Description:
  1398. This routine returns Maximum number of fonts supported. Assumes each
  1399. Font Cartridges and device has not more than MAXDEVFONTS.
  1400. Arguments:
  1401. pPDev - Pointer to PDEV.
  1402. Return Value:
  1403. Maximum number of device fonts - for success
  1404. Zero - for failure or Device fonts.
  1405. Note:
  1406. 11-18-96: Created it -ganeshp-
  1407. --*/
  1408. {
  1409. PFONTPDEV pFontPDev = pPDev->pFontPDev;
  1410. PLISTNODE pListNode;
  1411. INT iFontCt = 0;
  1412. //
  1413. // Count Device resident fonts.
  1414. //
  1415. if (pListNode = LISTNODEPTR(pPDev->pDriverInfo , pPDev->pGlobals->liDeviceFontList ) )
  1416. {
  1417. while (pListNode)
  1418. {
  1419. iFontCt++;
  1420. pListNode = LISTNODEPTR(pPDev->pDriverInfo, pListNode->dwNextItem);
  1421. }
  1422. }
  1423. //
  1424. // Add Cartridge Fonts. By this time we have scanned the regitry and know
  1425. // which fontcartridges has been installed. All we have have to do is
  1426. // go through each font cartriges font list and add them to our list.
  1427. //
  1428. if (pFontPDev->FontCartInfo.iNumInstalledCarts)
  1429. {
  1430. INT iNumAllCartridges, iI;
  1431. FONTCARTMAP *pFontCartMap; /* FontCart Map Pointer */
  1432. SHORT sOrient;
  1433. pFontCartMap = (pFontPDev->FontCartInfo.pFontCartMap);
  1434. iNumAllCartridges = pFontPDev->FontCartInfo.iNumAllFontCarts;
  1435. sOrient = (pPDev->pdm->dmFields & DM_ORIENTATION) ?
  1436. pPDev->pdm->dmOrientation : (SHORT)DMORIENT_PORTRAIT;
  1437. //
  1438. // The logic is very simple. Installed font Cartridges are marked in
  1439. // the Font Cartridge mapping table. We go through the mapping table
  1440. // and for each installed cartridges we get the font list and add them
  1441. // to our list.
  1442. //
  1443. for( iI = 0; iI < iNumAllCartridges ; iI++,pFontCartMap++ )
  1444. {
  1445. if (pFontCartMap->bInstalled == TRUE )
  1446. {
  1447. //
  1448. // Check for Orientation, as there can be different font list
  1449. // for different orientation.
  1450. //
  1451. if ( sOrient == DMORIENT_LANDSCAPE )
  1452. {
  1453. pListNode = LISTNODEPTR(pPDev->pDriverInfo ,
  1454. pFontCartMap->pFontCart->dwLandFontLst );
  1455. }
  1456. else
  1457. {
  1458. pListNode = LISTNODEPTR(pPDev->pDriverInfo ,
  1459. pFontCartMap->pFontCart->dwPortFontLst );
  1460. }
  1461. while (pListNode)
  1462. {
  1463. iFontCt++;
  1464. pListNode = LISTNODEPTR(pPDev->pDriverInfo,
  1465. pListNode->dwNextItem);
  1466. }
  1467. }
  1468. }
  1469. }
  1470. return max(MAXDEVFONT,iFontCt);
  1471. //
  1472. // return iFontCt;
  1473. //
  1474. }
  1475. #define MAXBUFFLEN (MAXCARTNAMELEN - 1)
  1476. VOID
  1477. VGetFromBuffer(
  1478. IN PWSTR pwstrDest, /* Destination */
  1479. IN size_t cchDestStr, /* How many Characters can pwstrDest hold*/
  1480. IN OUT PWSTR *ppwstrSrc, /* Source */
  1481. IN OUT PINT piRemBuffSize /*Remaining Buffer size in WCHAR */
  1482. )
  1483. /*++
  1484. Routine Description:
  1485. Reads a string from Multi string buffer.
  1486. Arguments:
  1487. pwstrDest - Pointer to Destination Buffer.
  1488. cchDestStr - Size of Destination Buffer (in characters).
  1489. ppwstrSrc - Pointer Sourc Buffer, Updated by the function.
  1490. piRemBuffSize - Pointer to remaining buffer size. Also updated. Number of characters.
  1491. Return Value:
  1492. None
  1493. Note:
  1494. 11-25-96: Created it -ganeshp-
  1495. --*/
  1496. {
  1497. if ( wcslen(*ppwstrSrc) > MAXBUFFLEN )
  1498. {
  1499. ERR(("Rasddlib!vGetFromBuffer:Bad Value read from registry !!\n") );
  1500. ERR(("String Length = %d is too Big, String is %ws !!\n",wcslen(*ppwstrSrc), *ppwstrSrc) );
  1501. *piRemBuffSize = 0;
  1502. *ppwstrSrc[ 0 ] = UNICODE_NULL;
  1503. }
  1504. if ( *piRemBuffSize > 0 ) //piRemBuffSize is integer, so it can be negative.
  1505. {
  1506. size_t cchIncr;
  1507. HRESULT hr;
  1508. hr = StringCchCopy ( (LPWSTR)pwstrDest, cchDestStr, *ppwstrSrc);
  1509. if ( SUCCEEDED (hr) )
  1510. {
  1511. StringCchLength ( pwstrDest, cchDestStr, &cchIncr );
  1512. /* The return Count Doesn't include '/0'.It is number of chars copied */
  1513. cchIncr++;
  1514. *ppwstrSrc += cchIncr;
  1515. *piRemBuffSize -= cchIncr;
  1516. }
  1517. else
  1518. {
  1519. *piRemBuffSize = 0;
  1520. *ppwstrSrc[ 0 ] = UNICODE_NULL;
  1521. }
  1522. }
  1523. }
  1524. LRESULT
  1525. PartialClipOn(
  1526. PDEV *pPDev)
  1527. {
  1528. DWORD dwData, dwType, dwSize;
  1529. PVOID pvData;
  1530. LRESULT Ret;
  1531. Ret = E_NOTIMPL;
  1532. pvData = &dwData;
  1533. dwSize = sizeof(dwData);
  1534. //
  1535. // If there is not registry value set, returns E_NOTIMPL.
  1536. // If there is and it is TRUE,, return S_OK
  1537. // If there is and it is FALSE, return S_FALSE;
  1538. //
  1539. if ((GetPrinterData(pPDev->devobj.hPrinter, REGVAL_PARTIALCLIP, &dwType, pvData, dwSize, &dwSize) == ERROR_SUCCESS))
  1540. {
  1541. if (dwData)
  1542. Ret = S_OK;
  1543. else
  1544. Ret = S_FALSE;
  1545. }
  1546. return Ret;
  1547. }
  1548. #ifdef DELETE
  1549. INT
  1550. iMaxFontID(
  1551. IN INT iMax, /* Highest found so far */
  1552. OUT DWORD *pFontIndex /* Address of start of list */
  1553. )
  1554. /*++
  1555. Routine Description:
  1556. Returns the index number (1 based) of the highest numbered font
  1557. in the list supplied.
  1558. Arguments:
  1559. iMax - Highest Font resource id foundso far.
  1560. pFontMax - Start of the font list.
  1561. Return Value:
  1562. Highest font index encountered, or passed in.
  1563. Note:
  1564. 11-26-96: Created it -ganeshp-
  1565. --*/
  1566. {
  1567. /*
  1568. * All we need do is scan along, remembering the largest we find.
  1569. */
  1570. while( *pFontIndex )
  1571. {
  1572. if( (INT)*pFontIndex > iMax )
  1573. iMax = (INT)*pFontIndex;
  1574. ++pFontIndex;
  1575. }
  1576. return iMax;
  1577. }
  1578. #endif //DELETE