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_i18npool.hxx" 26 #include <sal/config.h> 27 #include <rtl/ustring.hxx> 28 #include <rtl/string.hxx> 29 #include <com/sun/star/i18n/ScriptType.hpp> 30 31 #include "i18npool/mslangid.hxx" 32 33 34 LanguageType MsLangId::nConfiguredSystemLanguage = LANGUAGE_SYSTEM; 35 LanguageType MsLangId::nConfiguredSystemUILanguage = LANGUAGE_SYSTEM; 36 37 LanguageType MsLangId::nConfiguredWesternFallback = LANGUAGE_SYSTEM; 38 LanguageType MsLangId::nConfiguredAsianFallback = LANGUAGE_SYSTEM; 39 LanguageType MsLangId::nConfiguredComplexFallback = LANGUAGE_SYSTEM; 40 41 // static 42 void MsLangId::setConfiguredSystemLanguage( LanguageType nLang ) 43 { 44 nConfiguredSystemLanguage = nLang; 45 } 46 47 48 // static 49 void MsLangId::setConfiguredSystemUILanguage( LanguageType nLang ) 50 { 51 nConfiguredSystemUILanguage = nLang; 52 } 53 54 // static 55 void MsLangId::setConfiguredWesternFallback( LanguageType nLang ) 56 { 57 nConfiguredWesternFallback = nLang; 58 } 59 60 // static 61 void MsLangId::setConfiguredAsianFallback( LanguageType nLang ) 62 { 63 nConfiguredAsianFallback = nLang; 64 } 65 66 // static 67 void MsLangId::setConfiguredComplexFallback( LanguageType nLang ) 68 { 69 nConfiguredComplexFallback = nLang; 70 } 71 72 // static 73 inline LanguageType MsLangId::simplifySystemLanguages( LanguageType nLang ) 74 { 75 switch (nLang) 76 { 77 case LANGUAGE_PROCESS_OR_USER_DEFAULT : 78 case LANGUAGE_SYSTEM_DEFAULT : 79 case LANGUAGE_SYSTEM : 80 nLang = LANGUAGE_SYSTEM; 81 break; 82 default: 83 ; // nothing 84 } 85 return nLang; 86 } 87 88 89 // static 90 LanguageType MsLangId::getRealLanguageWithoutConfig( LanguageType nLang ) 91 { 92 switch (simplifySystemLanguages( nLang)) 93 { 94 case LANGUAGE_SYSTEM : 95 nLang = getSystemLanguage(); 96 break; 97 case LANGUAGE_NONE : 98 nLang = getSystemUILanguage(); 99 break; 100 default: 101 /* TODO: would this be useful here? */ 102 //nLang = MsLangId::getReplacementForObsoleteLanguage( nLang); 103 ; // nothing 104 } 105 if (nLang == LANGUAGE_DONTKNOW) 106 nLang = LANGUAGE_ENGLISH_US; 107 return nLang; 108 } 109 110 111 // static 112 LanguageType MsLangId::getRealLanguage( LanguageType nLang ) 113 { 114 switch (simplifySystemLanguages( nLang)) 115 { 116 case LANGUAGE_SYSTEM : 117 if (nConfiguredSystemLanguage == LANGUAGE_SYSTEM) 118 nLang = getSystemLanguage(); 119 else 120 nLang = nConfiguredSystemLanguage; 121 break; 122 case LANGUAGE_NONE : 123 if (nConfiguredSystemUILanguage == LANGUAGE_SYSTEM) 124 nLang = getSystemUILanguage(); 125 else 126 nLang = nConfiguredSystemUILanguage; 127 break; 128 default: 129 /* TODO: would this be useful here? */ 130 //nLang = MsLangId::getReplacementForObsoleteLanguage( nLang); 131 ; // nothing 132 } 133 if (nLang == LANGUAGE_DONTKNOW) 134 nLang = LANGUAGE_ENGLISH_US; 135 return nLang; 136 } 137 138 139 // static 140 LanguageType MsLangId::resolveSystemLanguageByScriptType( LanguageType nLang, sal_Int16 nType ) 141 { 142 if (nLang == LANGUAGE_NONE) 143 return nLang; 144 145 nLang = getRealLanguage(nLang); 146 if (nType != ::com::sun::star::i18n::ScriptType::WEAK && getScriptType(nLang) != nType) 147 { 148 switch(nType) 149 { 150 case ::com::sun::star::i18n::ScriptType::ASIAN: 151 if (nConfiguredAsianFallback == LANGUAGE_SYSTEM) 152 nLang = LANGUAGE_CHINESE_SIMPLIFIED; 153 else 154 nLang = nConfiguredAsianFallback; 155 break; 156 case ::com::sun::star::i18n::ScriptType::COMPLEX: 157 if (nConfiguredComplexFallback == LANGUAGE_SYSTEM) 158 nLang = LANGUAGE_HINDI; 159 else 160 nLang = nConfiguredComplexFallback; 161 break; 162 default: 163 if (nConfiguredWesternFallback == LANGUAGE_SYSTEM) 164 nLang = LANGUAGE_ENGLISH_US; 165 else 166 nLang = nConfiguredWesternFallback; 167 break; 168 } 169 } 170 return nLang; 171 } 172 173 // static 174 void MsLangId::convertLanguageToLocale( LanguageType nLang, 175 ::com::sun::star::lang::Locale & rLocale ) 176 { 177 if (rLocale.Variant.getLength()) 178 rLocale.Variant = rtl::OUString(); 179 convertLanguageToIsoNames( nLang, rLocale.Language, rLocale.Country); 180 } 181 182 183 // static 184 ::com::sun::star::lang::Locale MsLangId::convertLanguageToLocale( 185 LanguageType nLang, bool bResolveSystem ) 186 { 187 ::com::sun::star::lang::Locale aLocale; 188 if (!bResolveSystem && simplifySystemLanguages( nLang) == LANGUAGE_SYSTEM) 189 ; // nothing => empty locale 190 else 191 { 192 // Still resolve LANGUAGE_DONTKNOW if resolving is not requested, 193 // but not LANGUAGE_NONE or others. 194 if (bResolveSystem || nLang == LANGUAGE_DONTKNOW) 195 nLang = MsLangId::getRealLanguage( nLang); 196 convertLanguageToLocale( nLang, aLocale); 197 } 198 return aLocale; 199 } 200 201 202 // static 203 LanguageType MsLangId::convertLocaleToLanguage( 204 const ::com::sun::star::lang::Locale& rLocale ) 205 { 206 // empty language => LANGUAGE_SYSTEM 207 if (rLocale.Language.getLength() == 0) 208 return LANGUAGE_SYSTEM; 209 210 LanguageType nRet = convertIsoNamesToLanguage( rLocale.Language, 211 rLocale.Country); 212 if (nRet == LANGUAGE_DONTKNOW) 213 nRet = LANGUAGE_SYSTEM; 214 215 return nRet; 216 } 217 218 219 // static 220 LanguageType MsLangId::convertLocaleToLanguageWithFallback( 221 const ::com::sun::star::lang::Locale & rLocale ) 222 { 223 // empty language => LANGUAGE_SYSTEM 224 if (rLocale.Language.getLength() == 0) 225 return lookupFallbackLanguage( LANGUAGE_SYSTEM); 226 227 return lookupFallbackLanguage( rLocale); 228 } 229 230 231 // static 232 ::com::sun::star::lang::Locale MsLangId::convertLanguageToLocaleWithFallback( 233 LanguageType nLang ) 234 { 235 return lookupFallbackLocale( MsLangId::getRealLanguage( nLang)); 236 } 237 238 239 // static 240 ::com::sun::star::lang::Locale MsLangId::getFallbackLocale( 241 const ::com::sun::star::lang::Locale & rLocale ) 242 { 243 // empty language => LANGUAGE_SYSTEM 244 if (rLocale.Language.getLength() == 0) 245 return convertLanguageToLocaleWithFallback( LANGUAGE_SYSTEM); 246 247 return lookupFallbackLocale( rLocale); 248 } 249 250 251 // static 252 LanguageType MsLangId::getFallbackLanguage( LanguageType nLang ) 253 { 254 return lookupFallbackLanguage( MsLangId::getRealLanguage( nLang)); 255 } 256 257 258 // static 259 bool MsLangId::isRightToLeft( LanguageType nLang ) 260 { 261 switch( nLang & LANGUAGE_MASK_PRIMARY ) 262 { 263 case LANGUAGE_ARABIC_SAUDI_ARABIA & LANGUAGE_MASK_PRIMARY : 264 case LANGUAGE_HEBREW & LANGUAGE_MASK_PRIMARY : 265 case LANGUAGE_YIDDISH & LANGUAGE_MASK_PRIMARY : 266 case LANGUAGE_URDU & LANGUAGE_MASK_PRIMARY : 267 case LANGUAGE_FARSI & LANGUAGE_MASK_PRIMARY : 268 case LANGUAGE_KASHMIRI & LANGUAGE_MASK_PRIMARY : 269 case LANGUAGE_SINDHI & LANGUAGE_MASK_PRIMARY : 270 case LANGUAGE_UIGHUR_CHINA & LANGUAGE_MASK_PRIMARY : 271 return true; 272 273 default: 274 break; 275 } 276 return false; 277 } 278 279 280 // static 281 bool MsLangId::hasForbiddenCharacters( LanguageType nLang ) 282 { 283 switch (nLang & LANGUAGE_MASK_PRIMARY) 284 { 285 case LANGUAGE_CHINESE & LANGUAGE_MASK_PRIMARY: 286 case LANGUAGE_JAPANESE & LANGUAGE_MASK_PRIMARY: 287 case LANGUAGE_KOREAN & LANGUAGE_MASK_PRIMARY: 288 return true; 289 default: 290 break; 291 } 292 return false; 293 } 294 295 296 // static 297 bool MsLangId::needsSequenceChecking( LanguageType nLang ) 298 { 299 switch (nLang & LANGUAGE_MASK_PRIMARY) 300 { 301 case LANGUAGE_BURMESE & LANGUAGE_MASK_PRIMARY: 302 case LANGUAGE_KHMER & LANGUAGE_MASK_PRIMARY: 303 case LANGUAGE_LAO & LANGUAGE_MASK_PRIMARY: 304 case LANGUAGE_THAI & LANGUAGE_MASK_PRIMARY: 305 return true; 306 default: 307 break; 308 } 309 return false; 310 } 311 312 313 // static 314 sal_Int16 MsLangId::getScriptType( LanguageType nLang ) 315 { 316 sal_Int16 nScript; 317 switch( nLang ) 318 { 319 // CJK 320 // all LANGUAGE_CHINESE_... are caught below 321 case LANGUAGE_JAPANESE: 322 case LANGUAGE_KOREAN: 323 case LANGUAGE_KOREAN_JOHAB: 324 case LANGUAGE_USER_KOREAN_NORTH: 325 nScript = ::com::sun::star::i18n::ScriptType::ASIAN; 326 break; 327 328 // CTL 329 // all LANGUAGE_ARABIC_... are caught below 330 case LANGUAGE_AMHARIC_ETHIOPIA: 331 case LANGUAGE_ASSAMESE: 332 case LANGUAGE_BENGALI: 333 case LANGUAGE_BENGALI_BANGLADESH: 334 case LANGUAGE_BURMESE: 335 case LANGUAGE_FARSI: 336 case LANGUAGE_HEBREW: 337 case LANGUAGE_YIDDISH: 338 case LANGUAGE_USER_YIDDISH_US: 339 case LANGUAGE_MARATHI: 340 case LANGUAGE_PUNJABI: 341 case LANGUAGE_GUJARATI: 342 case LANGUAGE_HINDI: 343 case LANGUAGE_KANNADA: 344 case LANGUAGE_KASHMIRI: 345 case LANGUAGE_KASHMIRI_INDIA: 346 case LANGUAGE_KHMER: 347 case LANGUAGE_LAO: 348 case LANGUAGE_MALAYALAM: 349 case LANGUAGE_MANIPURI: 350 case LANGUAGE_MONGOLIAN_MONGOLIAN: 351 case LANGUAGE_NEPALI: 352 case LANGUAGE_NEPALI_INDIA: 353 case LANGUAGE_ORIYA: 354 case LANGUAGE_SANSKRIT: 355 case LANGUAGE_SINDHI: 356 case LANGUAGE_SINDHI_PAKISTAN: 357 case LANGUAGE_SINHALESE_SRI_LANKA: 358 case LANGUAGE_SYRIAC: 359 case LANGUAGE_TAMIL: 360 case LANGUAGE_TELUGU: 361 case LANGUAGE_THAI: 362 case LANGUAGE_TIBETAN: 363 case LANGUAGE_DZONGKHA: 364 case LANGUAGE_URDU: 365 case LANGUAGE_URDU_PAKISTAN: 366 case LANGUAGE_URDU_INDIA: 367 case LANGUAGE_USER_KURDISH_IRAQ: 368 case LANGUAGE_USER_KURDISH_IRAN: 369 case LANGUAGE_DHIVEHI: 370 case LANGUAGE_USER_BODO_INDIA: 371 case LANGUAGE_USER_DOGRI_INDIA: 372 case LANGUAGE_USER_MAITHILI_INDIA: 373 case LANGUAGE_UIGHUR_CHINA: 374 case LANGUAGE_USER_LIMBU: 375 nScript = ::com::sun::star::i18n::ScriptType::COMPLEX; 376 break; 377 378 // currently not knowing scripttype - defaulted to LATIN: 379 /* 380 #define LANGUAGE_ARMENIAN 0x042B 381 #define LANGUAGE_INDONESIAN 0x0421 382 #define LANGUAGE_KAZAK 0x043F 383 #define LANGUAGE_KONKANI 0x0457 384 #define LANGUAGE_MACEDONIAN 0x042F 385 #define LANGUAGE_TATAR 0x0444 386 */ 387 388 default: 389 switch ( nLang & LANGUAGE_MASK_PRIMARY ) 390 { 391 // CJK catcher 392 case LANGUAGE_CHINESE & LANGUAGE_MASK_PRIMARY: 393 nScript = ::com::sun::star::i18n::ScriptType::ASIAN; 394 break; 395 // CTL catcher 396 case LANGUAGE_ARABIC_SAUDI_ARABIA & LANGUAGE_MASK_PRIMARY: 397 nScript = ::com::sun::star::i18n::ScriptType::COMPLEX; 398 break; 399 // Western (actually not necessarily Latin but also Cyrillic, for example) 400 default: 401 nScript = ::com::sun::star::i18n::ScriptType::LATIN; 402 } 403 break; 404 } 405 return nScript; 406 } 407 408 409 // static 410 LanguageType MsLangId::getReplacementForObsoleteLanguage( LanguageType nLang ) 411 { 412 switch (nLang) 413 { 414 default: 415 break; // nothing 416 case LANGUAGE_OBSOLETE_USER_LATIN: 417 nLang = LANGUAGE_LATIN; 418 break; 419 case LANGUAGE_OBSOLETE_USER_MAORI: 420 nLang = LANGUAGE_MAORI_NEW_ZEALAND; 421 break; 422 case LANGUAGE_OBSOLETE_USER_KINYARWANDA: 423 nLang = LANGUAGE_KINYARWANDA_RWANDA; 424 break; 425 case LANGUAGE_OBSOLETE_USER_UPPER_SORBIAN: 426 nLang = LANGUAGE_UPPER_SORBIAN_GERMANY; 427 break; 428 case LANGUAGE_OBSOLETE_USER_LOWER_SORBIAN: 429 nLang = LANGUAGE_LOWER_SORBIAN_GERMANY; 430 break; 431 case LANGUAGE_OBSOLETE_USER_OCCITAN: 432 nLang = LANGUAGE_OCCITAN_FRANCE; 433 break; 434 case LANGUAGE_OBSOLETE_USER_BRETON: 435 nLang = LANGUAGE_BRETON_FRANCE; 436 break; 437 case LANGUAGE_OBSOLETE_USER_KALAALLISUT: 438 nLang = LANGUAGE_KALAALLISUT_GREENLAND; 439 break; 440 case LANGUAGE_OBSOLETE_USER_LUXEMBOURGISH: 441 nLang = LANGUAGE_LUXEMBOURGISH_LUXEMBOURG; 442 break; 443 444 // The following are not strictly obsolete but should be mapped to a 445 // replacement locale when encountered. 446 447 // no_NO is an alias for nb_NO 448 case LANGUAGE_NORWEGIAN: 449 nLang = LANGUAGE_NORWEGIAN_BOKMAL; 450 break; 451 452 // #i94435# A Spanish variant that differs only in collation details we 453 // do not support. 454 case LANGUAGE_SPANISH_DATED: 455 nLang = LANGUAGE_SPANISH_MODERN; 456 break; 457 458 // Do not use ca-XV, ca-XR for document content. 459 /* TODO: remove in case we implement BCP47 language tags. */ 460 case LANGUAGE_USER_CATALAN_VALENCIAN: 461 case LANGUAGE_USER_CATALAN_VALENCIAN_RACV: 462 nLang = LANGUAGE_CATALAN; 463 break; 464 } 465 return nLang; 466 } 467