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.

423 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 - 1999 Microsoft Corporation
  3. Module Name:
  4. ctt2rle.c
  5. Abstract:
  6. Convert Win 3.1 CTT CTT_WTYPE_DIRECT format tables to NT 4.0 RLE spec.
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. 01/10/97 -ganeshp-
  11. Created
  12. --*/
  13. #include "font.h"
  14. /*
  15. * Some useful definitions for memory sizes and masks.
  16. */
  17. #define DW_MASK (DWBITS - 1)
  18. #define OVERFLOW_SZ sizeof( WORD )
  19. NT_RLE *
  20. PNTRLE1To1(
  21. IN BOOL bSymbolCharSet,
  22. int iFirst,
  23. int iLast
  24. )
  25. /*++
  26. Routine Description:
  27. Generates a simple mapping format for the RLE stuff. This is
  28. typically used for a printer with a 1:1 mapping to the Windows
  29. character set.
  30. Arguments:
  31. iFirst The lowest glyph in the range.
  32. iLast The last glyph in the range (inclusive).
  33. Return Value:
  34. Address of NT_RLE structure allocated from heap; NULL on failure.
  35. Note:
  36. 2/10/1997 -ganeshp-
  37. Created it.
  38. --*/
  39. {
  40. /*
  41. * Operation is simple. We create a dummy CTT that is a 1:1 mapping,
  42. * then call the conversion function to generate the correct values.
  43. */
  44. int iI; /* Loop index */
  45. int iMax; /* Find the longest data length for CTT_WTYPE_COMPOSE */
  46. int cHandles; /* The number of handles we need */
  47. int cjExtra; /* Extra storage needed for offset modes */
  48. int cjTotal; /* Total amount of storage to be requested */
  49. int iIndex; /* Index we install in the HGLYPH for widths etc */
  50. int cRuns; /* Number of runs we create */
  51. NT_RLE *pntrle; /* Allocated memory, and returned to caller */
  52. UHG uhg; /* Clearer (?) access to HGLYPH contents */
  53. HGLYPH *phg; /* For working through the array of HGLYPHS */
  54. BYTE *pb; /* Current address in overflow area */
  55. BYTE *pbBase; /* Start of overflow area containing data */
  56. WCRUN *pwcr; /* Scanning the run data */
  57. DWORD *pdwBits; /* For figuring out runs */
  58. DWORD cdwBits; /* Size of this area */
  59. DWORD cbWch;
  60. BOOL bInRun; /* For processing run accumulations */
  61. BYTE ajAnsi[ 256 ];
  62. WCHAR wchMin; /* Find the first unicode value */
  63. WCHAR wchMax; /* Find the last unicode value */
  64. WCHAR awch[ 512 ]; /* Converted array of points */
  65. ASSERT(iFirst == 0x20 && iLast == 0xFF);
  66. cHandles = iLast - iFirst + 1;
  67. if( cHandles > 256 )
  68. return NULL; /* This code does not handle that situation */
  69. cjExtra = 0; /* Presume no extra storage required */
  70. /*
  71. * We need to figure out how many runs are required to describe
  72. * this font. First obtain the correct Unicode encoding of these
  73. * values, then examine them to find the number of runs, and
  74. * hence much extra storage is required.
  75. */
  76. ZeroMemory(awch, sizeof(awch));
  77. for( iI = 0; iI < cHandles; ++iI )
  78. ajAnsi[ iI ] = (BYTE)(iI + iFirst);
  79. #ifndef WINNT_40 //NT 5.0
  80. //
  81. // force Windows ANSI codepage
  82. //
  83. if( -1 == (cbWch = EngMultiByteToWideChar(1252,
  84. awch,
  85. (ULONG)(cHandles * sizeof(WCHAR)),
  86. (PCH) ajAnsi,
  87. (ULONG) cHandles)))
  88. {
  89. #if DBG
  90. DbgPrint( "EngMultiByteToWideChar failed \n");
  91. #endif
  92. return NULL;
  93. }
  94. cHandles = cbWch;
  95. #else // NT 4.0
  96. EngMultiByteToUnicodeN(awch,cHandles * sizeof(WCHAR),NULL,ajAnsi,cHandles);
  97. #endif //!WINNT_40
  98. /*
  99. * Find the largest Unicode value, then allocate storage to allow us
  100. * to create a bit array of valid unicode points. Then we can
  101. * examine this to determine the number of runs.
  102. */
  103. if (bSymbolCharSet)
  104. {
  105. for (iI = 0; iI < NUM_OF_SYMBOL; iI ++)
  106. {
  107. awch[cHandles + iI] = SYMBOL_START + iI;
  108. }
  109. cHandles += NUM_OF_SYMBOL;
  110. }
  111. for( wchMax = 0, wchMin = 0xffff, iI = 0; iI < cHandles; ++iI )
  112. {
  113. //
  114. // Bugfix: Euro currency symbol doesn't print.
  115. // Euro currency symbols Unicode is U+20AC. NLS Unicode to Multibyte
  116. // table converts 0x80 (Multi byte) to U+20AC. We have to exclude
  117. // 0x80 from ASCII table. So that we don't substitute U+20AC with
  118. // device font 0x80.
  119. //
  120. if (awch[ iI ] == 0x20ac)
  121. continue;
  122. if( awch[ iI ] > wchMax )
  123. wchMax = awch[ iI ];
  124. if( awch[ iI ] < wchMin )
  125. wchMin = awch[ iI ];
  126. }
  127. /*
  128. * Note that the expression 1 + wchMax IS correct. This comes about
  129. * from using these values as indices into the bit array, and that
  130. * this is essentially 1 based.
  131. */
  132. cdwBits = (1 + wchMax + DWBITS - 1) / DWBITS * sizeof( DWORD );
  133. if( !(pdwBits = (DWORD *)MemAllocZ(cdwBits )) )
  134. {
  135. return NULL; /* Nothing going */
  136. }
  137. /*
  138. * Set bits in this array corresponding to Unicode code points
  139. */
  140. for( iI = 0; iI < cHandles; ++iI )
  141. {
  142. if (awch[ iI ] == 0x20ac)
  143. continue;
  144. pdwBits[ awch[ iI ] / DWBITS ] |= (1 << (awch[ iI ] & DW_MASK));
  145. }
  146. /*
  147. * Now we can examine the number of runs required. For starters,
  148. * we stop a run whenever a hole is discovered in the array of 1
  149. * bits we just created. Later we MIGHT consider being a little
  150. * less pedantic.
  151. */
  152. bInRun = FALSE;
  153. cRuns = 0; /* None so far */
  154. for( iI = 1; iI <= (int)wchMax; ++iI )
  155. {
  156. if( pdwBits[ iI / DWBITS ] & (1 << (iI & DW_MASK)) )
  157. {
  158. /*
  159. * Not in a run: is this the end of one?
  160. */
  161. if( !bInRun )
  162. {
  163. /*
  164. * It's time to start one
  165. */
  166. bInRun = TRUE;
  167. ++cRuns;
  168. }
  169. }
  170. else
  171. {
  172. if( bInRun )
  173. {
  174. /* Not any more! */
  175. bInRun = FALSE;
  176. }
  177. }
  178. }
  179. cjTotal = sizeof( NT_RLE ) +
  180. (cRuns - 1) * sizeof( WCRUN ) +
  181. cHandles * sizeof( HGLYPH ) +
  182. cjExtra;
  183. //
  184. // Allocate Real NTRLE
  185. //
  186. if( !(pntrle = (NT_RLE *)MemAllocZ( cjTotal )) )
  187. {
  188. MemFree((LPSTR)pdwBits );
  189. return pntrle;
  190. }
  191. //
  192. // For calculating offsets, we need these addresses
  193. //
  194. pbBase = (BYTE *)pntrle;
  195. //
  196. // FD_GLYPHSET contains the first WCRUN data structure,
  197. // so that cRun - 1 is correct.
  198. //
  199. phg = (HGLYPH *)(pbBase + sizeof( NT_RLE ) + (cRuns - 1) * sizeof( WCRUN ));
  200. pb = (BYTE *)phg + cHandles * sizeof( HGLYPH );
  201. pntrle->wType = RLE_DIRECT;
  202. pntrle->bMagic0 = RLE_MAGIC0;
  203. pntrle->bMagic1 = RLE_MAGIC1;
  204. pntrle->cjThis = cjTotal;
  205. pntrle->wchFirst = wchMin; /* Lowest unicode code point */
  206. pntrle->wchLast = wchMax; /* Highest unicode code point */
  207. pntrle->fdg.cjThis = sizeof( FD_GLYPHSET ) + (cRuns - 1) * sizeof( WCRUN );
  208. pntrle->fdg.cGlyphsSupported = cHandles;
  209. pntrle->fdg.cRuns = cRuns;
  210. pntrle->fdg.awcrun[ 0 ].wcLow = pntrle->wchFirst;
  211. pntrle->fdg.awcrun[ 0 ].cGlyphs = (WORD)cHandles;
  212. pntrle->fdg.awcrun[ 0 ].phg = (HGLYPH*)((BYTE *)phg - pbBase);
  213. /*
  214. * We now wish to fill in the awcrun data. Filling it in now
  215. * simplifies operations later on. Now we can scan the bit array
  216. * data, and so easily figure out how large the runs are and
  217. * where abouts a particular HGLYPH is located.
  218. */
  219. bInRun = FALSE;
  220. cRuns = 0; /* None so far */
  221. iMax = 0; /* Count glyphs for address arithmetic */
  222. for( iI = 1; iI <= (int)wchMax; ++iI )
  223. {
  224. if( pdwBits[ iI / DWBITS ] & (1 << (iI & DW_MASK)) )
  225. {
  226. /*
  227. * Not in a run: is this the end of one?
  228. */
  229. if( !bInRun )
  230. {
  231. /*
  232. * It's time to start one
  233. */
  234. bInRun = TRUE;
  235. pntrle->fdg.awcrun[ cRuns ].wcLow = (WCHAR)iI;
  236. pntrle->fdg.awcrun[ cRuns ].cGlyphs = 0;
  237. pntrle->fdg.awcrun[ cRuns ].phg = (HGLYPH*)((PBYTE)(phg + iMax) - pbBase);
  238. }
  239. pntrle->fdg.awcrun[ cRuns ].cGlyphs++; /* One more */
  240. ++iMax;
  241. }
  242. else
  243. {
  244. if( bInRun )
  245. {
  246. /* Not any more! */
  247. bInRun = FALSE;
  248. ++cRuns; /* Onto the next structure */
  249. }
  250. }
  251. }
  252. if( bInRun )
  253. ++cRuns; /* It has finished now */
  254. /*
  255. * Now go fill in the array of HGLYPHS. The actual format varies
  256. * depending upon the range of glyphs, and upon the CTT format.
  257. */
  258. for( iIndex = 0, iI = iFirst; iI <= iLast; ++iI, ++iIndex )
  259. {
  260. WCHAR wchTemp; /* For Unicode mapping */
  261. /*
  262. * Need to map this BYTE value into the appropriate WCHAR
  263. * value, then look for the location of the phg that fits.
  264. */
  265. wchTemp = awch[ iIndex ];
  266. if (wchTemp == 0x20ac)
  267. continue;
  268. phg = NULL; /* Flag that we failed */
  269. pwcr = pntrle->fdg.awcrun;
  270. for( iMax = 0; iMax < cRuns; ++iMax )
  271. {
  272. if( pwcr->wcLow <= wchTemp &&
  273. (pwcr->wcLow + pwcr->cGlyphs) > wchTemp )
  274. {
  275. /*
  276. * Found the range, so now select the slot
  277. */
  278. if (pwcr->phg)
  279. phg = (HGLYPH*)((ULONG_PTR)pbBase + (ULONG_PTR)pwcr->phg) + wchTemp - pwcr->wcLow;
  280. else
  281. phg = NULL;
  282. break;
  283. }
  284. ++pwcr;
  285. }
  286. if( phg == NULL )
  287. continue; /* Should not happen */
  288. uhg.rd.b0 = *((PBYTE)&iI);
  289. uhg.rd.b1 = 0;
  290. uhg.rd.wIndex = (WORD)iIndex;
  291. *phg = uhg.hg;
  292. }
  293. if (bSymbolCharSet)
  294. {
  295. pwcr = pntrle->fdg.awcrun;
  296. phg = NULL;
  297. for ( iMax = 0; iMax < cRuns; ++iMax)
  298. {
  299. if (SYMBOL_START == pwcr->wcLow)
  300. {
  301. /*
  302. * Found the range, so now select the slot
  303. */
  304. if (pwcr->phg)
  305. phg = (HGLYPH*)((ULONG_PTR)pbBase + (ULONG_PTR)pwcr->phg);
  306. else
  307. phg = NULL;
  308. break;
  309. }
  310. ++pwcr;
  311. }
  312. if (phg)
  313. {
  314. for (iI = SYMBOL_START; iI <= SYMBOL_END; iI ++, iIndex++, phg++)
  315. {
  316. uhg.rd.b0 = *((PBYTE)&iI);
  317. uhg.rd.b1 = 0;
  318. uhg.rd.wIndex = (WORD)iIndex;
  319. *phg = uhg.hg;
  320. }
  321. }
  322. }
  323. //
  324. // Error check
  325. //
  326. if( (pb - pbBase) > cjTotal )
  327. {
  328. ERR(( "Rasdd!ctt2rle: overflow of data area: alloc %ld, used %ld\n", cjTotal, pb - pbBase ));
  329. }
  330. MemFree( (LPSTR)pdwBits );
  331. return pntrle;
  332. }