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.

2235 lines
67 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: fdcvt.c
  3. *
  4. * ifi interface calls, file loading and file conversions.
  5. *
  6. * Created: 22-Oct-1990 13:33:55
  7. * Author: Bodin Dresevic [BodinD]
  8. *
  9. * Copyright (c) 1990 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "fd.h"
  12. #include "ctype.h"
  13. #include "exehdr.h"
  14. #include <string.h>
  15. #if DBG
  16. unsigned gflBmfdDebug = 0;
  17. #define BMFD_DEBUG_DUMP_HEADER 1
  18. typedef VOID (*VPRINT) (char*,...);
  19. VOID vDumpFontHeader(PRES_ELEM, VPRINT);
  20. #endif
  21. // This points to the base of our list of FD_GLYPHSETS
  22. CP_GLYPHSET *gpcpGlyphsets = NULL;
  23. /******************************Public*Routine******************************\
  24. * BmfdQueryFontCaps
  25. *
  26. * Effects: returns the capabilities of this driver.
  27. * Only mono bitmaps are supported.
  28. *
  29. * History:
  30. * 27-Nov-1990 -by- Bodin Dresevic [BodinD]
  31. * Wrote it.
  32. \**************************************************************************/
  33. LONG BmfdQueryFontCaps(ULONG culCaps, PULONG pulCaps)
  34. {
  35. ASSERTGDI(culCaps == 2, "ERROR why would the engine call us like this");
  36. if (culCaps < 2)
  37. return(0L);
  38. pulCaps[0] = 2L;
  39. //
  40. // 1 bit per pel bitmaps only are supported
  41. //
  42. pulCaps[1] = QC_1BIT;
  43. return(2L);
  44. }
  45. /******************************Public*Routine******************************\
  46. * BmfdUnloadFontFile(HFF hff)
  47. *
  48. * Frees the resources that have been loced allocated by BmfdLoadFontFile
  49. * BmfdLoadFontResData
  50. *
  51. * History:
  52. * 15-Nov-1990 -by- Bodin Dresevic [BodinD]
  53. * Wrote it.
  54. \**************************************************************************/
  55. BOOL
  56. BmfdUnloadFontFile(
  57. HFF hff
  58. )
  59. {
  60. FACEINFO *pfai, *pfaiTooFar;
  61. ASSERTGDI(hff, "BmfdUnloadFontFile, hff\n");
  62. // check the reference count, if not 0 (font file is still
  63. // selected into a font context) we have a problem
  64. ASSERTGDI(PFF(hff)->cRef == 0L, "cRef: did not update links properly\n");
  65. // free the memory associated with all converted files
  66. pfai = PFF(hff)->afai;
  67. pfaiTooFar = pfai + PFF(hff)->cFntRes;
  68. EngAcquireSemaphore(ghsemBMFD);
  69. while (pfai < pfaiTooFar)
  70. {
  71. vUnloadGlyphset(&gpcpGlyphsets, pfai->pcp);
  72. pfai += 1;
  73. }
  74. EngReleaseSemaphore(ghsemBMFD);
  75. // free memory associated with this FONTFILE object,
  76. VFREEMEM(hff);
  77. return(TRUE);
  78. }
  79. /******************************Public*Routine******************************\
  80. *
  81. * FSHORT fsSelectionFlags(PBYTE ajHdr)
  82. *
  83. * Effects: compute fsSelection field of the ifimetrics
  84. *
  85. * History:
  86. * 13-May-1991 -by- Bodin Dresevic [BodinD]
  87. * Wrote it.
  88. \**************************************************************************/
  89. FSHORT
  90. fsSelectionFlags(
  91. PBYTE ajHdr
  92. )
  93. {
  94. FSHORT fsSelection = 0;
  95. if (ajHdr[OFF_Italic])
  96. fsSelection |= FM_SEL_ITALIC;
  97. if (ajHdr[OFF_Underline])
  98. fsSelection |= FM_SEL_UNDERSCORE;
  99. if (ajHdr[OFF_StrikeOut])
  100. fsSelection |= FM_SEL_STRIKEOUT;
  101. #ifdef DEBUG_ITALIC
  102. DbgPrint("It = %ld, Str = %ld, Und = %ld, Asc = %ld\n",
  103. (ULONG)ajHdr[OFF_Italic],
  104. (ULONG)ajHdr[OFF_StrikeOut],
  105. (ULONG)ajHdr[OFF_Underline],
  106. (ULONG)sMakeSHORT((PBYTE)&ajHdr[OFF_Ascent])
  107. );
  108. #endif // DEBUG_ITALIC
  109. // the following line is somewhat arbitrary, we set the FM_SEL_BOLD
  110. // flag iff weight is > FW_NORMAL (400). we will not allow emboldening
  111. // simulation on the font that has this flag set
  112. if (usMakeUSHORT((PBYTE)&ajHdr[OFF_Weight]) > FW_NORMAL)
  113. fsSelection |= FM_SEL_BOLD;
  114. return(fsSelection);
  115. }
  116. /******************************Public*Routine******************************\
  117. *
  118. * vAlignHdrData
  119. *
  120. * Effects: packs header data into dword alligned structure
  121. *
  122. * History:
  123. * 29-Oct-1990 -by- Bodin Dresevic [BodinD]
  124. * Wrote it.
  125. \**************************************************************************/
  126. VOID
  127. vAlignHdrData(
  128. PCVTFILEHDR pcvtfh,
  129. PRES_ELEM pre
  130. )
  131. {
  132. PBYTE ajHdr = (PBYTE)pre->pvResData;
  133. #ifdef DUMPCALL
  134. DbgPrint("\nvAlignHdrData(" );
  135. DbgPrint("\n PCVTFILEHDR pcvtfh = %-#8lx", pcvtfh );
  136. DbgPrint("\n PRES_ELEM pre = %-#8lx", pre );
  137. DbgPrint("\n )\n" );
  138. #endif
  139. /******************************************************/
  140. /**/ #if DBG /**/
  141. /**/ if (gflBmfdDebug & BMFD_DEBUG_DUMP_HEADER) /**/
  142. /**/ vDumpFontHeader(pre, (VPRINT) DbgPrint); /**/
  143. /**/ #endif /**/
  144. /******************************************************/
  145. // zero out the whole structure before doing anything
  146. RtlZeroMemory(pcvtfh, sizeof(CVTFILEHDR));
  147. // The iVersion only had length of 2 bytes in the original struct
  148. pcvtfh->iVersion = usMakeUSHORT((PBYTE)&ajHdr[OFF_Version]);
  149. pcvtfh->chFirstChar = ajHdr[OFF_FirstChar ];
  150. pcvtfh->chLastChar = ajHdr[OFF_LastChar ];
  151. pcvtfh->chDefaultChar = ajHdr[OFF_DefaultChar];
  152. pcvtfh->chBreakChar = ajHdr[OFF_BreakChar ];
  153. pcvtfh->cy = usMakeUSHORT((PBYTE)&ajHdr[OFF_PixHeight]);
  154. #ifdef FE_SB // vAlignHdrData():Get DBCS character's width
  155. pcvtfh->usCharSet = (USHORT) ajHdr[OFF_CharSet];
  156. if( !IS_ANY_DBCS_CHARSET( pcvtfh->usCharSet ) )
  157. #endif // FE_SB
  158. {
  159. // Fri 29-Apr-1994 07:11:06 by Kirk Olynyk [kirko]
  160. //
  161. // There are some buggy font files that are fixed pitch but
  162. // have a MaxWidth greater than the fixed pitch width
  163. // e.g. "Crosstalk IBMPC Fonts v2.0". We check for the
  164. // disparity here. If the font is fixed pitch, as indicated
  165. // by a non zero value of PixWidth, and the average width
  166. // is equal to the fixed pitch width, then the maximum
  167. // pixel width (MaxWidth) is set equal to the PixWidth.
  168. // If the MaxWidth value was correct, then this piece
  169. // of code puts in a bad value for the maxiumum width.
  170. // But this will be fixed! The calling sequences of
  171. // interest are:
  172. //
  173. // bConverFontRes() calls bVerifyFNT() calls vAlignHdrData()
  174. //
  175. // then later in bConvertFontRes()
  176. //
  177. // bConverFontRes() calls vCheckOffsetTable()
  178. //
  179. // It is vCheckOffsetTabl() that would correct
  180. // the maximum pixel if it was incorrectly set here
  181. USHORT usPixWidth = usMakeUSHORT(ajHdr + OFF_PixWidth);
  182. USHORT usAvgWidth = usMakeUSHORT(ajHdr + OFF_AvgWidth);
  183. USHORT usMaxWidth = usMakeUSHORT(ajHdr + OFF_MaxWidth);
  184. if (usPixWidth && usPixWidth == usAvgWidth)
  185. usMaxWidth = usPixWidth;
  186. pcvtfh->usMaxWidth = usMaxWidth;
  187. #ifdef FE_SB // vAlignHdrData():Init DBCS width 0 for non DBCS font.
  188. pcvtfh->usDBCSWidth = 0;
  189. #endif // FE_SB
  190. }
  191. #ifdef FE_SB // vAlignHdrData():Get DBCS character's width
  192. else
  193. {
  194. // usMaxWidth specifies DBCS width in 3.0J and 3.1J font width of double byte
  195. // character let keep this value, because pcvtfh->usMaxWidth might be change in
  196. // vCheckOffsetTable()
  197. pcvtfh->usDBCSWidth = usMakeUSHORT(ajHdr + OFF_MaxWidth);
  198. pcvtfh->usMaxWidth = usMakeUSHORT(ajHdr + OFF_MaxWidth);
  199. }
  200. #endif // FE_SB
  201. if (pcvtfh->iVersion == 0x00000200)
  202. pcvtfh->dpOffsetTable = OFF_OffTable20;
  203. else if (pcvtfh->iVersion == 0x00000300)
  204. pcvtfh->dpOffsetTable = OFF_OffTable30;
  205. else
  206. pcvtfh->dpOffsetTable = -1; // will generate error
  207. }
  208. /******************************Public*Routine******************************\
  209. * BOOL bDbgPrintAndFail(PSZ psz)
  210. *
  211. * History:
  212. * 06-Dec-1990 -by- Bodin Dresevic [BodinD]
  213. * Wrote it.
  214. \**************************************************************************/
  215. #if DBG
  216. BOOL
  217. bDbgPrintAndFail(
  218. PSZ psz
  219. )
  220. {
  221. DONTUSE(psz);
  222. //#ifdef DEBUGFF
  223. DbgPrint(psz);
  224. //#endif
  225. return(FALSE);
  226. }
  227. #else
  228. #define bDbgPrintAndFail(psz) FALSE
  229. #endif
  230. BOOL
  231. bVerifyFNTQuick(
  232. PRES_ELEM pre
  233. )
  234. {
  235. #ifdef DUMPCALL
  236. DbgPrint("\nbVerifyResource(" );
  237. DbgPrint("\n PCVTFILEHDR pcvtfh = %-#8lx", pcvtfh);
  238. DbgPrint("\n PRES_ELEM pre = %-#8lx", pre );
  239. DbgPrint("\n )\n" );
  240. #endif
  241. PBYTE ajHdr = (PBYTE)pre->pvResData;
  242. USHORT usVersion;
  243. if (pre->cjResData < OFF_OffTable20)
  244. return(bDbgPrintAndFail("BMFD! resource size too small for OFF_OffTable20\n")); // supported.
  245. if ((READ_WORD(&ajHdr[OFF_Type]) & TYPE_VECTOR)) // Vector bit has to
  246. return(FALSE); // we expect to hit this line on vector fonts
  247. usVersion = READ_WORD(&ajHdr[OFF_Version]);
  248. if ((usVersion != 0x0200) && // The only version
  249. (usVersion != 0x0300) ) // The only version
  250. return(FALSE); // we hit that one too on vector fonts
  251. if ((usVersion == 0x0300) && (pre->cjResData < OFF_OffTable30))
  252. return(bDbgPrintAndFail("BMFD! resource size too small for OFF_OffTable30\n")); // supported.
  253. return TRUE;
  254. }
  255. /******************************Public*Routine******************************\
  256. * bVerifyResource
  257. *
  258. * Effects: CHECK whether header contains file info which corresponds to
  259. * the raster font requirements, go into the file and check
  260. * the consistency of the header data
  261. *
  262. * History:
  263. * 30-Oct-1990 -by- Bodin Dresevic [BodinD]
  264. * Wrote it.
  265. \**************************************************************************/
  266. BOOL
  267. bVerifyResource(
  268. PCVTFILEHDR pcvtfh,
  269. PRES_ELEM pre
  270. )
  271. {
  272. #ifdef DUMPCALL
  273. DbgPrint("\nbVerifyResource(" );
  274. DbgPrint("\n PCVTFILEHDR pcvtfh = %-#8lx", pcvtfh);
  275. DbgPrint("\n PRES_ELEM pre = %-#8lx", pre );
  276. DbgPrint("\n )\n" );
  277. #endif
  278. PBYTE ajHdr = (PBYTE)pre->pvResData;
  279. ULONG cjSize;
  280. LONG dpBits = lMakeLONG((PBYTE)&ajHdr[OFF_BitsOffset]);
  281. SHORT sAscent;
  282. ASSERTGDI(
  283. ((READ_WORD(&ajHdr[OFF_Version]) == 0x0200) || (READ_WORD(&ajHdr[OFF_Version]) == 0x0300)),
  284. "BMFD!wrong iVersion for bitmap font\n"
  285. );
  286. if (pcvtfh->iVersion == 0x00000200)
  287. if (dpBits > SEGMENT_SIZE)
  288. return(bDbgPrintAndFail("BMFD!dpBits \n")); // Bits Offset Not Ok
  289. // file size must be <= than the size of the view
  290. cjSize = ulMakeULONG(ajHdr + OFF_Size);
  291. if (cjSize > pre->cjResData)
  292. {
  293. cjSize = pre->cjResData; // no offset can be bigger than this
  294. }
  295. sAscent = sMakeSHORT((PBYTE)&ajHdr[OFF_Ascent]);
  296. if (abs(sAscent) > (SHORT)pcvtfh->cy)
  297. return(bDbgPrintAndFail("BMFD!sAscent \n")); // Ascent Too Big
  298. if (sMakeSHORT((PBYTE)&ajHdr[OFF_ExtLeading]) < 0)
  299. return(bDbgPrintAndFail("BMFD!ExtLeading \n")); // Ext Lead Not Ok;
  300. #if DBG
  301. // CHECK fsType field, if vector type, this would have been caught by
  302. // bVerifyFNTQuick
  303. ASSERTGDI(
  304. (READ_WORD(&ajHdr[OFF_Type]) & TYPE_VECTOR) == 0,
  305. "bmfd!this mustn't have been a vector font\n"
  306. );
  307. if (sMakeSHORT((PBYTE)&ajHdr[OFF_IntLeading]) < 0)
  308. DbgPrint(
  309. "bmfd warning: possibly bad font file - sIntLeading = %ld\n\n",
  310. (LONG)sMakeSHORT((PBYTE)&ajHdr[OFF_IntLeading])
  311. );
  312. #endif
  313. if (sMakeSHORT((PBYTE)&ajHdr[OFF_IntLeading]) > sAscent)
  314. return(bDbgPrintAndFail("BMFD!IntLeading too big\n")); // Int Lead Too Big;
  315. // check consistency of character ranges
  316. if (pcvtfh->chFirstChar > pcvtfh->chLastChar)
  317. return(bDbgPrintAndFail("BMFD!FirstChar\n")); // this can't be
  318. // default and break character are given relative to the FirstChar,
  319. // so that the actual default (break) character is given as
  320. // chFirst + chDefault(Break)
  321. if ((UCHAR)(pcvtfh->chDefaultChar + pcvtfh->chFirstChar) > pcvtfh->chLastChar)
  322. {
  323. // here we will do something which never should have been done if
  324. // win 3.0 did any parameter validation on loading fonts .
  325. // This is done in order not to reject fonts that have only Def and Break
  326. // chars messed up, but everything else is ok. Example of such shipped
  327. // fonts are some samna corp. fonts that come with AmiPro application.
  328. // Their Def char is the absolute value rather than value relative to
  329. // the first char in the font. This is of course the bug in the font
  330. // files, but since win30 does not reject these files, we must not do that
  331. // either.
  332. #if DBG
  333. DbgPrint("bmfd!_bVerifyResource: warning -- bogus Default char = %ld\n", (ULONG)pcvtfh->chDefaultChar);
  334. #endif
  335. if ((pcvtfh->chDefaultChar >= pcvtfh->chFirstChar) && (pcvtfh->chDefaultChar <= pcvtfh->chLastChar))
  336. {
  337. // attempt to fix the problem stemming from the bug in the font file
  338. pcvtfh->chDefaultChar -= pcvtfh->chFirstChar;
  339. }
  340. else
  341. {
  342. // this definitely is not a sensible font file, but samna provided us
  343. // withone such font as well
  344. pcvtfh->chDefaultChar = 0;
  345. }
  346. }
  347. if ((UCHAR)(pcvtfh->chBreakChar + pcvtfh->chFirstChar) > pcvtfh->chLastChar)
  348. {
  349. // here we will do something which never should have been done if
  350. // win 3.0 did any parameter validation on loading fonts .
  351. // This is done in order not to reject fonts that have only Def and Break
  352. // chars messed up, but everything else is ok. Example of such shipped
  353. // fonts are some samna corp. fonts that come with AmiPro application.
  354. // Their Break char is the absolute value rather than value relative to
  355. // the first char in the font. This is of course the bug in the font
  356. // files, but since win30 does not reject these files, we must not do that
  357. // either.
  358. #if DBG
  359. DbgPrint("bmfd!_bVerifyResource: warning bogus Break char = %ld\n", (ULONG)pcvtfh->chBreakChar);
  360. #endif
  361. if ((pcvtfh->chBreakChar >= pcvtfh->chFirstChar) && (pcvtfh->chBreakChar <= pcvtfh->chLastChar))
  362. {
  363. // attempt to fix the problem stemming from the bug in the font file
  364. pcvtfh->chBreakChar -= pcvtfh->chFirstChar;
  365. }
  366. else
  367. {
  368. // this definitely is not a sensible font file, but samna provided us
  369. // with one such font as well
  370. pcvtfh->chBreakChar = 0;
  371. }
  372. }
  373. // offset to the offset table
  374. ASSERTGDI((pcvtfh->dpOffsetTable & 1) == 0, "dpOffsetTable is not even\n");
  375. if ((pcvtfh->dpOffsetTable != OFF_OffTable20) &&
  376. (pcvtfh->dpOffsetTable != OFF_OffTable30))
  377. return(bDbgPrintAndFail("BMFD!dpOffsetTable \n"));
  378. // make sure that the first offset in the offset table is equal to dpBits,
  379. // this is an internal consistency check of the font, also verify that
  380. // all offsets are smaller than cjSize
  381. {
  382. PBYTE pjFirstOffset = (PBYTE)pre->pvResData + pcvtfh->dpOffsetTable + 2;
  383. UINT cGlyphs = pcvtfh->chLastChar - pcvtfh->chFirstChar + 1;
  384. PBYTE pjOffsetEnd;
  385. if (pcvtfh->iVersion == 0x00000200)
  386. {
  387. // in 2.0 offsets are 16 bit
  388. if (dpBits != (PTRDIFF)(*((PUSHORT)pjFirstOffset)))
  389. return(bDbgPrintAndFail("BMFD!2.0 pjFirstOffset \n"));
  390. if (pcvtfh->dpOffsetTable + 2 + (cGlyphs * 4) > pre->cjResData)
  391. return(bDbgPrintAndFail("BMFD!2.0 OffsetTable out of file \n"));
  392. // 4 is sizeof(TYPE2TABLE) as defined and used in fdquery.c
  393. pjOffsetEnd = pjFirstOffset + cGlyphs * 4;
  394. for ( ; pjFirstOffset < pjOffsetEnd; pjFirstOffset += 4)
  395. {
  396. if ((ULONG)READ_WORD(pjFirstOffset) > cjSize)
  397. return bDbgPrintAndFail("BMFD!invalid offset in 2.0 bm font\n");
  398. }
  399. }
  400. else // 3.0 guarantedd by the very first check
  401. {
  402. // in 3.0 offsets are 32 bit
  403. if (dpBits != (PTRDIFF)ulMakeULONG(pjFirstOffset))
  404. return(bDbgPrintAndFail("BMFD!3.0 pjFirstOffset \n"));
  405. if (pcvtfh->dpOffsetTable + 2 + (cGlyphs * 6) > pre->cjResData)
  406. return(bDbgPrintAndFail("BMFD!3.0 OffsetTable out of file \n"));
  407. // 6 is sizeof(TYPE3TABLE) as defined and used in fdquery.c
  408. pjOffsetEnd = pjFirstOffset + cGlyphs * 6;
  409. for ( ; pjFirstOffset < pjOffsetEnd; pjFirstOffset += 6)
  410. {
  411. if (READ_DWORD(pjFirstOffset) > cjSize)
  412. return bDbgPrintAndFail("BMFD!invalid offset in 3.0 bm font\n");
  413. }
  414. }
  415. }
  416. // check 3.0 fields if necessary
  417. if (pcvtfh->iVersion == 0x00000300)
  418. {
  419. FSHORT fsFlags = usMakeUSHORT ((PBYTE)&ajHdr[OFF_Flags]);
  420. if (fsFlags & (DFF_16COLOR | DFF_256COLOR | DFF_RGBCOLOR))
  421. return(bDbgPrintAndFail("BMFD!Flags: Do not support color fonts\n"));
  422. if (lMakeLONG((PBYTE)pre->pvResData + OFF_ColorPointer))
  423. return(bDbgPrintAndFail("BMFD!dpColor: Do not support color fonts\n"));
  424. }
  425. return(TRUE);
  426. }
  427. /******************************Public*Routine******************************\
  428. * bVerifyFNT
  429. *
  430. * Combine the two routines into a single one
  431. *
  432. * History:
  433. * 27-Jan-1992 -by- Bodin Dresevic [BodinD]
  434. * Wrote it.
  435. \**************************************************************************/
  436. BOOL
  437. bVerifyFNT(
  438. PCVTFILEHDR pcvtfh,
  439. PRES_ELEM pre
  440. )
  441. {
  442. #ifdef DUMPCALL
  443. DbgPrint("\nbVerifyFNT(" );
  444. DbgPrint("\n PCVTFILEHDR pcvtfh = %-#8lx", pcvtfh );
  445. DbgPrint("\n PRES_ELEM pre = %-#8lx", pre );
  446. DbgPrint("\n )\n" );
  447. #endif
  448. // read nonalligned header data at the top of the view into an alligned structure
  449. vAlignHdrData(pcvtfh,pre);
  450. // make sure that the data matches requirements of a windows bitmap font
  451. return(bVerifyResource(pcvtfh,pre));
  452. }
  453. /******************************Public*Routine******************************\
  454. *
  455. * BOOL bBmfdLoadFont // forward declaration
  456. *
  457. * Loads an *.fon or an *.fnt file,
  458. * returns handle to a fonfile object if successfull
  459. *
  460. * History:
  461. * 27-Jan-1992 -by- Bodin Dresevic [BodinD]
  462. * Wrote it.
  463. \**************************************************************************/
  464. BOOL bBmfdLoadFont // forward declaration
  465. (
  466. HFF iFile,
  467. PBYTE pvView,
  468. ULONG cjView,
  469. ULONG iType,
  470. HFF *phff
  471. )
  472. {
  473. PFONTFILE pff;
  474. ULONG cjff;
  475. WINRESDATA wrd;
  476. RES_ELEM re;
  477. ULONG ifnt;
  478. ULONG cjDescription; // size of the desctiption string (in bytes)
  479. PTRDIFF dpwszDescription; // offset to the description string
  480. CHAR achDescription[256]; // this is the max length of string
  481. // in the 16-bit EXE format.
  482. ULONG cjBMFDIFIMETRICS;
  483. #ifdef FE_SB // hffLoadFont()
  484. ULONG cFontResIncludeVert;
  485. #endif // FE_SB
  486. ULONG dpIFI;
  487. IFIMETRICS *pifi;
  488. *phff = (HFF)NULL;
  489. #ifdef DUMPCALL
  490. DbgPrint("\nbBmfdLoadFont(" );
  491. DbgPrint("\n ULONG iType = %-#8lx" );
  492. DbgPrint("\n )\n" );
  493. #endif
  494. ASSERTGDI((iType == TYPE_DLL16) || (iType == TYPE_FNT) || ((iType == TYPE_EXE)),
  495. "bmfd!bBmfdLoadFont(): unknown iType\n");
  496. // If .FON format, there are possibly multiple font resources. Handle it.
  497. if (iType == TYPE_DLL16)
  498. {
  499. if (!bInitWinResData(pvView,cjView,&wrd))
  500. {
  501. return FALSE;
  502. }
  503. }
  504. // Otherwise, if .FNT format, the current file view may be used.
  505. else // fnt
  506. {
  507. re.pvResData = pvView;
  508. re.dpResData = 0;
  509. re.cjResData = cjView;
  510. re.pjFaceName = NULL; // get the face name from the FNT resource
  511. wrd.cFntRes = 1;
  512. }
  513. // If .FON format, retrieve the description string (because we won't have
  514. // the mapped file view later and therefore cannot search for it later).
  515. #ifdef FE_SB // hffLoadFont()
  516. // We assume font all font resource is SHIFT_JIS font. We prepare room for Vertical font
  517. cjff = offsetof(FONTFILE,afai) + ( wrd.cFntRes * 2 ) * sizeof(FACEINFO);
  518. #else
  519. cjff = offsetof(FONTFILE,afai) + wrd.cFntRes * sizeof(FACEINFO);
  520. #endif
  521. dpwszDescription = 0; // no description string, use Facename later
  522. cjDescription = 0;
  523. if ((iType == TYPE_DLL16) && bDescStr(pvView, cjView, achDescription))
  524. {
  525. dpwszDescription = cjff;
  526. cjDescription = (strlen(achDescription) + 1) * sizeof(WCHAR);
  527. cjff += cjDescription;
  528. }
  529. // remember where the first ifimetrics goes
  530. dpIFI = cjff = ALIGN_UP( cjff, PVOID );
  531. // compute the total amount of memory needed for the ifimetrics and everything
  532. // else:
  533. for (ifnt = 0L; ifnt < wrd.cFntRes; ifnt++)
  534. {
  535. if (iType == TYPE_DLL16)
  536. {
  537. if (!bGetFntResource(&wrd,ifnt,&re))
  538. return FALSE;
  539. }
  540. // do a preliminary check on the resource, before doing a thorough one
  541. if (!bVerifyFNTQuick(&re))
  542. return FALSE;
  543. if (!bBMFDIFIMETRICS(pvView, cjView, NULL, &re, &cjBMFDIFIMETRICS))
  544. return FALSE;
  545. #ifdef FE_SB
  546. cjff += ( cjBMFDIFIMETRICS * 2 );
  547. #else
  548. cjff += cjBMFDIFIMETRICS;
  549. #endif
  550. }
  551. // Allocate a FONTFILE of the appropriate size from the handle manager.
  552. if ((*phff = hffAlloc(cjff)) == HFF_INVALID)
  553. {
  554. SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
  555. RETURN("bmfd!bBmfdLoadFont(): memory allocation error\n", FALSE);
  556. }
  557. pff = PFF(*phff);
  558. // Init fields of pff structure
  559. pff->ident = ID_FONTFILE;
  560. pff->fl = 0;
  561. pff->iType = iType;
  562. pff->iFile = iFile; // will be needed at unload time
  563. pff->cFntRes = wrd.cFntRes;
  564. pff->cjDescription = cjDescription;
  565. pff->dpwszDescription = dpwszDescription;
  566. // Convert each of the font resources (RES_ELEM) to a CVTRESDATA and a
  567. // (set of) FACEDATA.
  568. pifi = (IFIMETRICS *)((PBYTE)pff + dpIFI);
  569. #ifdef FE_SB // bBmfdLoadFont()
  570. // We have to compute strict font face count include simulated @face
  571. // ifnt = Physical font counter
  572. // cFontResIncludeVert = FACEINFO structure counter
  573. cFontResIncludeVert = 0;
  574. for (ifnt = 0L; ifnt < wrd.cFntRes; ifnt++)
  575. {
  576. // At first We process for nomal face font
  577. if (iType == TYPE_DLL16)
  578. {
  579. if (!bGetFntResource(&wrd,ifnt,&re))
  580. {
  581. VFREEMEM(*phff);
  582. *phff = (HFF)NULL;
  583. return FALSE;
  584. }
  585. }
  586. pff->afai[cFontResIncludeVert].re = re; // remember this for easier access later
  587. pff->afai[cFontResIncludeVert].bVertical = FALSE;
  588. pff->afai[cFontResIncludeVert].pifi = pifi;
  589. if (!bConvertFontRes(pvView, cjView, &re, &pff->afai[cFontResIncludeVert]))
  590. {
  591. #ifdef DBG_NTRES
  592. WARNING("bmfd!hffLoadFont(): file format conversion failed\n");
  593. #endif // DBG_NTRES
  594. VFREEMEM(*phff);
  595. *phff = (HFF)NULL;
  596. return FALSE;
  597. }
  598. // Count Nomal face font
  599. cFontResIncludeVert ++;
  600. // Point it to next room
  601. pifi = (IFIMETRICS *)((PBYTE)pifi + pifi->cjThis);
  602. //
  603. // Check this font resource's Charset is some DBCS charset. If it is so , Set up
  604. // Vertical font stuff. Or not so. Increment counter.
  605. //
  606. // if the font is for DBCS font, usDBCSWidth is not be zero, the value is setted
  607. // above bConvertFontRes().
  608. //
  609. if( (pff->afai[cFontResIncludeVert - 1].cvtfh.usDBCSWidth) != 0 )
  610. {
  611. // Vertical Writting use the same font at SBCS CodeArea
  612. pff->afai[cFontResIncludeVert].re = re;
  613. // Vertical Writting use the different font at DBCS CoreArea
  614. pff->afai[cFontResIncludeVert].bVertical = TRUE;
  615. pff->afai[cFontResIncludeVert].pifi = pifi;
  616. // Convert font resource and setup CVTFILEHDR and IFIMETRICS
  617. if ( !bConvertFontRes(pvView, cjView, &re, &pff->afai[cFontResIncludeVert]))
  618. {
  619. #ifdef DBG_NTRES
  620. WARNING("bmfd!hffLoadFont(): file format conversion failed at Vertical font\n");
  621. #endif // DBG_NTRES
  622. VFREEMEM(*phff);
  623. *phff = (HFF)NULL;
  624. return FALSE;
  625. }
  626. // Count Vertical face font
  627. cFontResIncludeVert ++;
  628. // Point it to next room
  629. pifi = (IFIMETRICS *)((PBYTE)pifi + pifi->cjThis);
  630. }
  631. }
  632. // We have strictly font resource count include simulated Vertical font now
  633. // Reset font resource count in FONTFILE structure
  634. pff->cFntRes = cFontResIncludeVert;
  635. #else
  636. for (ifnt = 0L; ifnt < wrd.cFntRes; ifnt++)
  637. {
  638. if (iType == TYPE_DLL16)
  639. {
  640. if (!bGetFntResource(&wrd,ifnt,&re))
  641. {
  642. VFREEMEM(*phff);
  643. *phff = (HFF)NULL;
  644. return FALSE;
  645. }
  646. }
  647. pff->afai[ifnt].re = re; // remember this for easier access later
  648. pff->afai[ifnt].pifi = pifi; // remember this for easier access later
  649. if (!bConvertFontRes(pvView, cjView, &re, &pff->afai[ifnt]))
  650. {
  651. #ifdef DBG_NTRES
  652. WARNING("bmfd!bBmfdLoadFont(): file format conversion failed\n");
  653. #endif // DBG_NTRES
  654. VFREEMEM(*phff);
  655. *phff = (HFF)NULL;
  656. return FALSE;
  657. }
  658. pifi = (IFIMETRICS *)((PBYTE)pifi + pifi->cjThis);
  659. }
  660. #endif
  661. // If we found a description string, store it in the FONTFILE.
  662. if (cjDescription != 0)
  663. vToUNICODEN((PWSZ) ((PBYTE) pff + dpwszDescription), cjDescription/sizeof(WCHAR), achDescription, cjDescription/sizeof(WCHAR));
  664. // Initialize the rest.
  665. pff->cRef = 0;
  666. return TRUE;
  667. }
  668. /******************************Public*Routine******************************\
  669. * jFamilyType(FSHORT fsPitchAndFamily)
  670. *
  671. * computes jFamilyType field of the panose structure
  672. *
  673. * History:
  674. * 19-Dec-1990 -by- Bodin Dresevic [BodinD]
  675. * Wrote it.
  676. \**************************************************************************/
  677. BYTE
  678. jFamilyType(
  679. FSHORT fsPitchAndFamily
  680. )
  681. {
  682. BYTE j;
  683. if (fsPitchAndFamily & FF_DONTCARE)
  684. j = PAN_ANY;
  685. else if (fsPitchAndFamily & FF_SCRIPT)
  686. j = PAN_FAMILY_SCRIPT;
  687. else if (fsPitchAndFamily & FF_DECORATIVE)
  688. j = PAN_FAMILY_DECORATIVE;
  689. else
  690. {
  691. j = PAN_FAMILY_TEXT_DISPLAY;
  692. }
  693. return(j);
  694. }
  695. /******************************Public*Routine******************************\
  696. * bConvertFontRes
  697. *
  698. * format of the converted file:
  699. *
  700. * converted header on the top, followed by array of IFIMETRICS structures,
  701. * followed by the table of offsets to GLYPHDATA structures for individual
  702. * glyphs, followed by an array of GLYPHDATA structures themselves
  703. *
  704. * Warnings:
  705. *
  706. * History:
  707. * January 2002 -by- Jay Krell [JayKrell]
  708. * range check memory mapped i/o
  709. * 13-Nov-1990 -by- Bodin Dresevic [BodinD]
  710. * Wrote it.
  711. \**************************************************************************/
  712. BOOL
  713. bConvertFontRes(
  714. PVOID pvView,
  715. SIZE_T cjView,
  716. PRES_ELEM pre, // IN
  717. FACEINFO *pfai // OUT
  718. )
  719. {
  720. BOOL bResult;
  721. bResult = FALSE;
  722. #ifdef DUMPCALL
  723. DbgPrint("\nbConverFontRes(\n" );
  724. DbgPrint(" PRES_ELEM pre = %-#8lx\n",pre );
  725. DbgPrint(" FACEINFO *pfai = %-#8lx\n",pfai);
  726. DbgPrint(" );\n\n" );
  727. #endif
  728. // make sure that the data matches requirements of a windows bitmap font
  729. // Note: bVerifyFNT() does more than just look at the font -- it does
  730. // part of the conversion by copying the data to the CVFILEHDR
  731. // "converted file header"
  732. //
  733. if(!bVerifyFNT(&pfai->cvtfh,pre))
  734. {
  735. goto Exit;
  736. }
  737. ASSERTGDI(pfai->cvtfh.dpOffsetTable != -1L, "BMFD!bConvertFontRes(): could not align header\n");
  738. // compute the size of the IFIMETRICS structure that is followed by
  739. // FamilyName, FaceName and UniqueName UNICODE strings and simulations
  740. if (!bBMFDIFIMETRICS(pvView, cjView, &pfai->cvtfh, pre, NULL))
  741. {
  742. goto Exit;
  743. }
  744. // compute the size of the converted file to be created, fix bugs in file header
  745. vCheckOffsetTable(&pfai->cvtfh, pre);
  746. // calucate pfai->iDefFace
  747. vDefFace(pfai,pre);
  748. // compute glyph set that corresponds to this resource:
  749. EngAcquireSemaphore(ghsemBMFD);
  750. pfai->pcp = pcpComputeGlyphset(&gpcpGlyphsets,
  751. (UINT) pfai->cvtfh.chFirstChar,
  752. (UINT) pfai->cvtfh.chLastChar,
  753. ((PBYTE)pre->pvResData)[OFF_CharSet]);
  754. EngReleaseSemaphore(ghsemBMFD);
  755. if (pfai->pcp == NULL)
  756. {
  757. // If we fail it should be because of we are out of memory.
  758. SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
  759. WARNING("BMFD!bConvertFontRes(): memory allocation error\n");
  760. goto Exit;
  761. }
  762. // fill the ifimetrics
  763. vBmfdFill_IFIMETRICS(pfai,pre);
  764. bResult = TRUE;
  765. Exit:
  766. #if DBG
  767. if (!bResult)
  768. {
  769. NotifyBadFont("WIN32K: %s failing\n", __FUNCTION__);
  770. }
  771. #endif
  772. return bResult;
  773. }
  774. /******************************Public*Routine******************************\
  775. * bBMFDIFIMETRICS
  776. *
  777. * Effects: returns the size cjIFI of IFIMETRICS struct, with appended strings
  778. * caches the lengths of these strings,pszFamilyName, and cjIFI
  779. * for later use by vBmfdFill_IFIMETRICS
  780. * Warnings:
  781. *
  782. * History:
  783. * January 2002 -by- Jay Krell [JayKrell]
  784. * range check memory mapped i/o
  785. * 20-Oct-1992 -by- Kirk Olynyk [kirko]
  786. * The IFIMETRICS structure has changed. The effect of the change upon
  787. * this procedure is to allocate room for the new simulation structure
  788. * FONTDIFF which informs GDI of the available simulations.
  789. * 20-Nov-1990 -by- Bodin Dresevic [BodinD]
  790. * Wrote it.
  791. \**************************************************************************/
  792. BOOL
  793. bBMFDIFIMETRICS(
  794. PVOID pvView,
  795. SIZE_T cjView,
  796. PCVTFILEHDR pcvtfh OPTIONAL,
  797. PRES_ELEM pre,
  798. OUT PULONG pcjIFIOut OPTIONAL
  799. )
  800. {
  801. // face name lives in the original file
  802. ULONG cSims;
  803. ULONG cjIFI;
  804. ULONG cjFaceName;
  805. PSZ pszFaceName;
  806. BOOL bResult;
  807. SIZE_T pszFaceNameLength;
  808. bResult = FALSE;
  809. if (pcjIFIOut != NULL)
  810. {
  811. *pcjIFIOut = 0;
  812. }
  813. if( pre->pjFaceName == NULL )
  814. {
  815. // get facename from FNT resource for non 16bit resource files
  816. pszFaceName = (PSZ)((PBYTE)pre->pvResData +
  817. lMakeLONG((PBYTE)pre->pvResData + OFF_Face));
  818. }
  819. else
  820. {
  821. // otherwise get facename from the FONTDIR resource for win 3.1
  822. // compatibility reasons
  823. pszFaceName = pre->pjFaceName;
  824. }
  825. if (!bMappedViewStrlen(pvView, cjView, pszFaceName, &pszFaceNameLength))
  826. {
  827. goto Exit;
  828. }
  829. // 1 is added to the length of a string in WCHAR's
  830. // so as to allow for the terminating zero character, the number of
  831. // WCHAR's is then multiplied by 2 to get the corresponding number of bytes,
  832. // which is then rounded up to a DWORD boundary for faster access
  833. #ifdef FE_SB // VERTICAL:cjIFIMETRICS(): make room for '@'
  834. cjFaceName = ALIGN4(sizeof(WCHAR) * (pszFaceNameLength + 1 + 1));
  835. #else
  836. cjFaceName = ALIGN4(sizeof(WCHAR) * (pszFaceNameLength + 1));
  837. #endif
  838. // the full size of IFIMETRICS is the size of the structure itself followed by
  839. // the appended strings AND the 3 FONTDIFF structures corresponding to the
  840. // BOLD, ITALIC, and BOLD_ITALIC simulations.
  841. cjIFI = sizeof(IFIMETRICS) + cjFaceName;
  842. if (cSims = (cFacesRes(pre) - 1))
  843. {
  844. cjIFI += sizeof(FONTSIM) + cSims * sizeof(FONTDIFF);
  845. }
  846. cjIFI = ALIGN_UP( cjIFI, PVOID );
  847. if (pcvtfh)
  848. {
  849. // cache the lengths of these strings for later use
  850. pcvtfh->cjFaceName = cjFaceName;
  851. pcvtfh->cjIFI = cjIFI;
  852. }
  853. // make sure that the result is a multiple of ULONG size, otherwise we may
  854. // have a problem when making arrays of IFIMETRICS structures
  855. ASSERTGDI((cjIFI & 3L) == 0L, "ifi is not DWORD alligned\n");
  856. if (pcjIFIOut != NULL)
  857. {
  858. *pcjIFIOut = cjIFI;
  859. }
  860. bResult = TRUE;
  861. Exit:
  862. #if DBG
  863. if (!bResult)
  864. {
  865. NotifyBadFont("WIN32K: %s failing\n", __FUNCTION__);
  866. }
  867. #endif
  868. return bResult;
  869. }
  870. /******************************Public*Routine******************************\
  871. * bNonZeroRow
  872. *
  873. * History:
  874. * 21-Jun-1992 -by- Bodin Dresevic [BodinD]
  875. * Wrote it.
  876. \**************************************************************************/
  877. BOOL
  878. bNonZeroRow(
  879. PBYTE pjRow,
  880. ULONG cy,
  881. ULONG cjWidth
  882. )
  883. {
  884. ULONG ij; // index into a byte
  885. for (ij = 0; ij < cjWidth; ij++, pjRow += cy)
  886. {
  887. if (*pjRow)
  888. {
  889. return(TRUE);
  890. }
  891. }
  892. return(FALSE); // zero scan
  893. }
  894. /******************************Public*Routine******************************\
  895. * vFindTAndB
  896. *
  897. * computes top and bottom of the ink using the bits in the raw fnt format
  898. *
  899. * History:
  900. * 21-Jun-1992 -by- Bodin Dresevic [BodinD]
  901. * Wrote it.
  902. \**************************************************************************/
  903. VOID
  904. vFindTAndB(
  905. PBYTE pjBitmap, // pointer to the bitmap in *.fnt column format
  906. ULONG cx,
  907. ULONG cy,
  908. ULONG *pyTopIncMin,
  909. ULONG *pyBottomExcMax
  910. )
  911. {
  912. ULONG cjWidth = CJ_SCAN(cx); // # of bytes in row of the bitmap in the *.fnt format
  913. PBYTE pjRow;
  914. PBYTE pjRowEnd;
  915. #ifdef DUMPCALL
  916. DbgPrint("\nvFindTAndB(\n" );
  917. DbgPrint(" PBYTE pjBitmap = %-#8lx\n",pjBitmap );
  918. DbgPrint(" ULONG cx = %d\n",cx );
  919. DbgPrint(" ULONG cy = %d\n",cy );
  920. DbgPrint(" ULONG *pyTopIncMin = %-#8lx\n",pyTopIncMin );
  921. DbgPrint(" ULONG *pyBottomExcMax = %-#8lx\n",pyBottomExcMax );
  922. DbgPrint(" );\n\n" );
  923. #endif
  924. /* default them to null in every case to prevent accessing unitialized data
  925. in the case the bitmap is null, or all it's row are filled with zero */
  926. *pyTopIncMin = *pyBottomExcMax = 0;
  927. // case of zero width glyphs
  928. if (!pjBitmap)
  929. {
  930. // no ink at all, out of here
  931. ASSERTGDI(cx == 0, "bmfd, vFindTAndB, cx != 0\n");
  932. return;
  933. }
  934. // real glyphs
  935. for
  936. (
  937. pjRow = pjBitmap, pjRowEnd = pjRow + cy;
  938. pjRow < pjRowEnd;
  939. pjRow++
  940. )
  941. {
  942. if (bNonZeroRow(pjRow, cy, cjWidth))
  943. {
  944. *pyTopIncMin = (ULONG)(pjRow - pjBitmap);
  945. break;
  946. }
  947. }
  948. if (pjRow == pjRowEnd)
  949. {
  950. // no ink at all, out of here
  951. return;
  952. }
  953. // start searhing backwards for the bottom
  954. for
  955. (
  956. pjRow = pjBitmap + (cy - 1);
  957. pjRow >= pjBitmap;
  958. pjRow--
  959. )
  960. {
  961. if (bNonZeroRow(pjRow, cy, cjWidth))
  962. {
  963. *pyBottomExcMax = (ULONG)((pjRow - pjBitmap) + 1); // + 1 for exclusiveness
  964. break;
  965. }
  966. }
  967. ASSERTGDI(*pyTopIncMin <= *pyBottomExcMax, "BMFD!top>bottom\n");
  968. }
  969. /******************************Public*Routine******************************\
  970. * vComputeSpecialChars
  971. *
  972. * Effects:
  973. * compute special characters taking into account character set
  974. * Not quite sure what to do when char set is not ansi. It is really
  975. * to figure out what to do for a "font" where glyph bitmaps
  976. * are pushbuttons etc.
  977. * This routine will clearly blow up when a char set is catacana
  978. * This is char set == 37 (amisym)
  979. *
  980. * History:
  981. * 28-Nov-1990 -by- Bodin Dresevic [BodinD]
  982. * Wrote it.
  983. \**************************************************************************/
  984. VOID
  985. vComputeSpecialChars(
  986. PCVTFILEHDR pcvtfh,
  987. PWCHAR pwcDefaultChar,
  988. PWCHAR pwcBreakChar
  989. )
  990. {
  991. UCHAR chDefault = pcvtfh->chDefaultChar + pcvtfh->chFirstChar;
  992. UCHAR chBreak = pcvtfh->chBreakChar + pcvtfh->chFirstChar;
  993. // Default and Break chars are given relative to the first chaR
  994. RtlMultiByteToUnicodeN(pwcDefaultChar, sizeof(WCHAR), NULL, &chDefault, 1);
  995. RtlMultiByteToUnicodeN(pwcBreakChar, sizeof(WCHAR), NULL, &chBreak, 1);
  996. }
  997. /******************************Public*Routine******************************\
  998. * vBmfdFill_IFIMETRICS
  999. *
  1000. * Effects:
  1001. * fills the fields of the IFIMETRICS structure using the info from
  1002. * the converted and the original font file and converted file header
  1003. *
  1004. *
  1005. * History:
  1006. * Fri 24-Jun-1994 20:30:41 by Kirk Olynyk [kirko]
  1007. * Changed the test for pitch to look at PixWidth.
  1008. * 20-Oct-92 by Kirk Olynyk [kirko]
  1009. * Made changes to be compatible with the new and improved IFIMETRICS
  1010. * structure.
  1011. * Fri 24-Jan-1992 07:56:16 by Kirk Olynyk [kirko]
  1012. * Changed the way EmHeight is calculated.
  1013. * Fri 18-Oct-1991 10:36:43 by Kirk Olynyk [kirko]
  1014. * Changed the InlineDir, CharRot, CharSlope, and WidthClass
  1015. * to be expressed as POINTL's.
  1016. * 23-Jul-1991 Gilman Wong [gilmanw]
  1017. * Fixed PANOSE numbers for jFamily and jSerifStyle.
  1018. * 12-Nov-1990 -by- Bodin Dresevic [BodinD]
  1019. * Wrote it.
  1020. \**************************************************************************/
  1021. VOID
  1022. vBmfdFill_IFIMETRICS(
  1023. FACEINFO *pfai,
  1024. PRES_ELEM pre
  1025. )
  1026. {
  1027. FWORD fwdHeight;
  1028. FONTSIM *pFontSim;
  1029. FONTDIFF *pfdiffBold = 0, *pfdiffItalic = 0, *pfdiffBoldItalic = 0;
  1030. PANOSE *ppanose;
  1031. ULONG cchFaceName;
  1032. PBYTE ajHdr = (PBYTE)pre->pvResData;
  1033. FWORD sAscent,sIntLeading;
  1034. #ifdef FE_SB // vBmfdFill_IFIMETRICS()
  1035. BOOL bDBCSFont = (pfai->cvtfh.usDBCSWidth != 0 ? TRUE : FALSE);
  1036. #endif // FE_SB
  1037. // compute pointers to the various sections of the converted file
  1038. PCVTFILEHDR pcvtfh = &pfai->cvtfh;
  1039. PIFIMETRICS pifi = pfai->pifi;
  1040. // face name lives in the original file, this is the only place pvView is used
  1041. PSZ pszFaceName;
  1042. // Either grab the facename from the FONTDIR or the FNT resources depending
  1043. // on wether or not this is a 16bit font resource.
  1044. if( pre->pjFaceName == NULL )
  1045. {
  1046. pszFaceName = (PSZ)(ajHdr + lMakeLONG((PBYTE)&ajHdr[OFF_Face]));
  1047. }
  1048. else
  1049. {
  1050. pszFaceName = pre->pjFaceName;
  1051. }
  1052. #ifdef DUMPCALL
  1053. DbgPrint("\nvBmfdFill_IFIMETRICS(\n" );
  1054. DbgPrint(" FACEINFO *pfai = %-#8lx\n", pfai );
  1055. DbgPrint(" PRES_ELEM pre = %-#8lx\n", pre );
  1056. DbgPrint(" );\n\n" );
  1057. #endif
  1058. pifi->cjIfiExtra = 0;
  1059. //
  1060. // the string begins on a DWORD aligned address.
  1061. //
  1062. pifi->dpwszFaceName = OFFSET_OF_NEXT(DWORD,sizeof(IFIMETRICS));
  1063. // face name == family name for bitmap fonts [Win3.0 compatibility]
  1064. pifi->dpwszFamilyName = pifi->dpwszFaceName;
  1065. //
  1066. // these names don't exist, so point to the NULL char [Win3.1 compatibility]
  1067. // Note: lstrlen() does not count the terminating NULL.
  1068. //
  1069. cchFaceName = strlen(pszFaceName);
  1070. pifi->dpwszStyleName =
  1071. pifi->dpwszFaceName + sizeof(WCHAR) * cchFaceName;
  1072. pifi->dpwszUniqueName = pifi->dpwszStyleName;
  1073. // copy the strings to their new location. Here we assume that the sufficient
  1074. // memory has been allocated
  1075. #ifdef FE_SB // vBmfdFill_IFIMETRICS():Add @ to face name
  1076. if( pfai->bVertical )
  1077. {
  1078. vToUNICODEN((PWSZ)((PBYTE)pifi + pifi->dpwszFaceName + sizeof(WCHAR)),
  1079. cchFaceName+1, pszFaceName, cchFaceName+1);
  1080. // Insert @
  1081. *(PWCHAR)((PBYTE)pifi + pifi->dpwszFaceName) = L'@';
  1082. }
  1083. else
  1084. {
  1085. #endif // FE_SB
  1086. vToUNICODEN((PWSZ)((PBYTE)pifi + pifi->dpwszFaceName), cchFaceName+1, pszFaceName, cchFaceName+1);
  1087. #ifdef FE_SB
  1088. }
  1089. #endif // DBCS_VERT
  1090. pifi->cjThis = pcvtfh->cjIFI;
  1091. //
  1092. // Check to see if simulations are necessary and if they are, fill
  1093. // in the offsets to the various simulation fields and update cjThis
  1094. // field of the IFIMETRICS structure
  1095. //
  1096. switch (pfai->iDefFace)
  1097. {
  1098. case FF_FACE_NORMAL:
  1099. case FF_FACE_BOLD:
  1100. case FF_FACE_ITALIC:
  1101. pifi->dpFontSim =
  1102. OFFSET_OF_NEXT(
  1103. DWORD,
  1104. sizeof(IFIMETRICS) + pcvtfh->cjFaceName
  1105. );
  1106. pFontSim = (FONTSIM*) ((BYTE*)pifi + pifi->dpFontSim);
  1107. switch (pfai->iDefFace)
  1108. {
  1109. case FF_FACE_NORMAL:
  1110. //
  1111. // simulations are needed for bold, italic, and bold-italic
  1112. //
  1113. pFontSim->dpBold =
  1114. OFFSET_OF_NEXT(DWORD,sizeof(FONTSIM));
  1115. pFontSim->dpItalic =
  1116. OFFSET_OF_NEXT(DWORD,pFontSim->dpBold + sizeof(FONTDIFF));
  1117. pFontSim->dpBoldItalic =
  1118. OFFSET_OF_NEXT(DWORD,pFontSim->dpItalic + sizeof(FONTDIFF));
  1119. pfdiffBold =
  1120. (FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBold);
  1121. pfdiffItalic =
  1122. (FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpItalic);
  1123. pfdiffBoldItalic =
  1124. (FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBoldItalic);
  1125. break;
  1126. case FF_FACE_BOLD:
  1127. case FF_FACE_ITALIC:
  1128. //
  1129. // a simulation is needed for bold-italic only
  1130. //
  1131. pFontSim->dpBold = 0;
  1132. pFontSim->dpItalic = 0;
  1133. pFontSim->dpBoldItalic = OFFSET_OF_NEXT(DWORD,sizeof(FONTSIM));
  1134. pfdiffBoldItalic =
  1135. (FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBoldItalic);
  1136. break;
  1137. default:
  1138. RIP("BMFD -- bad iDefFace\n");
  1139. }
  1140. break;
  1141. case FF_FACE_BOLDITALIC:
  1142. pifi->dpFontSim = 0;
  1143. break;
  1144. default:
  1145. RIP("vBmfdFill_IFIMETRICS -- bad iDefFace");
  1146. }
  1147. pifi->jWinCharSet = ajHdr[OFF_CharSet];
  1148. // There are two way to determine the pitch of a font.
  1149. //
  1150. // a) If the low nibble of ajHdr[OFF_Family] is not zero then
  1151. // the font is variable pitch otherwise it is fixed
  1152. // b) if ajHdr[OFF_PixWidth] is non zero then the font is
  1153. // fixed pitch and this is the character width otherwise
  1154. // the font is varialble pitch
  1155. //
  1156. // Under Windows, method b) is used to determine the pitch of
  1157. // a font. There exist buggy fonts in which methods a) and
  1158. // b) give different answers. An example is found in Issac
  1159. // Asimov's "The Ultimate Robot". For the font face "URPalatI"
  1160. // method a) indicates that the font is fixed pitch while
  1161. // method b) indicates that it is variable. The truth is that
  1162. // this font is varialbe pitch. So, we choose method b).
  1163. // Of course, if another font gives the correct answer for method
  1164. // a) and the incorrect answer for method b) then we will
  1165. // look bad.
  1166. // Mon 27-Jun-1994 06:58:46 by Kirk Olynyk [kirko]
  1167. pifi->jWinPitchAndFamily = ajHdr[OFF_Family] & 0xf0;
  1168. pifi->jWinPitchAndFamily |= ajHdr[OFF_PixWidth] ? FIXED_PITCH : VARIABLE_PITCH;
  1169. #ifdef MAYBE_NEEDED_FOR_MET
  1170. if (ajHdr[OFF_Family] & MONO_FONT)
  1171. {
  1172. // Have no idea what MONO_FONT is, some new win95 invetion
  1173. pifi->jWinPitchAndFamily |= MONO_FONT;
  1174. }
  1175. #endif
  1176. // weight, we have seen files where the weight has been 0 or some other junk
  1177. // we replace 400, our mapper would have done it anyway [bodind]
  1178. pifi->usWinWeight = usMakeUSHORT((PBYTE)&ajHdr[OFF_Weight]);
  1179. if ((pifi->usWinWeight > MAX_WEIGHT) || (pifi->usWinWeight < MIN_WEIGHT))
  1180. pifi->usWinWeight = 400;
  1181. pifi->flInfo = ( FM_INFO_TECH_BITMAP
  1182. | FM_INFO_RETURNS_BITMAPS
  1183. | FM_INFO_1BPP
  1184. | FM_INFO_INTEGER_WIDTH
  1185. | FM_INFO_RIGHT_HANDED
  1186. | FM_INFO_INTEGRAL_SCALING
  1187. | FM_INFO_NONNEGATIVE_AC
  1188. #ifdef FE_SB // vBmfdFill_IFIMETRICS():set FM_INFO_90DEGREE_ROTATIONS flag
  1189. | FM_INFO_90DEGREE_ROTATIONS
  1190. #endif
  1191. );
  1192. // we have set it correctly above, we want to make sure that somebody
  1193. // is not going to alter that code so as to break the code here
  1194. ASSERTGDI(
  1195. ((pifi->jWinPitchAndFamily & 0xf) == FIXED_PITCH) || ((pifi->jWinPitchAndFamily & 0xf) == VARIABLE_PITCH),
  1196. "BMFD!WRONG PITCH \n"
  1197. );
  1198. #ifdef FE_SB // vBmfdFill_IFIMETRICS():remove FM_INFO_CONSTANT_WIDTH flag
  1199. if ((pifi->jWinPitchAndFamily & 0xf) == FIXED_PITCH)
  1200. {
  1201. if( !bDBCSFont )
  1202. pifi->flInfo |= FM_INFO_CONSTANT_WIDTH;
  1203. pifi->flInfo |= FM_INFO_OPTICALLY_FIXED_PITCH;
  1204. }
  1205. // Bmfd treat only FIXED pitch font in full width character, We report this infomation to GRE
  1206. // for optimaization
  1207. if( bDBCSFont )
  1208. {
  1209. pifi->flInfo |= FM_INFO_DBCS_FIXED_PITCH;
  1210. }
  1211. #else
  1212. if ((pifi->jWinPitchAndFamily & 0xf) == FIXED_PITCH)
  1213. {
  1214. pifi->flInfo |= FM_INFO_CONSTANT_WIDTH;
  1215. pifi->flInfo |= FM_INFO_OPTICALLY_FIXED_PITCH;
  1216. }
  1217. #endif
  1218. pifi->lEmbedId = 0;
  1219. pifi->fsSelection = fsSelectionFlags(ajHdr);
  1220. //
  1221. // The choices for fsType are FM_TYPE_LICENSED and FM_READONLY_EMBED
  1222. // These are TrueType things and do not apply to old fashioned bitmap
  1223. // fonts.
  1224. //
  1225. pifi->fsType = 0;
  1226. sIntLeading = sMakeSHORT((PBYTE)&ajHdr[OFF_IntLeading]);
  1227. pifi->fwdUnitsPerEm = (sIntLeading > 0) ?
  1228. (FWORD)pcvtfh->cy - sIntLeading : (FWORD)pcvtfh->cy;
  1229. pifi->fwdLowestPPEm = 0;
  1230. sAscent = (FWORD)sMakeSHORT((PBYTE)&ajHdr[OFF_Ascent]);
  1231. pifi->fwdWinAscender = sAscent;
  1232. pifi->fwdWinDescender = (FWORD)pcvtfh->cy - sAscent;
  1233. pifi->fwdMacAscender = sAscent;
  1234. pifi->fwdMacDescender = -pifi->fwdWinDescender;
  1235. pifi->fwdMacLineGap = (FWORD)sMakeSHORT((PBYTE)&ajHdr[OFF_ExtLeading]);
  1236. pifi->fwdTypoAscender = pifi->fwdMacAscender;
  1237. pifi->fwdTypoDescender = pifi->fwdMacDescender;
  1238. pifi->fwdTypoLineGap = pifi->fwdMacLineGap;
  1239. pifi->fwdMaxCharInc = (FWORD)pcvtfh->usMaxWidth;
  1240. pifi->fwdAveCharWidth = (FWORD)usMakeUSHORT((PBYTE)&ajHdr[OFF_AvgWidth]);
  1241. if (pifi->fwdAveCharWidth > pcvtfh->usMaxWidth)
  1242. {
  1243. // fix the bug in the header if there is one
  1244. pifi->fwdAveCharWidth = pcvtfh->usMaxWidth;
  1245. }
  1246. // don't know much about SuperScripts
  1247. pifi->fwdSubscriptXSize = 0;
  1248. pifi->fwdSubscriptYSize = 0;
  1249. pifi->fwdSubscriptXOffset = 0;
  1250. pifi->fwdSubscriptYOffset = 0;
  1251. //
  1252. // don't know much about SubScripts
  1253. //
  1254. pifi->fwdSuperscriptXSize = 0;
  1255. pifi->fwdSuperscriptYSize = 0;
  1256. pifi->fwdSuperscriptXOffset = 0;
  1257. pifi->fwdSuperscriptYOffset = 0;
  1258. //
  1259. // win 30 magic. see the code in textsims.c in the Win 3.1 sources
  1260. //
  1261. fwdHeight = pifi->fwdWinAscender + pifi->fwdWinDescender;
  1262. pifi->fwdUnderscoreSize = (fwdHeight > 12) ? (fwdHeight / 12) : 1;
  1263. pifi->fwdUnderscorePosition = -(FWORD)(pifi->fwdUnderscoreSize / 2 + 1);
  1264. pifi->fwdStrikeoutSize = pifi->fwdUnderscoreSize;
  1265. {
  1266. // We are further adjusting underscore position if underline
  1267. // hangs below char stems.
  1268. // The only font where this effect is noticed to
  1269. // be important is an ex pm font sys08cga.fnt, presently used in console
  1270. FWORD yUnderlineBottom = -pifi->fwdUnderscorePosition
  1271. + ((pifi->fwdUnderscoreSize + (FWORD)1) >> 1);
  1272. FWORD dy = yUnderlineBottom - pifi->fwdWinDescender;
  1273. if (dy > 0)
  1274. {
  1275. #ifdef CHECK_CRAZY_DESC
  1276. DbgPrint("bmfd: Crazy descender: old = %ld, adjusted = %ld\n\n",
  1277. (ULONG)pifi->fwdMaxDescender,
  1278. (ULONG)yUnderlineBottom);
  1279. #endif // CHECK_CRAZY_DESC
  1280. pifi->fwdUnderscorePosition += dy;
  1281. }
  1282. }
  1283. //
  1284. // Win 3.1 method
  1285. //
  1286. // LineOffset = ((((Ascent-IntLeading)*2)/3) + IntLeading)
  1287. //
  1288. // [remember that they measure the offset from the top of the cell,
  1289. // where as NT measures offsets from the baseline]
  1290. //
  1291. pifi->fwdStrikeoutPosition =
  1292. (FWORD) ((sAscent - sIntLeading + 2)/3);
  1293. pifi->chFirstChar = pcvtfh->chFirstChar;
  1294. pifi->chLastChar = pcvtfh->chLastChar;
  1295. pifi->chBreakChar = pcvtfh->chBreakChar + pcvtfh->chFirstChar;
  1296. // chDefault: here we are just putting the junk from the header, which we
  1297. // know may be wrong but this is what win31 is reporting.
  1298. // E.g. for SmallFonts (shipped with win31) they report
  1299. // 128 as default even though it is not even supported in a font.
  1300. // In NT however, we must report an existent char as default char to
  1301. // the engine. So for buggy fonts we break the relationship
  1302. // wcDefault == AnsiToUnicode(chDefault);
  1303. pifi->chDefaultChar = ((PBYTE)pre->pvResData)[OFF_DefaultChar] +
  1304. ((PBYTE)pre->pvResData)[OFF_FirstChar] ;
  1305. // wcDefaultChar
  1306. // wcBreakChar
  1307. vComputeSpecialChars(
  1308. pcvtfh,
  1309. &(pifi->wcDefaultChar),
  1310. &(pifi->wcBreakChar)
  1311. );
  1312. // These should be taken from the glyph set
  1313. {
  1314. FD_GLYPHSET * pgset = &pfai->pcp->gset;
  1315. WCRUN *pwcrunLast = &(pgset->awcrun[pgset->cRuns - 1]);
  1316. pifi->wcFirstChar = pgset->awcrun[0].wcLow;
  1317. pifi->wcLastChar = pwcrunLast->wcLow + pwcrunLast->cGlyphs - 1;
  1318. }
  1319. // This is what Win 3.1 returns for CapHeight and XHeight
  1320. // for TrueType fonts ... we will do the same here.
  1321. //
  1322. pifi->fwdCapHeight = pifi->fwdUnitsPerEm/2;
  1323. pifi->fwdXHeight = pifi->fwdUnitsPerEm/4;
  1324. pifi->dpCharSets = 0; // no multiple charsets in bm fonts
  1325. // All the fonts that this font driver will see are to be rendered left
  1326. // to right
  1327. pifi->ptlBaseline.x = 1;
  1328. pifi->ptlBaseline.y = 0;
  1329. pifi->ptlAspect.y = (LONG) usMakeUSHORT((PBYTE)&ajHdr[OFF_VertRes ]);
  1330. pifi->ptlAspect.x = (LONG) usMakeUSHORT((PBYTE)&ajHdr[OFF_HorizRes]);
  1331. if (pifi->ptlAspect.y == 0)
  1332. {
  1333. pifi->ptlAspect.y = 1;
  1334. WARNING("bmfd!vBmfdFill_IFIMETRICS():ptlAspect.y == 0\n");
  1335. }
  1336. if (pifi->ptlAspect.x == 0)
  1337. {
  1338. pifi->ptlAspect.x = 1;
  1339. WARNING("bmfd!vBmfdFill_IFIMETRICS():ptlAspect.x == 0\n");
  1340. }
  1341. if (!(pifi->fsSelection & FM_SEL_ITALIC))
  1342. {
  1343. // The base class of font is not italicized,
  1344. pifi->ptlCaret.x = 0;
  1345. pifi->ptlCaret.y = 1;
  1346. }
  1347. else
  1348. {
  1349. // somewhat arbitrary
  1350. pifi->ptlCaret.x = 1;
  1351. pifi->ptlCaret.y = 2;
  1352. }
  1353. //
  1354. // The font box reflects the fact that a-spacing and c-spacing are zero
  1355. //
  1356. pifi->rclFontBox.left = 0;
  1357. pifi->rclFontBox.top = (LONG) pifi->fwdTypoAscender;
  1358. pifi->rclFontBox.right = (LONG) pifi->fwdMaxCharInc;
  1359. pifi->rclFontBox.bottom = (LONG) pifi->fwdTypoDescender;
  1360. //
  1361. // achVendorId, unknown, don't bother figure it out from copyright msg
  1362. //
  1363. pifi->achVendId[0] = 'U';
  1364. pifi->achVendId[1] = 'n';
  1365. pifi->achVendId[2] = 'k';
  1366. pifi->achVendId[3] = 'n';
  1367. pifi->cKerningPairs = 0;
  1368. //
  1369. // Panose
  1370. //
  1371. pifi->ulPanoseCulture = FM_PANOSE_CULTURE_LATIN;
  1372. ppanose = &(pifi->panose);
  1373. ppanose->bFamilyType = jFamilyType((USHORT)pifi->jWinPitchAndFamily);
  1374. ppanose->bSerifStyle =
  1375. ((pifi->jWinPitchAndFamily & 0xf0) == FF_SWISS) ?
  1376. PAN_SERIF_NORMAL_SANS : PAN_ANY;
  1377. ppanose->bWeight = (BYTE) WINWT_TO_PANWT(pifi->usWinWeight);
  1378. ppanose->bProportion = (usMakeUSHORT((PBYTE)&ajHdr[OFF_PixWidth]) == 0) ? PAN_ANY : PAN_PROP_MONOSPACED;
  1379. ppanose->bContrast = PAN_ANY;
  1380. ppanose->bStrokeVariation = PAN_ANY;
  1381. ppanose->bArmStyle = PAN_ANY;
  1382. ppanose->bLetterform = PAN_ANY;
  1383. ppanose->bMidline = PAN_ANY;
  1384. ppanose->bXHeight = PAN_ANY;
  1385. //
  1386. // Now fill in the fields for the simulated fonts
  1387. //
  1388. if (pifi->dpFontSim)
  1389. {
  1390. //
  1391. // Create a FONTDIFF template reflecting the base font
  1392. //
  1393. FONTDIFF FontDiff;
  1394. FontDiff.jReserved1 = 0;
  1395. FontDiff.jReserved2 = 0;
  1396. FontDiff.jReserved3 = 0;
  1397. FontDiff.bWeight = pifi->panose.bWeight;
  1398. FontDiff.usWinWeight = pifi->usWinWeight;
  1399. FontDiff.fsSelection = pifi->fsSelection;
  1400. FontDiff.fwdAveCharWidth = pifi->fwdAveCharWidth;
  1401. FontDiff.fwdMaxCharInc = pifi->fwdMaxCharInc;
  1402. FontDiff.ptlCaret = pifi->ptlCaret;
  1403. if (pfdiffBold)
  1404. {
  1405. *pfdiffBold = FontDiff;
  1406. pfdiffBoldItalic->bWeight = PAN_WEIGHT_BOLD;
  1407. pfdiffBold->fsSelection |= FM_SEL_BOLD;
  1408. pfdiffBold->usWinWeight = FW_BOLD;
  1409. pfdiffBold->fwdAveCharWidth += 1;
  1410. pfdiffBold->fwdMaxCharInc += 1;
  1411. }
  1412. if (pfdiffItalic)
  1413. {
  1414. *pfdiffItalic = FontDiff;
  1415. pfdiffItalic->fsSelection |= FM_SEL_ITALIC;
  1416. pfdiffItalic->ptlCaret.x = 1;
  1417. pfdiffItalic->ptlCaret.y = 2;
  1418. }
  1419. if (pfdiffBoldItalic)
  1420. {
  1421. *pfdiffBoldItalic = FontDiff;
  1422. pfdiffBoldItalic->bWeight = PAN_WEIGHT_BOLD;
  1423. pfdiffBoldItalic->fsSelection |= (FM_SEL_BOLD | FM_SEL_ITALIC);
  1424. pfdiffBoldItalic->usWinWeight = FW_BOLD;
  1425. pfdiffBoldItalic->fwdAveCharWidth += 1;
  1426. pfdiffBoldItalic->fwdMaxCharInc += 1;
  1427. pfdiffBoldItalic->ptlCaret.x = 1;
  1428. pfdiffBoldItalic->ptlCaret.y = 2;
  1429. }
  1430. }
  1431. }
  1432. #if defined(_X86_)
  1433. extern VOID vLToE(FLOATL *pe, LONG l);
  1434. /*
  1435. VOID vLToE(FLOATL *pe, LONG l)
  1436. {
  1437. PULONG pul = (PULONG)pe;
  1438. ASSERTGDI(sizeof(FLOAT) == sizeof(LONG),
  1439. "vLtoE : sizeof(FLOAT) != sizeof(LONG)\n");
  1440. *pul = ulLToE(l);
  1441. }
  1442. */
  1443. /*
  1444. //!!! an assembly routine should be provided here instead
  1445. //!!! Now we comment out all lines where this function should be
  1446. //!!! used. Fortunately, this info is not used by the Engine yet
  1447. //!!! This is done per request of mikehar (BodinD)
  1448. VOID vDivE(FLOAT *pe, LONG l1, LONG l2) // *pe = l1/l2
  1449. {
  1450. //!!! this is a hack, it must be fixed to avoid
  1451. // 387 instructions in assembled code. This does not work
  1452. // on a machine without 387 or a system without math emulator
  1453. *pe = ((FLOAT)l1) / ((FLOAT)l2);
  1454. }
  1455. */
  1456. #endif
  1457. /******************************Public*Routine******************************\
  1458. * bDescStr
  1459. *
  1460. * Grunge around in the EXE header to retrieve the description string. Copy
  1461. * the string (if found) to the return string buffer. This buffer should
  1462. * be at least 256 characters. The EXE format limits the string to 255
  1463. * characters (not including a terminating NULL).
  1464. *
  1465. * Returns:
  1466. * TRUE if successful, FALSE otherwise.
  1467. *
  1468. * History:
  1469. * 09-Mar-1992 -by- Gilman Wong [gilmanw]
  1470. * Wrote it.
  1471. \**************************************************************************/
  1472. // !!! [GilmanW] 09-Mar-1992
  1473. // !!! This only supports the 16-bit .FON file format (which corresponds to
  1474. // !!! the 16-bit NEWEXE format defined in exehdr.h).
  1475. // !!!
  1476. // !!! We need to add support for the 32-bit .FON format, whatever that is.
  1477. // !!!
  1478. // !!! Effect this has on 32-bit files: facename will be used as descr string.
  1479. BOOL
  1480. bDescStr(
  1481. PVOID pvView,
  1482. SIZE_T cjView,
  1483. PSZ pszString
  1484. )
  1485. {
  1486. PTRDIFF dpNewExe; // offset to NEWEXE header
  1487. PTRDIFF dpNRSTOffset; // offset to non-resident names table
  1488. ULONG cch; // count of characters in string resource
  1489. PSZ psz; // pointer to characters in string resource
  1490. PSZ pszTmp;
  1491. PBYTE pj = (PBYTE) pvView; // PBYTE pointer into file view
  1492. #ifdef DUMPCALL
  1493. DbgPrint("\nbDescStr(\n" );
  1494. DbgPrint(" PSZ pszString = %-#8lx\n", pszString );
  1495. DbgPrint(" );\n\n" );
  1496. #endif
  1497. // Validation. Check EXE_HDR magic number.
  1498. if (OFF_e_magic + sizeof(WORD) > cjView)
  1499. {
  1500. WARNING("bmfd!bDescStr(): header too short\n");
  1501. return (FALSE);
  1502. }
  1503. if (READ_WORD(pj + OFF_e_magic) != EMAGIC)
  1504. {
  1505. WARNING("bmfd!bDescStr(): not a 16-bit .FON file (bad EMAGIC number)!\n");
  1506. return(FALSE);
  1507. }
  1508. // More validation. Check NEWEXE magic number.
  1509. dpNewExe = READ_DWORD(pj + OFF_e_lfanew);
  1510. if ((dpNewExe < 0) || (dpNewExe + sizeof(USHORT) > cjView))
  1511. {
  1512. WARNING("bmfd!bDescStr(): bad dpNewExe\n");
  1513. return (FALSE);
  1514. }
  1515. if (READ_WORD(pj + dpNewExe) != NEMAGIC )
  1516. {
  1517. WARNING("bmfd!bDescStr(): not a 16-bit .FON file (bad NEMAGIC number)!\n");
  1518. return(FALSE);
  1519. }
  1520. // Get description string out of the non-resident strings table of the
  1521. // NEWEXE header. Resource strings are counted strings: the first byte
  1522. // is the count of characters, and the string follows. A NULL is not
  1523. // guaranteed. However, we know the string is < 256 characters.
  1524. dpNRSTOffset = READ_DWORD(pj + dpNewExe + OFF_ne_nrestab);
  1525. if ( (DWORD)(dpNRSTOffset) > cjView - 1) // one byte the Pascal style string length
  1526. {
  1527. WARNING("bmfd!bDescStr(): bad dpNRSTOffset\n");
  1528. return (FALSE);
  1529. }
  1530. // If zero length string, then there is none.
  1531. if ( (cch = (ULONG)(*(pj + dpNRSTOffset))) == 0 )
  1532. {
  1533. WARNING("bmfd!bDescStr(): bad description string\n");
  1534. return (FALSE);
  1535. }
  1536. if ((dpNRSTOffset + 2 + cch > cjView) || (*(pj + dpNRSTOffset + cch + 1) != 0))
  1537. // length of the string + one character for the pascal size + one character for the null terminator
  1538. {
  1539. WARNING("bmfd!bDescStr(): bad string\n");
  1540. return (FALSE);
  1541. }
  1542. // Pointer to the actual string.
  1543. psz = pj + dpNRSTOffset + 1;
  1544. // Parse out the "FONTRES xxx, yyy, zzz : " header if it exists.
  1545. if ( (pszTmp = strchr(psz, ':')) != (PSZ) NULL )
  1546. {
  1547. // Skip over the ':'.
  1548. pszTmp++;
  1549. cch -= (ULONG)(pszTmp - psz);
  1550. // Skip spaces.
  1551. while ( *pszTmp == ' ' && cch > 0)
  1552. {
  1553. pszTmp++;
  1554. cch--;
  1555. }
  1556. // If not at end of string, then we're at the string.
  1557. if ( *pszTmp != '\0' && cch > 0)
  1558. {
  1559. psz = pszTmp;
  1560. }
  1561. // Otherwise, this is a bad string (contains only a header).
  1562. else
  1563. {
  1564. WARNING("bmfd!bDescStr(): bad description string (only string header)\n");
  1565. return (FALSE);
  1566. }
  1567. }
  1568. // Copy the string.
  1569. strncpy(pszString, psz, cch);
  1570. pszString[cch] = '\0'; // add terminating NULL
  1571. // Success.
  1572. return(TRUE);
  1573. }
  1574. /******************************Public*Routine******************************\
  1575. *
  1576. * PBYTE pjRawBitmap
  1577. *
  1578. * gets the pointer to the raw bitmap data in the resource file
  1579. *
  1580. * History:
  1581. * 23-Mar-1992 -by- Bodin Dresevic [BodinD]
  1582. * Wrote it.
  1583. \**************************************************************************/
  1584. PBYTE
  1585. pjRawBitmap(
  1586. HGLYPH hg, // IN
  1587. PCVTFILEHDR pcvtfh, // IN
  1588. PRES_ELEM pre, // IN
  1589. PULONG pcx // OUT place cx here
  1590. )
  1591. {
  1592. // size of table entry in USHORT's
  1593. ULONG cusTableEntry = ((pcvtfh->iVersion == 0x00000200) ? 2 : 3);
  1594. // get the pointer to the beginning of the offset table in
  1595. // the original *.fnt file
  1596. PUSHORT pusOffTable = (PUSHORT)((PBYTE)pre->pvResData + pcvtfh->dpOffsetTable);
  1597. PUSHORT pus_cx;
  1598. DWORD dwOffset;
  1599. #ifdef DUMPCALL
  1600. DbgPrint("\npjRawBitmap(\n");
  1601. DbgPrint(" HGLYPH hg = %-#8lx\n", hg );
  1602. DbgPrint(" PCVTFILEHDR pcvtfh = %-#8lx\n", pcvtfh);
  1603. DbgPrint(" PRES_ELEM pre = %-#8lx\n", pre );
  1604. DbgPrint(" PULONG pcx = %-#8lx\n", pcx );
  1605. DbgPrint(" );\n\n" );
  1606. #endif
  1607. // hg is equal to the ansi value of the glyph - chFirstChar:
  1608. if (hg > (HGLYPH)(pcvtfh->chLastChar - pcvtfh->chFirstChar))
  1609. {
  1610. // DbgPrint ( "hg 0x %lx, chFirst 0x %x, chLastChar 0x %x \n",
  1611. // hg, (WCHAR)pcvtfh->chFirstChar, (WCHAR)pcvtfh->chLastChar);
  1612. hg = pcvtfh->chDefaultChar;
  1613. }
  1614. // points to the table entry for this character
  1615. pus_cx = pusOffTable + hg * cusTableEntry;
  1616. // If cx is non-zero, then the character exists, else use default char
  1617. *pcx = *pus_cx;
  1618. if (*pus_cx == 0)
  1619. {
  1620. // no bits, will have to return fake bitmap
  1621. return NULL;
  1622. }
  1623. // increment pus_cx to point to the offset to the bitmap in the resource file
  1624. pus_cx++;
  1625. if (pcvtfh->iVersion == 0x00000200)
  1626. {
  1627. dwOffset = READ_WORD(pus_cx);
  1628. }
  1629. else // long offset, win 3.0 format
  1630. {
  1631. dwOffset = READ_DWORD(pus_cx);
  1632. }
  1633. if (dwOffset > (CJ_SCAN(*pcx) * pcvtfh->cy) + dwOffset ||
  1634. (CJ_SCAN(*pcx) * pcvtfh->cy) + dwOffset > pre->cjResData)
  1635. {
  1636. // bitmap is out of font file, will have to return fake bitmap
  1637. WARNING("bmfd!pjRawBitmap(): bitmap is out of font file\n");
  1638. *pcx = 0;
  1639. return NULL;
  1640. }
  1641. return ((PBYTE)pre->pvResData + dwOffset);
  1642. }
  1643. /******************************Public*Routine******************************\
  1644. *
  1645. * vCheckOffsetTable: fixes the possible problems in the file header
  1646. *
  1647. * History:
  1648. * 23-Mar-1992 -by- Bodin Dresevic [BodinD]
  1649. * Wrote it.
  1650. \**************************************************************************/
  1651. VOID
  1652. vCheckOffsetTable(
  1653. PCVTFILEHDR pcvtfh,
  1654. PRES_ELEM pre
  1655. )
  1656. {
  1657. ULONG cusTableEntry; // size of table entry in USHORT's
  1658. ULONG i; // loop index
  1659. USHORT cxMax; // has to be computed since there are bugs in files
  1660. ULONG cCodePoints = pcvtfh->chLastChar + 1 - pcvtfh->chFirstChar;
  1661. PUSHORT pus_cx; // pointer to the beginning of the offset table
  1662. #ifdef DUMPCALL
  1663. DbgPrint("\nvCheckOffsetTable(\n" );
  1664. DbgPrint(" PCVTFILEHDR pcvtfh = %-#8lx\n", pcvtfh);
  1665. DbgPrint(" PRES_ELEM pre = %-#8lx\n", pre );
  1666. DbgPrint(" );\n\n" );
  1667. #endif
  1668. pus_cx = (PUSHORT)((PBYTE)pre->pvResData + pcvtfh->dpOffsetTable);
  1669. ASSERTGDI (
  1670. ((ULONG_PTR)pus_cx & 1L) == 0,
  1671. "offset table begins at odd address\n"
  1672. );
  1673. // initialize the max so far
  1674. cxMax = 0;
  1675. if (pcvtfh->iVersion == 0x00000200) // 2.0 font file
  1676. cusTableEntry = 2; // 2 bytes for cx + 2 bytes for offset
  1677. else // 3.0 font file
  1678. {
  1679. ASSERTGDI(pcvtfh->iVersion == 0x00000300, "must be 0x00000300 font\n");
  1680. cusTableEntry = 3; // 2 bytes for cx + 4 bytes for offset
  1681. }
  1682. // check offset table for all codepoints. It is important to find the
  1683. // real cxMax and not to trust the value in the header since as we have
  1684. // seen it may be wrong, which could cause a crash. This in fact is the
  1685. // case with one of the faces in aldfonte.fon, where they report avg. width
  1686. // to be 0x14 and max width to be 0x13, i.e. smaller than the avg!!!!.
  1687. // However, cxMax for that font, found in the loop below, turns out to be
  1688. // 0x14, i.e. >= avg width, as it should be. [bodind]
  1689. pcvtfh->fsFlags = 0;
  1690. for (i = 0; i < cCodePoints; i++, pus_cx += cusTableEntry)
  1691. {
  1692. if ((*pus_cx) > cxMax)
  1693. cxMax = (*pus_cx);
  1694. // See if this font file contains zero width glyphs,
  1695. // if so we have to turn off usual DEVICEMETRICS accelerator
  1696. // flags for this font. We shall have to be providing
  1697. // the fake 1x1 bitmap for this font.
  1698. if ((*pus_cx) == 0)
  1699. {
  1700. pcvtfh->fsFlags |= FS_ZERO_WIDTH_GLYPHS;
  1701. }
  1702. }
  1703. #ifdef FOOGOO
  1704. if (pcvtfh->fsFlags & FS_ZERO_WIDTH_GLYPHS)
  1705. {
  1706. KdPrint(("\n %s: .fnt font resource with zero width glyphs\n", pre->pjFaceName));
  1707. }
  1708. #endif
  1709. // cache the values
  1710. pcvtfh->cjGlyphMax = CJ_GLYPHDATA(cxMax,pcvtfh->cy);
  1711. pcvtfh->usMaxWidth = max(pcvtfh->usMaxWidth, cxMax);
  1712. }
  1713. #if DBG
  1714. /******************************Public*Routine******************************\
  1715. * vDumpFontHeader *
  1716. * *
  1717. * History: *
  1718. * Mon 27-Jun-1994 07:00:29 by Kirk Olynyk [kirko] *
  1719. * Wrote it. *
  1720. \**************************************************************************/
  1721. #define GETBYTE(XXX) ajHdr[OFF_##XXX]
  1722. #define GETWORD(XXX) READ_WORD(&ajHdr[OFF_##XXX])
  1723. #define GETDWORD(XXX) READ_DWORD(&ajHdr[OFF_##XXX])
  1724. VOID vDumpFontHeader(
  1725. PRES_ELEM pre
  1726. , VPRINT vPrint
  1727. )
  1728. {
  1729. PBYTE ajHdr = (PBYTE)pre->pvResData;
  1730. vPrint("\n\nvDumpFontHeader\n\n");
  1731. vPrint("Version = %-#x\n", GETWORD(Version));
  1732. vPrint("Size = %-#x\n", GETDWORD(Size));
  1733. vPrint("Copyright = \"%s\"\n",ajHdr + OFF_Copyright);
  1734. vPrint("Type = %-#x\n", GETWORD(Type));
  1735. vPrint("Points = %-#x\n", GETWORD(Points));
  1736. vPrint("VertRes = %-#x\n", GETWORD(VertRes));
  1737. vPrint("HorizRes = %-#x\n", GETWORD(HorizRes));
  1738. vPrint("Ascent = %-#x\n", GETWORD(Ascent));
  1739. vPrint("IntLeading = %-#x\n", GETWORD(IntLeading));
  1740. vPrint("ExtLeading = %-#x\n", GETWORD(ExtLeading));
  1741. vPrint("Italic = %-#x\n", GETBYTE(Italic));
  1742. vPrint("Underline = %-#x\n", GETBYTE(Underline));
  1743. vPrint("StrikeOut = %-#x\n", GETBYTE(StrikeOut));
  1744. vPrint("Weight = %-#x\n", GETWORD(Weight));
  1745. vPrint("CharSet = %-#x\n", GETBYTE(CharSet));
  1746. vPrint("PixWidth = %-#x\n", GETWORD(PixWidth));
  1747. vPrint("PixHeight = %-#x\n", GETWORD(PixHeight));
  1748. vPrint("Family = %-#x\n", GETBYTE(Family));
  1749. vPrint("AvgWidth = %-#x\n", GETWORD(AvgWidth));
  1750. vPrint("MaxWidth = %-#x\n", GETWORD(MaxWidth));
  1751. vPrint("FirstChar = %-#x\n", GETBYTE(FirstChar));
  1752. vPrint("LastChar = %-#x\n", GETBYTE(LastChar));
  1753. vPrint("DefaultChar = %-#x\n", GETBYTE(DefaultChar));
  1754. vPrint("BreakChar = %-#x\n", GETBYTE(BreakChar));
  1755. vPrint("WidthBytes = %-#x\n", GETWORD(WidthBytes));
  1756. vPrint("Device = %-#x\n", GETDWORD(Device));
  1757. vPrint("Face = %-#x\n", GETDWORD(Face));
  1758. vPrint(" = \"%s\"\n",
  1759. (PSZ)(pre->pjFaceName == 0 ? ajHdr + GETWORD(Face) : pre->pjFaceName));
  1760. vPrint("BitsPointer = %-#x\n", GETDWORD(BitsPointer));
  1761. vPrint("BitsOffset = %-#x\n", GETDWORD(BitsOffset));
  1762. vPrint("jUnused20 = %-#x\n", GETBYTE(jUnused20));
  1763. vPrint("OffTable20 = %-#x\n", GETWORD(OffTable20));
  1764. vPrint("\n\n");
  1765. {
  1766. // consistency checks go here
  1767. char *pszBad = "Inconsistency detected:";
  1768. if ((GETWORD(PixWidth)) && (GETWORD(PixWidth) != GETWORD(MaxWidth)))
  1769. DbgPrint("%s PixWidth != MaxWidth\n",pszBad);
  1770. if ((ajHdr[OFF_Family] & 0xf) && ajHdr[OFF_PixWidth])
  1771. DbgPrint("%s Family indicates variable pitch and PixWidth indicates fixed\n",pszBad);
  1772. else if (!(ajHdr[OFF_Family] & 0xf) && !ajHdr[OFF_PixWidth])
  1773. DbgPrint("%s Family indicates fixed pitch and PixWidth indicates variable\n",pszBad);
  1774. vPrint("\n\n");
  1775. }
  1776. }
  1777. #endif