};
/*!
- * @brief EUCがシステムコードである環境下向けにUTF-8から変換処理を行うサブルーチン
- * @param str 変換する文字列のポインタ
- * @return なし
+ * @brief 受け取ったUTF-8文字列を調べ、特定のコードポイントの文字の置き換えを行う
+ *
+ * 受け取ったUTF-8の文字列に含まれる文字を1つ1つしらべて、ms_to_jis_unicode_conv で
+ * 定義されている特定のコードポイントの文字の変換を行う。
+ *
+ * '~'と'-'は、Windows環境(CP932)とLinux/UNIX環境(EUC-JP)でUTF-8に対応する
+ * 文字としてそれぞれ別のコードポイントが割り当てられており、別の環境の
+ * UTF-8からシステムの文字コードに変換した時に、これらの文字は変換できず
+ * 文字化けが起きてしまう。
+ *
+ * これを避けるため、Linux/UNIX環境(EUC-JP)ではUTF-8→EUC-JPの変換を行う前に
+ * 該当するコードポイントの文字をLinux/UNIX環境のものに置き換えてから
+ * 変換を行うようにするためのルーチン。
+ *
+ * @param str コードポイントの置き換えを行う文字列へのポインタ
*/
static void ms_to_jis_unicode(char *str)
{
#elif defined(SJIS) && defined(WINDOWS)
#include <Windows.h>
#endif
+
+#ifdef EUC
+/*!
+ * @brief 文字列の文字コードをUTF-8からEUC-JPに変換する
+ * @param utf8_str 変換元の文字列へのポインタ
+ * @param utf8_str_len 変換元の文字列の長さ(文字数ではなくバイト数)
+ * @param euc_buf 変換した文字列を格納するバッファへのポインタ
+ * @param euc_buf_len 変換した文字列を格納するバッファのサイズ
+ * @return 変換に成功した場合変換後の文字列の長さを返す
+ * 変換に失敗した場合-1を返す
+ */
+int utf8_to_euc(char *utf8_str, size_t utf8_str_len, char *euc_buf, size_t euc_buf_len)
+{
+ static iconv_t cd = NULL;
+ if (!cd)
+ cd = iconv_open("EUC-JP", "UTF-8");
+
+ ms_to_jis_unicode(utf8_str);
+
+ size_t inlen_left = utf8_str_len;
+ size_t outlen_left = euc_buf_len;
+ char *in = utf8_str;
+ char *out = euc_buf;
+
+ if (iconv(cd, &in, &inlen_left, &out, &outlen_left) == (size_t)-1) {
+ return -1;
+ }
+
+ return euc_buf_len - outlen_left;
+}
+
+/*!
+ * @brief 文字列の文字コードをEUC-JPからUTF-8に変換する
+ * @param euc_str 変換元の文字列へのポインタ
+ * @param euc_str_len 変換元の文字列の長さ(文字数ではなくバイト数)
+ * @param utf8_buf 変換した文字列を格納するバッファへのポインタ
+ * @param utf8_buf_len 変換した文字列を格納するバッファのサイズ
+ * @return 変換に成功した場合変換後の文字列の長さを返す
+ * 変換に失敗した場合-1を返す
+ */
+int euc_to_utf8(const char *euc_str, size_t euc_str_len, char *utf8_buf, size_t utf8_buf_len)
+{
+ static iconv_t cd = NULL;
+ if (!cd)
+ cd = iconv_open("UTF-8", "EUC-JP");
+
+ size_t inlen_left = euc_str_len;
+ size_t outlen_left = utf8_buf_len;
+ const char *in = euc_str;
+ char *out = utf8_buf;
+
+ // iconv は入力バッファを書き換えないのでキャストで const を外してよい
+ if (iconv(cd, (char **)&in, &inlen_left, &out, &outlen_left) == (size_t)-1) {
+ return -1;
+ }
+
+ return utf8_buf_len - outlen_left;
+}
+#endif
+
/*!
* @brief 文字コードがUTF-8の文字列をシステムの文字コードに変換する
* @param utf8_str 変換するUTF-8の文字列へのポインタ
{
#if defined(EUC)
- iconv_t cd = iconv_open("EUC-JP", "UTF-8");
- size_t utf8_len = strlen(utf8_str) + 1; /* include termination character */
- char *from = utf8_str;
- int ret;
-
- ms_to_jis_unicode(utf8_str);
- ret = iconv(cd, &from, &utf8_len, &sys_str_buffer, &sys_str_buflen);
- iconv_close(cd);
- return (ret >= 0);
+ /* strlen + 1 を渡して文字列終端('\0')を含めて変換する */
+ return (utf8_to_euc(utf8_str, strlen(utf8_str) + 1, sys_str_buffer, sys_str_buflen) >= 0);
#elif defined(SJIS) && defined(WINDOWS)
byte codeconv(char *str);
bool iskanji2(concptr s, int x);
void guess_convert_to_system_encoding(char* strbuf, int buflen);
+
+#ifdef EUC
+int utf8_to_euc(char *utf8_str, size_t utf8_str_len, char *euc_buf, size_t euc_buf_len);
+int euc_to_utf8(const char *euc_str, size_t euc_str_len, char *utf8_buf, size_t utf8_buf_len);
+#endif
+
#endif
#include "game-option/special-options.h"
#include "io/exit-panic.h"
#include "io/files-util.h"
+#include "locale/japanese.h"
#include "main/sound-definitions-table.h"
#include "main/sound-of-music.h"
#include "system/angband.h"
* Include the proper "header" file
*/
#include <curses.h>
-#include <iconv.h>
typedef struct term_data term_data;
#define MAX_TERM_DATA 4
static term_data data[MAX_TERM_DATA];
-static iconv_t iconv_to_sys;
-static iconv_t iconv_to_gui;
/*
* Hack -- try to guess which systems use what commands
}
/*
- * Convert to EUC-JP
- */
-static void convert_to_sys(char *buf)
-{
- size_t inlen = strlen(buf);
- size_t outlen = inlen;
- char tmp[outlen + 1];
-
- char *inbuf = buf;
- char *outbuf = tmp;
- size_t res;
- res = iconv(iconv_to_sys, 0, 0, 0, 0);
- if (res == (size_t)-1)
- return;
- res = iconv(iconv_to_sys, &inbuf, &inlen, &outbuf, &outlen);
- if (res == (size_t)-1)
- return;
- res = iconv(iconv_to_sys, 0, 0, &outbuf, &outlen);
- if (res == (size_t)-1)
- return;
-
- outbuf[0] = '\0';
- strcpy(buf, tmp);
-}
-
-/*
* Push multiple keys reversal
*/
static void term_string_push(char *buf)
nodelay(stdscr, FALSE);
*bp = '\0';
- convert_to_sys(buf);
- term_string_push(buf);
+#ifdef JP
+ char eucbuf[sizeof(buf)];
+ /* strlen + 1 を渡して文字列終端('\0')を含めて変換する */
+ if (utf8_to_euc(buf, strlen(buf) + 1, eucbuf, sizeof(eucbuf)) < 0) {
+ return (-1);
+ }
+#endif
+ term_string_push(_(eucbuf, buf));
}
/* Do not wait */
}
bp[0] = '\0';
- convert_to_sys(buf);
- term_string_push(buf);
+#ifdef JP
+ char eucbuf[sizeof(buf)];
+ /* strlen + 1 を渡して文字列終端('\0')を含めて変換する */
+ if (utf8_to_euc(buf, strlen(buf) + 1, eucbuf, sizeof(eucbuf)) < 0) {
+ return (-1);
+ }
+#endif
+ term_string_push(_(eucbuf, buf));
}
/* Do not wait */
{
term_data *td = (term_data *)(Term->data);
- char intext[n];
- char text[80 * 3 + 1];
- size_t inlen = n;
- size_t outlen = sizeof(text);
- char *inbuf = intext;
- char *outbuf = text;
- size_t res;
-
#ifdef USE_NCURSES_ACS
/* do we have colors + 16 ? */
/* then call special routine for drawing special characters */
}
#endif
- /* Copy to char array because of iconv's warning by const char pointer */
- memcpy(intext, s, (size_t)n);
-
- /* Obtain a copy of the text */
- res = iconv(iconv_to_gui, 0, 0, 0, 0);
- if (res == (size_t)-1)
- return (-1);
- res = iconv(iconv_to_gui, &inbuf, &inlen, &outbuf, &outlen);
- if (res == (size_t)-1)
- return (-1);
- res = iconv(iconv_to_gui, 0, 0, &outbuf, &outlen);
- if (res == (size_t)-1)
- return (-1);
-
- if (outlen == 0)
- return (-1);
- *outbuf = '\0';
-
/* Move the cursor and dump the string */
wmove(td->win, y, x);
wattrset(td->win, colortable[a & 0x0F]);
#endif
+#ifdef JP
+ char text[1024];
+ int text_len = euc_to_utf8(s, n, text, sizeof(text));
+ if (text_len < 0) {
+ return (-1);
+ }
+#endif
/* Add the text */
- waddstr(td->win, text);
+ waddnstr(td->win, _(text, s), _(text_len, n));
/* Success */
return (0);
/* Exit curses */
endwin();
-
- iconv_close(iconv_to_sys);
- iconv_close(iconv_to_gui);
}
/*
(void)argv;
setlocale(LC_ALL, "");
- iconv_to_sys = iconv_open("EUC-JP", "");
- if (iconv_to_sys == (iconv_t)-1)
- return (-1);
- iconv_to_gui = iconv_open("", "EUC-JP");
- if (iconv_to_gui == (iconv_t)-1)
- return (-1);
/* Build the "sound" path */
path_build(path, sizeof(path), ANGBAND_DIR_XTRA, "sound");
#include "game-option/runtime-arguments.h"
#include "game-option/special-options.h"
#include "io/files-util.h"
+#include "locale/japanese.h"
#include "locale/utf-8.h"
#include "main/sound-definitions-table.h"
#include "main/sound-of-music.h"
#include <X11/Xatom.h>
#endif /* __MAKEDEPEND__ */
-#include <iconv.h>
#ifdef USE_XFT
#include <X11/Xft/Xft.h>
#endif
}
#endif
} else {
- iconv_t cd = iconv_open("UTF-8", "EUC-JP");
- size_t inlen = len;
- size_t outlen = len * 2;
- char *kanji = malloc(outlen);
- char *sp;
- char *kp = kanji;
- char sbuf[1024];
- memcpy(sbuf, str, (size_t)len);
- sp = sbuf;
- iconv(cd, &sp, &inlen, &kp, &outlen);
- iconv_close(cd);
+#ifdef JP
+ char utf8_buf[1024];
+ int utf8_len = euc_to_utf8(str, len, utf8_buf, sizeof(utf8_buf));
+ if (utf8_len < 0) {
+ return (-1);
+ }
+#endif
#ifdef USE_XFT
XftDraw *draw = Infowin->draw;
r.height = Infofnt->hgt;
XftDrawSetClipRectangles(draw, x, y - Infofnt->asc, &r, 1);
XftDrawRect(draw, &Infoclr->bg, x, y - Infofnt->asc, Infofnt->wid * len, Infofnt->hgt);
- Infofnt_text_std_xft_draw_str(x, y, kanji, kp);
+ Infofnt_text_std_xft_draw_str(x, y, _(utf8_buf, str), _(utf8_buf + utf8_len, str + len));
XftDrawSetClip(draw, 0);
#else
- XmbDrawImageString(Metadpy->dpy, Infowin->win, Infofnt->info, Infoclr->gc, x, y, kanji, kp - kanji);
+ XmbDrawImageString(Metadpy->dpy, Infowin->win, Infofnt->info, Infoclr->gc, x, y, _(utf8_buf, str), _(utf8_len, len));
#endif
- free(kanji);
}
return (0);
static x11_selection_type s_ptr[1];
-// EUC-JP -> UTF-8 変換。
-// utf8_buf には十分なサイズがあると仮定している。
-// 出力文字列は0終端される。
-static void euc_to_utf8(const char *const euc, char *const utf8_buf, const size_t utf8_buf_len)
-{
- static iconv_t cd = NULL;
- if (!cd)
- cd = iconv_open("UTF-8", "EUC-JP");
-
- size_t inlen = strlen(euc);
- size_t outlen = utf8_buf_len;
- const char *in = euc;
- char *out = utf8_buf;
- // iconv は入力バッファを書き換えないのでキャストで const を外してよい
- iconv(cd, (char **)&in, &inlen, &out, &outlen);
-
- const size_t n = utf8_buf_len - outlen;
- utf8_buf[n] = '\0';
-}
-
-/*
- * Convert to EUC-JP
- */
-#ifdef USE_XIM
-static void convert_to_euc(char *buf)
-{
- size_t inlen = strlen(buf);
- size_t outlen_orig = inlen + 1;
- size_t outlen = outlen_orig;
- char tmp[outlen];
-
- iconv_t iconvd = iconv_open("EUC-JP", "UTF-8");
- char *inbuf = buf;
- char *outbuf = tmp;
- iconv(iconvd, &inbuf, &inlen, &outbuf, &outlen);
- iconv_close(iconvd);
-
- size_t n = outlen_orig - outlen;
- memcpy(buf, tmp, n);
- buf[n] = '\0';
-}
-#endif
-
// ゲーム側へキーを送る
static void send_key(const char key)
{
#ifdef USE_XIM
if (!valid_keysym) { /* XIMからの入力時のみ FALSE になる */
- convert_to_euc(buf);
- send_keys(buf);
+#ifdef JP
+ char euc_buf[sizeof(buf)];
+ /* strlen + 1 を渡して文字列終端('\0')を含めて変換する */
+ if (utf8_to_euc(buf, strlen(buf) + 1, euc_buf, sizeof(euc_buf)) < 0) {
+ return;
+ }
+#endif
+ send_keys(_(euc_buf, buf));
return;
}
#endif
buf[l] = '\0';
+#ifdef JP
char utf8_buf[2048];
- euc_to_utf8(buf, utf8_buf, sizeof(utf8_buf));
-
- XChangeProperty(DPY, rq->requestor, rq->property, xa_utf8, 8, PropModeAppend, (unsigned char *)utf8_buf, (int)strlen(utf8_buf));
+ const int len = euc_to_utf8(buf, l, utf8_buf, sizeof(utf8_buf));
+#endif
+ if (_(len, l) > 0) {
+ XChangeProperty(DPY, rq->requestor, rq->property, xa_utf8, 8, PropModeAppend, (unsigned char *)_(utf8_buf, buf), _(len, l));
+ }
}
return TRUE;