1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_vcl.hxx"
26 #include "salcvt.hxx"
27
28
SalConverterCache()29 SalConverterCache::SalConverterCache()
30 {
31 }
32
33 SalConverterCache*
GetInstance()34 SalConverterCache::GetInstance ()
35 {
36 static SalConverterCache* pCvt = NULL;
37 if (pCvt == NULL)
38 pCvt = new SalConverterCache;
39
40 return pCvt;
41 }
42
~SalConverterCache()43 SalConverterCache::~SalConverterCache()
44 {
45 }
46
47 // ---> FIXME
48 #include <stdio.h>
49 // <---
50
51 rtl_UnicodeToTextConverter
GetU2TConverter(rtl_TextEncoding nEncoding)52 SalConverterCache::GetU2TConverter( rtl_TextEncoding nEncoding )
53 {
54 if( rtl_isOctetTextEncoding( nEncoding ) )
55 {
56 ConverterT& rConverter( m_aConverters[ nEncoding ] );
57 if ( rConverter.mpU2T == NULL )
58 {
59 rConverter.mpU2T =
60 rtl_createUnicodeToTextConverter( nEncoding );
61 // ---> FIXME
62 if ( rConverter.mpU2T == NULL )
63 fprintf( stderr, "failed to create Unicode -> %i converter\n", nEncoding);
64 // <---
65 }
66 return rConverter.mpU2T;
67 }
68 return NULL;
69 }
70
71 rtl_TextToUnicodeConverter
GetT2UConverter(rtl_TextEncoding nEncoding)72 SalConverterCache::GetT2UConverter( rtl_TextEncoding nEncoding )
73 {
74 if( rtl_isOctetTextEncoding( nEncoding ) )
75 {
76 ConverterT& rConverter( m_aConverters[ nEncoding ] );
77 if ( rConverter.mpT2U == NULL )
78 {
79 rConverter.mpT2U =
80 rtl_createTextToUnicodeConverter( nEncoding );
81 // ---> FIXME
82 if ( rConverter.mpT2U == NULL )
83 fprintf( stderr, "failed to create %i -> Unicode converter\n", nEncoding );
84 // <---
85 }
86 return rConverter.mpT2U;
87 }
88 return NULL;
89 }
90
91 Bool
IsSingleByteEncoding(rtl_TextEncoding nEncoding)92 SalConverterCache::IsSingleByteEncoding( rtl_TextEncoding nEncoding )
93 {
94 if( rtl_isOctetTextEncoding( nEncoding ) )
95 {
96 ConverterT& rConverter( m_aConverters[ nEncoding ] );
97 if ( ! rConverter.mbValid )
98 {
99 rConverter.mbValid = True;
100
101 rtl_TextEncodingInfo aTextEncInfo;
102 aTextEncInfo.StructSize = sizeof( aTextEncInfo );
103 rtl_getTextEncodingInfo( nEncoding, &aTextEncInfo );
104
105 if ( aTextEncInfo.MinimumCharSize == aTextEncInfo.MaximumCharSize
106 && aTextEncInfo.MinimumCharSize == 1)
107 rConverter.mbSingleByteEncoding = True;
108 else
109 rConverter.mbSingleByteEncoding = False;
110 }
111
112 return rConverter.mbSingleByteEncoding;
113 }
114 return False;
115 }
116
117 // check whether the character set nEncoding contains the unicode
118 // code point nChar. This list has been compiled from the according
119 // ttmap files in /usr/openwin/lib/X11/fonts/TrueType/ttmap/
120 Bool
EncodingHasChar(rtl_TextEncoding nEncoding,sal_Unicode nChar)121 SalConverterCache::EncodingHasChar( rtl_TextEncoding nEncoding,
122 sal_Unicode nChar )
123 {
124 Bool bMatch = False;
125
126 switch ( nEncoding )
127 {
128 case RTL_TEXTENCODING_DONTKNOW:
129 bMatch = False;
130 break;
131
132 case RTL_TEXTENCODING_MS_1252:
133 case RTL_TEXTENCODING_ISO_8859_1:
134 case RTL_TEXTENCODING_ISO_8859_15:
135 // handle iso8859-15 and iso8859-1 the same (and both with euro)
136 // handle them also like ms1252
137 // this is due to the fact that so many X fonts say they are iso8859-1
138 // but have the other glyphs anyway because they are really ms1252
139 bMatch = ( /*nChar >= 0x0000 &&*/ nChar <= 0x00ff )
140 || ( nChar == 0x20ac )
141 || ( nChar == 0x201a )
142 || ( nChar == 0x0192 )
143 || ( nChar == 0x201e )
144 || ( nChar == 0x2026 )
145 || ( nChar == 0x2020 )
146 || ( nChar == 0x2021 )
147 || ( nChar == 0x02c6 )
148 || ( nChar == 0x2030 )
149 || ( nChar == 0x0160 )
150 || ( nChar == 0x2039 )
151 || ( nChar == 0x0152 )
152 || ( nChar == 0x017d )
153 || ( nChar == 0x2018 )
154 || ( nChar == 0x2019 )
155 || ( nChar == 0x201c )
156 || ( nChar == 0x201d )
157 || ( nChar == 0x2022 )
158 || ( nChar == 0x2013 )
159 || ( nChar == 0x2014 )
160 || ( nChar == 0x02dc )
161 || ( nChar == 0x2122 )
162 || ( nChar == 0x0161 )
163 || ( nChar == 0x203a )
164 || ( nChar == 0x0153 )
165 || ( nChar == 0x017e )
166 || ( nChar == 0x0178 )
167 ;
168 break;
169
170 case RTL_TEXTENCODING_ISO_8859_2:
171 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
172 || ( nChar >= 0x00a0 && nChar <= 0x017e )
173 || ( nChar >= 0x02c7 && nChar <= 0x02dd );
174 break;
175
176 case RTL_TEXTENCODING_ISO_8859_4:
177 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
178 || ( nChar >= 0x00a0 && nChar <= 0x017e )
179 || ( nChar >= 0x02c7 && nChar <= 0x02db );
180 break;
181
182 case RTL_TEXTENCODING_ISO_8859_5:
183 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
184 || ( nChar >= 0x00a0 && nChar <= 0x00ad )
185 || ( nChar >= 0x0401 && nChar <= 0x045f )
186 || ( nChar == 0x2116 );
187 break;
188
189 case RTL_TEXTENCODING_ISO_8859_6:
190 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
191 || ( nChar >= 0x0600 && nChar <= 0x06ff )
192 || ( nChar >= 0xfb50 && nChar <= 0xfffe );
193 break;
194
195 case RTL_TEXTENCODING_ISO_8859_7:
196 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
197 || ( nChar >= 0x00a0 && nChar <= 0x00bd )
198 || ( nChar == 0x02bd )
199 || ( nChar >= 0x0384 && nChar <= 0x03ce )
200 || ( nChar >= 0x2014 && nChar <= 0x2019 );
201 break;
202
203 case RTL_TEXTENCODING_ISO_8859_8:
204 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
205 || ( nChar >= 0x00a0 && nChar <= 0x00f7 )
206 || ( nChar >= 0x05d0 && nChar <= 0x05ea )
207 || ( nChar == 0x2017 );
208 break;
209
210 case RTL_TEXTENCODING_ISO_8859_9:
211 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
212 || ( nChar >= 0x00a0 && nChar <= 0x015f );
213 break;
214
215 case RTL_TEXTENCODING_ISO_8859_13:
216 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
217 || ( nChar >= 0x00a0 && nChar <= 0x017e )
218 || ( nChar >= 0x2019 && nChar <= 0x201e );
219 break;
220
221 /* real case for RTL_TEXTENCODING_ISO_8859_15
222 case RTL_TEXTENCODING_ISO_8859_15:
223 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
224 || ( nChar >= 0x00a0 && nChar <= 0x00ff )
225 || ( nChar >= 0x0152 && nChar <= 0x017e )
226 || ( nChar == 0x20ac );
227 break;
228 */
229
230 case RTL_TEXTENCODING_JIS_X_0201:
231 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
232 || ( nChar >= 0xff61 && nChar <= 0xff9f );
233 break;
234
235 case RTL_TEXTENCODING_MS_1251:
236 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
237 || ( nChar >= 0x00a0 && nChar <= 0x00bb )
238 || ( nChar >= 0x0401 && nChar <= 0x045f )
239 || ( nChar >= 0x0490 && nChar <= 0x0491 )
240 || ( nChar >= 0x2013 && nChar <= 0x203a )
241 || ( nChar >= 0x2116 && nChar <= 0x2122 );
242 break;
243
244 case RTL_TEXTENCODING_KOI8_R:
245 bMatch = ( nChar >= 0x0020 && nChar <= 0x007e )
246 || ( nChar >= 0x00a0 && nChar <= 0x00b7 )
247 || ( nChar == 0x00f7 )
248 || ( nChar >= 0x0401 && nChar <= 0x0451 )
249 || ( nChar >= 0x2219 && nChar <= 0x221a )
250 || ( nChar >= 0x2248 && nChar <= 0x2265 )
251 || ( nChar >= 0x2320 && nChar <= 0x2321 )
252 || ( nChar >= 0x2500 && nChar <= 0x25a0 );
253 break;
254
255 case RTL_TEXTENCODING_UNICODE:
256 bMatch = True;
257 break;
258
259 case RTL_TEXTENCODING_EUC_KR:
260 case RTL_TEXTENCODING_BIG5:
261 case RTL_TEXTENCODING_GBK:
262 case RTL_TEXTENCODING_GB_2312:
263 case RTL_TEXTENCODING_MS_1361:
264 case RTL_TEXTENCODING_JIS_X_0208:
265
266 // XXX Big5 and Korean EUC contain Ascii chars, but Solaris
267 // *-big5-1 and *-ksc5601.1992-3 fonts dont, in general CJK fonts
268 // are monospaced, so dont trust them for latin chars
269 if (nChar <= 0xFF)
270 {
271 bMatch = False;
272 break;
273 }
274
275 default:
276 // XXX really convert the unicode char into the encoding
277 // and check for conversion errors, this is expensive !
278 rtl_UnicodeToTextConverter aConverter;
279 rtl_UnicodeToTextContext aContext;
280
281 aConverter = GetU2TConverter(nEncoding);
282 aContext = rtl_createUnicodeToTextContext( aConverter );
283
284 // ---> FIXME
285 if ( aConverter == NULL )
286 return False;
287 // <---
288
289 sal_Char pConversionBuffer[ 32 ];
290 sal_uInt32 nConversionInfo;
291 sal_Size nConvertedChars;
292 sal_Size nSize;
293
294 nSize = rtl_convertUnicodeToText( aConverter, aContext,
295 &nChar, 1, pConversionBuffer, sizeof(pConversionBuffer),
296 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
297 | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR,
298 &nConversionInfo, &nConvertedChars );
299
300 rtl_destroyUnicodeToTextContext( aConverter, aContext );
301
302 bMatch = (nConvertedChars == 1)
303 && (nSize == 1 || nSize == 2) // XXX Fix me this is a hack
304 && ((nConversionInfo & RTL_UNICODETOTEXT_INFO_ERROR) == 0);
305 break;
306 }
307
308 return bMatch;
309 }
310
311 // wrapper for rtl_convertUnicodeToText that handles the usual cases for
312 // textconversion in drawtext and gettextwidth routines
313 sal_Size
ConvertStringUTF16(const sal_Unicode * pText,int nTextLen,sal_Char * pBuffer,sal_Size nBufferSize,rtl_TextEncoding nEncoding)314 SalConverterCache::ConvertStringUTF16( const sal_Unicode *pText, int nTextLen,
315 sal_Char *pBuffer, sal_Size nBufferSize, rtl_TextEncoding nEncoding )
316 {
317 rtl_UnicodeToTextConverter aConverter = GetU2TConverter(nEncoding);
318
319 const sal_uInt32 nCvtFlags =
320 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_REPLACE
321 | RTL_UNICODETOTEXT_FLAGS_UNDEFINED_QUESTIONMARK
322 | RTL_UNICODETOTEXT_FLAGS_INVALID_QUESTIONMARK ;
323 sal_uInt32 nCvtInfo;
324 sal_Size nCvtChars;
325
326 rtl_UnicodeToTextContext aContext =
327 rtl_createUnicodeToTextContext( aConverter );
328
329 sal_Size nSize = rtl_convertUnicodeToText( aConverter, aContext,
330 pText, nTextLen, pBuffer, nBufferSize,
331 nCvtFlags, &nCvtInfo, &nCvtChars );
332
333 rtl_destroyUnicodeToTextContext( aConverter, aContext );
334
335 return nSize;
336 }
337
338