Source code of Windows XP (NT5)
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.

503 lines
14 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. KdPrint(("Everything is well done...\n"));
  260. return( TRUE );
  261. }
  262. VOID
  263. FEDbcsFontFreeGlyphs(
  264. VOID
  265. )
  266. {
  267. if (FontFileViewAllocated) {
  268. SpMemFree(pvFontFileView);
  269. }
  270. }
  271. PUCHAR
  272. DbcsFontGetDbcsFontChar(
  273. USHORT Code
  274. )
  275. /*++
  276. Routine Description:
  277. Gets the font image for DBCS char.
  278. Arguments:
  279. Code - DBCS char code.
  280. Return Value:
  281. Pointer to font image, or else NULL.
  282. --*/
  283. {
  284. int Min,Max,Mid;
  285. int Multiplier;
  286. int Index;
  287. USHORT code;
  288. Min = 0;
  289. Max = BootFontHeader.NumDbcsChars;
  290. // multiplier = 2 (for index) +
  291. // 2 * height +
  292. // 2 (for unicode encoding)
  293. //
  294. Multiplier = 2 + (2*BootFontHeader.CharacterImageHeight) + 2;
  295. //
  296. // Do a binary search for the image.
  297. // Format of table:
  298. // First 2 bytes contain the DBCS char code.
  299. // Next (2 * CharacterImageHeight) bytes are the char image.
  300. // Next 2 bytes are for unicode version.
  301. //
  302. while(Max >= Min) {
  303. Mid = (Max + Min) / 2;
  304. Index = Mid*Multiplier;
  305. code = (DbcsImages[Index] << 8) | DbcsImages[Index+1];
  306. if(Code == code) {
  307. return(DbcsImages+Index+2);
  308. }
  309. if(Code < code) {
  310. Max = Mid - 1;
  311. } else {
  312. Min = Mid + 1;
  313. }
  314. }
  315. //
  316. // ERROR: No image found.
  317. //
  318. return(NULL);
  319. }
  320. PUCHAR
  321. DbcsFontGetSbcsFontChar(
  322. UCHAR Code
  323. )
  324. /*++
  325. Routine Description:
  326. Gets the font image for SBCS char.
  327. Arguments:
  328. Code - SBCS char code.
  329. Return Value:
  330. Pointer to font image, or else NULL.
  331. --*/
  332. {
  333. int Max,Min,Mid;
  334. int Multiplier;
  335. int Index;
  336. Min = 0;
  337. Max = BootFontHeader.NumSbcsChars;
  338. // multiplier = 1 (for index) +
  339. // height +
  340. // 2 (for unicode encoding)
  341. //
  342. Multiplier = 1 + (BootFontHeader.CharacterImageHeight) + 2;
  343. //
  344. // Do a binary search for the image.
  345. // Format of table:
  346. // First byte contains the SBCS char code.
  347. // Next (CharacterImageHeight) bytes are the char image.
  348. // Next 2 bytes are for unicode version.
  349. //
  350. while(Max >= Min) {
  351. Mid = (Max + Min) / 2;
  352. Index = Mid*Multiplier;
  353. if(Code == SbcsImages[Index]) {
  354. return(SbcsImages+Index+1);
  355. }
  356. if(Code < SbcsImages[Index]) {
  357. Max = Mid - 1;
  358. } else {
  359. Min = Mid + 1;
  360. }
  361. }
  362. //
  363. // ERROR: No image found.
  364. //
  365. return(NULL);
  366. }
  367. PBYTE
  368. DbcsFontGetGraphicsChar(
  369. UCHAR Char
  370. )
  371. {
  372. if (Char >= 0 && Char < 0x20)
  373. return(GraphicsCharImage[Char]);
  374. else
  375. return(NULL);
  376. }
  377. BOOLEAN
  378. DbcsFontIsGraphicsChar(
  379. UCHAR Char
  380. )
  381. {
  382. if (Char >= 0 && Char < 0x20)
  383. return(TRUE);
  384. else
  385. return(FALSE);
  386. }
  387. BOOLEAN
  388. DbcsFontIsDBCSLeadByte(
  389. IN UCHAR c
  390. )
  391. /*++
  392. Routine Description:
  393. Checks to see if a char is a DBCS leadbyte.
  394. Arguments:
  395. c - char to check if leadbyte or not.
  396. Return Value:
  397. TRUE - Leadbyte.
  398. FALSE - Non-Leadbyte.
  399. --*/
  400. {
  401. int i;
  402. //
  403. // Check to see if char is in leadbyte range.
  404. //
  405. // NOTE: If (CHAR)(0) is a valid leadbyte,
  406. // this routine will fail.
  407. //
  408. for( i = 0; BootFontHeader.DbcsLeadTable[i]; i += 2 ) {
  409. if ( BootFontHeader.DbcsLeadTable[i] <= c &&
  410. BootFontHeader.DbcsLeadTable[i+1] >= c )
  411. return( TRUE );
  412. }
  413. return( FALSE );
  414. }