summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
authorFabrice Di Meglio <fdimeglio@google.com>2011-06-29 20:40:43 -0700
committerFabrice Di Meglio <fdimeglio@google.com>2011-07-01 14:08:19 -0700
commit8f5026562f26dcde43ee9d9182b309c3204dc1ad (patch)
tree70ba6f72c4435661f2ca7c7c8b3e717ceb82b2a7 /core/java/android
parent222688682e6e072076489d8203d01bdf2366101a (diff)
Add charCount heuristic to TextView textDirection
- threshold set to 60% (using a constant) - fix also one issue during layout direction resolution (parent could be null so delay resolution up to when parent is no more null) Change-Id: I65f24a297aac6bc0d5d482ee31b55db0b201e5bf
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/view/View.java22
-rw-r--r--core/java/android/view/ViewGroup.java1
-rw-r--r--core/java/android/widget/TextView.java44
3 files changed, 64 insertions, 3 deletions
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index bf7f359303ef..8a72c4a14c66 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2523,18 +2523,26 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
public static final int TEXT_DIRECTION_ANY_RTL = 2;
/**
+ * Text direction is the same as the one held by a 60% majority of the characters. If there is
+ * no majority then the paragraph direction is the resolved layout direction of the View.
+ *
+ * @hide
+ */
+ public static final int TEXT_DIRECTION_CHAR_COUNT = 3;
+
+ /**
* Text direction is forced to LTR.
*
* @hide
*/
- public static final int TEXT_DIRECTION_LTR = 3;
+ public static final int TEXT_DIRECTION_LTR = 4;
/**
* Text direction is forced to RTL.
*
* @hide
*/
- public static final int TEXT_DIRECTION_RTL = 4;
+ public static final int TEXT_DIRECTION_RTL = 5;
/**
* Default text direction is inherited
@@ -2542,6 +2550,11 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
protected static int DEFAULT_TEXT_DIRECTION = TEXT_DIRECTION_INHERIT;
/**
+ * Default threshold for "char count" heuristic.
+ */
+ protected static float DEFAULT_TEXT_DIRECTION_CHAR_COUNT_THRESHOLD = 0.6f;
+
+ /**
* The text direction that has been defined by {@link #setTextDirection(int)}.
*
* {@hide}
@@ -2551,6 +2564,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
@ViewDebug.IntToString(from = TEXT_DIRECTION_INHERIT, to = "INHERIT"),
@ViewDebug.IntToString(from = TEXT_DIRECTION_FIRST_STRONG, to = "FIRST_STRONG"),
@ViewDebug.IntToString(from = TEXT_DIRECTION_ANY_RTL, to = "ANY_RTL"),
+ @ViewDebug.IntToString(from = TEXT_DIRECTION_CHAR_COUNT, to = "CHAR_COUNT"),
@ViewDebug.IntToString(from = TEXT_DIRECTION_LTR, to = "LTR"),
@ViewDebug.IntToString(from = TEXT_DIRECTION_RTL, to = "RTL")
})
@@ -11963,7 +11977,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
mPrivateFlags |= FORCE_LAYOUT;
mPrivateFlags |= INVALIDATED;
- if (mLayoutParams != null) {
+ if (mLayoutParams != null && mParent != null) {
mLayoutParams.resolveWithDirection(getResolvedLayoutDirection());
}
@@ -12990,6 +13004,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
* {@link #TEXT_DIRECTION_INHERIT},
* {@link #TEXT_DIRECTION_FIRST_STRONG}
* {@link #TEXT_DIRECTION_ANY_RTL},
+ * {@link #TEXT_DIRECTION_CHAR_COUNT},
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
*
@@ -13007,6 +13022,7 @@ public class View implements Drawable.Callback2, KeyEvent.Callback, Accessibilit
* {@link #TEXT_DIRECTION_INHERIT},
* {@link #TEXT_DIRECTION_FIRST_STRONG}
* {@link #TEXT_DIRECTION_ANY_RTL},
+ * {@link #TEXT_DIRECTION_CHAR_COUNT},
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
*
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 2a90ddea3b55..25ca42178417 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -5039,6 +5039,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// Pass down the hierarchy the following text direction values
case TEXT_DIRECTION_FIRST_STRONG:
case TEXT_DIRECTION_ANY_RTL:
+ case TEXT_DIRECTION_CHAR_COUNT:
case TEXT_DIRECTION_LTR:
case TEXT_DIRECTION_RTL:
resolvedTextDirection = mTextDirection;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f79dabd9a808..04b79c5ef8e6 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10039,6 +10039,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
case TEXT_DIRECTION_ANY_RTL:
resolvedTextDirection = getTextDirectionFromAnyRtl(mText);
break;
+ case TEXT_DIRECTION_CHAR_COUNT:
+ resolvedTextDirection = getTextDirectionFromCharCount(mText);
+ break;
case TEXT_DIRECTION_LTR:
resolvedTextDirection = TEXT_DIRECTION_LTR;
break;
@@ -10072,6 +10075,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
private static int getTextDirectionFromFirstStrong(final CharSequence cs) {
final int length = cs.length();
+ if (length == 0) {
+ return TEXT_DIRECTION_UNDEFINED;
+ }
for(int i = 0; i < length; i++) {
final char c = cs.charAt(i);
final byte dir = Character.getDirectionality(c);
@@ -10094,6 +10100,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
*/
private static int getTextDirectionFromAnyRtl(final CharSequence cs) {
final int length = cs.length();
+ if (length == 0) {
+ return TEXT_DIRECTION_UNDEFINED;
+ }
boolean foundStrongLtr = false;
boolean foundStrongRtl = false;
for(int i = 0; i < length; i++) {
@@ -10115,6 +10124,41 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
+ * Get text direction following the "char count" heuristic.
+ *
+ * @param cs the CharSequence used to get the text direction.
+ *
+ * @return {@link #TEXT_DIRECTION_RTL} if direction it RTL, {@link #TEXT_DIRECTION_LTR} if
+ * direction it LTR or {@link #TEXT_DIRECTION_UNDEFINED} if direction cannot be found.
+ */
+ private int getTextDirectionFromCharCount(CharSequence cs) {
+ final int length = cs.length();
+ if (length == 0) {
+ return TEXT_DIRECTION_UNDEFINED;
+ }
+ int countLtr = 0;
+ int countRtl = 0;
+ for(int i = 0; i < length; i++) {
+ final char c = cs.charAt(i);
+ final byte dir = Character.getDirectionality(c);
+ if (isStrongLtrChar(dir)) {
+ countLtr++;
+ } else if (isStrongRtlChar(dir)) {
+ countRtl++;
+ }
+ }
+ final float percentLtr = ((float) countLtr) / (countLtr + countRtl);
+ if (percentLtr > DEFAULT_TEXT_DIRECTION_CHAR_COUNT_THRESHOLD) {
+ return TEXT_DIRECTION_LTR;
+ }
+ final float percentRtl = ((float) countRtl) / (countLtr + countRtl);
+ if (percentRtl > DEFAULT_TEXT_DIRECTION_CHAR_COUNT_THRESHOLD) {
+ return TEXT_DIRECTION_RTL;
+ }
+ return TEXT_DIRECTION_UNDEFINED;
+ }
+
+ /**
* Return true if the char direction is corresponding to a "strong RTL char" following the
* Unicode Bidirectional Algorithm (UBA).
*/