Source code of Windows XP (NT5)
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.

669 lines
21 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WGFONT.C
  8. * WOW32 16-bit GDI API support
  9. *
  10. * History:
  11. * Created 07-Mar-1991 by Jeff Parsons (jeffpar)
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "wingdip.h"
  16. MODNAME(wgfont.c);
  17. extern int RemoveFontResourceTracking(LPCSTR psz, UINT id);
  18. extern int AddFontResourceTracking(LPCSTR psz, UINT id);
  19. // for Quickbooks v4 & v5 OCR font support
  20. void LoadOCRFont(void);
  21. char szOCRA[] = "OCR-A";
  22. char szFonts[] = "\\FONTS";
  23. char szOCRDotTTF[] = "\\OCR-A.TTF";
  24. BOOL gfOCRFontLoaded = FALSE;
  25. // a.k.a. WOWAddFontResource
  26. ULONG FASTCALL WG32AddFontResource(PVDMFRAME pFrame)
  27. {
  28. ULONG ul;
  29. PSZ psz1;
  30. register PADDFONTRESOURCE16 parg16;
  31. GETARGPTR(pFrame, sizeof(ADDFONTRESOURCE16), parg16);
  32. GETPSZPTR(parg16->f1, psz1);
  33. // note: we will never get an hModule in the low word here.
  34. // the 16-bit side resolves hModules to an lpsz before calling us
  35. if( CURRENTPTD()->dwWOWCompatFlags & WOWCF_UNLOADNETFONTS )
  36. {
  37. ul = GETINT16(AddFontResourceTracking(psz1,(UINT)CURRENTPTD()));
  38. }
  39. else
  40. {
  41. ul = GETINT16(AddFontResourceA(psz1));
  42. }
  43. FREEPSZPTR(psz1);
  44. FREEARGPTR(parg16);
  45. RETURN(ul);
  46. }
  47. #define PITCH_MASK ( FIXED_PITCH | VARIABLE_PITCH )
  48. ULONG FASTCALL WG32CreateFont(PVDMFRAME pFrame)
  49. {
  50. ULONG ul;
  51. PSZ psz14;
  52. register PCREATEFONT16 parg16;
  53. INT iWidth;
  54. char achCapString[LF_FACESIZE];
  55. BYTE lfCharSet;
  56. BYTE lfPitchAndFamily;
  57. #ifdef FE_SB
  58. BOOL bUseAlternateFace = FALSE;
  59. #endif
  60. GETARGPTR(pFrame, sizeof(CREATEFONT16), parg16);
  61. GETPSZPTR(parg16->f14, psz14);
  62. // take careof compatiblity flags:
  63. // if a specific width is specified and GACF_30AVGWIDTH compatiblity
  64. // flag is set, scaledown the width by 7/8.
  65. //
  66. iWidth = INT32(parg16->f2);
  67. if (iWidth != 0 &&
  68. (W32GetAppCompatFlags((HAND16)NULL) & GACF_30AVGWIDTH)) {
  69. iWidth = (iWidth * 7) / 8;
  70. }
  71. lfCharSet = BYTE32(parg16->f9);
  72. lfPitchAndFamily = BYTE32(parg16->f13);
  73. #ifdef FE_SB
  74. if (psz14 && *psz14)
  75. #else // !FE_SB
  76. if (psz14)
  77. #endif // !FE_SB
  78. {
  79. // Capitalize the string for faster compares.
  80. WOW32_strncpy(achCapString, psz14, LF_FACESIZE);
  81. WOW32_strupr(achCapString);
  82. // Here we are going to implement a bunch of Win 3.1 hacks rather
  83. // than contaminate the 32-bit engine. These same hacks can be found
  84. // in WOW (in the CreateFont/CreateFontIndirect code).
  85. //
  86. // These hacks are keyed off the facename in the LOGFONT. String
  87. // comparisons have been unrolled for maximal performance.
  88. // Win 3.1 facename-based hack. Some apps, like
  89. // Publisher, create a "Helv" font but have the lfPitchAndFamily
  90. // set to specify FIXED_PITCH. To work around this, we will patch
  91. // the pitch field for a "Helv" font to be variable.
  92. if ( !WOW32_strcmp(achCapString, szHelv) )
  93. {
  94. lfPitchAndFamily |= ( (lfPitchAndFamily & ~PITCH_MASK) | VARIABLE_PITCH );
  95. }
  96. else
  97. {
  98. // Win 3.1 hack for Legacy 2.0. When a printer does not enumerate
  99. // a "Tms Rmn" font, the app enumerates and gets the LOGFONT for
  100. // "Script" and then create a font with the name "Tms Rmn" but with
  101. // the lfCharSet and lfPitchAndFamily taken from the LOGFONT for
  102. // "Script". Here we will over the lfCharSet to be ANSI_CHARSET.
  103. if ( !WOW32_strcmp(achCapString, szTmsRmn) )
  104. {
  105. lfCharSet = ANSI_CHARSET;
  106. }
  107. else
  108. {
  109. // If the lfFaceName is "Symbol", "Zapf Dingbats", or "ZapfDingbats",
  110. // enforce lfCharSet to be SYMBOL_CHARSET. Some apps (like Excel) ask
  111. // for a "Symbol" font but have the char set set to ANSI. PowerPoint
  112. // has the same problem with "Zapf Dingbats".
  113. if ( !WOW32_strcmp(achCapString, szSymbol) ||
  114. !WOW32_strcmp(achCapString, szZapfDingbats) ||
  115. !WOW32_strcmp(achCapString, szZapf_Dingbats) )
  116. {
  117. lfCharSet = SYMBOL_CHARSET;
  118. }
  119. }
  120. }
  121. // Win3.1(Win95) hack for Mavis Beacon Teaches Typing 3.0
  122. // The app uses a fixed width of 34*13 for the typing screen.
  123. // NT returns 14 from GetTextExtent for Mavis Beacon Courier FP font (width of 14)
  124. // while Win95 returns 13, thus long strings won't fit in the typing screen on NT.
  125. // Force the width to 13.
  126. if ( iWidth==14 && (INT32(parg16->f1)== 20) && !WOW32_strcmp(achCapString, szMavisCourier))
  127. {
  128. iWidth = 13;
  129. }
  130. #ifdef FE_SB
  131. // WOWCF_FE_ICHITARO_ITALIC
  132. // Ichitaro asks for System Mincho because WIFE fonts aren't installed
  133. // we give it a proportional font which is can't handle. If we see
  134. // this face name we will replace it with Ms Mincho
  135. if (GetSystemDefaultLangID() == 0x411 &&
  136. CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_ICHITARO_ITALIC )
  137. {
  138. if(!WOW32_strcmp(achCapString, szSystemMincho))
  139. {
  140. strcpy(achCapString, szMsMincho);
  141. bUseAlternateFace = TRUE;
  142. }
  143. }
  144. #endif // FE_SB
  145. }
  146. #ifdef FE_SB
  147. ul = GETHFONT16(CreateFont(INT32(parg16->f1),
  148. iWidth,
  149. INT32(parg16->f3),
  150. INT32(parg16->f4),
  151. INT32(parg16->f5),
  152. BYTE32(parg16->f6),
  153. BYTE32(parg16->f7),
  154. BYTE32(parg16->f8),
  155. lfCharSet,
  156. BYTE32(parg16->f10),
  157. BYTE32(parg16->f11),
  158. BYTE32(parg16->f12),
  159. lfPitchAndFamily,
  160. (bUseAlternateFace ? achCapString : psz14)
  161. ));
  162. #else
  163. ul = GETHFONT16(CreateFont(INT32(parg16->f1),
  164. iWidth,
  165. INT32(parg16->f3),
  166. INT32(parg16->f4),
  167. INT32(parg16->f5),
  168. BYTE32(parg16->f6),
  169. BYTE32(parg16->f7),
  170. BYTE32(parg16->f8),
  171. lfCharSet,
  172. BYTE32(parg16->f10),
  173. BYTE32(parg16->f11),
  174. BYTE32(parg16->f12),
  175. lfPitchAndFamily,
  176. psz14));
  177. #endif
  178. FREEPSZPTR(psz14);
  179. FREEARGPTR(parg16);
  180. RETURN(ul);
  181. }
  182. ULONG FASTCALL WG32CreateFontIndirect(PVDMFRAME pFrame)
  183. {
  184. ULONG ul;
  185. LOGFONT logfont;
  186. register PCREATEFONTINDIRECT16 parg16;
  187. char achCapString[LF_FACESIZE];
  188. GETARGPTR(pFrame, sizeof(CREATEFONTINDIRECT16), parg16);
  189. GETLOGFONT16(parg16->f1, &logfont);
  190. // Capitalize the string for faster compares.
  191. WOW32_strncpy(achCapString, logfont.lfFaceName, LF_FACESIZE);
  192. CharUpperBuff(achCapString, LF_FACESIZE);
  193. // Here we are going to implement a bunch of Win 3.1 hacks rather
  194. // than contaminate the 32-bit engine. These same hacks can be found
  195. // in WOW (in the CreateFont/CreateFontIndirect code).
  196. //
  197. // These hacks are keyed off the facename in the LOGFONT. String
  198. // comparisons have been unrolled for maximal performance.
  199. // Win 3.1 facename-based hack. Some apps, like
  200. // Publisher, create a "Helv" font but have the lfPitchAndFamily
  201. // set to specify FIXED_PITCH. To work around this, we will patch
  202. // the pitch field for a "Helv" font to be variable.
  203. if ( !WOW32_strcmp(achCapString, szHelv) )
  204. {
  205. logfont.lfPitchAndFamily |= ( (logfont.lfPitchAndFamily & ~PITCH_MASK) | VARIABLE_PITCH );
  206. #ifdef FE_SB
  207. //
  208. // FE Win 3.1 facename-based hack. Some FE apps
  209. // create a "Helv" font but have the lfCharSet
  210. // set to DBCS charset (ex. SHIFTJIS_CHARSET).
  211. // To work around this, we will wipe out the
  212. // lfFaceName[0] with '\0' and let GDI picks a
  213. // DBCS font for us.
  214. //
  215. if (IS_ANY_DBCS_CHARSET(logfont.lfCharSet))
  216. logfont.lfFaceName[0]='\0';
  217. #endif // FE_SB
  218. }
  219. else
  220. {
  221. // Win 3.1 hack for Legacy 2.0. When a printer does not enumerate
  222. // a "Tms Rmn" font, the app enumerates and gets the LOGFONT for
  223. // "Script" and then create a font with the name "Tms Rmn" but with
  224. // the lfCharSet and lfPitchAndFamily taken from the LOGFONT for
  225. // "Script". Here we will over the lfCharSet to be ANSI_CHARSET.
  226. if ( !WOW32_strcmp(achCapString, szTmsRmn) )
  227. {
  228. logfont.lfCharSet = ANSI_CHARSET;
  229. }
  230. // for Quickbooks v4 & v5 OCR font support (see LoadOCRFont for details)
  231. else if ( !WOW32_strcmp(achCapString, szOCRA) )
  232. {
  233. // Further localize this hack to QuickBooks. Most other apps won't
  234. // know about this quirk in this particular font.
  235. if(logfont.lfCharSet == SYMBOL_CHARSET) {
  236. logfont.lfCharSet = DEFAULT_CHARSET;
  237. if(!gfOCRFontLoaded) {
  238. LoadOCRFont();
  239. }
  240. }
  241. }
  242. else
  243. {
  244. // If the lfFaceName is "Symbol", "Zapf Dingbats", or "ZapfDingbats",
  245. // enforce lfCharSet to be SYMBOL_CHARSET. Some apps (like Excel) ask
  246. // for a "Symbol" font but have the char set set to ANSI. PowerPoint
  247. // has the same problem with "Zapf Dingbats".
  248. if ( !WOW32_strcmp(achCapString, szSymbol) ||
  249. !WOW32_strcmp(achCapString, szZapfDingbats) ||
  250. !WOW32_strcmp(achCapString, szZapf_Dingbats) )
  251. {
  252. logfont.lfCharSet = SYMBOL_CHARSET;
  253. }
  254. #ifdef FE_SB
  255. // WOWCF_FE_ICHITARO_ITALIC
  256. // Ichitaro asks for System Mincho because WIFE fonts aren't installed
  257. // we give it a proportional font which is can't handle. If we see
  258. // this face name we will replace it with Ms Mincho
  259. if (GetSystemDefaultLangID() == 0x411 &&
  260. CURRENTPTD()->dwWOWCompatFlagsFE & WOWCF_FE_ICHITARO_ITALIC )
  261. {
  262. if(!WOW32_strcmp(achCapString, szSystemMincho))
  263. {
  264. strcpy(logfont.lfFaceName, szMsMincho);
  265. }
  266. }
  267. #endif // FE_SB
  268. }
  269. }
  270. ul = GETHFONT16(CreateFontIndirect(&logfont));
  271. FREEARGPTR(parg16);
  272. RETURN(ul);
  273. }
  274. LPSTR lpMSSansSerif = "MS Sans Serif";
  275. LPSTR lpMSSerif = "MS Serif";
  276. LPSTR lpHelvetica = "Helvetica";
  277. INT W32EnumFontFunc(LPENUMLOGFONT pEnumLogFont,
  278. LPNEWTEXTMETRIC pNewTextMetric, INT nFontType, PFNTDATA pFntData)
  279. {
  280. INT iReturn;
  281. PARM16 Parm16;
  282. LPSTR lpFaceNameT = NULL;
  283. WOW32ASSERT(pFntData);
  284. // take care of compatibility flags:
  285. // ORin DEVICE_FONTTYPE bit if the fonttype is truetype and the
  286. // Compataibility flag GACF_CALLTTDEVICE is set.
  287. //
  288. if (nFontType & TRUETYPE_FONTTYPE) {
  289. if (W32GetAppCompatFlags((HAND16)NULL) & GACF_CALLTTDEVICE) {
  290. nFontType |= DEVICE_FONTTYPE;
  291. }
  292. }
  293. // take care of compatibility flags:
  294. // replace Ms Sans Serif with Helv and
  295. // replace Ms Serif with Tms Rmn
  296. //
  297. // only if the facename is NULL and the compat flag GACF_ENUMHELVNTMSRMN
  298. // is set.
  299. if (pFntData->vpFaceName == (VPVOID)NULL) {
  300. if (W32GetAppCompatFlags((HAND16)NULL) & GACF_ENUMHELVNTMSRMN) {
  301. if (!WOW32_strcmp(pEnumLogFont->elfLogFont.lfFaceName, lpMSSansSerif)) {
  302. strcpy(pEnumLogFont->elfLogFont.lfFaceName, "Helv");
  303. lpFaceNameT = lpMSSansSerif;
  304. }
  305. else if (!WOW32_strcmp(pEnumLogFont->elfLogFont.lfFaceName, lpHelvetica)) {
  306. strcpy(pEnumLogFont->elfLogFont.lfFaceName, "Helv");
  307. lpFaceNameT = lpMSSansSerif;
  308. }
  309. else if (!WOW32_strcmp(pEnumLogFont->elfLogFont.lfFaceName, lpMSSerif)) {
  310. strcpy(pEnumLogFont->elfLogFont.lfFaceName, "Tms Rmn");
  311. lpFaceNameT = lpMSSerif;
  312. }
  313. }
  314. }
  315. CallAgain:
  316. // be sure allocation size matches stackfree16() size below
  317. pFntData->vpLogFont = stackalloc16(sizeof(ENUMLOGFONT16)+sizeof(NEWTEXTMETRIC16));
  318. pFntData->vpTextMetric = (VPVOID)((LPSTR)pFntData->vpLogFont + sizeof(ENUMLOGFONT16));
  319. PUTENUMLOGFONT16(pFntData->vpLogFont, pEnumLogFont);
  320. PUTNEWTEXTMETRIC16(pFntData->vpTextMetric, pNewTextMetric);
  321. STOREDWORD(Parm16.EnumFontProc.vpLogFont, pFntData->vpLogFont);
  322. STOREDWORD(Parm16.EnumFontProc.vpTextMetric, pFntData->vpTextMetric);
  323. STOREDWORD(Parm16.EnumFontProc.vpData,pFntData->dwUserFntParam);
  324. Parm16.EnumFontProc.nFontType = (SHORT)nFontType;
  325. CallBack16(RET_ENUMFONTPROC, &Parm16, pFntData->vpfnEnumFntProc, (PVPVOID)&iReturn);
  326. if(pFntData->vpLogFont) {
  327. stackfree16(pFntData->vpLogFont,
  328. (sizeof(ENUMLOGFONT16) + sizeof(NEWTEXTMETRIC16)));
  329. }
  330. if (((SHORT)iReturn) && lpFaceNameT) {
  331. // if the callback returned true, now call with the actual facename
  332. // Just to be sure, we again copy all the data for callback. This will
  333. // take care of any apps which modify the passed in structures.
  334. strcpy(pEnumLogFont->elfLogFont.lfFaceName, lpFaceNameT);
  335. lpFaceNameT = (LPSTR)NULL;
  336. goto CallAgain;
  337. }
  338. return (SHORT)iReturn;
  339. }
  340. ULONG W32EnumFontHandler( PVDMFRAME pFrame, BOOL fEnumFontFamilies )
  341. {
  342. ULONG ul = 0;
  343. PSZ psz2;
  344. FNTDATA FntData;
  345. register PENUMFONTS16 parg16;
  346. GETARGPTR(pFrame, sizeof(ENUMFONTS16), parg16);
  347. GETPSZPTR(parg16->f2, psz2);
  348. FntData.vpfnEnumFntProc = DWORD32(parg16->f3);
  349. FntData.dwUserFntParam = DWORD32(parg16->f4);
  350. FntData.vpFaceName = DWORD32(parg16->f2);
  351. if ( fEnumFontFamilies ) {
  352. ul = GETINT16(EnumFontFamilies(HDC32(parg16->f1),
  353. psz2,
  354. (FONTENUMPROC)W32EnumFontFunc,
  355. (LPARAM)&FntData));
  356. } else {
  357. ul = GETINT16(EnumFonts(HDC32(parg16->f1),
  358. psz2,
  359. (FONTENUMPROC)W32EnumFontFunc,
  360. (LPARAM)&FntData));
  361. }
  362. FREEPSZPTR(psz2);
  363. FREEARGPTR(parg16);
  364. RETURN(ul);
  365. }
  366. ULONG FASTCALL WG32EnumFonts(PVDMFRAME pFrame)
  367. {
  368. return( W32EnumFontHandler( pFrame, FALSE ) );
  369. }
  370. ULONG FASTCALL WG32GetAspectRatioFilter(PVDMFRAME pFrame)
  371. {
  372. ULONG ul = 0;
  373. SIZE size2;
  374. register PGETASPECTRATIOFILTER16 parg16;
  375. GETARGPTR(pFrame, sizeof(GETASPECTRATIOFILTER16), parg16);
  376. if (GETDWORD16(GetAspectRatioFilterEx(HDC32(parg16->f1), &size2))) {
  377. ul = (WORD)size2.cx | (size2.cy << 16);
  378. }
  379. FREEARGPTR(parg16);
  380. RETURN(ul);
  381. }
  382. ULONG FASTCALL WG32GetCharWidth(PVDMFRAME pFrame)
  383. {
  384. ULONG ul = 0L;
  385. INT ci;
  386. PINT pi4;
  387. register PGETCHARWIDTH16 parg16;
  388. INT BufferT[256];
  389. GETARGPTR(pFrame, sizeof(GETCHARWIDTH16), parg16);
  390. ci = WORD32(parg16->wLastChar) - WORD32(parg16->wFirstChar) + 1;
  391. pi4 = STACKORHEAPALLOC(ci * sizeof(INT), sizeof(BufferT), BufferT);
  392. if (pi4) {
  393. ULONG ulLast = WORD32(parg16->wLastChar);
  394. #ifdef FE_SB
  395. /*
  396. * If ulLast sets DBCS code (0x82xx), then below code is illigal.
  397. */
  398. if (ulLast > 0xff && !(IsDBCSLeadByte(HIBYTE(ulLast))))
  399. #else // !FE_SB
  400. if (ulLast > 0xff)
  401. #endif // !FE_SB
  402. ulLast = 0xff;
  403. ul = GETBOOL16(GetCharWidth(HDC32(parg16->hDC),
  404. WORD32(parg16->wFirstChar),
  405. ulLast,
  406. pi4));
  407. PUTINTARRAY16(parg16->lpIntBuffer, ci, pi4);
  408. STACKORHEAPFREE(pi4, BufferT);
  409. }
  410. FREEARGPTR(parg16);
  411. RETURN(ul);
  412. }
  413. // a.k.a. WOWRemoveFontResource
  414. ULONG FASTCALL WG32RemoveFontResource(PVDMFRAME pFrame)
  415. {
  416. ULONG ul;
  417. PSZ psz1;
  418. register PREMOVEFONTRESOURCE16 parg16;
  419. GETARGPTR(pFrame, sizeof(REMOVEFONTRESOURCE16), parg16);
  420. GETPSZPTR(parg16->f1, psz1);
  421. // note: we will never get an hModule in the low word here.
  422. // the 16-bit side resolves hModules to an lpsz before calling us
  423. if( CURRENTPTD()->dwWOWCompatFlags & WOWCF_UNLOADNETFONTS )
  424. {
  425. ul = GETBOOL16(RemoveFontResourceTracking(psz1,(UINT)CURRENTPTD()));
  426. }
  427. else
  428. {
  429. ul = GETBOOL16(RemoveFontResource(psz1));
  430. }
  431. FREEPSZPTR(psz1);
  432. FREEARGPTR(parg16);
  433. RETURN(ul);
  434. }
  435. /* WG32GetCurLogFont
  436. *
  437. * This thunk implements the undocumented Win3.0 and Win3.1 API
  438. * GetCurLogFont (GDI.411). Symantec QA4.0 uses it.
  439. *
  440. * HFONT GetCurLogFont (HDC)
  441. * HDC hDC; // Device Context
  442. *
  443. * This function returns the current Logical font selected for the
  444. * specified device context.
  445. *
  446. * To implement this undocumented API we will use the NT undocumented API
  447. * GetHFONT.
  448. *
  449. * SudeepB 08-Mar-1996
  450. *
  451. */
  452. extern HFONT APIENTRY GetHFONT (HDC hdc);
  453. ULONG FASTCALL WG32GetCurLogFont(PVDMFRAME pFrame)
  454. {
  455. ULONG ul;
  456. register PGETCURLOGFONT16 parg16;
  457. GETARGPTR(pFrame, sizeof(GETCURLOGFONT16), parg16);
  458. ul = GETHFONT16 (GetHFONT(HDC32 (parg16->hDC)));
  459. FREEARGPTR(parg16);
  460. return (ul);
  461. }
  462. //
  463. // This allows Quickbooks v4 & v5 to use their OCR-A.TTF font right after they
  464. // install. At the end of installation on both versions, you are asked if you
  465. // want to "restart" windows. If you click OK it logs you off of NT5, but does
  466. // *not* reboot the system -- which the app is counting on to cause the OCR-A
  467. // font to be loaded. The result on W2K is that whenever the app uses the OCR-A
  468. // font, it will get mapped to wingdings instead.
  469. //
  470. // This is further complicated by the fact that the font file OCR-A.TTF doesn't
  471. // specify the charset in the header. On Win3.1, Win95, & pre-NT5, unspecified
  472. // charset's got mapped to the SYMBOL_CHARSET - therefore, Quickbooks specifies
  473. // SYMBOL_CHARSET in its LOGFONT struct to accomodate this. (OCR-A apparently
  474. // is licenced from Monotype Typography, Ltd. which presumably is why Intuit
  475. // didn't fix the header issue in the font file).
  476. //
  477. // This changed on Win98 and W2K, unspecified charset's now get mapped to the
  478. // DEFAULT_CHARSET. This was done so these fonts will always map to a default
  479. // localized font that will always be readable. Hence, the hack where we change
  480. // the charset from SYMBOL_CHARSET to DEFAULT_CHARSET in the LOGFONT struct.
  481. //
  482. // On v4, the install program copies OCR-A.FOT & OCR-A.TTF to the SYSTEM dir.
  483. // Once you "restart" (not reboot) the system & log back on, the OCR-A font is
  484. // added to the registry (as OCR-A.FOT) but the font files are still in the
  485. // SYSTEM dir. Rebooting causes the fonts files to be moved to the FONTS dir,
  486. // the registry entry is changed to OCR-A.TTF. (done by the "Font Sweeper")
  487. //
  488. // On v5, the install program copies the .ttf & .fot files to the FONTS dir
  489. // but again, counts on the reboot to cause the fonts to be loaded. It puts
  490. // correct registry entry (OCR-A.TTF) in the registry fonts section.
  491. //
  492. // The result of all this is:
  493. // For either version of the app, without the charset hack, you will always get
  494. // a wingding font instead of OCR-A. With the charset hack, you will get a
  495. // readable font, such as Arial, until you reboot -- after which you will get
  496. // OCR-A for v5 but Arial for v4. With this function (in conjunction with the
  497. // charset hack) both version will always get OCR-A with or without rebooting.
  498. //
  499. // This function explicitly loads the OCR-A from the font files located in
  500. // either the FONTS dir or the SYSTEM dir.
  501. //
  502. void LoadOCRFont(void)
  503. {
  504. char szFontPath[MAX_PATH];
  505. DWORD dw;
  506. int cb;
  507. // get equivalent of "c:\windows" for this system
  508. dw = GetWindowsDirectory(szFontPath, MAX_PATH);
  509. // we're going to add a maximum of 18 chars "\SYSTEM\OCR-A.TTF"
  510. if(dw && ((MAX_PATH - 18) > dw)) {
  511. // build "c:\windows\FONTS\OCR-A.TTF" (QuickBooks v5)
  512. strcat(szFontPath, szFonts);
  513. strcat(szFontPath, szOCRDotTTF);
  514. // If font file doesn't exist in FONTS dir, this must be QuickBooks v4
  515. // The FR_PRIVATE flag means that the font will be unloaded when the vdm
  516. // process goes away. The FR_NO_ENUM flag means that this instance of
  517. // the font can't be enumerated by other processes (it might go away
  518. // while the other processes are trying to use it).
  519. cb = AddFontResourceEx(szFontPath, FR_PRIVATE | FR_NOT_ENUM, NULL);
  520. if(!cb) {
  521. // reset path to "c:\windows"
  522. szFontPath[dw] = '\0';
  523. // build "c:\windows\SYSTEM\OCR-A.TTF"
  524. strcat(szFontPath, szSystem);
  525. strcat(szFontPath, szOCRDotTTF);
  526. cb = AddFontResourceEx(szFontPath, FR_PRIVATE | FR_NOT_ENUM, NULL);
  527. // if it wasn't loaded from the SYSTEM dir either, punt
  528. }
  529. if(cb) {
  530. // specify that the font is already loaded for the life of this VDM
  531. gfOCRFontLoaded = TRUE;
  532. }
  533. }
  534. }