Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8c08fc9a authored by Fabrice Di Meglio's avatar Fabrice Di Meglio
Browse files

Fix bug #8656546 API REVIEW: android.text.bidi / android.text

- clean BidiFormatter APIs

Change-Id: I8591ce3c3e8f2de4138698aa14ddb38b933de5e1
parent 18414c4d
Loading
Loading
Loading
Loading
+22 −43
Original line number Diff line number Diff line
@@ -22723,6 +22723,28 @@ package android.text {
    method public static int getSize(android.view.View);
  }
  public final class BidiFormatter {
    method public static android.text.BidiFormatter getInstance();
    method public static android.text.BidiFormatter getInstance(boolean);
    method public static android.text.BidiFormatter getInstance(java.util.Locale);
    method public boolean getStereoReset();
    method public boolean isRtl(java.lang.String);
    method public boolean isRtlContext();
    method public java.lang.String unicodeWrap(java.lang.String, android.text.TextDirectionHeuristic, boolean);
    method public java.lang.String unicodeWrap(java.lang.String, android.text.TextDirectionHeuristic);
    method public java.lang.String unicodeWrap(java.lang.String, boolean);
    method public java.lang.String unicodeWrap(java.lang.String);
  }
  public static final class BidiFormatter.Builder {
    ctor public BidiFormatter.Builder();
    ctor public BidiFormatter.Builder(boolean);
    ctor public BidiFormatter.Builder(java.util.Locale);
    method public android.text.BidiFormatter build();
    method public android.text.BidiFormatter.Builder setTextDirectionHeuristic(android.text.TextDirectionHeuristic);
    method public android.text.BidiFormatter.Builder stereoReset(boolean);
  }
  public class BoringLayout extends android.text.Layout implements android.text.TextUtils.EllipsizeCallback {
    ctor public BoringLayout(java.lang.CharSequence, android.text.TextPaint, int, android.text.Layout.Alignment, float, float, android.text.BoringLayout.Metrics, boolean);
    ctor public BoringLayout(java.lang.CharSequence, android.text.TextPaint, int, android.text.Layout.Alignment, float, float, android.text.BoringLayout.Metrics, boolean, android.text.TextUtils.TruncateAt, int);
@@ -23217,49 +23239,6 @@ package android.text {
}
package android.text.bidi {
  public final class BidiFormatter {
    method public java.lang.String dirAttr(java.lang.String);
    method public java.lang.String dirAttr(java.lang.String, android.text.TextDirectionHeuristic);
    method public java.lang.String dirAttr(boolean);
    method public java.lang.String dirAttrValue(java.lang.String);
    method public java.lang.String dirAttrValue(java.lang.String, android.text.TextDirectionHeuristic);
    method public java.lang.String dirAttrValue(boolean);
    method public java.lang.String endEdge();
    method public static android.text.bidi.BidiFormatter getInstance();
    method public static android.text.bidi.BidiFormatter getInstance(boolean);
    method public static android.text.bidi.BidiFormatter getInstance(java.util.Locale);
    method public boolean getStereoReset();
    method public boolean isRtl(java.lang.String);
    method public boolean isRtlContext();
    method public java.lang.String mark();
    method public java.lang.String markAfter(java.lang.String);
    method public java.lang.String markAfter(java.lang.String, android.text.TextDirectionHeuristic);
    method public java.lang.String markBefore(java.lang.String);
    method public java.lang.String markBefore(java.lang.String, android.text.TextDirectionHeuristic);
    method public java.lang.String spanWrap(java.lang.String, android.text.TextDirectionHeuristic, boolean);
    method public java.lang.String spanWrap(java.lang.String, android.text.TextDirectionHeuristic);
    method public java.lang.String spanWrap(java.lang.String, boolean);
    method public java.lang.String spanWrap(java.lang.String);
    method public java.lang.String startEdge();
    method public java.lang.String unicodeWrap(java.lang.String, android.text.TextDirectionHeuristic, boolean);
    method public java.lang.String unicodeWrap(java.lang.String, android.text.TextDirectionHeuristic);
    method public java.lang.String unicodeWrap(java.lang.String, boolean);
    method public java.lang.String unicodeWrap(java.lang.String);
  }
  public static final class BidiFormatter.Builder {
    ctor public BidiFormatter.Builder();
    ctor public BidiFormatter.Builder(boolean);
    ctor public BidiFormatter.Builder(java.util.Locale);
    method public android.text.bidi.BidiFormatter build();
    method public android.text.bidi.BidiFormatter.Builder setTextDirectionHeuristic(android.text.TextDirectionHeuristic);
    method public android.text.bidi.BidiFormatter.Builder stereoReset(boolean);
  }
}
package android.text.format {
  public class DateFormat {
+13 −260
Original line number Diff line number Diff line
@@ -14,18 +14,14 @@
 * limitations under the License.
 */

package android.text.bidi;
package android.text;

import android.text.TextDirectionHeuristic;
import android.text.TextDirectionHeuristics;
import android.text.TextUtils;
import android.view.View;

import static android.text.TextDirectionHeuristics.FIRSTSTRONG_LTR;

import java.util.Locale;


/**
 * Utility class for formatting text for display in a potentially opposite-directionality context
 * without garbling. The directionality of the context is set at formatter creation and the
@@ -34,14 +30,12 @@ import java.util.Locale;
 * <p>
 * 1. Bidi Wrapping
 * When text in one language is mixed into a document in another, opposite-directionality language,
 * e.g. when an English business name is embedded in a Hebrew web page, both the inserted string
 * e.g. when an English business name is embedded in some Hebrew text, both the inserted string
 * and the text surrounding it may be displayed incorrectly unless the inserted string is explicitly
 * separated from the surrounding text in a "wrapper" that:
 * <p>
 * - Declares its directionality so that the string is displayed correctly. This can be done in HTML
 *   markup (e.g. a 'span dir="rtl"' element) by {@link #spanWrap} and similar methods, or - only in
 *   contexts where markup can't be used - in Unicode bidi formatting codes by {@link #unicodeWrap}
 *   and similar methods.
 * - Declares its directionality so that the string is displayed correctly. This can be done in
 *   Unicode bidi formatting codes by {@link #unicodeWrap} and similar methods.
 * <p>
 * - Isolates the string's directionality, so it does not unduly affect the surrounding content.
 *   Currently, this can only be done using invisible Unicode characters of the same direction as
@@ -80,16 +74,6 @@ import java.util.Locale;
 * estimated at run-time. The bidi formatter can do this automatically using the default
 * first-strong estimation algorithm. It can also be configured to use a custom directionality
 * estimation object.
 * <p>
 * 3. Escaping
 * When wrapping plain text - i.e. text that is not already HTML or HTML-escaped - in HTML markup,
 * the text must first be HTML-escaped to prevent XSS attacks and other nasty business. This of
 * course is always true, but the escaping can not be done after the string has already been wrapped
 * in markup, so the bidi formatter also serves as a last chance and includes escaping services.
 * <p>
 * Thus, in a single call, the formatter will escape the input string as specified, determine its
 * directionality, and wrap it as necessary. It is then up to the caller to insert the return value
 * in the output.
 */
public final class BidiFormatter {

@@ -133,36 +117,6 @@ public final class BidiFormatter {
     */
    private static final String RLM_STRING = Character.toString(RLM);

    /**
     * "ltr" string constant.
     */
    private static final String LTR_STRING = "ltr";

    /**
     * "rtl" string constant.
     */
    private static final String RTL_STRING = "rtl";

    /**
     * "dir=\"ltr\"" string constant.
     */
    private static final String DIR_LTR_STRING = "dir=\"ltr\"";

    /**
     * "dir=\"rtl\"" string constant.
     */
    private static final String DIR_RTL_STRING = "dir=\"rtl\"";

    /**
     * "right" string constant.
     */
    private static final String RIGHT = "right";

    /**
     * "left" string constant.
     */
    private static final String LEFT = "left";

    /**
     * Empty string constant.
     */
@@ -324,77 +278,6 @@ public final class BidiFormatter {
        return (mFlags & FLAG_STEREO_RESET) != 0;
    }

    /**
     * Returns "rtl" if {@code str}'s estimated directionality is RTL, and "ltr" if it is LTR.
     *
     * @param str String whose directionality is to be estimated.
     * @return "rtl" if {@code str}'s estimated directionality is RTL, and "ltr" otherwise.
     */
    public String dirAttrValue(String str) {
        return dirAttrValue(isRtl(str));
    }

    /**
     * Operates like {@link #dirAttrValue(String)}, but uses a given heuristic to estimate the
     * {@code str}'s directionality.
     *
     * @param str String whose directionality is to be estimated.
     * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s
     *                  directionality.
     * @return "rtl" if {@code str}'s estimated directionality is RTL, and "ltr" otherwise.
     */
    public String dirAttrValue(String str, TextDirectionHeuristic heuristic) {
        return dirAttrValue(heuristic.isRtl(str, 0, str.length()));
    }

    /**
     * Returns "rtl" if the given directionality is RTL, and "ltr" if it is LTR.
     *
     * @param isRtl Whether the directionality is RTL or not.
     * @return "rtl" if the given directionality is RTL, and "ltr" otherwise.
     */
    public String dirAttrValue(boolean isRtl) {
        return isRtl ? RTL_STRING : LTR_STRING;
    }

    /**
     * Returns "dir=\"ltr\"" or "dir=\"rtl\"", depending on {@code str}'s estimated directionality,
     * if it is not the same as the context directionality. Otherwise, returns the empty string.
     *
     * @param str String whose directionality is to be estimated.
     * @return "dir=\"rtl\"" for RTL text in non-RTL context; "dir=\"ltr\"" for LTR text in non-LTR
     *     context; else, the empty string.
     */
    public String dirAttr(String str) {
        return dirAttr(isRtl(str));
    }

    /**
     * Operates like {@link #dirAttr(String)}, but uses a given heuristic to estimate the
     * {@code str}'s directionality.
     *
     * @param str String whose directionality is to be estimated.
     * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s
     *                  directionality.
     * @return "dir=\"rtl\"" for RTL text in non-RTL context; "dir=\"ltr\"" for LTR text in non-LTR
     *     context; else, the empty string.
     */
    public String dirAttr(String str, TextDirectionHeuristic heuristic) {
        return dirAttr(heuristic.isRtl(str, 0, str.length()));
    }

    /**
     * Returns "dir=\"ltr\"" or "dir=\"rtl\"", depending on the given directionality, if it is not
     * the same as the context directionality. Otherwise, returns the empty string.
     *
     * @param isRtl Whether the directionality is RTL or not
     * @return "dir=\"rtl\"" for RTL text in non-RTL context; "dir=\"ltr\"" for LTR text in non-LTR
     *     context; else, the empty string.
     */
    public String dirAttr(boolean isRtl) {
        return (isRtl != mIsRtlContext) ? (isRtl ? DIR_RTL_STRING :  DIR_LTR_STRING) : EMPTY_STRING;
    }

    /**
     * Returns a Unicode bidi mark matching the context directionality (LRM or RLM) if either the
     * overall or the exit directionality of a given string is opposite to the context directionality.
@@ -402,25 +285,15 @@ public final class BidiFormatter {
     * from "sticking" to other opposite-directionality text or a number appearing after it inline
     * with only neutral content in between. Otherwise returns the empty string. While the exit
     * directionality is determined by scanning the end of the string, the overall directionality is
     * given explicitly in {@code dir}.
     *
     * @param str String after which the mark may need to appear.
     * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context;
     *     else, the empty string.
     */
    public String markAfter(String str) {
        return markAfter(str, mDefaultTextDirectionHeuristic);
    }

    /**
     * Operates like {@link #markAfter(String)}, but uses a given heuristic to estimate the
     * {@code str}'s directionality.
     * given explicitly by a heuristic to estimate the {@code str}'s directionality.
     *
     * @param str String after which the mark may need to appear.
     * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s
     *                  directionality.
     * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context;
     *     else, the empty string.
     *
     * @hide
     */
    public String markAfter(String str, TextDirectionHeuristic heuristic) {
        final boolean isRtl = heuristic.isRtl(str, 0, str.length());
@@ -438,28 +311,18 @@ public final class BidiFormatter {
     * Returns a Unicode bidi mark matching the context directionality (LRM or RLM) if either the
     * overall or the entry directionality of a given string is opposite to the context
     * directionality. Putting this before the string (including its directionality declaration
     * wrapping) prevents it from "sticking" to other opposite-directionality text appearing before it
     * inline with only neutral content in between. Otherwise returns the empty string. While the
     * wrapping) prevents it from "sticking" to other opposite-directionality text appearing before
     * it inline with only neutral content in between. Otherwise returns the empty string. While the
     * entry directionality is determined by scanning the beginning of the string, the overall
     * directionality is given explicitly in {@code dir}.
     *
     * @param str String before which the mark may need to appear.
     * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context;
     *     else, the empty string.
     */
    public String markBefore(String str) {
        return markBefore(str, mDefaultTextDirectionHeuristic);
    }

    /**
     * Operates like {@link #markBefore(String)}, but uses a given heuristic to estimate the
     * {@code str}'s directionality.
     * directionality is given explicitly by a heuristic to estimate the {@code str}'s directionality.
     *
     * @param str String before which the mark may need to appear.
     * @param heuristic The text direction heuristic that will be used to estimate the {@code str}'s
     *                  directionality.
     * @return LRM for RTL text in LTR context; RLM for LTR text in RTL context;
     *     else, the empty string.
     *
     * @hide
     */
    public String markBefore(String str, TextDirectionHeuristic heuristic) {
        final boolean isRtl = heuristic.isRtl(str, 0, str.length());
@@ -473,30 +336,6 @@ public final class BidiFormatter {
        return EMPTY_STRING;
    }

    /**
     * Returns the Unicode bidi mark matching the context directionality (LRM for LTR context
     * directionality, RLM for RTL context directionality).
     */
    public String mark() {
        return mIsRtlContext ? RLM_STRING : LRM_STRING;
    }

    /**
     * Returns "right" for RTL context directionality. Otherwise for LTR context directionality
     * returns "left".
     */
    public String startEdge() {
        return mIsRtlContext ? RIGHT : LEFT;
    }

    /**
     * Returns "left" for RTL context directionality. Otherwise for LTR context directionality
     * returns "right".
     */
    public String endEdge() {
        return mIsRtlContext ? LEFT : RIGHT;
    }

    /**
     * Estimates the directionality of a string using the default text direction heuristic.
     *
@@ -508,96 +347,10 @@ public final class BidiFormatter {
        return mDefaultTextDirectionHeuristic.isRtl(str, 0, str.length());
    }

    /**
     * Formats a given string of unknown directionality for use in HTML output of the context
     * directionality, so an opposite-directionality string is neither garbled nor garbles its
     * surroundings.
     * <p>
     * The algorithm: estimates the directionality of the given string using the given heuristic.
     * If the directionality is known, pass TextDirectionHeuristics.LTR or RTL for heuristic.
     * In case its directionality doesn't match the context directionality, wraps it with a 'span'
     * element and adds a "dir" attribute (either 'dir=\"rtl\"' or 'dir=\"ltr\"').
     * <p>
     * If {@code isolate}, directionally isolates the string so that it does not garble its
     * surroundings. Currently, this is done by "resetting" the directionality after the string by
     * appending a trailing Unicode bidi mark matching the context directionality (LRM or RLM) when
     * either the overall directionality or the exit directionality of the string is opposite to that
     * of the context. If the formatter was built using {@link Builder#stereoReset(boolean)} and
     * passing "true" as an argument, also prepends a Unicode bidi mark matching the context
     * directionality when either the overall directionality or the entry directionality of the
     * string is opposite to that of the context.
     * <p>
     *
     * @param str The input string.
     * @param heuristic The algorithm to be used to estimate the string's overall direction.
     * @param isolate Whether to directionally isolate the string to prevent it from garbling the
     *     content around it.
     * @return Input string after applying the above processing.
     */
    public String spanWrap(String str, TextDirectionHeuristic heuristic, boolean isolate) {
        final boolean isRtl = heuristic.isRtl(str, 0, str.length());
        String origStr = str;
        str = TextUtils.htmlEncode(str);

        StringBuilder result = new StringBuilder();
        if (getStereoReset() && isolate) {
            result.append(markBefore(origStr,
                    isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR));
        }
        if (isRtl != mIsRtlContext) {
            result.append("<span ").append(dirAttr(isRtl)).append('>').append(str).append("</span>");
        } else {
            result.append(str);
        }
        if (isolate) {
            result.append(markAfter(origStr,
                    isRtl ? TextDirectionHeuristics.RTL : TextDirectionHeuristics.LTR));
        }
        return result.toString();
    }

    /**
     * Operates like {@link #spanWrap(String, TextDirectionHeuristic, boolean)}, but assumes
     * {@code isolate} is true.
     *
     * @param str The input string.
     * @param heuristic The algorithm to be used to estimate the string's overall direction.
     * @return Input string after applying the above processing.
     */
    public String spanWrap(String str, TextDirectionHeuristic heuristic) {
        return spanWrap(str, heuristic, true /* isolate */);
    }

    /**
     * Operates like {@link #spanWrap(String, TextDirectionHeuristic, boolean)}, but uses the
     * formatter's default direction estimation algorithm.
     *
     * @param str The input string.
     * @param isolate Whether to directionally isolate the string to prevent it from garbling the
     *     content around it
     * @return Input string after applying the above processing.
     */
    public String spanWrap(String str, boolean isolate) {
        return spanWrap(str, mDefaultTextDirectionHeuristic, isolate);
    }

    /**
     * Operates like {@link #spanWrap(String, TextDirectionHeuristic, boolean)}, but uses the
     * formatter's default direction estimation algorithm and assumes {@code isolate} is true.
     *
     * @param str The input string.
     * @return Input string after applying the above processing.
     */
    public String spanWrap(String str) {
        return spanWrap(str, mDefaultTextDirectionHeuristic, true /* isolate */);
    }

    /**
     * Formats a string of given directionality for use in plain-text output of the context
     * directionality, so an opposite-directionality string is neither garbled nor garbles its
     * surroundings. As opposed to {@link #spanWrap}, this makes use of Unicode bidi
     * formatting characters. In HTML, its *only* valid use is inside of elements that do not allow
     * markup, e.g. the 'option' and 'title' elements.
     * surroundings. This makes use of Unicode bidi formatting characters.
     * <p>
     * The algorithm: In case the given directionality doesn't match the context directionality, wraps
     * the string with Unicode bidi formatting characters: RLE+{@code str}+PDF for RTL text, or