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.

398 lines
11 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: fdfc.c
  3. *
  4. * Various font context functions. Adapted from BodinD's bitmap font driver.
  5. *
  6. * Copyright (c) 1990-1995 Microsoft Corporation
  7. \**************************************************************************/
  8. #include "fd.h"
  9. #define MIN(A,B) ((A) < (B) ? (A) : (B))
  10. #define MAX(A,B) ((A) > (B) ? (A) : (B))
  11. #if defined(_AMD64_) || defined(_IA64_)
  12. #define MUL16(ef) {ef *= 16; }
  13. #define lCvt(ef, l) ((LONG) (ef * l))
  14. #else
  15. #define MUL16(ef) {if (ef.lMant != 0) ef.lExp += 4; }
  16. LONG lCvt(EFLOAT ef,LONG l);
  17. #endif
  18. /******************************Private*Routine*****************************\
  19. * BOOL bInitXform
  20. *
  21. * Initialize the coefficients of the transforms for the given font context.
  22. * It also transforms and saves various measurements of the font in the
  23. * context.
  24. *
  25. * History:
  26. * 25-Feb-1992 -by- Wendy Wu [wendywu]
  27. * Wrote it.
  28. \**************************************************************************/
  29. BOOL bInitXform(PFONTCONTEXT pfc, XFORMOBJ *pxo)
  30. {
  31. // !!! bFloatToFix should be replaced with a compare and a type cast.
  32. // Dont update the coefficeints in the font context yet since overflows
  33. // might occur.
  34. VECTORFL vtflTmp;
  35. POINTL ptl;
  36. XFORML xfm;
  37. // Get the transform elements.
  38. XFORMOBJ_iGetXform(pxo,&xfm);
  39. // Convert elements of the matrix from IEEE float to our EFLOAT.
  40. vEToEF(xfm.eM11, &pfc->efM11);
  41. vEToEF(xfm.eM12, &pfc->efM12);
  42. vEToEF(xfm.eM21, &pfc->efM21);
  43. vEToEF(xfm.eM22, &pfc->efM22);
  44. // The path we are to construct takes 1/16 pixel per unit. So lets
  45. // multiply this factor in the transform.
  46. MUL16(pfc->efM11)
  47. MUL16(pfc->efM12)
  48. MUL16(pfc->efM21)
  49. MUL16(pfc->efM22)
  50. //
  51. // These are the special cases for which we need to clip bottom and right
  52. // edges. Below is the lower case letter e all posible 90 rotations and
  53. // flips.
  54. //
  55. //
  56. // *** *** ** ***** *** *** ***** **
  57. // * * * * * * * * * * * * * * * * * *
  58. // ***** ***** * * * * * * ***** ***** * * * * * *
  59. // * * * * * * * * * * * * * * * * * *
  60. // *** *** ***** ** *** *** ** *****
  61. //
  62. // case 1 case 2 case 6 case 5 case 3 case 4 case 7 case 8
  63. //
  64. //
  65. if (bIsZero(pfc->efM12) && bIsZero(pfc->efM21))
  66. {
  67. pfc->flags |= FC_SCALE_ONLY;
  68. if (!bPositive(pfc->efM11))
  69. pfc->flags |= FC_X_INVERT;
  70. if( bPositive(pfc->efM11 ) )
  71. {
  72. pfc->flags |= (bPositive(pfc->efM22)) ? FC_ORIENT_1 : FC_ORIENT_2;
  73. }
  74. else
  75. {
  76. pfc->flags |= (bPositive(pfc->efM22)) ? FC_ORIENT_4 : FC_ORIENT_3;
  77. }
  78. }
  79. if( bIsZero(pfc->efM22) && bIsZero(pfc->efM11) )
  80. {
  81. if( bPositive(pfc->efM21 ) )
  82. {
  83. pfc->flags |= (bPositive(pfc->efM12)) ? FC_ORIENT_5 : FC_ORIENT_6;
  84. }
  85. else
  86. {
  87. pfc->flags |= (bPositive(pfc->efM12)) ? FC_ORIENT_7 : FC_ORIENT_8;
  88. }
  89. }
  90. // Transform the base and the side vectors. Should never overflow.
  91. ptl.x = 1;
  92. ptl.y = 0;
  93. bXformUnitVector(&ptl,
  94. &xfm,
  95. &pfc->vtflBase,
  96. &pfc->pteUnitBase,
  97. (pfc->flags & FC_SIM_EMBOLDEN) ? &pfc->ptqUnitBase : NULL,
  98. &pfc->efBase);
  99. pfc->fxEmbolden = 0;
  100. if (pfc->flags & FC_SIM_EMBOLDEN)
  101. {
  102. // emboldening shift for vector fonts in not always one with vector fonts
  103. // It is computed as 1 * efBase. This is win31 compatible way of doing this
  104. pfc->fxEmbolden = ((lCvt(pfc->efBase, 1) + 8) & 0xfffffff0);
  105. if (pfc->fxEmbolden < 24)
  106. {
  107. // primitive "hinting", do not let it become zero
  108. pfc->fxEmbolden = 16;
  109. pfc->pfxBaseOffset.x = FXTOL(pfc->ptqUnitBase.x.HighPart + 8);
  110. pfc->pfxBaseOffset.y = FXTOL(pfc->ptqUnitBase.y.HighPart + 8);
  111. // resolve mult of 45 degrees situations:
  112. if ((pfc->pfxBaseOffset.x == pfc->pfxBaseOffset.y) ||
  113. (pfc->pfxBaseOffset.x == -pfc->pfxBaseOffset.y) )
  114. {
  115. pfc->pfxBaseOffset.y = 0;
  116. }
  117. pfc->pfxBaseOffset.x = LTOFX(pfc->pfxBaseOffset.x);
  118. pfc->pfxBaseOffset.y = LTOFX(pfc->pfxBaseOffset.y);
  119. ASSERTDD(pfc->pfxBaseOffset.x || pfc->pfxBaseOffset.y, "x zero and y zero\n");
  120. ASSERTDD((pfc->pfxBaseOffset.x && pfc->pfxBaseOffset.y) == 0, "x * y not zero\n");
  121. }
  122. else
  123. {
  124. pfc->pfxBaseOffset.x = lCvt(pfc->vtflBase.x, 1);
  125. pfc->pfxBaseOffset.y = lCvt(pfc->vtflBase.y, 1);
  126. }
  127. }
  128. // Transform the side vector.
  129. ptl.x = 0;
  130. ptl.y = -1;
  131. bXformUnitVector(&ptl, &xfm, &vtflTmp,
  132. &pfc->pteUnitSide, NULL, &pfc->efSide);
  133. pfc->fxInkTop = fxLTimesEf(&pfc->efSide, pfc->pifi->fwdWinAscender);
  134. pfc->fxInkBottom = -fxLTimesEf(&pfc->efSide, pfc->pifi->fwdWinDescender);
  135. pfc->fxItalic = 0;
  136. if (pfc->flags & FC_SIM_ITALICIZE)
  137. {
  138. pfc->fxItalic
  139. = (fxLTimesEf(
  140. &pfc->efBase,
  141. (pfc->pifi->fwdWinAscender + pfc->pifi->fwdWinDescender + 1)/2
  142. ) + 8) & 0xfffffff0 ;
  143. }
  144. return(TRUE);
  145. }
  146. /******************************Public*Routine******************************\
  147. * HFC vtfdOpenFontContext
  148. *
  149. * Open a font context. Store font transform and other requests for
  150. * the realization of this font.
  151. *
  152. * History:
  153. * 27-Feb-1992 -by- Wendy Wu [wendywu]
  154. * Adapted from bmfd.
  155. \**************************************************************************/
  156. HFC vtfdOpenFontContext(FONTOBJ *pfo)
  157. {
  158. PFONTFILE pff = (PFONTFILE)pfo->iFile;
  159. PFONTCONTEXT pfc;
  160. BYTE *pjView;
  161. DWORD dwFirstCharOffset;
  162. #ifdef DEBUGSIM
  163. DbgPrint("vtfdOpenFontContext, ulFont = %ld\n", ulFont);
  164. #endif // DEBUGSIM
  165. if (pff == (PFONTFILE) NULL)
  166. return(HFC_INVALID);
  167. // iFace is 1 based:
  168. if ((pfo->iFace < 1L) || (pfo->iFace > pff->cFace)) // pfo->iFace values are 1 based
  169. return(HFC_INVALID);
  170. // increase the reference count of the font file, WE DO THIS ONLY WHEN
  171. // WE ARE SURE that can not fail any more
  172. // need to grab a sem for we will be looking into cRef now.
  173. if (pff->cRef == 0)
  174. {
  175. // need to remap the file into the memory again and update pointers:
  176. UINT i;
  177. if (!EngMapFontFileFD(pff->iFile,(PULONG*)&pff->pvView, &pff->cjView))
  178. {
  179. WARNING("somebody removed the file\n");
  180. return (HFC_INVALID);
  181. }
  182. for (i = 0; i < pff->cFace; i++)
  183. {
  184. pff->afd[i].re.pvResData = (PVOID) (
  185. (BYTE*)pff->pvView + pff->afd[i].re.dpResData
  186. );
  187. }
  188. }
  189. // remember this so that we do not have to read from the file
  190. // after we allocate the memory for the font context. This simplifies
  191. // clean up code in case of exception, i.e. disappearing font files.
  192. pjView = pff->afd[pfo->iFace-1].re.pvResData;
  193. dwFirstCharOffset = READ_DWORD(pjView + OFF_BitsOffset);
  194. // Allocate memory for the font context.
  195. if ((pfc = pfcAlloc()) == (PFONTCONTEXT)NULL)
  196. {
  197. if (pff->cRef == 0)
  198. {
  199. EngUnmapFontFileFD(pff->iFile);
  200. }
  201. return(HFC_INVALID);
  202. }
  203. // we MUST NOT not touch the memory mapped file past this point
  204. // until the end of the routine. This is important for the
  205. // proper clean up code in case of exception. [bodind]
  206. pfc->pre = &pff->afd[pfo->iFace-1].re;
  207. pfc->pifi = pff->afd[pfo->iFace-1].pifi;
  208. // SET wendywu style flags
  209. pfc->flags = 0;
  210. if (pfo->flFontType & FO_SIM_BOLD)
  211. pfc->flags |= FC_SIM_EMBOLDEN;
  212. if (pfo->flFontType & FO_SIM_ITALIC)
  213. pfc->flags |= FC_SIM_ITALICIZE;
  214. pfc->dpFirstChar = dwFirstCharOffset;
  215. // !!! Vector font file doesn't have the byte filler. Win31 bug?
  216. //pfc->ajCharTable = pjView + OFF_jUnused20;
  217. // Store the transform matrix.
  218. if ( !bInitXform(pfc, FONTOBJ_pxoGetXform(pfo)) )
  219. {
  220. WARNING("vtfdOpenFontContext transform out of range\n");
  221. if (pff->cRef == 0)
  222. {
  223. EngUnmapFontFileFD(pff->iFile);
  224. }
  225. vFree(pfc);
  226. return(HFC_INVALID);
  227. }
  228. // State that the hff passed to this function is the FF selected in
  229. // this font context.
  230. pfc->pff = pff;
  231. (pff->cRef)++;
  232. return((HFC)pfc);
  233. }
  234. /******************************Public*Routine******************************\
  235. * vtfdDestroyFont
  236. *
  237. * Driver can release all resources associated with this font realization
  238. * (embodied in the FONTOBJ).
  239. *
  240. * History:
  241. * 02-Sep-1992 -by- Gilman Wong [gilmanw]
  242. * Wrote it.
  243. \**************************************************************************/
  244. VOID
  245. vtfdDestroyFont (
  246. FONTOBJ *pfo
  247. )
  248. {
  249. //
  250. // For the vector font driver, this is simply closing the font context.
  251. // We cleverly store the font context handle in the FONTOBJ pvProducer
  252. // field.
  253. //
  254. EngAcquireSemaphore(ghsemVTFD);
  255. vtfdCloseFontContext((HFC) pfo->pvProducer);
  256. EngReleaseSemaphore(ghsemVTFD);
  257. }
  258. /******************************Public*Routine******************************\
  259. * BOOL vtfdCloseFontContext
  260. *
  261. * Close the font context and update the context link for the associated
  262. * font file.
  263. *
  264. * History:
  265. * 27-Feb-1992 -by- Wendy Wu [wendywu]
  266. * Adapted from bmfd.
  267. \**************************************************************************/
  268. BOOL vtfdCloseFontContext(HFC hfc)
  269. {
  270. BOOL bRet;
  271. if (hfc != HFC_INVALID)
  272. {
  273. //
  274. // decrement the reference count for the corresponding FONTFILE
  275. //
  276. if (PFC(hfc)->pff->cRef > 0L)
  277. {
  278. (PFC(hfc)->pff->cRef)--;
  279. //
  280. // if this file is going out of use we can close it to save memory
  281. //
  282. if (PFC(hfc)->pff->cRef == 0L)
  283. {
  284. // if FF_EXCEPTION_IN_PAGE_ERROR is set
  285. // and the font type is TYPE_FNT or TYPE_DLL16
  286. // the font file must have been unmapped in vVtfdMarkFontGone
  287. if (!(PFC(hfc)->pff->fl & FF_EXCEPTION_IN_PAGE_ERROR) ||
  288. !((PFC(hfc)->pff->iType == TYPE_FNT) || (PFC(hfc)->pff->iType == TYPE_DLL16)))
  289. {
  290. EngUnmapFontFileFD(PFC(hfc)->pff->iFile);
  291. }
  292. PFC(hfc)->pff->fl &= ~FF_EXCEPTION_IN_PAGE_ERROR;
  293. }
  294. //
  295. // free the memory associated with hfc
  296. //
  297. vFree(PFC(hfc));
  298. bRet = TRUE;
  299. }
  300. else
  301. {
  302. WARNING("vtfdCloseFontContext: cRef <= 0\n");
  303. bRet = FALSE;
  304. }
  305. }
  306. else
  307. {
  308. bRet = FALSE;
  309. }
  310. return bRet;
  311. }