102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader/* 202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * Copyright (C) 2008 The Android Open Source Project 302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * 402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * Licensed under the Apache License, Version 2.0 (the "License"); 502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * you may not use this file except in compliance with the License. 602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * You may obtain a copy of the License at 702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * 802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * http://www.apache.org/licenses/LICENSE-2.0 902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * 1002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * Unless required by applicable law or agreed to in writing, software 1102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * distributed under the License is distributed on an "AS IS" BASIS, 1202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * See the License for the specific language governing permissions and 1402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader * limitations under the License. 1502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader */ 1602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 1702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderpackage android.text; 1802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 1902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport static org.junit.Assert.assertEquals; 2002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport static org.junit.Assert.assertFalse; 2102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport static org.junit.Assert.assertNull; 2202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport static org.junit.Assert.assertSame; 2302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport static org.junit.Assert.assertTrue; 2402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport static org.junit.Assert.fail; 2502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 2602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.graphics.Bitmap; 2702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.graphics.Canvas; 2802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.graphics.Paint; 2902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.graphics.Path; 3002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.graphics.Rect; 3102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.graphics.RectF; 32a6b12de7dfaccd61e904d9cb69d9e07d6a9ce377Siyamed Sinirimport android.platform.test.annotations.Presubmit; 3302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.support.test.filters.SmallTest; 3402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.support.test.runner.AndroidJUnit4; 3502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.text.Layout.Alignment; 3602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport android.text.style.StrikethroughSpan; 3702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 3802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport org.junit.Before; 3902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport org.junit.Test; 4002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport org.junit.runner.RunWith; 4102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 4202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport java.util.ArrayList; 4302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderimport java.util.List; 44c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å eginaimport java.util.Locale; 4502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 46a6b12de7dfaccd61e904d9cb69d9e07d6a9ce377Siyamed Sinir@Presubmit 4702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader@SmallTest 4802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader@RunWith(AndroidJUnit4.class) 4902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournaderpublic class LayoutTest { 5002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private static final int LINE_COUNT = 5; 5102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private static final int LINE_HEIGHT = 12; 5202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private static final int LINE_DESCENT = 4; 5302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private static final CharSequence LAYOUT_TEXT = "alwei\t;sdfs\ndf @"; 5402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 5502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private SpannableString mSpannedText; 5602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 5702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private int mWidth; 5802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private Layout.Alignment mAlign; 5902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private float mSpacingMult; 6002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private float mSpacingAdd; 6102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private TextPaint mTextPaint; 6202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 6302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Before 6402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void setup() { 6502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mTextPaint = new TextPaint(); 6602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mSpannedText = new SpannableString(LAYOUT_TEXT); 6702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mSpannedText.setSpan(new StrikethroughSpan(), 0, 1, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); 6802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mWidth = 11; 6902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign = Alignment.ALIGN_CENTER; 7002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mSpacingMult = 1; 7102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mSpacingAdd = 2; 7202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 7302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 7402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 7502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testConstructor() { 7602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, mSpacingAdd); 7702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 7802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 7902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test(expected = IllegalArgumentException.class) 8002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testConstructorNull() { 8102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader new MockLayout(null, null, -1, null, 0, 0); 8202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 8302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 8402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 8502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetText() { 8602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader CharSequence text = "test case 1"; 8702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(text, mTextPaint, mWidth, 8802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 8902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(text, layout.getText()); 9002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 9102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(null, mTextPaint, mWidth, mAlign, mSpacingMult, mSpacingAdd); 9202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertNull(layout.getText()); 9302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 9402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 9502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 9602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetPaint() { 9702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 9802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 9902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 10002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertSame(mTextPaint, layout.getPaint()); 10102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 10202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(LAYOUT_TEXT, null, mWidth, mAlign, mSpacingMult, mSpacingAdd); 10302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertNull(layout.getPaint()); 10402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 10502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 10602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 10702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetWidth() { 10802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 10, 10902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 11002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(10, layout.getWidth()); 11102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 11202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingMult, mSpacingAdd); 11302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(0, layout.getWidth()); 11402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 11502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 11602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 11702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetEllipsizedWidth() { 11802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 15, 11902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 12002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(15, layout.getEllipsizedWidth()); 12102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 12202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(LAYOUT_TEXT, mTextPaint, 0, mAlign, mSpacingMult, mSpacingAdd); 12302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(0, layout.getEllipsizedWidth()); 12402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 12502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 12602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 12702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testIncreaseWidthTo() { 12802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 12902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 13002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader int oldWidth = layout.getWidth(); 13102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 13202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout.increaseWidthTo(oldWidth); 13302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(oldWidth, layout.getWidth()); 13402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 13502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader try { 13602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout.increaseWidthTo(oldWidth - 1); 13702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader fail("should throw runtime exception attempted to reduce Layout width"); 13802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } catch (RuntimeException e) { 13902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 14002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 14102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout.increaseWidthTo(oldWidth + 1); 14202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(oldWidth + 1, layout.getWidth()); 14302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 14402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 14502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 14602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetHeight() { 14702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 14802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 14902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(60, layout.getHeight()); 15002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 15102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 15202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 15302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetAlignment() { 15402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 15502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 15602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertSame(mAlign, layout.getAlignment()); 15702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 15802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, null, mSpacingMult, mSpacingAdd); 15902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertNull(layout.getAlignment()); 16002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 16102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 16202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 16302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetSpacingMultiplier() { 16402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, -1, mSpacingAdd); 16502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(-1.0f, layout.getSpacingMultiplier(), 0.0f); 16602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 16702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, 5, mSpacingAdd); 16802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(5.0f, layout.getSpacingMultiplier(), 0.0f); 16902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 17002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 17102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 17202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetSpacingAdd() { 17302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, -1); 17402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(-1.0f, layout.getSpacingAdd(), 0.0f); 17502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 17602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, mAlign, mSpacingMult, 20); 17702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(20.0f, layout.getSpacingAdd(), 0.0f); 17802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 17902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 18002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 18102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineBounds() { 18202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 18302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 18402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Rect bounds = new Rect(); 18502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 18602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(32, layout.getLineBounds(2, bounds)); 18702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(0, bounds.left); 18802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(mWidth, bounds.right); 18902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(24, bounds.top); 19002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(36, bounds.bottom); 19102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 19202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 19302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 19402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineForVertical() { 19502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 19602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 19702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(0, layout.getLineForVertical(-1)); 19802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(0, layout.getLineForVertical(0)); 19902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(0, layout.getLineForVertical(LINE_COUNT)); 20002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(LINE_COUNT - 1, layout.getLineForVertical(1000)); 20102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 20202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 20302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 20402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineForOffset() { 20502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 20602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 20702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(0, layout.getLineForOffset(-1)); 20802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(1, layout.getLineForOffset(1)); 20902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(LINE_COUNT - 1, layout.getLineForOffset(LINE_COUNT - 1)); 21002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(LINE_COUNT - 1, layout.getLineForOffset(1000)); 21102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 21202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 21302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 21402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineEnd() { 21502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 21602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 21702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(2, layout.getLineEnd(1)); 21802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 21902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 22002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 2210fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir public void testGetLineExtra_returnsZeroByDefault() { 2220fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir final String text = "a\nb\nc\n"; 2230fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir final Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 2240fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir mAlign, 100 /* spacingMult*/, 100 /*spacingAdd*/); 2250fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir final int lineCount = text.split("\n").length; 2260fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir for (int i = 0; i < lineCount; i++) { 2270fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir assertEquals(0, layout.getLineExtra(i)); 2280fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir } 2290fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir } 2300fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir 2310fa89d6f62c31a033a9dece9c7cfee2d50dc063dSiyamed Sinir @Test 23202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineVisibleEnd() { 23302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 23402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 23502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 23602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(2, layout.getLineVisibleEnd(1)); 23702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(LINE_COUNT, layout.getLineVisibleEnd(LINE_COUNT - 1)); 23802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(LAYOUT_TEXT.length(), layout.getLineVisibleEnd(LAYOUT_TEXT.length() - 1)); 23902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader try { 24002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout.getLineVisibleEnd(LAYOUT_TEXT.length()); 24102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader fail("should throw .StringIndexOutOfBoundsException here"); 24202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } catch (StringIndexOutOfBoundsException e) { 24302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 24402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 24502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 24602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 24702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineBottom() { 24802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 24902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 25002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(LINE_HEIGHT, layout.getLineBottom(0)); 25102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 25202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 25302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 25402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineBaseline() { 25502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 25602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 25702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(8, layout.getLineBaseline(0)); 25802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 25902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 26002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 26102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineAscent() { 26202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 26302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 26402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(-8, layout.getLineAscent(0)); 26502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 26602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 26702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 26802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetParagraphAlignment() { 26902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 27002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 27102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertSame(mAlign, layout.getParagraphAlignment(0)); 27202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 27302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(mSpannedText, mTextPaint, mWidth, 27402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 27502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertSame(mAlign, layout.getParagraphAlignment(0)); 27602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertSame(mAlign, layout.getParagraphAlignment(1)); 27702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 27802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 27902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 28002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetParagraphLeft() { 28102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 28202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 28302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(0, layout.getParagraphLeft(0)); 28402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 28502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 28602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 28702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetParagraphRight() { 28802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 28902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 29002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(mWidth, layout.getParagraphRight(0)); 29102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 29202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 29302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 294c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina public void testGetSelectionWithEmptySelection() { 295c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 296c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina mAlign, mSpacingMult, mSpacingAdd); 297c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 298c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina /* 299c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * When the selection is empty (i.e. the start and the end index are the same), we do not 300c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * expect any rectangles to be generated. 301c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina */ 302c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 303c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina layout.getSelection(5 /* startIndex */, 5 /* endIndex */, 304b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina (left, top, right, bottom, textSelectionLayout) -> fail( 305b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina String.format(Locale.getDefault(), 306c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina "Did not expect any rectangles, got a rectangle with (left: %f," 307c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina + " top: %f), (right: %f, bottom: %f)", 308c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina left, top, right, bottom))); 309c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina } 310c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 311c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina @Test 312c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina public void testGetSelectionWithASingleLineSelection() { 313c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final Layout layout = new StaticLayout("abc", mTextPaint, Integer.MAX_VALUE, 314c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false); 315c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 316c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final List<RectF> rectangles = new ArrayList<>(); 317c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 318c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina layout.getSelection(0 /* startIndex */, 1 /* endIndex */, 319b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina (left, top, right, bottom, textSelectionLayout) -> rectangles.add( 320b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina new RectF(left, top, right, bottom))); 321c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 322c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina /* 323c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * The selection we expect will only cover the letter "a". Hence, we expect one rectangle 324c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * to be generated and this rectangle should start at the top left of the canvas and should 325c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * end somewhere to the right and down. 326c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * 327c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * | a | b c 328c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * 329c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina */ 330c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 331c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(1, rectangles.size()); 332c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 333c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF rectangle = rectangles.get(0); 334c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 335c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(0, rectangle.left, 0.0f); 336c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(0, rectangle.top, 0.0f); 337c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(rectangle.right > 0); 338c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(rectangle.bottom > 0); 339c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina } 340c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 341c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina @Test 342c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina public void 343c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina testGetSelectionWithMultilineSelection_secondLineSelectionEndsBeforeFirstCharacter() { 344c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final Layout layout = new StaticLayout("a\nb\nc", mTextPaint, Integer.MAX_VALUE, 345c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false); 346c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 347c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final List<RectF> rectangles = new ArrayList<>(); 348c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 349c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina layout.getSelection(0 /* startIndex */, 2 /* endIndex */, 350b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina (left, top, right, bottom, textSelectionLayout) -> rectangles.add( 351b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina new RectF(left, top, right, bottom))); 352c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 353c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina /* 354c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * The selection that will be selected is "a\n" - the selection starts at the beginning 355c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * of the first line and ends at the start of the second line. This means the selection 356c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * highlight will span from the beginning of the first line to the end of the first line 357c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * and will appear as a zero width line at the beginning of the second line. 358c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * 359c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * Hence, we expect three rectangles - one that will select the "a" on the first line, 360c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * one that will extend the selection from the "a" to the end of the first line and one 361c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * that will prepare the selection for the second line. 362c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * 363c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * | a | *topToEndOfLineRectangle* | 364c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * | b 365c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * c 366c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina */ 367c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 368c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(3, rectangles.size()); 369c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 370c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF topRectangle = rectangles.get(0); 371c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF topToEndOfLineRectangle = rectangles.get(1); 372c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF bottomLineStartRectangle = rectangles.get(2); 373c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 374c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertFalse(topRectangle.intersect(bottomLineStartRectangle)); 375c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(topRectangle.top < bottomLineStartRectangle.top); 376c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(topRectangle.left == bottomLineStartRectangle.left); 377c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 378c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertFalse(topRectangle.intersect(topToEndOfLineRectangle)); 379c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(Integer.MAX_VALUE, topToEndOfLineRectangle.right, 1); 380c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(topRectangle.top == topToEndOfLineRectangle.top); 381c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(topRectangle.right == topToEndOfLineRectangle.left); 382c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(topRectangle.bottom == topToEndOfLineRectangle.bottom); 383c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 384c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(0, bottomLineStartRectangle.left, 0.0f); 385c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(0, bottomLineStartRectangle.right, 0.0f); 386c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina } 387c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 388c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina @Test 389c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina public void testGetSelectionWithMultilineSelection_secondLineSelectionEndsAfterACharacter() { 390c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final Layout layout = new StaticLayout("a\nb\nc", mTextPaint, Integer.MAX_VALUE, 391c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false); 392c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 393c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final List<RectF> rectangles = new ArrayList<>(); 394c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 395c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina layout.getSelection(0 /* startIndex */, 3 /* endIndex */, 396b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina (left, top, right, bottom, textSelectionLayout) -> rectangles.add( 397b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina new RectF(left, top, right, bottom))); 398c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 399c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina /* 400c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * The selection that will be selected is "a\nb" - the selection starts at the beginning 401c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * of the first line and ends at the end of the letter "b". This means the selection 402c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * highlight will span from the beginning of the first line to the end of the first line 403c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * and will also cover the letter "b" on the second line. 404c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * 405c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * We expect four rectangles - one that will select the "a" on the first line, 406c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * one that will extend the selection from the "a" to the end of the first line the one 407c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * from the previous case that will prepare the selection for the second line and finally 408c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * one that will select the letter b. 409c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * 410c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * | a | *topToEndOfLineRectangle* | 411c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * || b | 412c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * c 413c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina */ 414c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 415c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(4, rectangles.size()); 416c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 417c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF topRectangle = rectangles.get(0); 418c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF topToEndOfLineRectangle = rectangles.get(1); 419c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF bottomRectangle = rectangles.get(2); 420c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF bottomLineStartRectangle = rectangles.get(3); 421c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 422c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(topRectangle.top == topToEndOfLineRectangle.top); 423c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(bottomLineStartRectangle.top == bottomRectangle.top); 424c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(bottomLineStartRectangle.bottom == bottomRectangle.bottom); 425c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(0, bottomLineStartRectangle.left, 0.0f); 426c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(0, bottomLineStartRectangle.right, 0.0f); 427c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(0, bottomRectangle.left, 0.0f); 428c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(bottomRectangle.right > 0); 429c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina } 430c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 431c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina @Test 432c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina public void testGetSelectionPathWithASingleLineSelection() { 433c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final Layout layout = new StaticLayout("abc", mTextPaint, Integer.MAX_VALUE, 434c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false); 435c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 436c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final List<RectF> rectangles = new ArrayList<>(); 437c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 438c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina layout.getSelection(0 /* startIndex */, 1 /* endIndex */, 439b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina (left, top, right, bottom, textSelectionLayout) -> rectangles.add( 440b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina new RectF(left, top, right, bottom))); 441c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 442c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina /* 443c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * In the single line selection case, we expect that only one rectangle covering the letter 444c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * "a" will be generated. Hence, we expect that the generated path will only consist of 445c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * that rectangle as well. 446c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * 447c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * | a | b c 448c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina * 449c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina */ 450c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 451c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(1, rectangles.size()); 452c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 453c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF rectangle = rectangles.get(0); 454c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 455c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final Path generatedPath = new Path(); 456c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina layout.getSelectionPath(0 /* startIndex */, 1 /* endIndex */, generatedPath); 457c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 458c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina final RectF pathRectangle = new RectF(); 459c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 460c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertTrue(generatedPath.isRect(pathRectangle)); 461c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina assertEquals(rectangle, pathRectangle); 462c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina } 463c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina 464c7f89450a6cea6ad70e69e21f56404c6dc36eaf1Petar Å egina @Test 465b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina public void testGetSelection_latinTextDirection() { 466b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina final Layout layout = new StaticLayout("abc", mTextPaint, Integer.MAX_VALUE, 467b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false); 468b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina 469b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina layout.getSelection(0 /* startIndex */, 2 /* endIndex */, 470b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina (left, top, right, bottom, textSelectionLayout) -> 4713a92fb632b6509610c5c3bf2a117631816a56899Petar Å egina assertEquals(Layout.TEXT_SELECTION_LAYOUT_LEFT_TO_RIGHT, 472b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina textSelectionLayout)); 473b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina } 474b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina 475b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina @Test 476b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina public void testGetSelection_arabicTextDirection() { 477b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina final Layout layout = new StaticLayout("غينيا", mTextPaint, Integer.MAX_VALUE, 478b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false); 479b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina 480b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina layout.getSelection(0 /* startIndex */, 2 /* endIndex */, 481b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina (left, top, right, bottom, textSelectionLayout) -> 4823a92fb632b6509610c5c3bf2a117631816a56899Petar Å egina assertEquals(Layout.TEXT_SELECTION_LAYOUT_RIGHT_TO_LEFT, 483b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina textSelectionLayout)); 484b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina } 485b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina 486b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina @Test 487b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina public void testGetSelection_mixedLatinAndArabicTextDirection() { 488b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina final Layout layout = new StaticLayout("abcغينيا", mTextPaint, Integer.MAX_VALUE, 489b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina Alignment.ALIGN_LEFT, mSpacingMult, mSpacingAdd, false); 490b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina 491b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina final List<Integer> layouts = new ArrayList<>(2); 492b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina 493b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina layout.getSelection(0 /* startIndex */, 6 /* endIndex */, 494b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina (left, top, right, bottom, textSelectionLayout) -> layouts.add( 495b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina textSelectionLayout)); 496b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina 497b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina assertEquals(2, layouts.size()); 4983a92fb632b6509610c5c3bf2a117631816a56899Petar Å egina assertEquals(Layout.TEXT_SELECTION_LAYOUT_LEFT_TO_RIGHT, (long) layouts.get(0)); 4993a92fb632b6509610c5c3bf2a117631816a56899Petar Å egina assertEquals(Layout.TEXT_SELECTION_LAYOUT_RIGHT_TO_LEFT, (long) layouts.get(1)); 500b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina } 501b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina 502b92c539232900537d5005bcf7cbc8950ff7f42d9Petar Å egina @Test 50302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testIsSpanned() { 50402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader MockLayout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 50502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 50602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader // default is not spanned text 50702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertFalse(layout.mockIsSpanned()); 50802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 50902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader // try to create a spanned text 51002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout = new MockLayout(mSpannedText, mTextPaint, mWidth, 51102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 51202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertTrue(layout.mockIsSpanned()); 51302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 51402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 51502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private static final class MockLayout extends Layout { 51602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader MockLayout(CharSequence text, TextPaint paint, int width, 51702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Alignment align, float spacingmult, float spacingadd) { 51802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader super(text, paint, width, align, spacingmult, spacingadd); 51902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 52002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 52102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader protected boolean mockIsSpanned() { 52202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return super.isSpanned(); 52302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 52402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 52502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 52602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getBottomPadding() { 52702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return 0; 52802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 52902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 53002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 53102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getEllipsisCount(int line) { 53202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return 0; 53302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 53402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 53502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 53602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getEllipsisStart(int line) { 53702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return 0; 53802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 53902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 54002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 54102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public boolean getLineContainsTab(int line) { 54202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return false; 54302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 54402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 54502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 54602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getLineCount() { 54702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return LINE_COUNT; 54802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 54902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 55002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 55102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getLineDescent(int line) { 55202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return LINE_DESCENT; 55302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 55402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 55502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 55602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public Directions getLineDirections(int line) { 55702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return Layout.DIRS_ALL_LEFT_TO_RIGHT; 55802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 55902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 56002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 56102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getLineStart(int line) { 56202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader if (line < 0) { 56302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return 0; 56402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 56502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return line; 56602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 56702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 56802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 56902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getLineTop(int line) { 57002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader if (line < 0) { 57102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return 0; 57202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 57302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return LINE_HEIGHT * (line); 57402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 57502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 57602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 57702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getParagraphDirection(int line) { 57802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return 0; 57902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 58002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 58102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 58202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public int getTopPadding() { 58302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return 0; 58402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 58502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 58602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 58702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 58802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetLineWidth() { 58902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 59002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 59102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader for (int i = 0; i < LINE_COUNT; i++) { 59202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader int start = layout.getLineStart(i); 59302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader int end = layout.getLineEnd(i); 59402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader String text = LAYOUT_TEXT.toString().substring(start, end); 59502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(mTextPaint.measureText(text), layout.getLineWidth(i), 1.0f); 59602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 59702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 59802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 59902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 60002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testGetCursorPath() { 60102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 60202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 60302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Path path = new Path(); 60402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader final float epsilon = 1.0f; 60502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader for (int i = 0; i < LINE_COUNT; i++) { 60602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout.getCursorPath(i, path, LAYOUT_TEXT); 60702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader RectF bounds = new RectF(); 60802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader path.computeBounds(bounds, false); 60902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertTrue(bounds.top >= layout.getLineTop(i) - epsilon); 61002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertTrue(bounds.bottom <= layout.getLineBottom(i) + epsilon); 61102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 61202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 61302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 61402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Test 61502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void testDraw() { 61602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Layout layout = new MockLayout(LAYOUT_TEXT, mTextPaint, mWidth, 61702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mAlign, mSpacingMult, mSpacingAdd); 61802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader final int width = 256; 61902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader final int height = 256; 62002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader MockCanvas c = new MockCanvas(width, height); 62102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader layout.draw(c); 62202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader List<MockCanvas.DrawCommand> drawCommands = c.getDrawCommands(); 62302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(LINE_COUNT, drawCommands.size()); 62402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader for (int i = 0; i < LINE_COUNT; i++) { 62502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader MockCanvas.DrawCommand drawCommand = drawCommands.get(i); 62602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader int start = layout.getLineStart(i); 62702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader int end = layout.getLineEnd(i); 62802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(LAYOUT_TEXT.toString().substring(start, end), drawCommand.text); 62902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader float expected_y = (i + 1) * LINE_HEIGHT - LINE_DESCENT; 63002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader assertEquals(expected_y, drawCommand.y, 0.0f); 63102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 63202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 63302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 63402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader private final class MockCanvas extends Canvas { 63502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 63602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader class DrawCommand { 63702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public final String text; 63802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public final float x; 63902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public final float y; 64002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 64102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader DrawCommand(String text, float x, float y) { 64202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader this.text = text; 64302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader this.x = x; 64402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader this.y = y; 64502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 64602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 64702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 64802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader List<DrawCommand> mDrawCommands; 64902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 65002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader MockCanvas(int width, int height) { 65102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader super(); 65202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mDrawCommands = new ArrayList<>(); 65302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 65402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader setBitmap(bitmap); 65502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 65602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 65702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader // Drawing text with either drawText or drawTextRun is valid; we don't care which. 65802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader // We also don't care which of the string representations is used. 65902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 66002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 66102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void drawText(String text, int start, int end, float x, float y, Paint p) { 66202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mDrawCommands.add(new DrawCommand(text.substring(start, end), x, y)); 66302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 66402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 66502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 66602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void drawText(CharSequence text, int start, int end, float x, float y, Paint p) { 66702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader drawText(text.toString(), start, end, x, y, p); 66802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 66902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 67002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 67102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void drawText(char[] text, int index, int count, float x, float y, Paint p) { 67202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader mDrawCommands.add(new DrawCommand(new String(text, index, count), x, y)); 67302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 67402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 67502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 67602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void drawTextRun(CharSequence text, int start, int end, int contextStart, 67702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader int contextEnd, float x, float y, boolean isRtl, Paint paint) { 67802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader drawText(text, start, end, x, y, paint); 67902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 68002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 68102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader @Override 68202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader public void drawTextRun(char[] text, int index, int count, int contextIndex, 68302f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader int contextCount, float x, float y, boolean isRtl, Paint paint) { 68402f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader drawText(text, index, count, x, y, paint); 68502f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 68602f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 68702f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader List<DrawCommand> getDrawCommands() { 68802f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader return mDrawCommands; 68902f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 69002f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader } 69102f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader} 69202f167c35ad81fce82c0ebc14a15892fb6981866Roozbeh Pournader 693