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.

595 lines
14 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: fdfc.c
  3. *
  4. * functions that deal with font contexts
  5. *
  6. * Created: 08-Nov-1990 12:42:34
  7. * Author: Bodin Dresevic [BodinD]
  8. *
  9. * Copyright (c) 1990 Microsoft Corporation
  10. \**************************************************************************/
  11. #include "fd.h"
  12. #define MAX_HORZ_SCALE 5
  13. #define MAX_VERT_SCALE 255
  14. #ifdef FE_SB // ROTATION: ulGetRotate() function body
  15. /******************************Private*Routine*****************************\
  16. *
  17. * VOID vComputeRotatedXform()
  18. *
  19. * History :
  20. *
  21. * 14-Feb-1993 -By- Hideyuki Nagase [HideyukN]
  22. * Wrote it.
  23. \**************************************************************************/
  24. VOID
  25. vComputeRotatedXform
  26. (
  27. POINTL *pptlScale,
  28. LONG lXscale ,
  29. LONG lYscale
  30. )
  31. {
  32. // If the caling factor is 0 , We have to set it to 1 for avoiding overflow
  33. if( lXscale == 0L )
  34. {
  35. pptlScale->x = 1L;
  36. }
  37. else
  38. {
  39. pptlScale->x = lXscale;
  40. if( pptlScale->x < 0 )
  41. pptlScale->x = -(pptlScale->x);
  42. if( pptlScale->x > MAX_HORZ_SCALE )
  43. pptlScale->x = MAX_HORZ_SCALE;
  44. }
  45. if( lYscale == 0L )
  46. {
  47. pptlScale->y = 1L;
  48. }
  49. else
  50. {
  51. pptlScale->y = lYscale;
  52. if( pptlScale->y < 0 )
  53. pptlScale->y = -(pptlScale->y);
  54. if( pptlScale->y > MAX_VERT_SCALE )
  55. pptlScale->y = MAX_VERT_SCALE;
  56. }
  57. }
  58. /******************************Public*Routine******************************\
  59. * ULONG ulGetRotate()
  60. *
  61. * Effects:
  62. *
  63. * Warnings:
  64. *
  65. * History:
  66. *
  67. * 8-Feb-1993 -by- Hideyuki Nagase [HideyukN]
  68. * Wrote it.
  69. \**************************************************************************/
  70. ULONG ulGetRotate( POINTL *pptlScale , XFORMOBJ *pxo )
  71. {
  72. EFLOAT efXX , efXY , efYX , efYY;
  73. LONG lXX , lXY , lYX , lYY;
  74. XFORML xform;
  75. // Get the transform elements.
  76. XFORMOBJ_iGetXform(pxo,&xform);
  77. // Convert elements of the matrix from IEEE float to our EFLOAT.
  78. vEToEF(xform.eM11 , &efXX );
  79. vEToEF(xform.eM12 , &efXY );
  80. vEToEF(xform.eM21 , &efYX );
  81. vEToEF(xform.eM22 , &efYY );
  82. // Convert these from EFLOAT to LONG
  83. if( !bEFtoL( &efXX , &lXX ) ||
  84. !bEFtoL( &efXY , &lXY ) ||
  85. !bEFtoL( &efYX , &lYX ) ||
  86. !bEFtoL( &efYY , &lYY )
  87. )
  88. {
  89. WARNING("BMFD!bEToEF() fail\n");
  90. vComputeRotatedXform( pptlScale , MAX_HORZ_SCALE , MAX_VERT_SCALE );
  91. return( 0L );
  92. }
  93. // Check transform.
  94. //
  95. // 0 ' 180 '
  96. //
  97. // ( 1 0 )(X) = ( X) ( -1 0 )(X) = (-X) ( XX XY )(X)
  98. // ( 0 1 )(Y) ( Y) ( 0 -1 )(Y) (-Y) ( YX YY )(Y)
  99. //
  100. // 90 ' 270 '
  101. //
  102. // ( 0 -1 )(X) = (-Y) ( 0 1 )(X) = ( Y)
  103. // ( 1 0 )(Y) ( X) ( -1 0 )(Y) (-X)
  104. //
  105. #ifdef FIREWALLS_MORE
  106. DbgPrint(" XX = %ld , XY = %ld\n" , lXX , lXY );
  107. DbgPrint(" YX = %ld , YY = %ld\n" , lYX , lYY );
  108. #endif // FIREWALLS_MORE
  109. if ( ( lXX > 0 && lXY == 0 ) &&
  110. ( lYX == 0 && lYY > 0 ) )
  111. {
  112. // We have to Rotate bitmap image to 0 degree
  113. // Compute X Y scaling factor
  114. vComputeRotatedXform( pptlScale , lXX , lYY );
  115. return( 0L );
  116. }
  117. else if ( ( lXX == 0 && lXY < 0 ) &&
  118. ( lYX > 0 && lYY == 0 ) )
  119. {
  120. vComputeRotatedXform( pptlScale , lXY , lYX );
  121. return( 900L );
  122. }
  123. else if ( ( lXX < 0 && lXY == 0 ) &&
  124. ( lYX == 0 && lYY < 0 ) )
  125. {
  126. vComputeRotatedXform( pptlScale , lXX , lYY );
  127. return( 1800L );
  128. }
  129. else if ( ( lXX == 0 && lXY > 0 ) &&
  130. ( lYX < 0 && lYY == 0 ) )
  131. {
  132. vComputeRotatedXform( pptlScale , lXY , lYX );
  133. return( 2700L );
  134. }
  135. //
  136. // we are here because:
  137. // 1) we are asked to handle arbitrary rotation. ( this should not happen )
  138. // 2) lXX == lXY == lYX == lYY == 0
  139. //
  140. // we choose default transformation
  141. //
  142. vComputeRotatedXform( pptlScale , 1L , 1L );
  143. #ifdef FIREWALLS_MORE
  144. WARNING("Bmfd:ulGetRatate():Use default transform ( ulRotate = 0 )\n");
  145. #endif // FIREWALLS_MORE
  146. return( 0L );
  147. }
  148. #endif // FE_SB
  149. #ifndef FE_SB // We use vComputeRotatedXform() instead of vInitXform()
  150. /******************************Private*Routine*****************************\
  151. * VOID vInitXform
  152. *
  153. * Initialize the coefficients of the transforms for the given font context.
  154. * It also transforms and saves various measurements of the font in the
  155. * context.
  156. *
  157. * Mon 01-Feb-1993 -by- Bodin Dresevic [BodinD]
  158. * update: changed it to return data into pptlScale
  159. *
  160. \**************************************************************************/
  161. VOID vInitXform(POINTL * pptlScale , XFORMOBJ *pxo)
  162. {
  163. EFLOAT efloat;
  164. XFORM xfm;
  165. // Get the transform elements.
  166. XFORMOBJ_iGetXform(pxo, &xfm);
  167. // Convert elements of the matrix from IEEE float to our EFLOAT.
  168. vEToEF(xfm.eM11, &efloat);
  169. // If we overflow set to the maximum scaling factor
  170. if( !bEFtoL( &efloat, &pptlScale->x ) )
  171. pptlScale->x = MAX_HORZ_SCALE;
  172. else
  173. {
  174. // Ignore the sign of the scale
  175. if( pptlScale->x == 0 )
  176. {
  177. pptlScale->x = 1;
  178. }
  179. else
  180. {
  181. if( pptlScale->x < 0 )
  182. pptlScale->x = -pptlScale->x;
  183. if( pptlScale->x > MAX_HORZ_SCALE )
  184. pptlScale->x = MAX_HORZ_SCALE;
  185. }
  186. }
  187. vEToEF(xfm.eM22, &efloat);
  188. if( !bEFtoL( &efloat, &pptlScale->y ) )
  189. pptlScale->y = MAX_VERT_SCALE;
  190. else
  191. {
  192. // Ignore the sign of the scale
  193. if( pptlScale->y == 0 )
  194. {
  195. pptlScale->y = 1;
  196. }
  197. else
  198. {
  199. if( pptlScale->y < 0 )
  200. pptlScale->y = -pptlScale->y;
  201. if( pptlScale->y > MAX_VERT_SCALE )
  202. pptlScale->y = MAX_VERT_SCALE;
  203. }
  204. }
  205. }
  206. #endif
  207. /******************************Public*Routine******************************\
  208. * BmfdOpenFontContext
  209. *
  210. * History:
  211. * 19-Nov-1990 -by- Bodin Dresevic [BodinD]
  212. * Wrote it.
  213. \**************************************************************************/
  214. HFC
  215. BmfdOpenFontContext (
  216. FONTOBJ *pfo
  217. )
  218. {
  219. PFONTFILE pff;
  220. FACEINFO *pfai;
  221. FONTCONTEXT *pfc = (FONTCONTEXT *)NULL;
  222. PCVTFILEHDR pcvtfh;
  223. ULONG cxMax;
  224. ULONG cjGlyphMax;
  225. POINTL ptlScale;
  226. PVOID pvView;
  227. COUNT cjView;
  228. ULONG cjfc = offsetof(FONTCONTEXT,ajStretchBuffer);
  229. FLONG flStretch;
  230. #ifdef FE_SB
  231. ULONG cxMaxNoRotate;
  232. ULONG cjGlyphMaxNoRotate;
  233. ULONG cyMax;
  234. ULONG ulRotate;
  235. #endif // FE_SB
  236. #ifdef DUMPCALL
  237. DbgPrint("\nBmfdOpenFontContext(");
  238. DbgPrint("\n FONTOBJ *pfo = %-#8lx", pfo);
  239. DbgPrint("\n )\n");
  240. #endif
  241. if ( ((HFF) pfo->iFile) == HFF_INVALID)
  242. return(HFC_INVALID);
  243. pff = PFF((HFF) pfo->iFile);
  244. if ((pfo->iFace < 1L) || (pfo->iFace > pff->cFntRes)) // pfo->iFace values are 1 based
  245. return(HFC_INVALID);
  246. pfai = &pff->afai[pfo->iFace - 1];
  247. pcvtfh = &(pfai->cvtfh);
  248. if ((pfo->flFontType & FO_SIM_BOLD) && (pfai->pifi->fsSelection & FM_SEL_BOLD))
  249. return HFC_INVALID;
  250. if ((pfo->flFontType & FO_SIM_ITALIC) && (pfai->pifi->fsSelection & FM_SEL_ITALIC))
  251. return HFC_INVALID;
  252. #ifdef FE_SB // BmfdOpenFontContext():Get Rotate and compute XY scaling
  253. // get rotation ( 0 , 900 , 1800 or 2700 )
  254. // And we compute horizontal and vertical scaling factors
  255. ulRotate = ulGetRotate( &ptlScale , FONTOBJ_pxoGetXform(pfo));
  256. #else // We compute horizontal and vertical scaling facter in above function.
  257. // compute the horizontal and vertical scaling factors
  258. vInitXform(&ptlScale, FONTOBJ_pxoGetXform(pfo));
  259. #endif
  260. #ifdef FE_SB // BmfdOpenFontConText(): Compute cjGlyphMax
  261. // Compute cjGlyphMax of Rotated font
  262. cjGlyphMaxNoRotate =
  263. cjGlyphDataSimulated(
  264. pfo,
  265. (ULONG)pcvtfh->usMaxWidth * ptlScale.x,
  266. (ULONG)pcvtfh->cy * ptlScale.y,
  267. &cxMaxNoRotate,
  268. 0L);
  269. // In Y axis, We do not have to consider font simulation.
  270. cyMax = (ULONG)pcvtfh->cy * ptlScale.y;
  271. if( ( ulRotate == 0L ) || ( ulRotate == 1800L ) )
  272. {
  273. // In the case of 0 or 180 degree.
  274. cjGlyphMax = cjGlyphMaxNoRotate;
  275. cxMax = cxMaxNoRotate;
  276. }
  277. else
  278. {
  279. // In the case of 90 or 270 degree.
  280. // Compute simulated and rotated cjGlyphMax.
  281. cjGlyphMax =
  282. cjGlyphDataSimulated(
  283. pfo,
  284. (ULONG)pcvtfh->usMaxWidth * ptlScale.x,
  285. (ULONG)pcvtfh->cy * ptlScale.y,
  286. NULL,
  287. ulRotate);
  288. cxMax = cyMax;
  289. }
  290. #ifdef DBG_MORE
  291. DbgPrint("clGlyphMax - 0x%x\n",cjGlyphMax);
  292. #endif
  293. #else
  294. cjGlyphMax =
  295. cjGlyphDataSimulated(
  296. pfo,
  297. (ULONG)pcvtfh->usMaxWidth * ptlScale.x,
  298. (ULONG)pcvtfh->cy * ptlScale.y,
  299. &cxMax);
  300. #endif
  301. // init stretch flags
  302. flStretch = 0;
  303. if ((ptlScale.x != 1) || (ptlScale.y != 1))
  304. {
  305. #ifdef FE_SB // BmfdOpenFontContext() Adjust stretch buffer
  306. ULONG cjScan = CJ_SCAN(cxMaxNoRotate);
  307. #else
  308. ULONG cjScan = CJ_SCAN(cxMax); // cj of the stretch buffer
  309. #endif
  310. flStretch |= FC_DO_STRETCH;
  311. if (cjScan > CJ_STRETCH) // will use the one at the bottom of FC
  312. {
  313. cjfc += cjScan;
  314. flStretch |= FC_STRETCH_WIDE;
  315. }
  316. }
  317. // allocate memory for the font context and get the pointer to font context
  318. // NOTE THAT WE ARE NOT TOUCHING THE MEMORY MAPPED FILE AFTER WE ALLOCATE MEMORY
  319. // IN THIS ROUTINE. GOOD CONSEQUENCE OF THIS IS THAT NO SPECIAL CLEAN UP
  320. // CODE IS NECESSARY TO FREE THAT MEMORY, IT WILL GET CLEANED WHEN
  321. // CloseFontContext is called [bodind]
  322. if (!(pfc = PFC(hfcAlloc(cjfc))))
  323. {
  324. SAVE_ERROR_CODE(ERROR_NOT_ENOUGH_MEMORY);
  325. return(HFC_INVALID);
  326. }
  327. pfc->ident = ID_FONTCONTEXT;
  328. // state that the hff passed to this function is the FF selected in
  329. // this font context
  330. pfc->hff = (HFF) pfo->iFile;
  331. pfc->pfai = pfai;
  332. pfc->flFontType = pfo->flFontType;
  333. pfc->ptlScale = ptlScale;
  334. pfc->flStretch = flStretch;
  335. pfc->cxMax = cxMax;
  336. pfc->cjGlyphMax = cjGlyphMax;
  337. #ifdef FE_SB // BmfdOpenFontContext() keep rotation degree in FONTCONTEXT
  338. pfc->ulRotate = ulRotate;
  339. #endif // FE_SB
  340. // increase the reference count of the font file
  341. // ONLY AFTER WE ARE SURE THAT WE CAN NOT FAIL ANY MORE
  342. // make sure that another thread is not doing it at the same time
  343. // opening another context off of the same fontfile pff
  344. EngAcquireSemaphore(ghsemBMFD);
  345. // if this is the first font context corresponding to this font file
  346. // and then we have to remap file to memory and make sure the pointers
  347. // to FNT resources are updated accordingly
  348. if (pff->cRef == 0)
  349. {
  350. INT i;
  351. if (!EngMapFontFileFD(pff->iFile, (PULONG *) &pvView, &cjView))
  352. {
  353. WARNING("BMFD!somebody removed that bm font file!!!\n");
  354. EngReleaseSemaphore(ghsemBMFD);
  355. VFREEMEM(pfc);
  356. return HFC_INVALID;
  357. }
  358. for (i = 0; i < (INT)pff->cFntRes; i++)
  359. {
  360. pff->afai[i].re.pvResData = (PVOID) (
  361. (BYTE*)pvView + pff->afai[i].re.dpResData
  362. );
  363. }
  364. }
  365. // now can not fail, update cRef
  366. (pff->cRef)++;
  367. EngReleaseSemaphore(ghsemBMFD);
  368. return((HFC)pfc);
  369. }
  370. /******************************Public*Routine******************************\
  371. * BmfdDestroyFont
  372. *
  373. * Driver can release all resources associated with this font realization
  374. * (embodied in the FONTOBJ).
  375. *
  376. * History:
  377. * 30-Aug-1992 -by- Gilman Wong [gilmanw]
  378. * Wrote it.
  379. \**************************************************************************/
  380. VOID
  381. BmfdDestroyFont (
  382. FONTOBJ *pfo
  383. )
  384. {
  385. //
  386. // For the bitmap font driver, this is simply closing the font context.
  387. // We cleverly store the font context handle in the FONTOBJ pvProducer
  388. // field.
  389. //
  390. // This pvProducer could be null if exception occured while
  391. // trying to create fc
  392. if (pfo->pvProducer)
  393. {
  394. BmfdCloseFontContext((HFC) pfo->pvProducer);
  395. pfo->pvProducer = NULL;
  396. }
  397. }
  398. /******************************Public*Routine******************************\
  399. * BmfdCloseFontContext
  400. *
  401. * History:
  402. * 19-Nov-1990 -by- Bodin Dresevic [BodinD]
  403. * Wrote it.
  404. \**************************************************************************/
  405. BOOL
  406. BmfdCloseFontContext (
  407. HFC hfc
  408. )
  409. {
  410. PFONTFILE pff;
  411. BOOL bRet;
  412. if (hfc != HFC_INVALID)
  413. {
  414. //
  415. // get the handle of the font file that is selected into this FONTCONTEXT
  416. // get the pointer to the FONTFILE
  417. //
  418. pff = PFF(PFC(hfc)->hff);
  419. // decrement the reference count for the corresponding FONTFILE
  420. // make sure that another thread is not doing it at the same time
  421. // closing another context off of the same fontfile pff
  422. EngAcquireSemaphore(ghsemBMFD);
  423. if (pff->cRef > 0L)
  424. {
  425. (pff->cRef)--;
  426. //
  427. // if this file is temporarily going out of use, unmap it
  428. //
  429. if (pff->cRef == 0)
  430. {
  431. if (!(pff->fl & FF_EXCEPTION_IN_PAGE_ERROR))
  432. {
  433. // if FF_EXCEPTION_IN_PAGE_ERROR is set
  434. // the file should have been unmapped
  435. // in vBmfdMarkFontGone function
  436. EngUnmapFontFileFD(pff->iFile);
  437. }
  438. pff->fl &= ~FF_EXCEPTION_IN_PAGE_ERROR;
  439. }
  440. // free the memory associated with hfc
  441. VFREEMEM(hfc);
  442. bRet = TRUE;
  443. }
  444. else
  445. {
  446. WARNING("BmfdCloseFontContext: cRef <= 0\n");
  447. bRet = FALSE;
  448. }
  449. EngReleaseSemaphore(ghsemBMFD);
  450. }
  451. else
  452. {
  453. bRet = FALSE;
  454. }
  455. return bRet;
  456. }