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.

1243 lines
35 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: fdquery.c
  3. *
  4. * Contains all the vtfdQueryXXX functions. Adapted from BodinD's bitmap font
  5. * driver.
  6. *
  7. * Copyright (c) 1990-1995 Microsoft Corporation
  8. \**************************************************************************/
  9. #include "fd.h"
  10. #include "exehdr.h"
  11. #define OFF_CharWidth 2 //!!!Move to winfont.h
  12. //!!!Define OFF_CharTable10
  13. // Retrieve description string from .FON files.
  14. BOOL bDescStr (PVOID pvView, SIZE_T cjView, PSZ pszString);
  15. //
  16. // Function prototypes.
  17. //
  18. ULONG
  19. cjVtfdDeviceMetrics (
  20. PFONTCONTEXT pfc,
  21. FD_DEVICEMETRICS *pdevm
  22. );
  23. VOID
  24. vFill_GlyphData (
  25. PFONTCONTEXT pfc,
  26. GLYPHDATA *pgldt,
  27. UINT iIndex
  28. );
  29. BOOL
  30. bCreatePath (
  31. PCHAR pch,
  32. PCHAR pchEnd,
  33. PFONTCONTEXT pfc,
  34. PATHOBJ *ppo,
  35. FIX fxAB
  36. );
  37. VOID
  38. vFill_GlyphData (
  39. PFONTCONTEXT pfc,
  40. GLYPHDATA *pgldt,
  41. UINT iIndex
  42. );
  43. #if defined(_AMD64_) || defined(_IA64_)
  44. #define lCvt(ef, l) ((LONG) (ef * l))
  45. #else
  46. LONG lCvt(EFLOAT ef,LONG l);
  47. #endif
  48. //!!! this function is living in ttfd. should be moved to the engine [bodind]
  49. VOID vAddPOINTQF(POINTQF *, POINTQF *);
  50. /******************************Public*Routine******************************\
  51. *
  52. * BOOL bReconnectVtfdFont(FONTFILE *pff)
  53. *
  54. *
  55. * Effects: If the file is marked gone, we try to reconnect and see if we can
  56. * use it again. We clear the exception bit so that the system will
  57. * be able to use this font again.
  58. *
  59. * History:
  60. * 17-Aug-1994 -by- Bodin Dresevic [BodinD]
  61. * Wrote it.
  62. \**************************************************************************/
  63. BOOL bReconnectVtfdFont(FONTFILE *pff)
  64. {
  65. INT i;
  66. if ((pff->iType == TYPE_FNT) || (pff->iType == TYPE_DLL16))
  67. {
  68. if (!EngMapFontFileFD(pff->iFile, (PULONG*)&pff->pvView, &pff->cjView ))
  69. {
  70. WARNING("can not reconnect this vector font !!!\n");
  71. return FALSE;
  72. }
  73. for (i = 0; i < (INT)pff->cFace; i++)
  74. {
  75. pff->afd[i].re.pvResData = (PVOID) (
  76. (BYTE*)pff->pvView + pff->afd[i].re.dpResData
  77. );
  78. }
  79. }
  80. else
  81. {
  82. return FALSE;
  83. }
  84. // everything is fine again, clear the bit
  85. pff->fl &= ~FF_EXCEPTION_IN_PAGE_ERROR;
  86. return TRUE;
  87. }
  88. /******************************Public*Routine******************************\
  89. * PIFIMETRICS vtfdQueryFont
  90. *
  91. * Return a pointer to the IFIMETRICS for the given face.
  92. *
  93. * History:
  94. * 31-Aug-1992 Gilman Wong [gilmanw]
  95. * IFI/DDI merge.
  96. *
  97. * 26-Feb-1992 -by- Wendy Wu [wendywu]
  98. * Adapted from bmfd.
  99. \**************************************************************************/
  100. PIFIMETRICS vtfdQueryFont (
  101. DHPDEV dhpdev,
  102. HFF hff,
  103. ULONG iFace,
  104. ULONG_PTR *pid
  105. )
  106. {
  107. PFONTFILE pff;
  108. //
  109. // Validate handle.
  110. //
  111. if (hff == HFF_INVALID)
  112. {
  113. WARNING("vtfdQueryFaces(): invalid iFile (hff)\n");
  114. return (PIFIMETRICS) NULL;
  115. }
  116. //
  117. // We never unlock FONTFILE since it contains IFIMETRICS that engine
  118. // has a pointer to. hff is actually a pointer to the FONTFILE struct.
  119. //
  120. pff = (PFONTFILE)hff;
  121. //
  122. // Assume iFace within bounds.
  123. //
  124. ASSERTDD((iFace >= 1L) && (iFace <= pff->cFace),
  125. "vtfdQueryFaces: iFace out of range\n");
  126. //
  127. // Return pointer to IFIMETRICS.
  128. //
  129. return pff->afd[iFace-1].pifi;
  130. }
  131. /******************************Public*Routine******************************\
  132. * LONG vtfdQueryFontCaps
  133. *
  134. * Retrieve the capabilities of the font driver.
  135. *
  136. * History:
  137. * 26-Feb-1992 -by- Wendy Wu [wendywu]
  138. * Adapted from bmfd.
  139. \**************************************************************************/
  140. LONG vtfdQueryFontCaps (
  141. ULONG culCaps,
  142. PULONG pulCaps
  143. )
  144. {
  145. ASSERTDD(culCaps == 2, "ERROR - come on - update the font drivers");
  146. pulCaps[0] = 2L;
  147. //
  148. // The vector font driver only returns outlines.
  149. //
  150. pulCaps[1] = QC_OUTLINES;
  151. return(2);
  152. }
  153. /******************************Public*Routine******************************\
  154. * vtfdQueryFontTree
  155. *
  156. * This function returns pointers to per-face information.
  157. *
  158. * Parameters:
  159. *
  160. * dhpdev Not used.
  161. *
  162. * hff Handle to a font file.
  163. *
  164. * iFace Index of a face in the font file.
  165. *
  166. * iMode This is a 32-bit number that must be one of the following
  167. * values:
  168. *
  169. * Allowed ulMode values:
  170. * ----------------------
  171. *
  172. * QFT_LIGATURES -- returns a pointer to the ligature map.
  173. *
  174. * QFT_KERNPAIRS -- return a pointer to the kerning pair table.
  175. *
  176. * QFT_GLYPHSET -- return a pointer to the WC->HGLYPH mapping table.
  177. *
  178. * pid Not used.
  179. *
  180. * Returns:
  181. a Returns a pointer to the requested data. This data will not change
  182. * until VtfdfdFree is called on the pointer. Caller must not attempt to
  183. * modify the data. NULL is returned if an error occurs.
  184. *
  185. * History:
  186. * 31-Aug-1992 -by- Gilman Wong [gilmanw]
  187. * Wrote it.
  188. \**************************************************************************/
  189. PVOID
  190. vtfdQueryFontTree (
  191. DHPDEV dhpdev,
  192. HFF hff,
  193. ULONG iFace,
  194. ULONG iMode,
  195. ULONG_PTR *pid
  196. )
  197. {
  198. PFONTFILE pff;
  199. //
  200. // Validate parameters.
  201. //
  202. if (hff == HFF_INVALID)
  203. {
  204. WARNING("vtfdQueryFontTree(): invalid iFile (hff)\n");
  205. return ((PVOID) NULL);
  206. }
  207. //
  208. // Convert from handle to pointer.
  209. //
  210. pff = (PFONTFILE)hff;
  211. // Note: ulFont values are index-1 based.
  212. if ((iFace < 1L) || (iFace > pff->cFace))
  213. {
  214. WARNING("vtfdQueryFontTree()\n");
  215. return (NULL);
  216. }
  217. //
  218. // Which mode?
  219. //
  220. switch (iMode)
  221. {
  222. case QFT_LIGATURES:
  223. case QFT_KERNPAIRS:
  224. //
  225. // There are no ligatures or kerning pairs for the vector fonts,
  226. // therefore we return NULL
  227. //
  228. return ((PVOID) NULL);
  229. case QFT_GLYPHSET:
  230. return &pff->afd[iFace - 1].pcp->gset;
  231. default:
  232. //
  233. // Should never get here.
  234. //
  235. RIP("gdisrv!vtfdQueryFontTree(): unknown iMode\n");
  236. return ((PVOID) NULL);
  237. }
  238. }
  239. /******************************Public*Routine******************************\
  240. * vtfdQueryFontData
  241. *
  242. * dhpdev Not used.
  243. *
  244. * pfo Pointer to a FONTOBJ.
  245. *
  246. * iMode This is a 32-bit number that must be one of the following
  247. * values:
  248. *
  249. * Allowed ulMode values:
  250. * ----------------------
  251. *
  252. * QFD_GLYPH -- return glyph metrics only
  253. *
  254. * QFD_GLYPHANDBITMAP -- return glyph metrics and bitmap
  255. *
  256. * QFD_GLYPHANDOUTLINE -- return glyph metrics and outline
  257. *
  258. * QFD_MAXEXTENTS -- return FD_DEVICEMETRICS structure
  259. *
  260. * QFD_MAXGLYPHBITMAP -- return size of largest glyph AND its metrics
  261. *
  262. * cData Count of data items in the pvIn buffer.
  263. *
  264. * pvIn An array of glyph handles.
  265. *
  266. * pvOut Output buffer.
  267. *
  268. * Returns:
  269. * If mode is QFD_MAXGLYPHBITMAP, then size of glyph metrics plus
  270. * largest bitmap is returned.
  271. *
  272. * Otherwise, if pvOut is NULL, function will return size of the buffer
  273. * needed to copy the data requested; else, the function will return the
  274. * number of bytes written.
  275. *
  276. * FD_ERROR is returned if an error occurs.
  277. *
  278. * History:
  279. * 31-Aug-1992 -by- Gilman Wong [gilmanw]
  280. * Wrote it.
  281. \**************************************************************************/
  282. LONG
  283. vtfdQueryFontData (
  284. FONTOBJ *pfo,
  285. ULONG iMode,
  286. HGLYPH hg,
  287. GLYPHDATA *pgd,
  288. PVOID pv,
  289. ULONG cjSize
  290. )
  291. {
  292. PFONTCONTEXT pfc;
  293. PBYTE ajHdr;
  294. UINT iIndex, iIndexNext, offset1, offset2;
  295. PCHAR pch, pchEnd;
  296. PATHOBJ *ppo;
  297. PBYTE pjFirstChar, ajCharTable;
  298. GLYPHDATA gd;
  299. // MAKE sure that the file is not gone
  300. if (PFF(pfo->iFile)->fl & FF_EXCEPTION_IN_PAGE_ERROR)
  301. {
  302. // file gone, try to reconnect, if can not reconnect,
  303. // no questions will be answered about it:
  304. if (!bReconnectVtfdFont(PFF(pfo->iFile)))
  305. {
  306. WARNING("vtfdQueryFontData: EXCEPTION_IN_PAGE_ERROR\n");
  307. return FD_ERROR;
  308. }
  309. }
  310. // If pfo->pvProducer is NULL, then we need to open a font context.
  311. if ( pfo->pvProducer == (PVOID) NULL )
  312. pfo->pvProducer = (PVOID) vtfdOpenFontContext(pfo);
  313. if ( pfo->pvProducer == (PVOID) NULL )
  314. {
  315. WARNING("vtfdQueryFontData: pvProducer\n");
  316. return FD_ERROR;
  317. }
  318. pfc = (PFONTCONTEXT) pfo->pvProducer;
  319. // Setup local pointers to font file header. Note that these
  320. // could not be saved at fc creation time, for they could have changed
  321. // after net went down and back up again after reconnecting. [bodind]
  322. ajHdr = pfc->pre->pvResData;
  323. pjFirstChar = ajHdr + pfc->dpFirstChar;
  324. ajCharTable = ajHdr + OFF_jUnused20;
  325. // What mode?
  326. switch (iMode)
  327. {
  328. case QFD_GLYPHANDOUTLINE:
  329. {
  330. //
  331. // Grab pointer to PATHOBJ* array.
  332. //
  333. ppo = (PATHOBJ *)pv;
  334. //
  335. // Assume the engine will not pass an invalid handle.
  336. //
  337. ASSERTDD(hg != HGLYPH_INVALID,
  338. "vtfdQueryFontData(QFD_GLYPHANDOUTLINE): invalid hglyph\n");
  339. //
  340. // Use default glyph if hglyph out of range.
  341. //
  342. if (hg > (HGLYPH)(ajHdr[OFF_LastChar] - ajHdr[OFF_FirstChar]))
  343. iIndex = ajHdr[OFF_DefaultChar];
  344. else
  345. iIndex = hg;
  346. //
  347. // Fill in the GLYPHDATA structure.
  348. //
  349. if( pgd == NULL )
  350. {
  351. pgd = &gd;
  352. }
  353. vFill_GlyphData(pfc, pgd, iIndex);
  354. pgd->hg = hg;
  355. //
  356. // Construct the path.
  357. //
  358. if (ppo != NULL)
  359. {
  360. iIndexNext = iIndex + 1;
  361. if (pfc->pifi->flInfo & FM_INFO_CONSTANT_WIDTH)
  362. {
  363. iIndex <<= 1; // each entry is 2-byte long
  364. iIndexNext <<= 1;
  365. }
  366. else
  367. {
  368. iIndex <<= 2; // each entry is 4-byte long
  369. iIndexNext <<= 2;
  370. }
  371. offset1 = READ_WORD(&ajCharTable[iIndex]);
  372. offset2 = READ_WORD(&ajCharTable[iIndexNext]);
  373. if ((offset2 < offset1) || (pfc->dpFirstChar + offset2 > pfc->pre->cjResData))
  374. {
  375. WARNING("vtfd!vtfdQueryFontData: offset to path out of file\n");
  376. return FD_ERROR;
  377. }
  378. pch = pjFirstChar + offset1;
  379. pchEnd = pjFirstChar + offset2;
  380. ASSERTDD((*pch == PEN_UP),
  381. "vtfdQueryFontData(QFD_GLYPHANDOUTLINE): First command is not PEN_UP");
  382. if ( !bCreatePath(pch, pchEnd, pfc, ppo, pgd->fxAB) )
  383. {
  384. return FD_ERROR;
  385. }
  386. }
  387. }
  388. //
  389. // Return buffer size needed for all GLYPHDATA.
  390. //
  391. return 0;
  392. case QFD_MAXEXTENTS:
  393. //
  394. // If buffer NULL, return size.
  395. //
  396. if ( pv == (PVOID) NULL )
  397. return (sizeof(FD_DEVICEMETRICS));
  398. //
  399. // Otherwise, copy the data structure.
  400. //
  401. else
  402. return cjVtfdDeviceMetrics(pfc, (FD_DEVICEMETRICS *) pv);
  403. default:
  404. WARNING("vtfdQueryFontData(): unsupported mode\n");
  405. return FD_ERROR;
  406. }
  407. }
  408. /******************************Public*Routine******************************\
  409. * vtfdQueryFontFile
  410. *
  411. * A function to query per font file information.
  412. *
  413. * Parameters:
  414. *
  415. * hff Handle to a font file.
  416. *
  417. * ulMode This is a 32-bit number that must be one of the following
  418. * values:
  419. *
  420. * Allowed ulMode values:
  421. * ----------------------
  422. *
  423. * QFF_DESCRIPTION -- copies a UNICODE string in the buffer
  424. * that describes the contents of the font file.
  425. *
  426. * QFF_NUMFACES -- returns number of faces in the font file.
  427. *
  428. * cjBuf Maximum number of BYTEs to copy into the buffer. The
  429. * driver will not copy more than this many BYTEs.
  430. *
  431. * This should be zero if pulBuf is NULL.
  432. *
  433. * This parameter is not used in QFF_NUMFACES mode.
  434. *
  435. * pulBuf Pointer to the buffer to receive the data
  436. * If this is NULL, then the required buffer size
  437. * is returned as a count of BYTEs. Notice that this
  438. * is a PULONG, to enforce 32-bit data alignment.
  439. *
  440. * This parameter is not used in QFF_NUMFACES mode.
  441. *
  442. * Returns:
  443. *
  444. * If mode is QFF_DESCRIPTION, then the number of BYTEs copied into
  445. * the buffer is returned by the function. If pulBuf is NULL,
  446. * then the required buffer size (as a count of BYTEs) is returned.
  447. *
  448. * If mode is QFF_NUMFACES, then number of faces in font file is returned.
  449. *
  450. * FD_ERROR is returned if an error occurs.
  451. *
  452. * History:
  453. * 09-Mar-1992 -by- Gilman Wong [gilmanw]
  454. * Wrote it.
  455. \**************************************************************************/
  456. LONG vtfdQueryFontFile (
  457. HFF hff, // handle to font file
  458. ULONG ulMode, // type of query
  459. ULONG cjBuf, // size of buffer (in BYTEs)
  460. PULONG pulBuf // return buffer (NULL if requesting size of data)
  461. )
  462. {
  463. //
  464. // We never unlock FONTFILE since it contains IFIMETRICS that the engine
  465. // has a pointer to. hff is actually a pointer to the FONTFILE struct.
  466. //
  467. ULONG cjDescription;
  468. PVOID pvView;
  469. ULONG cjView;
  470. PIFIMETRICS pifi;
  471. LPWSTR pwszDescription;
  472. ASSERTDD(hff, "vtfdQueryFontFile, hff invalid\n");
  473. if (PFF(hff)->fl & FF_EXCEPTION_IN_PAGE_ERROR)
  474. {
  475. // file gone, try to reconnect, if can not reconnect,
  476. // no questions will be answered about it:
  477. if (!bReconnectVtfdFont(PFF(hff)))
  478. {
  479. WARNING("vtfdQueryFontFile: EXCEPTION_IN_PAGE_ERROR\n");
  480. return FD_ERROR;
  481. }
  482. }
  483. //
  484. // Which mode?
  485. //
  486. switch (ulMode)
  487. {
  488. case QFF_DESCRIPTION:
  489. //
  490. // If .FON format, retrieve the description string from the mapped file view.
  491. //
  492. if (PFF(hff)->iType == TYPE_DLL16)
  493. {
  494. CHAR achDescription[256]; // max length of string in the 16-bit EXE.
  495. // check, maybe cRef is 0 so that fvw is not valid:
  496. if (PFF(hff)->cRef == 0)
  497. {
  498. if (!EngMapFontFileFD(PFF(hff)->iFile,(PULONG*)&pvView,&cjView))
  499. {
  500. WARNING("somebody removed the file \n");
  501. return FD_ERROR;
  502. }
  503. }
  504. else
  505. {
  506. pvView = PFF(hff)->pvView;
  507. cjView = PFF(hff)->cjView;
  508. }
  509. cjDescription = FD_ERROR;
  510. if (bDescStr(pvView, cjView, achDescription))
  511. {
  512. cjDescription = (strlen(achDescription) + 1) * sizeof(WCHAR);
  513. //
  514. // If there is a buffer, copy the data.
  515. //
  516. if ( pulBuf != (PULONG) NULL )
  517. {
  518. //
  519. // Is buffer big enough?
  520. //
  521. if ( cjBuf < cjDescription )
  522. {
  523. WARNING("vtfdQueryFontFile(): buffer too small for string\n");
  524. return (FD_ERROR);
  525. }
  526. else
  527. {
  528. vToUNICODEN((LPWSTR)pulBuf, cjDescription/sizeof(WCHAR), achDescription, cjDescription/sizeof(WCHAR));
  529. }
  530. }
  531. }
  532. // clean up if need be
  533. if (PFF(hff)->cRef == 0)
  534. EngUnmapFontFileFD(PFF(hff)->iFile);
  535. return(cjDescription);
  536. }
  537. //
  538. // Otherwise, .FNT files do not have a description string. We may also
  539. // get here if its a .FON format but bDescStr failed. We will have
  540. // to use the facename.
  541. //
  542. //
  543. // Get ptr to the facename in the IFIMETRICS of the first font
  544. // in this font file.
  545. //
  546. pifi = PFF(hff)->afd[0].pifi;
  547. pwszDescription = (LPWSTR)((PBYTE) pifi + pifi->dpwszFaceName);
  548. cjDescription = (wcslen(pwszDescription) + 1) * sizeof(WCHAR);
  549. //
  550. // If there is a buffer, copy to it.
  551. //
  552. if ( pulBuf != (PULONG) NULL )
  553. {
  554. //
  555. // Is buffer big enough?
  556. //
  557. if ( cjBuf < cjDescription )
  558. {
  559. WARNING("vtfdQueryFontFile(): buffer too small for face\n");
  560. return (FD_ERROR);
  561. }
  562. else
  563. {
  564. RtlCopyMemory((PVOID) pulBuf,
  565. (PVOID) pwszDescription,
  566. cjDescription);
  567. }
  568. }
  569. return(cjDescription);
  570. case QFF_NUMFACES:
  571. return PFF(hff)->cFace;
  572. default:
  573. WARNING("vtfdQueryFontFile(): unknown mode\n");
  574. break;
  575. }
  576. // Default return. We should not get here.
  577. return FD_ERROR;
  578. }
  579. /******************************Public*Routine******************************\
  580. * cjVtfdDeviceMetrics
  581. *
  582. *
  583. * Effects:
  584. *
  585. * Warnings:
  586. *
  587. * History:
  588. * 30-Aug-1992 -by- Gilman Wong [gilmanw]
  589. * Stole it from WendyWu's FdQueryFaceAttr() implementation.
  590. \**************************************************************************/
  591. ULONG
  592. cjVtfdDeviceMetrics (
  593. PFONTCONTEXT pfc,
  594. FD_DEVICEMETRICS *pdevm
  595. )
  596. {
  597. PIFIMETRICS pifi;
  598. EFLOAT efM11, efM12, efM21, efM22;
  599. BOOL bScaleOnly;
  600. // Compute the accelerator flags for this font.
  601. pdevm->flRealizedType = 0; // no bitmaps are produced
  602. if ((pfc->flags & FC_SIM_ITALICIZE) == 0)
  603. pdevm->flRealizedType |= FDM_TYPE_ZERO_BEARINGS;
  604. // Make sure nobody updates the font context when we're reading from it.
  605. // !!! not possible, ResetFontContext is gone, [BODIND]
  606. efM11 = pfc->efM11;
  607. efM12 = pfc->efM12;
  608. efM21 = pfc->efM21;
  609. efM22 = pfc->efM22;
  610. pdevm->pteBase = pfc->pteUnitBase;
  611. pdevm->pteSide = pfc->pteUnitSide;
  612. // fxMaxAscender/Descender are the distance from the baseline to the
  613. // top/bottom of the glyph. fxInkTop/Bottom are vectors along the
  614. // ascent direction. We need to adjust the sign properly.
  615. pdevm->fxMaxAscender = pfc->fxInkTop;
  616. pdevm->fxMaxDescender = -pfc->fxInkBottom;
  617. bScaleOnly = pfc->flags & FC_SCALE_ONLY;
  618. pdevm->cxMax = (ULONG)
  619. ((fxLTimesEf(&pfc->efBase, (LONG)pfc->pifi->fwdMaxCharInc) + 8) >> 4);
  620. // Transform the character increment vector.
  621. if
  622. (
  623. // only report accellerators for horiz case
  624. (pfc->pifi->flInfo & FM_INFO_CONSTANT_WIDTH) &&
  625. (pfc->flags & FC_SCALE_ONLY)
  626. )
  627. {
  628. pdevm->lD = (LONG)pdevm->cxMax;
  629. }
  630. else // var pitch
  631. {
  632. pdevm->lD = 0;
  633. }
  634. // Transform the StrikeOut and Underline vectors.
  635. pifi = pfc->pifi;
  636. pdevm->ptlUnderline1.y = FXTOLROUND(fxLTimesEf(&efM22, -pifi->fwdUnderscorePosition));
  637. pdevm->ptlStrikeOut.y = FXTOLROUND(fxLTimesEf(&efM22, -pifi->fwdStrikeoutPosition));
  638. pdevm->ptlULThickness.y = pdevm->ptlSOThickness.y = 1;
  639. pdevm->ptlULThickness.x = pdevm->ptlSOThickness.x = 0;
  640. if (pfc->flags & FC_SIM_EMBOLDEN)
  641. pdevm->ptlULThickness.y = pdevm->ptlSOThickness.y = 2;
  642. if (bScaleOnly)
  643. {
  644. pdevm->ptlUnderline1.x = pdevm->ptlStrikeOut.x = 0;
  645. if (!bPositive(efM22))
  646. {
  647. pdevm->ptlULThickness.y = -pdevm->ptlULThickness.y;
  648. pdevm->ptlSOThickness.y = -pdevm->ptlSOThickness.y;
  649. }
  650. }
  651. else
  652. {
  653. // !!!Cache this in HDC if underline or strikeout are used often.
  654. pdevm->ptlULThickness.x = FXTOLROUND(fxLTimesEf(&efM21, pdevm->ptlULThickness.y));
  655. pdevm->ptlULThickness.y = FXTOLROUND(fxLTimesEf(&efM22, pdevm->ptlULThickness.y));
  656. pdevm->ptlSOThickness.x = pdevm->ptlULThickness.x;
  657. pdevm->ptlSOThickness.y = pdevm->ptlULThickness.y;
  658. pdevm->ptlUnderline1.x = FXTOLROUND(fxLTimesEf(&efM21, -pifi->fwdUnderscorePosition));
  659. pdevm->ptlStrikeOut.x = FXTOLROUND(fxLTimesEf(&efM21, -pifi->fwdStrikeoutPosition));
  660. }
  661. // devm, no bitmaps are supported;
  662. pdevm->cyMax = 0;
  663. pdevm->cjGlyphMax = 0;
  664. return(sizeof(FD_DEVICEMETRICS));
  665. }
  666. /******************************Private*Routine*****************************\
  667. * VOID vFill_GlyphData
  668. *
  669. * Fill in the GLYPHDATA structure for the given glyph index.
  670. *
  671. * History:
  672. * 18-Feb-1992 -by- Wendy Wu [wendywu]
  673. * Wrote it.
  674. \**************************************************************************/
  675. VOID vFill_GlyphData(PFONTCONTEXT pfc, GLYPHDATA *pgldt, UINT iIndex)
  676. {
  677. LONG lCharInc;
  678. PBYTE ajCharTable = (PBYTE)pfc->pre->pvResData + OFF_jUnused20;
  679. pgldt->gdf.pgb = NULL;
  680. pgldt->hg = iIndex; //!!!????
  681. // Transform the character increment vector.
  682. if (pfc->pifi->flInfo & FM_INFO_CONSTANT_WIDTH)
  683. {
  684. lCharInc = pfc->pifi->fwdMaxCharInc;
  685. }
  686. else
  687. {
  688. // We're dealing with variable-width font, get the width from
  689. // the chartable. Each entry in CharTable is 4-byte long.
  690. lCharInc = READ_WORD(ajCharTable + OFF_CharWidth + (iIndex << 2));
  691. }
  692. pgldt->fxInkTop = pfc->fxInkTop;
  693. pgldt->fxInkBottom = pfc->fxInkBottom;
  694. if (pfc->flags & FC_SCALE_ONLY)
  695. {
  696. // here we do rounding to be compat with windows 31, and also to
  697. // so that we can report the accelerator pdevm->lD for fixed pitch
  698. // font as being really equal to fxD's for such a font
  699. pgldt->fxD = ((fxLTimesEf(&pfc->efBase, lCharInc) + 8) & 0xfffffff0);
  700. // Simple scaling transform.
  701. if (pfc->flags & FC_X_INVERT)
  702. pgldt->ptqD.x.HighPart = -pgldt->fxD;
  703. else
  704. pgldt->ptqD.x.HighPart = pgldt->fxD;
  705. pgldt->ptqD.x.LowPart = 0;
  706. pgldt->ptqD.y.HighPart = 0;
  707. pgldt->ptqD.y.LowPart = 0;
  708. }
  709. else
  710. {
  711. // in this case we do not do rounding, we want everything consistent:
  712. pgldt->fxD = fxLTimesEf(&pfc->efBase, lCharInc);
  713. // Non trivial transform.
  714. vLTimesVtfl(lCharInc, &pfc->vtflBase, &pgldt->ptqD);
  715. }
  716. //!!! not sure if these should be calculated differently for non-trivial cases.
  717. pgldt->fxA = 0;
  718. pgldt->fxAB = pgldt->fxD;
  719. if (pfc->flags & FC_SIM_EMBOLDEN)
  720. {
  721. pgldt->fxAB += pfc->fxEmbolden;
  722. }
  723. if (pfc->flags & FC_SIM_ITALICIZE)
  724. {
  725. pgldt->fxAB += pfc->fxItalic;
  726. }
  727. //!!! rclInk is missing, but not needed I guess (bodind)
  728. }
  729. /******************************Public*Routine******************************\
  730. * vtfdQueryAdvanceWidths *
  731. * *
  732. * A routine to compute advance widths. *
  733. * *
  734. * History: *
  735. * Mon 18-Jan-1993 08:13:02 -by- Charles Whitmer [chuckwh] *
  736. * Wrote it. *
  737. \**************************************************************************/
  738. BOOL vtfdQueryAdvanceWidths
  739. (
  740. FONTOBJ *pfo,
  741. ULONG iMode,
  742. HGLYPH *phg,
  743. LONG *plWidths,
  744. ULONG cGlyphs
  745. )
  746. {
  747. FONTCONTEXT *pfc;
  748. USHORT *psWidths = (USHORT *) plWidths; // True for the cases we handle.
  749. LONG dx;
  750. ULONG ii;
  751. PBYTE ajCharTable;
  752. if (PFF(pfo->iFile)->fl & FF_EXCEPTION_IN_PAGE_ERROR)
  753. {
  754. // file gone, try to reconnect, if can not reconnect,
  755. // no questions will be answered about it:
  756. if (!bReconnectVtfdFont(PFF(pfo->iFile)))
  757. {
  758. WARNING("vtfdQueryAdvanceWidths: EXCEPTION_IN_PAGE_ERROR\n");
  759. return FD_ERROR;
  760. }
  761. }
  762. // If pfo->pvProducer is NULL, then we need to open a font context.
  763. if ( pfo->pvProducer == (PVOID) NULL )
  764. pfo->pvProducer = (PVOID) vtfdOpenFontContext(pfo);
  765. if ( pfo->pvProducer == (PVOID) NULL )
  766. {
  767. WARNING("vtfdQueryAdvanceWidths: pvProducer\n");
  768. return FD_ERROR;
  769. }
  770. pfc = (FONTCONTEXT *) pfo->pvProducer;
  771. ajCharTable = (PBYTE)pfc->pre->pvResData + OFF_jUnused20;
  772. ASSERTDD(!(pfc->pifi->flInfo & FM_INFO_CONSTANT_WIDTH),
  773. "this is a fixed pitch font\n");
  774. // only report accellerators
  775. ASSERTDD((pfc->flags & FC_SCALE_ONLY),
  776. "must not be a rotating xform\n");
  777. // Get the widths.
  778. for (ii=0; ii<cGlyphs; ii++,phg++,psWidths++)
  779. {
  780. dx = READ_WORD(ajCharTable + OFF_CharWidth + (*phg << 2));
  781. *psWidths = (SHORT) ((lCvt(pfc->efBase,dx) + 8) & 0xfffffff0);
  782. }
  783. return(TRUE);
  784. }
  785. /******************************Private*Routine*****************************\
  786. * BOOL bCreatePath
  787. *
  788. * Create a path by reading the vector descriptions contained in the
  789. * memory space pointed to between pch and pchEnd.
  790. *
  791. * History:
  792. * 18-Feb-1992 -by- Wendy Wu [wendywu]
  793. * Wrote it.
  794. \**************************************************************************/
  795. #define CPTS_MAX 5
  796. BOOL
  797. bCreatePath(
  798. PCHAR pch,
  799. PCHAR pchEnd,
  800. PFONTCONTEXT pfc,
  801. PATHOBJ *ppo,
  802. FIX fxAB)
  803. {
  804. UINT iPt, cPts = 0;
  805. LONG lXLast, lDesc;
  806. POINTL aptl[CPTS_MAX];
  807. POINTFIX aptfx[CPTS_MAX];
  808. BOOL bEmbolden, bItalicize, bScaleOnly, bReturn = TRUE;
  809. EFLOAT efM11, efM12, efM21, efM22;
  810. POINTFIX pfxBaseOffset;
  811. POINTFIX ptfxBound;
  812. efM11 = pfc->efM11;
  813. efM12 = pfc->efM12;
  814. efM21 = pfc->efM21;
  815. efM22 = pfc->efM22;
  816. lDesc = pfc->pifi->fwdWinDescender;
  817. bEmbolden = pfc->flags & FC_SIM_EMBOLDEN;
  818. bItalicize = pfc->flags & FC_SIM_ITALICIZE;
  819. bScaleOnly = pfc->flags & FC_SCALE_ONLY;
  820. pfxBaseOffset = pfc->pfxBaseOffset;
  821. // Some points in the glyphs paths may end up on the bottom or right edge of
  822. // the bounding rectangle for a glyph. Because of GIQ it is possible that
  823. // sometimes these pels will get lit. However, because our bounding rectangles
  824. // are bottom right exclusive they will never be considered to contain these
  825. // pels. This is a problem. We need to adjust by making sure that any points
  826. // which can possibly light a pel on the bottom or right edge of the bounding
  827. // rectangle are adjust either to the right or up. Note that we only need
  828. // to worry about orientations of 90 degrees because the engine will relax
  829. // the bouding rectangle by one pel at other orientations. There are 8 cases
  830. // altogether when we take flipping into account. [gerritv]
  831. switch( pfc->flags & ORIENT_MASK )
  832. {
  833. case FC_ORIENT_1:
  834. ptfxBound.x = fxAB - 0x10;
  835. ptfxBound.y = -pfc->fxInkBottom - 0x10;
  836. break;
  837. case FC_ORIENT_2:
  838. ptfxBound.x = fxAB - 0x10;
  839. ptfxBound.y = pfc->fxInkTop - 0x10;
  840. break;
  841. case FC_ORIENT_3:
  842. ptfxBound.y = pfc->fxInkTop - 0x10;
  843. ptfxBound.x = -0x10;
  844. break;
  845. case FC_ORIENT_4:
  846. ptfxBound.y = -pfc->fxInkBottom - 0x10;
  847. ptfxBound.x = -0x10;
  848. break;
  849. case FC_ORIENT_5:
  850. ptfxBound.x = -pfc->fxInkBottom - 0x10;
  851. ptfxBound.y = fxAB - 0x10;
  852. break;
  853. case FC_ORIENT_6:
  854. ptfxBound.x = -pfc->fxInkBottom - 0x10;
  855. ptfxBound.y = -0x10;
  856. break;
  857. case FC_ORIENT_7:
  858. ptfxBound.x = pfc->fxInkTop - 0x10;
  859. ptfxBound.y = fxAB - 0x10;
  860. break;
  861. case FC_ORIENT_8:
  862. ptfxBound.y = -0x10;
  863. ptfxBound.x = pfc->fxInkTop - 0x10;
  864. break;
  865. }
  866. // The path starts from the top left corner of the cell.
  867. aptl[0].y = -pfc->pifi->fwdWinAscender;
  868. aptl[0].x = 0;
  869. while(pch <= pchEnd)
  870. {
  871. if ( (pch != pchEnd) && (*pch != PEN_UP))
  872. {
  873. // Check if there is space left. If not, send this batch of points
  874. // to engine for path construction.
  875. if (cPts >= CPTS_MAX)
  876. goto BUILD_PATH;
  877. // Attach this point to the end of the pointl array.
  878. // claudebe, NTRAID#440755 and 440756, PREFIX, we could have cPts == 0 and accessing
  879. // aptl[-1], since vector font are becoming obsolete and this is very old code
  880. // and no customer ever complain about a problem getting the path of a vector font
  881. // I'm just doing a minimal fix to prevent accessing aptl[-1]
  882. if (cPts > 0)
  883. {
  884. aptl[cPts].x = (signed char)*pch++ + aptl[cPts-1].x;
  885. if (pch == pchEnd)
  886. {
  887. WARNING("vtfd!bCreatePath(): y coordinate out of font file\n");
  888. return FALSE;
  889. }
  890. aptl[cPts].y = (signed char)*pch++ + aptl[cPts-1].y;
  891. } else {
  892. aptl[cPts].x = (signed char)*pch++ ;
  893. if (pch == pchEnd)
  894. {
  895. WARNING("vtfd!bCreatePath(): y coordinate out of font file\n");
  896. return FALSE;
  897. }
  898. aptl[cPts].y = (signed char)*pch++ ;
  899. }
  900. cPts++;
  901. }
  902. else
  903. {
  904. if (cPts > 1)
  905. {
  906. BUILD_PATH:
  907. cPts--;
  908. // If Italic simulation is asked, x coordinates of all the points
  909. // will be changed. Save the x of the last point so the next
  910. // batch will have a correct reference point.
  911. lXLast = aptl[cPts].x;
  912. #if DEBUG
  913. {
  914. UINT i;
  915. DbgPrint("MoveTo (%lx, %lx)\n", aptl[0].x, aptl[0].y);
  916. DbgPrint("PolyLineTo cPts = %lx\n",cPts);
  917. for (i = 1; i <= cPts; i++)
  918. {
  919. DbgPrint(" (%lx, %lx)\n",aptl[i].x, aptl[i].y);
  920. }
  921. }
  922. #endif
  923. if (bItalicize)
  924. {
  925. for (iPt = 0; iPt <= cPts; iPt++)
  926. aptl[iPt].x += (lDesc - aptl[iPt].y)>>1;
  927. }
  928. if (bScaleOnly)
  929. {
  930. for (iPt = 0; iPt <= cPts; iPt++)
  931. {
  932. aptfx[iPt].x = (FIX)lCvt(efM11, aptl[iPt].x);
  933. aptfx[iPt].y = (FIX)lCvt(efM22, aptl[iPt].y);
  934. if( aptfx[iPt].y > ptfxBound.y )
  935. {
  936. #if DEBUG
  937. DbgPrint("y adjust %x to %x\n", aptfx[iPt].y, ptfxBound.y );
  938. #endif
  939. aptfx[iPt].y = ptfxBound.y;
  940. }
  941. if( aptfx[iPt].x > ptfxBound.x )
  942. {
  943. #if DEBUG
  944. DbgPrint("x adjust %x %x\n", aptfx[iPt].x, ptfxBound.x );
  945. #endif
  946. aptfx[iPt].x = ptfxBound.x;
  947. }
  948. }
  949. }
  950. else
  951. {
  952. for (iPt = 0; iPt <= cPts; iPt++)
  953. {
  954. aptfx[iPt].x = (FIX)lCvt(efM11, aptl[iPt].x) +
  955. (FIX)lCvt(efM21, aptl[iPt].y);
  956. aptfx[iPt].y = (FIX)lCvt(efM12, aptl[iPt].x) +
  957. (FIX)lCvt(efM22, aptl[iPt].y);
  958. // only if an orientation flag is set then we must adjust
  959. if( pfc->flags & ORIENT_MASK )
  960. {
  961. if( aptfx[iPt].y > ptfxBound.y )
  962. {
  963. #if DEBUG
  964. DbgPrint("y adjust %x %x\n", aptfx[iPt].y, ptfxBound.y );
  965. #endif
  966. aptfx[iPt].y = ptfxBound.y;
  967. }
  968. if( aptfx[iPt].x > ptfxBound.x )
  969. {
  970. #if DEBUG
  971. DbgPrint("x adjust %x %x\n", aptfx[iPt].x, ptfxBound.x );
  972. #endif
  973. aptfx[iPt].x = ptfxBound.x;
  974. }
  975. }
  976. }
  977. }
  978. bReturn &= PATHOBJ_bMoveTo(ppo, aptfx[0]);
  979. bReturn &= PATHOBJ_bPolyLineTo(ppo, &aptfx[1], cPts);
  980. #if DEBUG
  981. {
  982. UINT i;
  983. DbgPrint("MoveTo (%lx, %lx)\n", aptfx[0].x, aptfx[0].y);
  984. DbgPrint("PolyLineTo cPts = %lx\n",cPts);
  985. for (i = 1; i <= cPts; i++)
  986. {
  987. DbgPrint(" (%lx, %lx)\n",aptfx[i].x, aptfx[i].y);
  988. }
  989. }
  990. #endif
  991. if (bEmbolden)
  992. {
  993. for (iPt = 0; iPt <= cPts; iPt++)
  994. {
  995. // offset the whole path in the unit base direction
  996. aptfx[iPt].x += pfxBaseOffset.x;
  997. aptfx[iPt].y += pfxBaseOffset.y;
  998. }
  999. bReturn &= PATHOBJ_bMoveTo(ppo, aptfx[0]);
  1000. bReturn &= PATHOBJ_bPolyLineTo(ppo, &aptfx[1], cPts);
  1001. }
  1002. if ((pch != pchEnd) && (*pch != PEN_UP) )
  1003. {
  1004. // We got here because the aptl[] and aptfx[] buffer is
  1005. // not big enough. Move to the last point in PolyLineTo
  1006. // and start storing the next batch of points.
  1007. aptl[0].x = lXLast;
  1008. aptl[0].y = aptl[cPts].y;
  1009. cPts = 1;
  1010. continue;
  1011. }
  1012. aptl[cPts].x = lXLast;
  1013. }
  1014. pch++;
  1015. if (pch == pchEnd)
  1016. {
  1017. WARNING("vtfd!bCreatePath(): final x coordinate out of font file\n");
  1018. return FALSE;
  1019. }
  1020. aptl[0].x = (signed char)*pch++ + aptl[cPts].x;
  1021. if (pch == pchEnd)
  1022. {
  1023. WARNING("vtfd!bCreatePath(): final y coordinate out of font file\n");
  1024. return FALSE;
  1025. }
  1026. aptl[0].y = (signed char)*pch++ + aptl[cPts].y;
  1027. cPts = 1;
  1028. }
  1029. }
  1030. return(bReturn);
  1031. }