177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio/*
277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * Copyright (C) 2013 The Android Open Source Project
377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio *
477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * Licensed under the Apache License, Version 2.0 (the "License");
577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * you may not use this file except in compliance with the License.
677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * You may obtain a copy of the License at
777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio *
877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio *      http://www.apache.org/licenses/LICENSE-2.0
977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio *
1077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * Unless required by applicable law or agreed to in writing, software
1177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * distributed under the License is distributed on an "AS IS" BASIS,
1277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * See the License for the specific language governing permissions and
1477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * limitations under the License.
1577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio */
1677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
1777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Megliopackage android.support.v4.text;
1877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
1977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
2077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglioimport android.support.v4.view.ViewCompat;
2177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
2277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglioimport java.nio.CharBuffer;
2377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
2477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio/**
2577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio * Some objects that implement TextDirectionHeuristic.
2677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio *
2777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio */
2877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Megliopublic class TextDirectionHeuristicsCompat {
2977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
3077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
3177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Always decides that the direction is left to right.
3277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
3377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    public static final android.support.v4.text.TextDirectionHeuristicCompat LTR =
3477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            new TextDirectionHeuristicInternal(null /* no algorithm */, false);
3577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
3677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
3777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Always decides that the direction is right to left.
3877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
3977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    public static final android.support.v4.text.TextDirectionHeuristicCompat RTL =
4077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            new TextDirectionHeuristicInternal(null /* no algorithm */, true);
4177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
4277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
4377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Determines the direction based on the first strong directional character, including bidi
4477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * format chars, falling back to left to right if it finds none. This is the default behavior
4577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * of the Unicode Bidirectional Algorithm.
4677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
4777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    public static final android.support.v4.text.TextDirectionHeuristicCompat FIRSTSTRONG_LTR =
4877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, false);
4977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
5077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
5177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Determines the direction based on the first strong directional character, including bidi
5277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * format chars, falling back to right to left if it finds none. This is similar to the default
5377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * behavior of the Unicode Bidirectional Algorithm, just with different fallback behavior.
5477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
5577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    public static final android.support.v4.text.TextDirectionHeuristicCompat FIRSTSTRONG_RTL =
5677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, true);
5777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
5877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
5977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * If the text contains any strong right to left non-format character, determines that the
6077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * direction is right to left, falling back to left to right if it finds none.
6177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
6277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    public static final android.support.v4.text.TextDirectionHeuristicCompat ANYRTL_LTR =
6377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, false);
6477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
6577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
6677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Force the paragraph direction to the Locale direction. Falls back to left to right.
6777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
6877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    public static final android.support.v4.text.TextDirectionHeuristicCompat LOCALE =
6977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            TextDirectionHeuristicLocale.INSTANCE;
7077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
7177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
7277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * State constants for taking care about true / false / unknown
7377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
7477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static final int STATE_TRUE = 0;
7577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static final int STATE_FALSE = 1;
7677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static final int STATE_UNKNOWN = 2;
7777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
7877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static int isRtlText(int directionality) {
7977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        switch (directionality) {
8077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
8177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                return STATE_FALSE;
8277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
8377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
8477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                return STATE_TRUE;
8577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            default:
8677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                return STATE_UNKNOWN;
8777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
8877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    }
8977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
9077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static int isRtlTextOrFormat(int directionality) {
9177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        switch (directionality) {
9277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
9377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING:
9477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE:
9577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                return STATE_FALSE;
9677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
9777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
9877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
9977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
10077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                return STATE_TRUE;
10177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            default:
10277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                return STATE_UNKNOWN;
10377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
10477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    }
10577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
10677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
10777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Computes the text direction based on an algorithm.  Subclasses implement
10877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * {@link #defaultIsRtl} to handle cases where the algorithm cannot determine the
10977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * direction from the text alone.
11077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
11177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static abstract class TextDirectionHeuristicImpl implements TextDirectionHeuristicCompat {
11277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        private final TextDirectionAlgorithm mAlgorithm;
11377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
11477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public TextDirectionHeuristicImpl(TextDirectionAlgorithm algorithm) {
11577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            mAlgorithm = algorithm;
11677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
11777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
11877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        /**
11977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio         * Return true if the default text direction is rtl.
12077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio         */
12177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        abstract protected boolean defaultIsRtl();
12277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
12377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        @Override
12477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public boolean isRtl(char[] array, int start, int count) {
12577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            return isRtl(CharBuffer.wrap(array), start, count);
12677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
12777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
12877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        @Override
12977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public boolean isRtl(CharSequence cs, int start, int count) {
13077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            if (cs == null || start < 0 || count < 0 || cs.length() - count < start) {
13177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                throw new IllegalArgumentException();
13277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            }
13377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            if (mAlgorithm == null) {
13477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                return defaultIsRtl();
13577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            }
13677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            return doCheck(cs, start, count);
13777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
13877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
13977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        private boolean doCheck(CharSequence cs, int start, int count) {
14077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            switch(mAlgorithm.checkRtl(cs, start, count)) {
14177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                case STATE_TRUE:
14277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                    return true;
14377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                case STATE_FALSE:
14477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                    return false;
14577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                default:
14677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                    return defaultIsRtl();
14777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            }
14877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
14977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    }
15077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
15177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static class TextDirectionHeuristicInternal extends TextDirectionHeuristicImpl {
15277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        private final boolean mDefaultIsRtl;
15377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
15477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        private TextDirectionHeuristicInternal(TextDirectionAlgorithm algorithm,
15577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                                               boolean defaultIsRtl) {
15677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            super(algorithm);
15777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            mDefaultIsRtl = defaultIsRtl;
15877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
15977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
16077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        @Override
16177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        protected boolean defaultIsRtl() {
16277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            return mDefaultIsRtl;
16377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
16477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    }
16577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
16677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
16777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Interface for an algorithm to guess the direction of a paragraph of text.
16877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
16977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static interface TextDirectionAlgorithm {
17077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        /**
17177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio         * Returns whether the range of text is RTL according to the algorithm.
17277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio         */
17377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        int checkRtl(CharSequence cs, int start, int count);
17477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    }
17577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
17677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
17777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Algorithm that uses the first strong directional character to determine the paragraph
17877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * direction. This is the standard Unicode Bidirectional algorithm.
17977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
18077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static class FirstStrong implements TextDirectionAlgorithm {
18177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        @Override
18277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public int checkRtl(CharSequence cs, int start, int count) {
18377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            int result = STATE_UNKNOWN;
18477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            for (int i = start, e = start + count; i < e && result == STATE_UNKNOWN; ++i) {
18577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                result = isRtlTextOrFormat(Character.getDirectionality(cs.charAt(i)));
18677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            }
18777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            return result;
18877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
18977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
19077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        private FirstStrong() {
19177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
19277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
19377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public static final FirstStrong INSTANCE = new FirstStrong();
19477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    }
19577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
19677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
19777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Algorithm that uses the presence of any strong directional non-format
19877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * character (e.g. excludes LRE, LRO, RLE, RLO) to determine the
19977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * direction of text.
20077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
20177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static class AnyStrong implements TextDirectionAlgorithm {
20277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        private final boolean mLookForRtl;
20377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
20477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        @Override
20577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public int checkRtl(CharSequence cs, int start, int count) {
20677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            boolean haveUnlookedFor = false;
20777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            for (int i = start, e = start + count; i < e; ++i) {
20877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                switch (isRtlText(Character.getDirectionality(cs.charAt(i)))) {
20977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                    case STATE_TRUE:
21077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        if (mLookForRtl) {
21177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                            return STATE_TRUE;
21277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        }
21377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        haveUnlookedFor = true;
21477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        break;
21577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                    case STATE_FALSE:
21677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        if (!mLookForRtl) {
21777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                            return STATE_FALSE;
21877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        }
21977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        haveUnlookedFor = true;
22077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        break;
22177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                    default:
22277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                        break;
22377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                }
22477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            }
22577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            if (haveUnlookedFor) {
22677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                return mLookForRtl ? STATE_FALSE : STATE_TRUE;
22777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            }
22877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            return STATE_UNKNOWN;
22977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
23077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
23177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        private AnyStrong(boolean lookForRtl) {
23277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            this.mLookForRtl = lookForRtl;
23377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
23477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
23577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public static final AnyStrong INSTANCE_RTL = new AnyStrong(true);
23677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public static final AnyStrong INSTANCE_LTR = new AnyStrong(false);
23777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    }
23877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
23977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    /**
24077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     * Algorithm that uses the Locale direction to force the direction of a paragraph.
24177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio     */
24277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    private static class TextDirectionHeuristicLocale extends TextDirectionHeuristicImpl {
24377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
24477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public TextDirectionHeuristicLocale() {
24577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            super(null);
24677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
24777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
24877f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        @Override
24977f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        protected boolean defaultIsRtl() {
25077f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            final int dir = TextUtilsCompat.getLayoutDirectionFromLocale(java.util.Locale.getDefault());
25177f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio            return (dir == ViewCompat.LAYOUT_DIRECTION_RTL);
25277f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        }
25377f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio
25477f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio        public static final TextDirectionHeuristicLocale INSTANCE =
25577f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio                new TextDirectionHeuristicLocale();
25677f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio    }
25777f6bada6f88acea9025afce3eb0127d45411798Fabrice Di Meglio}
258