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
22cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt/**
23cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt * Some objects that implement TextDirectionHeuristic.
24cefb4bc011fe47ec83b2fd9ec4da28bdf806c0cdGilles Debunne *
25cefb4bc011fe47ec83b2fd9ec4da28bdf806c0cdGilles Debunne * @hide
26cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt */
27cb379120456d8065d742021fc5c66748fc8a11a8Doug Feltpublic class TextDirectionHeuristics {
28cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
29cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /** Always decides that the direction is left to right. */
30cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    public static final TextDirectionHeuristic LTR =
31cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        new TextDirectionHeuristicInternal(null /* no algorithm */, false);
32cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
33cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /** Always decides that the direction is right to left. */
34cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    public static final TextDirectionHeuristic RTL =
35cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        new TextDirectionHeuristicInternal(null /* no algorithm */, true);
36cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
37cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
38cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Determines the direction based on the first strong directional character,
39cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * including bidi format chars, falling back to left to right if it
40cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * finds none.  This is the default behavior of the Unicode Bidirectional
41cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Algorithm.
42cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     */
43cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    public static final TextDirectionHeuristic FIRSTSTRONG_LTR =
44cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, false);
45cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
46cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
47cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Determines the direction based on the first strong directional character,
48cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * including bidi format chars, falling back to right to left if it
49cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * finds none.  This is similar to the default behavior of the Unicode
50cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Bidirectional Algorithm, just with different fallback behavior.
51cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     */
52cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    public static final TextDirectionHeuristic FIRSTSTRONG_RTL =
53cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, true);
54cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
55cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
564b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio     * If the text contains any strong right to left non-format character, determines
574b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio     * that the direction is right to left, falling back to left to right if it
584b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio     * finds none.
594b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio     */
604b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio    public static final TextDirectionHeuristic ANYRTL_LTR =
614b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio        new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, false);
624b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio
634b60c30838fbd635964f1e79c057de5048dcc66fFabrice Di Meglio    /**
647810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio     * Force the paragraph direction to the Locale direction. Falls back to left to right.
657810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio     */
667810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio    public static final TextDirectionHeuristic LOCALE = TextDirectionHeuristicLocale.INSTANCE;
677810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio
68cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    private static enum TriState {
69cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        TRUE, FALSE, UNKNOWN;
70cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
71cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
72cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
73cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Computes the text direction based on an algorithm.  Subclasses implement
74cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * {@link #defaultIsRtl} to handle cases where the algorithm cannot determine the
75cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * direction from the text alone.
76cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     */
77e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio    private static abstract class TextDirectionHeuristicImpl implements TextDirectionHeuristic {
78cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        private final TextDirectionAlgorithm mAlgorithm;
79cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
80cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        public TextDirectionHeuristicImpl(TextDirectionAlgorithm algorithm) {
81cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            mAlgorithm = algorithm;
82cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
83cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
84cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        /**
85cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt         * Return true if the default text direction is rtl.
86cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt         */
87cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        abstract protected boolean defaultIsRtl();
88cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
89cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        @Override
90cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        public boolean isRtl(char[] chars, int start, int count) {
91cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            if (chars == null || start < 0 || count < 0 || chars.length - count < start) {
92cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                throw new IllegalArgumentException();
93cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            }
94cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            if (mAlgorithm == null) {
95cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                return defaultIsRtl();
96cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            }
97cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            return doCheck(chars, start, count);
98cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
99cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
100cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        private boolean doCheck(char[] chars, int start, int count) {
101cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            switch(mAlgorithm.checkRtl(chars, start, count)) {
102cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                case TRUE:
103cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                    return true;
104cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                case FALSE:
105cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                    return false;
106cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                default:
107cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                    return defaultIsRtl();
108cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            }
109cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
110cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
111cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
112cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    private static class TextDirectionHeuristicInternal extends TextDirectionHeuristicImpl {
113cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        private final boolean mDefaultIsRtl;
114cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
115cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        private TextDirectionHeuristicInternal(TextDirectionAlgorithm algorithm,
116cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                boolean defaultIsRtl) {
117cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            super(algorithm);
118cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            mDefaultIsRtl = defaultIsRtl;
119cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
120cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
121cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        @Override
122cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        protected boolean defaultIsRtl() {
123cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            return mDefaultIsRtl;
124cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
125cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
126cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
127cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    private static TriState isRtlText(int directionality) {
128cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        switch (directionality) {
129cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
130cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                return TriState.FALSE;
131cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
132cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
133cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                return TriState.TRUE;
134cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            default:
135cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                return TriState.UNKNOWN;
136cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
137cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
138cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
139cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    private static TriState isRtlTextOrFormat(int directionality) {
140cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        switch (directionality) {
141cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
142cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING:
143cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE:
144cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                return TriState.FALSE;
145cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
146cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
147cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
148cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
149cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                return TriState.TRUE;
150cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            default:
151cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                return TriState.UNKNOWN;
152cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
153cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
154cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
155cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
156cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Interface for an algorithm to guess the direction of a paragraph of text.
157cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     *
158cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     */
159e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio    private static interface TextDirectionAlgorithm {
160cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        /**
161cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt         * Returns whether the range of text is RTL according to the algorithm.
162cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt         *
163cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt         */
164cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        TriState checkRtl(char[] text, int start, int count);
165cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
166cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
167cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
168cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Algorithm that uses the first strong directional character to determine
169cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * the paragraph direction.  This is the standard Unicode Bidirectional
170cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * algorithm.
171cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     *
172cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     */
173e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio    private static class FirstStrong implements TextDirectionAlgorithm {
174cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        @Override
175cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        public TriState checkRtl(char[] text, int start, int count) {
176cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            TriState result = TriState.UNKNOWN;
177cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            for (int i = start, e = start + count; i < e && result == TriState.UNKNOWN; ++i) {
178cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                result = isRtlTextOrFormat(Character.getDirectionality(text[i]));
179cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            }
180cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            return result;
181cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
182cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
183cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        private FirstStrong() {
184cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
185cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
186cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        public static final FirstStrong INSTANCE = new FirstStrong();
187cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
188cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
189cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
190cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * Algorithm that uses the presence of any strong directional non-format
191cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * character (e.g. excludes LRE, LRO, RLE, RLO) to determine the
192cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     * direction of text.
193cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     *
194cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt     */
195e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio    private static class AnyStrong implements TextDirectionAlgorithm {
196cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        private final boolean mLookForRtl;
197cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
198cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        @Override
199cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        public TriState checkRtl(char[] text, int start, int count) {
200cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            boolean haveUnlookedFor = false;
201cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            for (int i = start, e = start + count; i < e; ++i) {
202cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                switch (isRtlText(Character.getDirectionality(text[i]))) {
203cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                    case TRUE:
204cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        if (mLookForRtl) {
205cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                            return TriState.TRUE;
206cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        }
207cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        haveUnlookedFor = true;
208cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        break;
209cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                    case FALSE:
210cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        if (!mLookForRtl) {
211cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                            return TriState.FALSE;
212cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        }
213cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        haveUnlookedFor = true;
214cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        break;
215cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                    default:
216cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                        break;
217cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                }
218cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            }
219cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            if (haveUnlookedFor) {
220cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt                return mLookForRtl ? TriState.FALSE : TriState.TRUE;
221cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            }
222cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            return TriState.UNKNOWN;
223cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
224cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
225cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        private AnyStrong(boolean lookForRtl) {
226cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt            this.mLookForRtl = lookForRtl;
227cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        }
228cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
229cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        public static final AnyStrong INSTANCE_RTL = new AnyStrong(true);
230cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt        public static final AnyStrong INSTANCE_LTR = new AnyStrong(false);
231cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    }
232cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt
233cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt    /**
2347810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio     * Algorithm that uses the Locale direction to force the direction of a paragraph.
2357810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio     */
236e7beae3f4c9c170c7c6c42cf9b572f0ee1ec9c81Fabrice Di Meglio    private static class TextDirectionHeuristicLocale extends TextDirectionHeuristicImpl {
2377810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio
2387810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio        public TextDirectionHeuristicLocale() {
2397810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio            super(null);
2407810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio        }
2417810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio
2427810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio        @Override
2437810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio        protected boolean defaultIsRtl() {
244d3d9f3f1004dfee2649a26cfe8dba948cd364904Fabrice Di Meglio            final int dir = TextUtils.getLayoutDirectionFromLocale(java.util.Locale.getDefault());
2453fb824bae3322252a68c1cf8537280a5d2bd356dFabrice Di Meglio            return (dir == View.LAYOUT_DIRECTION_RTL);
2467810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio        }
2477810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio
2487810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio        public static final TextDirectionHeuristicLocale INSTANCE =
2497810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio                new TextDirectionHeuristicLocale();
2507810b5f8cffb3c2c98fd0df579f4da5a9ac6cc73Fabrice Di Meglio    }
251cb379120456d8065d742021fc5c66748fc8a11a8Doug Felt}
252