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.

448 lines
11 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. qfontree.c
  5. Abstract:
  6. Routines Generates the trees required by the engine. There are three
  7. tree types defined, UNICODE (handle <-> glyph), ligatures and kerning
  8. pairs.
  9. Environment:
  10. Windows NT Unidrv driver
  11. Revision History:
  12. 12/30/96 -ganeshp-
  13. Created
  14. --*/
  15. #include "font.h"
  16. //
  17. //
  18. // Functions
  19. //
  20. //
  21. PVOID
  22. FMQueryFontTree(
  23. PDEV *pPDev,
  24. ULONG_PTR iFile,
  25. ULONG iFace,
  26. ULONG iMode,
  27. ULONG_PTR *pid
  28. )
  29. /*++
  30. Routine Description:
  31. Returns tree structured data describing the mapping between UNICODE
  32. and printer glyphs, or ligature information or kerning pair data.
  33. Arguments:
  34. pPDev Pointer to PDEV
  35. iFile Not Used.
  36. iFace Font about which information is desired
  37. iMode Type of information requested
  38. pid Our field: fill as needed for recognition
  39. Return Value:
  40. A pointer to the relevant structure.
  41. Note:
  42. 12-30-96: Created it -ganeshp-
  43. --*/
  44. {
  45. /*
  46. * Processing differs dramatically, depending upon iMode. We will
  47. * always handle the QFT_GLYPHSET case, the others we may not have
  48. * any information about.
  49. */
  50. void *pvRet; /* Return value */
  51. UNREFERENCED_PARAMETER(iFile);
  52. if( PFDV->dwSignature != FONTPDEV_ID )
  53. {
  54. ERR(( "UniFont!FMQueryFontTree: Invalid FONTPDEV\n" ));
  55. SetLastError( ERROR_INVALID_PARAMETER );
  56. return NULL;
  57. }
  58. if( iFace < 1 || (int)iFace > pPDev->iFonts )
  59. {
  60. ERR(( "UniFont!FMQueryFontTree: Illegal value for iFace (%ld)", iFace ));
  61. SetLastError( ERROR_INVALID_PARAMETER );
  62. return NULL;
  63. }
  64. pvRet = NULL; /* Default return value: error */
  65. /*
  66. * The pid field is one which allows us to put identification data in
  67. * the font information, and which we can use later in DrvFree().
  68. */
  69. *pid = 0;
  70. switch( iMode )
  71. {
  72. case QFT_GLYPHSET: /* RLE style UNICODE -> glyph handle mapping */
  73. pvRet = PVGetUCGlyphSetData( pPDev, iFace );
  74. break;
  75. case QFT_LIGATURES: /* Ligature variant information */
  76. SetLastError( ERROR_NO_DATA );
  77. break;
  78. case QFT_KERNPAIRS: /* Kerning information */
  79. pvRet = PVGetUCKernPairData( pPDev, iFace );
  80. break;
  81. default:
  82. ERR(( "Rasdd!DrvQueryFontTree: iMode = %ld - illegal value\n", iMode ));
  83. SetLastError( ERROR_INVALID_PARAMETER );
  84. break;
  85. }
  86. return pvRet;
  87. }
  88. VOID *
  89. PVGetUCGlyphSetData(
  90. PDEV *pPDev,
  91. UINT iFace
  92. )
  93. /*++
  94. Routine Description:
  95. Generates the array of WCRUN data used as a mapping between UNICODE and
  96. our internal representation.
  97. Arguments:
  98. pPDev Pointer to PDEV
  99. iFace Font about which information is desired
  100. Return Value:
  101. A pointer to the array of WCRUN structure.
  102. Note:
  103. 12-30-96: Created it -ganeshp-
  104. --*/
  105. {
  106. FONTMAP *pFM; /* Details of the particular font */
  107. FONTMAP_DEV *pFMDev;
  108. VOID *pvData = NULL;
  109. if (pFM = PfmGetDevicePFM( pPDev, iFace ) )
  110. {
  111. pFMDev = pFM->pSubFM;
  112. if (!pFMDev->pUCTree) //No FD_GLYPHSET data for this font.
  113. {
  114. if( pFM->flFlags & FM_GLYVER40 ) //NT 4.0 RLE
  115. pvData = PVGetUCRLE(pPDev, pFM);
  116. else // New stuff
  117. pvData = PVGetUCFD_GLYPHSET(pPDev, pFM);
  118. }
  119. else
  120. pvData = pFMDev->pUCTree;
  121. }
  122. // VDBGDUMPUCGLYPHDATA(pFM);
  123. return pvData;
  124. }
  125. VOID *
  126. PVGetUCKernPairData(
  127. PDEV *pPDev,
  128. UINT iFace
  129. )
  130. /*++
  131. Routine Description:
  132. Generates the array of FD_KERNPAIR data for the given font.
  133. Arguments:
  134. pPDev Pointer to PDEV
  135. iFace Font about which information is desired
  136. Return Value:
  137. A pointer to the array of WCRUN structure.
  138. Note:
  139. 12-30-96: Created it -ganeshp-
  140. --*/
  141. {
  142. FONTMAP *pFM; /* Details of the particular font */
  143. FONTMAP_DEV *pFMDev;
  144. VOID *pvData = NULL;
  145. if (pFM = PfmGetDevicePFM( pPDev, iFace ) )
  146. {
  147. pFMDev = pFM->pSubFM;
  148. if (!pFMDev->pUCKernTree) //No FD_GLYPHSET data for this font.
  149. {
  150. /* pvUCKernPair should allocate the appropriate buffer, if
  151. * necessary and store the value in FONTMAP, pFM->pUCKernTree.
  152. */
  153. if( pFM->flFlags & FM_GLYVER40 ) //NT 4.0 RLE
  154. {
  155. SetLastError( ERROR_NO_DATA );
  156. }
  157. else
  158. pvData = PVUCKernPair(pPDev, pFM);
  159. }
  160. else
  161. pvData = pFMDev->pUCKernTree;
  162. }
  163. return pvData;
  164. }
  165. VOID *
  166. PVGetUCRLE(
  167. PDEV *pPDev,
  168. FONTMAP *pFM
  169. )
  170. /*++
  171. Routine Description:
  172. Generates the array of WCRUN data used as a mapping between
  173. UNICODE and our internal representation. The format of this
  174. data is explained in the DDI, but basically for each group of
  175. glyphs we support, we provide starting glyph and count info.
  176. There is an overall structure to define the number and location
  177. of each of the run data.
  178. Arguments:
  179. pPDev Pointer to PDEV.
  180. pFM FONTMAP struct of the Font about for which information is
  181. desired.
  182. Return Value:
  183. A pointer to the array of WCRUN structure.
  184. Note:
  185. 12-30-96: Created it -ganeshp-
  186. --*/
  187. {
  188. /*
  189. * Basically all we need do is allocate storage for the FD_GLYPHSET
  190. * structure we will return. Then the WCRUN entries in this need
  191. * to have the offsets (contained in the resource format data) changed
  192. * to addresses, and we are done. One minor point is to amend the
  193. * WCRUN data to only point to glyphs actually available with this
  194. * font. This means limiting the lower and upper bounds as
  195. * determined by the IFIMETRICS.
  196. */
  197. INT cbReq; /* Bytes to allocate for tables */
  198. INT cRuns; /* Number of runs we discover */
  199. INT iI; /* Loop index */
  200. INT iStart, iStop; /* First and last WCRUNs to use */
  201. INT iDiff; /* For range limiting operations */
  202. FD_GLYPHSET *pGLSet; /* Base of returned data */
  203. IFIMETRICS *pIFI; /* For convenience */
  204. NT_RLE *pntrle; /* RLE style data already available */
  205. WCRUN *pwcr;
  206. FONTMAP_DEV *pFMDev;
  207. #if DBG
  208. PWSTR pwszFaceName;
  209. #endif
  210. pIFI = pFM->pIFIMet;
  211. pFMDev = pFM->pSubFM;
  212. #if DBG
  213. pwszFaceName = (PWSTR)(((BYTE*) pIFI) + pIFI->dpwszFaceName );
  214. #endif
  215. TRACE(\nUniFont!PVGetUCRLE:START);
  216. PRINTVAL(pwszFaceName, %ws);
  217. PRINTVAL((pFM->flFlags & FM_GLYVER40), 0X%x);
  218. /*
  219. * Start working on memory requirements. First generate the bit
  220. * array of available glyphs. In the process, count the number
  221. * of glyphs too! This tells us how much storage will be needed
  222. * just for the glyph handles.
  223. */
  224. cRuns = 0; /* Count number of runs */
  225. pntrle = pFMDev->pvNTGlyph; /* Translation table */
  226. if( !pntrle )
  227. {
  228. ERR(( "!!!UniFont!PVGetUCRLE:( NULL Glyph Translation Data, pwszFaceName = %s )\n",pwszFaceName ));
  229. TRACE(UniFont!PVGetUCRLE:END\n);
  230. return NULL; /* Should not happen */
  231. }
  232. /*
  233. * The hard part is deciding whether to trim the number of glyph
  234. * handles returned due to limitiations of the font metrics.
  235. */
  236. cRuns = pntrle->fdg.cRuns; /* Max number of runs */
  237. iStart = 0;
  238. iStop = cRuns;
  239. /*
  240. * Look to see if the first glyph in the font is higher than the lowest
  241. * in the RLE data. If so, we need to amend the lower limit.
  242. */
  243. if( pFM->wFirstChar > pntrle->wchFirst )
  244. {
  245. /* Need to amend the lower end */
  246. pwcr = &pntrle->fdg.awcrun[ iStart ];
  247. for( ; iStart < iStop; ++iStart, ++pwcr )
  248. {
  249. if( pFM->wFirstChar < (pwcr->wcLow + pwcr->cGlyphs) )
  250. break;
  251. }
  252. }
  253. if( pFM->wLastChar < pntrle->wchLast )
  254. {
  255. /* The top end goes too far! */
  256. pwcr = &pntrle->fdg.awcrun[ iStop - 1 ];
  257. for( ; iStop > iStart; --iStop, --pwcr )
  258. {
  259. if( pFM->wLastChar >= pwcr->wcLow )
  260. break;
  261. }
  262. }
  263. /* Now have a new count of runs (sometimes, anyway) */
  264. cRuns = iStop - iStart;
  265. if( cRuns == 0 )
  266. {
  267. /* SHOULD NEVER HAPPEN! */
  268. cRuns = 1;
  269. ERR(( "UniFont!DrvQueryFontTree: cRuns == 0, pwszFaceName = %s\n", pwszFaceName ));
  270. }
  271. /*
  272. * Allocate the storage required for the header. Note that the
  273. * FD_GLYPHSET structure contains 1 WCRUN, so we reduce the number
  274. * required by one.
  275. */
  276. cbReq = sizeof( FD_GLYPHSET ) + (cRuns - 1) * sizeof( WCRUN );
  277. pFMDev->pUCTree = (void *)MemAllocZ(cbReq );
  278. if( pFMDev->pUCTree == NULL )
  279. {
  280. /* Tough - give up now */
  281. ERR(( "!!!UniFont!PVGetUCRLE:( MemAlloc Failed for pUCTree \n"));
  282. TRACE(UniFont!PVGetUCRLE:END\n);
  283. return NULL;
  284. }
  285. pGLSet = pFMDev->pUCTree;
  286. CopyMemory( pGLSet, &pntrle->fdg, sizeof( FD_GLYPHSET ) );
  287. /*
  288. * Copy the WCRUN data as appropriate. Some of those in the
  289. * resource may be dropped at this time, depending upon the range
  290. * of glyphs in the font. It is also time to convert the offsets
  291. * stored in the phg field to an address.
  292. */
  293. pwcr = &pntrle->fdg.awcrun[ iStart ];
  294. pGLSet->cGlyphsSupported = 0; /* Add them up as we go! */
  295. pGLSet->cRuns = cRuns;
  296. for( iI = 0; iI < cRuns; ++iI, ++pwcr )
  297. {
  298. pGLSet->awcrun[ iI ].wcLow = pwcr->wcLow;
  299. pGLSet->awcrun[ iI ].cGlyphs = pwcr->cGlyphs;
  300. pGLSet->cGlyphsSupported += pwcr->cGlyphs;
  301. pGLSet->awcrun[ iI ].phg = (HGLYPH *)((BYTE *)pntrle + (ULONG_PTR)pwcr->phg);
  302. }
  303. /* Do the first and last entries need modifying?? */
  304. if( (iDiff = (UINT)pGLSet->awcrun[0].wcLow - (UINT)pFM->wFirstChar) > 0 )
  305. {
  306. /* The first is not the first, so adjust values */
  307. pGLSet->awcrun[ 0 ].wcLow += (WORD)iDiff;
  308. pGLSet->awcrun[ 0 ].cGlyphs -= (WORD)iDiff;
  309. pGLSet->awcrun[ 0 ].phg += (ULONG_PTR)iDiff;
  310. pGLSet->cGlyphsSupported -= iDiff;
  311. }
  312. if( (iDiff = (UINT)pGLSet->awcrun[ cRuns - 1 ].wcLow +
  313. (UINT)pGLSet->awcrun[ cRuns - 1 ].cGlyphs - 1 -
  314. (UINT)pFM->wLastChar) > 0 )
  315. {
  316. /* Need to limit the top one too! */
  317. pGLSet->awcrun[ cRuns - 1 ].cGlyphs -= (WORD)iDiff;
  318. pGLSet->cGlyphsSupported -= (ULONG)iDiff;
  319. }
  320. TRACE(UniFont!PVGetUCRLE:END\n);
  321. return pFMDev->pUCTree;
  322. }