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