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.

512 lines
15 KiB

  1. /*++
  2. Copyright (c) 1993 Microsoft Corporation
  3. Module Name:
  4. fefont.c
  5. Abstract:
  6. Text setup display support for FarEast text output.
  7. Author:
  8. Hideyuki Nagase (hideyukn) 01-July-1994
  9. Revision History:
  10. --*/
  11. #include <precomp.h>
  12. #pragma hdrstop
  13. #define FE_FONT_FILE_NAME L"BOOTFONT.BIN"
  14. //
  15. // FontFile image information
  16. //
  17. PVOID pvFontFileView = NULL;
  18. ULONG ulFontFileSize = 0L;
  19. BOOLEAN FontFileViewAllocated = FALSE;
  20. //
  21. // Font Glyph information
  22. //
  23. BOOTFONTBIN_HEADER BootFontHeader;
  24. PUCHAR SbcsImages;
  25. PUCHAR DbcsImages;
  26. //
  27. // Graphics Character image 19x8.
  28. //
  29. UCHAR GraphicsCharImage[0x20][19] = {
  30. /* 0x00 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  31. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  32. /* 0x01 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xDF,
  33. 0xD8, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB },
  34. /* 0x02 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0xFB,
  35. 0x1B, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB },
  36. /* 0x03 */ { 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xD8, 0xDF,
  37. 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  38. /* 0x04 */ { 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x1B, 0xFB,
  39. 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  40. /* 0x05 */ { 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB,
  41. 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB },
  42. /* 0x06 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF,
  43. 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  44. /* 0x07 */ { 0xFF, 0xFF, 0xFF, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
  45. 0xF7, 0xF7, 0xF7, 0xC1, 0xE3, 0xE3, 0xF7, 0xFF, 0xFF, 0xFF },
  46. /* 0x08 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  47. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  48. /* 0x09 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE7, 0xDB, 0xDB, 0xBD,
  49. 0xBD, 0xBD, 0xBD, 0xDB, 0xDB, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF },
  50. /* 0x0a */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  51. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  52. /* 0x0b */ { 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x7D, 0x39, 0x55, 0x55,
  53. 0x6D, 0x6D, 0x55, 0x55, 0x39, 0x7D, 0x01, 0xFF, 0xFF, 0xFF },
  54. /* 0x0c */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  55. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  56. /* 0x0d */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  57. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  58. /* 0x0e */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0x01, 0x01, 0x01,
  59. 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xFF, 0xFF },
  60. /* 0x0f */ { 0xFF, 0xFF, 0xFF, 0xB6, 0xB6, 0xD5, 0xC9, 0xEB, 0xDD,
  61. 0x1C, 0xDD, 0xEB, 0xC9, 0xD5, 0xB6, 0xB6, 0xFF, 0xFF, 0xFF },
  62. /* 0x10 */ { 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x18, 0xFF,
  63. 0x18, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB },
  64. /* 0x11 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  65. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  66. /* 0x12 */ { 0xFF, 0xFF, 0xFF, 0xF7, 0xE3, 0xE3, 0xC1, 0xF7, 0xF7,
  67. 0xF7, 0xF7, 0xF7, 0xC1, 0xE3, 0xE3, 0xF7, 0xFF, 0xFF, 0xFF },
  68. /* 0x13 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  69. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  70. /* 0x14 */ { 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55,
  71. 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 },
  72. /* 0x15 */ { 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x18, 0xFF,
  73. 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  74. /* 0x16 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0xFF,
  75. 0x18, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB },
  76. /* 0x17 */ { 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x1B, 0xFB,
  77. 0x1B, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB },
  78. /* 0x18 */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
  79. 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  80. /* 0x19 */ { 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xD8, 0xDF,
  81. 0xD8, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB },
  82. /* 0x1a */ { 0xFF, 0xFF, 0xAA, 0xFF, 0x55, 0xFF, 0xAA, 0xFF, 0x55,
  83. 0xFF, 0xAA, 0xFF, 0x55, 0xFF, 0xAA, 0xFF, 0x55, 0xFF, 0xAA },
  84. /* 0x1b */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD, 0xFD, 0xDD,
  85. 0x9D, 0x01, 0x9F, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  86. /* 0x1c */ { 0xFF, 0xFF, 0xFF, 0xF7, 0xE3, 0xE3, 0xC1, 0xF7, 0xF7,
  87. 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xFF, 0xFF, 0xFF },
  88. /* 0x1d */ { 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
  89. 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7 },
  90. /* 0x1e */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFB,
  91. 0xF9, 0x80, 0xF9, 0xfB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF },
  92. /* 0x1f */ { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xDF,
  93. 0x9F, 0x01, 0x9F, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }
  94. };
  95. BOOLEAN
  96. FEDbcsFontInitGlyphs(
  97. IN PCWSTR BootDevicePath,
  98. IN PCWSTR DirectoryOnBootDevice,
  99. IN PVOID BootFontImage OPTIONAL,
  100. IN ULONG BootFontImageLength OPTIONAL
  101. )
  102. {
  103. WCHAR NtFEFontPath[129];
  104. BOOLEAN bRet;
  105. NTSTATUS NtStatus;
  106. PVOID pvFontFileOnDisk = NULL;
  107. HANDLE hFontFile = 0 ,
  108. hFontSection = 0;
  109. if (BootFontImage && BootFontImageLength) {
  110. //
  111. // Use the loader passed bootfont.bin image as it is (if one exists)
  112. //
  113. pvFontFileView = BootFontImage;
  114. ulFontFileSize = BootFontImageLength;
  115. FontFileViewAllocated = FALSE;
  116. } else {
  117. //
  118. // Build FontFile path.
  119. //
  120. wcscpy( NtFEFontPath,BootDevicePath);
  121. if( NtFEFontPath[ wcslen(NtFEFontPath) - 1 ] != L'\\' )
  122. {
  123. wcscat( NtFEFontPath , L"\\" );
  124. }
  125. wcscat( NtFEFontPath , FE_FONT_FILE_NAME );
  126. //
  127. // Check the font is exist
  128. //
  129. bRet = SpFileExists( NtFEFontPath , FALSE );
  130. if( !bRet ) {
  131. //
  132. // It's not in the root of our BootDevice. Check the
  133. // DirectoryOnBootDevice path too before we fail.
  134. //
  135. wcscpy( NtFEFontPath,BootDevicePath);
  136. wcscat( NtFEFontPath,DirectoryOnBootDevice);
  137. if( NtFEFontPath[ wcslen(NtFEFontPath) - 1 ] != L'\\' )
  138. {
  139. wcscat( NtFEFontPath , L"\\" );
  140. }
  141. wcscat( NtFEFontPath , FE_FONT_FILE_NAME );
  142. //
  143. // Check the font is exist
  144. //
  145. bRet = SpFileExists( NtFEFontPath , FALSE );
  146. if( !bRet ) {
  147. KdPrint(("SETUP:FarEast font file (%ws) is not exist\n",NtFEFontPath));
  148. return( FALSE );
  149. }
  150. }
  151. //
  152. // Read and Map fontfile into Memory.
  153. //
  154. NtStatus = SpOpenAndMapFile(
  155. NtFEFontPath , // IN PWSTR FileName,
  156. &hFontFile , // OUT PHANDLE FileHandle,
  157. &hFontSection , // OUT PHANDLE SectionHandle,
  158. &pvFontFileOnDisk , // OUT PVOID *ViewBase,
  159. &ulFontFileSize , // OUT PULONG FileSize,
  160. FALSE // IN BOOLEAN WriteAccess
  161. );
  162. if( !NT_SUCCESS(NtStatus) ) {
  163. KdPrint(("SETUP:Fail to map FontFile\n"));
  164. return( FALSE );
  165. }
  166. KdPrint(("FONTFILE ON DISK CHECK\n"));
  167. KdPrint((" pvFontFileView - %x\n",pvFontFileOnDisk));
  168. KdPrint((" ulFontFileSize - %d\n",ulFontFileSize));
  169. //
  170. // Allocate buffer for FontFile image.
  171. //
  172. pvFontFileView = SpMemAlloc( ulFontFileSize );
  173. FontFileViewAllocated = TRUE;
  174. //
  175. // Copy image to local beffer
  176. //
  177. RtlCopyMemory( pvFontFileView , pvFontFileOnDisk , ulFontFileSize );
  178. //
  179. // Unmap/Close fontfile.
  180. //
  181. SpUnmapFile( hFontSection , pvFontFileOnDisk );
  182. ZwClose( hFontFile );
  183. }
  184. KdPrint(("FONTFILE ON MEMORY CHECK\n"));
  185. KdPrint((" pvFontFileView - %x\n",pvFontFileView));
  186. KdPrint((" ulFontFileSize - %d\n",ulFontFileSize));
  187. //
  188. // Check fontfile validation (at least, we should have font header).
  189. //
  190. if( ulFontFileSize < sizeof(BOOTFONTBIN_HEADER) )
  191. {
  192. KdPrint(("SETUPDD:FontFile Size < sizeof(BOOTFONTBIN_HEADER)\n"));
  193. return( FALSE );
  194. }
  195. //
  196. // Copy header to local...
  197. //
  198. RtlCopyMemory((PCHAR)&BootFontHeader,
  199. (PCHAR)pvFontFileView,
  200. sizeof(BOOTFONTBIN_HEADER));
  201. //
  202. // Check font signature.
  203. //
  204. if( BootFontHeader.Signature != BOOTFONTBIN_SIGNATURE )
  205. {
  206. KdPrint(("SETUPDD:Invalid font signature.\n"));
  207. return( FALSE );
  208. }
  209. SbcsImages = (PUCHAR)pvFontFileView + BootFontHeader.SbcsOffset;
  210. DbcsImages = (PUCHAR)pvFontFileView + BootFontHeader.DbcsOffset;
  211. //
  212. // Dump Physical FontGlyph information
  213. //
  214. KdPrint(("FONT GLYPH INFORMATION\n"));
  215. KdPrint((" LanguageId - %d\n",BootFontHeader.LanguageId));
  216. KdPrint((" Width(S) - %d\n",BootFontHeader.CharacterImageSbcsWidth));
  217. KdPrint((" Width(D) - %d\n",BootFontHeader.CharacterImageDbcsWidth));
  218. KdPrint((" Height - %d\n",BootFontHeader.CharacterImageHeight));
  219. KdPrint((" TopPad - %d\n",BootFontHeader.CharacterTopPad));
  220. KdPrint((" BottomPad - %d\n",BootFontHeader.CharacterBottomPad));
  221. KdPrint((" SbcsOffset - %x\n",BootFontHeader.SbcsOffset));
  222. KdPrint((" DbcsOffset - %x\n",BootFontHeader.DbcsOffset));
  223. KdPrint((" SbcsImages - %x\n",SbcsImages));
  224. KdPrint((" DbcsImages - %x\n",DbcsImages));
  225. //
  226. // Check Language ID..
  227. //
  228. switch (BootFontHeader.LanguageId) {
  229. case 0x411: // Japan
  230. FEFontDefaultChar = 0x8140;
  231. break;
  232. case 0x404: // Taiwan
  233. case 0x804: // PRC
  234. case 0x412: // Korea
  235. FEFontDefaultChar = 0xa1a1;
  236. break;
  237. default: // Illigal language Id
  238. KdPrint(("SETUPDD:Invalid Language ID\n"));
  239. return( FALSE );
  240. }
  241. //
  242. // Check font file size, more strictly..
  243. //
  244. if( ulFontFileSize < (sizeof(BOOTFONTBIN_HEADER) +
  245. BootFontHeader.SbcsEntriesTotalSize +
  246. BootFontHeader.DbcsEntriesTotalSize) ) {
  247. KdPrint(("SETUPDD:Invalid file size\n"));
  248. return( FALSE );
  249. }
  250. //
  251. // Check font image size... SBCS 16x8 : DBCS 16x16.
  252. //
  253. if( (BootFontHeader.CharacterImageSbcsWidth != 8 ) ||
  254. (BootFontHeader.CharacterImageDbcsWidth != 16 ) ||
  255. (BootFontHeader.CharacterImageHeight != 16 ) ) {
  256. KdPrint(("SETUPDD:Invalid font size\n"));
  257. return( FALSE );
  258. }
  259. //
  260. // Check the character entry sizes
  261. //
  262. if( BootFontHeader.SbcsEntriesTotalSize != BootFontHeader.NumSbcsChars * (BootFontHeader.CharacterImageHeight + 3) ||
  263. BootFontHeader.DbcsEntriesTotalSize != BootFontHeader.NumDbcsChars * (2 * BootFontHeader.CharacterImageHeight + 4)) {
  264. KdPrint(("SETUPDD:Invalid font entry sizes\n"));
  265. return FALSE;
  266. }
  267. KdPrint(("Everything is well done...\n"));
  268. return( TRUE );
  269. }
  270. VOID
  271. FEDbcsFontFreeGlyphs(
  272. VOID
  273. )
  274. {
  275. if (FontFileViewAllocated) {
  276. SpMemFree(pvFontFileView);
  277. }
  278. }
  279. PUCHAR
  280. DbcsFontGetDbcsFontChar(
  281. USHORT Code
  282. )
  283. /*++
  284. Routine Description:
  285. Gets the font image for DBCS char.
  286. Arguments:
  287. Code - DBCS char code.
  288. Return Value:
  289. Pointer to font image, or else NULL.
  290. --*/
  291. {
  292. int Min,Max,Mid;
  293. int Multiplier;
  294. int Index;
  295. USHORT code;
  296. Min = 0;
  297. Max = BootFontHeader.NumDbcsChars;
  298. // multiplier = 2 (for index) +
  299. // 2 * height +
  300. // 2 (for unicode encoding)
  301. //
  302. Multiplier = 2 + (2*BootFontHeader.CharacterImageHeight) + 2;
  303. //
  304. // Do a binary search for the image.
  305. // Format of table:
  306. // First 2 bytes contain the DBCS char code.
  307. // Next (2 * CharacterImageHeight) bytes are the char image.
  308. // Next 2 bytes are for unicode version.
  309. //
  310. while(Max >= Min) {
  311. Mid = (Max + Min) / 2;
  312. Index = Mid*Multiplier;
  313. code = (DbcsImages[Index] << 8) | DbcsImages[Index+1];
  314. if(Code == code) {
  315. return(DbcsImages+Index+2);
  316. }
  317. if(Code < code) {
  318. Max = Mid - 1;
  319. } else {
  320. Min = Mid + 1;
  321. }
  322. }
  323. //
  324. // ERROR: No image found.
  325. //
  326. return(NULL);
  327. }
  328. PUCHAR
  329. DbcsFontGetSbcsFontChar(
  330. UCHAR Code
  331. )
  332. /*++
  333. Routine Description:
  334. Gets the font image for SBCS char.
  335. Arguments:
  336. Code - SBCS char code.
  337. Return Value:
  338. Pointer to font image, or else NULL.
  339. --*/
  340. {
  341. int Max,Min,Mid;
  342. int Multiplier;
  343. int Index;
  344. Min = 0;
  345. Max = BootFontHeader.NumSbcsChars;
  346. // multiplier = 1 (for index) +
  347. // height +
  348. // 2 (for unicode encoding)
  349. //
  350. Multiplier = 1 + (BootFontHeader.CharacterImageHeight) + 2;
  351. //
  352. // Do a binary search for the image.
  353. // Format of table:
  354. // First byte contains the SBCS char code.
  355. // Next (CharacterImageHeight) bytes are the char image.
  356. // Next 2 bytes are for unicode version.
  357. //
  358. while(Max >= Min) {
  359. Mid = (Max + Min) / 2;
  360. Index = Mid*Multiplier;
  361. if(Code == SbcsImages[Index]) {
  362. return(SbcsImages+Index+1);
  363. }
  364. if(Code < SbcsImages[Index]) {
  365. Max = Mid - 1;
  366. } else {
  367. Min = Mid + 1;
  368. }
  369. }
  370. //
  371. // ERROR: No image found.
  372. //
  373. return(NULL);
  374. }
  375. PBYTE
  376. DbcsFontGetGraphicsChar(
  377. UCHAR Char
  378. )
  379. {
  380. if (Char >= 0 && Char < 0x20)
  381. return(GraphicsCharImage[Char]);
  382. else
  383. return(NULL);
  384. }
  385. BOOLEAN
  386. DbcsFontIsGraphicsChar(
  387. UCHAR Char
  388. )
  389. {
  390. if (Char >= 0 && Char < 0x20)
  391. return(TRUE);
  392. else
  393. return(FALSE);
  394. }
  395. BOOLEAN
  396. DbcsFontIsDBCSLeadByte(
  397. IN UCHAR c
  398. )
  399. /*++
  400. Routine Description:
  401. Checks to see if a char is a DBCS leadbyte.
  402. Arguments:
  403. c - char to check if leadbyte or not.
  404. Return Value:
  405. TRUE - Leadbyte.
  406. FALSE - Non-Leadbyte.
  407. --*/
  408. {
  409. int i;
  410. //
  411. // Check to see if char is in leadbyte range.
  412. //
  413. // NOTE: If (CHAR)(0) is a valid leadbyte,
  414. // this routine will fail.
  415. //
  416. for( i = 0; BootFontHeader.DbcsLeadTable[i]; i += 2 ) {
  417. if ( BootFontHeader.DbcsLeadTable[i] <= c &&
  418. BootFontHeader.DbcsLeadTable[i+1] >= c )
  419. return( TRUE );
  420. }
  421. return( FALSE );
  422. }