[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][TOP]

galeon 0.12 bookmark moji-bake patch


galeon の 0.12 が出ましたが、いくつか文字化けが発生する可能性がありま
す。

  環境によるかもしれませんが、私のところでは「―」「〜」などを
<title> … </title> に含むページをブックマークすると文字化けしました。

  ちょっと調べただけなんで正確ではないかもしれませんが、JIS X 0208 の 
0x2141 (EUC-JP なら 0xA1C1)の 「〜」については Mozilla の内部では 
U+FF5E (FULL WIDTH TILDE) として扱われているけど、これを glibc 2.2.4 
内蔵の変換表使って EUC-JP に変換すると、JIS X 0212 の 0x2237 (TILDE)
(EUC-JP なら SS2 0xA2B7) にされてしまいます。JIS X 0212 な文字だからっ
て化けるのはなぜ? というのはありますが、なんとなく嬉しくありません (フォ
ント設定の問題?)。

  あと、変換には iconv(3) などを使うべきだと思うのですが、galeon では
unicode (UCS-2 あるいは UTF-16) で取り出した文字列を as-is で wchar_t 
の配列にコピーし、wcstombs(3) を使ってlocale の encoding に変換してい
ます。つまり、wchar_t が Unicode であることを仮定しています。

  Linux + glibc の環境ではそれなりに動きますが、それ以外の環境ではうま
く動作しないんじゃないかと思います。たとえば、*BSD 系の環境では問題が
あると思います。

  ということで、Mozilla 内蔵の変換サービスを使って、この処理を行うよう、
galeon のコードを書き変えるパッチを作ってみたので添付します。すこし使っ
た限りではそれなりにうまく動くようです。メモリリークなどがあるかもしれ
ませんし、他の処理に影響はあるかもしれませんが、未検証です。あと、ほんと
にこのやり方でいいのかどうかは深く考えてません。

 ( TODO によればブックマークについては Unicode のまま保持して、表示す
   る時に変換するようにする、という方針のようではありますが、このパッ
   チ自体は汎用のルーチンの変更のみなので、たぶん影響しません )

  あと、Mozilla のブックマークをインポートすると化ける、スマートブック
バーの Google の検索が化ける、Big5 で文字中に '_' 相当の値を持ってたら
ブックマークまだ文字化けするかもしれない (未確認)、などの問題がありま
すが、これらについてのはこのパッチだけでは解決しません。

  KUSANO Takayuki <URL:http://www.asahi-net.or.jp/~AE5T-KSN/>
diff -ur galeon-0.12.orig/src/mozilla.cpp galeon-0.12/src/mozilla.cpp
--- galeon-0.12.orig/src/mozilla.cpp	Wed Aug 15 16:43:13 2001
+++ galeon-0.12/src/mozilla.cpp	Tue Aug 21 07:39:58 2001
@@ -33,6 +33,7 @@
 #include "nsICharsetConverterManager.h"
 #include "nsICharsetConverterManager2.h"
 #include "nsIUnicodeEncoder.h"
+#include "nsIUnicodeDecoder.h"
 #include "nsISupportsPrimitives.h"
 #include "nsIPrintOptions.h"
 #include "nsGfxCIID.h"
@@ -52,9 +53,11 @@
 #include "nsIDOMWindowInternal.h"
 #include "nsIJVMManager.h"
 #include "nsIJSConsoleService.h"
+#include "nsIPlatformCharset.h"
 
 static NS_DEFINE_CID(kPrintOptionsCID, NS_PRINTOPTIONS_CID);
 static NS_DEFINE_CID(kJVMManagerCID, NS_JVMMANAGER_CID);
+static NS_DEFINE_CID(kPlatformCharsetCID, NS_PLATFORMCHARSET_CID);
 
 /* local function prototypes */
 static char  *convert_ns_string_to_c_string (const nsString & ns_string);
@@ -1037,10 +1040,10 @@
 extern "C" gchar *
 mozilla_unicode_to_locale (const PRUnichar *uniStr)
 {
-	PRInt32 sSize;
-	wchar_t *wide;
+	PRInt32 sSize,dSize;
 	gchar *output;
-	gint i, count;
+	nsAutoString platformCharset;
+	nsresult rv;
 
 	/* sanity */
 	if (uniStr == NULL)
@@ -1048,39 +1051,41 @@
 		return NULL;
 	}
 
