TextDirectionHeuristics.java revision e442662330c972aa96986e6f09305be836b6a7f4
14b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio/* 24b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * Copyright (C) 2011 The Android Open Source Project 34b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * 44b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License"); 54b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * you may not use this file except in compliance with the License. 64b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * You may obtain a copy of the License at 74b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * 84b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * http://www.apache.org/licenses/LICENSE-2.0 94b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * 104b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * Unless required by applicable law or agreed to in writing, software 114b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS, 124b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 134b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * See the License for the specific language governing permissions and 144b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio * limitations under the License. 154b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio */ 16cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 17cb379120456d8065d742021fc5c66748fc8a11a8Doug Feltpackage android.text; 18cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 19cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 203fb824bae3322252a68c1cf8537280a5d2bd356dFabrice Di Meglioimport android.view.View; 217810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio 2257a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglioimport java.nio.CharBuffer; 2357a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio 24cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt/** 25e442662330c972aa96986e6f09305be836b6a7f4Scott Main * Some objects that implement {@link TextDirectionHeuristic}. Use these with 26e442662330c972aa96986e6f09305be836b6a7f4Scott Main * the {@link BidiFormatter#unicodeWrap unicodeWrap()} methods in {@link BidiFormatter}. 27e442662330c972aa96986e6f09305be836b6a7f4Scott Main * Also notice that these direction heuristics correspond to the same types of constants 28e442662330c972aa96986e6f09305be836b6a7f4Scott Main * provided in the {@link android.view.View} class for {@link android.view.View#setTextDirection 29e442662330c972aa96986e6f09305be836b6a7f4Scott Main * setTextDirection()}, such as {@link android.view.View#TEXT_DIRECTION_RTL}. 30e442662330c972aa96986e6f09305be836b6a7f4Scott Main * <p>To support versions lower than {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, 31e442662330c972aa96986e6f09305be836b6a7f4Scott Main * you can use the support library's {@link android.support.v4.text.TextDirectionHeuristicsCompat} 32e442662330c972aa96986e6f09305be836b6a7f4Scott Main * class. 33cefb4bc011fe47ec83b2fd9ec4da28bdf806c0cdGilles Debunne * 34cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 35cb379120456d8065d742021fc5c66748fc8a11a8Doug Feltpublic class TextDirectionHeuristics { 36cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 3757a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio /** 3857a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * Always decides that the direction is left to right. 3957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio */ 40cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt public static final TextDirectionHeuristic LTR = 41cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt new TextDirectionHeuristicInternal(null /* no algorithm */, false); 42cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 4357a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio /** 4457a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * Always decides that the direction is right to left. 4557a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio */ 46cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt public static final TextDirectionHeuristic RTL = 47cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt new TextDirectionHeuristicInternal(null /* no algorithm */, true); 48cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 49cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 5057a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * Determines the direction based on the first strong directional character, including bidi 5157a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * format chars, falling back to left to right if it finds none. This is the default behavior 5257a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * of the Unicode Bidirectional Algorithm. 53cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 54cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt public static final TextDirectionHeuristic FIRSTSTRONG_LTR = 55cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, false); 56cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 57cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 5857a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * Determines the direction based on the first strong directional character, including bidi 5957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * format chars, falling back to right to left if it finds none. This is similar to the default 6057a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * behavior of the Unicode Bidirectional Algorithm, just with different fallback behavior. 61cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 62cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt public static final TextDirectionHeuristic FIRSTSTRONG_RTL = 63cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, true); 64cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 65cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 6657a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * If the text contains any strong right to left non-format character, determines that the 6757a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * direction is right to left, falling back to left to right if it finds none. 684b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio */ 694b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio public static final TextDirectionHeuristic ANYRTL_LTR = 704b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, false); 714b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio 724b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio /** 737810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio * Force the paragraph direction to the Locale direction. Falls back to left to right. 747810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio */ 757810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio public static final TextDirectionHeuristic LOCALE = TextDirectionHeuristicLocale.INSTANCE; 767810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio 7757a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio /** 7857a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * State constants for taking care about true / false / unknown 7957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio */ 8057a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio private static final int STATE_TRUE = 0; 8157a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio private static final int STATE_FALSE = 1; 8257a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio private static final int STATE_UNKNOWN = 2; 8357a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio 8457a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio private static int isRtlText(int directionality) { 8557a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio switch (directionality) { 8657a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_LEFT_TO_RIGHT: 8757a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_FALSE; 8857a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_RIGHT_TO_LEFT: 8957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: 9057a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_TRUE; 9157a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio default: 9257a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_UNKNOWN; 9357a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio } 9457a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio } 9557a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio 9657a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio private static int isRtlTextOrFormat(int directionality) { 9757a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio switch (directionality) { 9857a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_LEFT_TO_RIGHT: 9957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING: 10057a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE: 10157a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_FALSE; 10257a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_RIGHT_TO_LEFT: 10357a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: 10457a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING: 10557a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE: 10657a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_TRUE; 10757a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio default: 10857a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_UNKNOWN; 10957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio } 110cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 111cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 112cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 113cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * Computes the text direction based on an algorithm. Subclasses implement 114cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * {@link #defaultIsRtl} to handle cases where the algorithm cannot determine the 115cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * direction from the text alone. 116cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 117e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio private static abstract class TextDirectionHeuristicImpl implements TextDirectionHeuristic { 118cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt private final TextDirectionAlgorithm mAlgorithm; 119cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 120cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt public TextDirectionHeuristicImpl(TextDirectionAlgorithm algorithm) { 121cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt mAlgorithm = algorithm; 122cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 123cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 124cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 125cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * Return true if the default text direction is rtl. 126cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 127cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt abstract protected boolean defaultIsRtl(); 128cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 129cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt @Override 13057a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio public boolean isRtl(char[] array, int start, int count) { 13157a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return isRtl(CharBuffer.wrap(array), start, count); 13257a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio } 13357a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio 13457a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio @Override 13557a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio public boolean isRtl(CharSequence cs, int start, int count) { 13657a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio if (cs == null || start < 0 || count < 0 || cs.length() - count < start) { 137cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt throw new IllegalArgumentException(); 138cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 139cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt if (mAlgorithm == null) { 140cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt return defaultIsRtl(); 141cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 14257a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return doCheck(cs, start, count); 143cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 144cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 14557a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio private boolean doCheck(CharSequence cs, int start, int count) { 14657a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio switch(mAlgorithm.checkRtl(cs, start, count)) { 14757a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case STATE_TRUE: 148cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt return true; 14957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case STATE_FALSE: 150cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt return false; 151cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt default: 152cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt return defaultIsRtl(); 153cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 154cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 155cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 156cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 157cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt private static class TextDirectionHeuristicInternal extends TextDirectionHeuristicImpl { 158cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt private final boolean mDefaultIsRtl; 159cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 160cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt private TextDirectionHeuristicInternal(TextDirectionAlgorithm algorithm, 161cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt boolean defaultIsRtl) { 162cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt super(algorithm); 163cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt mDefaultIsRtl = defaultIsRtl; 164cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 165cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 166cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt @Override 167cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt protected boolean defaultIsRtl() { 168cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt return mDefaultIsRtl; 169cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 170cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 171cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 172cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 173cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * Interface for an algorithm to guess the direction of a paragraph of text. 174cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 175e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio private static interface TextDirectionAlgorithm { 176cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 177cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * Returns whether the range of text is RTL according to the algorithm. 178cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 17957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio int checkRtl(CharSequence cs, int start, int count); 180cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 181cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 182cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 18357a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * Algorithm that uses the first strong directional character to determine the paragraph 18457a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio * direction. This is the standard Unicode Bidirectional algorithm. 185cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 186e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio private static class FirstStrong implements TextDirectionAlgorithm { 187cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt @Override 18857a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio public int checkRtl(CharSequence cs, int start, int count) { 18957a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio int result = STATE_UNKNOWN; 19057a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio for (int i = start, e = start + count; i < e && result == STATE_UNKNOWN; ++i) { 19157a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio result = isRtlTextOrFormat(Character.getDirectionality(cs.charAt(i))); 192cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 193cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt return result; 194cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 195cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 196cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt private FirstStrong() { 197cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 198cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 199cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt public static final FirstStrong INSTANCE = new FirstStrong(); 200cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 201cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 202cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 203cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * Algorithm that uses the presence of any strong directional non-format 204cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * character (e.g. excludes LRE, LRO, RLE, RLO) to determine the 205cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * direction of text. 206cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */ 207e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio private static class AnyStrong implements TextDirectionAlgorithm { 208cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt private final boolean mLookForRtl; 209cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 210cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt @Override 21157a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio public int checkRtl(CharSequence cs, int start, int count) { 212cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt boolean haveUnlookedFor = false; 213cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt for (int i = start, e = start + count; i < e; ++i) { 21457a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio switch (isRtlText(Character.getDirectionality(cs.charAt(i)))) { 21557a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case STATE_TRUE: 216cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt if (mLookForRtl) { 21757a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_TRUE; 218cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 219cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt haveUnlookedFor = true; 220cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt break; 22157a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio case STATE_FALSE: 222cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt if (!mLookForRtl) { 22357a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_FALSE; 224cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 225cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt haveUnlookedFor = true; 226cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt break; 227cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt default: 228cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt break; 229cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 230cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 231cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt if (haveUnlookedFor) { 23257a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return mLookForRtl ? STATE_FALSE : STATE_TRUE; 233cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 23457a85740d721caf8dcd94a545b2dd920e8e84e01Fabrice Di Meglio return STATE_UNKNOWN; 235cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 236cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 237cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt private AnyStrong(boolean lookForRtl) { 238cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt this.mLookForRtl = lookForRtl; 239cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 240cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 241cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt public static final AnyStrong INSTANCE_RTL = new AnyStrong(true); 242cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt public static final AnyStrong INSTANCE_LTR = new AnyStrong(false); 243cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt } 244cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt 245cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt /** 2467810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio * Algorithm that uses the Locale direction to force the direction of a paragraph. 2477810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio */ 248e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio private static class TextDirectionHeuristicLocale extends TextDirectionHeuristicImpl { 2497810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio 2507810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio public TextDirectionHeuristicLocale() { 2517810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio super(null); 2527810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio } 2537810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio 2547810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio @Override 2557810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio protected boolean defaultIsRtl() { 256d3d9f3f1004dfee2649a26cfe8dba948cd364904Fabrice Di Meglio final int dir = TextUtils.getLayoutDirectionFromLocale(java.util.Locale.getDefault()); 2573fb824bae3322252a68c1cf8537280a5d2bd356dFabrice Di Meglio return (dir == View.LAYOUT_DIRECTION_RTL); 2587810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio } 2597810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio 2607810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio public static final TextDirectionHeuristicLocale INSTANCE = 2617810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio new TextDirectionHeuristicLocale(); 2627810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio } 263cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt} 264