public final class

TextDirectionHeuristicsCompat

extends java.lang.Object

 java.lang.Object

↳androidx.core.text.TextDirectionHeuristicsCompat

Gradle dependencies

compile group: 'androidx.core', name: 'core', version: '1.9.0-alpha04'

  • groupId: androidx.core
  • artifactId: core
  • version: 1.9.0-alpha04

Artifact androidx.core:core:1.9.0-alpha04 it located at Google repository (https://maven.google.com/)

Androidx artifact mapping:

androidx.core:core com.android.support:support-compat

Androidx class mapping:

androidx.core.text.TextDirectionHeuristicsCompat android.support.v4.text.TextDirectionHeuristicsCompat

Overview

Some objects that implement TextDirectionHeuristic.

Summary

Fields
public static final TextDirectionHeuristicCompatANYRTL_LTR

If the text contains any strong right to left non-format character, determines that the direction is right to left, falling back to left to right if it finds none.

public static final TextDirectionHeuristicCompatFIRSTSTRONG_LTR

Determines the direction based on the first strong directional character, including bidi format chars, falling back to left to right if it finds none.

public static final TextDirectionHeuristicCompatFIRSTSTRONG_RTL

Determines the direction based on the first strong directional character, including bidi format chars, falling back to right to left if it finds none.

public static final TextDirectionHeuristicCompatLOCALE

Force the paragraph direction to the Locale direction.

public static final TextDirectionHeuristicCompatLTR

Always decides that the direction is left to right.

public static final TextDirectionHeuristicCompatRTL

Always decides that the direction is right to left.

Methods
from java.lang.Objectclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Fields

public static final TextDirectionHeuristicCompat LTR

Always decides that the direction is left to right.

public static final TextDirectionHeuristicCompat RTL

Always decides that the direction is right to left.

public static final TextDirectionHeuristicCompat FIRSTSTRONG_LTR

Determines the direction based on the first strong directional character, including bidi format chars, falling back to left to right if it finds none. This is the default behavior of the Unicode Bidirectional Algorithm.

public static final TextDirectionHeuristicCompat FIRSTSTRONG_RTL

Determines the direction based on the first strong directional character, including bidi format chars, falling back to right to left if it finds none. This is similar to the default behavior of the Unicode Bidirectional Algorithm, just with different fallback behavior.

public static final TextDirectionHeuristicCompat ANYRTL_LTR

If the text contains any strong right to left non-format character, determines that the direction is right to left, falling back to left to right if it finds none.

public static final TextDirectionHeuristicCompat LOCALE

Force the paragraph direction to the Locale direction. Falls back to left to right.

Source

/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.core.text;


import androidx.core.view.ViewCompat;

import java.nio.CharBuffer;

/**
 * Some objects that implement TextDirectionHeuristic.
 *
 */
public final class TextDirectionHeuristicsCompat {

    /**
     * Always decides that the direction is left to right.
     */
    public static final androidx.core.text.TextDirectionHeuristicCompat LTR =
            new TextDirectionHeuristicInternal(null /* no algorithm */, false);

    /**
     * Always decides that the direction is right to left.
     */
    public static final androidx.core.text.TextDirectionHeuristicCompat RTL =
            new TextDirectionHeuristicInternal(null /* no algorithm */, true);

    /**
     * Determines the direction based on the first strong directional character, including bidi
     * format chars, falling back to left to right if it finds none. This is the default behavior
     * of the Unicode Bidirectional Algorithm.
     */
    public static final androidx.core.text.TextDirectionHeuristicCompat FIRSTSTRONG_LTR =
            new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, false);

    /**
     * Determines the direction based on the first strong directional character, including bidi
     * format chars, falling back to right to left if it finds none. This is similar to the default
     * behavior of the Unicode Bidirectional Algorithm, just with different fallback behavior.
     */
    public static final androidx.core.text.TextDirectionHeuristicCompat FIRSTSTRONG_RTL =
            new TextDirectionHeuristicInternal(FirstStrong.INSTANCE, true);

    /**
     * If the text contains any strong right to left non-format character, determines that the
     * direction is right to left, falling back to left to right if it finds none.
     */
    public static final androidx.core.text.TextDirectionHeuristicCompat ANYRTL_LTR =
            new TextDirectionHeuristicInternal(AnyStrong.INSTANCE_RTL, false);

    /**
     * Force the paragraph direction to the Locale direction. Falls back to left to right.
     */
    public static final androidx.core.text.TextDirectionHeuristicCompat LOCALE =
            TextDirectionHeuristicLocale.INSTANCE;

    /**
     * State constants for taking care about true / false / unknown
     */
    private static final int STATE_TRUE = 0;
    private static final int STATE_FALSE = 1;
    private static final int STATE_UNKNOWN = 2;

    static int isRtlText(int directionality) {
        switch (directionality) {
            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
                return STATE_FALSE;
            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
                return STATE_TRUE;
            default:
                return STATE_UNKNOWN;
        }
    }

    static int isRtlTextOrFormat(int directionality) {
        switch (directionality) {
            case Character.DIRECTIONALITY_LEFT_TO_RIGHT:
            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING:
            case Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE:
                return STATE_FALSE;
            case Character.DIRECTIONALITY_RIGHT_TO_LEFT:
            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC:
            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING:
            case Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE:
                return STATE_TRUE;
            default:
                return STATE_UNKNOWN;
        }
    }

    /**
     * Computes the text direction based on an algorithm.  Subclasses implement
     * {@link #defaultIsRtl} to handle cases where the algorithm cannot determine the
     * direction from the text alone.
     */
    private static abstract class TextDirectionHeuristicImpl implements TextDirectionHeuristicCompat {
        private final TextDirectionAlgorithm mAlgorithm;

        TextDirectionHeuristicImpl(TextDirectionAlgorithm algorithm) {
            mAlgorithm = algorithm;
        }

        /**
         * Return true if the default text direction is rtl.
         */
        abstract protected boolean defaultIsRtl();

        @Override
        public boolean isRtl(char[] array, int start, int count) {
            return isRtl(CharBuffer.wrap(array), start, count);
        }

        @Override
        public boolean isRtl(CharSequence cs, int start, int count) {
            if (cs == null || start < 0 || count < 0 || cs.length() - count < start) {
                throw new IllegalArgumentException();
            }
            if (mAlgorithm == null) {
                return defaultIsRtl();
            }
            return doCheck(cs, start, count);
        }

        private boolean doCheck(CharSequence cs, int start, int count) {
            switch(mAlgorithm.checkRtl(cs, start, count)) {
                case STATE_TRUE:
                    return true;
                case STATE_FALSE:
                    return false;
                default:
                    return defaultIsRtl();
            }
        }
    }

    private static class TextDirectionHeuristicInternal extends TextDirectionHeuristicImpl {
        private final boolean mDefaultIsRtl;

        TextDirectionHeuristicInternal(TextDirectionAlgorithm algorithm,
                boolean defaultIsRtl) {
            super(algorithm);
            mDefaultIsRtl = defaultIsRtl;
        }

        @Override
        protected boolean defaultIsRtl() {
            return mDefaultIsRtl;
        }
    }

    /**
     * Interface for an algorithm to guess the direction of a paragraph of text.
     */
    private interface TextDirectionAlgorithm {
        /**
         * Returns whether the range of text is RTL according to the algorithm.
         */
        int checkRtl(CharSequence cs, int start, int count);
    }

    /**
     * Algorithm that uses the first strong directional character to determine the paragraph
     * direction. This is the standard Unicode Bidirectional algorithm.
     */
    private static class FirstStrong implements TextDirectionAlgorithm {
        @Override
        public int checkRtl(CharSequence cs, int start, int count) {
            int result = STATE_UNKNOWN;
            for (int i = start, e = start + count; i < e && result == STATE_UNKNOWN; ++i) {
                result = isRtlTextOrFormat(Character.getDirectionality(cs.charAt(i)));
            }
            return result;
        }

        private FirstStrong() {
        }

        static final FirstStrong INSTANCE = new FirstStrong();
    }

    /**
     * Algorithm that uses the presence of any strong directional non-format
     * character (e.g. excludes LRE, LRO, RLE, RLO) to determine the
     * direction of text.
     */
    private static class AnyStrong implements TextDirectionAlgorithm {
        private final boolean mLookForRtl;

        @Override
        public int checkRtl(CharSequence cs, int start, int count) {
            boolean haveUnlookedFor = false;
            for (int i = start, e = start + count; i < e; ++i) {
                switch (isRtlText(Character.getDirectionality(cs.charAt(i)))) {
                    case STATE_TRUE:
                        if (mLookForRtl) {
                            return STATE_TRUE;
                        }
                        haveUnlookedFor = true;
                        break;
                    case STATE_FALSE:
                        if (!mLookForRtl) {
                            return STATE_FALSE;
                        }
                        haveUnlookedFor = true;
                        break;
                    default:
                        break;
                }
            }
            if (haveUnlookedFor) {
                return mLookForRtl ? STATE_FALSE : STATE_TRUE;
            }
            return STATE_UNKNOWN;
        }

        private AnyStrong(boolean lookForRtl) {
            this.mLookForRtl = lookForRtl;
        }

        static final AnyStrong INSTANCE_RTL = new AnyStrong(true);
    }

    /**
     * Algorithm that uses the Locale direction to force the direction of a paragraph.
     */
    private static class TextDirectionHeuristicLocale extends TextDirectionHeuristicImpl {

        TextDirectionHeuristicLocale() {
            super(null);
        }

        @Override
        protected boolean defaultIsRtl() {
            final int dir = TextUtilsCompat.getLayoutDirectionFromLocale(java.util.Locale.getDefault());
            return (dir == ViewCompat.LAYOUT_DIRECTION_RTL);
        }

        static final TextDirectionHeuristicLocale INSTANCE =
                new TextDirectionHeuristicLocale();
    }

    private TextDirectionHeuristicsCompat() {}
}