Develop and Download Open Source Software

Browse Subversion Repository

Annotation of /trunk/teraterm/teraterm/charset.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 10763 - (hide annotations) (download) (as text)
Wed Jun 14 14:24:25 2023 UTC (9 months, 4 weeks ago) by zmatsuo
Original Path: trunk/teraterm/teraterm/charset.c
File MIME type: text/x-csrc
File size: 19558 byte(s)
受信文字コードがUTF-8の時の不正な文字の扱いを修正

- UTF-8として不正な文字の扱いを変更
  - 修正前は常にISO8859-1 として扱っていた
- FallbackToCP932=OFF時
  - '?' を表示
- FallbackToCP932=ON時
  - 日本語/UTF-8の時、可能ならShift_JISとして扱う
  - その他の場合は ISO8859-1 として扱う

ticket #48226
1 zmatsuo 10755 /*
2     * (C) 2023- TeraTerm Project
3     * All rights reserved.
4     *
5     * Redistribution and use in source and binary forms, with or without
6     * modification, are permitted provided that the following conditions
7     * are met:
8     *
9     * 1. Redistributions of source code must retain the above copyright
10     * notice, this list of conditions and the following disclaimer.
11     * 2. Redistributions in binary form must reproduce the above copyright
12     * notice, this list of conditions and the following disclaimer in the
13     * documentation and/or other materials provided with the distribution.
14     * 3. The name of the author may not be used to endorse or promote products
15     * derived from this software without specific prior written permission.
16     *
17     * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
18     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20     * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27     */
28    
29     #include "teraterm.h"
30     #include "tttypes.h"
31     #include <stdio.h>
32     #include <string.h>
33     #if !defined(_CRTDBG_MAP_ALLOC)
34     #define _CRTDBG_MAP_ALLOC
35     #endif
36     #include <stdlib.h>
37     #include <crtdbg.h>
38     #include <assert.h>
39    
40     #include "buffer.h" // for Wrap
41     #include "ttwinman.h"
42     #include "codeconv.h"
43     #include "unicode.h"
44     #include "language.h" // for JIS2SJIS()
45 zmatsuo 10763 #include "ttcstd.h"
46 zmatsuo 10755
47     #include "charset.h"
48    
49 zmatsuo 10763 // UTF-8���s�����l�����������\����������
50     #define REPLACEMENT_CHARACTER '?'
51     //#define REPLACEMENT_CHARACTER 0x2592
52     //#define REPLACEMENT_CHARACTER 0x20
53     //#define REPLACEMENT_CHARACTER 0xfffd
54    
55 zmatsuo 10755 static BOOL KanjiIn; // TRUE = MBCS��1byte�������M��������
56     static BOOL EUCkanaIn, EUCsupIn;
57     static int EUCcount;
58     #if 0
59     static BOOL Special;
60     #endif
61    
62     /* GL for single shift 2/3 */
63     static int GLtmp;
64     /* single shift 2/3 flag */
65     static BOOL SSflag;
66     /* JIS -> SJIS conversion flag */
67     static BOOL ConvJIS;
68     static WORD Kanji;
69 zmatsuo 10763 static BOOL Fallbacked;
70 zmatsuo 10755
71     typedef struct {
72     /* GL, GR code group */
73     int Glr[2];
74     /* G0, G1, G2, G3 code group */
75     int Gn[4];
76 zmatsuo 10763 //
77     char32_t replacement_char;
78 zmatsuo 10755 } VttermKanjiWork;
79    
80     static VttermKanjiWork KanjiWork;
81    
82 zmatsuo 10760 // Unicode�x�[�X����������
83     static void PutChar(BYTE b)
84     {
85     PutU32(b);
86     }
87 zmatsuo 10755
88     /**
89     * ISO2022�p���[�N������������
90     */
91     static void CharSetInit2(VttermKanjiWork *w)
92     {
93     if (ts.Language==IdJapanese) {
94     w->Gn[0] = IdASCII;
95     w->Gn[1] = IdKatakana;
96     w->Gn[2] = IdKatakana;
97     w->Gn[3] = IdKanji;
98     w->Glr[0] = 0;
99     if ((ts.KanjiCode==IdJIS) && (ts.JIS7Katakana==0))
100     w->Glr[1] = 2; // 8-bit katakana
101     else
102     w->Glr[1] = 3;
103     }
104     else {
105     w->Gn[0] = IdASCII;
106     w->Gn[1] = IdSpecial;
107     w->Gn[2] = IdASCII;
108     w->Gn[3] = IdASCII;
109     w->Glr[0] = 0;
110     w->Glr[1] = 0;
111     }
112     }
113    
114     /**
115     * �������A���[�N������������
116     */
117     void CharSetInit(void)
118     {
119 zmatsuo 10763 VttermKanjiWork *w = &KanjiWork;
120    
121     CharSetInit2(w);
122    
123     w->replacement_char = REPLACEMENT_CHARACTER;
124 zmatsuo 10755 SSflag = FALSE;
125    
126     KanjiIn = FALSE;
127     EUCkanaIn = FALSE;
128     EUCsupIn = FALSE;
129     ConvJIS = FALSE;
130     Fallbacked = FALSE;
131     }
132    
133     /**
134     * 1byte���`�F�b�N
135     */
136     static BOOL CheckFirstByte(BYTE b, int lang, int kanji_code)
137     {
138     switch (lang) {
139     case IdKorean:
140     return __ismbblead(b, 51949);
141     case IdChinese:
142     if (kanji_code == IdCnGB2312) {
143     return __ismbblead(b, 936);
144     }
145     else if (ts.KanjiCode == IdCnBig5) {
146     return __ismbblead(b, 950);
147     }
148     break;
149     default:
150     assert(FALSE);
151     break;
152     }
153     assert(FALSE);
154     return FALSE;
155     }
156 zmatsuo 10763
157 zmatsuo 10755 /**
158 zmatsuo 10763 * Double-byte Character Sets
159     * SJIS��1byte��?
160     *
161     * ��1�o�C�g0x81...0x9F or 0xE0...0xEF
162     * ��1�o�C�g0x81...0x9F or 0xE0...0xFC
163     */
164     static BOOL ismbbleadSJIS(BYTE b)
165     {
166     if (((0x80<b) && (b<0xa0)) || ((0xdf<b) && (b<0xfd))) {
167     return TRUE;
168     }
169     return FALSE;
170     }
171    
172     /**
173 zmatsuo 10755 * ts.Language == IdJapanese ��
174     * 1byte���`�F�b�N
175     */
176     static BOOL CheckKanji(BYTE b)
177     {
178     VttermKanjiWork *w = &KanjiWork;
179     BOOL Check;
180    
181     if (ts.Language!=IdJapanese)
182     return FALSE;
183    
184     ConvJIS = FALSE;
185    
186     if (ts.KanjiCode==IdSJIS ||
187     (ts.FallbackToCP932 && ts.KanjiCode==IdUTF8)) {
188 zmatsuo 10759 if (((0x80<b) && (b<0xa0)) || ((0xdf<b) && (b<0xfd))) {
189 zmatsuo 10755 Fallbacked = TRUE;
190     return TRUE; // SJIS kanji
191     }
192     if ((0xa1<=b) && (b<=0xdf)) {
193     return FALSE; // SJIS katakana
194     }
195     }
196    
197     if ((b>=0x21) && (b<=0x7e)) {
198     Check = (w->Gn[w->Glr[0]] == IdKanji);
199     ConvJIS = Check;
200     }
201     else if ((b>=0xA1) && (b<=0xFE)) {
202     Check = (w->Gn[w->Glr[1]] == IdKanji);
203     if (ts.KanjiCode==IdEUC) {
204     Check = TRUE;
205     }
206     else if (ts.KanjiCode==IdJIS && ((ts.TermFlag & TF_FIXEDJIS)!=0) && (ts.JIS7Katakana==0)) {
207     Check = FALSE; // 8-bit katakana
208     }
209     ConvJIS = Check;
210     }
211     else {
212     Check = FALSE;
213     }
214    
215     return Check;
216     }
217    
218     static BOOL ParseFirstJP(BYTE b)
219     // returns TRUE if b is processed
220     // (actually allways returns TRUE)
221     {
222     VttermKanjiWork *w = &KanjiWork;
223     if (KanjiIn) {
224 zmatsuo 10759 if (((! ConvJIS) && (0x3F<b) && (b<0xFD)) ||
225     (ConvJIS && ( ((0x20<b) && (b<0x7f)) ||
226     ((0xa0<b) && (b<0xff)) )) )
227 zmatsuo 10755 {
228 zmatsuo 10758 unsigned long u32;
229     Kanji = Kanji + b;
230     if (ConvJIS) {
231     // JIS -> Shift_JIS(CP932)
232     Kanji = JIS2SJIS((WORD)(Kanji & 0x7f7f));
233     }
234     u32 = CP932ToUTF32(Kanji);
235     PutU32(u32);
236 zmatsuo 10755 KanjiIn = FALSE;
237     return TRUE;
238     }
239     else if ((ts.TermFlag & TF_CTRLINKANJI)==0) {
240     KanjiIn = FALSE;
241     }
242     else if ((b==CR) && Wrap) {
243     CarriageReturn(FALSE);
244     LineFeed(LF,FALSE);
245     Wrap = FALSE;
246     }
247     }
248    
249     if (SSflag) {
250     if (w->Gn[GLtmp] == IdKanji) {
251     Kanji = b << 8;
252     KanjiIn = TRUE;
253     SSflag = FALSE;
254     return TRUE;
255     }
256     else if (w->Gn[GLtmp] == IdKatakana) {
257     b = b | 0x80;
258     }
259    
260     PutChar(b);
261     SSflag = FALSE;
262     return TRUE;
263     }
264    
265     if ((!EUCsupIn) && (!EUCkanaIn) && (!KanjiIn) && CheckKanji(b)) {
266     Kanji = b << 8;
267     KanjiIn = TRUE;
268     return TRUE;
269     }
270    
271     if (b<=US) {
272     ParseControl(b);
273     }
274     else if (b==0x20) {
275     PutChar(b);
276     }
277     else if ((b>=0x21) && (b<=0x7E)) {
278     if (EUCsupIn) {
279     EUCcount--;
280     EUCsupIn = (EUCcount==0);
281     return TRUE;
282     }
283    
284     if ((w->Gn[w->Glr[0]] == IdKatakana) || EUCkanaIn) {
285     b = b | 0x80;
286     EUCkanaIn = FALSE;
287     {
288     // b��sjis�����p�J�^�J�i
289     unsigned long u32 = CP932ToUTF32(b);
290     PutU32(u32);
291     }
292     return TRUE;
293     }
294     PutChar(b);
295     }
296     else if (b==0x7f) {
297     return TRUE;
298     }
299     else if ((b>=0x80) && (b<=0x8D)) {
300     ParseControl(b);
301     }
302     else if (b==0x8E) { // SS2
303     switch (ts.KanjiCode) {
304     case IdEUC:
305     if (ts.ISO2022Flag & ISO2022_SS2) {
306     EUCkanaIn = TRUE;
307     }
308     break;
309     case IdUTF8:
310 zmatsuo 10763 PutU32(REPLACEMENT_CHARACTER);
311 zmatsuo 10755 break;
312     default:
313     ParseControl(b);
314     }
315     }
316     else if (b==0x8F) { // SS3
317     switch (ts.KanjiCode) {
318     case IdEUC:
319     if (ts.ISO2022Flag & ISO2022_SS3) {
320     EUCcount = 2;
321     EUCsupIn = TRUE;
322     }
323     break;
324     case IdUTF8:
325 zmatsuo 10763 PutU32(REPLACEMENT_CHARACTER);
326 zmatsuo 10755 break;
327     default:
328     ParseControl(b);
329     }
330     }
331     else if ((b>=0x90) && (b<=0x9F)) {
332     ParseControl(b);
333     }
334     else if (b==0xA0) {
335     PutChar(0x20);
336     }
337     else if ((b>=0xA1) && (b<=0xFE)) {
338     if (EUCsupIn) {
339     EUCcount--;
340     EUCsupIn = (EUCcount==0);
341     return TRUE;
342     }
343    
344     if ((w->Gn[w->Glr[1]] != IdASCII) ||
345 zmatsuo 10759 ((ts.KanjiCode==IdEUC) && EUCkanaIn) ||
346 zmatsuo 10755 (ts.KanjiCode==IdSJIS) ||
347 zmatsuo 10759 ((ts.KanjiCode==IdJIS) &&
348     (ts.JIS7Katakana==0) &&
349     ((ts.TermFlag & TF_FIXEDJIS)!=0))) {
350 zmatsuo 10755 // b��sjis�����p�J�^�J�i
351     unsigned long u32 = CP932ToUTF32(b);
352     PutU32(u32);
353     } else {
354     if (w->Gn[w->Glr[1]] == IdASCII) {
355     b = b & 0x7f;
356     }
357     PutChar(b);
358     }
359     EUCkanaIn = FALSE;
360     }
361     else {
362     PutChar(b);
363     }
364    
365     return TRUE;
366     }
367    
368     static BOOL ParseFirstKR(BYTE b)
369     // returns TRUE if b is processed
370     // (actually allways returns TRUE)
371     {
372     VttermKanjiWork *w = &KanjiWork;
373     if (KanjiIn) {
374 zmatsuo 10759 if (((0x41<=b) && (b<=0x5A)) ||
375     ((0x61<=b) && (b<=0x7A)) ||
376     ((0x81<=b) && (b<=0xFE)))
377 zmatsuo 10755 {
378 zmatsuo 10758 unsigned long u32 = 0;
379     if (ts.KanjiCode == IdKoreanCP51949) {
380     // CP51949
381     Kanji = Kanji + b;
382     u32 = MBCP_UTF32(Kanji, 51949);
383     }
384     else {
385     assert(FALSE);
386     }
387     PutU32(u32);
388 zmatsuo 10755 KanjiIn = FALSE;
389     return TRUE;
390     }
391     else if ((ts.TermFlag & TF_CTRLINKANJI)==0) {
392     KanjiIn = FALSE;
393     }
394     else if ((b==CR) && Wrap) {
395     CarriageReturn(FALSE);
396     LineFeed(LF,FALSE);
397     Wrap = FALSE;
398     }
399     }
400    
401     if ((!KanjiIn) && CheckFirstByte(b, ts.Language, ts.KanjiCode)) {
402     Kanji = b << 8;
403     KanjiIn = TRUE;
404     return TRUE;
405     }
406    
407     if (b<=US) {
408     ParseControl(b);
409     }
410     else if (b==0x20) {
411     PutChar(b);
412     }
413     else if ((b>=0x21) && (b<=0x7E)) {
414     // if (Gn[Glr[0]] == IdKatakana) {
415     // b = b | 0x80;
416     // }
417     PutChar(b);
418     }
419     else if (b==0x7f) {
420     return TRUE;
421     }
422     else if ((0x80<=b) && (b<=0x9F)) {
423     ParseControl(b);
424     }
425     else if (b==0xA0) {
426     PutChar(0x20);
427     }
428     else if ((b>=0xA1) && (b<=0xFE)) {
429     if (w->Gn[w->Glr[1]] == IdASCII) {
430     b = b & 0x7f;
431     }
432     PutChar(b);
433     }
434     else {
435     PutChar(b);
436     }
437    
438     return TRUE;
439     }
440    
441     static BOOL ParseFirstCn(BYTE b)
442     // returns TRUE if b is processed
443     // (actually allways returns TRUE)
444     {
445     VttermKanjiWork *w = &KanjiWork;
446     if (KanjiIn) {
447     // TODO
448 zmatsuo 10759 if (((0x40<=b) && (b<=0x7e)) ||
449     ((0xa1<=b) && (b<=0xFE)))
450 zmatsuo 10755 {
451 zmatsuo 10758 unsigned long u32 = 0;
452     Kanji = Kanji + b;
453     if (ts.KanjiCode == IdCnGB2312) {
454     // CP936 GB2312
455     u32 = MBCP_UTF32(Kanji, 936);
456     }
457     else if (ts.KanjiCode == IdCnBig5) {
458     // CP950 Big5
459     u32 = MBCP_UTF32(Kanji, 950);
460     }
461     else {
462     assert(FALSE);
463     }
464     PutU32(u32);
465 zmatsuo 10755 KanjiIn = FALSE;
466     return TRUE;
467     }
468     else if ((ts.TermFlag & TF_CTRLINKANJI)==0) {
469     KanjiIn = FALSE;
470     }
471     else if ((b==CR) && Wrap) {
472     CarriageReturn(FALSE);
473     LineFeed(LF,FALSE);
474     Wrap = FALSE;
475     }
476     }
477    
478     if ((!KanjiIn) && CheckFirstByte(b, ts.Language, ts.KanjiCode)) {
479     Kanji = b << 8;
480     KanjiIn = TRUE;
481     return TRUE;
482     }
483    
484     if (b<=US) {
485     ParseControl(b);
486     }
487     else if (b==0x20) {
488     PutChar(b);
489     }
490     else if ((b>=0x21) && (b<=0x7E)) {
491     // if (Gn[Glr[0]] == IdKatakana) {
492     // b = b | 0x80;
493     // }
494     PutChar(b);
495     }
496     else if (b==0x7f) {
497     return TRUE;
498     }
499     else if ((0x80<=b) && (b<=0x9F)) {
500     ParseControl(b);
501     }
502     else if (b==0xA0) {
503     PutChar(0x20);
504     }
505     else if ((b>=0xA1) && (b<=0xFE)) {
506     if (w->Gn[w->Glr[1]] == IdASCII) {
507     b = b & 0x7f;
508     }
509     PutChar(b);
510     }
511     else {
512     PutChar(b);
513     }
514    
515     return TRUE;
516     }
517    
518     static void ParseASCII(BYTE b)
519     {
520     if (SSflag) {
521     PutChar(b);
522     SSflag = FALSE;
523     return;
524     }
525    
526     if (b<=US) {
527     ParseControl(b);
528     } else if ((b>=0x20) && (b<=0x7E)) {
529 zmatsuo 10760 PutU32(b);
530 zmatsuo 10755 } else if ((b==0x8E) || (b==0x8F)) {
531 zmatsuo 10763 PutU32(REPLACEMENT_CHARACTER);
532 zmatsuo 10755 } else if ((b>=0x80) && (b<=0x9F)) {
533     ParseControl(b);
534     } else if (b>=0xA0) {
535 zmatsuo 10760 PutU32(b);
536 zmatsuo 10755 }
537     }
538    
539 zmatsuo 10763 static void PutReplacementChr(VttermKanjiWork *w, const BYTE *ptr, size_t len)
540     {
541     const char32_t replacement_char = w->replacement_char;
542     int i;
543     for (i = 0; i < len; i++) {
544     BYTE c = *ptr++;
545     if (c < 0x80) {
546     // �s����UTF-8��������������0x80�������������A
547     // 1������UTF-8�������������������\������
548     ParseASCII(c);
549     }
550     else {
551     PutU32(replacement_char);
552     }
553     }
554     }
555    
556 zmatsuo 10755 // UTF-8�����M�f�[�^����������
557     // returns TRUE if b is processed
558     // (actually allways returns TRUE)
559     static BOOL ParseFirstUTF8(BYTE b)
560     {
561 zmatsuo 10763 VttermKanjiWork *w = &KanjiWork;
562 zmatsuo 10755 static BYTE buf[4];
563     static int count = 0;
564    
565     unsigned int code;
566     int i;
567    
568 zmatsuo 10763 if (Fallbacked) {
569     BOOL r = ParseFirstJP(b);
570     Fallbacked = FALSE;
571     return r;
572 zmatsuo 10755 }
573    
574 zmatsuo 10763 if (b < 0x20) {
575     PutReplacementChr(w, buf, count);
576     count = 0;
577     ParseASCII(b);
578     return TRUE;
579     }
580    
581 zmatsuo 10755 // UTF-8�G���R�[�h
582     // Unicode 1byte, 2byte, 3byte, 4byte
583     // U+0000 ... U+007f 0x00 .. 0x7f
584     // U+0080 ... U+07ff 0xc2 .. 0xdf, 0x80 .. 0xbf
585     // U+0800 ... U+ffff 0xe0 .. 0xef, 0x80 .. 0xbf, 0x80 .. 0xbf
586     // U+10000 ... U+10ffff 0xf0 .. 0xf4, 0x80 .. 0xbf, 0x80 .. 0xbf, 0x80 .. 0xbf
587     // UTF-8���f�R�[�h������������
588     // - 1byte��
589     // - C1(0x80 - 0x9f)
590     // - 0xa0 - 0xc1
591     // - 0xf5 - 0xff
592     // - 2byte�����~
593     // - 0x00 - 0x7f
594     // - 0xc0 - 0xff
595 zmatsuo 10763 recheck:
596 zmatsuo 10755 // 1byte(7bit)
597     if (count == 0) {
598     if ((b & 0x80) == 0x00) {
599     // 1byte(7bit)
600     // 0x7f����, �������A���������o��
601     ParseASCII(b);
602     return TRUE;
603     }
604     if ((b & 0x40) == 0x00 || b >= 0xf6 ) {
605 zmatsuo 10763 // UTF-8��1byte���o���������R�[�h������
606 zmatsuo 10755 // 0x40 = 0b1011_1111, 0b10xx_xxxx������bit�p�^�[��������������
607     // 0xf6 ���������� U+10FFFF��������������
608 zmatsuo 10763 if (ts.FallbackToCP932) {
609     // fallback��������
610     if ((ts.Language == IdJapanese) && ismbbleadSJIS(b)) {
611     // ���{�������� && Shift_JIS 1byte��
612     // Shift_JIS �� fallback
613     Fallbacked = TRUE;
614     ConvJIS = FALSE;
615     Kanji = b << 8;
616     KanjiIn = TRUE;
617     return TRUE;
618     }
619     // fallback ISO8859-1
620     PutU32(b);
621     return TRUE;
622     }
623     else {
624     // fallback������, �s������������
625     buf[0] = b;
626     PutReplacementChr(w, buf, 1);
627     }
628 zmatsuo 10755 return TRUE;
629     }
630     // 1byte������
631     buf[count++] = b;
632     return TRUE;
633     }
634    
635     // 2byte(11bit)
636     if ((buf[0] & 0xe0) == 0xc0) {
637     code = 0;
638     if((b & 0xc0) == 0x80) {
639     // 5bit + 6bit
640     code = ((buf[0] & 0x1f) << 6) | (b & 0x3f);
641     if (code < 0x80) {
642     // 11bit�g����7bit���������AUTF-8���������\��
643     code = 0;
644     }
645     }
646     if (code == 0){
647 zmatsuo 10763 if (ts.FallbackToCP932) {
648     // fallback ISO8859-1
649     PutU32(buf[0]);
650     }
651     else {
652     buf[1] = b;
653     PutReplacementChr(w, buf, 1);
654     }
655 zmatsuo 10755 count = 0;
656 zmatsuo 10763 goto recheck;
657 zmatsuo 10755 }
658     else {
659     PutU32(code);
660     count = 0;
661     return TRUE;
662     }
663     }
664    
665     // 2byte�����~����
666     buf[count++] = b;
667    
668     // 3byte(16bit)
669     if ((buf[0] & 0xf0) == 0xe0) {
670     if(count < 3) {
671     return TRUE;
672     }
673     code = 0;
674     if ((buf[1] & 0xc0) == 0x80 && (buf[2] & 0xc0) == 0x80) {
675     // 4bit + 6bit + 6bit
676     code = ((buf[0] & 0xf) << 12);
677     code |= ((buf[1] & 0x3f) << 6);
678     code |= ((buf[2] & 0x3f));
679     if (code < 0x800) {
680     // 16bit�g����11bit�����������AUTF-8���������\��
681     code = 0;
682     }
683     }
684     if (code == 0) {
685 zmatsuo 10763 if (ts.FallbackToCP932) {
686     // fallback ISO8859-1
687     PutU32(buf[0]);
688     PutU32(buf[1]);
689     }
690     else {
691     PutReplacementChr(w, buf, 2);
692     }
693 zmatsuo 10755 count = 0;
694 zmatsuo 10763 goto recheck;
695 zmatsuo 10755 } else {
696     PutU32(code);
697     count = 0;
698     return TRUE;
699     }
700     }
701    
702     // 4byte(21bit)
703     if ((buf[0] & 0xf8) == 0xf0) {
704     if(count < 4) {
705     return TRUE;
706     }
707     code = 0;
708     if ((buf[1] & 0xc0) == 0x80 && (buf[2] & 0xc0) == 0x80 && (buf[3] & 0xc0) == 0x80) {
709     // 3bit + 6bit + 6bit + 6bit
710     code = ((buf[0] & 0x07) << 18);
711     code |= ((buf[1] & 0x3f) << 12);
712     code |= ((buf[2] & 0x3f) << 6);
713     code |= (buf[3] & 0x3f);
714     if (code < 0x10000) {
715     // 21bit�g����16bit�����������AUTF-8���������\��
716     code = 0;
717     }
718     }
719     if (code == 0) {
720 zmatsuo 10763 if (ts.FallbackToCP932) {
721     // fallback ISO8859-1
722     PutU32(buf[0]);
723     PutU32(buf[1]);
724     PutU32(buf[2]);
725     }
726     else {
727     PutReplacementChr(w, buf, 3);
728     }
729 zmatsuo 10755 count = 0;
730 zmatsuo 10763 goto recheck;
731 zmatsuo 10755 } else {
732     PutU32(code);
733     count = 0;
734     return TRUE;
735     }
736     }
737    
738     // ��������������
739     assert(FALSE);
740    
741     for (i = 0; i < count; i++) {
742     ParseASCII(buf[i]);
743     }
744     count = 0;
745     return TRUE;
746     }
747    
748     static BOOL ParseFirstRus(BYTE b)
749     // returns if b is processed
750     {
751 zmatsuo 10756 // CP1251������
752     BYTE c = RussConv(ts.KanjiCode, IdWindows, b);
753     // CP1251->Unicode
754     unsigned long u32 = MBCP_UTF32(c, 1251);
755     PutU32(u32);
756     return TRUE;
757 zmatsuo 10755 }
758    
759     static BOOL ParseEnglish(BYTE b)
760     {
761     unsigned short u16 = 0;
762     int part = KanjiCodeToISO8859Part(ts.KanjiCode);
763     int r = UnicodeFromISO8859(part, b, &u16);
764     if (r == 0) {
765     return FALSE;
766     }
767     if (u16 < 0x100) {
768     ParseASCII((BYTE)u16);
769     }
770     else {
771     PutU32(u16);
772     }
773     return TRUE;
774     }
775    
776     void ParseFirst(BYTE b) {
777     switch (ts.Language) {
778     case IdUtf8:
779     ParseFirstUTF8(b);
780     return;
781    
782     case IdJapanese:
783     switch (ts.KanjiCode) {
784     case IdUTF8:
785     if (ParseFirstUTF8(b)) {
786     return;
787     }
788     break;
789     default:
790     if (ParseFirstJP(b)) {
791     return;
792     }
793     }
794     break;
795    
796     case IdKorean:
797     switch (ts.KanjiCode) {
798     case IdUTF8:
799     if (ParseFirstUTF8(b)) {
800     return;
801     }
802     break;
803     default:
804     if (ParseFirstKR(b)) {
805     return;
806     }
807     }
808     break;
809    
810     case IdRussian:
811     if (ParseFirstRus(b)) {
812     return;
813     }
814     break;
815    
816     case IdChinese:
817     switch (ts.KanjiCode) {
818     case IdUTF8:
819     if (ParseFirstUTF8(b)) {
820     return;
821     }
822     break;
823     default:
824     if (ParseFirstCn(b)) {
825     return;
826     }
827     }
828     break;
829     case IdEnglish: {
830     if (ParseEnglish(b)) {
831     return;
832     }
833     break;
834     }
835     }
836    
837     if (SSflag) {
838     PutChar(b);
839     SSflag = FALSE;
840     return;
841     }
842    
843     if (b<=US)
844     ParseControl(b);
845     else if ((b>=0x20) && (b<=0x7E))
846     PutChar(b);
847     else if ((b>=0x80) && (b<=0x9F))
848     ParseControl(b);
849     else if (b>=0xA0)
850     PutChar(b);
851     }
852    
853     /**
854     * �w��(Designate)
855     *
856     * @param Gn 0/1/2/3 = G0/G1/G2/G3
857     * @param codeset IdASCII 0
858     * IdKatakana 1
859     * IdKanji 2
860     * IdSpecial 3
861     */
862     void CharSet2022Designate(int gn, int cs)
863     {
864     VttermKanjiWork *w = &KanjiWork;
865     w->Gn[gn] = cs;
866     }
867    
868     /**
869     * �����o��(Invoke)
870     * @param glr 0/1 = GL/GR (Locking shift�������L��)
871     * @param gn 0/1/2/3 = G0/G1/G2/G3
872     * @param single_shift FALSE Locking shift
873     * TRUE Single shift
874     */
875     void CharSet2022Invoke(int glr, int gn, BOOL single_shift)
876     {
877     VttermKanjiWork *w = &KanjiWork;
878     if (single_shift == FALSE) {
879     // Locking shift
880     w->Glr[glr] = gn;
881     }
882     else {
883     // Single shift
884     GLtmp = gn;
885     SSflag = TRUE;
886     }
887     }
888    
889     /**
890     * DEC�����t�H���g(Tera Special font)
891     * 0140(0x60) ... 0176(0x7f) ���r�����A�T�C������������
892 zmatsuo 10760 * (0xe0) ... (0xff) ��?
893 zmatsuo 10755 * <ESC>(0 �������������G�X�P�[�v�V�[�P���X�����`
894     * about/emulations.html
895     *
896     * @param b �R�[�h
897 zmatsuo 10760 * @retval TRUE IdSpecial
898     * @retval FALSE IdSpecial��������
899 zmatsuo 10755 */
900     BOOL CharSetIsSpecial(BYTE b)
901     {
902     VttermKanjiWork *w = &KanjiWork;
903     BOOL SpecialNew = FALSE;
904    
905     if ((b>0x5F) && (b<0x80)) {
906     if (SSflag)
907     SpecialNew = (w->Gn[GLtmp]==IdSpecial);
908     else
909     SpecialNew = (w->Gn[w->Glr[0]]==IdSpecial);
910     }
911     else if (b>0xDF) {
912     if (SSflag)
913     SpecialNew = (w->Gn[GLtmp]==IdSpecial);
914     else
915     SpecialNew = (w->Gn[w->Glr[1]]==IdSpecial);
916     }
917    
918     return SpecialNew;
919     }
920    
921     static void CharSetSaveStateLow(CharSetState *state, const VttermKanjiWork *w)
922     {
923     int i;
924     state->infos[0] = w->Glr[0];
925     state->infos[1] = w->Glr[1];
926     for (i=0 ; i<=3; i++) {
927     state->infos[2 + i] = w->Gn[i];
928     }
929     }
930    
931     /**
932     * ��������������
933     */
934     void CharSetSaveState(CharSetState *state)
935     {
936     VttermKanjiWork *w = &KanjiWork;
937     CharSetSaveStateLow(state, w);
938     }
939    
940     /**
941     * ���������A����
942     */
943     void CharSetLoadState(const CharSetState *state)
944     {
945     VttermKanjiWork *w = &KanjiWork;
946     int i;
947     w->Glr[0] = state->infos[0];
948     w->Glr[1] = state->infos[1];
949     for (i=0 ; i<=3; i++) {
950     w->Gn[i] = state->infos[2 + i];
951     }
952     }
953 zmatsuo 10763
954     /**
955     * �t�H�[���o�b�N���I��
956     * ���M�f�[�^UTF-8�����AShift_JIS�o����(fallback����)�����f����
957     *
958     */
959     void CharSetFallbackFinish(void)
960     {
961     Fallbacked = FALSE;
962     }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26