home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / libi18n / unicode / unifont.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  9.6 KB  |  352 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. #include "xp.h"
  19. #include "prtypes.h"
  20. #include "prlog.h"
  21. #include "csid.h"
  22.  
  23. /*    define CHARSET For Win16 */
  24. #ifndef _WIN32
  25. #ifndef GB2312_CHARSET
  26. #define GB2312_CHARSET    134
  27. #endif  
  28. #ifndef RUSSIAN_CHARSET
  29. #define RUSSIAN_CHARSET 204
  30. #endif  
  31. #ifndef EASTEUROPE_CHARSET
  32. #define EASTEUROPE_CHARSET 238
  33. #endif  
  34. #ifndef GREEK_CHARSET
  35. #define GREEK_CHARSET 161
  36. #endif  
  37. #ifndef TURKISH_CHARSET
  38. #define TURKISH_CHARSET 162
  39. #endif  
  40. #endif /* !_WIN32 */
  41.  
  42. #if defined(XP_OS2)
  43. #ifndef CALLBACK
  44. #defined CALLBACK
  45. #endif
  46. #endif
  47.  
  48. PR_PUBLIC_API(int) UNICODE_VERIFYCSIDLIST(int inNumOfItem, int16 *csidlist);
  49. PR_PUBLIC_API(int) UNICODE_MENUFONTID();
  50. PR_PUBLIC_API(int16) UNICODE_MENUFONTCSID();
  51.  
  52. /*    Private */
  53. static BOOL iswin95();
  54. static UINT unicode_CsidToCodePage(int16 csid);
  55. static BYTE unicode_CsidToCharset(int16 csid);
  56. static int16 unicode_CharsetToCsid(BYTE charset);
  57. static int CALLBACK DetectCharset(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param);
  58. static BOOL unicode_CheckFontOfCsid(HDC hdc, int16 csid);
  59. static BOOL unicode_CheckNJWINForCsid(HDC hdc, int16 csid);
  60. static BOOL unicode_CheckNJWINForCsid(HDC hdc, int16 csid);
  61. static int CALLBACK DetectTwinBridge(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param);
  62. static int CALLBACK DetectUnionway(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param);
  63. static BOOL unicode_CheckUnionwayForCsid(HDC hdc,int16 csid);
  64. static BOOL unicode_IsCsidAvailable(HDC hdc, int16 csid);
  65.  
  66. #ifdef _WIN32
  67. BOOL unicode_UnicodeFontOfCodePage(HDC hdc, UINT cp);
  68. #endif
  69.  
  70. typedef struct 
  71. {
  72.     int16    csid;
  73.     UINT    cp;
  74.     BYTE    charset;
  75. } csidcpmap;
  76.  
  77. static csidcpmap csidcpmaptbl[] = {
  78.     {CS_LATIN1,     1252,    ANSI_CHARSET},
  79.     {CS_SJIS,         932,    SHIFTJIS_CHARSET},
  80.     {CS_GB_8BIT,    936,    GB2312_CHARSET},
  81.     {CS_BIG5,         950,    CHINESEBIG5_CHARSET},
  82.     {CS_KSC_8BIT,    949,    HANGEUL_CHARSET},
  83.     {CS_CP_1251,     1251,    RUSSIAN_CHARSET},
  84.     {CS_CP_1250,     1250,    EASTEUROPE_CHARSET},
  85.     {CS_CP_1253,     1253,    GREEK_CHARSET},
  86.     {CS_8859_9,     1254,    TURKISH_CHARSET},
  87.     {0,             0,        0}
  88. };
  89. /* This function do a csid to codepage conversion    */
  90. static UINT unicode_CsidToCodePage(int16 csid)
  91. {
  92.     csidcpmap *p;
  93.     for(p = csidcpmaptbl; p->csid != 0 ; p++)
  94.         if(csid == p->csid)
  95.             return p->cp;
  96.     return 0;
  97. }
  98. /* This function do a csid to codepage conversion    */
  99. static BYTE unicode_CsidToCharset(int16 csid)
  100. {
  101.     csidcpmap *p;
  102.     for(p = csidcpmaptbl; p->csid != 0 ; p++)
  103.         if(csid == p->csid)
  104.             return p->charset;
  105.     return 0;
  106. }
  107. /* This function do a csid to codepage conversion    */
  108. static int16 unicode_CharsetToCsid(BYTE charset)
  109. {
  110.     csidcpmap *p;
  111.     for(p = csidcpmaptbl; p->csid != 0 ; p++)
  112.         if(charset == p->charset)
  113.             return p->csid;
  114.     return CS_DEFAULT;
  115. }
  116. /*========================================================================================
  117. //    For Standard Localized Windows
  118. //========================================================================================
  119. */
  120. typedef struct {
  121.     BOOL    found;
  122.     int16    testparam;
  123. } EnumFontTest;
  124.  
  125. static int CALLBACK DetectCharset(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param)
  126. {
  127.     EnumFontTest *pTest = (EnumFontTest *)param;
  128.     if((pTest->testparam & 0x00FF) == lpelf->lfCharSet)
  129.     {
  130.         pTest->found = TRUE;
  131.         return 0;    /* Done */
  132.     }
  133.     else
  134.         return 1;    /* Continue */
  135. }
  136. static BOOL unicode_CheckFontOfCsid(HDC hdc, int16 csid)
  137. {
  138.     EnumFontTest    test;
  139.     test.found = FALSE;
  140.     test.testparam = unicode_CsidToCharset(csid);
  141.     EnumFontFamilies(hdc, NULL,(FONTENUMPROC)DetectCharset, (LPARAM)&test);
  142.     return test.found;
  143. }
  144. #ifdef _WIN32
  145. /*========================================================================================
  146. //    For UnicodeFont
  147. //========================================================================================
  148. */
  149. static BOOL unicode_UnicodeFontOfCodePage(HDC hdc, UINT cp)
  150. {
  151.     /* How can we detect Unicode font that only use those API support in
  152.     // Both Win95 and WinNT ?    
  153.     */
  154.     return FALSE;
  155. }
  156. #endif
  157. /*========================================================================================
  158. //    For NJWIN
  159. //========================================================================================
  160. */
  161. static BOOL unicode_CheckNJWINForCsid(HDC hdc, int16 csid)
  162. {
  163.     /* For NJWIN
  164.     // We should first check wheather njwin.ini is in the system directory
  165.     // It only support System Font    
  166.     */
  167.     return FALSE;
  168. }
  169. /*========================================================================================
  170. //    For TwinBridge
  171. //========================================================================================
  172. */
  173. static int CALLBACK DetectTwinBridge(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param)
  174. {
  175.     EnumFontTest *pTest = (EnumFontTest *)param;
  176.     pTest->found = TRUE;
  177.     return 0;    /* Done    */
  178. }
  179. static BOOL unicode_CheckTwinBridgeForCsid(HDC hdc, int16 csid)
  180. {
  181.     /*    For 4.0 
  182.     // Chinese:
  183.     //     Check for twin40.ini
  184.     //     Check for Font "Chn System"
  185.     // Japanese:
  186.     //     Check for twinj40.ini
  187.     //     Check for Font "Jpn System"
  188.     */
  189.     switch(csid)
  190.     {
  191.         case CS_BIG5:
  192.         case CS_GB_8BIT:
  193.         case CS_SJIS:
  194.         {
  195.             EnumFontTest test;
  196.             test.found = FALSE;
  197.             EnumFontFamilies(hdc, ((csid == CS_SJIS) ? "Jpn System" : "Chn System"),
  198.                                 (FONTENUMPROC)DetectTwinBridge, (LPARAM)&test);
  199.             return test.found;
  200.         }
  201.         case CS_KSC_8BIT:
  202.         default:
  203.             return FALSE;
  204.     }
  205. }
  206. /*========================================================================================
  207. //    For Unionway
  208. //========================================================================================
  209. */
  210. static int CALLBACK DetectUnionway(LOGFONT FAR* lpelf, TEXTMETRIC FAR*lpntm, int FontType, LPARAM param)
  211. {
  212.     int l ;
  213.     EnumFontTest *pTest = (EnumFontTest *)param;
  214.  
  215.     if(lpelf)    {
  216.         char *postfix;
  217.         switch(pTest->testparam)
  218.         {
  219.             case CS_SJIS:
  220.                 postfix = "JDEF";
  221.                 break;
  222.             case CS_BIG5:
  223.                 postfix = "CDEF";
  224.                 break;
  225.             case CS_GB_8BIT:
  226.                 postfix = "PDEF";
  227.                 break;
  228.             case CS_KSC_8BIT:
  229.                 postfix = "UDEF";
  230.                 break;
  231.             default:
  232.                 return 1;
  233.         }
  234.         l = strlen(lpelf->lfFaceName) - strlen(postfix);
  235.         if(l < 0)
  236.             return 1;
  237.         if(strcmp(postfix, lpelf->lfFaceName +  l) == 0)
  238.         {
  239.             pTest->found = TRUE;
  240.             return 0;
  241.         }
  242.     }
  243.     return 1;
  244. }
  245. static BOOL unicode_CheckUnionwayForCsid(HDC hdc,int16 csid)
  246. {
  247.     /*
  248.     // For Uniway, we could use EnumFontFamilies to check font name.
  249.     // xxxUDEF    ? Maybe Korean ?
  250.     // xxxPDEF    Simplified Chinese
  251.     // xxxJDEF    Japanese
  252.     // xxxCDEF    Chinese 
  253.     // Maybe we should first check wheather UWTOOLS.INI or uwfont.ini is
  254.     // in the Windows directory    
  255.     */
  256.     EnumFontTest test;
  257.     test.found = FALSE;
  258.     test.testparam = csid;
  259.     EnumFontFamilies(hdc, NULL,(FONTENUMPROC)DetectUnionway, (LPARAM)&test);
  260.     return test.found;
  261. }
  262.  
  263. BOOL unicode_IsCsidAvailable(HDC hdc, int16 csid)
  264. {
  265.     /* We always sure this three csid is available. */
  266.     if( (csid == CS_LATIN1) || (csid == CS_SYMBOL) || (csid == CS_DINGBATS))
  267.         return TRUE;
  268.     /* Check the charset in font */
  269.     if(unicode_CheckFontOfCsid(hdc, csid))
  270.         return TRUE;
  271.     /* For 32 bit Windows, we check both code page and Unicode font also */
  272. #ifdef _WIN32
  273.     {
  274.         UINT cp = unicode_CsidToCodePage(csid);
  275.         if((cp != 0) && (IsValidCodePage(cp) || unicode_UnicodeFontOfCodePage(hdc, cp)))
  276.             return TRUE;
  277.     }
  278. #endif
  279.     /* For Windows 3.1 and 95, we check those hacking package for Multibyte system */
  280. #ifdef _WIN32
  281.     if((csid & MULTIBYTE) && iswin95() )
  282. #else
  283.     if(csid & MULTIBYTE)
  284. #endif
  285.     {
  286.         if(    unicode_CheckUnionwayForCsid(hdc, csid) ||
  287.             unicode_CheckTwinBridgeForCsid(hdc, csid)    ||
  288.             unicode_CheckNJWINForCsid(hdc, csid))
  289.             return TRUE;
  290.     }
  291.     return FALSE;
  292. }
  293. static BOOL iswin95()
  294. {
  295.     DWORD dwVer;
  296.     int iVer;
  297.     static BOOL initialized = FALSE;
  298.     static BOOL iswin95 = FALSE;
  299.     if(initialized)
  300.         return iswin95;
  301.     // The following code are copy from styles.cpp
  302.     dwVer = GetVersion();
  303.     iVer = (LOBYTE(LOWORD(dwVer))*100) + HIBYTE(LOWORD(dwVer));
  304.     if( iVer >= 395)
  305.         iswin95 = TRUE;
  306.     else
  307.         iswin95 = FALSE;
  308.     initialized = TRUE;
  309.     return iswin95;
  310. }
  311. PR_PUBLIC_API(int) UNICODE_VERIFYCSIDLIST(int inNumOfItem, int16 *csidlist)
  312. {
  313.     int iIn, iOut;
  314.     HDC hdc = CreateIC("DISPLAY", NULL,NULL, NULL);
  315.     if(hdc == NULL)
  316.         return inNumOfItem;
  317.     for(iIn=iOut=0; iIn < inNumOfItem; iIn++)
  318.     {
  319.         if(unicode_IsCsidAvailable(hdc,csidlist[iIn]))
  320.             csidlist[iOut++] = csidlist[iIn];
  321.     }
  322.     DeleteDC(hdc);
  323.     return iOut;
  324. }
  325.  
  326. PR_PUBLIC_API(int16) UNICODE_MENUFONTCSID()
  327. {
  328.     HDC hdc = CreateIC("DISPLAY", NULL,NULL, NULL);
  329.     if(hdc)
  330.     {
  331.         TEXTMETRIC metrics;
  332.         int16 csid;
  333.         SelectObject(hdc, GetStockObject(SYSTEM_FONT));
  334.         GetTextMetrics(hdc, &metrics);
  335.         DeleteDC(hdc);
  336.         csid = unicode_CharsetToCsid(metrics.tmCharSet);
  337.         if(csid != CS_DEFAULT)
  338.             return csid;
  339.     }
  340.     return CS_LATIN1;
  341. }
  342. PR_PUBLIC_API(int) UNICODE_MENUFONTID()
  343. {
  344. #ifdef _WIN32
  345.     if(iswin95())
  346.         return DEFAULT_GUI_FONT;
  347.     else
  348. #endif    /* _WIN32    */
  349.         return    SYSTEM_FONT;
  350. }
  351.  
  352.