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

Commit 937a7ba3 authored by Steve Kondik's avatar Steve Kondik Committed by Gerrit Code Review
Browse files

Merge "-Fixes issue 3573...

Merge "-Fixes issue 3573 (http://code.google.com/p/cyanogenmod/issues/detail?id=3573) with RTL characters wrapping down to the next line when there's enough space on the line itself." into gingerbread
parents daa64c6c 33376da5
Loading
Loading
Loading
Loading
+24 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ package android.text;
     * @param off
     * @param len
     * @return int
     * @hide
     */
    public static int reorderAndReshapeBidiText(char[] chs, char[] outputChs, int off, int len) {

@@ -64,7 +65,30 @@ package android.text;
        return reorderReshapeBidiText(chs, outputChs, off, len);
    }

    /**
     * @author: Eyad Aboulouz
     * Arabic text reshaping by by calling native reshapeArabicText function
     * @param chs
     * @param map
     * @param off
     * @param len
     * @return int
     * @hide
     */
    public static int reshapeReversedArabicText(char[] chs, char[] outputChs, int off, int len) {

        if (chs == null)
            throw new NullPointerException();

        if (off < 0 || len < 0 || off + len > chs.length)
            throw new IndexOutOfBoundsException();

        return reshapeArabicText(chs, outputChs, off, len);
    }

    private native static int runBidi(int dir, char[] chs, byte[] chInfo, int n, boolean haveInfo);

    private native static int reorderReshapeBidiText(char[] chs, char[] outputChs, int off, int len);

    private native static int reshapeArabicText(char[] chs, char[] outputChs, int off, int len);
}
 No newline at end of file
+121 −6
Original line number Diff line number Diff line
@@ -18,11 +18,9 @@ package android.text;

import com.android.internal.R;

import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.method.TextKeyListener.Capitalize;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.AlignmentSpan;
import android.text.style.BackgroundColorSpan;
@@ -48,9 +46,6 @@ import android.util.Printer;

import com.android.internal.util.ArrayUtils;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.util.regex.Pattern;
import java.util.Iterator;