-	const nsString str (uniStr);
-	sSize = str.Length ();
-
-	/* allocate a wide string big enough to hold the unicode string,
-	 * this is necessary since wchar_t is 32-bits with glibc */
-	wide = g_new0 (wchar_t, sSize + 1);
-	for (i = 0; i < sSize + 1; i++)
+	nsCOMPtr<nsIPlatformCharset> platformCharsetService
+	    = do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
+	if (! NS_SUCCEEDED(rv))
 	{
-		wide[i] = uniStr[i];
+		return NULL;
 	}
 
-	/* use glibc function to determine the size of this string once
-	 * encoded to a locale specfic multibyte string */
-	count = wcstombs (NULL, wide, 0);
+	rv = platformCharsetService->GetCharset(kPlatformCharsetSel_Menu,
+						platformCharset);
+	nsCOMPtr<nsICharsetConverterManager> ccm =
+	    do_GetService (NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
+	if (! NS_SUCCEEDED(rv))
+	{
+		return NULL;
+	}
 
-	/* check for success */
-	if (count == -1)
+	nsCOMPtr<nsIUnicodeEncoder> encoder;
+	rv = ccm->GetUnicodeEncoder(&platformCharset, getter_AddRefs(encoder));
+	if (! NS_SUCCEEDED(rv))
 	{
-		/* let Mozilla do a (lossy) conversion then */
-		nsCString str;
-		str.AssignWithConversion(uniStr);
-		g_free (wide);
-		return g_strdup (str.get()); /* FIXME strdup needed? */
-					     /* Phil: Oh Yes! indeed. */
+		return NULL;
 	}
 
-	/* allocate a string big enough and do the actual conversion */
-	output = g_new0 (gchar, count + 1);
-	count = wcstombs (output, wide, count + 1);
-	g_assert (count != -1);
+	const nsString str (uniStr);
+	sSize = str.Length ();
+	encoder->GetMaxLength (str.get(), sSize, &dSize);
+	if (! dSize)
+	{
+		return NULL;
+	} 
 
-	/* free wide version and return */
-	g_free (wide);
+	output = g_new0 (gchar, dSize + 1);
+	encoder->Convert (str.get(), &sSize, output, &dSize);
+	encoder->Finish (output, &dSize);
+	encoder->Reset ();
 	return output;
 }
 
@@ -1120,9 +1125,10 @@
 extern "C" PRUnichar *
 mozilla_locale_to_unicode (const gchar *locStr)
 {
+	PRInt32 sSize,dSize;
 	PRUnichar *uniStr;
-	wchar_t *wide;
-	gint i, count;
+	nsAutoString platformCharset;
+	nsresult rv;
 
 	/* sanity */
 	if (locStr == NULL)
@@ -1130,28 +1136,41 @@
 		return NULL;
 	}
 
-	/* count the number of wide characters which will be produced */
-	count = mbstowcs (NULL, locStr, 0);
-	if (count == -1)
+	nsCOMPtr<nsIPlatformCharset> platformCharsetService
+		= do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
+	if (! NS_SUCCEEDED(rv))
 	{
-		/* hmm, shouldnt happen but fallback to utf8 */
-		g_warning ("unusual locale string: [%s]\n", locStr);
-		return mozilla_utf8_to_unicode (locStr);
+		return NULL;
 	}
 
-	/* allocate and decode */
-	wide = g_new0 (wchar_t, count + 1);
-	mbstowcs (wide, locStr, count + 1);
+	rv = platformCharsetService->GetCharset(kPlatformCharsetSel_Menu,
+						platformCharset);
+	nsCOMPtr<nsICharsetConverterManager> ccm =
+	    do_GetService (NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
+	if (! NS_SUCCEEDED(rv))
+	{
+		return NULL;
+	}
 
-	/* make a unicode string and copy into it */
-	uniStr = g_new0 (PRUnichar, count + 1);
-	for (i = 0; i < count + 1; i++)
+	nsCOMPtr<nsIUnicodeDecoder> decoder;
+	rv = ccm->GetUnicodeDecoder(&platformCharset, getter_AddRefs(decoder));
+	if (! NS_SUCCEEDED(rv))
 	{
-		uniStr[i] = wide[i];
+		return NULL;
 	}
 
-	/* free wide string and return the unicode one */
-	g_free (wide);
+	/* FIXME if locStr in UTF-16, this will not work */
+	sSize = strlen(locStr);
+	decoder->GetMaxLength (locStr, sSize, &dSize);
+	if (! dSize)
+	{
+		return NULL;
+	} 
+
+	uniStr = g_new0 (PRUnichar, dSize + 1);
+	decoder->Convert (locStr, &sSize, uniStr, &dSize);
+	uniStr[dSize] = '\0';
+	decoder->Reset ();
 	return uniStr;
 }