1/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.graphics;
18
19import android.test.AndroidTestCase;
20
21public class PaintTest extends AndroidTestCase {
22    public void testGetTextRunAdvances() {
23        {
24            // LTR
25            String text = "abcdef";
26            assertGetTextRunAdvances(text, 0, text.length(), 0, text.length(), false, true);
27            assertGetTextRunAdvances(text, 1, text.length() - 1, 0, text.length(), false, false);
28        }
29        {
30            // RTL
31            final String text =
32                    "\u0645\u0627\u0020\u0647\u064A\u0020\u0627\u0644\u0634" +
33                    "\u0641\u0631\u0629\u0020\u0627\u0644\u0645\u0648\u062D" +
34                    "\u062F\u0629\u0020\u064A\u0648\u0646\u064A\u0643\u0648" +
35                    "\u062F\u061F";
36            assertGetTextRunAdvances(text, 0, text.length(), 0, text.length(), true, true);
37            assertGetTextRunAdvances(text, 1, text.length() - 1, 0, text.length(), true, false);
38        }
39    }
40
41    private void assertGetTextRunAdvances(String str, int start, int end,
42            int contextStart, int contextEnd, boolean isRtl, boolean compareWithOtherMethods) {
43        Paint p = new Paint();
44
45        final int count = end - start;
46        final float[][] advanceArrays = new float[4][count];
47
48        final float advance = p.getTextRunAdvances(str, start, end, contextStart, contextEnd,
49                isRtl, advanceArrays[0], 0);
50
51        char chars[] = str.toCharArray();
52        final float advance_c = p.getTextRunAdvances(chars, start, count, contextStart,
53                contextEnd - contextStart, isRtl, advanceArrays[1], 0);
54        assertEquals(advance, advance_c, 1.0f);
55
56        for (int c = 1; c < count; ++c) {
57            final float firstPartAdvance = p.getTextRunAdvances(str, start, start + c,
58                    contextStart, contextEnd, isRtl, advanceArrays[2], 0);
59            final float secondPartAdvance = p.getTextRunAdvances(str, start + c, end,
60                    contextStart, contextEnd, isRtl, advanceArrays[2], c);
61            assertEquals(advance, firstPartAdvance + secondPartAdvance, 1.0f);
62
63
64            final float firstPartAdvance_c = p.getTextRunAdvances(chars, start, c,
65                    contextStart, contextEnd - contextStart, isRtl, advanceArrays[3], 0);
66            final float secondPartAdvance_c = p.getTextRunAdvances(chars, start + c,
67                    count - c, contextStart, contextEnd - contextStart, isRtl,
68                    advanceArrays[3], c);
69            assertEquals(advance, firstPartAdvance_c + secondPartAdvance_c, 1.0f);
70            assertEquals(firstPartAdvance, firstPartAdvance_c, 1.0f);
71            assertEquals(secondPartAdvance, secondPartAdvance_c, 1.0f);
72
73            for (int i = 1; i < advanceArrays.length; i++) {
74                for (int j = 0; j < count; j++) {
75                    assertEquals(advanceArrays[0][j], advanceArrays[i][j], 1.0f);
76                }
77            }
78
79            // Compare results with measureText, getRunAdvance, and getTextWidths.
80            if (compareWithOtherMethods && start == contextStart && end == contextEnd) {
81                assertEquals(advance, p.measureText(str, start, end), 1.0f);
82                assertEquals(advance, p.getRunAdvance(
83                        str, start, end, contextStart, contextEnd, isRtl, end), 1.0f);
84
85                final float[] widths = new float[count];
86                p.getTextWidths(str, start, end, widths);
87                for (int i = 0; i < count; i++) {
88                    assertEquals(advanceArrays[0][i], widths[i], 1.0f);
89                }
90            }
91        }
92    }
93
94    public void testGetTextRunAdvances_invalid() {
95        Paint p = new Paint();
96        String text = "test";
97
98        try {
99            p.getTextRunAdvances((String)null, 0, 0, 0, 0, false, null, 0);
100            fail("Should throw an IllegalArgumentException.");
101        } catch (IllegalArgumentException e) {
102        }
103
104        try {
105            p.getTextRunAdvances((CharSequence)null, 0, 0, 0, 0, false, null, 0);
106            fail("Should throw an IllegalArgumentException.");
107        } catch (IllegalArgumentException e) {
108        }
109
110        try {
111            p.getTextRunAdvances((char[])null, 0, 0, 0, 0, false, null, 0);
112            fail("Should throw an IllegalArgumentException.");
113        } catch (IllegalArgumentException e) {
114        }
115
116        try {
117            p.getTextRunAdvances(text, 0, text.length(), 0, text.length(), false,
118                    new float[text.length() - 1], 0);
119            fail("Should throw an IndexOutOfBoundsException.");
120        } catch (IndexOutOfBoundsException e) {
121        }
122
123        try {
124            p.getTextRunAdvances(text, 0, text.length(), 0, text.length(), false,
125                    new float[text.length()], 1);
126            fail("Should throw an IndexOutOfBoundsException.");
127        } catch (IndexOutOfBoundsException e) {
128        }
129
130        // 0 > contextStart
131        try {
132            p.getTextRunAdvances(text, 0, text.length(), -1, text.length(), false, null, 0);
133            fail("Should throw an IndexOutOfBoundsException.");
134        } catch (IndexOutOfBoundsException e) {
135        }
136
137        // contextStart > start
138        try {
139            p.getTextRunAdvances(text, 0, text.length(), 1, text.length(), false, null, 0);
140            fail("Should throw an IndexOutOfBoundsException.");
141        } catch (IndexOutOfBoundsException e) {
142        }
143
144        // start > end
145        try {
146            p.getTextRunAdvances(text, 1, 0, 0, text.length(), false, null, 0);
147            fail("Should throw an IndexOutOfBoundsException.");
148        } catch (IndexOutOfBoundsException e) {
149        }
150
151        // end > contextEnd
152        try {
153            p.getTextRunAdvances(text, 0, text.length(), 0, text.length() - 1, false, null, 0);
154            fail("Should throw an IndexOutOfBoundsException.");
155        } catch (IndexOutOfBoundsException e) {
156        }
157
158        // contextEnd > text.length
159        try {
160            p.getTextRunAdvances(text, 0, text.length(), 0, text.length() + 1, false, null, 0);
161            fail("Should throw an IndexOutOfBoundsException.");
162        } catch (IndexOutOfBoundsException e) {
163        }
164    }
165
166    public void testMeasureTextBidi() {
167        Paint p = new Paint();
168        {
169            String bidiText = "abc \u0644\u063A\u0629 def";
170            p.setBidiFlags(Paint.BIDI_LTR);
171            float width = p.measureText(bidiText, 0, 4);
172            p.setBidiFlags(Paint.BIDI_RTL);
173            width += p.measureText(bidiText, 4, 7);
174            p.setBidiFlags(Paint.BIDI_LTR);
175            width += p.measureText(bidiText, 7, bidiText.length());
176            assertEquals(width, p.measureText(bidiText), 1.0f);
177        }
178        {
179            String bidiText = "abc \u0644\u063A\u0629 def";
180            p.setBidiFlags(Paint.BIDI_DEFAULT_LTR);
181            float width = p.measureText(bidiText, 0, 4);
182            width += p.measureText(bidiText, 4, 7);
183            width += p.measureText(bidiText, 7, bidiText.length());
184            assertEquals(width, p.measureText(bidiText), 1.0f);
185        }
186        {
187            String bidiText = "abc \u0644\u063A\u0629 def";
188            p.setBidiFlags(Paint.BIDI_FORCE_LTR);
189            float width = p.measureText(bidiText, 0, 4);
190            width += p.measureText(bidiText, 4, 7);
191            width += p.measureText(bidiText, 7, bidiText.length());
192            assertEquals(width, p.measureText(bidiText), 1.0f);
193        }
194        {
195            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
196            p.setBidiFlags(Paint.BIDI_RTL);
197            float width = p.measureText(bidiText, 0, 4);
198            p.setBidiFlags(Paint.BIDI_LTR);
199            width += p.measureText(bidiText, 4, 7);
200            p.setBidiFlags(Paint.BIDI_RTL);
201            width += p.measureText(bidiText, 7, bidiText.length());
202            assertEquals(width, p.measureText(bidiText), 1.0f);
203        }
204        {
205            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
206            p.setBidiFlags(Paint.BIDI_DEFAULT_RTL);
207            float width = p.measureText(bidiText, 0, 4);
208            width += p.measureText(bidiText, 4, 7);
209            width += p.measureText(bidiText, 7, bidiText.length());
210            assertEquals(width, p.measureText(bidiText), 1.0f);
211        }
212        {
213            String bidiText = "\u0644\u063A\u0629 abc \u0644\u063A\u0629";
214            p.setBidiFlags(Paint.BIDI_FORCE_RTL);
215            float width = p.measureText(bidiText, 0, 4);
216            width += p.measureText(bidiText, 4, 7);
217            width += p.measureText(bidiText, 7, bidiText.length());
218            assertEquals(width, p.measureText(bidiText), 1.0f);
219        }
220    }
221}
222