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 29 SalConverterCache::SalConverterCache() 30 { 31 } 32 33 SalConverterCache* 34 SalConverterCache::GetInstance () 35 { 36 static SalConverterCache* pCvt = NULL; 37 if (pCvt == NULL) 38 pCvt = new SalConverterCache; 39 40 return pCvt; 41 } 42 43 SalConverterCache::~SalConverterCache() 44 { 45 } 46 47 // ---> FIXME 48 #include <stdio.h> 49 // <--- 50 51 rtl_UnicodeToTextConverter 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 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 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 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 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