1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.text.cts; 18 19 import static com.android.compatibility.common.util.WidgetTestUtils.sameCharSequence; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertNotEquals; 24 import static org.junit.Assert.assertNotNull; 25 import static org.junit.Assert.assertNull; 26 import static org.junit.Assert.assertSame; 27 import static org.junit.Assert.assertTrue; 28 import static org.mockito.Matchers.any; 29 import static org.mockito.Matchers.anyFloat; 30 import static org.mockito.Matchers.anyInt; 31 import static org.mockito.Matchers.eq; 32 import static org.mockito.Mockito.reset; 33 import static org.mockito.Mockito.spy; 34 import static org.mockito.Mockito.times; 35 import static org.mockito.Mockito.verify; 36 37 import android.graphics.Bitmap; 38 import android.graphics.Bitmap.Config; 39 import android.graphics.Canvas; 40 import android.graphics.Paint; 41 import android.os.LocaleList; 42 import android.text.BoringLayout; 43 import android.text.BoringLayout.Metrics; 44 import android.text.Layout; 45 import android.text.Layout.Alignment; 46 import android.text.PrecomputedText; 47 import android.text.TextDirectionHeuristic; 48 import android.text.TextDirectionHeuristics; 49 import android.text.TextPaint; 50 import android.text.TextUtils; 51 52 import androidx.test.filters.SmallTest; 53 import androidx.test.runner.AndroidJUnit4; 54 55 import org.junit.Before; 56 import org.junit.Test; 57 import org.junit.runner.RunWith; 58 59 @SmallTest 60 @RunWith(AndroidJUnit4.class) 61 public class BoringLayoutTest { 62 private static final float SPACING_MULT_NO_SCALE = 1.0f; 63 private static final float SPACING_ADD_NO_SCALE = 0.0f; 64 private static final int DEFAULT_OUTER_WIDTH = 100; 65 private static final int METRICS_TOP = 10; 66 private static final int METRICS_ASCENT = 20; 67 private static final int METRICS_DESCENT = 40; 68 private static final int METRICS_BOTTOM = 50; 69 private static final int METRICS_WIDTH = 50; 70 private static final int METRICS_LEADING = 50; 71 72 private static final CharSequence DEFAULT_CHAR_SEQUENCE = "default"; 73 private static final TextPaint DEFAULT_PAINT = new TextPaint(); 74 private static final Layout.Alignment DEFAULT_ALIGN = Layout.Alignment.ALIGN_CENTER; 75 private static final Metrics DEFAULT_METRICS = createMetrics( 76 METRICS_TOP, 77 METRICS_ASCENT, 78 METRICS_DESCENT, 79 METRICS_BOTTOM, 80 METRICS_WIDTH, 81 METRICS_LEADING); 82 83 private BoringLayout mBoringLayout; 84 85 @Before setup()86 public void setup() { 87 mBoringLayout = makeDefaultBoringLayout(); 88 } 89 90 @Test testConstructors()91 public void testConstructors() { 92 new BoringLayout(DEFAULT_CHAR_SEQUENCE, 93 DEFAULT_PAINT, 94 DEFAULT_OUTER_WIDTH, 95 DEFAULT_ALIGN, 96 SPACING_MULT_NO_SCALE, 97 SPACING_ADD_NO_SCALE, 98 DEFAULT_METRICS, 99 true); 100 101 new BoringLayout(DEFAULT_CHAR_SEQUENCE, 102 DEFAULT_PAINT, 103 DEFAULT_OUTER_WIDTH, 104 DEFAULT_ALIGN, 105 SPACING_MULT_NO_SCALE, 106 SPACING_ADD_NO_SCALE, 107 DEFAULT_METRICS, 108 true, 109 TextUtils.TruncateAt.START, 110 DEFAULT_OUTER_WIDTH); 111 } 112 verifyMultAddScale(float spacingMult, float spacingAdd)113 private void verifyMultAddScale(float spacingMult, float spacingAdd) { 114 final int height = METRICS_BOTTOM - METRICS_TOP; 115 116 BoringLayout boringLayout = makeBoringLayout(spacingMult, spacingAdd); 117 assertEquals(height, boringLayout.getHeight()); 118 assertEquals(height + METRICS_TOP, boringLayout.getLineDescent(0)); 119 } 120 121 @Test testScale()122 public void testScale() { 123 // no scale 124 verifyMultAddScale(1.0f, 0.0f); 125 126 // test line spacing multiplier 127 verifyMultAddScale(2.0f, 0.0f); 128 verifyMultAddScale(0.5f, 0.0f); 129 130 // test line spacing add 131 verifyMultAddScale(1.0f, 1.5f); 132 verifyMultAddScale(1.0f, -1.6f); 133 verifyMultAddScale(1.0f, 1.4f); 134 verifyMultAddScale(1.0f, -1.4f); 135 verifyMultAddScale(1.0f, 3.0f); 136 verifyMultAddScale(1.0f, -3.0f); 137 } 138 139 @Test testPreconditions()140 public void testPreconditions() { 141 assertEquals(1, mBoringLayout.getLineCount()); 142 assertEquals(0, mBoringLayout.getLineTop(0)); 143 assertEquals(mBoringLayout.getHeight(), mBoringLayout.getLineTop(1)); 144 assertEquals(mBoringLayout.getHeight(), mBoringLayout.getLineTop(10)); 145 assertEquals(0, mBoringLayout.getLineStart(0)); 146 assertEquals(DEFAULT_CHAR_SEQUENCE.length(), mBoringLayout.getLineStart(1)); 147 assertEquals(DEFAULT_CHAR_SEQUENCE.length(), mBoringLayout.getLineStart(10)); 148 assertEquals(Layout.DIR_LEFT_TO_RIGHT, mBoringLayout.getParagraphDirection(0)); 149 assertFalse(mBoringLayout.getLineContainsTab(0)); 150 assertEquals((float) METRICS_WIDTH, mBoringLayout.getLineMax(0), 0.0f); 151 assertEquals(Layout.DIR_LEFT_TO_RIGHT, mBoringLayout.getParagraphDirection(0)); 152 assertEquals(0, mBoringLayout.getEllipsisCount(0)); 153 mBoringLayout.ellipsized(0, 1); 154 assertEquals(1, mBoringLayout.getEllipsisCount(0)); 155 mBoringLayout.ellipsized(1, 2); 156 assertEquals(1, mBoringLayout.getEllipsisStart(0)); 157 } 158 159 @Test testReplaceOrMake()160 public void testReplaceOrMake() { 161 String source = "This is a SpannableString."; 162 BoringLayout layout_1 = mBoringLayout.replaceOrMake( 163 source, 164 DEFAULT_PAINT, 165 DEFAULT_OUTER_WIDTH, 166 DEFAULT_ALIGN, 167 SPACING_MULT_NO_SCALE, 168 SPACING_ADD_NO_SCALE, 169 DEFAULT_METRICS, 170 true); 171 assertSame(mBoringLayout, layout_1); 172 173 layout_1 = mBoringLayout.replaceOrMake( 174 source, 175 DEFAULT_PAINT, 176 DEFAULT_OUTER_WIDTH, 177 DEFAULT_ALIGN, 178 SPACING_MULT_NO_SCALE, 179 SPACING_ADD_NO_SCALE, 180 DEFAULT_METRICS, 181 true, 182 TextUtils.TruncateAt.START, 183 100); 184 assertSame(mBoringLayout, layout_1); 185 assertEquals(100, mBoringLayout.getEllipsizedWidth()); 186 } 187 188 189 @Test testAlignment()190 public void testAlignment() { 191 BoringLayout boringLayout = makeBoringLayoutAlign(Layout.Alignment.ALIGN_NORMAL); 192 assertEquals(0.0f, boringLayout.getLineLeft(0), 0.0f); 193 assertEquals((float) DEFAULT_METRICS.width, boringLayout.getLineRight(0), 0.0f); 194 195 boringLayout = makeBoringLayoutAlign(Layout.Alignment.ALIGN_CENTER); 196 int expectedWidth = DEFAULT_OUTER_WIDTH - METRICS_WIDTH; 197 assertEquals((float) expectedWidth / 2, boringLayout.getLineLeft(0), 0.0f); 198 expectedWidth = DEFAULT_OUTER_WIDTH + METRICS_WIDTH; 199 assertEquals((float) expectedWidth / 2, boringLayout.getLineRight(0), 0.0f); 200 201 boringLayout = makeBoringLayoutAlign(Layout.Alignment.ALIGN_OPPOSITE); 202 expectedWidth = DEFAULT_OUTER_WIDTH - METRICS_WIDTH; 203 assertEquals((float) expectedWidth, boringLayout.getLineLeft(0), 0.0f); 204 assertEquals((float) DEFAULT_OUTER_WIDTH, boringLayout.getLineRight(0), 0.0f); 205 } 206 207 @Test testGetLineDescent_withIncludePadding()208 public void testGetLineDescent_withIncludePadding() { 209 final int height = METRICS_BOTTOM - METRICS_TOP; 210 assertEquals(height + METRICS_TOP, mBoringLayout.getLineDescent(0)); 211 } 212 213 @Test testGetLineDescent_withoutIncludePadding()214 public void testGetLineDescent_withoutIncludePadding() { 215 BoringLayout boringLayout = new BoringLayout( 216 DEFAULT_CHAR_SEQUENCE, 217 DEFAULT_PAINT, 218 DEFAULT_OUTER_WIDTH, 219 DEFAULT_ALIGN, 220 SPACING_MULT_NO_SCALE, 221 SPACING_ADD_NO_SCALE, 222 DEFAULT_METRICS, 223 false); 224 225 final int height = METRICS_DESCENT - METRICS_ASCENT; 226 assertEquals(height + METRICS_ASCENT, boringLayout.getLineDescent(0)); 227 } 228 229 @Test testIncludePadding()230 public void testIncludePadding() { 231 assertEquals(METRICS_TOP - METRICS_ASCENT, mBoringLayout.getTopPadding()); 232 assertEquals(METRICS_BOTTOM - METRICS_DESCENT, mBoringLayout.getBottomPadding()); 233 assertEquals(METRICS_BOTTOM - METRICS_TOP, mBoringLayout.getHeight()); 234 235 BoringLayout boringLayout = new BoringLayout( 236 DEFAULT_CHAR_SEQUENCE, 237 DEFAULT_PAINT, 238 DEFAULT_OUTER_WIDTH, 239 DEFAULT_ALIGN, 240 SPACING_MULT_NO_SCALE, 241 SPACING_ADD_NO_SCALE, 242 DEFAULT_METRICS, 243 false); 244 245 assertEquals(0, boringLayout.getTopPadding()); 246 assertEquals(0, boringLayout.getBottomPadding()); 247 assertEquals(METRICS_DESCENT - METRICS_ASCENT, boringLayout.getHeight()); 248 } 249 250 @Test testIsBoringString()251 public void testIsBoringString() { 252 TextPaint paint = new TextPaint(); 253 assertNotNull(BoringLayout.isBoring("hello android", paint)); 254 255 Metrics metrics = new Metrics(); 256 metrics.width = 100; 257 assertNotNull(BoringLayout.isBoring("hello android", paint, metrics)); 258 259 assertNull(BoringLayout.isBoring("\u0590 \u0591", paint)); 260 assertNull(BoringLayout.isBoring("hello \t android", paint)); 261 assertNull(BoringLayout.isBoring("hello \n android", paint)); 262 assertNull(BoringLayout.isBoring("hello \n\n\n android", paint)); 263 assertNull(BoringLayout.isBoring("\nhello \n android\n", paint)); 264 assertNull(BoringLayout.isBoring("hello android\n\n\n", paint)); 265 } 266 267 @Test testIsBoringForEmptyString()268 public void testIsBoringForEmptyString() { 269 Metrics metrics = new Metrics(); 270 assertNotNull(BoringLayout.isBoring("", new TextPaint(), metrics)); 271 272 // The default font Roboto has non-zero ascent/descent values. If metrics returns zeros, it 273 // means failed to retrieve the font metrics. 274 assertNotEquals(0, metrics.ascent); 275 assertNotEquals(0, metrics.descent); 276 } 277 278 @Test testIsBoring_resetsFontMetrics()279 public void testIsBoring_resetsFontMetrics() { 280 int someInt = 100; 281 String text = "some text"; 282 283 TextPaint paint = new TextPaint(); 284 Paint.FontMetricsInt paintMetrics = paint.getFontMetricsInt(); 285 Metrics changedMetrics = new Metrics(); 286 changedMetrics.top = paintMetrics.top - someInt; 287 changedMetrics.ascent = paintMetrics.ascent - someInt; 288 changedMetrics.bottom = paintMetrics.bottom + someInt; 289 changedMetrics.descent = paintMetrics.descent + someInt; 290 changedMetrics.leading = paintMetrics.leading + someInt; 291 292 Metrics expectedMetrics = BoringLayout.isBoring(text, paint, (Metrics) null); 293 Metrics actualMetrics = BoringLayout.isBoring(text, paint, changedMetrics); 294 295 assertNotNull(actualMetrics); 296 assertNotNull(expectedMetrics); 297 assertEquals(expectedMetrics.top, actualMetrics.top); 298 assertEquals(expectedMetrics.ascent, actualMetrics.ascent); 299 assertEquals(expectedMetrics.bottom, actualMetrics.bottom); 300 assertEquals(expectedMetrics.descent, actualMetrics.descent); 301 assertEquals(expectedMetrics.leading, actualMetrics.leading); 302 } 303 304 @Test testGetLineDirections()305 public void testGetLineDirections() { 306 assertNotNull(mBoringLayout.getLineDirections(0)); 307 assertNotNull(mBoringLayout.getLineDirections(2)); 308 } 309 310 @Test testMake()311 public void testMake() { 312 BoringLayout boringLayout = BoringLayout.make(DEFAULT_CHAR_SEQUENCE, 313 DEFAULT_PAINT, 314 DEFAULT_OUTER_WIDTH, 315 DEFAULT_ALIGN, 316 SPACING_MULT_NO_SCALE, 317 SPACING_ADD_NO_SCALE, 318 DEFAULT_METRICS, 319 true); 320 assertNotNull(boringLayout); 321 322 boringLayout = BoringLayout.make(DEFAULT_CHAR_SEQUENCE, 323 DEFAULT_PAINT, 324 DEFAULT_OUTER_WIDTH, 325 DEFAULT_ALIGN, 326 SPACING_MULT_NO_SCALE, 327 SPACING_ADD_NO_SCALE, 328 DEFAULT_METRICS, 329 true, 330 TextUtils.TruncateAt.START, 331 DEFAULT_OUTER_WIDTH); 332 assertNotNull(boringLayout); 333 } 334 335 @Test testDraw()336 public void testDraw() { 337 BoringLayout boringLayout = BoringLayout.make(DEFAULT_CHAR_SEQUENCE, 338 DEFAULT_PAINT, 339 DEFAULT_OUTER_WIDTH, 340 Alignment.ALIGN_NORMAL, 341 SPACING_MULT_NO_SCALE, 342 SPACING_ADD_NO_SCALE, 343 DEFAULT_METRICS, 344 true); 345 346 Bitmap mutableBitmap = Bitmap.createBitmap(10, 28, Config.ARGB_8888); 347 Canvas canvas = spy(new Canvas(mutableBitmap)); 348 boringLayout.draw(canvas, null, null, 0); 349 verify(canvas, times(1)).drawText(eq(DEFAULT_CHAR_SEQUENCE.toString()), 350 anyFloat(), anyFloat(), any(Paint.class)); 351 352 reset(canvas); 353 boringLayout = BoringLayout.make(DEFAULT_CHAR_SEQUENCE, 354 DEFAULT_PAINT, 355 DEFAULT_OUTER_WIDTH, 356 Alignment.ALIGN_OPPOSITE, 357 SPACING_MULT_NO_SCALE, 358 SPACING_ADD_NO_SCALE, 359 DEFAULT_METRICS, 360 true); 361 boringLayout.draw(canvas, null, null, 0); 362 verify(canvas, times(1)).drawText(sameCharSequence(DEFAULT_CHAR_SEQUENCE), 363 anyInt(), anyInt(), anyFloat(), anyFloat(), any(Paint.class)); 364 } 365 drawToBitmap(Layout l)366 private static Bitmap drawToBitmap(Layout l) { 367 final Bitmap bmp = Bitmap.createBitmap(l.getWidth(), l.getHeight(), Bitmap.Config.RGB_565); 368 final Canvas c = new Canvas(bmp); 369 370 c.save(); 371 c.translate(0, 0); 372 l.draw(c); 373 c.restore(); 374 return bmp; 375 } 376 textPaintToString(TextPaint p)377 private static String textPaintToString(TextPaint p) { 378 return "{" 379 + "mTextSize=" + p.getTextSize() + ", " 380 + "mTextSkewX=" + p.getTextSkewX() + ", " 381 + "mTextScaleX=" + p.getTextScaleX() + ", " 382 + "mLetterSpacing=" + p.getLetterSpacing() + ", " 383 + "mFlags=" + p.getFlags() + ", " 384 + "mTextLocales=" + p.getTextLocales() + ", " 385 + "mFontVariationSettings=" + p.getFontVariationSettings() + ", " 386 + "mTypeface=" + p.getTypeface() + ", " 387 + "mFontFeatureSettings=" + p.getFontFeatureSettings() 388 + "}"; 389 } 390 directionToString(TextDirectionHeuristic dir)391 private static String directionToString(TextDirectionHeuristic dir) { 392 if (dir == TextDirectionHeuristics.LTR) { 393 return "LTR"; 394 } else if (dir == TextDirectionHeuristics.RTL) { 395 return "RTL"; 396 } else if (dir == TextDirectionHeuristics.FIRSTSTRONG_LTR) { 397 return "FIRSTSTRONG_LTR"; 398 } else if (dir == TextDirectionHeuristics.FIRSTSTRONG_RTL) { 399 return "FIRSTSTRONG_RTL"; 400 } else if (dir == TextDirectionHeuristics.ANYRTL_LTR) { 401 return "ANYRTL_LTR"; 402 } else { 403 throw new RuntimeException("Unknown Direction"); 404 } 405 } 406 407 static class LayoutParam { 408 final int mStrategy; 409 final int mFrequency; 410 final TextPaint mPaint; 411 final TextDirectionHeuristic mDir; 412 LayoutParam(int strategy, int frequency, TextPaint paint, TextDirectionHeuristic dir)413 LayoutParam(int strategy, int frequency, TextPaint paint, TextDirectionHeuristic dir) { 414 mStrategy = strategy; 415 mFrequency = frequency; 416 mPaint = new TextPaint(paint); 417 mDir = dir; 418 } 419 420 @Override toString()421 public String toString() { 422 return "{" 423 + "mStrategy=" + mStrategy + ", " 424 + "mFrequency=" + mFrequency + ", " 425 + "mPaint=" + textPaintToString(mPaint) + ", " 426 + "mDir=" + directionToString(mDir) 427 + "}"; 428 429 } 430 getPrecomputedText(CharSequence text)431 PrecomputedText getPrecomputedText(CharSequence text) { 432 PrecomputedText.Params param = new PrecomputedText.Params.Builder(mPaint) 433 .setBreakStrategy(mStrategy) 434 .setHyphenationFrequency(mFrequency) 435 .setTextDirection(mDir).build(); 436 return PrecomputedText.create(text, param); 437 } 438 }; 439 assertSameDrawOutput( CharSequence text, LayoutParam measuredTextParam, TextPaint layoutPaint)440 void assertSameDrawOutput( 441 CharSequence text, 442 LayoutParam measuredTextParam, 443 TextPaint layoutPaint) { 444 String msg = "BoringLayout#draw for String and PrecomputedText with " + measuredTextParam 445 + " must output the same BMP."; 446 447 final BoringLayout.Metrics metricsWithString = BoringLayout.isBoring(text, layoutPaint); 448 final Layout layoutWithString = BoringLayout.make( 449 text, layoutPaint, metricsWithString.width, Alignment.ALIGN_NORMAL, 450 SPACING_MULT_NO_SCALE, SPACING_ADD_NO_SCALE, DEFAULT_METRICS, 451 true /* include padding */); 452 453 final PrecomputedText precomputed = measuredTextParam.getPrecomputedText(text); 454 final BoringLayout.Metrics metricsWithPrecomputed = BoringLayout.isBoring( 455 precomputed, layoutPaint); 456 final Layout layoutWithPrecomputed = BoringLayout.make( 457 precomputed, layoutPaint, metricsWithPrecomputed.width, Alignment.ALIGN_NORMAL, 458 SPACING_MULT_NO_SCALE, SPACING_ADD_NO_SCALE, DEFAULT_METRICS, 459 true /* include padding */); 460 461 assertEquals(msg, layoutWithString.getHeight(), layoutWithPrecomputed.getHeight(), 0.0f); 462 463 final Bitmap expectedBMP = drawToBitmap(layoutWithString); 464 final Bitmap resultBMP = drawToBitmap(layoutWithPrecomputed); 465 466 assertTrue(msg, resultBMP.sameAs(expectedBMP)); 467 } 468 469 @Test testPrecomputedText()470 public void testPrecomputedText() { 471 int[] breaks = { 472 Layout.BREAK_STRATEGY_SIMPLE, 473 Layout.BREAK_STRATEGY_HIGH_QUALITY, 474 Layout.BREAK_STRATEGY_BALANCED, 475 }; 476 477 int[] frequencies = { 478 Layout.HYPHENATION_FREQUENCY_NORMAL, 479 Layout.HYPHENATION_FREQUENCY_FULL, 480 Layout.HYPHENATION_FREQUENCY_NONE, 481 }; 482 483 TextDirectionHeuristic[] dirs = { 484 TextDirectionHeuristics.LTR, 485 TextDirectionHeuristics.RTL, 486 TextDirectionHeuristics.FIRSTSTRONG_LTR, 487 TextDirectionHeuristics.FIRSTSTRONG_RTL, 488 TextDirectionHeuristics.ANYRTL_LTR, 489 }; 490 491 float[] textSizes = { 492 8.0f, 16.0f, 32.0f 493 }; 494 495 LocaleList[] locales = { 496 LocaleList.forLanguageTags("en-US"), 497 LocaleList.forLanguageTags("ja-JP"), 498 LocaleList.forLanguageTags("en-US,ja-JP"), 499 }; 500 501 String onelineText = "Hello, World."; 502 503 TextPaint paint = new TextPaint(); 504 505 // If the PrecomputedText is created with the same Paint, the draw result must be the same. 506 for (int b : breaks) { 507 for (int f : frequencies) { 508 for (TextDirectionHeuristic dir : dirs) { 509 for (float textSize : textSizes) { 510 for (LocaleList locale : locales) { 511 paint.setTextSize(textSize); 512 paint.setTextLocales(locale); 513 514 assertSameDrawOutput(onelineText, new LayoutParam(b, f, paint, dir), 515 paint); 516 } 517 } 518 } 519 } 520 } 521 522 // Even if the parameters are different, the output of the static layout must be 523 // same bitmap. 524 for (int bi = 0; bi < breaks.length; bi++) { 525 for (int fi = 0; fi < frequencies.length; fi++) { 526 for (int diri = 0; diri < dirs.length; diri++) { 527 for (int sizei = 0; sizei < textSizes.length; sizei++) { 528 for (int localei = 0; localei < locales.length; localei++) { 529 TextPaint precomputedPaint = new TextPaint(); 530 TextPaint layoutPaint = new TextPaint(); 531 532 precomputedPaint.setTextSize(textSizes[sizei]); 533 layoutPaint.setTextSize(textSizes[(sizei + 1) % textSizes.length]); 534 535 precomputedPaint.setTextLocales(locales[localei]); 536 layoutPaint.setTextLocales(locales[(localei + 1) % locales.length]); 537 538 int b = breaks[bi]; 539 540 int f = frequencies[fi]; 541 542 TextDirectionHeuristic dir = dirs[diri]; 543 544 assertSameDrawOutput(onelineText, 545 new LayoutParam(b, f, precomputedPaint, dir), 546 layoutPaint); 547 } 548 } 549 } 550 } 551 } 552 } 553 createMetrics( final int top, final int ascent, final int descent, final int bottom, final int width, final int leading)554 private static Metrics createMetrics( 555 final int top, 556 final int ascent, 557 final int descent, 558 final int bottom, 559 final int width, 560 final int leading) { 561 562 final Metrics metrics = new Metrics(); 563 564 metrics.top = top; 565 metrics.ascent = ascent; 566 metrics.descent = descent; 567 metrics.bottom = bottom; 568 metrics.width = width; 569 metrics.leading = leading; 570 571 return metrics; 572 } 573 makeDefaultBoringLayout()574 private static BoringLayout makeDefaultBoringLayout() { 575 return new BoringLayout(DEFAULT_CHAR_SEQUENCE, 576 DEFAULT_PAINT, 577 DEFAULT_OUTER_WIDTH, 578 DEFAULT_ALIGN, 579 SPACING_MULT_NO_SCALE, 580 SPACING_ADD_NO_SCALE, 581 DEFAULT_METRICS, 582 true); 583 } 584 makeBoringLayout(float spacingMult,float spacingAdd)585 private static BoringLayout makeBoringLayout(float spacingMult,float spacingAdd) { 586 return new BoringLayout(DEFAULT_CHAR_SEQUENCE, 587 DEFAULT_PAINT, 588 DEFAULT_OUTER_WIDTH, 589 DEFAULT_ALIGN, 590 spacingMult, 591 spacingAdd, 592 DEFAULT_METRICS, 593 true); 594 } 595 makeBoringLayoutAlign(Alignment align)596 private static BoringLayout makeBoringLayoutAlign(Alignment align) { 597 return new BoringLayout(DEFAULT_CHAR_SEQUENCE, 598 DEFAULT_PAINT, 599 DEFAULT_OUTER_WIDTH, 600 align, 601 SPACING_MULT_NO_SCALE, 602 SPACING_ADD_NO_SCALE, 603 DEFAULT_METRICS, 604 true); 605 } 606 } 607