source: vendor/trolltech/current/src/codecs/qisciicodec.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 5.4 KB
Line 
1#include "qisciicodec_p.h"
2#ifndef QT_NO_CODECS
3
4#define QValidChar(u) ((u) ? QChar((u)) : QChar::replacement)
5
6/*!
7 \class QIsciiCodec
8 \brief The QIsciiCodec class provides conversion to and from the ISCII encoding.
9
10 \ingroup i18n
11 \internal
12*/
13
14QIsciiCodec::QIsciiCodec(int i)
15: idx(i)
16{
17}
18
19int QIsciiCodec::mibEnum() const
20{
21 /* There is no MIBEnum for Iscii */
22 return -3000-idx;
23}
24
25
26struct Codecs {
27 const char *name;
28 ushort base;
29};
30
31static const Codecs codecs [] = {
32 { "Iscii-Dev", 0x900 },
33 { "Iscii-Bng", 0x980 },
34 { "Iscii-Pnj", 0xa00 },
35 { "Iscii-Gjr", 0xa80 },
36 { "Iscii-Ori", 0xb00 },
37 { "Iscii-Tml", 0xb80 },
38 { "Iscii-Tlg", 0xc00 },
39 { "Iscii-Knd", 0xc80 },
40 { "Iscii-Mlm", 0xd00 }
41};
42
43const char* QIsciiCodec::name() const
44{
45 return codecs[idx].name;
46}
47
48const char* QIsciiCodec::mimeName() const
49{
50 return codecs[idx].name;
51}
52
53
54int QIsciiCodec::heuristicNameMatch(const char* hint) const
55{
56 const char *p = strchr(hint, '.');
57 if (p)
58 p++;
59 else
60 p = hint;
61
62 if (QString::fromLatin1(p).lower() == QString::fromLatin1(codecs[idx].name).lower())
63 return 4;
64 else
65 return QTextCodec::heuristicNameMatch(hint);
66}
67
68int QIsciiCodec::heuristicContentMatch(const char*, int) const
69{
70 return 0;
71}
72
73#define INV 0xff
74
75/* iscii range from 0xa0 - 0xff */
76static const uchar iscii_to_uni_table[0x60] = {
77 0x00, 0x01, 0x02, 0x03,
78 0x05, 0x06, 0x07, 0x08,
79 0x09, 0x0a, 0x0b, 0x0e,
80 0x0f, 0x20, 0x0d, 0x12,
81
82 0x13, 0x14, 0x11, 0x15,
83 0x16, 0x17, 0x18, 0x19,
84 0x1a, 0x1b, 0x1c, 0x1d,
85 0x1e, 0x1f, 0x20, 0x21,
86
87 0x22, 0x23, 0x24, 0x25,
88 0x26, 0x27, 0x28, 0x29,
89 0x2a, 0x2b, 0x2c, 0x2d,
90 0x2e, 0x2f, 0x5f, 0x30,
91
92 0x31, 0x32, 0x33, 0x34,
93 0x35, 0x36, 0x37, 0x38,
94 0x39, INV, 0x3e, 0x3f,
95 0x40, 0x41, 0x42, 0x43,
96
97 0x46, 0x47, 0x48, 0x45,
98 0x4a, 0x4b, 0x4c, 0x49,
99 0x4d, 0x3c, 0x64, 0x00,
100 0x00, 0x00, 0x00, 0x00,
101
102 0x00, 0x66, 0x67, 0x68,
103 0x69, 0x6a, 0x6b, 0x6c,
104 0x6d, 0x6e, 0x6f, 0x00,
105 0x00, 0x00, 0x00, 0x00
106};
107
108static const uchar uni_to_iscii_table[0x80] = {
109 0x00, 0xa1, 0xa2, 0xa3,
110 0x00, 0xa4, 0xa5, 0xa6,
111 0xa7, 0xa8, 0xa9, 0xaa,
112 0x00, 0xae, 0xab, 0xac,
113
114 0xad, 0xb2, 0xaf, 0xb0,
115 0xb1, 0xb3, 0xb4, 0xb5,
116 0xb6, 0xb7, 0xb8, 0xb9,
117 0xba, 0xbb, 0xbc, 0xbd,
118
119 0xbe, 0xbf, 0xc0, 0xc1,
120 0xc2, 0xc3, 0xc4, 0xc5,
121 0xc6, 0xc7, 0xc8, 0xc9,
122 0xca, 0xcb, 0xcc, 0xcd,
123
124 0xcf, 0xd0, 0xd1, 0xd2,
125 0xd3, 0xd4, 0xd5, 0xd6,
126 0xd7, 0xd8, 0x00, 0x00,
127 0xe9, 0x00, 0xda, 0xdb,
128
129 0xdc, 0xdd, 0xde, 0xdf,
130 0x00, 0xe3, 0xe0, 0xe1,
131 0xe2, 0xe7, 0xe4, 0xe5,
132 0xe6, 0xe8, 0x00, 0x00,
133
134 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00,
136 0x01, 0x02, 0x03, 0x04, // decomposable into the uc codes listed here + nukta
137 0x05, 0x06, 0x07, 0xce,
138
139 0x00, 0x00, 0x00, 0x00,
140 0xea, 0x08, 0xf1, 0xf2,
141 0xf3, 0xf4, 0xf5, 0xf6,
142 0xf7, 0xf8, 0xf9, 0xfa,
143
144 0x00, 0x00, 0x00, 0x00,
145 0x00, 0x00, 0x00, 0x00,
146 0x00, 0x00, 0x00, 0x00,
147 0x00, 0x00, 0x00, 0x00
148};
149
150static const uchar uni_to_iscii_pairs[] = {
151 0x00, 0x00,
152 0x15, 0x3c, // 0x958
153 0x16, 0x3c, // 0x959
154 0x17, 0x3c, // 0x95a
155 0x1c, 0x3c, // 0x95b
156 0x21, 0x3c, // 0x95c
157 0x22, 0x3c, // 0x95d
158 0x2b, 0x3c, // 0x95e
159 0x64, 0x64 // 0x965
160};
161
162
163QCString QIsciiCodec::fromUnicode(const QString& uc, int& len_in_out) const
164{
165 int l = uc.length();
166 if (len_in_out > 0)
167 l = QMIN(l, len_in_out);
168 QCString result(2*l); //worst case
169
170 const QChar *data = uc.unicode();
171 uchar *ch = (uchar *)result.data();
172
173 int base = codecs[idx].base;
174
175 bool halant = false;
176 for (int i =0; i < l; ++i) {
177 int pos = data[i].unicode() - base;
178 if (pos > 0 && pos < 0x80) {
179 uchar iscii = uni_to_iscii_table[pos];
180 if (iscii > 0x80) {
181 *ch++ = iscii;
182 } else if (iscii) {
183 const uchar *pair = uni_to_iscii_pairs + 2*iscii;
184 *ch++ = *pair++;
185 *ch++ = *pair++;
186 } else {
187 *ch++ = '?';
188 }
189 } else {
190 if (data[i].unicode() == 0x200c) { // ZWNJ
191 if (halant)
192 // Consonant Halant ZWNJ -> Consonant Halant Halant
193 *ch++ = 0xe8;
194 } else if (data[i].unicode() == 0x200d) { // ZWJ
195 if (halant)
196 // Consonant Halant ZWJ -> Consonant Halant Nukta
197 *ch++ = 0xe9;
198 } else {
199 *ch++ = '?';
200 }
201 }
202 halant = (pos == 0x4d);
203 }
204 len_in_out = ch - (uchar *)result.data();
205 result.truncate(len_in_out);
206 return result;
207}
208
209QString QIsciiCodec::toUnicode( const char* chars, int len_in ) const
210{
211 QString result;
212 result.setLength(len_in);
213
214 QChar *uc = (QChar *)result.unicode();
215
216 int base = codecs[idx].base;
217
218 bool halant = false;
219 for (int i = 0; i < len_in; ++i) {
220 ushort ch = (uchar) chars[i];
221 if (ch < 0xa0)
222 *uc++ = QValidChar(ch);
223 else {
224 ushort c = iscii_to_uni_table[ch - 0xa0];
225 if (halant && (c == INV || c == 0xe9)) {
226 // Consonant Halant INV -> Consonant Halant ZWJ
227 // Consonant Halant Nukta -> Consonant Halant ZWJ
228 *uc++ = QChar(0x200d);
229 } else if (halant && c == 0xe8) {
230 // Consonant Halant Halant -> Consonant Halant ZWNJ
231 *uc++ = QChar(0x200c);
232 } else {
233 *uc++ = QChar(c+base);
234 }
235 }
236 halant = ((uchar)chars[i] == 0xe8);
237 }
238 return result;
239}
240#endif // QT_NO_CODECS
Note: See TracBrowser for help on using the repository browser.