1 /* Copyright (c) 1993-2003
2 * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
3 * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
4 * Copyright (c) 1987 Oliver Laumann
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (see the file COPYING); if not, write to the
18 * Free Software Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21 ****************************************************************
24 #include <sys/types.h>
32 extern unsigned char *null
;
33 extern struct display
*display
, *displays
;
34 extern struct layer
*flayer
;
36 extern char *screenencodings
;
38 static int encmatch
__P((char *, char *));
40 static int recode_char
__P((int, int, int));
41 static int recode_char_to_encoding
__P((int, int));
42 static void comb_tofront
__P((int, int));
44 static int recode_char_dw
__P((int, int *, int, int));
45 static int recode_char_dw_to_encoding
__P((int, int *, int));
59 /* KOI8-R font: 96 ! */
60 /* CP1251 font: 96 ? */
62 struct encoding encodings
[] = {
63 { "C", 0, 0, 0, 0, 0 },
64 { "eucJP", "B\002I\00401", 0, 1, 0, "\002\004I" },
65 { "SJIS", "BIBB01", 0, 1, 1, "\002I" },
66 { "eucKR", "B\003BB01", 0, 1, 0, "\003" },
67 { "eucCN", "B\001BB01", 0, 1, 0, "\001" },
68 { "Big5", "B\030BB01", 0, 1, 0, "\030" },
69 { "KOI8-R", 0, 0x80|'!', 0, 1, 0 },
70 { "CP1251", 0, 0x80|'?', 0, 1, 0 },
71 { "UTF-8", 0, -1, 0, 0, 0 },
72 { "ISO8859-2", 0, 0x80|'B', 0, 0, 0 },
73 { "ISO8859-3", 0, 0x80|'C', 0, 0, 0 },
74 { "ISO8859-4", 0, 0x80|'D', 0, 0, 0 },
75 { "ISO8859-5", 0, 0x80|'L', 0, 0, 0 },
76 { "ISO8859-6", 0, 0x80|'G', 0, 0, 0 },
77 { "ISO8859-7", 0, 0x80|'F', 0, 0, 0 },
78 { "ISO8859-8", 0, 0x80|'H', 0, 0, 0 },
79 { "ISO8859-9", 0, 0x80|'M', 0, 0, 0 },
80 { "ISO8859-10", 0, 0x80|'V', 0, 0, 0 },
81 { "ISO8859-15", 0, 0x80|'b', 0, 0, 0 },
82 { "jis", 0, 0, 0, 0, "\002\004I" },
83 { "GBK", "B\031BB01", 0x80|'b', 1, 1, "\031" }
88 static unsigned short builtin_tabs
[][2] = {
89 { 0x30, 0 }, /* 0: special graphics (line drawing) */
124 { 0x34, 0 }, /* 4: Dutch */
136 { 0x35, 0 }, /* 5: Finnish */
148 { 0x36, 0 }, /* 6: Norwegian/Danish */
161 { 0x37, 0 }, /* 7: Swedish */
174 { 0x3d, 0}, /* =: Swiss */
189 { 0x41, 0}, /* A: UK */
193 { 0x4b, 0}, /* K: German */
204 { 0x51, 0}, /* Q: French Canadian */
217 { 0x52, 0}, /* R: French */
229 { 0x59, 0}, /* Y: Italian */
242 { 0x5a, 0}, /* Z: Spanish */
253 { 0xe2, 0}, /* 96-b: ISO-8859-15 */
264 { 0x4a, 0}, /* J: JIS 0201 Roman */
269 { 0x49, 0}, /* I: halfwidth katakana */
271 { 0x005f|0x8000, 0xff9f },
279 unsigned short (*tab
)[2];
283 #define RECODETAB_ALLOCED 1
284 #define RECODETAB_BUILTIN 2
285 #define RECODETAB_TRIED 4
287 static struct recodetab recodetabs
[256];
292 unsigned short (*p
)[2];
293 for (p
= builtin_tabs
; (*p
)[0]; p
++)
295 recodetabs
[(*p
)[0]].flags
= RECODETAB_BUILTIN
;
296 recodetabs
[(*p
)[0]].tab
= p
+ 1;
304 recode_char(c
, to_utf
, font
)
308 unsigned short (*p
)[2];
316 /* map aliases to keep the table small */
331 p
= recodetabs
[f
].tab
;
332 if (p
== 0 && recodetabs
[f
].flags
== 0)
334 LoadFontTranslation(f
, 0);
335 p
= recodetabs
[f
].tab
;
340 if ((p
[0][0] & 0x8000) && (c
<= (p
[0][0] & 0x7fff)) && c
>= p
[-1][0])
341 return c
- p
[-1][0] + p
[-1][1];
345 return c
& 0xff; /* map to latin1 */
350 return c
; /* latin1 */
351 for (font
= 32; font
< 128; font
++)
353 p
= recodetabs
[font
].tab
;
357 if ((p
[0][0] & 0x8000) && c
<= p
[0][1] && c
>= p
[-1][1])
358 return (c
- p
[-1][1] + p
[-1][0]) | (font
<< 8);
360 return (*p
)[0] | (font
<< 8);
365 if (c
< 128 && (font
& 128) != 0)
369 p
= recodetabs
[font
].tab
;
370 if (p
== 0 && recodetabs
[font
].flags
== 0)
372 LoadFontTranslation(font
, 0);
373 p
= recodetabs
[font
].tab
;
378 if ((p
[0][0] & 0x8000) && c
<= p
[0][1] && c
>= p
[-1][1])
379 return (c
- p
[-1][1] + p
[-1][0]) | (font
& 128 ? 0 : font
<< 8);
381 return (*p
)[0] | (font
& 128 ? 0 : font
<< 8);
390 recode_char_dw(c
, c2p
, to_utf
, font
)
391 int c
, *c2p
, to_utf
, font
;
394 unsigned short (*p
)[2];
399 c
= (c
& 255) << 8 | (*c2p
& 255);
401 p
= recodetabs
[f
].tab
;
402 if (p
== 0 && recodetabs
[f
].flags
== 0)
404 LoadFontTranslation(f
, 0);
405 p
= recodetabs
[f
].tab
;
412 if (!utf8_isdouble((*p
)[1]))
421 for (font
= 0; font
< 030; font
++)
423 p
= recodetabs
[font
].tab
;
428 *c2p
= ((*p
)[0] & 255) | font
<< 8 | 0x8000;
429 return ((*p
)[0] >> 8) | font
<< 8;
437 p
= recodetabs
[font
].tab
;
438 if (p
== 0 && recodetabs
[font
].flags
== 0)
440 LoadFontTranslation(font
, 0);
441 p
= recodetabs
[font
].tab
;
447 *c2p
= ((*p
)[0] & 255) | font
<< 8 | 0x8000;
448 return ((*p
)[0] >> 8) | font
<< 8;
456 recode_char_to_encoding(c
, encoding
)
462 if (encoding
== UTF8
)
463 return recode_char(c
, 1, -1);
464 if ((fp
= encodings
[encoding
].fontlist
) != 0)
466 if ((x
= recode_char(c
, 0, (unsigned char)*fp
++)) != -1)
468 if (encodings
[encoding
].deffont
)
469 if ((x
= recode_char(c
, 0, encodings
[encoding
].deffont
)) != -1)
471 return recode_char(c
, 0, -1);
476 recode_char_dw_to_encoding(c
, c2p
, encoding
)
477 int c
, *c2p
, encoding
;
482 if (encoding
== UTF8
)
483 return recode_char_dw(c
, c2p
, 1, -1);
484 if ((fp
= encodings
[encoding
].fontlist
) != 0)
486 if ((x
= recode_char_dw(c
, c2p
, 0, (unsigned char)*fp
++)) != -1)
488 if (encodings
[encoding
].deffont
)
489 if ((x
= recode_char_dw(c
, c2p
, 0, encodings
[encoding
].deffont
)) != -1)
491 return recode_char_dw(c
, c2p
, 0, -1);
497 recode_mchar(mc
, from
, to
)
501 static struct mchar rmc
;
504 debug3("recode_mchar %02x from %d to %d\n", mc
->image
, from
, to
);
505 if (from
== to
|| (from
!= UTF8
&& to
!= UTF8
))
508 if (rmc
.font
== 0 && from
!= UTF8
)
509 rmc
.font
= encodings
[from
].deffont
;
510 if (rmc
.font
== 0) /* latin1 is the same in unicode */
512 c
= rmc
.image
| (rmc
.font
<< 8);
517 c
= recode_char_dw_to_encoding(c
, &c2
, to
);
522 c
= recode_char_to_encoding(c
, to
);
524 rmc
.font
= c
>> 8 & 255;
529 recode_mline(ml
, w
, from
, to
)
536 static struct mline rml
[2], *rl
;
539 if (from
== to
|| (from
!= UTF8
&& to
!= UTF8
) || w
== 0)
541 if (ml
->font
== null
&& encodings
[from
].deffont
== 0)
545 for (i
= 0; i
< 2; i
++)
547 if (rml
[i
].image
== 0)
548 rml
[i
].image
= malloc(w
);
550 rml
[i
].image
= realloc(rml
[i
].image
, w
);
551 if (rml
[i
].font
== 0)
552 rml
[i
].font
= malloc(w
);
554 rml
[i
].font
= realloc(rml
[i
].font
, w
);
555 if (rml
[i
].image
== 0 || rml
[i
].font
== 0)
558 return ml
; /* sorry */
564 debug("recode_mline: from\n");
565 for (i
= 0; i
< w
; i
++)
566 debug1("%c", "0123456789abcdef"[(ml
->image
[i
] >> 4) & 15]);
568 for (i
= 0; i
< w
; i
++)
569 debug1("%c", "0123456789abcdef"[(ml
->image
[i
] ) & 15]);
571 for (i
= 0; i
< w
; i
++)
572 debug1("%c", "0123456789abcdef"[(ml
->font
[i
] >> 4) & 15]);
574 for (i
= 0; i
< w
; i
++)
575 debug1("%c", "0123456789abcdef"[(ml
->font
[i
] ) & 15]);
581 rl
->color
= ml
->color
;
583 rl
->colorx
= ml
->colorx
;
586 for (i
= 0; i
< w
; i
++)
588 c
= ml
->image
[i
] | (ml
->font
[i
] << 8);
589 if (from
!= UTF8
&& c
< 256)
590 c
|= encodings
[from
].deffont
<< 8;
592 if ((from
!= UTF8
&& (c
& 0x1f00) != 0 && (c
& 0xe000) == 0) || (from
== UTF8
&& utf8_isdouble(c
)))
600 c2
= ml
->image
[i
] | (ml
->font
[i
] << 8);
601 c
= recode_char_dw_to_encoding(c
, &c2
, to
);
602 rl
->font
[i
- 1] = c
>> 8 & 255;
603 rl
->image
[i
- 1] = c
& 255;
609 c
= recode_char_to_encoding(c
, to
);
610 rl
->image
[i
] = c
& 255;
611 rl
->font
[i
] = c
>> 8 & 255;
614 debug("recode_mline: to\n");
615 for (i
= 0; i
< w
; i
++)
616 debug1("%c", "0123456789abcdef"[(rl
->image
[i
] >> 4) & 15]);
618 for (i
= 0; i
< w
; i
++)
619 debug1("%c", "0123456789abcdef"[(rl
->image
[i
] ) & 15]);
621 for (i
= 0; i
< w
; i
++)
622 debug1("%c", "0123456789abcdef"[(rl
->font
[i
] >> 4) & 15]);
624 for (i
= 0; i
< w
; i
++)
625 debug1("%c", "0123456789abcdef"[(rl
->font
[i
] ) & 15]);
636 struct combchar
**combchars
;
642 ASSERT(D_encoding
== UTF8
);
643 if (c
>= 0xd800 && c
< 0xe000 && combchars
&& combchars
[c
- 0xd800])
645 AddUtf8(combchars
[c
- 0xd800]->c1
);
646 c
= combchars
[c
- 0xd800]->c2
;
650 AddChar((c
& 0xf000) >> 12 | 0xe0);
651 c
= (c
& 0x0fff) | 0x1000;
655 AddChar((c
& 0x1fc0) >> 6 ^ 0xc0);
656 c
= (c
& 0x3f) | 0x80;
668 if (c
>= 0xd800 && c
< 0xe000 && combchars
&& combchars
[c
- 0xd800])
670 l
= ToUtf8_comb(p
, combchars
[c
- 0xd800]->c1
);
671 return l
+ ToUtf8(p
? p
+ l
: 0, combchars
[c
- 0xd800]->c2
);
685 *p
++ = (c
& 0xf000) >> 12 | 0xe0;
687 c
= (c
& 0x0fff) | 0x1000;
692 *p
++ = (c
& 0x1fc0) >> 6 ^ 0xc0;
694 c
= (c
& 0x3f) | 0x80;
703 * -1: need more bytes, sequence not finished
704 * -2: corrupt sequence found, redo last char
705 * >= 0: decoded character
708 FromUtf8(c
, utf8charp
)
711 int utf8char
= *utf8charp
;
714 if ((c
& 0xc0) != 0x80)
717 return -2; /* corrupt sequence! */
720 c
= (c
& 0x3f) | (utf8char
<< 6);
721 if (!(utf8char
& 0x40000000))
723 /* check for overlong sequences */
724 if ((c
& 0x820823e0) == 0x80000000)
726 else if ((c
& 0x020821f0) == 0x02000000)
728 else if ((c
& 0x000820f8) == 0x00080000)
730 else if ((c
& 0x0000207c) == 0x00002000)
740 c
= (c
& 0x01) | 0xbffffffc; /* 5 bytes to follow */
742 c
= (c
& 0x03) | 0xbfffff00; /* 4 */
744 c
= (c
& 0x07) | 0xbfffc000; /* 3 */
746 c
= (c
& 0x0f) | 0xbff00000; /* 2 */
748 c
= (c
& 0x1f) | 0xfc000000; /* 1 */
750 c
= 0xfdffffff; /* overlong */
754 *utf8charp
= utf8char
= (c
& 0x80000000) ? c
: 0;
758 c
= UCS_REPL
; /* sorry, only know 16bit Unicode */
759 if (c
>= 0xd800 && (c
<= 0xdfff || c
== 0xfffe || c
== 0xffff))
760 c
= UCS_REPL
; /* illegal code */
766 WinSwitchEncoding(p
, encoding
)
774 struct layer
*oldflayer
;
776 if ((p
->w_encoding
== UTF8
) == (encoding
== UTF8
))
778 p
->w_encoding
= encoding
;
782 for (d
= displays
; d
; d
= d
->d_next
)
783 for (cv
= d
->d_cvlist
; cv
; cv
= cv
->c_next
)
784 if (p
== Layer2Window(cv
->c_layer
))
786 flayer
= cv
->c_layer
;
787 while(flayer
->l_next
)
789 if (oldflayer
== flayer
)
790 oldflayer
= flayer
->l_next
;
795 for (j
= 0; j
< p
->w_height
+ p
->w_histheight
; j
++)
798 ml
= j
< p
->w_height
? &p
->w_mlines
[j
] : &p
->w_hlines
[j
- p
->w_height
];
800 ml
= &p
->w_mlines
[j
];
802 if (ml
->font
== null
&& encodings
[p
->w_encoding
].deffont
== 0)
804 for (i
= 0; i
< p
->w_width
; i
++)
806 c
= ml
->image
[i
] | (ml
->font
[i
] << 8);
807 if (p
->w_encoding
!= UTF8
&& c
< 256)
808 c
|= encodings
[p
->w_encoding
].deffont
<< 8;
811 if (ml
->font
== null
)
813 if ((ml
->font
= (unsigned char *)malloc(p
->w_width
+ 1)) == 0)
818 bzero(ml
->font
, p
->w_width
+ 1);
821 if ((p
->w_encoding
!= UTF8
&& (c
& 0x1f00) != 0 && (c
& 0xe000) == 0) || (p
->w_encoding
== UTF8
&& utf8_isdouble(c
)))
823 if (i
+ 1 == p
->w_width
)
829 c2
= ml
->image
[i
] | (ml
->font
[i
] << 8);
830 c
= recode_char_dw_to_encoding(c
, &c2
, encoding
);
831 ml
->font
[i
- 1] = c
>> 8 & 255;
832 ml
->image
[i
- 1] = c
& 255;
838 c
= recode_char_to_encoding(c
, encoding
);
839 ml
->image
[i
] = c
& 255;
840 ml
->font
[i
] = c
>> 8 & 255;
843 p
->w_encoding
= encoding
;
854 (c
<= 0x115f || /* Hangul Jamo init. consonants */
855 (c
>= 0x2e80 && c
<= 0xa4cf && (c
& ~0x0011) != 0x300a &&
856 c
!= 0x303f) || /* CJK ... Yi */
857 (c
>= 0xac00 && c
<= 0xd7a3) || /* Hangul Syllables */
858 (c
>= 0xdf00 && c
<= 0xdfff) || /* dw combining sequence */
859 (c
>= 0xf900 && c
<= 0xfaff) || /* CJK Compatibility Ideographs */
860 (c
>= 0xfe30 && c
<= 0xfe6f) || /* CJK Compatibility Forms */
861 (c
>= 0xff00 && c
<= 0xff5f) || /* Fullwidth Forms */
862 (c
>= 0xffe0 && c
<= 0xffe6) ||
863 (c
>= 0x20000 && c
<= 0x2ffff)));
871 /* taken from Markus Kuhn's wcwidth */
873 unsigned short first
;
876 { 0x0300, 0x034F }, { 0x0360, 0x036F }, { 0x0483, 0x0486 },
877 { 0x0488, 0x0489 }, { 0x0591, 0x05A1 }, { 0x05A3, 0x05B9 },
878 { 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 },
879 { 0x05C4, 0x05C4 }, { 0x064B, 0x0655 }, { 0x0670, 0x0670 },
880 { 0x06D6, 0x06E4 }, { 0x06E7, 0x06E8 }, { 0x06EA, 0x06ED },
881 { 0x070F, 0x070F }, { 0x0711, 0x0711 }, { 0x0730, 0x074A },
882 { 0x07A6, 0x07B0 }, { 0x0901, 0x0902 }, { 0x093C, 0x093C },
883 { 0x0941, 0x0948 }, { 0x094D, 0x094D }, { 0x0951, 0x0954 },
884 { 0x0962, 0x0963 }, { 0x0981, 0x0981 }, { 0x09BC, 0x09BC },
885 { 0x09C1, 0x09C4 }, { 0x09CD, 0x09CD }, { 0x09E2, 0x09E3 },
886 { 0x0A02, 0x0A02 }, { 0x0A3C, 0x0A3C }, { 0x0A41, 0x0A42 },
887 { 0x0A47, 0x0A48 }, { 0x0A4B, 0x0A4D }, { 0x0A70, 0x0A71 },
888 { 0x0A81, 0x0A82 }, { 0x0ABC, 0x0ABC }, { 0x0AC1, 0x0AC5 },
889 { 0x0AC7, 0x0AC8 }, { 0x0ACD, 0x0ACD }, { 0x0B01, 0x0B01 },
890 { 0x0B3C, 0x0B3C }, { 0x0B3F, 0x0B3F }, { 0x0B41, 0x0B43 },
891 { 0x0B4D, 0x0B4D }, { 0x0B56, 0x0B56 }, { 0x0B82, 0x0B82 },
892 { 0x0BC0, 0x0BC0 }, { 0x0BCD, 0x0BCD }, { 0x0C3E, 0x0C40 },
893 { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D }, { 0x0C55, 0x0C56 },
894 { 0x0CBF, 0x0CBF }, { 0x0CC6, 0x0CC6 }, { 0x0CCC, 0x0CCD },
895 { 0x0D41, 0x0D43 }, { 0x0D4D, 0x0D4D }, { 0x0DCA, 0x0DCA },
896 { 0x0DD2, 0x0DD4 }, { 0x0DD6, 0x0DD6 }, { 0x0E31, 0x0E31 },
897 { 0x0E34, 0x0E3A }, { 0x0E47, 0x0E4E }, { 0x0EB1, 0x0EB1 },
898 { 0x0EB4, 0x0EB9 }, { 0x0EBB, 0x0EBC }, { 0x0EC8, 0x0ECD },
899 { 0x0F18, 0x0F19 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 },
900 { 0x0F39, 0x0F39 }, { 0x0F71, 0x0F7E }, { 0x0F80, 0x0F84 },
901 { 0x0F86, 0x0F87 }, { 0x0F90, 0x0F97 }, { 0x0F99, 0x0FBC },
902 { 0x0FC6, 0x0FC6 }, { 0x102D, 0x1030 }, { 0x1032, 0x1032 },
903 { 0x1036, 0x1037 }, { 0x1039, 0x1039 }, { 0x1058, 0x1059 },
904 { 0x1160, 0x11FF }, { 0x1712, 0x1714 }, { 0x1732, 0x1734 },
905 { 0x1752, 0x1753 }, { 0x1772, 0x1773 }, { 0x17B7, 0x17BD },
906 { 0x17C6, 0x17C6 }, { 0x17C9, 0x17D3 }, { 0x180B, 0x180E },
907 { 0x18A9, 0x18A9 }, { 0x200B, 0x200F }, { 0x202A, 0x202E },
908 { 0x2060, 0x2063 }, { 0x206A, 0x206F }, { 0x20D0, 0x20EA },
909 { 0x302A, 0x302F }, { 0x3099, 0x309A }, { 0xFB1E, 0xFB1E },
910 { 0xFE00, 0xFE0F }, { 0xFE20, 0xFE23 }, { 0xFEFF, 0xFEFF },
913 int mid
, min
= 0, max
= sizeof(combining
)/sizeof(*combining
) - 1;
915 if (c
< 0x0300 || c
> 0xfffb)
919 mid
= (min
+ max
) / 2;
920 if (c
> combining
[mid
].last
)
922 else if (c
< combining
[mid
].first
)
931 comb_tofront(root
, i
)
936 debug1("bring to front: %x\n", i
);
937 combchars
[combchars
[i
]->prev
]->next
= combchars
[i
]->next
;
938 combchars
[combchars
[i
]->next
]->prev
= combchars
[i
]->prev
;
939 combchars
[i
]->next
= combchars
[root
]->next
;
940 combchars
[i
]->prev
= root
;
941 combchars
[combchars
[root
]->next
]->prev
= i
;
942 combchars
[root
]->next
= i
;
943 i
= combchars
[i
]->c1
;
944 if (i
< 0xd800 || i
>= 0xe000)
951 utf8_handle_comb(c
, mc
)
958 c1
= mc
->image
| (mc
->font
<< 8);
959 isdouble
= c1
>= 0x1100 && utf8_isdouble(c1
);
962 combchars
= (struct combchar
**)malloc(sizeof(struct combchar
*) * 0x802);
965 bzero((char *)combchars
, sizeof(struct combchar
*) * 0x802);
966 combchars
[0x800] = (struct combchar
*)malloc(sizeof(struct combchar
));
967 combchars
[0x801] = (struct combchar
*)malloc(sizeof(struct combchar
));
968 if (!combchars
[0x800] || !combchars
[0x801])
970 if (combchars
[0x800])
971 free(combchars
[0x800]);
972 if (combchars
[0x801])
973 free(combchars
[0x801]);
977 combchars
[0x800]->c1
= 0x000;
978 combchars
[0x800]->c2
= 0x700;
979 combchars
[0x800]->next
= 0x800;
980 combchars
[0x800]->prev
= 0x800;
981 combchars
[0x801]->c1
= 0x700;
982 combchars
[0x801]->c2
= 0x800;
983 combchars
[0x801]->next
= 0x801;
984 combchars
[0x801]->prev
= 0x801;
986 root
= isdouble
? 0x801 : 0x800;
987 for (i
= combchars
[root
]->c1
; i
< combchars
[root
]->c2
; i
++)
991 if (combchars
[i
]->c1
== c1
&& combchars
[i
]->c2
== c
)
994 if (i
== combchars
[root
]->c2
)
996 /* full, recycle old entry */
997 if (c1
>= 0xd800 && c1
< 0xe000)
998 comb_tofront(root
, c1
- 0xd800);
999 i
= combchars
[root
]->prev
;
1000 if (c1
== i
+ 0xd800)
1002 /* completely full, can't recycle */
1003 debug("utf8_handle_comp: completely full!\n");
1008 /* FIXME: delete old char from all buffers */
1010 else if (!combchars
[i
])
1012 combchars
[i
] = (struct combchar
*)malloc(sizeof(struct combchar
));
1015 combchars
[i
]->prev
= i
;
1016 combchars
[i
]->next
= i
;
1018 combchars
[i
]->c1
= c1
;
1019 combchars
[i
]->c2
= c
;
1020 mc
->image
= i
& 0xff;
1021 mc
->font
= (i
>> 8) + 0xd8;
1022 debug3("combinig char %x %x -> %x\n", c1
, c
, i
+ 0xd800);
1023 comb_tofront(root
, i
);
1029 WinSwitchEncoding(p
, encoding
)
1033 p
->w_encoding
= encoding
;
1047 c1
= (unsigned char)*s1
;
1048 if (c1
>= 'A' && c1
<= 'Z')
1050 if (!(c1
>= 'a' && c1
<= 'z') && !(c1
>= '0' && c1
<= '9'))
1055 c2
= (unsigned char)*s2
;
1056 if (c2
>= 'A' && c2
<= 'Z')
1058 if (!(c2
>= 'a' && c2
<= 'z') && !(c2
>= '0' && c2
<= '9'))
1078 debug1("FindEncoding %s\n", name
);
1079 if (name
== 0 || *name
== 0)
1081 if (encmatch(name
, "euc"))
1083 if (encmatch(name
, "off") || encmatch(name
, "iso8859-1"))
1086 if (encmatch(name
, "UTF-8"))
1089 for (encoding
= 0; encoding
< (int)(sizeof(encodings
)/sizeof(*encodings
)); encoding
++)
1090 if (encmatch(name
, encodings
[encoding
].name
))
1093 LoadFontTranslationsForEncoding(encoding
);
1101 EncodingName(encoding
)
1104 if (encoding
>= (int)(sizeof(encodings
)/sizeof(*encodings
)))
1106 return encodings
[encoding
].name
;
1110 EncodingDefFont(encoding
)
1113 return encodings
[encoding
].deffont
;
1121 int encoding
= p
->w_encoding
;
1123 c
= encodings
[encoding
].charsets
;
1127 LoadFontTranslationsForEncoding(encoding
);
1129 if (encodings
[encoding
].usegr
)
1132 p
->w_FontE
= encodings
[encoding
].charsets
[1];
1136 if (encodings
[encoding
].noc1
)
1141 DecodeChar(c
, encoding
, statep
)
1148 debug2("Decoding char %02x for encoding %d\n", c
, encoding
);
1150 if (encoding
== UTF8
)
1151 return FromUtf8(c
, statep
);
1153 if (encoding
== SJIS
)
1157 if ((0x81 <= c
&& c
<= 0x9f) || (0xe0 <= c
&& c
<= 0xef))
1164 return c
| (KANA
<< 16);
1169 if (0x40 <= t
&& t
<= 0xfc && t
!= 0x7f)
1172 c
= (c
- 0x81) * 2 + 0x21;
1174 c
= (c
- 0xc1) * 2 + 0x21;
1181 return (c
<< 8) | t
| (KANJI
<< 16);
1185 if (encoding
== EUC_JP
|| encoding
== EUC_KR
|| encoding
== EUC_CN
)
1199 if (encoding
== EUC_JP
)
1202 return t
| (KANA
<< 16);
1205 *statep
= t
| (KANJI0212
<< 8);
1212 if (encoding
== EUC_KR
)
1213 return c
| (3 << 16);
1214 if (encoding
== EUC_CN
)
1215 return c
| (1 << 16);
1216 if (c
& (KANJI0212
<< 16))
1219 return c
| (KANJI
<< 16);
1221 if (encoding
== BIG5
|| encoding
== GBK
)
1227 if (encoding
== GBK
&& c
== 0x80)
1228 return 0xa4 | (('b'|0x80) << 16);
1238 return c
<< 8 | t
| (encoding
== BIG5
? 030 << 16 : 031 << 16);
1240 return c
| (encodings
[encoding
].deffont
<< 16);
1244 EncodeChar(bp
, c
, encoding
, fontp
)
1252 debug2("Encoding char %02x for encoding %d\n", c
, encoding
);
1253 if (c
== -1 && fontp
)
1268 if (encoding
== UTF8
)
1276 c
= (c
>> 8 & 0xff) | (f
<< 8);
1277 c
= recode_char_dw_to_encoding(c
, &c2
, encoding
);
1282 c
= (c
& 0xff) | (f
<< 8);
1283 c
= recode_char_to_encoding(c
, encoding
);
1286 return ToUtf8(bp
, c
);
1288 if ((c
& 0xff00) && f
== 0) /* is_utf8? */
1291 if (utf8_isdouble(c
))
1294 c
= recode_char_dw_to_encoding(c
, &c2
, encoding
);
1295 c
= (c
<< 8) | (c2
& 0xff);
1300 c
= recode_char_to_encoding(c
, encoding
);
1301 c
= ((c
& 0xff00) << 8) | (c
& 0xff);
1303 debug1("Encode: char mapped from utf8 to %x\n", c
);
1307 if (f
& 0x80) /* map special 96-fonts to latin1 */
1310 if (encoding
== SJIS
)
1313 c
= (c
& 0xff) | 0x80;
1314 else if (f
== KANJI
)
1319 c
= (c
>> 8) & 0xff;
1320 t
+= (c
& 1) ? ((t
<= 0x5f) ? 0x1f : 0x20) : 0x7e;
1321 c
= (c
- 0x21) / 2 + ((c
< 0x5f) ? 0x81 : 0xc1);
1327 if (encoding
== EUC
)
1342 *bp
++ = (c
>> 8) | 0x80;
1358 if ((encoding
== EUC_KR
&& f
== 3) || (encoding
== EUC_CN
&& f
== 1))
1362 *bp
++ = (c
>> 8) | 0x80;
1367 if ((encoding
== BIG5
&& f
== 030) || (encoding
== GBK
&& f
== 031))
1371 *bp
++ = (c
>> 8) | 0x80;
1376 if (encoding
== GBK
&& f
== 0 && c
== 0xa4)
1380 if (fontp
&& f
!= *fontp
)
1420 CanEncodeFont(encoding
, f
)
1430 return f
== KANJI
|| f
== KANA
;
1432 return f
== KANJI
|| f
== KANA
|| f
== KANJI0212
;
1449 PrepareEncodedChar(c
)
1456 encoding
= D_encoding
;
1459 if (encoding
== SJIS
)
1463 else if (f
== KANJI
)
1465 t
+= (c
& 1) ? ((t
<= 0x5f) ? 0x1f : 0x20) : 0x7e;
1466 c
= (c
- 0x21) / 2 + ((c
< 0x5f) ? 0x81 : 0xc1);
1471 if (encoding
== EUC
)
1490 if ((encoding
== EUC_KR
&& f
== 3) || (encoding
== EUC_CN
&& f
== 1))
1495 if ((encoding
== BIG5
&& f
== 030) || (encoding
== GBK
&& f
== 031))
1502 RecodeBuf(fbuf
, flen
, fenc
, tenc
, tbuf
)
1503 unsigned char *fbuf
;
1506 unsigned char *tbuf
;
1509 int decstate
= 0, font
= 0;
1511 for (i
= j
= 0; i
< flen
; i
++)
1514 c
= DecodeChar(c
, fenc
, &decstate
);
1519 j
+= EncodeChar(tbuf
? (char *)tbuf
+ j
: 0, c
, tenc
, &font
);
1521 j
+= EncodeChar(tbuf
? (char *)tbuf
+ j
: 0, -1, tenc
, &font
);
1527 ContainsSpecialDeffont(ml
, xs
, xe
, encoding
)
1532 unsigned char *f
, *i
;
1535 if (encoding
== UTF8
|| encodings
[encoding
].deffont
== 0)
1545 x
= recode_char_to_encoding(c
| (encodings
[encoding
].deffont
<< 8), UTF8
);
1548 debug2("ContainsSpecialDeffont: yes %02x != %02x\n", c
, x
);
1552 debug("ContainsSpecialDeffont: no\n");
1558 LoadFontTranslation(font
, file
)
1562 char buf
[1024], *myfile
;
1567 unsigned short (*p
)[2], (*tab
)[2];
1572 if (font
== 0 || screenencodings
== 0)
1574 if (strlen(screenencodings
) > sizeof(buf
) - 10)
1576 sprintf(buf
, "%s/%02x", screenencodings
, font
& 0xff);
1579 debug1("LoadFontTranslation: trying %s\n", myfile
);
1580 if ((f
= secfopen(myfile
, "r")) == 0)
1586 if (getc(f
) != "ScreenI2UTF8"[i
])
1588 if (getc(f
) != 0) /* format */
1590 fo
= getc(f
); /* id */
1593 if (font
!= -1 && font
!= fo
)
1601 while ((x
= getc(f
)) && x
!= EOF
)
1602 getc(f
); /* skip font name (padded to 2 bytes) */
1603 if ((p
= malloc(sizeof(*p
) * (i
+ 1))) == 0)
1609 x
= x
<< 8 | getc(f
);
1622 if (i
|| (tab
[0][0] & 0x8000))
1627 if (recodetabs
[fo
].tab
&& (recodetabs
[fo
].flags
& RECODETAB_ALLOCED
) != 0)
1628 free(recodetabs
[fo
].tab
);
1629 recodetabs
[fo
].tab
= tab
;
1630 recodetabs
[fo
].flags
= RECODETAB_ALLOCED
;
1631 debug1("Successful load of recodetab %02x\n", fo
);
1643 if (font
!= -1 && file
== 0 && recodetabs
[font
].flags
== 0)
1644 recodetabs
[font
].flags
= RECODETAB_TRIED
;
1649 LoadFontTranslationsForEncoding(encoding
)
1655 debug1("LoadFontTranslationsForEncoding: encoding %d\n", encoding
);
1656 if ((c
= encodings
[encoding
].fontlist
) != 0)
1657 while ((f
= (unsigned char)*c
++) != 0)
1658 if (recodetabs
[f
].flags
== 0)
1659 LoadFontTranslation(f
, 0);
1660 f
= encodings
[encoding
].deffont
;
1661 if (f
> 0 && recodetabs
[f
].flags
== 0)
1662 LoadFontTranslation(f
, 0);
1667 #else /* !ENCODINGS */
1669 /* Simple version of EncodeChar to encode font changes for
1673 EncodeChar(bp
, c
, encoding
, fontp
)
1680 f
= (c
== -1) ? 0 : c
>> 16;
1682 if (fontp
&& f
!= *fontp
)
1723 #endif /* ENCODINGS */