Intial commit
[profile/ivi/w3m.git] / libwc / viet.c
1
2 #include "wc.h"
3 #include "viet.h"
4 #include "wtf.h"
5 #include "search.h"
6 #ifdef USE_UNICODE
7 #include "ucs.h"
8 #endif
9 #include "map/tcvn57123_tcvn5712.map"
10
11 wc_uint8 wc_c0_tcvn57122_map[ 0x20 ] = {
12     0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,     
13     0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0,     
14 };
15 wc_uint8 wc_c0_viscii112_map[ 0x20 ] = {
16     0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,     
17     0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0,     
18 };
19 wc_uint8 wc_c0_vps2_map[ 0x20 ] = {
20     0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0,     
21     1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0,     
22 };
23 static wc_uint8 tcvn5712_precompose_map[ 0x100 ] = {
24     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
25     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
26     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
27     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
28 /*     A           E           I                 O */
29     0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
30 /*                 U           Y                   */
31     0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
32 /*     a           e           i                 o */
33     0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
34 /*                 u           y                   */
35     0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
36
37     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
38     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
39 /*     A( A^ E^ O^ O+ U+    a( a^ e^ o^ o+ u+      */
40     0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0,
41 /*  `  ?  ~  '  .                                  */
42     2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
43     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
44     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
46     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
47 };
48 static wc_uint8 cp1258_precompose_map[ 0x100 ] = {
49     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
50     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
51     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
52     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
53 /*     A           E           I                 O */
54     0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
55 /*                 U           Y                   */
56     0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
57 /*     a           e           i                 o */
58     0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1,
59 /*                 u           y                   */
60     0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0,
61
62     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
63     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
64     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
65     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
66 /*        A^ A(                   E^    `          */
67     0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0,
68 /*        ?     O^ O+                      U+ ~    */
69     0, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 2, 0,
70 /*        a^ a(                   e^    '          */
71     0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0,
72 /*        .     o^ o+                      u+      */
73     0, 0, 2, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
74 };
75
76 wc_uint32
77 wc_tcvn5712_precompose(wc_uchar c1, wc_uchar c2)
78 {
79     if (tcvn5712_precompose_map[c1] == 1 && tcvn5712_precompose_map[c2] == 2)
80         return ((wc_uint32)c1 << 8) | c2;
81     else
82         return 0;
83 }
84
85 wc_wchar_t
86 wc_tcvn57123_to_tcvn5712(wc_wchar_t cc)
87 {
88     wc_map *map;
89
90     map = wc_map_search((wc_uint16)(cc.code & 0x7f7f),
91         tcvn57123_tcvn5712_map, N_tcvn57123_tcvn5712_map);
92     if (map) {
93         cc.ccs = (map->code2 < 0x20) ? WC_CCS_TCVN_5712_2 : WC_CCS_TCVN_5712_1;
94         cc.code = map->code2 | 0x80;
95     } else {
96         cc.ccs = WC_CCS_UNKNOWN;
97     }
98     return cc;
99 }
100
101 wc_uint32
102 wc_cp1258_precompose(wc_uchar c1, wc_uchar c2)
103 {
104     if (cp1258_precompose_map[c1] == 1 && cp1258_precompose_map[c2] == 2)
105         return ((wc_uint32)c1 << 8) | c2;
106     else
107         return 0;
108 }
109
110 Str
111 wc_conv_from_viet(Str is, wc_ces ces)
112 {
113     Str os;
114     wc_uchar *sp = (wc_uchar *)is->ptr;
115     wc_uchar *ep = sp + is->length;
116     wc_uchar *p;
117     wc_ccs ccs1 = WcCesInfo[WC_CCS_INDEX(ces)].gset[1].ccs;
118     wc_ccs ccs2 = WcCesInfo[WC_CCS_INDEX(ces)].gset[2].ccs;
119     wc_uint8 *map = NULL;
120
121     switch (ces) {
122     case WC_CES_TCVN_5712:
123         map = wc_c0_tcvn57122_map;
124         break;
125     case WC_CES_VISCII_11:
126         map = wc_c0_viscii112_map;
127         break;
128     case WC_CES_VPS:
129         map = wc_c0_vps2_map;
130         break;
131     }
132
133     wc_create_detect_map(ces, WC_FALSE);
134     for (p = sp; p < ep && ! WC_DETECT_MAP[*p]; p++)
135         ;
136     if (p == ep)
137         return is;
138     os = Strnew_size(is->length);
139     if (p > sp)
140         Strcat_charp_n(os, is->ptr, (int)(p - sp));
141
142     for (; p < ep; p++) {
143         if (*p & 0x80)
144             wtf_push(os, ccs1, (wc_uint32)*p);
145         else if (*p < 0x20 && map[*p])
146             wtf_push(os, ccs2, (wc_uint32)*p);
147         else
148             Strcat_char(os, (char)*p);
149     }
150     return os;
151 }
152
153 void
154 wc_push_to_viet(Str os, wc_wchar_t cc, wc_status *st)
155 {
156     wc_ccs ccs1 = st->ces_info->gset[1].ccs;
157     wc_ccs ccs2 = 0, ccs3 = 0;
158     wc_uint8 *map = NULL;
159
160     switch (st->ces_info->id) {
161     case WC_CES_CP1258:
162         ccs3 = st->ces_info->gset[2].ccs;
163         break;
164     case WC_CES_TCVN_5712:
165         map = wc_c0_tcvn57122_map;
166         ccs2 = st->ces_info->gset[2].ccs;
167         ccs3 = st->ces_info->gset[3].ccs;
168         break;
169     case WC_CES_VISCII_11:
170         map = wc_c0_viscii112_map;
171         ccs2 = st->ces_info->gset[2].ccs;
172         break;
173     case WC_CES_VPS:
174         map = wc_c0_vps2_map;
175         ccs2 = st->ces_info->gset[2].ccs;
176         break;
177     }
178
179   while (1) {
180     if (cc.ccs == ccs1) {
181         Strcat_char(os, (char)(cc.code | 0x80));
182         return;
183     } else if (cc.ccs == ccs2) {
184         Strcat_char(os, (char)(cc.code & 0x7f));
185         return;
186     } else if (cc.ccs == ccs3) {
187         Strcat_char(os, (char)((cc.code >> 8) & 0xff));
188         Strcat_char(os, (char)(cc.code & 0xff));
189         return;
190     }
191     switch (cc.ccs) {
192     case WC_CCS_US_ASCII:
193         if (cc.code < 0x20 && map && map[cc.code])
194             Strcat_char(os, ' ');
195         else
196             Strcat_char(os, (char)cc.code);
197         return;
198     case WC_CCS_UNKNOWN_W:
199         if (!WcOption.no_replace)
200             Strcat_charp(os, WC_REPLACE_W);
201         return;
202     case WC_CCS_UNKNOWN:
203         if (!WcOption.no_replace)
204             Strcat_charp(os, WC_REPLACE);
205         return;
206     default:
207 #ifdef USE_UNICODE
208         if (WcOption.ucs_conv)
209             cc = wc_any_to_any_ces(cc, st);
210         else
211 #endif
212             cc.ccs = WC_CCS_IS_WIDE(cc.ccs) ? WC_CCS_UNKNOWN_W : WC_CCS_UNKNOWN;
213         continue;
214     }
215   }
216 }
217
218 Str
219 wc_char_conv_from_viet(wc_uchar c, wc_status *st)
220 {
221     Str os = Strnew_size(1);
222     wc_uint8 *map = NULL;
223
224     switch (st->ces_info->id) {
225     case WC_CES_TCVN_5712:
226         map = wc_c0_tcvn57122_map;
227         break;
228     case WC_CES_VISCII_11:
229         map = wc_c0_viscii112_map;
230         break;
231     case WC_CES_VPS:
232         map = wc_c0_vps2_map;
233         break;
234     }
235
236     if (c & 0x80)
237         wtf_push(os, st->ces_info->gset[1].ccs, (wc_uint32)c);
238     else if (c < 0x20 && map[c])
239         wtf_push(os, st->ces_info->gset[2].ccs, (wc_uint32)c);
240     else
241         Strcat_char(os, (char)c);
242     return os;
243 }