Intial commit
[profile/ivi/w3m.git] / symbol.c
1
2 #include "fm.h"
3
4 #include "Symbols/alt.sym"
5 #include "Symbols/graph.sym"
6 #ifdef USE_M17N
7 #include "Symbols/eucjp.sym"
8 #include "Symbols/euckr.sym"
9 #include "Symbols/euccn.sym"
10 #include "Symbols/euctw.sym"
11 #include "Symbols/big5.sym"
12 #ifdef USE_UNICODE
13 #include "Symbols/utf8.sym"
14 #endif
15 #include "Symbols/cp850.sym"
16
17 typedef struct {
18     wc_ces ces;
19     char width;
20     char **item;
21     char encode;
22 } symbol_set;
23
24 typedef struct {
25     wc_ces charset;
26     symbol_set *symbol;
27 } charset_symbol_set;
28
29 /* *INDENT-OFF* */
30 static symbol_set alt_symbol_set   = { WC_CES_US_ASCII, 1, alt_symbol,   1 };
31 static symbol_set alt2_symbol_set  = { WC_CES_US_ASCII, 2, alt2_symbol,  1 };
32 static symbol_set eucjp_symbol_set = { WC_CES_EUC_JP,   2, eucjp_symbol, 0 };
33 static symbol_set euckr_symbol_set = { WC_CES_EUC_KR,   2, euckr_symbol, 0 };
34 static symbol_set euccn_symbol_set = { WC_CES_EUC_CN,   2, euccn_symbol, 0 };
35 static symbol_set euctw_symbol_set = { WC_CES_EUC_TW,   2, euctw_symbol, 0 };
36 static symbol_set big5_symbol_set  = { WC_CES_BIG5,     2, big5_symbol,  0 };
37 #ifdef USE_UNICODE
38 static symbol_set utf8_symbol_set  = { WC_CES_UTF_8,    1, utf8_symbol,  0 };
39 #endif
40 static symbol_set cp850_symbol_set = { WC_CES_CP850,    1, cp850_symbol, 0 };
41
42 static charset_symbol_set charset_symbol_list[] = {
43     { WC_CES_EUC_JP,        &eucjp_symbol_set },
44     { WC_CES_SHIFT_JIS,     &eucjp_symbol_set },
45     { WC_CES_ISO_2022_JP,   &eucjp_symbol_set },
46     { WC_CES_ISO_2022_JP_2, &eucjp_symbol_set },
47     { WC_CES_ISO_2022_JP_3, &eucjp_symbol_set },
48     { WC_CES_EUC_KR,        &euckr_symbol_set },
49     { WC_CES_ISO_2022_KR,   &euckr_symbol_set },
50     { WC_CES_JOHAB,         &euckr_symbol_set },
51     { WC_CES_UHC,           &euckr_symbol_set },
52     { WC_CES_EUC_CN,        &euccn_symbol_set },
53     { WC_CES_GBK,           &euccn_symbol_set },
54     { WC_CES_GB18030,       &euccn_symbol_set },
55     { WC_CES_HZ_GB_2312,    &euccn_symbol_set },
56     { WC_CES_ISO_2022_CN,   &euccn_symbol_set },
57     { WC_CES_EUC_TW,        &euctw_symbol_set },
58     { WC_CES_BIG5,          &big5_symbol_set  },
59     { WC_CES_HKSCS,         &big5_symbol_set  },
60 #ifdef USE_UNICODE
61     { WC_CES_UTF_8,         &utf8_symbol_set  },
62 #endif
63     { WC_CES_CP850,         &cp850_symbol_set },
64     { 0, NULL },
65 };
66 /* *INDENT-ON* */
67
68 static wc_ces save_charset = 0;
69 static symbol_set *save_symbol = NULL;
70
71 static void
72 encode_symbol(symbol_set * s)
73 {
74     int i;
75
76     for (i = 0; s->item[i]; i++) {
77         if (*(s->item[i]))
78             s->item[i] = wc_conv(s->item[i], s->ces, InnerCharset)->ptr;
79     }
80     s->encode = 1;
81 }
82
83 char **
84 get_symbol(wc_ces charset, int *width)
85 {
86     charset_symbol_set *p;
87     symbol_set *s = NULL;
88
89     if (charset == save_charset && save_symbol != NULL &&
90         *width == save_symbol->width) {
91         *width = save_symbol->width;
92         return save_symbol->item;
93     }
94     save_charset = charset;
95     for (p = charset_symbol_list; p->charset; p++) {
96         if (charset == p->charset &&
97             (*width == 0 || *width == p->symbol->width)) {
98             s = p->symbol;
99             break;
100         }
101     }
102     if (s == NULL)
103         s = (*width == 2) ? &alt2_symbol_set : &alt_symbol_set;
104     if (s != save_symbol) {
105         if (!s->encode)
106             encode_symbol(s);
107         save_symbol = s;
108     }
109     *width = s->width;
110     return s->item;
111 }
112
113 char **
114 set_symbol(int width)
115 {
116     static char **symbol_buf = NULL;
117     static int save_width = -1;
118     symbol_set *s = &alt_symbol_set;
119     int i;
120     Str tmp;
121
122     if (width == save_width)
123         return symbol_buf;
124     if (symbol_buf == NULL) {
125         for (i = 0; s->item[i]; i++) ;
126         symbol_buf = New_N(char *, i);
127     }
128     for (i = 0; s->item[i]; i++) {
129         tmp = Strnew_size(4);
130         if (width == 2)
131             wtf_push(tmp, WC_CCS_SPECIAL_W, (wc_uint32) (SYMBOL_BASE + i));
132         else
133             wtf_push(tmp, WC_CCS_SPECIAL, (wc_uint32) (SYMBOL_BASE + i));
134         symbol_buf[i] = tmp->ptr;
135     }
136     save_width = width;
137     return symbol_buf;
138 }
139
140 #else
141
142 char **
143 get_symbol(void)
144 {
145     return alt_symbol;
146 }
147 #endif
148
149 void
150 push_symbol(Str str, char symbol, int width, int n)
151 {
152     char buf[2], *p;
153     int i;
154
155 #ifdef USE_M17N
156     if (width == 2)
157         p = alt2_symbol[(int)symbol];
158     else
159 #endif
160         p = alt_symbol[(int)symbol];
161     for (i = 0; i < 2 && *p; i++, p++)
162         buf[i] = (*p == ' ') ? NBSP_CODE : *p;
163
164     Strcat(str, Sprintf("<_SYMBOL TYPE=%d>", symbol));
165     for (; n > 0; n--)
166         Strcat_charp_n(str, buf, i);
167     Strcat_charp(str, "</_SYMBOL>");
168 }