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);
999
i = combchars[root]->prev;
1000
/* FIXME: delete old char from all buffers */
1002
else if (!combchars[i])
1004
combchars[i] = (struct combchar *)malloc(sizeof(struct combchar));
1007
combchars[i]->prev = i;
1008
combchars[i]->next = i;
1010
combchars[i]->c1 = c1;
1011
combchars[i]->c2 = c;
1012
mc->image = i & 0xff;
1013
mc->font = (i >> 8) + 0xd8;
1014
debug3("combinig char %x %x -> %x\n", c1, c, i + 0xd800);
1015
comb_tofront(root, i);
1021
WinSwitchEncoding(p, encoding)
1025
p->w_encoding = encoding;
1039
c1 = (unsigned char)*s1;
1040
if (c1 >= 'A' && c1 <= 'Z')
1042
if (!(c1 >= 'a' && c1 <= 'z') && !(c1 >= '0' && c1 <= '9'))
1047
c2 = (unsigned char)*s2;
1048
if (c2 >= 'A' && c2 <= 'Z')
1050
if (!(c2 >= 'a' && c2 <= 'z') && !(c2 >= '0' && c2 <= '9'))
1070
debug1("FindEncoding %s\n", name);
1071
if (name == 0 || *name == 0)
1073
if (encmatch(name, "euc"))
1075
if (encmatch(name, "off") || encmatch(name, "iso8859-1"))
1078
if (encmatch(name, "UTF-8"))
1081
for (encoding = 0; encoding < (int)(sizeof(encodings)/sizeof(*encodings)); encoding++)
1082
if (encmatch(name, encodings[encoding].name))
1085
LoadFontTranslationsForEncoding(encoding);
1093
EncodingName(encoding)
1096
if (encoding >= (int)(sizeof(encodings)/sizeof(*encodings)))
1098
return encodings[encoding].name;
1102
EncodingDefFont(encoding)
1105
return encodings[encoding].deffont;
1113
int encoding = p->w_encoding;
1115
c = encodings[encoding].charsets;
1119
LoadFontTranslationsForEncoding(encoding);
1121
if (encodings[encoding].usegr)
1124
p->w_FontE = encodings[encoding].charsets[1];
1128
if (encodings[encoding].noc1)
1133
DecodeChar(c, encoding, statep)
1140
debug2("Decoding char %02x for encoding %d\n", c, encoding);
1142
if (encoding == UTF8)
1143
return FromUtf8(c, statep);
1145
if (encoding == SJIS)
1149
if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef))
1154
return c | (KANA << 16);
1159
if (0x40 <= t && t <= 0xfc && t != 0x7f)
1161
if (c <= 0x9f) c = (c - 0x81) * 2 + 0x21;
1162
else c = (c - 0xc1) * 2 + 0x21;
1163
if (t <= 0x7e) t -= 0x1f;
1164
else if (t <= 0x9e) t -= 0x20;
1165
else t -= 0x7e, c++;
1166
return (c << 8) | t | (KANJI << 16);
1170
if (encoding == EUC_JP || encoding == EUC_KR || encoding == EUC_CN)
1184
if (encoding == EUC_JP)
1187
return t | (KANA << 16);
1190
*statep = t | (KANJI0212 << 8);
1197
if (encoding == EUC_KR)
1198
return c | (3 << 16);
1199
if (encoding == EUC_CN)
1200
return c | (1 << 16);
1201
if (c & (KANJI0212 << 16))
1204
return c | (KANJI << 16);
1206
if (encoding == BIG5 || encoding == GBK)
1212
if (encoding == GBK && c == 0x80)
1213
return 0xa4 | (('b'|0x80) << 16);
1223
return c << 8 | t | (encoding == BIG5 ? 030 << 16 : 031 << 16);
1225
return c | (encodings[encoding].deffont << 16);
1229
EncodeChar(bp, c, encoding, fontp)
1237
debug2("Encoding char %02x for encoding %d\n", c, encoding);
1238
if (c == -1 && fontp)
1253
if (encoding == UTF8)
1261
c = (c >> 8 & 0xff) | (f << 8);
1262
c = recode_char_dw_to_encoding(c, &c2, encoding);
1267
c = (c & 0xff) | (f << 8);
1268
c = recode_char_to_encoding(c, encoding);
1271
return ToUtf8(bp, c);
1273
if ((c & 0xff00) && f == 0) /* is_utf8? */
1276
if (utf8_isdouble(c))
1279
c = recode_char_dw_to_encoding(c, &c2, encoding);
1280
c = (c << 8) | (c2 & 0xff);
1285
c = recode_char_to_encoding(c, encoding);
1286
c = ((c & 0xff00) << 8) | (c & 0xff);
1288
debug1("Encode: char mapped from utf8 to %x\n", c);
1292
if (f & 0x80) /* map special 96-fonts to latin1 */
1295
if (encoding == SJIS)
1298
c = (c & 0xff) | 0x80;
1299
else if (f == KANJI)
1304
c = (c >> 8) & 0xff;
1305
t += (c & 1) ? ((t <= 0x5f) ? 0x1f : 0x20) : 0x7e;
1306
c = (c - 0x21) / 2 + ((c < 0x5f) ? 0x81 : 0xc1);
1312
if (encoding == EUC)
1327
*bp++ = (c >> 8) | 0x80;
1343
if ((encoding == EUC_KR && f == 3) || (encoding == EUC_CN && f == 1))
1347
*bp++ = (c >> 8) | 0x80;
1352
if ((encoding == BIG5 && f == 030) || (encoding == GBK && f == 031))
1356
*bp++ = (c >> 8) | 0x80;
1361
if (encoding == GBK && f == 0 && c == 0xa4)
1365
if (fontp && f != *fontp)
1405
CanEncodeFont(encoding, f)
1415
return f == KANJI || f == KANA;
1417
return f == KANJI || f == KANA || f == KANJI0212;
1434
PrepareEncodedChar(c)
1441
encoding = D_encoding;
1444
if (encoding == SJIS)
1448
else if (f == KANJI)
1450
t += (c & 1) ? ((t <= 0x5f) ? 0x1f : 0x20) : 0x7e;
1451
c = (c - 0x21) / 2 + ((c < 0x5f) ? 0x81 : 0xc1);
1456
if (encoding == EUC)
1475
if ((encoding == EUC_KR && f == 3) || (encoding == EUC_CN && f == 1))
1480
if ((encoding == BIG5 && f == 030) || (encoding == GBK && f == 031))
1487
RecodeBuf(fbuf, flen, fenc, tenc, tbuf)
1488
unsigned char *fbuf;
1491
unsigned char *tbuf;
1494
int decstate = 0, font = 0;
1496
for (i = j = 0; i < flen; i++)
1499
c = DecodeChar(c, fenc, &decstate);
1504
j += EncodeChar(tbuf ? (char *)tbuf + j : 0, c, tenc, &font);
1506
j += EncodeChar(tbuf ? (char *)tbuf + j : 0, -1, tenc, &font);
1512
ContainsSpecialDeffont(ml, xs, xe, encoding)
1517
unsigned char *f, *i;
1520
if (encoding == UTF8 || encodings[encoding].deffont == 0)
1530
x = recode_char_to_encoding(c | (encodings[encoding].deffont << 8), UTF8);
1533
debug2("ContainsSpecialDeffont: yes %02x != %02x\n", c, x);
1537
debug("ContainsSpecialDeffont: no\n");
1543
LoadFontTranslation(font, file)
1547
char buf[1024], *myfile;
1552
unsigned short (*p)[2], (*tab)[2];
1557
if (font == 0 || screenencodings == 0)
1559
if (strlen(screenencodings) > sizeof(buf) - 10)
1561
sprintf(buf, "%s/%02x", screenencodings, font & 0xff);
1564
debug1("LoadFontTranslation: trying %s\n", myfile);
1565
if ((f = secfopen(myfile, "r")) == 0)
1571
if (getc(f) != "ScreenI2UTF8"[i])
1573
if (getc(f) != 0) /* format */
1575
fo = getc(f); /* id */
1578
if (font != -1 && font != fo)
1586
while ((x = getc(f)) && x != EOF)
1587
getc(f); /* skip font name (padded to 2 bytes) */
1588
if ((p = malloc(sizeof(*p) * (i + 1))) == 0)
1594
x = x << 8 | getc(f);
1607
if (i || (tab[0][0] & 0x8000))
1612
if (recodetabs[fo].tab && (recodetabs[fo].flags & RECODETAB_ALLOCED) != 0)
1613
free(recodetabs[fo].tab);
1614
recodetabs[fo].tab = tab;
1615
recodetabs[fo].flags = RECODETAB_ALLOCED;
1616
debug1("Successful load of recodetab %02x\n", fo);
1628
if (font != -1 && file == 0 && recodetabs[font].flags == 0)
1629
recodetabs[font].flags = RECODETAB_TRIED;
1634
LoadFontTranslationsForEncoding(encoding)
1640
debug1("LoadFontTranslationsForEncoding: encoding %d\n", encoding);
1641
if ((c = encodings[encoding].fontlist) != 0)
1642
while ((f = (unsigned char)*c++) != 0)
1643
if (recodetabs[f].flags == 0)
1644
LoadFontTranslation(f, 0);
1645
f = encodings[encoding].deffont;
1646
if (f > 0 && recodetabs[f].flags == 0)
1647
LoadFontTranslation(f, 0);
1652
#else /* !ENCODINGS */
1654
/* Simple version of EncodeChar to encode font changes for
1658
EncodeChar(bp, c, encoding, fontp)
1665
f = (c == -1) ? 0 : c >> 16;
1667
if (fontp && f != *fontp)
1708
#endif /* ENCODINGS */