@@ -1697,6 +1692,17 @@ public class TextUtils {
               (c >= 0xFE70 && c <= 0xFEFE)    ;
    }

    /**
     * @hide
     */
    private static boolean isArabicCharacter(char c) {
        //range of Arabic characters per unicode specification
        return (c >= 0x0600 && c <= 0x06FF) ||
               (c >= 0x0750 && c <= 0x077F) ||
               (c >= 0xFB50 && c <= 0xFDFF) ||
               (c >= 0xFE70 && c <= 0xFEFE)    ;
    }

    /**
     * function to check if text range has RTL characters.
     * @hide
@@ -1714,6 +1720,40 @@ public class TextUtils {
        return false;
    }

    /**
     * function to check if text range has Arabic characters.
     * @hide
     */
    private static boolean hasArabicCharacters(final char[] text, int start, int end) {
        if (text == null)
            return false;

        //go through all characters
        for (int i = start; i < end; i++) {
            if (isArabicCharacter(text[i]))
                return true;
        }

        return false;
    }

    /**
     * function to check if text range has Arabic characters.
     * @hide
     */
    public static boolean hasArabicCharacters(String text, int start, int end) {
        if (text == null)
            return false;

        //go through all characters
        for (int i = start; i < end; i++) {
            if (isArabicCharacter(text.charAt(i)))
                return true;
        }

        return false;
    }

    /**
     * function to check if text range has RTL characters.
     * @hide
@@ -1741,6 +1781,16 @@ public class TextUtils {
        return src == null ? null : TextUtils.processBidi(src, 0, src.length());
    }

    /**
     * function to reshape the given text
     * @param src
     * @return String
     * @hide
     */
    public static String reshapeArabic(final String src) {
        return src == null ? null : TextUtils.reshapeArabic(src, 0, src.length());
    }

    /**
     * function to process bidi the given text
     * @param src
@@ -1751,6 +1801,16 @@ public class TextUtils {
        return src == null ? null : TextUtils.processBidi(src, 0, src.length);
    }

    /**
     * function to reshape the given text
     * @param src
     * @return char[]
     * @hide
     */
    public static char[] reshapeArabic(final char[] src) {
        return src == null ? null : TextUtils.reshapeArabicChars(src, 0, src.length);
    }

    /**
     * function to process bidi on the given text
     * @param src
@@ -1763,6 +1823,18 @@ public class TextUtils {
        return src != null && hasRTLCharacters(src, start, end) ? String.valueOf(TextUtils.processBidi(src.toCharArray(), start, end)) : src;
    }

    /**
     * function to reshape the given text
     * @param src
     * @param begin
     * @param end
     * @return String
     * @hide
     */
    public static String reshapeArabic(final String src, int start, int end) {
        return src != null && hasArabicCharacters(src, start, end) ? String.valueOf(TextUtils.reshapeArabicChars(src.toCharArray(), start, end)) : src;
    }

    /**
     * function to process bidi on the given text
     * @author: Eyad Aboulouz
@@ -1773,7 +1845,20 @@ public class TextUtils {
     * @hide
     */
    public static char[] processBidi(final char[] src, int start, int end) {
        return src != null && hasRTLCharacters(src, start, end) ? processBidiChars(src, start, end) : src;
        return src != null && hasRTLCharacters(src, start, end) ? TextUtils.processBidiChars(src, start, end) : src;
    }

    /**
     * function to reshape the given text
     * @author: Eyad Aboulouz
     * @param src
     * @param start
     * @param end
     * @return char[]
     * @hide
     */
    public static char[] reshapeArabic(final char[] src, int start, int end) {
        return src != null && hasArabicCharacters(src, start, end) ? TextUtils.reshapeArabicChars(src, start, end) : src;
    }

    /**
@@ -1806,6 +1891,36 @@ public class TextUtils {
        }
    }

    /**
     * function to reshape arabic text
     * @author: Eyad Aboulouz
     * @param src
     * @param start
     * @param end
     * @return char[]
     * @hide
     */
    private static char[] reshapeArabicChars(final char[] src, int start, int end) {

        try {
            char[] outputTxt = new char[end-start];
            char[] ret = src.clone();

            int outputSize = AndroidBidi.reshapeReversedArabicText(ret, outputTxt, start, end-start);

            if (outputSize != (end-start))
                throw new Exception ("Error Processing Bidi Reordering And Reshaping");

            System.arraycopy(outputTxt, 0, ret, start, end-start);

            return (ret);

        } catch (Exception e) {

            return (src);
        }
    }

    private static Object sLock = new Object();
    private static char[] sTemp = null;
}
+49 −1
Original line number Diff line number Diff line
@@ -114,11 +114,59 @@ static jint reorderReshapeBidiText (JNIEnv* env, jclass c, jcharArray srcArray,
    return outputSize;
}

/*
Native Arabic text reshaping
by: Eyad Aboulouz
*/
static jint reshapeArabicText (JNIEnv* env, jclass c, jcharArray srcArray, jcharArray destArray, jint offset, jint n) {

    bool hasErrors = false;
    jint outputSize = 0;
    UChar *intermediate = new UChar[n];
    UChar *intermediate2 = new UChar[n];
    UChar *output = new UChar[n];
    UErrorCode status = U_ZERO_ERROR;

    jchar* src = env->GetCharArrayElements(srcArray, NULL);

    if (src != NULL) {

        ubidi_writeReverse (src+offset, n, intermediate, n, UBIDI_DO_MIRRORING | UBIDI_REMOVE_BIDI_CONTROLS, &status);

        if (U_SUCCESS(status)) {
            outputSize = u_shapeArabic(intermediate, n, intermediate2, n, U_SHAPE_TEXT_DIRECTION_VISUAL_LTR | U_SHAPE_LETTERS_SHAPE | U_SHAPE_LENGTH_FIXED_SPACES_AT_END, &status);

            if (U_SUCCESS(status)) {

                ubidi_writeReverse (intermediate2, n, output, n, UBIDI_REMOVE_BIDI_CONTROLS, &status);

                env->SetCharArrayRegion(destArray, 0, outputSize, output);
            } else
                hasErrors = true;
        } else
            hasErrors = true;
    } else
        hasErrors = true;

    delete [] intermediate;
    delete [] intermediate2;
    delete [] output;

    env->ReleaseCharArrayElements(srcArray, src, JNI_ABORT);

    if (hasErrors)
        jniThrowException(env, "java/lang/RuntimeException", NULL);

    return outputSize;
}

