1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxEncodingConverter class for converting between different
5 // Author: Vaclav Slavik
6 // Copyright: (c) 1999 Vaclav Slavik
7 // Licence: wxWindows Licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "encconv.h"
14 // For compilers that support precompilation, includes "wx.h".
15 #include "wx/wxprec.h"
21 #include "wx/encconv.h"
25 #include "unictabl.inc"
26 // conversion tables, generated by scripts in $(WXWIN)/misc/unictabl
29 static wxUint16
*GetEncTable(wxFontEncoding enc
)
31 for (int i
= 0; encodings_list
[i
].table
!= NULL
; i
++)
33 if (encodings_list
[i
].encoding
== enc
)
34 return encodings_list
[i
].table
;
46 static int CompareCharsetItems(const void *i1
, const void *i2
)
48 return ( ((CharsetItem
*)i1
) -> u
- ((CharsetItem
*)i2
) -> u
);
52 static CharsetItem
* BuildReverseTable(wxUint16
*tbl
)
54 CharsetItem
*rev
= new CharsetItem
[128];
56 for (int i
= 0; i
< 128; i
++)
57 rev
[i
].c
= 128 + i
, rev
[i
].u
= tbl
[i
];
59 qsort(rev
, 128, sizeof(CharsetItem
), CompareCharsetItems
);
66 wxEncodingConverter::wxEncodingConverter()
69 m_UnicodeInput
= FALSE
;
75 bool wxEncodingConverter::Init(wxFontEncoding input_enc
, wxFontEncoding output_enc
, int method
)
78 wxUint16
*in_tbl
= NULL
, *out_tbl
= NULL
;
80 if (m_Table
) {delete[] m_Table
; m_Table
= NULL
;}
83 if (input_enc
== wxFONTENCODING_UNICODE
|| output_enc
== wxFONTENCODING_UNICODE
) return FALSE
;
86 if (input_enc
== output_enc
) {m_JustCopy
= TRUE
; return TRUE
;}
90 if (input_enc
== wxFONTENCODING_UNICODE
)
92 if ((out_tbl
= GetEncTable(output_enc
)) == NULL
) return FALSE
;
94 m_Table
= new wxChar
[65536];
95 for (i
= 0; i
< 128; i
++) m_Table
[i
] = (wxChar
)i
; // 7bit ASCII
96 for (i
= 128; i
< 65536; i
++) m_Table
[i
] = (wxChar
)'?';
97 // FIXME - this should be character that means `unicode to charset' impossible, not '?'
99 if (method
== wxCONVERT_SUBSTITUTE
)
101 for (i
= 0; i
< encoding_unicode_fallback_count
; i
++)
102 m_Table
[encoding_unicode_fallback
[i
].c
] = (wxChar
) encoding_unicode_fallback
[i
].s
;
105 for (i
= 0; i
< 128; i
++)
106 m_Table
[out_tbl
[i
]] = (wxChar
)(128 + i
);
108 m_UnicodeInput
= TRUE
;
114 if ((in_tbl
= GetEncTable(input_enc
)) == NULL
) return FALSE
;
115 if (output_enc
!= wxFONTENCODING_UNICODE
)
116 if ((out_tbl
= GetEncTable(output_enc
)) == NULL
) return FALSE
;
118 m_UnicodeInput
= FALSE
;
120 m_Table
= new wxChar
[256];
121 for (i
= 0; i
< 128; i
++) m_Table
[i
] = (wxChar
)i
; // 7bit ASCII
123 if (output_enc
== wxFONTENCODING_UNICODE
)
125 for (i
= 0; i
< 128; i
++) m_Table
[128 + i
] = (wxChar
)in_tbl
[i
]; // wxChar is 2byte now
130 CharsetItem
*rev
= BuildReverseTable(out_tbl
);
131 CharsetItem
*item
, key
;
133 for (i
= 0; i
< 128; i
++)
136 item
= (CharsetItem
*) bsearch(&key
, rev
, 128, sizeof(CharsetItem
), CompareCharsetItems
);
137 if (item
== NULL
&& method
== wxCONVERT_SUBSTITUTE
)
138 item
= (CharsetItem
*) bsearch(&key
, encoding_unicode_fallback
,
139 encoding_unicode_fallback_count
, sizeof(CharsetItem
), CompareCharsetItems
);
141 m_Table
[128 + i
] = (wxChar
)item
-> c
;
143 m_Table
[128 + i
] = 128 + i
; // don't know => don't touch
153 void wxEncodingConverter::Convert(const wxChar
* input
, wxChar
* output
)
157 wxStrcpy(output
, input
);
161 wxASSERT_MSG(m_Table
!= NULL
, wxT("You must call wxEncodingConverter::Init() before actually converting!"));
167 for (i
= input
, o
= output
; *i
!= 0; i
++, o
++)
168 *o
= (wxChar
)(m_Table
[(wxUint16
)*i
]);
170 for (i
= input
, o
= output
; *i
!= 0; i
++, o
++)
171 *o
= (wxChar
)(m_Table
[(wxUint8
)*i
]);
177 wxString
wxEncodingConverter::Convert(const wxString
& input
)
179 if (m_JustCopy
) return input
;
184 wxASSERT_MSG(m_Table
!= NULL
, wxT("You must call wxEncodingConverter::Init() before actually converting!"));
187 for (i
= input
.c_str(); *i
!= 0; i
++)
188 s
<< (wxChar
)(m_Table
[(wxUint16
)*i
]);
190 for (i
= input
.c_str(); *i
!= 0; i
++)
191 s
<< (wxChar
)(m_Table
[(wxUint8
)*i
]);
198 // Following tables describe classes of encoding equivalence.
201 #define STOP wxFONTENCODING_SYSTEM
203 #define NUM_OF_PLATFORMS 4 /*must conform to enum wxPLATFORM_XXXX !!!*/
204 #define ENC_PER_PLATFORM 3
205 // max no. of encodings for one language used on one platform
206 // Anybody thinks 3 is not enough? ;-)
208 static wxFontEncoding
209 EquivalentEncodings
[][NUM_OF_PLATFORMS
][ENC_PER_PLATFORM
+1] = {
211 // West European (Latin1)
213 /* unix */ {wxFONTENCODING_ISO8859_1
, wxFONTENCODING_ISO8859_15
, STOP
},
214 /* windows */ {wxFONTENCODING_CP1252
, STOP
},
219 // Central European (Latin2)
221 /* unix */ {wxFONTENCODING_ISO8859_2
, STOP
},
222 /* windows */ {wxFONTENCODING_CP1250
, STOP
},
227 {{STOP
},{STOP
},{STOP
},{STOP
}} /* Terminator */
228 /* no, _not_ Arnold! */
234 wxFontEncodingArray
wxEncodingConverter::GetPlatformEquivalents(wxFontEncoding enc
, int platform
)
236 if (platform
== wxPLATFORM_CURRENT
)
238 #if defined(__WXMSW__)
239 platform
= wxPLATFORM_WINDOWS
;
240 #elif defined(__WXGTK__) || defined(__WXMOTIF__)
241 platform
= wxPLATFORM_UNIX
;
242 #elif defined(__WXOS2__)
243 platform
= wxPLATFORM_OS2
;
244 #elif defined(__WXMAC__)
245 platform
= wxPLATFORM_MAC
;
251 wxFontEncodingArray arr
;
254 while (EquivalentEncodings
[clas
][0][0] != STOP
)
256 for (i
= 0; i
< NUM_OF_PLATFORMS
; i
++)
257 for (e
= 0; EquivalentEncodings
[clas
][i
][e
] != STOP
; e
++)
258 if (EquivalentEncodings
[clas
][i
][e
] == enc
)
260 for (f
= EquivalentEncodings
[clas
][platform
]; *f
!= STOP
; f
++)
261 if (arr
.Index(*f
) == wxNOT_FOUND
) arr
.Add(*f
);
262 i
= NUM_OF_PLATFORMS
/*hack*/; break;
272 wxFontEncodingArray
wxEncodingConverter::GetAllEquivalents(wxFontEncoding enc
)
276 wxFontEncodingArray arr
;
279 while (EquivalentEncodings
[clas
][0][0] != STOP
)
281 for (i
= 0; i
< NUM_OF_PLATFORMS
; i
++)
282 for (e
= 0; EquivalentEncodings
[clas
][i
][e
] != STOP
; e
++)
283 if (EquivalentEncodings
[clas
][i
][e
] == enc
)
285 for (j
= 0; j
< NUM_OF_PLATFORMS
; j
++)
286 for (f
= EquivalentEncodings
[clas
][j
]; *f
!= STOP
; f
++)
287 if (arr
.Index(*f
) == wxNOT_FOUND
) arr
.Add(*f
);
288 i
= NUM_OF_PLATFORMS
/*hack*/; break;