summaryrefslogtreecommitdiff
path: root/android/text/NonEditableTextGenerator.java
blob: 7c0cf0eebc790f9ee86e64e1869a8f2da5e04af2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
package android.text;

import static android.text.Spanned.SPAN_INCLUSIVE_INCLUSIVE;

import android.text.style.BulletSpan;

import java.util.Random;

/**
 *
 */
public class NonEditableTextGenerator {

    enum TextType {
        STRING,
        SPANNED,
        SPANNABLE_BUILDER
    }

    private boolean mCreateBoring;
    private TextType mTextType;
    private int mSequenceLength;
    private final Random mRandom;

    public NonEditableTextGenerator(Random random) {
        mRandom = random;
    }

    public NonEditableTextGenerator setCreateBoring(boolean createBoring) {
        mCreateBoring = createBoring;
        return this;
    }

    public NonEditableTextGenerator setTextType(TextType textType) {
        mTextType = textType;
        return this;
    }

    public NonEditableTextGenerator setSequenceLength(int sequenceLength) {
        mSequenceLength = sequenceLength;
        return this;
    }

    /**
     * Sample charSequence generated:
     * NRjPzjvUadHmH ExoEoTqfx pCLw qtndsqfpk AqajVCbgjGZ igIeC dfnXRgA
     */
    public CharSequence build() {
        final RandomCharSequenceGenerator sequenceGenerator = new RandomCharSequenceGenerator(
                mRandom);
        if (mSequenceLength > 0) {
            sequenceGenerator.setSequenceLength(mSequenceLength);
        }

        final CharSequence charSequence = sequenceGenerator.buildLatinSequence();

        switch (mTextType) {
            case SPANNED:
            case SPANNABLE_BUILDER:
                return createSpannable(charSequence);
            case STRING:
            default:
                return createString(charSequence);
        }
    }

    private Spannable createSpannable(CharSequence charSequence) {
        final Spannable spannable = (mTextType == TextType.SPANNABLE_BUILDER) ?
                new SpannableStringBuilder(charSequence) : new SpannableString(charSequence);

        if (!mCreateBoring) {
            // add a paragraph style to make it non boring
            spannable.setSpan(new BulletSpan(), 0, spannable.length(), SPAN_INCLUSIVE_INCLUSIVE);
        }

        spannable.setSpan(new Object(), 0, spannable.length(), SPAN_INCLUSIVE_INCLUSIVE);
        spannable.setSpan(new Object(), 0, 1, SPAN_INCLUSIVE_INCLUSIVE);

        return spannable;
    }

    private String createString(CharSequence charSequence) {
        if (mCreateBoring) {
            return charSequence.toString();
        } else {
            // BoringLayout checks to see if there is a surrogate pair and if so tells that
            // the charSequence is not suitable for boring. Add an emoji to make it non boring.
            // Emoji is added instead of RTL, since emoji stays in the same run and is a more
            // common case.
            return charSequence.toString() + "\uD83D\uDC68\uD83C\uDFFF";
        }
    }

    public static class RandomCharSequenceGenerator {

        private static final int DEFAULT_MIN_WORD_LENGTH = 3;
        private static final int DEFAULT_MAX_WORD_LENGTH = 15;
        private static final int DEFAULT_SEQUENCE_LENGTH = 256;

        private int mMinWordLength = DEFAULT_MIN_WORD_LENGTH;
        private int mMaxWordLength = DEFAULT_MAX_WORD_LENGTH;
        private int mSequenceLength = DEFAULT_SEQUENCE_LENGTH;
        private final Random mRandom;

        public RandomCharSequenceGenerator(Random random) {
            mRandom = random;
        }

        public RandomCharSequenceGenerator setSequenceLength(int sequenceLength) {
            mSequenceLength = sequenceLength;
            return this;
        }

        public CharSequence buildLatinSequence() {
            final StringBuilder result = new StringBuilder();
            while (result.length() < mSequenceLength) {
                // add random word
                result.append(buildLatinWord());
                result.append(' ');
            }
            return result.substring(0, mSequenceLength);
        }

        public CharSequence buildLatinWord() {
            final StringBuilder result = new StringBuilder();
            // create a random length that is (mMinWordLength + random amount of chars) where
            // total size is less than mMaxWordLength
            final int length = mRandom.nextInt(mMaxWordLength - mMinWordLength) + mMinWordLength;
            while (result.length() < length) {
                // add random letter
                int base = mRandom.nextInt(2) == 0 ? 'A' : 'a';
                result.append(Character.toChars(mRandom.nextInt(26) + base));
            }
            return result.toString();
        }
    }

}