home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / intlwin.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  40.3 KB  |  1,349 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.  
  19. #include "stdafx.h"
  20. #include "mainfrm.h"
  21. #include "libi18n.h"
  22. #include "xplocale.h"
  23. #include "cxprint.h"
  24. #include "cxsave.h"
  25.  
  26. #include "np.h"
  27. #include "java.h"
  28. #include "prlog.h"
  29. #include "prlink.h"
  30. #include "xpstrsw.h"
  31.  
  32. #include "cuvfs.h"
  33. #include "intl_csi.h"
  34. #include "edt.h"
  35.  
  36. #include "prefapi.h"
  37. #include "edt.h"
  38.  
  39. #ifdef XP_WIN32
  40. static BOOL intlUnicodeFlag(int16 wincsid);
  41. #define INIT_FLAG_FOR_CSID(c) { CIntlWin::flagTable[(c) & MASK_FLAG_TABLE] = intlUnicodeFlag(c);}
  42. BOOL CIntlWin::flagTable[MAX_FLAG_TABLE_NUM];
  43. #endif // XP_WIN32
  44.  
  45.  
  46. extern int INTL_DocCharSetID(MWContext *context);
  47.  
  48. enum {                            // just to ignore unnecessary strcomp
  49.         javaFontHelvetica = 0,
  50.         javaFontTimesRoman,
  51.         javaFontCourier,
  52.         javaFontDialog,
  53.         javaFontDialogInput,
  54.         javaFontZapfDingbats
  55. };
  56.  
  57. extern "C" {
  58.     const char* IntlGetJavaFaceName(int csid, int javaFontID);
  59.     BYTE IntlGetJavaCharset(int csid, int javaFontID);
  60.     jref *intl_makeJavaString(int16 encoding, char *str, int len);
  61.  
  62. };
  63.  
  64. extern "C" {
  65. PR_PUBLIC_API(BOOL ) CINTLWIN_TEXTOUT_E(int16 wincsid, HDC hdc, int nXStart, int nYStart, LPCSTR  lpString,int  iLength);
  66. PR_PUBLIC_API(BOOL ) CINTLWIN_GETTEXTEXTENTPOINT_E(int wincsid, HDC hDC, LPCSTR lpString, int cbString, LPSIZE lpSize);
  67.  
  68. PR_PUBLIC_API(const char*) INTLGETJAVAFACENAME_E(int csid, int javaFontID);
  69. PR_PUBLIC_API(BYTE ) INTLGETJAVACHARSET_E(int csid, int javaFontID);
  70.  
  71. #ifdef JAVA
  72. PR_PUBLIC_API(jref* ) INTL_MAKEJAVASTRING_E(int16 encoding, char *str, int len);
  73. #endif    // JAVA
  74.  
  75. PR_PUBLIC_API(int16* ) INTL_GETUNICODECSIDLIST_E(int16 * outnum);
  76. PR_PUBLIC_API(int32 ) INTL_UNICODELEN_E(uint16* ustr);
  77. PR_PUBLIC_API(INTL_CompoundStr* ) INTL_COMPOUNDSTRFROMUNICODE_E(uint16* inunicode, uint32 inlen);
  78. PR_PUBLIC_API(void ) INTL_COMPOUNDSTRDESTROY_E(INTL_CompoundStr* This);
  79. PR_PUBLIC_API(INTL_CompoundStrIterator ) INTL_COMPOUNDSTRFIRSTSTR_E(INTL_CompoundStr* This, INTL_Encoding_ID *outencoding, unsigned char** outtext);
  80. PR_PUBLIC_API(INTL_CompoundStrIterator ) INTL_COMPOUNDSTRNEXTSTR_E(INTL_CompoundStrIterator iterator, INTL_Encoding_ID *outencoding, unsigned char** outtext);
  81. PR_PUBLIC_API(INTL_CompoundStr* ) INTL_COMPOUNDSTRCLONE_E(INTL_CompoundStr* s1);
  82. PR_PUBLIC_API(int16 ) INTL_DEFAULTWINCHARSETID_E(MWContext *context);
  83. PR_PUBLIC_API(int32 ) INTL_TEXTBYTECOUNTTOCHARLEN_E(int16 csid, unsigned char* text, uint32 byteCount);
  84. PR_PUBLIC_API(int32 ) INTL_TEXTCHARLENTOBYTECOUNT_E(int16 csid, unsigned char* text, uint32 charLen);
  85. PR_PUBLIC_API(uint32 ) INTL_UNICODETOSTRLEN_E(INTL_Encoding_ID encoding,INTL_Unicode* ustr, uint32    ustrlen);
  86. PR_PUBLIC_API(void ) INTL_UNICODETOSTR_E(INTL_Encoding_ID encoding,INTL_Unicode* ustr,uint32 ustrlen,unsigned char* dest, uint32 destbuflen);
  87. };
  88.  
  89. //
  90. //    Data type use for Unicode table loader
  91. //
  92. #define MAXUTABLENAME    16
  93. typedef struct tblrsrcinfo {
  94.     char    name[MAXUTABLENAME];
  95.     uint16    refcount;
  96.     HGLOBAL hTbl;
  97. } tblrsrcinfo;
  98.  
  99. typedef struct utablename {
  100.     uint16        csid;
  101.     tblrsrcinfo    frominfo;
  102.     tblrsrcinfo toinfo;
  103.  
  104. } utablename;
  105. //
  106. //    The following are private 
  107. //
  108. static void intl_WriteUnicodeConvList(int num_of_csid, int16* csidlist);
  109. static void intl_ReadUnicodeConvList();
  110. static void    intl_UnloadUCS2Table(uint16 csid, void *utblPtr, int from);
  111. static tblrsrcinfo* intl_FindUTableName(uint16 csid, int from);
  112. static void *intl_LoadUCS2Table(uint16 csid, int from);
  113. static void    intl_UnloadUCS2Table(uint16 csid, void *utblPtr, int from);
  114.  
  115.  
  116. // This structure is used for following table for default font value,
  117. // It'll be removed after default value goes to resource file.
  118. struct FontCharTable
  119. {
  120.      int16 csid;
  121.     char  szPropFont[LF_FACESIZE] ;
  122.     int   iPropSize ;
  123.     char  szFixFont[LF_FACESIZE] ;
  124.     int   iFixSize ;
  125.     int   iPropCharset;
  126.     int   iFixCharset;
  127. };
  128.  
  129. // Note: always add new comer to last line.
  130. struct FontCharTable  fontchar_tbl[] =
  131. {
  132.     CS_LATIN1,     DEF_PROPORTIONAL_FONT,     12, DEF_FIXED_FONT, 10, ANSI_CHARSET, ANSI_CHARSET,
  133.     CS_SJIS,      "élér û╛Æ⌐",             10, "élér û╛Æ⌐",     10, SHIFTJIS_CHARSET,    SHIFTJIS_CHARSET,
  134.     CS_BIG5,     "Times New Roman",         12, "Courier New",  10, CHINESEBIG5_CHARSET, CHINESEBIG5_CHARSET,
  135.     CS_KSC_8BIT,"Times New Roman",         12, "Courier New",  10, HANGEUL_CHARSET,     HANGEUL_CHARSET,
  136.     CS_GB_8BIT, "Times New Roman",         12, "Courier New",  10, 134, 134,
  137.     CS_CP_1250, "Times New Roman",         12, "Courier New",  10, 238,238,  
  138.     CS_CP_1251, "Times New Roman",         12, "Courier New",  10, 204,204,  
  139.     CS_CP_1253, "Times New Roman",         12, "Courier New",  10, 161,161,  
  140.     CS_8859_9, "Times New Roman",         12, "Courier New",  10, 162,162,  
  141.     CS_UTF8,     DEF_PROPORTIONAL_FONT,     12, DEF_FIXED_FONT, 10, DEFAULT_CHARSET, DEFAULT_CHARSET,
  142.     CS_USER_DEFINED_ENCODING,     DEF_PROPORTIONAL_FONT,     12, DEF_FIXED_FONT, 10, ANSI_CHARSET, ANSI_CHARSET,
  143.     0,            "",                     0,     "",             0,   0, 0
  144. } ;
  145.  
  146. // This table defined how many encoding we supports in our Navigator and 
  147. // what kind of conversion we support for each encoding.
  148. // Note: always add new comer to last line.
  149. //     Encoding, Encoding used for Display, supported CSID list, 0
  150.  
  151. unsigned int lang_table[] = 
  152. {
  153.     IDS_LANGUAGE_LATIN1, CS_LATIN1, CS_LATIN1, 0,
  154.     IDS_LANGUAGE_LATIN2, CS_CP_1250, CS_CP_1250, CS_LATIN2, 0,
  155.     IDS_LANGUAGE_JAPANESE, CS_SJIS, CS_AUTO | CS_SJIS, CS_SJIS, CS_JIS, CS_EUCJP, 0,
  156.     IDS_LANGUAGE_TAIWANESE, CS_BIG5, CS_BIG5, CS_CNS_8BIT, 0,
  157.     IDS_LANGUAGE_CHINESE, CS_GB_8BIT, CS_GB_8BIT, 0,
  158.     IDS_LANGUAGE_KOREAN, CS_KSC_8BIT, CS_KSC_8BIT | CS_AUTO, CS_KSC_8BIT, CS_2022_KR, 0,
  159.     IDS_LANGUAGE_WIN1251, CS_CP_1251, CS_CP_1251, CS_8859_5, CS_KOI8_R, 0,
  160.     IDS_LANGUAGE_GREEK, CS_CP_1253, CS_CP_1253, CS_8859_7, 0,
  161.     IDS_LANGUAGE_TURKISH, CS_8859_9, CS_8859_9, 0,
  162.     IDS_LANGUAGE_UTF8, CS_UTF8, CS_UTF8, CS_UTF7, CS_UCS2, CS_UCS2_SWAP, 0,
  163.     IDS_LANGUAGE_USERDEFINED, CS_USER_DEFINED_ENCODING, CS_USER_DEFINED_ENCODING, 0,
  164.     UINT_MAX
  165. };
  166.  
  167. CIntlFont::CIntlFont()
  168. {
  169.     CString fontList;
  170.     LPSTR lpszPropName = NULL;
  171.     LPSTR lpszFixName = NULL;
  172.     int32    iPropSize, iFixSize ;
  173.     int    iPropCharset, iFixCharset;
  174.     BOOL   ret = FALSE;
  175.     int        i ;
  176.     int        nLang ;
  177.     EncodingInfo *pEncoding;
  178.  
  179.     iPropCharset = iFixCharset = 0;
  180.  
  181. #ifdef XP_WIN32
  182.     for(int j = 0; j < MAX_FLAG_TABLE_NUM; j++)
  183.         INIT_FLAG_FOR_CSID(j);
  184. #endif
  185.  
  186.     pEncodingInfoTbl =  (struct EncodingInfo *) malloc( (MAXLANGNUM + 1) * sizeof (struct EncodingInfo) ) ;
  187.  
  188.     if (pEncodingInfoTbl == NULL)
  189.     {
  190.         TRACE("No memory for MultiLingual support.\n");
  191.         return ;
  192.     }
  193.  
  194.  
  195.     memset(pEncodingInfoTbl, 0, (MAXLANGNUM + 1) * sizeof(struct EncodingInfo));
  196.  
  197.     nLang = 0;
  198.     pEncoding = pEncodingInfoTbl;
  199.     for (i = 0; (lang_table[i] != UINT_MAX) && (nLang < MAXLANGNUM); i++)
  200.     {
  201.         pEncoding->iLangResId = lang_table[i++];
  202.         pEncoding->iCSID = lang_table[i++];
  203.  
  204.         // Setup default font information.
  205.         for (int j = 0; j < MAXLANGNUM; j++)
  206.         {
  207.             if (fontchar_tbl[j].csid == pEncoding->iCSID)
  208.             {
  209.                 // First, lets try to copy from the hard coded table
  210.                 strcpy(pEncoding->szPropName, fontchar_tbl[j].szPropFont);
  211.                 pEncoding->iPropSize = fontchar_tbl[j].iPropSize;
  212.                 strcpy(pEncoding->szFixName, fontchar_tbl[j].szFixFont);
  213.                 pEncoding->iFixSize = fontchar_tbl[j].iFixSize;
  214.                 pEncoding->iPropCharset = fontchar_tbl[j].iPropCharset;
  215.                 pEncoding->iFixCharset = fontchar_tbl[j].iFixCharset;
  216.             }
  217.         }
  218.  
  219.         char key[80];
  220.         // Now, let's try to get it from the PREF
  221.         sprintf(key, "intl.font%d.win.prop_font",    pEncoding->iCSID);
  222.         lpszPropName = NULL;
  223.         if( PREF_NOERROR == PREF_CopyCharPref(key,    &lpszPropName))
  224.         {
  225.             strcpy(pEncoding->szPropName, lpszPropName);
  226.             XP_FREE(lpszPropName);
  227.         }
  228.         sprintf(key, "intl.font%d.win.fixed_font",    pEncoding->iCSID);
  229.         lpszFixName = NULL;
  230.         if( PREF_NOERROR ==  PREF_CopyCharPref(key, &lpszFixName))
  231.         {
  232.             strcpy(pEncoding->szFixName, lpszFixName);
  233.             XP_FREE(lpszFixName);
  234.         }
  235.  
  236.         sprintf(key, "intl.font%d.win.prop_size",    pEncoding->iCSID);
  237.         if(  PREF_NOERROR == PREF_GetIntPref(key,    &iPropSize))
  238.             pEncoding->iPropSize = (int)iPropSize;
  239.  
  240.         sprintf(key, "intl.font%d.win.fixed_size",    pEncoding->iCSID);
  241.         if(  PREF_NOERROR == PREF_GetIntPref(key,    &iFixSize))
  242.             pEncoding->iFixSize = (int)iFixSize;
  243.  
  244.         // Setup supported CSID list
  245.         for (j =0; lang_table[i]; j++)
  246.         {
  247.             pEncoding->csid[j] = lang_table[i++] ;
  248. #ifdef XP_WIN32
  249.             INIT_FLAG_FOR_CSID(pEncoding->csid[j]);
  250. #endif
  251.         }
  252.  
  253.         pEncoding->nCodeset = j;
  254.  
  255.         nLang ++ ;
  256.         pEncoding ++ ;
  257.  
  258.     }
  259.  
  260.     nEncoding = MAXLANGNUM;
  261.     intl_ReadUnicodeConvList();
  262. }
  263.  
  264. EncodingInfo * CIntlFont::GetEncodingInfo(int id)
  265. {
  266.  
  267.     if (id < nEncoding)
  268.         return &pEncodingInfoTbl[id];
  269.     else
  270.         return NULL;
  271. }
  272.  
  273. EncodingInfo * CIntlFont::GetEncodingInfo(MWContext *pContext)
  274. {
  275.     int doc_csid, id;
  276.     doc_csid = INTL_DocCharSetID(pContext)    & ~CS_AUTO ;
  277.     id = DocCSIDtoID(doc_csid);
  278.  
  279.     return GetEncodingInfo(id);
  280. }
  281.  
  282. int16 IntlCharsetToCsid(BYTE charset)
  283. {
  284.     int i;
  285.  
  286.     for (i = 0; i < MAXLANGNUM; i++)
  287.     {
  288.         EncodingInfo *pEncoding = theApp.m_pIntlFont->GetEncodingInfo(i);
  289.          if (charset == pEncoding->iPropCharset)
  290.             return (pEncoding->iCSID & ~CS_AUTO);
  291.     }
  292.     return CS_LATIN1;
  293. }
  294.  
  295. int CIntlFont::DocCSIDtoID(int doc_csid)
  296. {
  297.     int i, j;
  298.     EncodingInfo  *pEncoding ;
  299.  
  300.     pEncoding = &pEncodingInfoTbl[0];
  301.  
  302.     for (i = 0; i < nEncoding; i++)
  303.     {
  304.         for (j = 0; j < pEncoding->nCodeset; j++)
  305.         {
  306.              if (doc_csid == pEncoding->csid[j])
  307.             {
  308.                 return i ;
  309.             }
  310.         }
  311.         pEncoding ++ ;
  312.     }
  313.     // Note!!!:  return 0 here is not good idea, but it can avoid crash.
  314.     //           need to revisit this code later.
  315.     return 0;
  316. }
  317.  
  318. char * CIntlFont::GetEncodingName(int id)
  319. {
  320.     if (id < nEncoding)
  321.         return szLoadString(pEncodingInfoTbl[id].iLangResId);
  322.     else    // Never should come here
  323.         return "Unknown";
  324. }
  325.  
  326. void  CIntlFont::WriteToIniFile()
  327. {
  328.     EncodingInfo *pEncoding;
  329.     pEncoding = &pEncodingInfoTbl[0];
  330.     for (int i = 0; i < MAXLANGNUM; i++)
  331.     {
  332.         char key[80];
  333.  
  334.         sprintf(key, "intl.font%d.win.prop_font",    pEncoding->iCSID);
  335.         PREF_SetCharPref(key,    pEncoding->szPropName);
  336.  
  337.         sprintf(key, "intl.font%d.win.fixed_font",    pEncoding->iCSID);
  338.         PREF_SetCharPref(key,    pEncoding->szFixName);
  339.  
  340.         sprintf(key, "intl.font%d.win.prop_size",    pEncoding->iCSID);
  341.         PREF_SetIntPref(key,    (int32)pEncoding->iPropSize);
  342.  
  343.         sprintf(key, "intl.font%d.win.fixed_size",    pEncoding->iCSID);
  344.         PREF_SetIntPref(key,    (int32)pEncoding->iFixSize);
  345.  
  346.         pEncoding ++ ;
  347.     }
  348. }
  349.  
  350.  
  351. BYTE IntlGetLfCharset(int csid)
  352. {
  353.     int id;
  354.     if (csid == 0)
  355.         csid = INTL_DefaultWinCharSetID(0);
  356.     csid = csid & ~CS_AUTO;  // mask off AUTO bit
  357.  
  358.     if (csid == 0 || csid == CS_LATIN1 || csid == CS_UNKNOWN)
  359.         return ANSI_CHARSET;
  360.  
  361.     id = theApp.m_pIntlFont->DocCSIDtoID(csid);
  362.     EncodingInfo *pEncoding = theApp.m_pIntlFont->GetEncodingInfo(id);
  363.     return pEncoding->iPropCharset;
  364. }
  365.  
  366. const char *IntlGetUIFixFaceName(int csid)
  367. {
  368.     int id ;
  369.     if (csid == 0)
  370.         csid = INTL_DefaultWinCharSetID(0);
  371.     csid = csid & ~CS_AUTO;  // mask off AUTO bit
  372.  
  373.     id = theApp.m_pIntlFont->DocCSIDtoID(csid);
  374.     EncodingInfo *pEncoding = theApp.m_pIntlFont->GetEncodingInfo(id);
  375.     return pEncoding->szFixName;
  376. }
  377.  
  378. const char *IntlGetUIPropFaceName(int csid)
  379. {
  380.     int id ;
  381.     if (csid == 0)
  382.         csid = INTL_DefaultWinCharSetID(0);
  383.     csid = csid & ~CS_AUTO;  // mask off AUTO bit
  384.  
  385.     id = theApp.m_pIntlFont->DocCSIDtoID(csid);
  386.     EncodingInfo *pEncoding = theApp.m_pIntlFont->GetEncodingInfo(id);
  387.     return pEncoding->szPropName;
  388. }
  389.  
  390.  
  391. //------------------------------------------------------------
  392. //  Function called from cross-platform code
  393. //------------------------------------------------------------
  394. extern "C" int FE_StrColl(const char* s1, const char* s2)
  395. {
  396.     return    lstrcmp(s1, s2);
  397. }
  398.  
  399. extern "C" size_t FE_StrfTime(MWContext *context, char *result, size_t maxsize, int format,
  400.     const struct tm *timeptr)
  401. {
  402. #ifdef XP_WIN16
  403.     switch(format)
  404.     {
  405.     case XP_TIME_FORMAT:
  406.         return strftime (result, maxsize, "%H:%M", timeptr);
  407.     case XP_WEEKDAY_TIME_FORMAT:
  408.         return strftime (result, maxsize, "%a %H:%M", timeptr);
  409.     case XP_DATE_TIME_FORMAT:
  410.         return strftime (result, maxsize, "%x %H:%M", timeptr);
  411.     case XP_LONG_DATE_TIME_FORMAT:
  412.         return strftime (result, maxsize, "%c", timeptr);
  413.     default:
  414.         result[0] = '\0';
  415.         return 0;
  416.     }
  417. #else
  418.     int wincsid = INTL_DefaultWinCharSetID(context);
  419.     LANGID langid;
  420.     langid = GetSystemDefaultLangID();
  421.  
  422.     if ((wincsid & MULTIBYTE) &&
  423.          sysInfo.m_bDBCS &&
  424.          !((GetSystemDefaultLangID() == 0x0411  &&  wincsid == CS_SJIS) ||
  425.            (GetSystemDefaultLangID() == 0x0412 && wincsid == CS_KSC_8BIT) ||
  426.            (GetSystemDefaultLangID() == 0x0812 && wincsid == CS_KSC_8BIT) ||
  427.            (GetSystemDefaultLangID() == 0x0804 && wincsid == CS_GB_8BIT) ||
  428.            (GetSystemDefaultLangID() == 0x1004 && wincsid == CS_GB_8BIT) ||
  429.            (GetSystemDefaultLangID() == 0x0C04 && wincsid == CS_BIG5) ||
  430.            (GetSystemDefaultLangID() == 0x0404 && wincsid == CS_BIG5)))
  431.     {                // In multibyte, if system doesn't match with current win_csid
  432.         switch(format)
  433.         {
  434.         case XP_TIME_FORMAT:
  435.             return strftime (result, maxsize, "%H:%M", timeptr);
  436.         case XP_WEEKDAY_TIME_FORMAT:
  437.             return strftime (result, maxsize, "%a %H:%M", timeptr);
  438.         case XP_DATE_TIME_FORMAT:
  439.             return strftime (result, maxsize, "%x %H:%M", timeptr);
  440.         case XP_LONG_DATE_TIME_FORMAT:
  441.             return strftime (result, maxsize, "%c", timeptr);
  442.         default:
  443.             result[0] = '\0';
  444.             return 0;
  445.         }
  446.     }
  447.     else
  448.     {
  449.         SYSTEMTIME daytime;
  450.         int n, m;
  451.         daytime.wYear = 1900 + timeptr->tm_year;
  452.         daytime.wMonth = timeptr->tm_mon + 1;
  453.         daytime.wDayOfWeek = timeptr->tm_wday;
  454.         daytime.wDay = timeptr->tm_mday;
  455.         daytime.wHour = timeptr->tm_hour;
  456.         daytime.wMinute = timeptr->tm_min;
  457.         daytime.wSecond = timeptr->tm_sec;
  458.         daytime.wMilliseconds = 0;
  459.  
  460.         *result = '\0';
  461.  
  462.  
  463.         switch(format)
  464.         {
  465.         case XP_TIME_FORMAT:
  466.             // return strftime (result, maxsize, "%X", timeptr);
  467.             if (n = GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOSECONDS | TIME_NOTIMEMARKER, &daytime, NULL, result, maxsize))
  468.                 return n;
  469.             else
  470.                 return strftime (result, maxsize, "%H:%M", timeptr);
  471.         case XP_WEEKDAY_TIME_FORMAT:
  472.             // return strftime (result, maxsize, "%a %X", timeptr);
  473.             if (GetDateFormat(LOCALE_SYSTEM_DEFAULT,0,&daytime,"ddd ", result, maxsize))
  474.             {
  475.                 n = strlen(result);
  476.                 if (m = GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOSECONDS | TIME_NOTIMEMARKER, &daytime, NULL, result+n, maxsize-n))
  477.                     return n + m;
  478.                 else
  479.                     return strftime (result, maxsize, "%a %H:%M", timeptr);
  480.             }
  481.             else
  482.                 return strftime (result, maxsize, "%a %H:%M", timeptr);
  483.         case XP_DATE_TIME_FORMAT:
  484.             // return strftime (result, maxsize, "%x %X", timeptr);
  485.             if (GetDateFormat(LOCALE_SYSTEM_DEFAULT,DATE_SHORTDATE, &daytime,NULL, result, maxsize))
  486.             {
  487.                 n = strlen(result);
  488.                 result[n++] = ' ';
  489.                 if (m = GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOSECONDS | TIME_NOTIMEMARKER, &daytime, NULL, result+n, maxsize-n))
  490.                     return m + n;
  491.                 else
  492.                     return strftime (result, maxsize, "%x %H:%M", timeptr);
  493.             }
  494.             else
  495.                 return strftime (result, maxsize, "%x %H:%M", timeptr);
  496.         case XP_LONG_DATE_TIME_FORMAT:
  497.             // return strftime (result, maxsize, "%x %X", timeptr);
  498.             if (GetDateFormat(LOCALE_SYSTEM_DEFAULT,DATE_LONGDATE, &daytime,NULL, result, maxsize))
  499.             {
  500.                 n = strlen(result);
  501.                 result[n++] = ' ';
  502.                 if (m = GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_FORCE24HOURFORMAT | TIME_NOTIMEMARKER, &daytime, NULL, result+n, maxsize-n))
  503.                     return m + n;
  504.                 else
  505.                     return strftime (result, maxsize, "%x %H:%M", timeptr);
  506.             }
  507.             else
  508.                 return strftime (result, maxsize, "%x %H:%M", timeptr);
  509.         default:
  510.             result[0] = '\0';
  511.             return 0;
  512.         }
  513.     }
  514. #endif
  515. }
  516.  
  517.  
  518. CXPResSwitcher g_xpResSwitcher; 
  519.  
  520. /* XP_GetString
  521.  *
  522.  * This one takes XP string ID (which is used mainly by libnet, libsec) 
  523.  * and loads String from resource file (netscape.rc3).
  524.  */
  525. extern "C" char *XP_GetString(int id)
  526. {
  527.     int16  resid;
  528.     resid = id + 7000;
  529.  
  530.      char *buf = szLoadString(resid, &g_xpResSwitcher);
  531.     return buf;
  532.  
  533. }
  534.  
  535. /*
  536.   INTL_DocCharSetID and INTL_DefaultDocCharSetID getting closer and closer
  537.   For 2.1, we need to remove one of them.
  538. */
  539. int INTL_DocCharSetID(MWContext *context)
  540. {
  541.     int doccsid;
  542.     if (context == NULL)
  543.         return theApp.m_iCSID;
  544.     else if (doccsid = INTL_GetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context)))
  545.         return doccsid;
  546.     else if (context->type == MWContextPrint && ((CPrintCX *)((context)->fe.cx))->m_iCSID)
  547.         return ((CPrintCX *)((context)->fe.cx))->m_iCSID;
  548.     else if (GetFrame(context) && GetFrame(context)->m_iCSID)
  549.         return GetFrame(context)->m_iCSID;
  550.     else
  551.         return theApp.m_iCSID;
  552. }
  553.  
  554. /*
  555.  This routine will retrieve default URL charset Id
  556.  from conversion engine.
  557. */
  558. extern int16 INTL_DefaultDocCharSetID(MWContext * context)
  559. {
  560.     int doccsid;
  561.     if (context == NULL)
  562.         return theApp.m_iCSID;
  563.     else if (doccsid = INTL_GetCSIDocCSID(LO_GetDocumentCharacterSetInfo(context)))
  564.         return doccsid;
  565.     else if (context->type == MWContextPrint && ((CPrintCX *)((context)->fe.cx))->m_iCSID)
  566.         return ((CPrintCX *)((context)->fe.cx))->m_iCSID;
  567.     else if (context->type == MWContextSaveToDisk && ((CSaveCX*)((context)->fe.cx))->m_iCSID)
  568.         return ((CSaveCX *)((context)->fe.cx))->m_iCSID;
  569.     else  if (GetFrame(context) && ((CMainFrame *)GetFrame(context))->m_iCSID)
  570.         return  ((CMainFrame *)GetFrame(context))->m_iCSID;
  571.     else
  572.         return theApp.m_iCSID;
  573. }
  574.  
  575. extern "C" uint16 FE_DefaultDocCharSetID(MWContext * context)
  576. {
  577.     if (context == NULL)
  578.         return theApp.m_iCSID;
  579.     else if (context->type == MWContextPrint && ((CPrintCX *)((context)->fe.cx))->m_iCSID)
  580.         return ((CPrintCX *)((context)->fe.cx))->m_iCSID;
  581.     else if (context->type == MWContextSaveToDisk && ((CSaveCX*)((context)->fe.cx))->m_iCSID)
  582.         return ((CSaveCX *)((context)->fe.cx))->m_iCSID;
  583.     else if (GetFrame(context) && ((CMainFrame *)GetFrame(context))->m_iCSID)
  584.         return  ((CMainFrame *)GetFrame(context))->m_iCSID;
  585.     else
  586.         return theApp.m_iCSID;
  587. }
  588.  
  589. /*
  590.  This routine will relayout current document.
  591.  It's called from xp rountine to do CharSet conversion
  592.  based on new doc_csid found from <Meta ...> 
  593. */
  594. extern void INTL_Relayout(MWContext * pContext)
  595. {
  596.     if(pContext == NULL || ABSTRACTCX(pContext) == NULL || ABSTRACTCX(pContext)->IsDestroyed())    {
  597.         //    Don't allow this to happen if the context has been destroyed...
  598.         return;
  599.     }
  600.  
  601.     //  Let the page load, so that it is in the cache (bug fix 51701)
  602.     //      or will get a page that is partially "transfer interrupted"
  603.     //      if just doing a Reload() as that part of the page is
  604.     //      possibly already cached before the entire page is downloaded
  605.     //      leading to lossy display.
  606.     //  Another way to do this is to ignore the cache altogether for a
  607.     //      more immediate effect:  Reload(NET_SUPER_RELOAD)
  608.     //      but that is not nice to the cache, or the user if working
  609.     //      offline, etc.
  610. #ifdef EDITOR
  611.     if(EDT_IS_EDITOR(pContext)){
  612.         EDT_RefreshLayout(pContext);
  613.     } else
  614. #endif
  615.         ABSTRACTCX(pContext)->NiceReload();
  616. }
  617.  
  618.  
  619. /*
  620. See information in
  621. Unicode Functions Supported by Windows 95
  622. PSS ID Number: Q125671
  623. */
  624. int CIntlWin::m_iConvBufSize = 0;
  625. #ifdef XP_WIN32
  626. LPWSTR CIntlWin::m_wConvBuf = NULL;
  627. #endif
  628.  
  629. BOOL CIntlWin::FontSelectIgnorePitch(int16 wincsid)
  630. {
  631.     return ( (wincsid & MULTIBYTE)    
  632.         );
  633. }
  634. BOOL CIntlWin::FontSelectIgnoreCharset(int16 wincsid)
  635. {
  636.     return (  UseUnicodeFontAPI(wincsid)  || 
  637.           ( CS_USER_DEFINED_ENCODING == wincsid)
  638.         );
  639. }
  640. BOOL CIntlWin::AllocConvBuffer(int iLength)
  641. {
  642. #ifdef WIN32
  643.     if (m_iConvBufSize == 0)
  644.     {
  645.         if (iLength < 1024)
  646.             iLength = 1024;
  647.         m_wConvBuf = (WCHAR *)malloc(iLength);
  648.         m_iConvBufSize = iLength;
  649.     }
  650.     else
  651.     {
  652.         m_wConvBuf = (WCHAR *) realloc(m_wConvBuf, iLength);
  653.         m_iConvBufSize = iLength;
  654.     }
  655. #endif
  656.     return TRUE;
  657. }
  658.  
  659. int16 CIntlWin::m_system_locale_csid = 0;
  660.  
  661. int16 CIntlWin::GetSystemLocaleCsid()
  662. {
  663.     if( 0 == m_system_locale_csid )
  664.     {
  665. #ifdef XP_WIN32
  666.         m_system_locale_csid = CodePageToCsid(GetACP());
  667. #else
  668.         m_system_locale_csid = CodePageToCsid(GetKBCodePage()); // In Win3.1 We cannot call GetACP(), we can just call GetKBCodePage()
  669. #endif
  670.     }
  671.     if( 0 == m_system_locale_csid )    // if still cannot find the csid, Fall back to Latin 1
  672.     {
  673.         m_system_locale_csid = CS_LATIN1;
  674.     }
  675.     return m_system_locale_csid;
  676. }
  677. int16 CIntlWin::CodePageToCsid(UINT cp)
  678. {
  679.     switch(cp)
  680.     {
  681.     case 1250:
  682.     case 852:    // MS-DOS Slavic OEM in the case of Win16 GetKBCodePage 
  683.         return CS_CP_1250;
  684.  
  685.     case 1251:
  686.     case 855:    // IBM Cyrillic OEM in the case of Win16 GetKBCodePage 
  687.     case 866:    // MS-DOS Russian OEM in the case of Win16 GetKBCodePage 
  688.         return CS_CP_1251;
  689.  
  690.     case 1252:
  691.     case 437:    // US OEM in the case of Win16 GetKBCodePage 
  692.     case 850:    // MS-DOS Multilingual OEM in the case of Win16 GetKBCodePage 
  693.     case 860:    // MS-DOS Portutuese OEM in the case of Win16 GetKBCodePage 
  694.     case 861:    // MS-DOS Icelandic OEM in the case of Win16 GetKBCodePage 
  695.     case 863:    // MS-DOS Canadian-French OEM in the case of Win16 GetKBCodePage 
  696.     case 865:    // MS-DOS Nordic OEM in the case of Win16 GetKBCodePage 
  697.         return CS_LATIN1;
  698.  
  699.     case 1253:
  700.     case 737:    // Greek OEM in the case of Win16 GetKBCodePage 
  701.     case 869:    // IBM Modern Greek OEM in the case of Win16 GetKBCodePage 
  702.         return CS_CP_1253;
  703.  
  704.     case 1254:
  705.     case 857:    // IBM Turkish OEM in the case of Win16 GetKBCodePage 
  706.         return CS_CP_1254; // CS_CP_1254;
  707.  
  708.     case 1255:
  709.         return CS_UNKNOWN; // CS_CP_1255;
  710.  
  711.     case 1256:
  712.         return CS_UNKNOWN; // CS_CP_1256;
  713.  
  714.     case 775:    // Baltic OEM in the case of Win16 GetKBCodePage 
  715.     case 1257:
  716.         return CS_UNKNOWN; // CS_CP_1257;
  717.  
  718.     case 932:
  719.         return CS_SJIS;
  720.  
  721.     case 936:
  722.         return CS_GB_8BIT;
  723.  
  724.     case 949:
  725.     case 1361:    // Korean (Johab) OEM in the case of Win16 GetKBCodePage 
  726.         return CS_KSC_8BIT;
  727.  
  728.     case 950:
  729.         return CS_BIG5;
  730.  
  731.     default:
  732.         return CS_UNKNOWN;
  733.     }
  734. }
  735. int CIntlWin::MultiByteToWideChar(int16 wincsid, LPCSTR lpMultiByte, int iLength)
  736. {
  737.     if((lpMultiByte == NULL) || (lpMultiByte[0] == '\0') || (iLength == 0))
  738.         return 0;
  739. #ifdef WIN32
  740.     if (iLength == -1)
  741.         iLength = strlen(lpMultiByte);
  742.     if (((iLength+1) * 2) > m_iConvBufSize)
  743.         AllocConvBuffer((iLength+1) * 2);
  744.  
  745.     iLength = INTL_TextToUnicode(wincsid, (unsigned char*)lpMultiByte, iLength,  m_wConvBuf, m_iConvBufSize) ;
  746. #endif
  747.     return iLength;
  748. }
  749. //
  750. //    UseUnicodeFontAPI return
  751. //
  752. //    csid        Latin1/Symbol/        UTF8    MultiByte    Other Single Byte        
  753. //                UserDefined/Digbats            J/K/SC/TC    CE/Greek/Cyr/Turk    
  754. //    Platform
  755. //    Win 95 NonDB     FALSE            TRUE    TRUE        FALSE (Need test)
  756. //    Win NT NonDB     FALSE            TRUE    TRUE        TRUE  (Need test)
  757. //    Win 95 DB        FALSE            TRUE    (1)         FALSE
  758. //    Win NT DB        FALSE            TRUE    (1)            TRUE(2)
  759. //
  760. //    (1) FALSE if it is equal to the system locale's csid.
  761. //    (2) Could be true or false. But need more work for Edit control if use TRUE
  762. //
  763. #ifdef XP_WIN32
  764. static BOOL intlUnicodeFlag(int16 wincsid)
  765. {
  766.     if(! theApp.m_bUseUnicodeFont)
  767.         return FALSE;
  768.  
  769.     if(0 == wincsid)    // Unknown csid
  770.         return FALSE;
  771.  
  772.     if(CS_UTF8 == wincsid)
  773.         return TRUE;
  774.  
  775.     if(    (CS_LATIN1 == wincsid) ||    (CS_SYMBOL == wincsid) ||
  776.         (CS_DINGBATS == wincsid) ||    (CS_USER_DEFINED_ENCODING == wincsid)) 
  777.     {
  778.         return FALSE;
  779.     }
  780.  
  781.     if( wincsid & MULTIBYTE)
  782.     {
  783.         if(CIntlWin::GetSystemLocaleCsid() == wincsid)
  784.             return FALSE;
  785.         else
  786.             return TRUE;
  787.     }
  788.     else    // Other SingleByte csid
  789.     {
  790.         if(sysInfo.m_bWinNT)
  791.             return TRUE;
  792.         else
  793.             return FALSE;
  794.     }
  795. }
  796. #endif
  797.  
  798.  
  799. BOOL CIntlWin::UseVirtualFont()
  800. {
  801.     return theApp.m_bUseVirtualFont; 
  802. }
  803. BOOL CIntlWin::GetTextExtentPoint(int wincsid, HDC hDC, LPCSTR pString, int iLength, LPSIZE lpSize)
  804. {
  805.     if(0 == iLength)
  806.     {
  807.         lpSize->cx = 0;
  808.         lpSize->cy = 0;
  809.         return TRUE;
  810.     }
  811.     wincsid = INTL_DocToWinCharSetID(wincsid) & ~ CS_AUTO;
  812. #ifdef XP_WIN32
  813.     int wlen;
  814.  
  815.     if ( CIntlWin::UseUnicodeFontAPI(wincsid))
  816.     {
  817.         // Handle UTF8 by using multifont
  818.         if((wincsid == CS_UTF8) && CIntlWin::UseVirtualFont())
  819.         {
  820.             return CIntlUnicodeVirtualFontStrategy::GetTextExtentPoint(hDC, pString, iLength, lpSize );
  821.         }
  822.  
  823.         if(wlen = MultiByteToWideChar(wincsid, pString, iLength))
  824.         {
  825.             return  ::GetTextExtentPoint32W(hDC, m_wConvBuf, wlen, lpSize);
  826.         }
  827.     }
  828. #endif    // XP_WIN32
  829.     if(wincsid == CS_UTF8)
  830.     {
  831.         return CIntlUnicodeVirtualFontStrategy::GetTextExtentPoint(hDC, pString, iLength, lpSize );
  832.     } 
  833.  
  834. #ifdef XP_WIN32    // The final fallback
  835.     return::GetTextExtentPoint32(hDC, pString, iLength, lpSize);
  836. #else
  837.     return::GetTextExtentPoint(hDC, pString, iLength, lpSize);
  838. #endif
  839. }
  840.  
  841. BOOL CIntlWin::GetTextExtentPointWithCyaFont(CyaFont *theNSFont,int wincsid, HDC hDC, LPCSTR pString, int iLength, LPSIZE lpSize)
  842. {
  843.     if(0 == iLength)
  844.     {
  845.         lpSize->cx = 0;
  846.         lpSize->cy = 0;
  847.         return TRUE;
  848.     }
  849.     // wincsid = INTL_DocToWinCharSetID(wincsid) & ~ CS_AUTO;
  850.     XP_ASSERT(((wincsid & CS_AUTO) == 0) && (wincsid != CS_JIS) && (wincsid!=CS_EUCJP));
  851. #ifdef XP_WIN32
  852.     int wlen;
  853.  
  854.     if ( CIntlWin::UseUnicodeFontAPI(wincsid))
  855.     {
  856.         // Handle UTF8 by using multifont
  857.         if((wincsid == CS_UTF8) && CIntlWin::UseVirtualFont())
  858.         {
  859.             return CIntlUnicodeVirtualFontStrategy::GetTextExtentPointWithCyaFont(theNSFont,hDC, pString, iLength, lpSize );
  860.         }
  861.  
  862.         if(wlen = MultiByteToWideChar(wincsid, pString, iLength))
  863.         {
  864.             return  theNSFont->MeasureTextSize(hDC,    (char *)m_wConvBuf, wlen*sizeof(*m_wConvBuf), NULL, 0, lpSize);
  865.         }
  866.     }
  867. #endif    // XP_WIN32
  868.     if(wincsid == CS_UTF8)
  869.     {
  870.         return CIntlUnicodeVirtualFontStrategy::GetTextExtentPointWithCyaFont(theNSFont,hDC, pString, iLength, lpSize );
  871.     } 
  872.  
  873.     return( theNSFont->MeasureTextSize( hDC, (char *)pString, iLength, NULL, 0, lpSize) );
  874. // #ifdef XP_WIN32    // The final fallback
  875. //    return::GetTextExtentPoint32(hDC, pString, iLength, lpSize);
  876. // #else
  877. //    return::GetTextExtentPoint(hDC, pString, iLength, lpSize);
  878. // #endif
  879. }
  880.  
  881. CSize CIntlWin::GetTextExtent(int16 wincsid, HDC pDC, LPCTSTR pString, int iLength)
  882. {
  883.     CSize csSize;
  884.     BOOL bRetval;
  885.     bRetval = CIntlWin::GetTextExtentPoint(wincsid, pDC, pString, iLength, &csSize);
  886.     return(csSize);
  887. }
  888.  
  889. BOOL CIntlWin::TextOut(int16 wincsid, HDC hDC, int nXStart, int nYStart, LPCSTR  lpString,int  iLength)
  890. {
  891.     if(0 == iLength)
  892.         return TRUE;
  893.     wincsid = INTL_DocToWinCharSetID(wincsid) & ~ CS_AUTO;
  894. #ifdef XP_WIN32
  895.     int wlen;
  896.     if ( CIntlWin::UseUnicodeFontAPI(wincsid))
  897.     {
  898.         // Handle UTF8 by using multifont
  899.         if((wincsid == CS_UTF8)  && CIntlWin::UseVirtualFont())
  900.         {
  901.             return CIntlUnicodeVirtualFontStrategy::TextOut(
  902.                 hDC, nXStart, nYStart, lpString, iLength);
  903.         }
  904.         if(wlen = MultiByteToWideChar(wincsid, lpString, iLength))
  905.         {
  906.             return ::TextOutW(hDC, nXStart, nYStart, m_wConvBuf, wlen);
  907.         }
  908.     }
  909. #endif // XP_WIN32
  910.     if(wincsid == CS_UTF8)
  911.     {
  912.         return CIntlUnicodeVirtualFontStrategy::TextOut(hDC, nXStart, nYStart, lpString, iLength);
  913.     }    
  914.     return ::TextOut(hDC, nXStart, nYStart, lpString, iLength);        // The final fallback
  915. }
  916.  
  917. //based on BOOL CIntlWin::TextOut(int16 wincsid, HDC hDC, int nXStart, int nYStart, LPCSTR  lpString,int  iLength)
  918. BOOL CIntlWin::TextOutWithCyaFont(CyaFont *theNSFont, int16 wincsid, HDC hDC,  
  919.                                   int nXStart, int nYStart, LPCSTR  lpString,int  iLength)
  920. {
  921.     if(0 == iLength)
  922.         return TRUE;
  923. #ifdef XP_WIN32
  924.     int wlen;
  925.     if ( CIntlWin::UseUnicodeFontAPI(wincsid))
  926.     {
  927.         // Handle UTF8 by using multifont
  928.         if((wincsid == CS_UTF8)  && CIntlWin::UseVirtualFont())
  929.         {
  930.             return( CIntlUnicodeVirtualFontStrategy::TextOutWithCyaFont(theNSFont, hDC, nXStart, nYStart, lpString, iLength) );
  931.         }
  932.         if(wlen = MultiByteToWideChar(wincsid, lpString, iLength))
  933.         {
  934.             // the encording flag in theNSFont makes it call ::TextOutW()
  935.             if( theNSFont->drawText(hDC, nXStart, nYStart, (char *)m_wConvBuf, wlen * 2) == FONTERR_OK)
  936.                 return(TRUE);
  937.             else
  938.                 return(FALSE);
  939.             // return ::TextOutW(hDC, nXStart, nYStart, m_wConvBuf, wlen);
  940.         }
  941.     }
  942. #endif // XP_WIN32
  943.     if(wincsid == CS_UTF8)
  944.     {
  945.         // todo 
  946.         return CIntlUnicodeVirtualFontStrategy::TextOut(hDC, nXStart, nYStart, lpString, iLength);
  947.     }    
  948.     //return ::TextOut(hDC, nXStart, nYStart, lpString, iLength);        // The final fallback
  949.     if( theNSFont->drawText(hDC, nXStart, nYStart, (char *)lpString, iLength) == FONTERR_OK )
  950.         return(TRUE);
  951.     else
  952.         return(FALSE);
  953. }
  954.  
  955. //    *** Fix Me: Need to change to support UTF8
  956. BOOL CIntlWin::ExtTextOut(int16 wincsid, HDC pDC, int x, int y, UINT nOptions, LPCRECT lpRect, LPCSTR lpszString, UINT nCount, LPINT lpDxWidths)
  957. {
  958.     if(0 == nCount)
  959.         return TRUE;
  960.     wincsid = INTL_DocToWinCharSetID(wincsid) & ~ CS_AUTO;
  961. #ifdef XP_WIN32
  962.     int wlen;
  963.     if ( CIntlWin::UseUnicodeFontAPI(wincsid))
  964.     {
  965.         // Handle UTF8 by using multifont
  966.         if((wincsid == CS_UTF8)  && CIntlWin::UseVirtualFont())
  967.         {
  968.             // Fix Me: For now, igore the option and rect. Just use TextOut
  969.             // Need to implement the CIntlUnicodeVirtualFontStrategy::ExTextOut() later
  970.             return CIntlUnicodeVirtualFontStrategy::TextOut(
  971.                 pDC, x, y, lpszString, nCount);
  972.         }
  973.         if(wlen = MultiByteToWideChar(wincsid, lpszString, nCount))
  974.         {
  975.             return ::ExtTextOutW(pDC, x, y, nOptions, lpRect, m_wConvBuf, wlen, lpDxWidths);
  976.         }
  977.     }
  978. #endif
  979.     if(wincsid == CS_UTF8)
  980.     {
  981.         // Fix Me: For now, igore the option and rect. Just use TextOut
  982.         // Need to implement the CIntlUnicodeVirtualFontStrategy::ExTextOut() later
  983.         return CIntlUnicodeVirtualFontStrategy::TextOut(
  984.             pDC, x, y, lpszString, nCount);
  985.     }
  986.     return  ::ExtTextOut(pDC, x, y, nOptions, lpRect, lpszString, nCount, lpDxWidths);
  987. }
  988.  
  989. #ifdef XP_WIN32
  990. int CIntlWin::DrawTextEx(int16 wincsid, HDC hdc, LPSTR lpchText, int cchText,LPRECT lprc,UINT dwDTFormat,LPDRAWTEXTPARAMS lpDTParams)
  991. {
  992.     wincsid = INTL_DocToWinCharSetID(wincsid) & ~ CS_AUTO;
  993.  
  994.     int iRetval;
  995.     int wlen;
  996.     if (cchText == -1)
  997.         cchText = strlen(lpchText);
  998.  
  999.     if ( CIntlWin::UseUnicodeFontAPI(wincsid))
  1000.     {
  1001.  
  1002.         // DrawTextExW and DrawTextW is not working on Win95 right now. See Note above
  1003.         if( (!((wincsid == CS_UTF8)  && CIntlWin::UseVirtualFont()))
  1004.             && (sysInfo.m_bWinNT)
  1005.             && (wlen = MultiByteToWideChar(wincsid, lpchText, cchText))
  1006.           )
  1007.         {
  1008.             return ::DrawTextW(hdc, m_wConvBuf, wlen, lprc, dwDTFormat);
  1009.         }
  1010.         int x, y;
  1011.         SIZE sz;
  1012.         CIntlWin::GetTextExtentPoint(wincsid, hdc, lpchText, cchText, &sz);
  1013.  
  1014.         //    Caculate X 
  1015.         x = lprc->left;
  1016.         if(dwDTFormat & DT_CENTER)    
  1017.             x = (lprc->right + lprc->right - sz.cx) / 2;
  1018.         else if(dwDTFormat & DT_RIGHT)
  1019.             x = lprc->right - sz.cx;
  1020.  
  1021.         //    Caculate Y
  1022.         y = lprc->top ;
  1023.         if(dwDTFormat & DT_VCENTER)
  1024.             y = ( lprc->top + lprc->bottom - sz.cy ) / 2;
  1025.         else if(dwDTFormat & DT_BOTTOM)
  1026.             y = lprc->bottom - sz.cy;
  1027.  
  1028.         if(dwDTFormat & DT_CALCRECT)
  1029.         {
  1030.             lprc->right = x + sz.cx;
  1031.             return sz.cy;
  1032.         }        
  1033.         return  CIntlWin::TextOut(wincsid, hdc, x, y, lpchText, cchText);
  1034.     }
  1035.     else
  1036.     {
  1037.         if (sysInfo.m_bWinNT)
  1038.             iRetval =  ::DrawText(hdc, lpchText, cchText, lprc, dwDTFormat);
  1039.         else
  1040.             iRetval =  ::DrawTextEx(hdc, lpchText, cchText, lprc, dwDTFormat, lpDTParams);
  1041.     }
  1042.     return iRetval;
  1043. }
  1044. #endif
  1045.  
  1046. int CIntlWin::DrawText(int16 wincsid, HDC hdc, LPSTR lpchText, int cchText,LPRECT lprc,UINT dwDTFormat)
  1047. {
  1048. #ifdef _WIN32
  1049.     return CIntlWin::DrawTextEx( wincsid,  hdc,  lpchText,  cchText, lprc, dwDTFormat, NULL);
  1050. #else
  1051.     wincsid = INTL_DocToWinCharSetID(wincsid) & ~ CS_AUTO;
  1052.     if (cchText == -1)
  1053.         cchText = strlen(lpchText);
  1054.  
  1055.     if(wincsid == CS_UTF8)
  1056.     {
  1057.         int x, y;
  1058.         SIZE sz;
  1059.         CIntlUnicodeVirtualFontStrategy::GetTextExtentPoint(hdc, lpchText, cchText, &sz);
  1060.  
  1061.         //    Caculate X 
  1062.         x = lprc->left;
  1063.         if(dwDTFormat & DT_CENTER)    
  1064.             x = (lprc->right + lprc->right - sz.cx) / 2;
  1065.         else if(dwDTFormat & DT_RIGHT)
  1066.             x = lprc->right - sz.cx;
  1067.  
  1068.         //    Caculate Y
  1069.         y = lprc->top;
  1070.         if(dwDTFormat & DT_VCENTER)
  1071.             y = ( lprc->top + lprc->bottom - sz.cy ) / 2;
  1072.         else if(dwDTFormat & DT_BOTTOM)
  1073.             y = lprc->bottom - sz.cy;
  1074.  
  1075.         if(dwDTFormat & DT_CALCRECT)
  1076.         {
  1077.             lprc->right = x + sz.cx;
  1078.             return sz.cy;
  1079.         }        
  1080.         return  CIntlUnicodeVirtualFontStrategy::TextOut(hdc, x, y, lpchText, cchText);
  1081.     }
  1082.     return  ::DrawText(hdc, lpchText, cchText, lprc, dwDTFormat );
  1083. #endif
  1084. }
  1085.  
  1086. extern "C" void *FE_GetSingleByteTable(int16 from_csid, int16 to_csid, int resourceid)
  1087. {
  1088.     HRSRC    hrsrc;
  1089.     HGLOBAL    hRes;
  1090.     char     szName[256];
  1091.  
  1092.     strcpy(szName, (const char *)INTL_CsidToCharsetNamePt(from_csid));
  1093.     strcpy(szName + strlen(szName), "_TO_");
  1094.     strcpy(szName + strlen(szName), (const char *)INTL_CsidToCharsetNamePt(to_csid));
  1095.     for (char *p = szName; *p; p++)
  1096.     {
  1097.         if (*p == '-')      *p = '_';
  1098.     }
  1099.  
  1100.     hrsrc = ::FindResource(AfxGetResourceHandle(), szName, RT_RCDATA);
  1101.  
  1102.     XP_ASSERT(hrsrc);
  1103.  
  1104.     if (!hrsrc) {
  1105.         TRACE1("FE_GetSingleByteTable cannot find resource: %s\n", szName);
  1106.         return NULL;
  1107.     }
  1108.  
  1109.     hRes = ::LoadResource(AfxGetResourceHandle(), hrsrc);
  1110.  
  1111.     XP_ASSERT(hRes);
  1112.  
  1113.     if (!hRes) {
  1114.         TRACE1("FE_GetSingleByteTable cannot load resource: %s\n", szName);
  1115.         return NULL;        
  1116.     }
  1117.  
  1118.     return (void *) hRes;
  1119. }
  1120.  
  1121. extern "C" char *FE_LockTable(void **hres)
  1122. {
  1123.     return (LPSTR)::LockResource((HGLOBAL) hres);
  1124. }
  1125.  
  1126. extern "C" void FE_FreeSingleByteTable(void **hres) 
  1127. {
  1128. #ifndef XP_WIN32    
  1129.     ::UnlockResource((HGLOBAL) hres);
  1130. #endif
  1131.     ::FreeResource((HGLOBAL) hres);
  1132. }
  1133.  
  1134. /*--------------------------------------------------------------------------*/
  1135.  
  1136. #define MAXNUMOFCSIDLIST 64
  1137. #define UNICODECONVERSIONCHARTLIST "UnicodeConversionCharsetList"
  1138.  
  1139.  
  1140. #ifdef XP_WIN32
  1141. #define UNICODEDLL "UNI3200.DLL"
  1142. #define LIBRARYLOADOK(l)    (l != NULL)
  1143. #define UNICODE_VERIFYCSIDLIST_SYM    "UNICODE_VERIFYCSIDLIST"
  1144. #else
  1145. #define UNICODEDLL "UNI1600.DLL"
  1146. #define LIBRARYLOADOK(l)    (l > HINSTANCE_ERROR)
  1147. #define UNICODE_VERIFYCSIDLIST_SYM    "_UNICODE_VERIFYCSIDLIST"
  1148. #endif
  1149.  
  1150. static int intl_VerifyCsidList(int inNumOfItem, int16 *csidlist)
  1151. {
  1152.     int iRetval = 0;
  1153.     HINSTANCE hUniLib = LoadLibrary(UNICODEDLL);
  1154.     if(LIBRARYLOADOK(hUniLib)) {
  1155.         typedef int (*func)(int, int16 *);
  1156.         func VerifyProc = (func)GetProcAddress(hUniLib, UNICODE_VERIFYCSIDLIST_SYM);
  1157.         ASSERT(VerifyProc);
  1158.         if(VerifyProc) {
  1159.             iRetval = VerifyProc(inNumOfItem, csidlist);
  1160.             VerifyProc = NULL;
  1161.         }
  1162.         
  1163.         FreeLibrary(hUniLib);
  1164.         hUniLib = NULL;
  1165.     }
  1166.     return(iRetval);
  1167. }
  1168.  
  1169. //
  1170. //    Read and Write charset List for Unicode conversion
  1171. //
  1172. static void intl_ReadUnicodeConvList()
  1173. {
  1174.     CString charsetlist;
  1175.     int16 csidlist[MAXNUMOFCSIDLIST];
  1176.     int num_of_csid;
  1177.  
  1178.     // Find the charsetlist from preference
  1179.     charsetlist = theApp.GetProfileString("INTL", UNICODECONVERSIONCHARTLIST, "");
  1180.  
  1181.     // If we cannot find it from preference , find it from resource
  1182.     if(strlen((const char*)charsetlist) == 0)
  1183.         charsetlist = szLoadString(IDS_CHARSET_LIST_FOR_UNICODE);
  1184.  
  1185.     // Otherwise, it is very wrong, however, we still give it
  1186.     // CS_LATIN1 , CS_SYMBOL, and CS_DINGBATS
  1187.     if(strlen((const char*)charsetlist) == 0)
  1188.         charsetlist = 
  1189.         "iso-8859-1,x-cp1250,x-cp1251,x-cp1253,iso-8859-9,Shift_JIS,euc-kr,gb2312,big5,adobe-symbol-encoding,x-dingbats";
  1190.  
  1191.     for(num_of_csid=0; num_of_csid < MAXNUMOFCSIDLIST; )
  1192.     {
  1193.         int duplicate;
  1194.         int csid; 
  1195.         int i;
  1196.         int lastone = 0;
  1197.         int len = charsetlist.GetLength();
  1198.         int thislen = charsetlist.Find(','); 
  1199.         if(thislen == -1)
  1200.         {
  1201.             lastone = 1;
  1202.             thislen = len;
  1203.         }
  1204.         
  1205.         csid=INTL_CharSetNameToID((char *)(const char *)charsetlist.Left(thislen));
  1206.         // Check to see is that duplicate ?
  1207.         for(i=0, duplicate=0;i < num_of_csid; i ++)
  1208.         {
  1209.             if(csid == csidlist[i])
  1210.                 duplicate = 1;
  1211.         }
  1212.         // If not duplicate, add it to the list
  1213.         if(duplicate == 0 )
  1214.             csidlist[num_of_csid++] = csid;
  1215.         
  1216.         if(lastone == 0 )
  1217.             charsetlist = charsetlist.Right(len - thislen - 1);
  1218.         else
  1219.             break;
  1220.     }  
  1221.     // Write it to the Prefs
  1222.     intl_WriteUnicodeConvList(num_of_csid, csidlist);
  1223.  
  1224.     // Filter through our csid checking code - intl_VerifyCsidList()
  1225.     num_of_csid = intl_VerifyCsidList(num_of_csid, csidlist);
  1226.  
  1227.     // OK, now we have the list. Call the xp function to initialize 
  1228.     // Unicode Converter
  1229.     INTL_SetUnicodeCSIDList(num_of_csid, csidlist);    
  1230.  
  1231. }
  1232. static void intl_WriteUnicodeConvList(int num_of_csid, int16* csidlist)
  1233. {
  1234.     char str[512];
  1235.     int first, i;
  1236.     char * cur;
  1237.     // Now, convert those csid to string
  1238.     for(first=1,i=0,cur=str;i < num_of_csid;i++)
  1239.     {
  1240.         if(first)
  1241.             first = 0;
  1242.         else
  1243.             *cur++ = ',';
  1244.         INTL_CharSetIDToName(csidlist[i], cur);
  1245.         cur += strlen(cur);
  1246.     }
  1247.     // And write to the Profile
  1248.     theApp.WriteProfileString("INTL", UNICODECONVERSIONCHARTLIST, str);
  1249. }
  1250.  
  1251.  
  1252. extern "C" {
  1253.  
  1254. BYTE IntlGetJavaCharset(int csid, int javaFontID)
  1255. {
  1256.     // currently, we ignore javaFontID. We may need to use it later
  1257.     switch(csid)
  1258.     {
  1259.         case CS_DINGBATS:
  1260.         case CS_SYMBOL:
  1261.             return SYMBOL_CHARSET;
  1262.         default:
  1263.             return IntlGetLfCharset(csid);
  1264.     }
  1265. }
  1266. const char* IntlGetJavaFaceName(int csid, int javaFontID)
  1267. {
  1268.     switch(csid)
  1269.     {
  1270.         case CS_DINGBATS:
  1271.             return "Wingdings";
  1272.         case CS_SYMBOL:
  1273.             return "Symbol";
  1274.         default:
  1275.             switch(javaFontID)
  1276.             {
  1277.                 case javaFontTimesRoman:
  1278.                 case javaFontDialog:
  1279.                 case javaFontHelvetica:
  1280.                     return IntlGetUIPropFaceName(csid);
  1281.                 case javaFontDialogInput:
  1282.                 case javaFontCourier:
  1283.                     return IntlGetUIFixFaceName(csid);
  1284.                 default:
  1285.                     return IntlGetUIPropFaceName(csid);
  1286.             }    
  1287.     }
  1288. }
  1289. };
  1290. extern "C" {
  1291.  
  1292. PR_PUBLIC_API(const char* )
  1293.     INTLGETJAVAFACENAME_E(int csid, int javaFontID)
  1294.         { return IntlGetJavaFaceName(csid, javaFontID); }
  1295. PR_PUBLIC_API(BYTE )
  1296.     INTLGETJAVACHARSET_E(int csid, int javaFontID)
  1297.         { return IntlGetJavaCharset(csid, javaFontID); }
  1298. PR_PUBLIC_API(int16* )
  1299.     INTL_GETUNICODECSIDLIST_E(int16 * outnum)
  1300.         { return INTL_GetUnicodeCSIDList(outnum); }
  1301. PR_PUBLIC_API(int32 )
  1302.     INTL_UNICODELEN_E(uint16* ustr)
  1303.         { return INTL_UnicodeLen(ustr); } 
  1304. PR_PUBLIC_API(INTL_CompoundStr* )
  1305.     INTL_COMPOUNDSTRFROMUNICODE_E(uint16* inunicode, uint32 inlen)
  1306.         { return INTL_CompoundStrFromUnicode(inunicode, inlen); }
  1307. PR_PUBLIC_API(void )
  1308.     INTL_COMPOUNDSTRDESTROY_E(INTL_CompoundStr* This)
  1309.         { INTL_CompoundStrDestroy(This); }
  1310. PR_PUBLIC_API(INTL_CompoundStrIterator )
  1311.     INTL_COMPOUNDSTRFIRSTSTR_E(INTL_CompoundStr* This, INTL_Encoding_ID *outencoding, unsigned char** outtext)
  1312.         { return INTL_CompoundStrFirstStr(This, outencoding,outtext); }
  1313. PR_PUBLIC_API(INTL_CompoundStrIterator )
  1314.     INTL_COMPOUNDSTRNEXTSTR_E(INTL_CompoundStrIterator iterator, INTL_Encoding_ID *outencoding, unsigned char** outtext)
  1315.         { return INTL_CompoundStrNextStr(iterator, outencoding, outtext); }
  1316. PR_PUBLIC_API(INTL_CompoundStr* )         
  1317.     INTL_COMPOUNDSTRCLONE_E(INTL_CompoundStr* s1)
  1318.         { return INTL_CompoundStrClone(s1); }
  1319. PR_PUBLIC_API(int16 )
  1320.     INTL_DEFAULTWINCHARSETID_E(MWContext *context)
  1321.         { return INTL_DefaultWinCharSetID(context); }
  1322. PR_PUBLIC_API(int32 )
  1323.     INTL_TEXTBYTECOUNTTOCHARLEN_E(int16 csid, unsigned char* text, uint32 byteCount)
  1324.         { return INTL_TextByteCountToCharLen(csid, text, byteCount); }
  1325. PR_PUBLIC_API(int32 )
  1326.     INTL_TEXTCHARLENTOBYTECOUNT_E(int16 csid, unsigned char* text, uint32 charLen)
  1327.         { return INTL_TextCharLenToByteCount(csid, text,  charLen); }
  1328. PR_PUBLIC_API(uint32 )
  1329.     INTL_UNICODETOSTRLEN_E(INTL_Encoding_ID encoding,INTL_Unicode* ustr, uint32    ustrlen)
  1330.         { return INTL_UnicodeToStrLen(encoding,ustr,ustrlen); }
  1331. PR_PUBLIC_API(void )
  1332.     INTL_UNICODETOSTR_E(INTL_Encoding_ID encoding,INTL_Unicode* ustr,uint32 ustrlen,unsigned char* dest, uint32 destbuflen)
  1333.         { INTL_UnicodeToStr(encoding,ustr,ustrlen,dest,destbuflen); }
  1334.  
  1335. #ifdef JAVA
  1336. PR_PUBLIC_API(jref * )
  1337.     INTL_MAKEJAVASTRING_E(int16 encoding, char *str, int len)
  1338.         { return intl_makeJavaString(encoding, str, len); }
  1339. #endif    // JAVA
  1340.  
  1341. PR_PUBLIC_API(BOOL )
  1342.     CINTLWIN_TEXTOUT_E(int16 wincsid, HDC hdc, int nXStart, int nYStart, LPCSTR  lpString,int  iLength)
  1343.         { return CIntlWin::TextOut( wincsid,  hdc,  nXStart,  nYStart,   lpString,  iLength); }
  1344. PR_PUBLIC_API(BOOL )
  1345.     CINTLWIN_GETTEXTEXTENTPOINT_E(int wincsid, HDC hDC, LPCSTR lpString, int cbString, LPSIZE lpSize)
  1346.         { return CIntlWin::GetTextExtentPoint( wincsid,  hDC,  lpString,  cbString,  lpSize); }
  1347.  
  1348. };    // extern "C"
  1349.