1 /* 2 * Copyright (C) 2018 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.graphics.text.cts; 18 19 import static android.graphics.text.LineBreaker.BREAK_STRATEGY_BALANCED; 20 import static android.graphics.text.LineBreaker.BREAK_STRATEGY_HIGH_QUALITY; 21 import static android.graphics.text.LineBreaker.BREAK_STRATEGY_SIMPLE; 22 import static android.graphics.text.LineBreaker.HYPHENATION_FREQUENCY_FULL; 23 import static android.graphics.text.LineBreaker.HYPHENATION_FREQUENCY_NONE; 24 import static android.graphics.text.LineBreaker.HYPHENATION_FREQUENCY_NORMAL; 25 import static android.graphics.text.LineBreaker.JUSTIFICATION_MODE_INTER_WORD; 26 import static android.graphics.text.LineBreaker.JUSTIFICATION_MODE_NONE; 27 import static android.graphics.text.LineBreaker.ParagraphConstraints; 28 import static android.graphics.text.LineBreaker.Result; 29 30 import static org.junit.Assert.assertEquals; 31 import static org.junit.Assert.assertFalse; 32 import static org.junit.Assert.assertNotNull; 33 import static org.junit.Assert.assertNull; 34 import static org.junit.Assert.assertTrue; 35 36 import android.content.Context; 37 import android.content.res.AssetManager; 38 import android.graphics.Paint; 39 import android.graphics.Typeface; 40 import android.graphics.text.LineBreaker; 41 import android.graphics.text.MeasuredText; 42 43 import androidx.test.InstrumentationRegistry; 44 import androidx.test.filters.SmallTest; 45 import androidx.test.runner.AndroidJUnit4; 46 47 import org.junit.BeforeClass; 48 import org.junit.Test; 49 import org.junit.runner.RunWith; 50 51 @SmallTest 52 @RunWith(AndroidJUnit4.class) 53 public class LineBreakerTest { 54 private static final String TAG = "LineBreakerTest"; 55 56 private static Paint sPaint; 57 @BeforeClass 58 public static void classSetUp() { 59 sPaint = new Paint(); 60 Context context = InstrumentationRegistry.getTargetContext(); 61 AssetManager am = context.getAssets(); 62 Typeface tf = new Typeface.Builder(am, "fonts/layout/linebreak.ttf").build(); 63 sPaint.setTypeface(tf); 64 sPaint.setTextSize(10.0f); // Make 1em = 10px 65 } 66 67 @Test 68 public void testLineBreak_construct() { 69 assertNotNull(new LineBreaker.Builder().build()); 70 } 71 72 @Test 73 public void testSetBreakStrategy_shoulNotThrowExceptions() { 74 assertNotNull(new LineBreaker.Builder().setBreakStrategy(BREAK_STRATEGY_SIMPLE).build()); 75 assertNotNull(new LineBreaker.Builder().setBreakStrategy(BREAK_STRATEGY_HIGH_QUALITY) 76 .build()); 77 assertNotNull(new LineBreaker.Builder().setBreakStrategy(BREAK_STRATEGY_BALANCED).build()); 78 } 79 80 @Test 81 public void testSetHyphenationFrequency_shouldNotThrowExceptions() { 82 assertNotNull(new LineBreaker.Builder() 83 .setHyphenationFrequency(HYPHENATION_FREQUENCY_NORMAL).build()); 84 assertNotNull(new LineBreaker.Builder() 85 .setHyphenationFrequency(HYPHENATION_FREQUENCY_FULL).build()); 86 assertNotNull(new LineBreaker.Builder() 87 .setHyphenationFrequency(HYPHENATION_FREQUENCY_NONE).build()); 88 } 89 90 @Test 91 public void testSetJustification_shouldNotThrowExceptions() { 92 assertNotNull(new LineBreaker.Builder() 93 .setJustificationMode(JUSTIFICATION_MODE_NONE).build()); 94 assertNotNull(new LineBreaker.Builder() 95 .setJustificationMode(JUSTIFICATION_MODE_INTER_WORD).build()); 96 } 97 98 @Test 99 public void testSetIntent_shouldNotThrowExceptions() { 100 assertNotNull(new LineBreaker.Builder().setIndents(null).build()); 101 assertNotNull(new LineBreaker.Builder().setIndents(new int[] {}).build()); 102 assertNotNull(new LineBreaker.Builder().setIndents(new int[] { 100 }).build()); 103 } 104 105 @Test 106 public void testSetGetWidth() { 107 ParagraphConstraints c = new ParagraphConstraints(); 108 assertEquals(0, c.getWidth(), 0.0f); // 0 by default 109 c.setWidth(100); 110 assertEquals(100, c.getWidth(), 0.0f); 111 c.setWidth(200); 112 assertEquals(200, c.getWidth(), 0.0f); 113 } 114 115 @Test 116 public void testSetGetIndent() { 117 ParagraphConstraints c = new ParagraphConstraints(); 118 assertEquals(0.0f, c.getFirstWidth(), 0.0f); // 0 by default 119 assertEquals(0, c.getFirstWidthLineCount()); // 0 by default 120 c.setIndent(100.0f, 1); 121 assertEquals(100.0f, c.getFirstWidth(), 0.0f); 122 assertEquals(1, c.getFirstWidthLineCount()); 123 c.setIndent(200.0f, 5); 124 assertEquals(200.0f, c.getFirstWidth(), 0.0f); 125 assertEquals(5, c.getFirstWidthLineCount()); 126 } 127 128 @Test 129 public void testSetGetTabStops() { 130 ParagraphConstraints c = new ParagraphConstraints(); 131 assertNull(c.getTabStops()); // null by default 132 assertEquals(0, c.getDefaultTabStop(), 0.0); // 0 by default 133 c.setTabStops(new float[] { 120 }, 240); 134 assertEquals(1, c.getTabStops().length); 135 assertEquals(120, c.getTabStops()[0], 0.0); 136 assertEquals(240, c.getDefaultTabStop(), 0.0); 137 } 138 139 @Test 140 public void testLineBreak_Simple() { 141 final String text = "Hello, World."; 142 final LineBreaker lb = new LineBreaker.Builder() 143 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 144 .build(); 145 final ParagraphConstraints c = new ParagraphConstraints(); 146 c.setWidth(Float.MAX_VALUE); 147 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 148 .appendStyleRun(sPaint, text.length(), false).build(), c, 0); 149 assertEquals(1, r.getLineCount()); 150 assertEquals(13, r.getLineBreakOffset(0)); 151 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 152 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 153 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 154 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 155 assertFalse(r.hasLineTab(0)); 156 assertEquals(130.0f, r.getLineWidth(0), 0.0f); 157 } 158 159 @Test 160 public void testLineBreak_Simple2() { 161 // The visual line break output is like 162 // |abc defg| 163 // |hijkl | 164 final String text = "abc defg hijkl"; 165 final LineBreaker lb = new LineBreaker.Builder() 166 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 167 .build(); 168 final ParagraphConstraints c = new ParagraphConstraints(); 169 c.setWidth(80.0f); 170 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 171 .appendStyleRun(sPaint, text.length(), false).build(), c, 0); 172 assertEquals(2, r.getLineCount()); 173 assertEquals(9, r.getLineBreakOffset(0)); 174 assertEquals(14, r.getLineBreakOffset(1)); 175 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 176 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 177 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 178 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 179 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 180 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 181 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 182 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 183 assertFalse(r.hasLineTab(0)); 184 assertFalse(r.hasLineTab(1)); 185 assertEquals(80.0f, r.getLineWidth(0), 0.0f); 186 assertEquals(50.0f, r.getLineWidth(1), 0.0f); 187 } 188 189 @Test 190 public void testLineBreak_Simple3() { 191 // The visual line break output is like 192 // |abc | 193 // |defg| 194 // |hijk| 195 // |l | 196 final String text = "abc defg hijkl"; 197 final LineBreaker lb = new LineBreaker.Builder() 198 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 199 .build(); 200 final ParagraphConstraints c = new ParagraphConstraints(); 201 c.setWidth(40.0f); 202 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 203 .appendStyleRun(sPaint, text.length(), false).build(), c, 0); 204 assertEquals(4, r.getLineCount()); 205 assertEquals(4, r.getLineBreakOffset(0)); 206 assertEquals(9, r.getLineBreakOffset(1)); 207 assertEquals(13, r.getLineBreakOffset(2)); 208 assertEquals(14, r.getLineBreakOffset(3)); 209 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 210 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 211 assertEquals(-10.0f, r.getLineAscent(2), 0.0f); 212 assertEquals(-10.0f, r.getLineAscent(3), 0.0f); 213 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 214 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 215 assertEquals(2.0f, r.getLineDescent(2), 0.0f); 216 assertEquals(2.0f, r.getLineDescent(3), 0.0f); 217 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 218 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 219 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 220 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 221 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(2)); 222 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(2)); 223 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(3)); 224 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(3)); 225 assertFalse(r.hasLineTab(0)); 226 assertFalse(r.hasLineTab(1)); 227 assertFalse(r.hasLineTab(2)); 228 assertFalse(r.hasLineTab(3)); 229 assertEquals(30.0f, r.getLineWidth(0), 0.0f); 230 assertEquals(40.0f, r.getLineWidth(1), 0.0f); 231 assertEquals(40.0f, r.getLineWidth(2), 0.0f); 232 assertEquals(10.0f, r.getLineWidth(3), 0.0f); 233 } 234 235 @Test 236 public void testLineBreak_Simple_NotRectangle() { 237 // The visual line break output is like 238 // |abc | 239 // |defg hijkl| 240 final String text = "abc defg hijkl"; 241 final LineBreaker lb = new LineBreaker.Builder() 242 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 243 .build(); 244 final ParagraphConstraints c = new ParagraphConstraints(); 245 c.setWidth(100.0f); 246 c.setIndent(50.0f, 1); // Make the first line width 50 px. 247 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 248 .appendStyleRun(sPaint, text.length(), false).build(), c, 0); 249 assertEquals(2, r.getLineCount()); 250 assertEquals(4, r.getLineBreakOffset(0)); 251 assertEquals(14, r.getLineBreakOffset(1)); 252 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 253 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 254 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 255 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 256 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 257 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 258 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 259 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 260 assertFalse(r.hasLineTab(0)); 261 assertFalse(r.hasLineTab(1)); 262 assertEquals(30.0f, r.getLineWidth(0), 0.0f); 263 assertEquals(100.0f, r.getLineWidth(1), 0.0f); 264 } 265 266 @Test 267 public void testLineBreak_Simple_Hyphenation() { 268 // The visual line break output is like 269 // |abc | 270 // |defg| 271 // |hi- | 272 // |jkl | 273 final String text = "ab\u00ADc de\u00ADfg hi\u00ADjkl"; 274 final LineBreaker lb = new LineBreaker.Builder() 275 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 276 .setHyphenationFrequency(HYPHENATION_FREQUENCY_NORMAL) 277 .build(); 278 final ParagraphConstraints c = new ParagraphConstraints(); 279 c.setWidth(40.0f); 280 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 281 .appendStyleRun(sPaint, text.length(), false).build(), c, 0); 282 assertEquals(4, r.getLineCount()); 283 assertEquals(5, r.getLineBreakOffset(0)); 284 assertEquals(11, r.getLineBreakOffset(1)); 285 assertEquals(14, r.getLineBreakOffset(2)); 286 assertEquals(17, r.getLineBreakOffset(3)); 287 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 288 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 289 assertEquals(-10.0f, r.getLineAscent(2), 0.0f); 290 assertEquals(-10.0f, r.getLineAscent(3), 0.0f); 291 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 292 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 293 assertEquals(2.0f, r.getLineDescent(2), 0.0f); 294 assertEquals(2.0f, r.getLineDescent(3), 0.0f); 295 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 296 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 297 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 298 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 299 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(2)); 300 assertEquals(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN, r.getEndLineHyphenEdit(2)); 301 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(3)); 302 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(3)); 303 assertFalse(r.hasLineTab(0)); 304 assertFalse(r.hasLineTab(1)); 305 assertFalse(r.hasLineTab(2)); 306 assertFalse(r.hasLineTab(3)); 307 assertEquals(30.0f, r.getLineWidth(0), 0.0f); 308 assertEquals(40.0f, r.getLineWidth(1), 0.0f); 309 assertEquals(30.0f, r.getLineWidth(2), 0.0f); 310 assertEquals(30.0f, r.getLineWidth(3), 0.0f); 311 } 312 313 @Test 314 public void testLineBreak_Simple_Styled() { 315 // The visual line break output is like 316 // |abc | 317 // |ddeeffgg | (Make text size of "defg" doubled) 318 // |hijkl | 319 final String text = "abc defg hijkl"; 320 final LineBreaker lb = new LineBreaker.Builder() 321 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 322 .build(); 323 final ParagraphConstraints c = new ParagraphConstraints(); 324 c.setWidth(90.0f); 325 final Paint biggerPaint = new Paint(sPaint); 326 biggerPaint.setTextSize(sPaint.getTextSize() * 2.0f); 327 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 328 .appendStyleRun(sPaint, 4, false) 329 .appendStyleRun(biggerPaint, 5, false) 330 .appendStyleRun(sPaint, 5, false).build(), c, 0); 331 assertEquals(3, r.getLineCount()); 332 assertEquals(4, r.getLineBreakOffset(0)); 333 assertEquals(9, r.getLineBreakOffset(1)); 334 assertEquals(14, r.getLineBreakOffset(2)); 335 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 336 assertEquals(-20.0f, r.getLineAscent(1), 0.0f); 337 assertEquals(-10.0f, r.getLineAscent(2), 0.0f); 338 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 339 assertEquals(4.0f, r.getLineDescent(1), 0.0f); 340 assertEquals(2.0f, r.getLineDescent(2), 0.0f); 341 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 342 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 343 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 344 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 345 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(2)); 346 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(2)); 347 assertFalse(r.hasLineTab(0)); 348 assertFalse(r.hasLineTab(1)); 349 assertFalse(r.hasLineTab(2)); 350 assertEquals(30.0f, r.getLineWidth(0), 0.0f); 351 assertEquals(80.0f, r.getLineWidth(1), 0.0f); 352 assertEquals(50.0f, r.getLineWidth(2), 0.0f); 353 } 354 355 @Test 356 public void testLineBreak_Simple_Styled2() { 357 // The visual line break output is like 358 // |abc deffg| (Make text size of "f" doubled) 359 // |hijkl | 360 final String text = "abc defg hijkl"; 361 final LineBreaker lb = new LineBreaker.Builder() 362 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 363 .build(); 364 final ParagraphConstraints c = new ParagraphConstraints(); 365 c.setWidth(90.0f); 366 final Paint biggerPaint = new Paint(sPaint); 367 biggerPaint.setTextSize(sPaint.getTextSize() * 2.0f); 368 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 369 .appendStyleRun(sPaint, 6, false) 370 .appendStyleRun(biggerPaint, 1, false) 371 .appendStyleRun(sPaint, 7, false) 372 .build(), c, 0); 373 assertEquals(2, r.getLineCount()); 374 assertEquals(9, r.getLineBreakOffset(0)); 375 assertEquals(14, r.getLineBreakOffset(1)); 376 assertEquals(-20.0f, r.getLineAscent(0), 0.0f); 377 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 378 assertEquals(4.0f, r.getLineDescent(0), 0.0f); 379 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 380 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 381 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 382 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 383 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 384 assertFalse(r.hasLineTab(0)); 385 assertFalse(r.hasLineTab(1)); 386 assertEquals(90.0f, r.getLineWidth(0), 0.0f); 387 assertEquals(50.0f, r.getLineWidth(1), 0.0f); 388 } 389 390 @Test 391 public void testLineBreak_Simple_indents() { 392 // The visual line break output is like 393 // |abc | 394 // |defg hijkl| 395 final String text = "abc defg hijkl"; 396 final LineBreaker lb = new LineBreaker.Builder() 397 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 398 .setIndents(new int[] { 50, 0 }) // The first line indent is 50 and 0 for others. 399 .build(); 400 final ParagraphConstraints c = new ParagraphConstraints(); 401 c.setWidth(100.0f); 402 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 403 .appendStyleRun(sPaint, text.length(), false) 404 .build(), c, 0); 405 assertEquals(2, r.getLineCount()); 406 assertEquals(4, r.getLineBreakOffset(0)); 407 assertEquals(14, r.getLineBreakOffset(1)); 408 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 409 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 410 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 411 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 412 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 413 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 414 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 415 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 416 assertFalse(r.hasLineTab(0)); 417 assertFalse(r.hasLineTab(1)); 418 assertEquals(30.0f, r.getLineWidth(0), 0.0f); 419 assertEquals(100.0f, r.getLineWidth(1), 0.0f); 420 } 421 422 @Test 423 public void testLineBreak_Simple_indents2() { 424 // The visual line break output is like 425 // |abc | 426 // |defg| 427 // |hijkl | 428 final String text = "abc defg hijkl"; 429 final LineBreaker lb = new LineBreaker.Builder() 430 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 431 .setIndents(new int[] { 60, 60, 0 }) 432 .build(); 433 final ParagraphConstraints c = new ParagraphConstraints(); 434 c.setWidth(100.0f); 435 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 436 .appendStyleRun(sPaint, text.length(), false) 437 .build(), c, 0); 438 assertEquals(3, r.getLineCount()); 439 assertEquals(4, r.getLineBreakOffset(0)); 440 assertEquals(9, r.getLineBreakOffset(1)); 441 assertEquals(14, r.getLineBreakOffset(2)); 442 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 443 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 444 assertEquals(-10.0f, r.getLineAscent(2), 0.0f); 445 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 446 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 447 assertEquals(2.0f, r.getLineDescent(2), 0.0f); 448 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 449 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 450 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 451 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 452 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(2)); 453 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(2)); 454 assertFalse(r.hasLineTab(0)); 455 assertFalse(r.hasLineTab(1)); 456 assertFalse(r.hasLineTab(2)); 457 assertEquals(30.0f, r.getLineWidth(0), 0.0f); 458 assertEquals(40.0f, r.getLineWidth(1), 0.0f); 459 assertEquals(50.0f, r.getLineWidth(2), 0.0f); 460 } 461 462 @Test 463 public void testLineBreak_Simple_tabStop() { 464 // The visual line break output is like 465 // |abc | 466 // |de fg | 467 // |hijkl | 468 final String text = "abc de\tfg hijkl"; 469 final LineBreaker lb = new LineBreaker.Builder() 470 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 471 .build(); 472 final ParagraphConstraints c = new ParagraphConstraints(); 473 c.setWidth(70.0f); 474 c.setTabStops(null, 40); 475 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 476 .appendStyleRun(sPaint, text.length(), false) 477 .build(), c, 0); 478 assertEquals(3, r.getLineCount()); 479 assertEquals(4, r.getLineBreakOffset(0)); 480 assertEquals(10, r.getLineBreakOffset(1)); 481 assertEquals(15, r.getLineBreakOffset(2)); 482 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 483 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 484 assertEquals(-10.0f, r.getLineAscent(2), 0.0f); 485 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 486 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 487 assertEquals(2.0f, r.getLineDescent(2), 0.0f); 488 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 489 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 490 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 491 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 492 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(2)); 493 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(2)); 494 assertFalse(r.hasLineTab(0)); 495 assertTrue(r.hasLineTab(1)); 496 assertFalse(r.hasLineTab(2)); 497 assertEquals(30.0f, r.getLineWidth(0), 0.0f); 498 assertEquals(60.0f, r.getLineWidth(1), 0.0f); 499 assertEquals(50.0f, r.getLineWidth(2), 0.0f); 500 } 501 502 @Test 503 public void testLineBreak_Simple_tabStop2() { 504 // The visual line break output is like 505 // |a b c | 506 // |defg | 507 // |hijkl | 508 final String text = "a\tb\tc defg hijkl"; 509 final LineBreaker lb = new LineBreaker.Builder() 510 .setBreakStrategy(BREAK_STRATEGY_SIMPLE) 511 .build(); 512 final ParagraphConstraints c = new ParagraphConstraints(); 513 c.setWidth(70.0f); 514 c.setTabStops(new float[] { 20 }, 50); 515 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 516 .appendStyleRun(sPaint, text.length(), false) 517 .build(), c, 0); 518 assertEquals(3, r.getLineCount()); 519 assertEquals(6, r.getLineBreakOffset(0)); 520 assertEquals(11, r.getLineBreakOffset(1)); 521 assertEquals(16, r.getLineBreakOffset(2)); 522 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 523 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 524 assertEquals(-10.0f, r.getLineAscent(2), 0.0f); 525 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 526 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 527 assertEquals(2.0f, r.getLineDescent(2), 0.0f); 528 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 529 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 530 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 531 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 532 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(2)); 533 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(2)); 534 assertTrue(r.hasLineTab(0)); 535 assertFalse(r.hasLineTab(1)); 536 assertFalse(r.hasLineTab(2)); 537 assertEquals(60.0f, r.getLineWidth(0), 0.0f); 538 assertEquals(40.0f, r.getLineWidth(1), 0.0f); 539 assertEquals(50.0f, r.getLineWidth(2), 0.0f); 540 } 541 542 @Test 543 public void testLineBreak_Balanced() { 544 // The visual BALANCED line break output is like 545 // |This | 546 // |is an | 547 // |example| 548 // 549 // FYI, SIMPLE line breaker breaks this string to 550 // |This is| 551 // |an | 552 // |example| 553 final String text = "This is an example"; 554 final LineBreaker lb = new LineBreaker.Builder() 555 .setBreakStrategy(BREAK_STRATEGY_BALANCED) 556 .build(); 557 final ParagraphConstraints c = new ParagraphConstraints(); 558 c.setWidth(70.0f); 559 final Result r = lb.computeLineBreaks(new MeasuredText.Builder(text.toCharArray()) 560 .appendStyleRun(sPaint, text.length(), false) 561 .build(), c, 0); 562 assertEquals(3, r.getLineCount()); 563 assertEquals(5, r.getLineBreakOffset(0)); 564 assertEquals(11, r.getLineBreakOffset(1)); 565 assertEquals(18, r.getLineBreakOffset(2)); 566 assertEquals(-10.0f, r.getLineAscent(0), 0.0f); 567 assertEquals(-10.0f, r.getLineAscent(1), 0.0f); 568 assertEquals(-10.0f, r.getLineAscent(2), 0.0f); 569 assertEquals(2.0f, r.getLineDescent(0), 0.0f); 570 assertEquals(2.0f, r.getLineDescent(1), 0.0f); 571 assertEquals(2.0f, r.getLineDescent(2), 0.0f); 572 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(0)); 573 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(0)); 574 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(1)); 575 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(1)); 576 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, r.getStartLineHyphenEdit(2)); 577 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, r.getEndLineHyphenEdit(2)); 578 assertFalse(r.hasLineTab(0)); 579 assertFalse(r.hasLineTab(1)); 580 assertFalse(r.hasLineTab(2)); 581 assertEquals(40.0f, r.getLineWidth(0), 0.0f); 582 assertEquals(50.0f, r.getLineWidth(1), 0.0f); 583 assertEquals(70.0f, r.getLineWidth(2), 0.0f); 584 } 585 } 586