static JNINativeMethod gMethods[] = {
        { "runBidi", "(I[C[BIZ)I",
        (void*) runBidi },
        { "reorderReshapeBidiText", "([C[CII)I",
        (void*) reorderReshapeBidiText }
        (void*) reorderReshapeBidiText },
        { "reshapeArabicText", "([C[CII)I",
        (void*) reshapeArabicText }
};

int register_android_text_AndroidBidi(JNIEnv* env)
+7 −7
Original line number Diff line number Diff line
@@ -1000,7 +1000,7 @@ public class Paint {
     */
    public float measureText(char[] text, int index, int count) {

        char[] text2 = TextUtils.processBidi(text, index, index+count);
        char[] text2 = TextUtils.reshapeArabic(text, index, index+count);

        if (!mHasCompatScaling) return native_measureText(text2, index, count);
        final float oldSize = getTextSize();
@@ -1022,7 +1022,7 @@ public class Paint {
     */
    public float measureText(String text, int start, int end) {

        String text2 = TextUtils.processBidi(text, start, end);
        String text2 = TextUtils.reshapeArabic(text, start, end);

        if (!mHasCompatScaling) return native_measureText(text2, start, end);
        final float oldSize = getTextSize();
@@ -1042,7 +1042,7 @@ public class Paint {
     */
    public float measureText(String text) {

        String text2 = TextUtils.processBidi(text);
        String text2 = TextUtils.reshapeArabic(text);

        if (!mHasCompatScaling) return native_measureText(text2);
        final float oldSize = getTextSize();
@@ -1101,7 +1101,7 @@ public class Paint {
    public int breakText(char[] text, int index, int count,
                                float maxWidth, float[] measuredWidth) {

        char[] text2 = TextUtils.processBidi(text);
        char[] text2 = TextUtils.reshapeArabic(text);

        if (!mHasCompatScaling) {
            return native_breakText(text2, index, count, maxWidth, measuredWidth);
@@ -1176,7 +1176,7 @@ public class Paint {
    public int breakText(String text, boolean measureForwards,
                                float maxWidth, float[] measuredWidth) {

        String text2 = TextUtils.processBidi(text);
        String text2 = TextUtils.reshapeArabic(text);

        if (!mHasCompatScaling) {
            return native_breakText(text2, measureForwards, maxWidth, measuredWidth);
@@ -1210,7 +1210,7 @@ public class Paint {
            throw new ArrayIndexOutOfBoundsException();
        }

        char[] text2 = TextUtils.processBidi(text, index, index+count);
        char[] text2 = TextUtils.reshapeArabic(text, index, index+count);

        if (!mHasCompatScaling) {
            return native_getTextWidths(mNativePaint, text2, index, count, widths);
@@ -1275,7 +1275,7 @@ public class Paint {
            throw new ArrayIndexOutOfBoundsException();
        }

        String text2 = TextUtils.processBidi(text, start, end);
        String text2 = TextUtils.reshapeArabic(text, start, end);

        if (!mHasCompatScaling) {
            return native_getTextWidths(mNativePaint, text2, start, end, widths);