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.

850 lines
25 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: fdcvt.c
  3. *
  4. * Font file loading and unloadking. Adapted from BodinD's bitmap font driver.
  5. *
  6. * Created: 26-Feb-1992 20:23:54
  7. * Author: Wendy Wu [wendywu]
  8. *
  9. * Copyright (c) 1990 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "fd.h"
  12. // points to the linked list of glyphset strucs
  13. CP_GLYPHSET *gpcpVTFD = NULL;
  14. ULONG cjVTFDIFIMETRICS(PBYTE ajHdr);
  15. // !!! put prototype in common area for all font drivers so change
  16. // !!! in 1 is reflected in all.
  17. FSHORT fsSelectionFlags(PBYTE ajHdr); // in bmfd
  18. extern BOOL bDbgPrintAndFail(PSZ psz);
  19. #if DBG
  20. extern BOOL bDbgPrintAndFail(PSZ psz);
  21. #else
  22. #define bDbgPrintAndFail(psz) FALSE
  23. #endif
  24. ULONG iDefaultFace(PBYTE ajHdr) // similar to vDefFace, should not be duplicated
  25. {
  26. ULONG iDefFace;
  27. if (READ_WORD(&ajHdr[OFF_Weight]) <= FW_NORMAL)
  28. {
  29. if (ajHdr[OFF_Italic])
  30. {
  31. iDefFace = FF_FACE_ITALIC;
  32. }
  33. else
  34. {
  35. iDefFace = FF_FACE_NORMAL;
  36. }
  37. }
  38. else
  39. {
  40. if (ajHdr[OFF_Italic])
  41. {
  42. iDefFace = FF_FACE_BOLDITALIC;
  43. }
  44. else
  45. {
  46. iDefFace = FF_FACE_BOLD;
  47. }
  48. }
  49. return iDefFace;
  50. }
  51. /******************************Private*Routine*****************************\
  52. * BOOL bVerifyVTFD
  53. *
  54. * CHECK whether header contains file info which corresponds to
  55. * the raster font requirements, go into the file and check
  56. * the consistency of the header data
  57. *
  58. * History:
  59. * 26-Feb-1992 -by- Wendy Wu [wendywu]
  60. * Adapted from bmfd.
  61. \**************************************************************************/
  62. BOOL bVerifyVTFD(PRES_ELEM pre)
  63. {
  64. PBYTE ajHdr = (PBYTE)pre->pvResData;
  65. if (pre->cjResData < OFF_OffTable20)
  66. return(bDbgPrintAndFail("VTFD! resource size too small for OFF_OffTable20\n")); // supported.
  67. if (!(READ_WORD(&ajHdr[OFF_Type]) & TYPE_VECTOR)) // Vector bit has to
  68. return(bDbgPrintAndFail("VTFD!fsType \n")); // be on.
  69. if ((READ_WORD(&ajHdr[OFF_Version]) != 0x0100) && // The only version
  70. (READ_WORD(&ajHdr[OFF_Version]) != 0x0200) ) // The only version
  71. return(bDbgPrintAndFail("VTFD!iVersion\n")); // supported.
  72. if ((ajHdr[OFF_BitsOffset] & 1) != 0) // Must be an even
  73. return(bDbgPrintAndFail("VTFD!dpBits odd \n")); // offset.
  74. // file size must be <= than the size of the view
  75. if (READ_DWORD(&ajHdr[OFF_Size]) > pre->cjResData)
  76. return(bDbgPrintAndFail("VTFD!cjSize \n"));
  77. // make sure that the reserved bits are all zero
  78. if ((READ_WORD(&ajHdr[OFF_Type]) & BITS_RESERVED) != 0)
  79. return(bDbgPrintAndFail("VTFD!fsType, reserved bits \n"));
  80. if (abs(READ_WORD(&ajHdr[OFF_Ascent])) > READ_WORD(&ajHdr[OFF_PixHeight]))
  81. return(bDbgPrintAndFail("VTFD!sAscent \n")); // Ascent Too Big
  82. if (READ_WORD(&ajHdr[OFF_IntLeading]) > READ_WORD(&ajHdr[OFF_Ascent]))
  83. return(bDbgPrintAndFail("VTFD! IntLeading too big\n")); // Int Lead Too Big;
  84. // check consistency of character ranges
  85. if (ajHdr[OFF_FirstChar] > ajHdr[OFF_LastChar])
  86. return(bDbgPrintAndFail("VTFD! FirstChar\n")); // this can't be
  87. // default and break character are given relative to the FirstChar,
  88. // so that the actual default (break) character is given as
  89. // chFirst + chDefault(Break)
  90. if ((BYTE)(ajHdr[OFF_DefaultChar] + ajHdr[OFF_FirstChar]) > ajHdr[OFF_LastChar])
  91. return(bDbgPrintAndFail("VTFD! DefaultChar\n"));
  92. if ((BYTE)(ajHdr[OFF_BreakChar] + ajHdr[OFF_FirstChar]) > ajHdr[OFF_LastChar])
  93. return(bDbgPrintAndFail("VTFD! BreakChar\n"));
  94. // finally verify that all the offsets to glyph data point to locations
  95. // within the file and that what they point to is valid glyph data: [BodinD]
  96. {
  97. INT iIndex, dIndex, iIndexEnd;
  98. PBYTE pjCharTable, pjGlyphData,pjFirstChar, pjEndFile;
  99. iIndexEnd = (INT)ajHdr[OFF_LastChar] - (INT)ajHdr[OFF_FirstChar] + 1;
  100. // init out of the loop:
  101. if (READ_WORD(&ajHdr[OFF_PixWidth]) != 0) // fixed pitch
  102. {
  103. iIndexEnd <<= 1; // each entry is 2-byte long
  104. dIndex = 2;
  105. }
  106. else
  107. {
  108. iIndexEnd <<= 2; // each entry is 4-byte long
  109. dIndex = 4;
  110. }
  111. pjFirstChar = ajHdr + READ_DWORD(ajHdr + OFF_BitsOffset);
  112. // Vector font file doesn't have the byte filler. Win31 bug?
  113. pjCharTable = ajHdr + OFF_jUnused20;
  114. pjEndFile = ajHdr + READ_DWORD(ajHdr + OFF_Size);
  115. if (OFF_jUnused20 + (ULONG)(iIndexEnd * dIndex) > pre->cjResData)
  116. return(bDbgPrintAndFail("VTFD! OffsetTable out of file \n"));
  117. for (iIndex = 0; iIndex < iIndexEnd; iIndex += dIndex)
  118. {
  119. pjGlyphData = pjFirstChar + READ_WORD(&pjCharTable[iIndex]);
  120. if ((pjGlyphData >= pjEndFile) || (*pjGlyphData != (BYTE)PEN_UP))
  121. return(bDbgPrintAndFail("VTFD!bogus vector font \n"));
  122. }
  123. }
  124. {
  125. PSZ pszFaceName = ajHdr + READ_DWORD(&ajHdr[OFF_Face]);
  126. SIZE_T pszFaceNameLength;
  127. if (!bMappedViewStrlen(pre->pvResData, pre->cjResData, pszFaceName, &pszFaceNameLength))
  128. return(bDbgPrintAndFail("VTFD!bogus FaceName \n"));
  129. }
  130. return(TRUE);
  131. }
  132. /******************************Private*Routine*****************************\
  133. * ULONG cVtfdResFaces
  134. *
  135. * Compute the number of faces that the given .FNT file can support.
  136. *
  137. * History:
  138. * 04-Mar-1992 -by- Wendy Wu [wendywu]
  139. * Wrote it.
  140. \**************************************************************************/
  141. ULONG cVtfdResFaces(PBYTE ajHdr)
  142. {
  143. // We set the FM_SEL_BOLD flag iff weight is > FW_NORMAL (400).
  144. // We will not allow emboldening simulation on the font that has this
  145. // flag set.
  146. if (READ_WORD(&ajHdr[OFF_Weight]) <= FW_NORMAL)
  147. {
  148. if (ajHdr[OFF_Italic])
  149. return(2);
  150. else
  151. return(4);
  152. }
  153. else
  154. {
  155. if (ajHdr[OFF_Italic])
  156. return(1);
  157. else
  158. return(2);
  159. }
  160. }
  161. /******************************Private*Routine*****************************\
  162. * VOID vVtfdFill_IFIMetrics
  163. *
  164. * Looks into the .FNT file and fills the IFIMETRICS structure accordingly.
  165. *
  166. * History:
  167. * Wed 04-Nov-1992 -by- Bodin Dresevic [BodinD]
  168. * update: new ifimetrics
  169. * 26-Feb-1992 -by- Wendy Wu [wendywu]
  170. * Adapted from bmfd.
  171. \**************************************************************************/
  172. VOID vVtfdFill_IFIMetrics(PBYTE ajHdr, FD_GLYPHSET * pgset, PIFIMETRICS pifi)
  173. {
  174. FWORD fwdHeight;
  175. FONTSIM *pFontSim;
  176. FONTDIFF *pfdiffBold = 0, *pfdiffItalic = 0, *pfdiffBoldItalic = 0;
  177. PANOSE *ppanose;
  178. ULONG iDefFace;
  179. ULONG cjIFI = ALIGN4(sizeof(IFIMETRICS));
  180. ULONG cch;
  181. FWORD cy;
  182. // compute pointers to the various sections of the converted file
  183. // face name lives in the original file, this is the only place pvView is used
  184. PSZ pszFaceName = (PSZ)(ajHdr + READ_DWORD(&ajHdr[OFF_Face]));
  185. pifi->cjIfiExtra = 0;
  186. pifi->cjThis = cjVTFDIFIMETRICS(ajHdr);
  187. // the string begins on a DWORD aligned address.
  188. pifi->dpwszFaceName = cjIFI;
  189. // face name == family name for vector fonts [Win3.0 compatibility]
  190. pifi->dpwszFamilyName = pifi->dpwszFaceName;
  191. // these names don't exist, so point to the NULL char [Win3.1 compatibility]
  192. // Note: lstrlen() does not count the terminating NULL.
  193. cch = (ULONG)strlen(pszFaceName);
  194. pifi->dpwszStyleName = pifi->dpwszFaceName + sizeof(WCHAR) * cch;
  195. pifi->dpwszUniqueName = pifi->dpwszStyleName;
  196. cjIFI += ALIGN4((cch + 1) * sizeof(WCHAR));
  197. // copy the strings to their new location. Here we assume that the sufficient
  198. // memory has been allocated
  199. vToUNICODEN((LPWSTR)((PBYTE)pifi + pifi->dpwszFaceName), cch+1, pszFaceName, cch+1);
  200. // Check to see if simulations are necessary and if they are, fill
  201. // in the offsets to the various simulation fields and update cjThis
  202. // field of the IFIMETRICS structure
  203. iDefFace = iDefaultFace(ajHdr);
  204. if (iDefFace == FF_FACE_BOLDITALIC)
  205. {
  206. pifi->dpFontSim = 0;
  207. }
  208. else
  209. {
  210. pifi->dpFontSim = cjIFI;
  211. pFontSim = (FONTSIM*) ((BYTE*)pifi + pifi->dpFontSim);
  212. cjIFI += ALIGN4(sizeof(FONTSIM));
  213. switch (iDefFace)
  214. {
  215. case FF_FACE_NORMAL:
  216. //
  217. // simulations are needed for bold, italic, and bold-italic
  218. //
  219. pFontSim->dpBold = ALIGN4(sizeof(FONTSIM));
  220. pFontSim->dpItalic = pFontSim->dpBold + ALIGN4(sizeof(FONTDIFF));
  221. pFontSim->dpBoldItalic = pFontSim->dpItalic + ALIGN4(sizeof(FONTDIFF));
  222. pfdiffBold =
  223. (FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBold);
  224. pfdiffItalic =
  225. (FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpItalic);
  226. pfdiffBoldItalic =
  227. (FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBoldItalic);
  228. cjIFI += (3 * ALIGN4(sizeof(FONTDIFF)));
  229. break;
  230. case FF_FACE_BOLD:
  231. case FF_FACE_ITALIC:
  232. //
  233. // a simulation is needed for bold-italic only
  234. //
  235. pFontSim->dpBold = 0;
  236. pFontSim->dpItalic = 0;
  237. pFontSim->dpBoldItalic = ALIGN4(sizeof(FONTSIM));
  238. pfdiffBoldItalic =
  239. (FONTDIFF*) ((BYTE*) pFontSim + pFontSim->dpBoldItalic);
  240. cjIFI += ALIGN4(sizeof(FONTDIFF));
  241. break;
  242. default:
  243. RIP("VTFD -- bad iDefFace\n");
  244. break;
  245. }
  246. }
  247. ASSERTDD(cjIFI == pifi->cjThis, "cjIFI is wrong\n");
  248. pifi->jWinCharSet = ajHdr[OFF_CharSet];
  249. pifi->jWinPitchAndFamily = ajHdr[OFF_Family];
  250. //
  251. // !!![kirko] The next line of code is very scary but it seems to work.
  252. // This will call a font with FIXED_PITCH set, a varible pitch font.
  253. // Or should this be decided upon whether cx == 0 or not? [bodind]
  254. //
  255. // this is the excert from wendy's code:
  256. // if ((ajHdr[OFF_Family] & 1) == 0)
  257. // pifi->flInfo |= FM_INFO_CONSTANT_WIDTH;
  258. if (pifi->jWinPitchAndFamily & 0x0f)
  259. {
  260. pifi->jWinPitchAndFamily = ((pifi->jWinPitchAndFamily & 0xf0) | VARIABLE_PITCH);
  261. }
  262. else
  263. {
  264. pifi->jWinPitchAndFamily = ((pifi->jWinPitchAndFamily & 0xf0) | FIXED_PITCH);
  265. }
  266. pifi->usWinWeight = READ_WORD(&ajHdr[OFF_Weight]);
  267. // weight, may have to fix it up if the font contains a garbage value [bodind]
  268. if ((pifi->usWinWeight > MAX_WEIGHT) || (pifi->usWinWeight < MIN_WEIGHT))
  269. pifi->usWinWeight = 400;
  270. pifi->flInfo = ( FM_INFO_TECH_STROKE
  271. | FM_INFO_ARB_XFORMS
  272. | FM_INFO_RETURNS_STROKES
  273. | FM_INFO_RIGHT_HANDED
  274. );
  275. if ((pifi->jWinPitchAndFamily & 0xf) == FIXED_PITCH)
  276. {
  277. pifi->flInfo |= (FM_INFO_CONSTANT_WIDTH | FM_INFO_OPTICALLY_FIXED_PITCH);
  278. }
  279. pifi->lEmbedId = 0;
  280. pifi->fsSelection = fsSelectionFlags(ajHdr);
  281. //
  282. // The choices for fsType are FM_TYPE_LICENSED and FM_READONLY_EMBED
  283. // These are TrueType things and do not apply to old fashioned bitmap and vector
  284. // fonts.
  285. //
  286. pifi->fsType = 0;
  287. cy = (FWORD)READ_WORD(&ajHdr[OFF_PixHeight]);
  288. pifi->fwdUnitsPerEm = ((FWORD)READ_WORD(&ajHdr[OFF_IntLeading]) > 0) ?
  289. cy - (FWORD)READ_WORD(&ajHdr[OFF_IntLeading]) : cy;
  290. pifi->fwdLowestPPEm = 0;
  291. pifi->fwdWinAscender = (FWORD)READ_WORD(&ajHdr[OFF_Ascent]);
  292. pifi->fwdWinDescender = cy - pifi->fwdWinAscender;
  293. pifi->fwdMacAscender = pifi->fwdWinAscender ;
  294. pifi->fwdMacDescender = -pifi->fwdWinDescender;
  295. pifi->fwdMacLineGap = (FWORD)READ_WORD(&ajHdr[OFF_ExtLeading]);
  296. pifi->fwdTypoAscender = pifi->fwdMacAscender;
  297. pifi->fwdTypoDescender = pifi->fwdMacDescender;
  298. pifi->fwdTypoLineGap = pifi->fwdMacLineGap;
  299. pifi->fwdAveCharWidth = (FWORD)READ_WORD(&ajHdr[OFF_AvgWidth]);
  300. pifi->fwdMaxCharInc = (FWORD)READ_WORD(&ajHdr[OFF_MaxWidth]);
  301. //
  302. // don't know much about SuperScripts
  303. //
  304. pifi->fwdSubscriptXSize = 0;
  305. pifi->fwdSubscriptYSize = 0;
  306. pifi->fwdSubscriptXOffset = 0;
  307. pifi->fwdSubscriptYOffset = 0;
  308. //
  309. // don't know much about SubScripts
  310. //
  311. pifi->fwdSuperscriptXSize = 0;
  312. pifi->fwdSuperscriptYSize = 0;
  313. pifi->fwdSuperscriptXOffset = 0;
  314. pifi->fwdSuperscriptYOffset = 0;
  315. //
  316. // win 30 magic. see the code in textsims.c in the Win 3.1 sources
  317. //
  318. fwdHeight = pifi->fwdWinAscender + pifi->fwdWinDescender;
  319. pifi->fwdUnderscoreSize = (fwdHeight > 12) ? (fwdHeight / 12) : 1;
  320. pifi->fwdUnderscorePosition = -(FWORD)(pifi->fwdUnderscoreSize / 2 + 1);
  321. pifi->fwdStrikeoutSize = pifi->fwdUnderscoreSize;
  322. {
  323. // We are further adjusting underscore position if underline
  324. // hangs below char stems.
  325. // The only font where this effect is noticed to
  326. // be important is an ex pm font sys08cga.fnt, presently used in console
  327. FWORD yUnderlineBottom = -pifi->fwdUnderscorePosition
  328. + ((pifi->fwdUnderscoreSize + (FWORD)1) >> 1);
  329. FWORD dy = yUnderlineBottom - pifi->fwdWinDescender;
  330. if (dy > 0)
  331. {
  332. #ifdef CHECK_CRAZY_DESC
  333. DbgPrint("bmfd: Crazy descender: old = %ld, adjusted = %ld\n\n",
  334. (ULONG)pifi->fwdMaxDescender,
  335. (ULONG)yUnderlineBottom);
  336. #endif // CHECK_CRAZY_DESC
  337. pifi->fwdUnderscorePosition += dy;
  338. }
  339. }
  340. //
  341. // Win 3.1 method
  342. //
  343. // LineOffset = ((((Ascent-IntLeading)*2)/3) + IntLeading)
  344. //
  345. // [remember that they measure the offset from the top of the cell,
  346. // where as NT measures offsets from the baseline]
  347. //
  348. pifi->fwdStrikeoutPosition =
  349. (FWORD) (((FWORD)READ_WORD(&ajHdr[OFF_Ascent]) - (FWORD)READ_WORD(&ajHdr[OFF_IntLeading]) + 2)/3);
  350. pifi->chFirstChar = ajHdr[OFF_FirstChar];
  351. pifi->chLastChar = ajHdr[OFF_LastChar];;
  352. // wcDefaultChar
  353. // wcBreakChar
  354. {
  355. UCHAR chDefault = ajHdr[OFF_FirstChar] + ajHdr[OFF_DefaultChar];
  356. UCHAR chBreak = ajHdr[OFF_FirstChar] + ajHdr[OFF_BreakChar];
  357. // Default and Break chars are given relative to the first char
  358. pifi->chDefaultChar = chDefault;
  359. pifi->chBreakChar = chBreak;
  360. EngMultiByteToUnicodeN(&pifi->wcDefaultChar, sizeof(WCHAR), NULL, &chDefault, 1);
  361. EngMultiByteToUnicodeN(&pifi->wcBreakChar , sizeof(WCHAR), NULL, &chBreak, 1);
  362. }
  363. // These have to be taken from the glyph set [bodind]
  364. {
  365. WCRUN *pwcrunLast = &(pgset->awcrun[pgset->cRuns - 1]);
  366. pifi->wcFirstChar = pgset->awcrun[0].wcLow;
  367. pifi->wcLastChar = pwcrunLast->wcLow + pwcrunLast->cGlyphs - 1;
  368. }
  369. pifi->fwdCapHeight = 0;
  370. pifi->fwdXHeight = 0;
  371. pifi->dpCharSets = 0; // no multiple charsets in vector fonts
  372. // All the fonts that this font driver will see are to be rendered left
  373. // to right
  374. pifi->ptlBaseline.x = 1;
  375. pifi->ptlBaseline.y = 0;
  376. pifi->ptlAspect.y = (LONG) READ_WORD(&ajHdr[OFF_VertRes ]);
  377. pifi->ptlAspect.x = (LONG) READ_WORD(&ajHdr[OFF_HorizRes]);
  378. if (pifi->ptlAspect.y == 0)
  379. {
  380. pifi->ptlAspect.y = 1;
  381. WARNING("VTFD!vVtfdFill_IFIMetrics():ptlAspect.y == 0\n");
  382. }
  383. if (pifi->ptlAspect.x == 0)
  384. {
  385. pifi->ptlAspect.x = 1;
  386. WARNING("VTFD!vVtfdFill_IFIMetrics():ptlAspect.x == 0\n");
  387. }
  388. if (!(pifi->fsSelection & FM_SEL_ITALIC))
  389. {
  390. // The base class of font is not italicized,
  391. pifi->ptlCaret.x = 0;
  392. pifi->ptlCaret.y = 1;
  393. }
  394. else
  395. {
  396. // somewhat arbitrary
  397. pifi->ptlCaret.x = 1;
  398. pifi->ptlCaret.y = 2;
  399. }
  400. //
  401. // The font box reflects the fact that a-spacing and c-spacing are zero
  402. //
  403. pifi->rclFontBox.left = 0;
  404. pifi->rclFontBox.top = (LONG) pifi->fwdTypoAscender;
  405. pifi->rclFontBox.right = (LONG) pifi->fwdMaxCharInc;
  406. pifi->rclFontBox.bottom = (LONG) pifi->fwdTypoDescender;
  407. //
  408. // achVendorId, do not bother figuring it out
  409. //
  410. pifi->achVendId[0] = 'U';
  411. pifi->achVendId[1] = 'n';
  412. pifi->achVendId[2] = 'k';
  413. pifi->achVendId[3] = 'n';
  414. pifi->cKerningPairs = 0;
  415. //
  416. // Panose
  417. //
  418. pifi->ulPanoseCulture = FM_PANOSE_CULTURE_LATIN;
  419. ppanose = &(pifi->panose);
  420. ppanose->bFamilyType = PAN_NO_FIT;
  421. ppanose->bSerifStyle =
  422. ((pifi->jWinPitchAndFamily & 0xf0) == FF_SWISS) ?
  423. PAN_SERIF_NORMAL_SANS : PAN_ANY;
  424. ppanose->bWeight = (BYTE) WINWT_TO_PANWT(READ_WORD(&ajHdr[OFF_Weight]));
  425. ppanose->bProportion = (READ_WORD(&ajHdr[OFF_PixWidth]) == 0) ? PAN_ANY : PAN_PROP_MONOSPACED;
  426. ppanose->bContrast = PAN_ANY;
  427. ppanose->bStrokeVariation = PAN_ANY;
  428. ppanose->bArmStyle = PAN_ANY;
  429. ppanose->bLetterform = PAN_ANY;
  430. ppanose->bMidline = PAN_ANY;
  431. ppanose->bXHeight = PAN_ANY;
  432. //
  433. // Now fill in the fields for the simulated fonts
  434. //
  435. if (pifi->dpFontSim)
  436. {
  437. //
  438. // Create a FONTDIFF template reflecting the base font
  439. //
  440. FONTDIFF FontDiff;
  441. FontDiff.jReserved1 = 0;
  442. FontDiff.jReserved2 = 0;
  443. FontDiff.jReserved3 = 0;
  444. FontDiff.bWeight = pifi->panose.bWeight;
  445. FontDiff.usWinWeight = pifi->usWinWeight;
  446. FontDiff.fsSelection = pifi->fsSelection;
  447. FontDiff.fwdAveCharWidth = pifi->fwdAveCharWidth;
  448. FontDiff.fwdMaxCharInc = pifi->fwdMaxCharInc;
  449. FontDiff.ptlCaret = pifi->ptlCaret;
  450. if (pfdiffBold)
  451. {
  452. *pfdiffBold = FontDiff;
  453. pfdiffBoldItalic->bWeight = PAN_WEIGHT_BOLD;
  454. pfdiffBold->fsSelection |= FM_SEL_BOLD;
  455. pfdiffBold->usWinWeight = FW_BOLD;
  456. // in vtfd case this is only true in the notional space
  457. pfdiffBold->fwdAveCharWidth += 1;
  458. pfdiffBold->fwdMaxCharInc += 1;
  459. }
  460. if (pfdiffItalic)
  461. {
  462. *pfdiffItalic = FontDiff;
  463. pfdiffItalic->fsSelection |= FM_SEL_ITALIC;
  464. pfdiffItalic->ptlCaret.x = 1;
  465. pfdiffItalic->ptlCaret.y = 2;
  466. }
  467. if (pfdiffBoldItalic)
  468. {
  469. *pfdiffBoldItalic = FontDiff;
  470. pfdiffBoldItalic->bWeight = PAN_WEIGHT_BOLD;
  471. pfdiffBoldItalic->fsSelection |= (FM_SEL_BOLD | FM_SEL_ITALIC);
  472. pfdiffBoldItalic->usWinWeight = FW_BOLD;
  473. pfdiffBoldItalic->ptlCaret.x = 1;
  474. pfdiffBoldItalic->ptlCaret.y = 2;
  475. // in vtfd case this is only true in the notional space
  476. pfdiffBoldItalic->fwdAveCharWidth += 1;
  477. pfdiffBoldItalic->fwdMaxCharInc += 1;
  478. }
  479. }
  480. }
  481. ULONG cjVTFDIFIMETRICS(PBYTE ajHdr)
  482. {
  483. ULONG cjIFI = ALIGN4(sizeof(IFIMETRICS));
  484. PSZ pszFaceName = ajHdr + READ_DWORD(&ajHdr[OFF_Face]);
  485. ULONG cSims;
  486. cjIFI += ALIGN4((strlen(pszFaceName) + 1) * sizeof(WCHAR));
  487. // add simulations:
  488. if (cSims = (cVtfdResFaces(ajHdr) - 1))
  489. cjIFI += (ALIGN4(sizeof(FONTSIM)) + cSims * ALIGN4(sizeof(FONTDIFF)));
  490. return cjIFI;
  491. }
  492. /******************************Private*Routine*****************************\
  493. * HFF hffVtfdLoadFont
  494. *
  495. * Loads an *.fon or an *.fnt file, returns handle to a fonfile object
  496. * if successfull.
  497. *
  498. * History:
  499. * Wed 04-Nov-1992 -by- Bodin Dresevic [BodinD]
  500. * update: rewrote it to reflect the new ifimetrics organization;
  501. * 26-Feb-1992 -by- Wendy Wu [wendywu]
  502. * Adapted from bmfd.
  503. \**************************************************************************/
  504. BOOL bVtfdLoadFont(PVOID pvView, ULONG cjView, ULONG_PTR iFile, ULONG iType, HFF *phff)
  505. {
  506. WINRESDATA wrd;
  507. RES_ELEM re;
  508. ULONG dpIFI, cjFF;
  509. ULONG ifnt;
  510. PIFIMETRICS pifi;
  511. BOOL bResult;
  512. BOOL bCleanupOnError;
  513. bResult = FALSE;
  514. bCleanupOnError = FALSE;
  515. *phff = (HFF)NULL;
  516. if (iType == TYPE_DLL16)
  517. {
  518. if (!bInitWinResData(pvView,cjView, &wrd))
  519. {
  520. goto Exit;
  521. }
  522. }
  523. else // TYPE_FNT or TYPE_EXE
  524. {
  525. ASSERTDD((iType == TYPE_FNT) || (iType == TYPE_EXE),
  526. "hffVtfdLoadFont: wrong iType\n");
  527. re.pvResData = pvView;
  528. re.dpResData = 0;
  529. re.cjResData = cjView;
  530. re.pjFaceName = NULL;
  531. wrd.cFntRes = 1;
  532. }
  533. cjFF = dpIFI = offsetof(FONTFILE,afd) + wrd.cFntRes * sizeof(FACEDATA);
  534. for (ifnt = 0; ifnt < wrd.cFntRes; ifnt++)
  535. {
  536. if (iType == TYPE_DLL16)
  537. {
  538. if (!bGetFntResource(&wrd, ifnt, &re))
  539. {
  540. goto Exit;
  541. }
  542. }
  543. // verify that this is a no nonsense resource:
  544. if (!bVerifyVTFD(&re))
  545. {
  546. goto Exit;
  547. }
  548. cjFF += cjVTFDIFIMETRICS(re.pvResData);
  549. }
  550. // now at the bottom of the structure we will store File name
  551. // Let's allocate the FONTFILE struct.
  552. if ((*phff = (HFF)pffAlloc(cjFF)) == (HFF)NULL)
  553. {
  554. WARNING("hffVtfdLoadFont: memory allocation error\n");
  555. goto Exit;
  556. }
  557. bCleanupOnError = TRUE;
  558. // Initialize fields of FONTFILE struct.
  559. PFF(*phff)->iType = iType;
  560. PFF(*phff)->fl = 0;
  561. PFF(*phff)->cRef = 0L;
  562. PFF(*phff)->iFile = iFile;
  563. PFF(*phff)->pvView = pvView;
  564. PFF(*phff)->cjView = cjView;
  565. PFF(*phff)->cFace = wrd.cFntRes;
  566. pifi = (PIFIMETRICS)((PBYTE)PFF(*phff) + dpIFI);
  567. for (ifnt = 0; ifnt < wrd.cFntRes; ifnt++)
  568. {
  569. if (iType == TYPE_DLL16)
  570. {
  571. if (!bGetFntResource(&wrd, ifnt, &re))
  572. {
  573. goto Exit;
  574. }
  575. }
  576. PFF(*phff)->afd[ifnt].re = re;
  577. PFF(*phff)->afd[ifnt].iDefFace = iDefaultFace(re.pvResData);
  578. PFF(*phff)->afd[ifnt].pifi = pifi;
  579. PFF(*phff)->afd[ifnt].pcp = pcpComputeGlyphset(
  580. &gpcpVTFD,
  581. (UINT)((BYTE *)re.pvResData)[OFF_FirstChar],
  582. (UINT)((BYTE *)re.pvResData)[OFF_LastChar],
  583. ((BYTE*)(re.pvResData))[OFF_CharSet]
  584. );
  585. if (PFF(*phff)->afd[ifnt].pcp == NULL)
  586. {
  587. WARNING("pgsetCompute failed\n");
  588. goto Exit;
  589. }
  590. vVtfdFill_IFIMetrics(re.pvResData, &(PFF(*phff)->afd[ifnt].pcp->gset),pifi);
  591. pifi = (PIFIMETRICS)((PBYTE)pifi + pifi->cjThis);
  592. }
  593. bResult = TRUE;
  594. Exit:
  595. if (!bResult)
  596. {
  597. #if DBG
  598. NotifyBadFont("%s failing\n", __FUNCTION__);
  599. #endif
  600. if (bCleanupOnError)
  601. {
  602. vFree(*phff); // clean up
  603. *phff = (HFF)NULL; // do not clean up again in exception code path
  604. }
  605. }
  606. return bResult;
  607. }
  608. /******************************Public*Routine******************************\
  609. * vtfdLoadFontFile
  610. *
  611. * Load the given font file into memory and prepare the file for use.
  612. *
  613. * History:
  614. * 26-Feb-1992 -by- Wendy Wu [wendywu]
  615. * Adapted from bmfd.
  616. \**************************************************************************/
  617. BOOL vtfdLoadFontFile(ULONG_PTR iFile, PVOID pvView, ULONG cjView, HFF *phff)
  618. {
  619. BOOL bRet = FALSE;
  620. *phff = (HFF)NULL;
  621. // Try loading it as a fon file, if it does not work, try as an fnt file.
  622. if (!(bRet = bVtfdLoadFont(pvView, cjView, iFile, TYPE_DLL16,phff)))
  623. bRet = bVtfdLoadFont(pvView, cjView, iFile, TYPE_FNT, phff); // try as an *.fnt file
  624. return bRet;
  625. }
  626. /******************************Public*Routine******************************\
  627. * BOOL vtfdUnloadFontFile
  628. *
  629. * Unload a font file and free all the structures created.
  630. *
  631. * History:
  632. * 26-Feb-1992 -by- Wendy Wu [wendywu]
  633. * Adapted from bmfd.
  634. \**************************************************************************/
  635. BOOL vtfdUnloadFontFile(HFF hff)
  636. {
  637. ULONG iFace;
  638. if (hff == HFF_INVALID)
  639. return(FALSE);
  640. // check the reference count, if not 0 (font file is still
  641. // selected into a font context) we have a problem
  642. ASSERTDD(PFF(hff)->cRef == 0L, "cRef: links are broken\n");
  643. // unload all glyphsets:
  644. for (iFace = 0; iFace < PFF(hff)->cFace; iFace++)
  645. {
  646. vUnloadGlyphset(&gpcpVTFD,
  647. PFF(hff)->afd[iFace].pcp);
  648. }
  649. // the file has been umapped as cRef went back to zero
  650. vFree(PFF(hff));
  651. return(TRUE);
  652. }