blob: 0cc41ba0a36bce3d43040b632971d93678137b7d [file] [log] [blame]
Roozbeh Pournader02f167c2017-06-06 11:31:33 -07001/*
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
17package android.text;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertNull;
22import static org.junit.Assert.assertSame;
23import static org.junit.Assert.assertTrue;
24import static org.junit.Assert.fail;
25
26import android.graphics.Bitmap;
27import android.graphics.Canvas;
28import android.graphics.Paint;
29import android.graphics.Path;
30import android.graphics.Rect;
31import android.graphics.RectF;
32import android.support.test.filters.SmallTest;
33import android.support.test.runner.AndroidJUnit4;
34import android.text.Layout.Alignment;
35import android.text.style.StrikethroughSpan;
36
37import org.junit.Before;
38import org.junit.Test;
39import org.junit.runner.RunWith;
40
41import java.util.ArrayList;
42import java.util.List;
Petar Ĺ eginac7f89452017-08-14 16:11:54 +010043import java.util.Locale;
Roozbeh Pournader02f167c2017-06-06 11:31:33 -070044
45@SmallTest
46@RunWith(AndroidJUnit4.class)
47public class LayoutTest {
48 private static final int LINE_COUNT = 5;
49 private static final int LINE_HEIGHT = 12;
50 private static final int LINE_DESCENT = 4;
51 private static final CharSequence LAYOUT_TEXT = "alwei\t;sdfs\ndf @";
52
53 private SpannableString mSpannedText;
54
55 private int mWidth;
56 private Layout.Alignment mAlign;
57 private float mSpacingMult;
58 private float mSpacingAdd;
59 private TextPaint mTextPaint;
60
61 @Before
62 public void setup() {
63 mTextPaint = new TextPaint();
64 mSpannedText = new SpannableString(LAYOUT_TEXT);
65 mSpannedText.setSpan(new StrikethroughSpan(), 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
66 mWidth = 11;
67 mAlign = Alignment.ALIGN_CENTER;
68 mSpacingMult = 1;
69 mSpacingAdd = 2;
70 }
71
72 @Test
73 public void testConstructor() {
74 new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, mSpacingAdd);
75 }
76
77 @Test(expected = IllegalArgumentException.class)
78 public void testConstructorNull() {
79 new MockLayout(null, null, -1, null, 0, 0);
80 }
81
82 @Test
83 public void testGetText() {
84 CharSequence text = "test case 1";
85 Layout layout = new MockLayout(text, mTextPaint, mWidth,
86 mAlign, mSpacingMult, mSpacingAdd);
87 assertEquals(text, layout.getText());
88
89 layout = new MockLayout(null, mTextPaint, mWidth, mAlign, mSpacingMult, mSpacingAdd);
90 assertNull(layout.getText());
91 }
92
93 @Test
94 public void testGetPaint() {
95 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
96 mAlign, mSpacingMult, mSpacingAdd);
97
98 assertSame(mTextPaint, layout.getPaint());
99
100 layout = new MockLayout(LAYOUT_TEXT, null, mWidth, mAlign, mSpacingMult, mSpacingAdd);
101 assertNull(layout.getPaint());
102 }
103
104 @Test
105 public void testGetWidth() {
106 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 10,
107 mAlign, mSpacingMult, mSpacingAdd);
108 assertEquals(10, layout.getWidth());
109
110 layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingMult, mSpacingAdd);
111 assertEquals(0, layout.getWidth());
112 }
113
114 @Test
115 public void testGetEllipsizedWidth() {
116 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 15,
117 mAlign, mSpacingMult, mSpacingAdd);
118 assertEquals(15, layout.getEllipsizedWidth());
119
120 layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingMult, mSpacingAdd);
121 assertEquals(0, layout.getEllipsizedWidth());
122 }
123
124 @Test
125 public void testIncreaseWidthTo() {
126 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
127 mAlign, mSpacingMult, mSpacingAdd);
128 int oldWidth = layout.getWidth();
129
130 layout.increaseWidthTo(oldWidth);
131 assertEquals(oldWidth, layout.getWidth());
132
133 try {
134 layout.increaseWidthTo(oldWidth - 1);
135 fail("should throw runtime exception attempted to reduce Layout width");
136 } catch (RuntimeException e) {
137 }
138
139 layout.increaseWidthTo(oldWidth + 1);
140 assertEquals(oldWidth + 1, layout.getWidth());
141 }
142
143 @Test
144 public void testGetHeight() {
145 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
146 mAlign, mSpacingMult, mSpacingAdd);
147 assertEquals(60, layout.getHeight());
148 }
149
150 @Test
151 public void testGetAlignment() {
152 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
153 mAlign, mSpacingMult, mSpacingAdd);
154 assertSame(mAlign, layout.getAlignment());
155
156 layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, null, mSpacingMult, mSpacingAdd);
157 assertNull(layout.getAlignment());
158 }
159
160 @Test
161 public void testGetSpacingMultiplier() {
162 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, -1, mSpacingAdd);
163 assertEquals(-1.0f, layout.getSpacingMultiplier(), 0.0f);
164
165 layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, 5, mSpacingAdd);
166 assertEquals(5.0f, layout.getSpacingMultiplier(), 0.0f);
167 }
168
169 @Test
170 public void testGetSpacingAdd() {
171 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, -1);
172 assertEquals(-1.0f, layout.getSpacingAdd(), 0.0f);
173
174 layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, 20);
175 assertEquals(20.0f, layout.getSpacingAdd(), 0.0f);
176 }
177
178 @Test
179 public void testGetLineBounds() {
180 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
181 mAlign, mSpacingMult, mSpacingAdd);
182 Rect bounds = new Rect();
183
184 assertEquals(32, layout.getLineBounds(2, bounds));
185 assertEquals(0, bounds.left);
186 assertEquals(mWidth, bounds.right);
187 assertEquals(24, bounds.top);
188 assertEquals(36, bounds.bottom);
189 }
190
191 @Test
192 public void testGetLineForVertical() {
193 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
194 mAlign, mSpacingMult, mSpacingAdd);
195 assertEquals(0, layout.getLineForVertical(-1));
196 assertEquals(0, layout.getLineForVertical(0));
197 assertEquals(0, layout.getLineForVertical(LINE_COUNT));
198 assertEquals(LINE_COUNT - 1, layout.getLineForVertical(1000));
199 }
200
201 @Test
202 public void testGetLineForOffset() {
203 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
204 mAlign, mSpacingMult, mSpacingAdd);
205 assertEquals(0, layout.getLineForOffset(-1));
206 assertEquals(1, layout.getLineForOffset(1));
207 assertEquals(LINE_COUNT - 1, layout.getLineForOffset(LINE_COUNT - 1));
208 assertEquals(LINE_COUNT - 1, layout.getLineForOffset(1000));
209 }
210
211 @Test
212 public void testGetLineEnd() {
213 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
214 mAlign, mSpacingMult, mSpacingAdd);
215 assertEquals(2, layout.getLineEnd(1));
216 }
217
218 @Test
Siyamed Sinir0fa89d62017-07-24 20:46:41 -0700219 public void testGetLineExtra_returnsZeroByDefault() {
220 final String text = "a\nb\nc\n";
221 final Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
222 mAlign, 100 /* spacingMult*/, 100 /*spacingAdd*/);
223 final int lineCount = text.split("\n").length;
224 for (int i = 0; i < lineCount; i++) {
225 assertEquals(0, layout.getLineExtra(i));
226 }
227 }
228
229 @Test
Roozbeh Pournader02f167c2017-06-06 11:31:33 -0700230 public void testGetLineVisibleEnd() {
231 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
232 mAlign, mSpacingMult, mSpacingAdd);
233
234 assertEquals(2, layout.getLineVisibleEnd(1));
235 assertEquals(LINE_COUNT, layout.getLineVisibleEnd(LINE_COUNT - 1));
236 assertEquals(LAYOUT_TEXT.length(), layout.getLineVisibleEnd(LAYOUT_TEXT.length() - 1));
237 try {
238 layout.getLineVisibleEnd(LAYOUT_TEXT.length());
239 fail("should throw .StringIndexOutOfBoundsException here");
240 } catch (StringIndexOutOfBoundsException e) {
241 }
242 }
243
244 @Test
245 public void testGetLineBottom() {
246 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
247 mAlign, mSpacingMult, mSpacingAdd);
248 assertEquals(LINE_HEIGHT, layout.getLineBottom(0));
249 }
250
251 @Test
252 public void testGetLineBaseline() {
253 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
254 mAlign, mSpacingMult, mSpacingAdd);
255 assertEquals(8, layout.getLineBaseline(0));
256 }
257
258 @Test
259 public void testGetLineAscent() {
260 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
261 mAlign, mSpacingMult, mSpacingAdd);
262 assertEquals(-8, layout.getLineAscent(0));
263 }
264
265 @Test
266 public void testGetParagraphAlignment() {
267 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
268 mAlign, mSpacingMult, mSpacingAdd);
269 assertSame(mAlign, layout.getParagraphAlignment(0));
270
271 layout = new MockLayout(mSpannedText, mTextPaint, mWidth,
272 mAlign, mSpacingMult, mSpacingAdd);
273 assertSame(mAlign, layout.getParagraphAlignment(0));
274 assertSame(mAlign, layout.getParagraphAlignment(1));
275 }
276
277 @Test
278 public void testGetParagraphLeft() {
279 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
280 mAlign, mSpacingMult, mSpacingAdd);
281 assertEquals(0, layout.getParagraphLeft(0));
282 }
283
284 @Test
285 public void testGetParagraphRight() {
286 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
287 mAlign, mSpacingMult, mSpacingAdd);
288 assertEquals(mWidth, layout.getParagraphRight(0));
289 }
290
291 @Test
Petar Ĺ eginac7f89452017-08-14 16:11:54 +0100292 public void testGetSelectionWithEmptySelection() {
293 final Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
294 mAlign, mSpacingMult, mSpacingAdd);
295
296 /*
297 * When the selection is empty (i.e. the start and the end index are the same), we do not
298 * expect any rectangles to be generated.
299 */
300
301 layout.getSelection(5 /* startIndex */, 5 /* endIndex */,
302 (left, top, right, bottom) -> fail(String.format(Locale.getDefault(),
303 "Did not expect any rectangles, got a rectangle with (left: %f,"
304 + " top: %f), (right: %f, bottom: %f)",
305 left, top, right, bottom)));
306 }
307
308 @Test
309 public void testGetSelectionWithASingleLineSelection() {
310 final Layout layout = new StaticLayout("abc", mTextPaint, Integer.MAX_VALUE,
311 Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false);
312
313 final List<RectF> rectangles = new ArrayList<>();
314
315 layout.getSelection(0 /* startIndex */, 1 /* endIndex */,
316 (left, top, right, bottom) -> rectangles.add(new RectF(left, top, right, bottom)));
317
318 /*
319 * The selection we expect will only cover the letter "a". Hence, we expect one rectangle
320 * to be generated and this rectangle should start at the top left of the canvas and should
321 * end somewhere to the right and down.
322 *
323 * | a | b c
324 *
325 */
326
327 assertEquals(1, rectangles.size());
328
329 final RectF rectangle = rectangles.get(0);
330
331 assertEquals(0, rectangle.left, 0.0f);
332 assertEquals(0, rectangle.top, 0.0f);
333 assertTrue(rectangle.right > 0);
334 assertTrue(rectangle.bottom > 0);
335 }
336
337 @Test
338 public void
339 testGetSelectionWithMultilineSelection_secondLineSelectionEndsBeforeFirstCharacter() {
340 final Layout layout = new StaticLayout("a\nb\nc", mTextPaint, Integer.MAX_VALUE,
341 Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false);
342
343 final List<RectF> rectangles = new ArrayList<>();
344
345 layout.getSelection(0 /* startIndex */, 2 /* endIndex */,
346 (left, top, right, bottom) -> rectangles.add(new RectF(left, top, right, bottom)));
347
348 /*
349 * The selection that will be selected is "a\n" - the selection starts at the beginning
350 * of the first line and ends at the start of the second line. This means the selection
351 * highlight will span from the beginning of the first line to the end of the first line
352 * and will appear as a zero width line at the beginning of the second line.
353 *
354 * Hence, we expect three rectangles - one that will select the "a" on the first line,
355 * one that will extend the selection from the "a" to the end of the first line and one
356 * that will prepare the selection for the second line.
357 *
358 * | a | *topToEndOfLineRectangle* |
359 * | b
360 * c
361 */
362
363 assertEquals(3, rectangles.size());
364
365 final RectF topRectangle = rectangles.get(0);
366 final RectF topToEndOfLineRectangle = rectangles.get(1);
367 final RectF bottomLineStartRectangle = rectangles.get(2);
368
369 assertFalse(topRectangle.intersect(bottomLineStartRectangle));
370 assertTrue(topRectangle.top < bottomLineStartRectangle.top);
371 assertTrue(topRectangle.left == bottomLineStartRectangle.left);
372
373 assertFalse(topRectangle.intersect(topToEndOfLineRectangle));
374 assertEquals(Integer.MAX_VALUE, topToEndOfLineRectangle.right, 1);
375 assertTrue(topRectangle.top == topToEndOfLineRectangle.top);
376 assertTrue(topRectangle.right == topToEndOfLineRectangle.left);
377 assertTrue(topRectangle.bottom == topToEndOfLineRectangle.bottom);
378
379 assertEquals(0, bottomLineStartRectangle.left, 0.0f);
380 assertEquals(0, bottomLineStartRectangle.right, 0.0f);
381 }
382
383 @Test
384 public void testGetSelectionWithMultilineSelection_secondLineSelectionEndsAfterACharacter() {
385 final Layout layout = new StaticLayout("a\nb\nc", mTextPaint, Integer.MAX_VALUE,
386 Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false);
387
388 final List<RectF> rectangles = new ArrayList<>();
389
390 layout.getSelection(0 /* startIndex */, 3 /* endIndex */,
391 (left, top, right, bottom) -> rectangles.add(new RectF(left, top, right, bottom)));
392
393 /*
394 * The selection that will be selected is "a\nb" - the selection starts at the beginning
395 * of the first line and ends at the end of the letter "b". This means the selection
396 * highlight will span from the beginning of the first line to the end of the first line
397 * and will also cover the letter "b" on the second line.
398 *
399 * We expect four rectangles - one that will select the "a" on the first line,
400 * one that will extend the selection from the "a" to the end of the first line the one
401 * from the previous case that will prepare the selection for the second line and finally
402 * one that will select the letter b.
403 *
404 * | a | *topToEndOfLineRectangle* |
405 * || b |
406 * c
407 */
408
409 assertEquals(4, rectangles.size());
410
411 final RectF topRectangle = rectangles.get(0);
412 final RectF topToEndOfLineRectangle = rectangles.get(1);
413 final RectF bottomRectangle = rectangles.get(2);
414 final RectF bottomLineStartRectangle = rectangles.get(3);
415
416 assertTrue(topRectangle.top == topToEndOfLineRectangle.top);
417 assertTrue(bottomLineStartRectangle.top == bottomRectangle.top);
418 assertTrue(bottomLineStartRectangle.bottom == bottomRectangle.bottom);
419 assertEquals(0, bottomLineStartRectangle.left, 0.0f);
420 assertEquals(0, bottomLineStartRectangle.right, 0.0f);
421 assertEquals(0, bottomRectangle.left, 0.0f);
422 assertTrue(bottomRectangle.right > 0);
423 }
424
425 @Test
426 public void testGetSelectionPathWithASingleLineSelection() {
427 final Layout layout = new StaticLayout("abc", mTextPaint, Integer.MAX_VALUE,
428 Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false);
429
430 final List<RectF> rectangles = new ArrayList<>();
431
432 layout.getSelection(0 /* startIndex */, 1 /* endIndex */,
433 (left, top, right, bottom) -> rectangles.add(new RectF(left, top, right, bottom)));
434
435 /*
436 * In the single line selection case, we expect that only one rectangle covering the letter
437 * "a" will be generated. Hence, we expect that the generated path will only consist of
438 * that rectangle as well.
439 *
440 * | a | b c
441 *
442 */
443
444 assertEquals(1, rectangles.size());
445
446 final RectF rectangle = rectangles.get(0);
447
448 final Path generatedPath = new Path();
449 layout.getSelectionPath(0 /* startIndex */, 1 /* endIndex */, generatedPath);
450
451 final RectF pathRectangle = new RectF();
452
453 assertTrue(generatedPath.isRect(pathRectangle));
454 assertEquals(rectangle, pathRectangle);
455 }
456
457 @Test
Roozbeh Pournader02f167c2017-06-06 11:31:33 -0700458 public void testIsSpanned() {
459 MockLayout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
460 mAlign, mSpacingMult, mSpacingAdd);
461 // default is not spanned text
462 assertFalse(layout.mockIsSpanned());
463
464 // try to create a spanned text
465 layout = new MockLayout(mSpannedText, mTextPaint, mWidth,
466 mAlign, mSpacingMult, mSpacingAdd);
467 assertTrue(layout.mockIsSpanned());
468 }
469
470 private static final class MockLayout extends Layout {
471 MockLayout(CharSequence text, TextPaint paint, int width,
472 Alignment align, float spacingmult, float spacingadd) {
473 super(text, paint, width, align, spacingmult, spacingadd);
474 }
475
476 protected boolean mockIsSpanned() {
477 return super.isSpanned();
478 }
479
480 @Override
481 public int getBottomPadding() {
482 return 0;
483 }
484
485 @Override
486 public int getEllipsisCount(int line) {
487 return 0;
488 }
489
490 @Override
491 public int getEllipsisStart(int line) {
492 return 0;
493 }
494
495 @Override
496 public boolean getLineContainsTab(int line) {
497 return false;
498 }
499
500 @Override
501 public int getLineCount() {
502 return LINE_COUNT;
503 }
504
505 @Override
506 public int getLineDescent(int line) {
507 return LINE_DESCENT;
508 }
509
510 @Override
511 public Directions getLineDirections(int line) {
512 return Layout.DIRS_ALL_LEFT_TO_RIGHT;
513 }
514
515 @Override
516 public int getLineStart(int line) {
517 if (line < 0) {
518 return 0;
519 }
520 return line;
521 }
522
523 @Override
524 public int getLineTop(int line) {
525 if (line < 0) {
526 return 0;
527 }
528 return LINE_HEIGHT * (line);
529 }
530
531 @Override
532 public int getParagraphDirection(int line) {
533 return 0;
534 }
535
536 @Override
537 public int getTopPadding() {
538 return 0;
539 }
540 }
541
542 @Test
543 public void testGetLineWidth() {
544 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
545 mAlign, mSpacingMult, mSpacingAdd);
546 for (int i = 0; i < LINE_COUNT; i++) {
547 int start = layout.getLineStart(i);
548 int end = layout.getLineEnd(i);
549 String text = LAYOUT_TEXT.toString().substring(start, end);
550 assertEquals(mTextPaint.measureText(text), layout.getLineWidth(i), 1.0f);
551 }
552 }
553
554 @Test
555 public void testGetCursorPath() {
556 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
557 mAlign, mSpacingMult, mSpacingAdd);
558 Path path = new Path();
559 final float epsilon = 1.0f;
560 for (int i = 0; i < LINE_COUNT; i++) {
561 layout.getCursorPath(i, path, LAYOUT_TEXT);
562 RectF bounds = new RectF();
563 path.computeBounds(bounds, false);
564 assertTrue(bounds.top >= layout.getLineTop(i) - epsilon);
565 assertTrue(bounds.bottom <= layout.getLineBottom(i) + epsilon);
566 }
567 }
568
569 @Test
570 public void testDraw() {
571 Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth,
572 mAlign, mSpacingMult, mSpacingAdd);
573 final int width = 256;
574 final int height = 256;
575 MockCanvas c = new MockCanvas(width, height);
576 layout.draw(c);
577 List<MockCanvas.DrawCommand> drawCommands = c.getDrawCommands();
578 assertEquals(LINE_COUNT, drawCommands.size());
579 for (int i = 0; i < LINE_COUNT; i++) {
580 MockCanvas.DrawCommand drawCommand = drawCommands.get(i);
581 int start = layout.getLineStart(i);
582 int end = layout.getLineEnd(i);
583 assertEquals(LAYOUT_TEXT.toString().substring(start, end), drawCommand.text);
584 float expected_y = (i + 1) * LINE_HEIGHT - LINE_DESCENT;
585 assertEquals(expected_y, drawCommand.y, 0.0f);
586 }
587 }
588
589 private final class MockCanvas extends Canvas {
590
591 class DrawCommand {
592 public final String text;
593 public final float x;
594 public final float y;
595
596 DrawCommand(String text, float x, float y) {
597 this.text = text;
598 this.x = x;
599 this.y = y;
600 }
601 }
602
603 List<DrawCommand> mDrawCommands;
604
605 MockCanvas(int width, int height) {
606 super();
607 mDrawCommands = new ArrayList<>();
608 Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
609 setBitmap(bitmap);
610 }
611
612 // Drawing text with either drawText or drawTextRun is valid; we don't care which.
613 // We also don't care which of the string representations is used.
614
615 @Override
616 public void drawText(String text, int start, int end, float x, float y, Paint p) {
617 mDrawCommands.add(new DrawCommand(text.substring(start, end), x, y));
618 }
619
620 @Override
621 public void drawText(CharSequence text, int start, int end, float x, float y, Paint p) {
622 drawText(text.toString(), start, end, x, y, p);
623 }
624
625 @Override
626 public void drawText(char[] text, int index, int count, float x, float y, Paint p) {
627 mDrawCommands.add(new DrawCommand(new String(text, index, count), x, y));
628 }
629
630 @Override
631 public void drawTextRun(CharSequence text, int start, int end, int contextStart,
632 int contextEnd, float x, float y, boolean isRtl, Paint paint) {
633 drawText(text, start, end, x, y, paint);
634 }
635
636 @Override
637 public void drawTextRun(char[] text, int index, int count, int contextIndex,
638 int contextCount, float x, float y, boolean isRtl, Paint paint) {
639 drawText(text, index, count, x, y, paint);
640 }
641
642 List<DrawCommand> getDrawCommands() {
643 return mDrawCommands;
644 }
645 }
646}
647