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.

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