Home | History | Annotate | Download | only in cts
      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