package androidx.core.text; import android.text.SpannableStringBuilder; import java.util.Locale; public final class BidiFormatter { private static final int DEFAULT_FLAGS = 2; public static final BidiFormatter DEFAULT_LTR_INSTANCE; public static final BidiFormatter DEFAULT_RTL_INSTANCE; public static final TextDirectionHeuristicCompat DEFAULT_TEXT_DIRECTION_HEURISTIC; private static final int DIR_LTR = -1; private static final int DIR_RTL = 1; private static final int DIR_UNKNOWN = 0; private static final String EMPTY_STRING = ""; private static final int FLAG_STEREO_RESET = 2; private static final char LRE = 8234; private static final char LRM = 8206; private static final String LRM_STRING = Character.toString(8206); private static final char PDF = 8236; private static final char RLE = 8235; private static final char RLM = 8207; private static final String RLM_STRING = Character.toString(8207); private final TextDirectionHeuristicCompat mDefaultTextDirectionHeuristicCompat; private final int mFlags; private final boolean mIsRtlContext; public static final class Builder { private int mFlags; private boolean mIsRtlContext; private TextDirectionHeuristicCompat mTextDirectionHeuristicCompat; public Builder() { initialize(BidiFormatter.isRtlLocale(Locale.getDefault())); } public Builder(Locale locale) { initialize(BidiFormatter.isRtlLocale(locale)); } public Builder(boolean z2) { initialize(z2); } private static BidiFormatter getDefaultInstanceFromContext(boolean z2) { return z2 ? BidiFormatter.DEFAULT_RTL_INSTANCE : BidiFormatter.DEFAULT_LTR_INSTANCE; } private void initialize(boolean z2) { this.mIsRtlContext = z2; this.mTextDirectionHeuristicCompat = BidiFormatter.DEFAULT_TEXT_DIRECTION_HEURISTIC; this.mFlags = 2; } public BidiFormatter build() { return (this.mFlags == 2 && this.mTextDirectionHeuristicCompat == BidiFormatter.DEFAULT_TEXT_DIRECTION_HEURISTIC) ? getDefaultInstanceFromContext(this.mIsRtlContext) : new BidiFormatter(this.mIsRtlContext, this.mFlags, this.mTextDirectionHeuristicCompat); } public Builder setTextDirectionHeuristic(TextDirectionHeuristicCompat textDirectionHeuristicCompat) { this.mTextDirectionHeuristicCompat = textDirectionHeuristicCompat; return this; } public Builder stereoReset(boolean z2) { if (z2) { this.mFlags |= 2; } else { this.mFlags &= -3; } return this; } } public static class DirectionalityEstimator { private static final byte[] DIR_TYPE_CACHE = new byte[1792]; private static final int DIR_TYPE_CACHE_SIZE = 1792; private int charIndex; private final boolean isHtml; private char lastChar; private final int length; private final CharSequence text; static { for (int i = 0; i < 1792; i++) { DIR_TYPE_CACHE[i] = Character.getDirectionality(i); } } public DirectionalityEstimator(CharSequence charSequence, boolean z2) { this.text = charSequence; this.isHtml = z2; this.length = charSequence.length(); } private static byte getCachedDirectionality(char c2) { return c2 < 1792 ? DIR_TYPE_CACHE[c2] : Character.getDirectionality(c2); } private byte skipEntityBackward() { char charAt; int i = this.charIndex; do { int i2 = this.charIndex; if (i2 <= 0) { break; } CharSequence charSequence = this.text; int i3 = i2 - 1; this.charIndex = i3; charAt = charSequence.charAt(i3); this.lastChar = charAt; if (charAt == '&') { return 12; } } while (charAt != ';'); this.charIndex = i; this.lastChar = ';'; return 13; } private byte skipEntityForward() { char charAt; do { int i = this.charIndex; if (i >= this.length) { return 12; } CharSequence charSequence = this.text; this.charIndex = i + 1; charAt = charSequence.charAt(i); this.lastChar = charAt; } while (charAt != ';'); return 12; } private byte skipTagBackward() { char charAt; int i = this.charIndex; while (true) { int i2 = this.charIndex; if (i2 <= 0) { break; } CharSequence charSequence = this.text; int i3 = i2 - 1; this.charIndex = i3; char charAt2 = charSequence.charAt(i3); this.lastChar = charAt2; if (charAt2 == '<') { return 12; } if (charAt2 == '>') { break; } else if (charAt2 == '\"' || charAt2 == '\'') { do { int i4 = this.charIndex; if (i4 <= 0) { break; } CharSequence charSequence2 = this.text; int i5 = i4 - 1; this.charIndex = i5; charAt = charSequence2.charAt(i5); this.lastChar = charAt; } while (charAt != charAt2); } } this.charIndex = i; this.lastChar = '>'; return 13; } private byte skipTagForward() { char charAt; int i = this.charIndex; while (true) { int i2 = this.charIndex; if (i2 < this.length) { CharSequence charSequence = this.text; this.charIndex = i2 + 1; char charAt2 = charSequence.charAt(i2); this.lastChar = charAt2; if (charAt2 == '>') { return 12; } if (charAt2 == '\"' || charAt2 == '\'') { do { int i3 = this.charIndex; if (i3 >= this.length) { break; } CharSequence charSequence2 = this.text; this.charIndex = i3 + 1; charAt = charSequence2.charAt(i3); this.lastChar = charAt; } while (charAt != charAt2); } } else { this.charIndex = i; this.lastChar = '<'; return 13; } } } public byte dirTypeBackward() { char charAt = this.text.charAt(this.charIndex - 1); this.lastChar = charAt; if (Character.isLowSurrogate(charAt)) { int codePointBefore = Character.codePointBefore(this.text, this.charIndex); this.charIndex -= Character.charCount(codePointBefore); return Character.getDirectionality(codePointBefore); } this.charIndex--; byte cachedDirectionality = getCachedDirectionality(this.lastChar); if (!this.isHtml) { return cachedDirectionality; } char c2 = this.lastChar; return c2 == '>' ? skipTagBackward() : c2 == ';' ? skipEntityBackward() : cachedDirectionality; } public byte dirTypeForward() { char charAt = this.text.charAt(this.charIndex); this.lastChar = charAt; if (Character.isHighSurrogate(charAt)) { int codePointAt = Character.codePointAt(this.text, this.charIndex); this.charIndex = Character.charCount(codePointAt) + this.charIndex; return Character.getDirectionality(codePointAt); } this.charIndex++; byte cachedDirectionality = getCachedDirectionality(this.lastChar); if (!this.isHtml) { return cachedDirectionality; } char c2 = this.lastChar; return c2 == '<' ? skipTagForward() : c2 == '&' ? skipEntityForward() : cachedDirectionality; } public int getEntryDir() { this.charIndex = 0; int i = 0; int i2 = 0; int i3 = 0; while (this.charIndex < this.length && i == 0) { byte dirTypeForward = dirTypeForward(); if (dirTypeForward != 0) { if (dirTypeForward == 1 || dirTypeForward == 2) { if (i3 == 0) { return 1; } } else if (dirTypeForward != 9) { switch (dirTypeForward) { case 14: case 15: i3++; i2 = -1; break; case 16: case 17: i3++; i2 = 1; break; case 18: i3--; i2 = 0; break; } } } else if (i3 == 0) { return -1; } i = i3; } if (i == 0) { return 0; } if (i2 != 0) { return i2; } while (this.charIndex > 0) { switch (dirTypeBackward()) { case 14: case 15: if (i == i3) { return -1; } break; case 16: case 17: if (i == i3) { return 1; } break; case 18: i3++; continue; } i3--; } return 0; } public int getExitDir() { this.charIndex = this.length; int i = 0; int i2 = 0; while (this.charIndex > 0) { byte dirTypeBackward = dirTypeBackward(); if (dirTypeBackward != 0) { if (dirTypeBackward == 1 || dirTypeBackward == 2) { if (i == 0) { return 1; } if (i2 == 0) { } } else if (dirTypeBackward != 9) { switch (dirTypeBackward) { case 14: case 15: if (i2 == i) { return -1; } i--; break; case 16: case 17: if (i2 == i) { return 1; } i--; break; case 18: i++; break; default: if (i2 != 0) { break; } else { break; } } } else { continue; } } else if (i == 0) { return -1; } else { if (i2 == 0) { } } i2 = i; } return 0; } } static { TextDirectionHeuristicCompat textDirectionHeuristicCompat = TextDirectionHeuristicsCompat.FIRSTSTRONG_LTR; DEFAULT_TEXT_DIRECTION_HEURISTIC = textDirectionHeuristicCompat; DEFAULT_LTR_INSTANCE = new BidiFormatter(false, 2, textDirectionHeuristicCompat); DEFAULT_RTL_INSTANCE = new BidiFormatter(true, 2, textDirectionHeuristicCompat); } public BidiFormatter(boolean z2, int i, TextDirectionHeuristicCompat textDirectionHeuristicCompat) { this.mIsRtlContext = z2; this.mFlags = i; this.mDefaultTextDirectionHeuristicCompat = textDirectionHeuristicCompat; } private static int getEntryDir(CharSequence charSequence) { return new DirectionalityEstimator(charSequence, false).getEntryDir(); } private static int getExitDir(CharSequence charSequence) { return new DirectionalityEstimator(charSequence, false).getExitDir(); } public static BidiFormatter getInstance() { return new Builder().build(); } public static BidiFormatter getInstance(Locale locale) { return new Builder(locale).build(); } public static BidiFormatter getInstance(boolean z2) { return new Builder(z2).build(); } public static boolean isRtlLocale(Locale locale) { return TextUtilsCompat.getLayoutDirectionFromLocale(locale) == 1; } private String markAfter(CharSequence charSequence, TextDirectionHeuristicCompat textDirectionHeuristicCompat) { boolean isRtl = textDirectionHeuristicCompat.isRtl(charSequence, 0, charSequence.length()); return (this.mIsRtlContext || (!isRtl && getExitDir(charSequence) != 1)) ? this.mIsRtlContext ? (!isRtl || getExitDir(charSequence) == -1) ? RLM_STRING : "" : "" : LRM_STRING; } private String markBefore(CharSequence charSequence, TextDirectionHeuristicCompat textDirectionHeuristicCompat) { boolean isRtl = textDirectionHeuristicCompat.isRtl(charSequence, 0, charSequence.length()); return (this.mIsRtlContext || (!isRtl && getEntryDir(charSequence) != 1)) ? this.mIsRtlContext ? (!isRtl || getEntryDir(charSequence) == -1) ? RLM_STRING : "" : "" : LRM_STRING; } public boolean getStereoReset() { return (this.mFlags & 2) != 0; } public boolean isRtl(CharSequence charSequence) { return this.mDefaultTextDirectionHeuristicCompat.isRtl(charSequence, 0, charSequence.length()); } public boolean isRtl(String str) { return isRtl((CharSequence) str); } public boolean isRtlContext() { return this.mIsRtlContext; } public CharSequence unicodeWrap(CharSequence charSequence) { return unicodeWrap(charSequence, this.mDefaultTextDirectionHeuristicCompat, true); } public CharSequence unicodeWrap(CharSequence charSequence, TextDirectionHeuristicCompat textDirectionHeuristicCompat) { return unicodeWrap(charSequence, textDirectionHeuristicCompat, true); } public CharSequence unicodeWrap(CharSequence charSequence, TextDirectionHeuristicCompat textDirectionHeuristicCompat, boolean z2) { if (charSequence == null) { return null; } boolean isRtl = textDirectionHeuristicCompat.isRtl(charSequence, 0, charSequence.length()); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); if (getStereoReset() && z2) { spannableStringBuilder.append((CharSequence) markBefore(charSequence, isRtl ? TextDirectionHeuristicsCompat.RTL : TextDirectionHeuristicsCompat.LTR)); } if (isRtl != this.mIsRtlContext) { spannableStringBuilder.append(isRtl ? (char) 8235 : 8234); spannableStringBuilder.append(charSequence); spannableStringBuilder.append((char) 8236); } else { spannableStringBuilder.append(charSequence); } if (z2) { spannableStringBuilder.append((CharSequence) markAfter(charSequence, isRtl ? TextDirectionHeuristicsCompat.RTL : TextDirectionHeuristicsCompat.LTR)); } return spannableStringBuilder; } public CharSequence unicodeWrap(CharSequence charSequence, boolean z2) { return unicodeWrap(charSequence, this.mDefaultTextDirectionHeuristicCompat, z2); } public String unicodeWrap(String str) { return unicodeWrap(str, this.mDefaultTextDirectionHeuristicCompat, true); } public String unicodeWrap(String str, TextDirectionHeuristicCompat textDirectionHeuristicCompat) { return unicodeWrap(str, textDirectionHeuristicCompat, true); } public String unicodeWrap(String str, TextDirectionHeuristicCompat textDirectionHeuristicCompat, boolean z2) { if (str == null) { return null; } return unicodeWrap((CharSequence) str, textDirectionHeuristicCompat, z2).toString(); } public String unicodeWrap(String str, boolean z2) { return unicodeWrap(str, this.mDefaultTextDirectionHeuristicCompat, z2); } }