1 /*
2  * Copyright (C) 2008 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 
17 package android.text.cts;
18 
19 
20 import android.graphics.Rect;
21 import android.test.AndroidTestCase;
22 import android.text.Layout;
23 import android.text.Spannable;
24 import android.text.SpannableString;
25 import android.text.TextPaint;
26 import android.text.Layout.Alignment;
27 import android.text.style.StrikethroughSpan;
28 
29 public class LayoutTest extends AndroidTestCase {
30     private final static int LINE_COUNT = 5;
31     private final static int LINE_HEIGHT = 12;
32     private final static int LINE_DESCENT = 4;
33     private final static CharSequence LAYOUT_TEXT = "alwei\t;sdfs\ndf @";
34 
35     private int mWidth;
36     private Layout.Alignment mAlign;
37     private float mSpacingmult;
38     private float mSpacingadd;
39     private SpannableString mSpannedText;
40 
41     private TextPaint mTextPaint;
42 
43     @Override
setUp()44     protected void setUp() throws Exception {
45         super.setUp();
46         mTextPaint = new TextPaint();
47         mSpannedText = new SpannableString(LAYOUT_TEXT);
48         mSpannedText.setSpan(new StrikethroughSpan(), 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
49         mWidth = 11;
50         mAlign = Alignment.ALIGN_CENTER;
51         mSpacingmult = 1;
52         mSpacingadd = 2;
53     }
54 
testConstructor()55     public void testConstructor() {
56         new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingmult, mSpacingadd);
57 
58         try {
59             new MockLayout(null, null, -1, null, 0, 0);
60             fail("should throw IllegalArgumentException here");
61         } catch (IllegalArgumentException e) {
62         }
63     }
64 
testGetText()65     public void testGetText() {
66         CharSequence text = "test case 1";
67         Layout layout = new MockLayout(text, mTextPaint, mWidth,
68                 mAlign, mSpacingmult, mSpacingadd);
69         assertEquals(text, layout.getText());
70 
71         layout = new MockLayout(null, mTextPaint, mWidth, mAlign, mSpacingmult, mSpacingadd);
72         assertNull(layout.getText());
73     }
74 
testGetPaint()75     public void testGetPaint() {
76         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
77                 mAlign, mSpacingmult, mSpacingadd);
78 
79         assertSame(mTextPaint, layout.getPaint());
80 
81         layout = new MockLayout(LAYOUT_TEXT, null, mWidth, mAlign, mSpacingmult, mSpacingadd);
82         assertNull(layout.getPaint());
83     }
84 
testGetWidth()85     public void testGetWidth() {
86         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 10,
87                 mAlign, mSpacingmult, mSpacingadd);
88         assertEquals(10,  layout.getWidth());
89 
90         layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingmult, mSpacingadd);
91         assertEquals(0,  layout.getWidth());
92     }
93 
testGetEllipsizedWidth()94     public void testGetEllipsizedWidth() {
95         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 15,
96                 mAlign, mSpacingmult, mSpacingadd);
97         assertEquals(15, layout.getEllipsizedWidth());
98 
99         layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingmult, mSpacingadd);
100         assertEquals(0,  layout.getEllipsizedWidth());
101     }
102 
testIncreaseWidthTo()103     public void testIncreaseWidthTo() {
104         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
105                 mAlign, mSpacingmult, mSpacingadd);
106         int oldWidth = layout.getWidth();
107 
108         layout.increaseWidthTo(oldWidth);
109         assertEquals(oldWidth, layout.getWidth());
110 
111         try {
112             layout.increaseWidthTo(oldWidth - 1);
113             fail("should throw runtime exception attempted to reduce Layout width");
114         } catch (RuntimeException e) {
115         }
116 
117         layout.increaseWidthTo(oldWidth + 1);
118         assertEquals(oldWidth + 1, layout.getWidth());
119     }
120 
testGetHeight()121     public void testGetHeight() {
122         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
123                 mAlign, mSpacingmult, mSpacingadd);
124         assertEquals(60, layout.getHeight());
125     }
126 
testGetAlignment()127     public void testGetAlignment() {
128         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
129                 mAlign, mSpacingmult, mSpacingadd);
130         assertSame(mAlign, layout.getAlignment());
131 
132         layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, null, mSpacingmult, mSpacingadd);
133         assertNull(layout.getAlignment());
134     }
135 
testGetSpacingMultiplier()136     public void testGetSpacingMultiplier() {
137         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, -1, mSpacingadd);
138         assertEquals(-1.0f, layout.getSpacingMultiplier());
139 
140         layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, 5, mSpacingadd);
141         assertEquals(5.0f, layout.getSpacingMultiplier());
142     }
143 
testGetSpacingAdd()144     public void testGetSpacingAdd() {
145         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingmult, -1);
146         assertEquals(-1.0f, layout.getSpacingAdd());
147 
148         layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingmult, 20);
149         assertEquals(20.0f, layout.getSpacingAdd());
150     }
151 
testGetLineBounds()152     public void testGetLineBounds() {
153         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
154                 mAlign, mSpacingmult, mSpacingadd);
155         Rect bounds = new Rect();
156 
157         assertEquals(32, layout.getLineBounds(2, bounds));
158         assertEquals(0, bounds.left);
159         assertEquals(mWidth, bounds.right);
160         assertEquals(24, bounds.top);
161         assertEquals(36, bounds.bottom);
162     }
163 
testGetLineForVertical()164     public void testGetLineForVertical() {
165         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
166                 mAlign, mSpacingmult, mSpacingadd);
167         assertEquals(0, layout.getLineForVertical(-1));
168         assertEquals(0, layout.getLineForVertical(0));
169         assertEquals(0, layout.getLineForVertical(LINE_COUNT));
170         assertEquals(LINE_COUNT - 1, layout.getLineForVertical(1000));
171     }
172 
testGetLineForOffset()173     public void testGetLineForOffset() {
174         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
175                 mAlign, mSpacingmult, mSpacingadd);
176         assertEquals(0, layout.getLineForOffset(-1));
177         assertEquals(1, layout.getLineForOffset(1));
178         assertEquals(LINE_COUNT - 1, layout.getLineForOffset(LINE_COUNT - 1));
179         assertEquals(LINE_COUNT - 1, layout.getLineForOffset(1000));
180     }
181 
testGetLineEnd()182     public void testGetLineEnd() {
183         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
184                 mAlign, mSpacingmult, mSpacingadd);
185         assertEquals(2, layout.getLineEnd(1));
186     }
187 
testGetLineVisibleEnd()188     public void testGetLineVisibleEnd() {
189         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
190                 mAlign, mSpacingmult, mSpacingadd);
191 
192         assertEquals(2, layout.getLineVisibleEnd(1));
193         assertEquals(LINE_COUNT, layout.getLineVisibleEnd(LINE_COUNT - 1));
194         assertEquals(LAYOUT_TEXT.length(), layout.getLineVisibleEnd(LAYOUT_TEXT.length() - 1));
195         try {
196             layout.getLineVisibleEnd(LAYOUT_TEXT.length());
197             fail("should throw .StringIndexOutOfBoundsException here");
198         } catch (StringIndexOutOfBoundsException e) {
199         }
200     }
201 
testGetLineBottom()202     public void testGetLineBottom() {
203         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
204                 mAlign, mSpacingmult, mSpacingadd);
205         assertEquals(LINE_HEIGHT, layout.getLineBottom(0));
206     }
207 
testGetLineBaseline()208     public void testGetLineBaseline() {
209         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
210                 mAlign, mSpacingmult, mSpacingadd);
211         assertEquals(8, layout.getLineBaseline(0));
212     }
213 
testGetLineAscent()214     public void testGetLineAscent() {
215         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
216                 mAlign, mSpacingmult, mSpacingadd);
217         assertEquals(-8, layout.getLineAscent(0));
218     }
219 
testGetParagraphAlignment()220     public void testGetParagraphAlignment() {
221         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
222                 mAlign, mSpacingmult, mSpacingadd);
223         assertSame(mAlign, layout.getParagraphAlignment(0));
224 
225         layout = new MockLayout(mSpannedText, mTextPaint, mWidth,
226                 mAlign, mSpacingmult, mSpacingadd);
227         assertSame(mAlign, layout.getParagraphAlignment(0));
228         assertSame(mAlign, layout.getParagraphAlignment(1));
229     }
230 
testGetParagraphLeft()231     public void testGetParagraphLeft() {
232         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
233                 mAlign, mSpacingmult, mSpacingadd);
234         assertEquals(0, layout.getParagraphLeft(0));
235     }
236 
testGetParagraphRight()237     public void testGetParagraphRight() {
238         Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
239                 mAlign, mSpacingmult, mSpacingadd);
240         assertEquals(mWidth, layout.getParagraphRight(0));
241     }
242 
testIsSpanned()243     public void testIsSpanned() {
244         MockLayout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
245                 mAlign, mSpacingmult, mSpacingadd);
246         // default is not spanned text
247         assertFalse(layout.mockIsSpanned());
248 
249         // try to create a spanned text
250         layout = new MockLayout(mSpannedText, mTextPaint, mWidth,
251                 mAlign, mSpacingmult, mSpacingadd);
252         assertTrue(layout.mockIsSpanned());
253     }
254 
testGetDesiredWidthRange()255     public void testGetDesiredWidthRange() {
256         CharSequence textShort = "test";
257         CharSequence textLonger = "test\ngetDesiredWidth";
258         CharSequence textLongest = "test getDesiredWidth";
259         TextPaint paint = new TextPaint();
260         float widthShort = Layout.getDesiredWidth(textShort, 0, textShort.length(), paint);
261         float widthLonger = Layout.getDesiredWidth(textLonger, 0, textLonger.length(), paint);
262         float widthLongest = Layout.getDesiredWidth(textLongest, 0, textLongest.length(), paint);
263         float widthPartShort = Layout.getDesiredWidth(textShort, 2, textShort.length(), paint);
264         float widthZero = Layout.getDesiredWidth(textLonger, 5, textShort.length() - 3, paint);
265         assertTrue(widthLonger > widthShort);
266         assertTrue(widthLongest > widthLonger);
267         assertEquals(0f, widthZero);
268         assertTrue(widthShort > widthPartShort);
269     }
270 
testGetDesiredWidth()271     public void testGetDesiredWidth() {
272         CharSequence textShort = "test";
273         CharSequence textLonger = "test\ngetDesiredWidth";
274         CharSequence textLongest = "test getDesiredWidth";
275         TextPaint paint = new TextPaint();
276         float widthShort = Layout.getDesiredWidth(textShort, paint);
277         float widthLonger = Layout.getDesiredWidth(textLonger, paint);
278         float widthLongest = Layout.getDesiredWidth(textLongest, paint);
279         assertTrue(widthLonger > widthShort);
280         assertTrue(widthLongest > widthLonger);
281     }
282 
283     private final class MockLayout extends Layout {
MockLayout(CharSequence text, TextPaint paint, int width, Alignment align, float spacingmult, float spacingadd)284         public MockLayout(CharSequence text, TextPaint paint, int width,
285                 Alignment align, float spacingmult, float spacingadd) {
286             super(text, paint, width, align, spacingmult, spacingadd);
287         }
288 
mockIsSpanned()289         protected boolean mockIsSpanned() {
290             return super.isSpanned();
291         }
292 
293         @Override
getBottomPadding()294         public int getBottomPadding() {
295             return 0;
296         }
297 
298         @Override
getEllipsisCount(int line)299         public int getEllipsisCount(int line) {
300             return 0;
301         }
302 
303         @Override
getEllipsisStart(int line)304         public int getEllipsisStart(int line) {
305             return 0;
306         }
307 
308         @Override
getLineContainsTab(int line)309         public boolean getLineContainsTab(int line) {
310             return false;
311         }
312 
313         @Override
getLineCount()314         public int getLineCount() {
315             return LINE_COUNT;
316         }
317 
318         @Override
getLineDescent(int line)319         public int getLineDescent(int line) {
320             return LINE_DESCENT;
321         }
322 
323         @Override
getLineDirections(int line)324         public Directions getLineDirections(int line) {
325             return null;
326         }
327 
328         @Override
getLineStart(int line)329         public int getLineStart(int line) {
330             if (line < 0) {
331                 return 0;
332             }
333             return line;
334         }
335 
336         @Override
getLineTop(int line)337         public int getLineTop(int line) {
338             if (line < 0) {
339                 return 0;
340             }
341             return LINE_HEIGHT * (line);
342         }
343 
344         @Override
getParagraphDirection(int line)345         public int getParagraphDirection(int line) {
346             return 0;
347         }
348 
349         @Override
getTopPadding()350         public int getTopPadding() {
351             return 0;
352         }
353     }
354 }
355