LocaleUtil.java revision a47f45e4829f812ff47f9e5c9370b02284d92ae8
1a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio/* 2a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * Copyright (C) 2011 The Android Open Source Project 3a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 4a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License"); 5a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * you may not use this file except in compliance with the License. 6a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * You may obtain a copy of the License at 7a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 8a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * http://www.apache.org/licenses/LICENSE-2.0 9a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 10a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software 11a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS, 12a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * See the License for the specific language governing permissions and 14a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * limitations under the License. 15a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio */ 16a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 17a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Megliopackage android.util; 18a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 19a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglioimport java.util.Locale; 20a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 21a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglioimport libcore.icu.ICU; 22a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 23a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio/** 24a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * Various utilities for Locales 25a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 26a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @hide 27a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio */ 28a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Megliopublic class LocaleUtil { 29a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 30a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio private LocaleUtil() { /* cannot be instantiated */ } 31a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 32a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio /** 33a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @hide Do not use. Implementation not finished. 34a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio */ 35a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio public static final int TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE = -1; 36a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 37a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio /** 38a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @hide Do not use. Implementation not finished. 39a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio */ 40a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio public static final int TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE = 0; 41a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 42a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio /** 43a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @hide Do not use. Implementation not finished. 44a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio */ 45a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio public static final int TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE = 1; 46a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 47a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio private static final char UNDERSCORE_CHAR = '_'; 48a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 49a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio private static String ARAB_SCRIPT_SUBTAG = "Arab"; 50a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio private static String HEBR_SCRIPT_SUBTAG = "Hebr"; 51a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 52a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio /** 53a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * Return the layout direction for a given Locale 54a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 55a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @param locale the Locale for which we want the layout direction. Can be null. 56a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @return the layout direction. This may be one of: 57a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or 58a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or 59a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}. 60a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 61a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * Be careful: this code will need to be changed when vertical scripts will be supported 62a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 63a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @hide 64a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio */ 65a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio public static int getLayoutDirectionFromLocale(Locale locale) { 66a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio if (locale == null || locale.equals(Locale.ROOT)) { 67a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; 68a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio } 69a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 70a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio final String localeWithSubtags = ICU.addLikelySubtags(locale.toString()); 71a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio if (localeWithSubtags == null) return getLayoutDirectionFromFirstChar(locale); 72a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 73a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio // Need to check if we can extract the script subtag. For example, "Latn" in "en_Latn_US" 74a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio if (localeWithSubtags.charAt(2) != UNDERSCORE_CHAR || 75a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio localeWithSubtags.charAt(7) != UNDERSCORE_CHAR) { 76a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio return getLayoutDirectionFromFirstChar(locale); 77a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio } 78a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio // Extract the script subtag 79a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio final String scriptSubtag = localeWithSubtags.substring(3, 7); 80a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 81a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) || 82a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) { 83a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; 84a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio } 85a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; 86a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio } 87a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio 88a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio /** 89a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * Fallback algorithm to detect the locale direction. Rely on the fist char of the 90a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * localized locale name. This will not work if the localized locale name is in English 91a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * (this is the case for ICU 4.4 and "Urdu" script) 92a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 93a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @param locale 94a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @return the layout direction. This may be one of: 95a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * {@link #TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE} or 96a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * {@link #TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE} or 97a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * {@link #TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE}. 98a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 99a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * Be careful: this code will need to be changed when vertical scripts will be supported 100a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * 101a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio * @hide 102a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio */ 103a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio private static int getLayoutDirectionFromFirstChar(Locale locale) { 104a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio switch(Character.getDirectionality(locale.getDisplayName(locale).charAt(0))) { 105a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio case Character.DIRECTIONALITY_LEFT_TO_RIGHT: 106a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio return TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE; 107a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio case Character.DIRECTIONALITY_RIGHT_TO_LEFT: 108a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: 109a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio return TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE; 110a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio default: 111a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE; 112a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio } 113a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio } 114a47f45e4829f812ff47f9e5c9370b02284d92ae8Fabrice Di Meglio} 115