summaryrefslogtreecommitdiff
path: root/Build/source/texk/ptexenc/unicode-jp.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/ptexenc/unicode-jp.c')
-rw-r--r--Build/source/texk/ptexenc/unicode-jp.c278
1 files changed, 278 insertions, 0 deletions
diff --git a/Build/source/texk/ptexenc/unicode-jp.c b/Build/source/texk/ptexenc/unicode-jp.c
new file mode 100644
index 00000000000..a00cf290744
--- /dev/null
+++ b/Build/source/texk/ptexenc/unicode-jp.c
@@ -0,0 +1,278 @@
+/*
+ unicode-jp.c -- JIS X 0208 <=> UCS-2 converter
+ written by N. Tsuchimura
+*/
+
+#include <ptexenc/c-auto.h>
+#include <ptexenc/unicode-jp.h>
+#include <ptexenc/kanjicnv.h>
+
+#if defined(KANJI_ICONV) && defined(HAVE_ICONV_H)
+#include <iconv.h>
+#include <stdlib.h> /* for atexit() */
+
+#define ICONV_INVALID ((iconv_t)(-1))
+#define ICONV_JIS "ISO-2022-JP"
+#define ICONV_UNI "UCS-2BE"
+
+static int inited = FALSE;
+static iconv_t i_jis2ucs2 = ICONV_INVALID;
+static iconv_t i_ucs22jis = ICONV_INVALID;
+
+#ifdef HAVE_ATEXIT
+static void close_iconv(void)
+#else /* HAVE_ATEXIT */
+static void close_iconv(int dummy1, void *dummy2)
+#endif /* HAVE_ATEXIT */
+{
+ if (i_jis2ucs2 != ICONV_INVALID) iconv_close(i_jis2ucs2);
+ if (i_ucs22jis != ICONV_INVALID) iconv_close(i_ucs22jis);
+}
+
+static void open_iconv(void)
+{
+ inited = true;
+ i_jis2ucs2 = iconv_open(ICONV_UNI, ICONV_JIS);
+ i_ucs22jis = iconv_open(ICONV_JIS, ICONV_UNI);
+
+#ifdef HAVE_ATEXIT
+ atexit(close_iconv);
+#endif /* HAVE_ATEXIT */
+#ifdef HAVE_ON_EXIT
+ on_exit(close_iconv, NULL);
+#endif /* HAVE_ON_EXIT */
+}
+
+/* convert a JIS X 0208 char to UCS-2 */
+static int JIStoUCS2native(int jis)
+{
+ unsigned char jis_seq[8] = {
+ 0x1b, 0x24, 0x42, /* JIS X 0208-1983 */
+ (unsigned char)HI(jis), (unsigned char)LO(jis),
+ 0x1b, 0x28, 0x42, /* ASCII */
+ };
+ unsigned char unicode[2];
+ size_t from = sizeof jis_seq;
+ size_t to = sizeof unicode;
+ char *from_ptr = (char *)jis_seq;
+ char *to_ptr = (char *)unicode;
+
+ if (!inited) open_iconv();
+ if (i_jis2ucs2 == ICONV_INVALID) return 0;
+
+ if (iconv(i_jis2ucs2, &from_ptr, &from, &to_ptr, &to) == (size_t)(-1)) {
+ return 0;
+ }
+ return HILO(unicode[0], unicode[1]);
+}
+
+/* convert a UCS-2 char to JIS X 0208 */
+static int UCS2toJISnative(int ucs2)
+{
+ unsigned char unicode[2] = {
+ (unsigned char)HI(ucs2), (unsigned char)LO(ucs2),
+ };
+ unsigned char jis_seq[10] = { 0,0,0,0,0,0,0,0,0,0 };
+ size_t from = sizeof unicode;
+ size_t to = sizeof jis_seq;
+ char *from_ptr = (char *)unicode;
+ char *to_ptr = (char *)jis_seq;
+ unsigned char *ret = jis_seq;
+
+ if (!inited) open_iconv();
+ if (i_ucs22jis == ICONV_INVALID) return 0;
+
+ if (iconv(i_ucs22jis, &from_ptr, &from, &to_ptr, &to) == (size_t)(-1)) {
+ return 0;
+ }
+ if (ret[0] == 0x1b) ret += 3;
+ return HILO(ret[0], ret[1]);
+}
+
+#else /* KANJI_ICONV && HAVE_ICONV_H */
+
+#include "../../libs/gd/gd-2.0.35/jisx0208.h"
+#define MAXJIS 84
+
+/* convert a JIS X 0208 char to UCS-2 */
+static int JIStoUCS2native(int jis)
+{
+ int hi, low;
+
+ if (jis == 0x2121) return 0x3000; /* UnicodeTbl[0][0] bug fix */
+ hi = HI(jis) - 0x21;
+ low = LO(jis) - 0x21;
+ if (0 <= hi && hi < MAXJIS &&
+ 0 <= low && low < 94) return (int)UnicodeTbl[hi][low];
+ return 0;
+}
+
+/* convert a UCS-2 char to JIS X 0208 */
+static int UCS2toJISnative(int ucs2)
+{
+ int i, j;
+
+ if (ucs2 == 0x3000) return 0x2121; /* UnicodeTbl[0][0] bug fix */
+ for (i=0; i<MAXJIS; i++) {
+ for (j=0; j<94; j++) {
+ if (UnicodeTbl[i][j] == ucs2) {
+ return HILO(i, j) + 0x2121;
+ }
+ }
+ }
+ return 0;
+}
+#endif /* KANJI_ICONV && HAVE_ICONV_H */
+
+
+/*
+ http://euc.jp/i18n/ucsnote.ja.html
+ http://hp.vector.co.jp/authors/VA010341/unicode/
+ http://www.jca.apc.org/~earthian/aozora/0213/jisx0213code.zip
+*/
+static unsigned short int variation[] = {
+ /* JIS X 0208, UCS-2(1), UCS-2(2), ..., 0(sentinel) */
+ 0x2126 /* 1-6 */, 0x2022, 0x2219, 0x22C5, 0x30FB, 0,
+ 0x2131 /* 1-17 */, 0x203E, 0xFFE3, 0,
+ 0x213D /* 1-29 */, 0x2012, 0x2013, 0x2014, 0x2015, 0,
+ 0x2141 /* 1-33 */, 0x223C, 0x223E, 0x301C, 0xFF5E, 0,
+ 0x2142 /* 1-34 */, 0x2016, 0x2225, 0,
+ 0x2143 /* 1-35 */, 0x2223, 0xFF5C, 0,
+ 0x2144 /* 1-36 */, 0x2026, 0x22EF, 0,
+ 0x215D /* 1-61 */, 0x2212, 0xFF0D, 0,
+ 0x216f /* 1-79 */, 0x00A5, 0xFFE5, 0,
+ 0x2171 /* 1-81 */, 0x00A2, 0xFFE0, 0,
+ 0x2172 /* 1-82 */, 0x00A3, 0xFFE1, 0,
+ 0x224C /* 2-44 */, 0x00AC, 0xFFE2, 0,
+ 0x227E /* 2-94 */, 0x20DD, 0x25EF, 0,
+ 0 /* end */
+};
+
+/*
+ voiced sound of kana
+ http://developer.apple.com/technotes/tn/tn1150table.html
+*/
+static unsigned short int voiced_sounds[] = {
+ /* from, to */
+ 0x3046, 0x3094,
+ 0x304B, 0x304C,
+ 0x304D, 0x304E,
+ 0x304F, 0x3050,
+ 0x3051, 0x3052,
+ 0x3053, 0x3054,
+ 0x3055, 0x3056,
+ 0x3057, 0x3058,
+ 0x3059, 0x305A,
+ 0x305B, 0x305C,
+ 0x305D, 0x305E,
+ 0x305F, 0x3060,
+ 0x3061, 0x3062,
+ 0x3064, 0x3065,
+ 0x3066, 0x3067,
+ 0x3068, 0x3069,
+ 0x306F, 0x3070,
+ 0x3072, 0x3073,
+ 0x3075, 0x3076,
+ 0x3078, 0x3079,
+ 0x307B, 0x307C,
+ 0x309D, 0x309E,
+ 0x30A6, 0x30F4,
+ 0x30AB, 0x30AC,
+ 0x30AD, 0x30AE,
+ 0x30AF, 0x30B0,
+ 0x30B1, 0x30B2,
+ 0x30B3, 0x30B4,
+ 0x30B5, 0x30B6,
+ 0x30B7, 0x30B8,
+ 0x30B9, 0x30BA,
+ 0x30BB, 0x30BC,
+ 0x30BD, 0x30BE,
+ 0x30BF, 0x30C0,
+ 0x30C1, 0x30C2,
+ 0x30C4, 0x30C5,
+ 0x30C6, 0x30C7,
+ 0x30C8, 0x30C9,
+ 0x30CF, 0x30D0,
+ 0x30D2, 0x30D3,
+ 0x30D5, 0x30D6,
+ 0x30D8, 0x30D9,
+ 0x30DB, 0x30DC,
+ 0x30EF, 0x30F7,
+ 0x30F0, 0x30F8,
+ 0x30F1, 0x30F9,
+ 0x30F2, 0x30FA,
+ 0x30FD, 0x30FE,
+ 0 /* end mark */
+};
+
+/* semi voiced sound of kana */
+static unsigned short int semi_voiced_sounds[] = {
+ /* from, to */
+ 0x306F, 0x3071,
+ 0x3072, 0x3074,
+ 0x3075, 0x3077,
+ 0x3078, 0x307A,
+ 0x307B, 0x307D,
+ 0x30CF, 0x30D1,
+ 0x30D2, 0x30D4,
+ 0x30D5, 0x30D7,
+ 0x30D8, 0x30DA,
+ 0x30DB, 0x30DD,
+ 0 /* end mark */
+};
+
+/* convert a JIS X 0208 char to UCS-2 */
+int JIStoUCS2(int jis)
+{
+ return JIStoUCS2native(jis);
+}
+
+/* convert a UCS-2 char to JIS X 0208 */
+int UCS2toJIS(int ucs2)
+{
+ int i, j;
+
+ /* first: variation table */
+ for (i=0; variation[i]!=0; i=j+1) {
+ for (j=i+1; variation[j]!=0; j++) {
+ if (variation[j] == ucs2) return variation[i];
+ }
+ }
+
+ /* second: UnicodeTbl[][] */
+ return UCS2toJISnative(ucs2);
+}
+
+
+/* for U+3099 or U+309A */
+int get_voiced_sound(int ucs2, boolean semi)
+{
+ int i;
+ unsigned short int *table;
+
+ if (semi) table = semi_voiced_sounds;
+ else table = voiced_sounds;
+ for (i=0; table[i]!=0; i+=2) {
+ if (ucs2 == table[i]) return table[i+1];
+ }
+ return 0;
+}
+
+#ifdef TEST
+#include <stdio.h>
+int main(int argc, char **argv) {
+ int hi, low;
+ for (hi=0; hi<MAXJIS; hi++) {
+ for (low=0; low<94; low++) {
+ int jis = HILO(hi, low) + 0x2121;
+ int uni = JIStoUCS2(jis);
+ int jis2 = UCS2toJIS(uni);
+ if (uni != 0 && jis != jis2) {
+ printf("0x%x(%c%c) uni=0x%04x, jis2=0x%04x\n",
+ jis, HI(jis)|0x80, LO(jis)|0x80, uni, jis2);
+ }
+ }
+ }
+ return 0;
+}
+#endif /* TEST */