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.

428 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. qfontdat.c
  5. Abstract:
  6. Implements the DrvQueryFontData function - returns information
  7. about glyphs (size, position wrt box) or kerning information.
  8. Environment:
  9. Windows NT Unidrv driver
  10. Revision History:
  11. 12/19/96 -ganeshp-
  12. Created
  13. --*/
  14. #include "font.h"
  15. /*
  16. * The values for pteBase, pteSide in FD_DEVICEMETRICS, allowing
  17. * for rotation by 90 degree multiples.
  18. */
  19. #if defined(USEFLOATS) || defined(WINNT_40)
  20. static const POINTE pteRotBase[] =
  21. {
  22. { (FLOAT) 1.0, (FLOAT) 0.0 },
  23. { (FLOAT) 0.0, (FLOAT)-1.0 },
  24. { (FLOAT)-1.0, (FLOAT) 0.0 },
  25. { (FLOAT) 0.0, (FLOAT) 1.0 }
  26. };
  27. static const POINTE pteRotSide[] =
  28. {
  29. { (FLOAT) 0.0, (FLOAT)-1.0 },
  30. { (FLOAT)-1.0, (FLOAT) 0.0 },
  31. { (FLOAT) 0.0, (FLOAT) 1.0 },
  32. { (FLOAT) 1.0, (FLOAT) 0.0 }
  33. };
  34. #else
  35. static const POINTE pteRotBase[] =
  36. {
  37. { (FLOATL) FLOATL_1_0, (FLOATL) FLOATL_0_0 },
  38. { (FLOATL) FLOATL_0_0, (FLOATL) FLOATL_1_0M },
  39. { (FLOATL) FLOATL_1_0M,(FLOATL) FLOATL_0_0 },
  40. { (FLOATL) FLOATL_0_0, (FLOATL) FLOATL_1_0 }
  41. };
  42. static const POINTE pteRotSide[] =
  43. {
  44. { (FLOATL) FLOATL_0_0, (FLOATL) FLOATL_1_0M },
  45. { (FLOATL) FLOATL_1_0M,(FLOATL) FLOATL_0_0 },
  46. { (FLOATL) FLOATL_0_0, (FLOATL) FLOATL_1_0 },
  47. { (FLOATL) FLOATL_1_0, (FLOATL) FLOATL_0_0 }
  48. };
  49. #endif //defined(USEFLOATS) || defined(WINNT_40)
  50. /* The X dimension rotation cases */
  51. static const POINTL ptlXRot[] =
  52. {
  53. { 1, 0 },
  54. { 0, -1 },
  55. { -1, 0 },
  56. { 0, 1 },
  57. };
  58. /* The Y dimension rotation cases */
  59. static const POINTL ptlYRot[] =
  60. {
  61. { 0, 1 },
  62. { 1, 0 },
  63. { 0, -1 },
  64. { -1, 0 },
  65. };
  66. LONG
  67. FMQueryFontData(
  68. PDEV *pPDev,
  69. FONTOBJ *pfo,
  70. ULONG iMode,
  71. HGLYPH hg,
  72. GLYPHDATA *pgd,
  73. PVOID pv,
  74. ULONG cjSize
  75. )
  76. /*++
  77. Routine Description:
  78. Return information about glyphs in the font, OR kerning data.
  79. Arguments:
  80. pPDev Really a pPDev
  81. pfo The font of interest
  82. iMode Glyphdata or kerning information
  83. hg Handle to glyph
  84. pgd Place to put metrics
  85. pv Output area
  86. cjSize Size of output area
  87. Return Value:
  88. Number of bytes needed or written, 0xffffffff for error.
  89. Note:
  90. 12-29-96: Created it -ganeshp-
  91. --*/
  92. {
  93. FONTPDEV *pFontPDev;
  94. int iRot; /* Rotation multiple of 90 degrees */
  95. LONG lRet; /* Value returned */
  96. FONTMAP *pFM; /* Font data */
  97. FONTMAP_DEV *pFMDev; /* Font data */
  98. FONTCTL ctl; /* Font scale/rotation adjustments */
  99. IFIMETRICS *pIFI;
  100. XFORMOBJ *pxo;
  101. LONG lAscender;
  102. LONG lDescender;
  103. FLOATOBJ fo;
  104. pFontPDev = pPDev->pFontPDev;
  105. lRet = FD_ERROR;
  106. if( pfo->iFace < 1 || (int)pfo->iFace > pPDev->iFonts )
  107. {
  108. ERR(("Bad FONTOBJ, iFace is %d",pfo->iFace));
  109. SetLastError( ERROR_INVALID_PARAMETER );
  110. return lRet;
  111. }
  112. pFM = PfmGetDevicePFM( pPDev, pfo->iFace );
  113. if( pFM == NULL )
  114. return lRet;
  115. VDBGDUMPFONTMAP(pFM);
  116. pFMDev = pFM->pSubFM;
  117. pIFI = pFM->pIFIMet; /* IFIMETRICS - useful to have */
  118. if( pgd || pv )
  119. {
  120. /*
  121. * Need to obtain a transform to adjust these numbers as to
  122. * how the engine wants them.
  123. */
  124. if( !(pxo = FONTOBJ_pxoGetXform( pfo )) )
  125. {
  126. ERR(( "UniFont!FMQueryFontData: FONTOBJ_pxoGetXform fails\n" ));
  127. return lRet;
  128. }
  129. /* Can now obtain the transform! */
  130. //Added Check for HP Intellifont
  131. iRot = ISetScale( &ctl, pxo, ((pFM->flFlags & FM_SCALABLE) &&
  132. (pFMDev->wDevFontType ==
  133. DF_TYPE_HPINTELLIFONT)),
  134. (pFontPDev->flText & TC_CR_ANY)?TRUE:FALSE);
  135. if (pFontPDev->flText & TC_CR_ANY)
  136. iRot = (iRot + 45) / 90;
  137. /*
  138. * There are some adjustments to make to the scale factors. One
  139. * is to compensate for resolutions (these are coarse, integral
  140. * adjustments), the others are to to do with Intellifont. First
  141. * is the Intellifont point is 1/72.31 inches (!), and secondly
  142. * the LaserJet only adjusts font size to the nearest 0.25 point,
  143. * and hence when we round to that multiple, we need to adjust
  144. * the width accordingly.
  145. */
  146. if( pFM->flFlags & FM_SCALABLE )
  147. {
  148. int iPtSize, iAdjustedPtSize; /* For scale factor adjustment */
  149. #ifdef USEFLOATS
  150. /* The limited font size resolution */
  151. iPtSize = (int)(0.5 + ctl.eYScale * pIFI->fwdUnitsPerEm * 7200) / pPDev->ptGrxRes.y;
  152. /* if the tranform is very small (Less than a quarter of point size)
  153. * then make it atleast a quarter point. This was causing AV in certain
  154. * cases.
  155. */
  156. if (iPtSize < 25)
  157. {
  158. iPtSize = 25;
  159. }
  160. iAdjustedPtSize = ((iPtSize + 12) / 25) * 25;
  161. //Adjust the Scale Factor for quarter point adjustment.
  162. ctl.eXScale = (ctl.eXScale * iAdjustedPtSize) / iPtSize;
  163. ctl.eYScale = (ctl.eYScale * iAdjustedPtSize) / iPtSize;
  164. #else
  165. fo = ctl.eYScale;
  166. FLOATOBJ_MulLong(&fo,pIFI->fwdUnitsPerEm);
  167. FLOATOBJ_MulLong(&fo,7200);
  168. #ifndef WINNT_40 //NT 5.0
  169. FLOATOBJ_AddFloat(&fo,(FLOATL)FLOATL_00_50);
  170. #else // NT 4.0
  171. FLOATOBJ_AddFloat(&fo,(FLOAT)0.5);
  172. #endif //!WINNT_40
  173. iPtSize = FLOATOBJ_GetLong(&fo);
  174. iPtSize /= pPDev->ptGrxRes.y;
  175. /* if the trannform is very small (Less than a quarter of point size)
  176. * then make it atleast a quarter point. This was causing AV in certain
  177. * cases.
  178. */
  179. if (iPtSize < 25)
  180. {
  181. iPtSize = 25;
  182. }
  183. iAdjustedPtSize = ((iPtSize + 12) / 25) * 25;
  184. //Adjust the Scale Factor for quarter point adjustment.
  185. FLOATOBJ_MulLong(&ctl.eXScale,iAdjustedPtSize);
  186. FLOATOBJ_DivLong(&ctl.eXScale,iPtSize);
  187. FLOATOBJ_MulLong(&ctl.eYScale,iAdjustedPtSize);
  188. FLOATOBJ_DivLong(&ctl.eYScale,iPtSize);
  189. #endif
  190. }
  191. }
  192. /*
  193. * precompute the lDescender and lAscender
  194. */
  195. lDescender = LMulFloatLong(&ctl.eYScale,pIFI->fwdWinDescender);
  196. lAscender = LMulFloatLong(&ctl.eYScale,pIFI->fwdWinAscender);
  197. switch( iMode )
  198. {
  199. case QFD_GLYPHANDBITMAP: /* Glyph width etc data */
  200. // size is now just the size of the bitmap, which in this
  201. // case doesn't exist.
  202. lRet = 0;
  203. if( pgd )
  204. {
  205. int iWide; /* Glyph's width */
  206. /*
  207. * First get the width of this glyph, as this is needed
  208. * in several places.The width returned by IGetGlyphWidth
  209. * is not scaled in device units. To convert in device units
  210. * multily with the scale factor calculated earlier.
  211. */
  212. iWide = IGetGlyphWidth( pPDev, pFM, hg);
  213. iWide = LMulFloatLong(&ctl.eXScale,iWide);
  214. switch( iRot )
  215. {
  216. case 0:
  217. pgd->rclInk.left = 0;
  218. pgd->rclInk.top = lDescender;
  219. pgd->rclInk.right = iWide;
  220. pgd->rclInk.bottom = -lAscender;
  221. break;
  222. case 1:
  223. pgd->rclInk.left = lDescender;
  224. pgd->rclInk.top = iWide;
  225. pgd->rclInk.right = -lAscender;
  226. pgd->rclInk.bottom = 0;
  227. break;
  228. case 2:
  229. pgd->rclInk.left = -iWide;
  230. pgd->rclInk.top = -lAscender;
  231. pgd->rclInk.right = 0;
  232. pgd->rclInk.bottom = lDescender;
  233. break;
  234. case 3:
  235. pgd->rclInk.left = lAscender;
  236. pgd->rclInk.top = 0;
  237. pgd->rclInk.right = -lDescender;
  238. pgd->rclInk.bottom = -iWide;
  239. break;
  240. }
  241. pgd->fxD = LTOFX( iWide );
  242. pgd->ptqD.x.HighPart = pgd->fxD * ptlXRot[ iRot ].x;
  243. pgd->ptqD.x.LowPart = 0;
  244. pgd->ptqD.y.HighPart = pgd->fxD * ptlXRot[ iRot ].y;
  245. pgd->ptqD.y.LowPart = 0;
  246. pgd->fxA = 0;
  247. pgd->fxAB = pgd->fxD;
  248. pgd->fxInkTop = (FIX)LTOFX( lAscender );
  249. pgd->fxInkBottom = -(FIX)LTOFX( lDescender );
  250. pgd->hg = hg;
  251. pgd->gdf.pgb = NULL;
  252. }
  253. break;
  254. case QFD_MAXEXTENTS: /* Alternative form of the above */
  255. lRet = sizeof( FD_DEVICEMETRICS );
  256. if( pv )
  257. {
  258. LONG lTmp; /* Rotated case */
  259. FD_DEVICEMETRICS *pdm = ((FD_DEVICEMETRICS *)pv);
  260. /*
  261. * Check that the size is reasonable!
  262. */
  263. if( cjSize < sizeof( FD_DEVICEMETRICS ) )
  264. {
  265. SetLastError( ERROR_INSUFFICIENT_BUFFER );
  266. ERR(( "rasdd!DrvQueryFontData: cjSize (%ld) too small\n", cjSize ));
  267. return -1;
  268. }
  269. // BUG 757060 - set this to 0 explicitly, because some drivers
  270. // were using this before it was set, and may have code paths that
  271. // break if this is a reasonable value. Before this fix, the value
  272. // was the 0xCD pattern, and on newer IA64 machines, requests for this
  273. // much memory (>3GB) could be handled, but at the expense of locking up
  274. // the machine for minutes or even hours.
  275. pdm->cjGlyphMax = 0;
  276. /*
  277. * These are accelerator flags - it is not obvious to me
  278. * that any of them are relevant to printer driver fonts.
  279. */
  280. pdm->flRealizedType = 0;
  281. /*
  282. * Following fields set this as a normal type of font.
  283. */
  284. pdm->pteBase = pteRotBase[ iRot ];
  285. pdm->pteSide = pteRotSide[ iRot ];
  286. pdm->cxMax = LMulFloatLong(&ctl.eXScale,pIFI->fwdMaxCharInc);
  287. //
  288. // DBCS fonts are not monospaced, have halfwidth glyphs and
  289. // fullwidth glyphs.
  290. //
  291. if ( pFMDev->W.psWidth ||
  292. IS_DBCSCHARSET(((IFIMETRICS*)pFM->pIFIMet)->jWinCharSet))
  293. {
  294. pdm->lD = 0; /* Proportionally spaced font */
  295. }
  296. else
  297. {
  298. pdm->lD = pdm->cxMax;
  299. }
  300. pdm->fxMaxAscender = (FIX)LTOFX( lAscender );
  301. pdm->fxMaxDescender = (FIX)LTOFX( lDescender );
  302. lTmp = -LMulFloatLong(&ctl.eYScale,pIFI->fwdUnderscorePosition);
  303. pdm->ptlUnderline1.x = lTmp * ptlYRot[ iRot ].x;
  304. pdm->ptlUnderline1.y = lTmp * ptlYRot[ iRot ].y;
  305. lTmp = -LMulFloatLong(&ctl.eYScale,pIFI->fwdStrikeoutPosition);
  306. pdm->ptlStrikeOut.x = lTmp * ptlYRot[ iRot ].x;
  307. pdm->ptlStrikeOut.y = lTmp * ptlYRot[ iRot ].y;
  308. lTmp = LMulFloatLong(&ctl.eYScale,pIFI->fwdUnderscoreSize);
  309. pdm->ptlULThickness.x = lTmp * ptlYRot[ iRot ].x;
  310. pdm->ptlULThickness.y = lTmp * ptlYRot[ iRot ].y;
  311. lTmp = LMulFloatLong(&ctl.eYScale,pIFI->fwdStrikeoutSize);
  312. pdm->ptlSOThickness.x = lTmp * ptlYRot[ iRot ].x;
  313. pdm->ptlSOThickness.y = lTmp * ptlYRot[ iRot ].y;
  314. }
  315. break;
  316. default:
  317. ERR(( "Rasdd!DrvQueryFontData: unprocessed iMode value - %ld",iMode ));
  318. SetLastError( ERROR_INVALID_PARAMETER );
  319. break;
  320. }
  321. return lRet;
  322. }