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.graphics.cts; 18 19 import static android.graphics.Paint.CURSOR_AFTER; 20 import static android.graphics.Paint.CURSOR_AT; 21 import static android.graphics.Paint.CURSOR_AT_OR_AFTER; 22 import static android.graphics.Paint.CURSOR_AT_OR_BEFORE; 23 import static android.graphics.Paint.CURSOR_BEFORE; 24 25 import static org.junit.Assert.assertEquals; 26 import static org.junit.Assert.assertFalse; 27 import static org.junit.Assert.assertNull; 28 import static org.junit.Assert.assertTrue; 29 30 import android.content.Context; 31 import android.graphics.Bitmap; 32 import android.graphics.BitmapShader; 33 import android.graphics.BlendMode; 34 import android.graphics.Color; 35 import android.graphics.ColorFilter; 36 import android.graphics.ColorSpace; 37 import android.graphics.MaskFilter; 38 import android.graphics.Matrix; 39 import android.graphics.Paint; 40 import android.graphics.Paint.Align; 41 import android.graphics.Paint.Cap; 42 import android.graphics.Paint.Join; 43 import android.graphics.Paint.Style; 44 import android.graphics.Path; 45 import android.graphics.PathEffect; 46 import android.graphics.PorterDuff; 47 import android.graphics.PorterDuffXfermode; 48 import android.graphics.Rect; 49 import android.graphics.Shader; 50 import android.graphics.Typeface; 51 import android.graphics.Xfermode; 52 import android.os.LocaleList; 53 import android.text.SpannedString; 54 55 import androidx.test.InstrumentationRegistry; 56 import androidx.test.filters.SmallTest; 57 import androidx.test.runner.AndroidJUnit4; 58 59 import com.android.compatibility.common.util.CddTest; 60 import com.android.compatibility.common.util.ColorUtils; 61 62 import org.junit.Test; 63 import org.junit.runner.RunWith; 64 65 import java.util.Locale; 66 import java.util.function.BiConsumer; 67 import java.util.function.Function; 68 import java.util.function.Supplier; 69 70 @SmallTest 71 @RunWith(AndroidJUnit4.class) 72 public class PaintTest { 73 private static final Typeface[] TYPEFACES = new Typeface[] { 74 Typeface.DEFAULT, 75 Typeface.DEFAULT_BOLD, 76 Typeface.MONOSPACE, 77 Typeface.SANS_SERIF, 78 Typeface.SERIF, 79 }; 80 81 @Test testConstructor()82 public void testConstructor() { 83 new Paint(); 84 85 new Paint(1); 86 87 Paint p = new Paint(); 88 new Paint(p); 89 } 90 91 @Test testDefaultColor()92 public void testDefaultColor() { 93 Supplier<Paint> set = () -> { 94 Paint result = new Paint(); 95 result.setColor(Color.BLUE); 96 assertEquals(Color.BLUE, result.getColor()); 97 result.setShadowLayer(10.0f, 1.0f, 1.0f, Color.RED); 98 assertEquals(Color.RED, result.getShadowLayerColor()); 99 100 Paint def = new Paint(); 101 result.set(def); 102 return result; 103 }; 104 Supplier<Paint> reset = () -> { 105 Paint result = new Paint(); 106 result.setColor(Color.GREEN); 107 assertEquals(Color.GREEN, result.getColor()); 108 result.setShadowLayer(10.0f, 1.0f, 1.0f, Color.WHITE); 109 assertEquals(Color.WHITE, result.getShadowLayerColor()); 110 111 result.reset(); 112 return result; 113 }; 114 for (Paint p : new Paint[]{ new Paint(), 115 new Paint(1), 116 new Paint(new Paint()), 117 set.get(), 118 reset.get()}) { 119 assertEquals(Color.BLACK, p.getColor()); 120 assertEquals(Color.TRANSPARENT, p.getShadowLayerColor()); 121 122 assertEquals(Color.BLACK, Color.toArgb(p.getColorLong())); 123 assertEquals(Color.TRANSPARENT, Color.toArgb(p.getShadowLayerColorLong())); 124 } 125 } 126 127 @Test testBreakText()128 public void testBreakText() { 129 String text = "HIJKLMN"; 130 char[] textChars = text.toCharArray(); 131 SpannedString textSpan = new SpannedString(text); 132 133 Paint p = new Paint(); 134 135 // We need to turn off kerning in order to get accurate comparisons 136 p.setFlags(p.getFlags() & ~Paint.DEV_KERN_TEXT_FLAG); 137 138 float[] widths = new float[text.length()]; 139 assertEquals(text.length(), p.getTextWidths(text, widths)); 140 141 float totalWidth = 0.0f; 142 for (int i = 0; i < text.length(); i++) { 143 totalWidth += widths[i]; 144 } 145 146 for (int i = 0; i < text.length(); i++) { 147 verifyBreakText(text, textChars, textSpan, i, i + 1, true, totalWidth, 1, widths[i]); 148 } 149 150 // Measure empty string 151 verifyBreakText(text, textChars, textSpan, 0, 0, true, totalWidth, 0, 0); 152 153 // Measure substring from front: "HIJ" 154 verifyBreakText(text, textChars, textSpan, 0, 3, true, totalWidth, 155 3, widths[0] + widths[1] + widths[2]); 156 157 // Reverse measure substring from front: "HIJ" 158 verifyBreakText(text, textChars, textSpan, 0, 3, false, totalWidth, 159 3, widths[0] + widths[1] + widths[2]); 160 161 // Measure substring from back: "MN" 162 verifyBreakText(text, textChars, textSpan, 5, 7, true, totalWidth, 163 2, widths[5] + widths[6]); 164 165 // Reverse measure substring from back: "MN" 166 verifyBreakText(text, textChars, textSpan, 5, 7, false, totalWidth, 167 2, widths[5] + widths[6]); 168 169 // Measure substring in the middle: "JKL" 170 verifyBreakText(text, textChars, textSpan, 2, 5, true, totalWidth, 171 3, widths[2] + widths[3] + widths[4]); 172 173 // Reverse measure substring in the middle: "JKL" 174 verifyBreakText(text, textChars, textSpan, 2, 5, false, totalWidth, 175 3, widths[2] + widths[3] + widths[4]); 176 177 // Measure substring in the middle and restrict width to the first 2 characters. 178 verifyBreakText(text, textChars, textSpan, 2, 5, true, widths[2] + widths[3], 179 2, widths[2] + widths[3]); 180 181 // Reverse measure substring in the middle and restrict width to the last 2 characters. 182 verifyBreakText(text, textChars, textSpan, 2, 5, false, widths[3] + widths[4], 183 2, widths[3] + widths[4]); 184 185 // a single Emoji (U+1f601) 186 String emoji = "\ud83d\ude01"; 187 char[] emojiChars = emoji.toCharArray(); 188 SpannedString emojiSpan = new SpannedString(emoji); 189 190 float[] emojiWidths = new float[emoji.length()]; 191 assertEquals(emoji.length(), p.getTextWidths(emoji, emojiWidths)); 192 193 // Measure substring with a cluster 194 verifyBreakText(emoji, emojiChars, emojiSpan, 0, 2, true, 0, 195 0, 0); 196 197 // Measure substring with a cluster 198 verifyBreakText(emoji, emojiChars, emojiSpan, 0, 2, true, emojiWidths[0], 199 2, emojiWidths[0]); 200 201 // Reverse measure substring with a cluster 202 verifyBreakText(emoji, emojiChars, emojiSpan, 0, 2, false, 0, 203 0, 0); 204 205 // Measure substring with a cluster 206 verifyBreakText(emoji, emojiChars, emojiSpan, 0, 2, false, emojiWidths[0], 207 2, emojiWidths[0]); 208 } 209 verifyBreakText(String text, char[] textChars, SpannedString textSpan, int start, int end, boolean measureForwards, float maxWidth, int expectedCount, float expectedWidth)210 private void verifyBreakText(String text, char[] textChars, SpannedString textSpan, 211 int start, int end, boolean measureForwards, float maxWidth, int expectedCount, 212 float expectedWidth) { 213 Paint p = new Paint(); 214 215 // We need to turn off kerning in order to get accurate comparisons 216 p.setFlags(p.getFlags() & ~Paint.DEV_KERN_TEXT_FLAG); 217 218 int count = end - start; 219 if (!measureForwards) { 220 count = -count; 221 } 222 223 float[][] measured = new float[][] { 224 new float[1], 225 new float[1], 226 new float[1] 227 }; 228 String textSlice = text.substring(start, end); 229 assertEquals(expectedCount, p.breakText(textSlice, measureForwards, maxWidth, measured[0])); 230 assertEquals(expectedCount, p.breakText(textChars, start, count, maxWidth, measured[1])); 231 assertEquals(expectedCount, p.breakText(textSpan, start, end, measureForwards, maxWidth, 232 measured[2])); 233 234 for (int i = 0; i < measured.length; i++) { 235 assertEquals("i: " + i, expectedWidth, measured[i][0], 0.0f); 236 } 237 } 238 239 @Test testSet()240 public void testSet() { 241 Paint p = new Paint(); 242 Paint p2 = new Paint(); 243 ColorFilter c = new ColorFilter(); 244 MaskFilter m = new MaskFilter(); 245 PathEffect e = new PathEffect(); 246 Shader s = new Shader(); 247 Typeface t = Typeface.DEFAULT; 248 Xfermode x = new Xfermode(); 249 250 p.setColorFilter(c); 251 p.setMaskFilter(m); 252 p.setPathEffect(e); 253 p.setShader(s); 254 p.setTypeface(t); 255 p.setXfermode(x); 256 p2.set(p); 257 assertEquals(c, p2.getColorFilter()); 258 assertEquals(m, p2.getMaskFilter()); 259 assertEquals(e, p2.getPathEffect()); 260 assertEquals(s, p2.getShader()); 261 assertEquals(t, p2.getTypeface()); 262 assertEquals(x, p2.getXfermode()); 263 264 p2.set(p2); 265 assertEquals(c, p2.getColorFilter()); 266 assertEquals(m, p2.getMaskFilter()); 267 assertEquals(e, p2.getPathEffect()); 268 assertEquals(s, p2.getShader()); 269 assertEquals(t, p2.getTypeface()); 270 assertEquals(x, p2.getXfermode()); 271 272 p.setColorFilter(null); 273 p.setMaskFilter(null); 274 p.setPathEffect(null); 275 p.setShader(null); 276 p.setTypeface(null); 277 p.setXfermode(null); 278 p2.set(p); 279 assertNull(p2.getColorFilter()); 280 assertNull(p2.getMaskFilter()); 281 assertNull(p2.getPathEffect()); 282 assertNull(p2.getShader()); 283 assertNull(p2.getTypeface()); 284 assertNull(p2.getXfermode()); 285 286 p2.set(p2); 287 assertNull(p2.getColorFilter()); 288 assertNull(p2.getMaskFilter()); 289 assertNull(p2.getPathEffect()); 290 assertNull(p2.getShader()); 291 assertNull(p2.getTypeface()); 292 assertNull(p2.getXfermode()); 293 } 294 295 @Test testAccessStrokeCap()296 public void testAccessStrokeCap() { 297 Paint p = new Paint(); 298 299 p.setStrokeCap(Cap.BUTT); 300 assertEquals(Cap.BUTT, p.getStrokeCap()); 301 302 p.setStrokeCap(Cap.ROUND); 303 assertEquals(Cap.ROUND, p.getStrokeCap()); 304 305 p.setStrokeCap(Cap.SQUARE); 306 assertEquals(Cap.SQUARE, p.getStrokeCap()); 307 } 308 309 @Test(expected=RuntimeException.class) testSetStrokeCapNull()310 public void testSetStrokeCapNull() { 311 Paint p = new Paint(); 312 313 p.setStrokeCap(null); 314 } 315 316 @Test testAccessXfermode()317 public void testAccessXfermode() { 318 Paint p = new Paint(); 319 Xfermode x = new Xfermode(); 320 321 assertEquals(x, p.setXfermode(x)); 322 assertEquals(x, p.getXfermode()); 323 324 assertNull(p.setXfermode(null)); 325 assertNull(p.getXfermode()); 326 } 327 328 @Test testAccessShader()329 public void testAccessShader() { 330 Paint p = new Paint(); 331 Shader s = new Shader(); 332 333 assertEquals(s, p.setShader(s)); 334 assertEquals(s, p.getShader()); 335 336 assertNull(p.setShader(null)); 337 assertNull(p.getShader()); 338 } 339 340 @Test testShaderLocalMatrix()341 public void testShaderLocalMatrix() { 342 int width = 80; 343 int height = 120; 344 int[] color = new int[width * height]; 345 Bitmap bitmap = Bitmap.createBitmap(color, width, height, Bitmap.Config.RGB_565); 346 347 Paint p = new Paint(); 348 Matrix m = new Matrix(); 349 Shader s = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); 350 351 // set the shaders matrix to a non identity value and attach to paint 352 m.setScale(10, 0); 353 s.setLocalMatrix(m); 354 p.setShader(s); 355 356 Matrix m2 = new Matrix(); 357 assertTrue(p.getShader().getLocalMatrix(m2)); 358 assertEquals(m, m2); 359 360 // updated the matrix again and set it on the shader but NOT the paint 361 m.setScale(0, 10); 362 s.setLocalMatrix(m); 363 364 // assert that the matrix on the paint's shader also changed 365 Matrix m3 = new Matrix(); 366 assertTrue(p.getShader().getLocalMatrix(m3)); 367 assertEquals(m, m3); 368 } 369 370 @Test testSetAntiAlias()371 public void testSetAntiAlias() { 372 Paint p = new Paint(); 373 374 p.setAntiAlias(false); 375 assertFalse(p.isAntiAlias()); 376 377 p.setAntiAlias(true); 378 assertTrue(p.isAntiAlias()); 379 } 380 381 @Test testDefaultAntiAlias()382 public void testDefaultAntiAlias() { 383 Paint p = new Paint(); 384 assertTrue(p.isAntiAlias()); 385 } 386 387 @Test testAccessTypeface()388 public void testAccessTypeface() { 389 Paint p = new Paint(); 390 391 assertEquals(Typeface.DEFAULT, p.setTypeface(Typeface.DEFAULT)); 392 assertEquals(Typeface.DEFAULT, p.getTypeface()); 393 394 assertEquals(Typeface.DEFAULT_BOLD, p.setTypeface(Typeface.DEFAULT_BOLD)); 395 assertEquals(Typeface.DEFAULT_BOLD, p.getTypeface()); 396 397 assertEquals(Typeface.MONOSPACE, p.setTypeface(Typeface.MONOSPACE)); 398 assertEquals(Typeface.MONOSPACE, p.getTypeface()); 399 400 assertNull(p.setTypeface(null)); 401 assertNull(p.getTypeface()); 402 } 403 404 @Test testAccessPathEffect()405 public void testAccessPathEffect() { 406 Paint p = new Paint(); 407 PathEffect e = new PathEffect(); 408 409 assertEquals(e, p.setPathEffect(e)); 410 assertEquals(e, p.getPathEffect()); 411 412 assertNull(p.setPathEffect(null)); 413 assertNull(p.getPathEffect()); 414 } 415 416 @Test testSetFakeBoldText()417 public void testSetFakeBoldText() { 418 Paint p = new Paint(); 419 420 p.setFakeBoldText(true); 421 assertTrue(p.isFakeBoldText()); 422 423 p.setFakeBoldText(false); 424 assertFalse(p.isFakeBoldText()); 425 } 426 427 @Test testAccessStrokeJoin()428 public void testAccessStrokeJoin() { 429 Paint p = new Paint(); 430 431 p.setStrokeJoin(Join.BEVEL); 432 assertEquals(Join.BEVEL, p.getStrokeJoin()); 433 434 p.setStrokeJoin(Join.MITER); 435 assertEquals(Join.MITER, p.getStrokeJoin()); 436 437 p.setStrokeJoin(Join.ROUND); 438 assertEquals(Join.ROUND, p.getStrokeJoin()); 439 } 440 441 @Test(expected=RuntimeException.class) testSetStrokeJoinNull()442 public void testSetStrokeJoinNull() { 443 Paint p = new Paint(); 444 445 p.setStrokeJoin(null); 446 } 447 448 @Test testAccessStyle()449 public void testAccessStyle() { 450 Paint p = new Paint(); 451 452 p.setStyle(Style.FILL); 453 assertEquals(Style.FILL, p.getStyle()); 454 455 p.setStyle(Style.FILL_AND_STROKE); 456 assertEquals(Style.FILL_AND_STROKE, p.getStyle()); 457 458 p.setStyle(Style.STROKE); 459 assertEquals(Style.STROKE, p.getStyle()); 460 } 461 462 @Test(expected=RuntimeException.class) testSetStyleNull()463 public void testSetStyleNull() { 464 Paint p = new Paint(); 465 466 p.setStyle(null); 467 } 468 469 @Test testGetFontSpacing()470 public void testGetFontSpacing() { 471 Paint p = new Paint(); 472 473 for (Typeface typeface : TYPEFACES) { 474 p.setTypeface(typeface); 475 476 p.setTextSize(10); 477 float spacing10 = p.getFontSpacing(); 478 assertTrue(spacing10 > 0); 479 480 p.setTextSize(20); 481 float spacing20 = p.getFontSpacing(); 482 assertTrue(spacing20 > spacing10); 483 } 484 } 485 486 @Test testSetSubpixelText()487 public void testSetSubpixelText() { 488 Paint p = new Paint(); 489 490 p.setSubpixelText(true); 491 assertTrue(p.isSubpixelText()); 492 493 p.setSubpixelText(false); 494 assertFalse(p.isSubpixelText()); 495 } 496 497 @Test testAccessTextScaleX()498 public void testAccessTextScaleX() { 499 Paint p = new Paint(); 500 501 p.setTextScaleX(2.0f); 502 assertEquals(2.0f, p.getTextScaleX(), 0.0f); 503 504 p.setTextScaleX(1.0f); 505 assertEquals(1.0f, p.getTextScaleX(), 0.0f); 506 507 p.setTextScaleX(0.0f); 508 assertEquals(0.0f, p.getTextScaleX(), 0.0f); 509 510 } 511 512 @Test testAccessMaskFilter()513 public void testAccessMaskFilter() { 514 Paint p = new Paint(); 515 MaskFilter m = new MaskFilter(); 516 517 assertEquals(m, p.setMaskFilter(m)); 518 assertEquals(m, p.getMaskFilter()); 519 520 assertNull(p.setMaskFilter(null)); 521 assertNull(p.getMaskFilter()); 522 } 523 524 @Test testAccessColorFilter()525 public void testAccessColorFilter() { 526 Paint p = new Paint(); 527 ColorFilter c = new ColorFilter(); 528 529 assertEquals(c, p.setColorFilter(c)); 530 assertEquals(c, p.getColorFilter()); 531 532 assertNull(p.setColorFilter(null)); 533 assertNull(p.getColorFilter()); 534 } 535 536 @Test testSetARGB()537 public void testSetARGB() { 538 Paint p = new Paint(); 539 540 p.setARGB(0, 0, 0, 0); 541 assertEquals(0, p.getColor()); 542 543 p.setARGB(3, 3, 3, 3); 544 assertEquals((3 << 24) | (3 << 16) | (3 << 8) | 3, p.getColor()); 545 } 546 547 @Test testAscent()548 public void testAscent() { 549 Paint p = new Paint(); 550 551 for (Typeface typeface : TYPEFACES) { 552 p.setTypeface(typeface); 553 554 p.setTextSize(10); 555 float ascent10 = p.ascent(); 556 assertTrue(ascent10 < 0); 557 558 p.setTextSize(20); 559 float ascent20 = p.ascent(); 560 assertTrue(ascent20 < ascent10); 561 } 562 } 563 564 @Test 565 public void testAccessTextSkewX() { 566 Paint p = new Paint(); 567 568 p.setTextSkewX(1.0f); 569 assertEquals(1.0f, p.getTextSkewX(), 0.0f); 570 571 p.setTextSkewX(0.0f); 572 assertEquals(0.0f, p.getTextSkewX(), 0.0f); 573 574 p.setTextSkewX(-0.25f); 575 assertEquals(-0.25f, p.getTextSkewX(), 0.0f); 576 } 577 578 @Test 579 public void testAccessTextSize() { 580 Paint p = new Paint(); 581 582 p.setTextSize(1.0f); 583 assertEquals(1.0f, p.getTextSize(), 0.0f); 584 585 p.setTextSize(2.0f); 586 assertEquals(2.0f, p.getTextSize(), 0.0f); 587 588 // text size should be greater than 0, so set -1 has no effect 589 p.setTextSize(-1.0f); 590 assertEquals(2.0f, p.getTextSize(), 0.0f); 591 592 // text size should be greater than or equals to 0 593 p.setTextSize(0.0f); 594 assertEquals(0.0f, p.getTextSize(), 0.0f); 595 } 596 597 @Test 598 public void testGetTextWidths() throws Exception { 599 String text = "HIJKLMN"; 600 char[] textChars = text.toCharArray(); 601 SpannedString textSpan = new SpannedString(text); 602 603 // Test measuring the widths of the entire text 604 verifyGetTextWidths(text, textChars, textSpan, 0, 7); 605 606 // Test measuring a substring of the text 607 verifyGetTextWidths(text, textChars, textSpan, 1, 3); 608 609 // Test measuring a substring of zero length. 610 verifyGetTextWidths(text, textChars, textSpan, 3, 3); 611 612 // Test measuring substrings from the front and back 613 verifyGetTextWidths(text, textChars, textSpan, 0, 2); 614 verifyGetTextWidths(text, textChars, textSpan, 4, 7); 615 } 616 617 /** Tests all four overloads of getTextWidths are the same. */ 618 private void verifyGetTextWidths(String text, char[] textChars, SpannedString textSpan, 619 int start, int end) { 620 Paint p = new Paint(); 621 int count = end - start; 622 float[][] widths = new float[][] { 623 new float[count], 624 new float[count], 625 new float[count], 626 new float[count] 627 }; 628 629 String textSlice = text.substring(start, end); 630 assertEquals(count, p.getTextWidths(textSlice, widths[0])); 631 assertEquals(count, p.getTextWidths(textChars, start, count, widths[1])); 632 assertEquals(count, p.getTextWidths(textSpan, start, end, widths[2])); 633 assertEquals(count, p.getTextWidths(text, start, end, widths[3])); 634 635 // Check that the widths returned by the overloads are the same. 636 for (int i = 0; i < count; i++) { 637 assertEquals(widths[0][i], widths[1][i], 0.0f); 638 assertEquals(widths[1][i], widths[2][i], 0.0f); 639 assertEquals(widths[2][i], widths[3][i], 0.0f); 640 } 641 } 642 643 @Test 644 public void testSetStrikeThruText() { 645 Paint p = new Paint(); 646 647 p.setStrikeThruText(true); 648 assertTrue(p.isStrikeThruText()); 649 650 p.setStrikeThruText(false); 651 assertFalse(p.isStrikeThruText()); 652 } 653 654 @Test 655 public void testAccessTextAlign() { 656 Paint p = new Paint(); 657 658 p.setTextAlign(Align.CENTER); 659 assertEquals(Align.CENTER, p.getTextAlign()); 660 661 p.setTextAlign(Align.LEFT); 662 assertEquals(Align.LEFT, p.getTextAlign()); 663 664 p.setTextAlign(Align.RIGHT); 665 assertEquals(Align.RIGHT, p.getTextAlign()); 666 } 667 668 @Test 669 public void testAccessTextLocale() { 670 Paint p = new Paint(); 671 672 final Locale defaultLocale = Locale.getDefault(); 673 674 // Check default 675 assertEquals(defaultLocale, p.getTextLocale()); 676 677 // Check setter / getters 678 p.setTextLocale(Locale.US); 679 assertEquals(Locale.US, p.getTextLocale()); 680 assertEquals(new LocaleList(Locale.US), p.getTextLocales()); 681 682 p.setTextLocale(Locale.CHINESE); 683 assertEquals(Locale.CHINESE, p.getTextLocale()); 684 assertEquals(new LocaleList(Locale.CHINESE), p.getTextLocales()); 685 686 p.setTextLocale(Locale.JAPANESE); 687 assertEquals(Locale.JAPANESE, p.getTextLocale()); 688 assertEquals(new LocaleList(Locale.JAPANESE), p.getTextLocales()); 689 690 p.setTextLocale(Locale.KOREAN); 691 assertEquals(Locale.KOREAN, p.getTextLocale()); 692 assertEquals(new LocaleList(Locale.KOREAN), p.getTextLocales()); 693 694 // Check reverting back to default 695 p.setTextLocale(defaultLocale); 696 assertEquals(defaultLocale, p.getTextLocale()); 697 assertEquals(new LocaleList(defaultLocale), p.getTextLocales()); 698 } 699 700 @Test(expected=IllegalArgumentException.class) 701 public void testSetTextLocaleNull() { 702 Paint p = new Paint(); 703 704 p.setTextLocale(null); 705 } 706 707 @Test 708 public void testAccessTextLocales() { 709 Paint p = new Paint(); 710 711 final LocaleList defaultLocales = LocaleList.getDefault(); 712 713 // Check default 714 assertEquals(defaultLocales, p.getTextLocales()); 715 716 // Check setter / getters for a one-member locale list 717 p.setTextLocales(new LocaleList(Locale.CHINESE)); 718 assertEquals(Locale.CHINESE, p.getTextLocale()); 719 assertEquals(new LocaleList(Locale.CHINESE), p.getTextLocales()); 720 721 // Check setter / getters for a two-member locale list 722 p.setTextLocales(LocaleList.forLanguageTags("fr,de")); 723 assertEquals(Locale.forLanguageTag("fr"), p.getTextLocale()); 724 assertEquals(LocaleList.forLanguageTags("fr,de"), p.getTextLocales()); 725 726 // Check reverting back to default 727 p.setTextLocales(defaultLocales); 728 assertEquals(defaultLocales, p.getTextLocales()); 729 } 730 731 @Test(expected=IllegalArgumentException.class) 732 public void testAccessTextLocalesNull() { 733 Paint p = new Paint(); 734 735 // Check that we cannot pass a null locale list 736 p.setTextLocales(null); 737 } 738 739 @Test(expected=IllegalArgumentException.class) 740 public void testAccessTextLocalesEmpty() { 741 Paint p = new Paint(); 742 743 // Check that we cannot pass an empty locale list 744 p.setTextLocales(new LocaleList()); 745 } 746 747 @Test 748 public void testGetFillPath() { 749 Paint p = new Paint(); 750 Path path1 = new Path(); 751 Path path2 = new Path(); 752 753 assertTrue(path1.isEmpty()); 754 assertTrue(path2.isEmpty()); 755 p.getFillPath(path1, path2); 756 assertTrue(path1.isEmpty()); 757 assertTrue(path2.isEmpty()); 758 759 // No setter 760 } 761 762 @Test 763 public void testAccessAlpha() { 764 Paint p = new Paint(); 765 766 p.setAlpha(0); 767 assertEquals(0, p.getAlpha()); 768 769 p.setAlpha(255); 770 assertEquals(255, p.getAlpha()); 771 772 // set value should between 0 and 255, ensure return value is always in range 773 p.setAlpha(266); 774 assertTrue(0 <= p.getAlpha() && p.getAlpha() <= 255); 775 776 // set value should between 0 and 255, ensure return value is always in range 777 p.setAlpha(-20); 778 assertTrue(0 <= p.getAlpha() && p.getAlpha() <= 255); 779 } 780 781 @Test 782 public void testSetAlpha() { 783 for (ColorSpace.Named e : new ColorSpace.Named[] { 784 ColorSpace.Named.SRGB, 785 ColorSpace.Named.LINEAR_EXTENDED_SRGB, 786 ColorSpace.Named.DISPLAY_P3}) { 787 ColorSpace cs = ColorSpace.get(e); 788 789 // Arbitrary colors 790 final float red = .2f; 791 final float green = .7f; 792 final float blue = .9f; 793 final long desiredColor = Color.pack(red, green, blue, 1.0f, cs); 794 795 Paint p = new Paint(); 796 p.setColor(desiredColor); 797 final long origColor = p.getColorLong(); 798 assertEquals(desiredColor, origColor); 799 800 final float origRed = Color.red(origColor); 801 final float origGreen = Color.green(origColor); 802 final float origBlue = Color.blue(origColor); 803 804 // There is a slight difference in the packed color. 805 assertEquals(red, Color.red(origColor), 0.002f); 806 assertEquals(green, Color.green(origColor), 0.002f); 807 assertEquals(blue, Color.blue(origColor), 0.002f); 808 809 for (int alpha = 0; alpha <= 255; ++alpha) { 810 p.setAlpha(alpha); 811 assertEquals(alpha, p.getAlpha()); 812 813 final long color = p.getColorLong(); 814 assertEquals(origRed, Color.red(color), 0.0f); 815 assertEquals(origGreen, Color.green(color), 0.0f); 816 assertEquals(origBlue, Color.blue(color), 0.0f); 817 } 818 } 819 } 820 821 private void testIsFilterBitmap(Paint orig) { 822 Paint p = new Paint(orig); 823 assertEquals(orig.isFilterBitmap(), p.isFilterBitmap()); 824 825 p = new Paint(); 826 p.set(orig); 827 assertEquals(orig.isFilterBitmap(), p.isFilterBitmap()); 828 } 829 830 @Test 831 public void testSetFilterBitmap() { 832 Paint p = new Paint(); 833 assertTrue(p.isFilterBitmap()); 834 testIsFilterBitmap(p); 835 836 p.setFilterBitmap(true); 837 assertTrue(p.isFilterBitmap()); 838 839 p.setFilterBitmap(false); 840 assertFalse(p.isFilterBitmap()); 841 testIsFilterBitmap(p); 842 843 p.reset(); 844 assertTrue(p.isFilterBitmap()); 845 846 p.setFilterBitmap(false); 847 assertFalse(p.isFilterBitmap()); 848 849 p.setFlags(Paint.FILTER_BITMAP_FLAG); 850 assertTrue(p.isFilterBitmap()); 851 852 p.setFlags(~Paint.FILTER_BITMAP_FLAG); 853 assertFalse(p.isFilterBitmap()); 854 } 855 856 @Test 857 public void testAccessColor() { 858 Paint p = new Paint(); 859 860 p.setColor(1); 861 assertEquals(1, p.getColor()); 862 863 p.setColor(0); 864 assertEquals(0, p.getColor()); 865 866 p.setColor(255); 867 assertEquals(255, p.getColor()); 868 869 p.setColor(-1); 870 assertEquals(-1, p.getColor()); 871 872 p.setColor(256); 873 assertEquals(256, p.getColor()); 874 } 875 876 @Test 877 public void testSetGetShadowLayer() { 878 Paint paint = new Paint(); 879 paint.setShadowLayer(10, 1, 1, 0); 880 assertEquals(10, paint.getShadowLayerRadius(), 0.0f); 881 assertEquals(1, paint.getShadowLayerDx(), 0.0f); 882 assertEquals(1, paint.getShadowLayerDy(), 0.0f); 883 assertEquals(0, paint.getShadowLayerColor()); 884 } 885 886 @Test 887 public void testGetFontMetrics1() { 888 Paint p = new Paint(); 889 Paint.FontMetrics fm = new Paint.FontMetrics(); 890 891 for (Typeface typeface : TYPEFACES) { 892 p.setTypeface(typeface); 893 894 p.setTextSize(10); 895 p.getFontMetrics(fm); 896 assertEquals(p.ascent(), fm.ascent, 0.0f); 897 assertEquals(p.descent(), fm.descent, 0.0f); 898 899 p.setTextSize(20); 900 p.getFontMetrics(fm); 901 assertEquals(p.ascent(), fm.ascent, 0.0f); 902 assertEquals(p.descent(), fm.descent, 0.0f); 903 } 904 } 905 906 @Test 907 public void testGetFontMetrics2() { 908 Paint p = new Paint(); 909 910 for (Typeface typeface : TYPEFACES) { 911 p.setTypeface(typeface); 912 913 p.setTextSize(10); 914 Paint.FontMetrics fm = p.getFontMetrics(); 915 assertEquals(p.ascent(), fm.ascent, 0.0f); 916 assertEquals(p.descent(), fm.descent, 0.0f); 917 918 p.setTextSize(20); 919 fm = p.getFontMetrics(); 920 assertEquals(p.ascent(), fm.ascent, 0.0f); 921 assertEquals(p.descent(), fm.descent, 0.0f); 922 } 923 } 924 925 @Test 926 public void testAccessStrokeMiter() { 927 Paint p = new Paint(); 928 929 p.setStrokeMiter(0.0f); 930 assertEquals(0.0f, p.getStrokeMiter(), 0.0f); 931 932 p.setStrokeMiter(10.0f); 933 assertEquals(10.0f, p.getStrokeMiter(), 0.0f); 934 935 // set value should be greater or equal to 0, set to -10.0f has no effect 936 p.setStrokeMiter(-10.0f); 937 assertEquals(10.0f, p.getStrokeMiter(), 0.0f); 938 } 939 940 @Test 941 public void testClearShadowLayer() { 942 new Paint().clearShadowLayer(); 943 } 944 945 @Test 946 public void testSetUnderlineText() { 947 Paint p = new Paint(); 948 949 p.setUnderlineText(true); 950 assertTrue(p.isUnderlineText()); 951 952 p.setUnderlineText(false); 953 assertFalse(p.isUnderlineText()); 954 } 955 956 @Test 957 public void testSetDither() { 958 Paint p = new Paint(); 959 960 p.setDither(false); 961 assertFalse(p.isDither()); 962 963 p.setDither(true); 964 assertTrue(p.isDither()); 965 } 966 967 @Test 968 public void testDefaultDither() { 969 Paint p = new Paint(); 970 assertFalse(p.isDither()); 971 } 972 973 @Test 974 public void testDescent() { 975 Paint p = new Paint(); 976 977 for (Typeface typeface : TYPEFACES) { 978 p.setTypeface(typeface); 979 980 p.setTextSize(10); 981 float descent10 = p.descent(); 982 assertTrue(descent10 > 0); 983 984 p.setTextSize(20); 985 float descent20 = p.descent(); 986 assertTrue(descent20 > descent10); 987 } 988 } 989 990 @Test 991 public void testAccessFlags() { 992 Paint p = new Paint(); 993 994 p.setFlags(Paint.ANTI_ALIAS_FLAG); 995 assertEquals(Paint.ANTI_ALIAS_FLAG, p.getFlags()); 996 997 p.setFlags(Paint.DEV_KERN_TEXT_FLAG); 998 assertEquals(Paint.DEV_KERN_TEXT_FLAG, p.getFlags()); 999 } 1000 1001 @Test 1002 public void testAccessStrokeWidth() { 1003 Paint p = new Paint(); 1004 1005 p.setStrokeWidth(0.0f); 1006 assertEquals(0.0f, p.getStrokeWidth(), 0.0f); 1007 1008 p.setStrokeWidth(10.0f); 1009 assertEquals(10.0f, p.getStrokeWidth(), 0.0f); 1010 1011 // set value must greater or equal to 0, set -10.0f has no effect 1012 p.setStrokeWidth(-10.0f); 1013 assertEquals(10.0f, p.getStrokeWidth(), 0.0f); 1014 } 1015 1016 @Test 1017 public void testSetFontFeatureSettings() { 1018 Paint p = new Paint(); 1019 // Roboto font (system default) has "fi" ligature 1020 String text = "fi"; 1021 float[] widths = new float[text.length()]; 1022 p.getTextWidths(text, widths); 1023 assertTrue(widths[0] > 0.0f); 1024 assertEquals(0.0f, widths[1], 0.0f); 1025 1026 // Disable ligature using OpenType feature 1027 p.setFontFeatureSettings("'liga' off"); 1028 p.getTextWidths(text, widths); 1029 assertTrue(widths[0] > 0.0f); 1030 assertTrue(widths[1] > 0.0f); 1031 1032 // Re-enable ligature 1033 p.setFontFeatureSettings("'liga' on"); 1034 p.getTextWidths(text, widths); 1035 assertTrue(widths[0] > 0.0f); 1036 assertEquals(0.0f, widths[1], 0.0f); 1037 } 1038 1039 @Test 1040 public void testSetFontVariationSettings_defaultTypeface() { 1041 new Paint().setFontVariationSettings("'wght' 400"); 1042 } 1043 1044 @Test 1045 public void testSetGetFontVariationSettings() { 1046 final Paint defaultPaint = new Paint(); 1047 1048 Paint p = new Paint(); 1049 Context context = InstrumentationRegistry.getTargetContext(); 1050 Typeface typeface = Typeface.createFromAsset(context.getAssets(), 1051 "fonts/var_fonts/multiaxis.ttf"); 1052 p.setTypeface(typeface); 1053 1054 // multiaxis.ttf supports "wght", "PRIV", "PR12" axes. 1055 1056 // The default variation settings should be null. 1057 assertNull(p.getFontVariationSettings()); 1058 1059 final String[] nonEffectiveSettings = { 1060 "'slnt' 30", // unsupported tag 1061 "'BBBB' 1.0", // unsupported tag 1062 "'A ' 1.0", // unsupported tag 1063 "'PR0 ' 1.3", // unsupported tag 1064 "'WGHT' 0.7", // unsupported tag (case sensitive) 1065 "'BBBB' 1.0, 'CCCC' 2.0", // none of them are supported. 1066 }; 1067 1068 for (String notEffectiveSetting : nonEffectiveSettings) { 1069 if (!defaultPaint.setFontVariationSettings(notEffectiveSetting)) { 1070 // Test only when the system font don't support the above axes. OEMs may add 1071 // their fonts and these font may support above axes. 1072 assertFalse("Must return false for " + notEffectiveSetting, 1073 p.setFontVariationSettings(notEffectiveSetting)); 1074 assertNull("Must not change settings for " + notEffectiveSetting, 1075 p.getFontVariationSettings()); 1076 } 1077 } 1078 1079 String retainSettings = "'wght' 400"; 1080 assertTrue(p.setFontVariationSettings(retainSettings)); 1081 for (String notEffectiveSetting : nonEffectiveSettings) { 1082 assertFalse(p.setFontVariationSettings(notEffectiveSetting)); 1083 assertEquals("Must not change settings for " + notEffectiveSetting, 1084 retainSettings, p.getFontVariationSettings()); 1085 } 1086 1087 // At least one axis is supported, the settings should be applied. 1088 final String[] effectiveSettings = { 1089 "'wght' 300", // supported tag 1090 "'wght' 300, 'PRIV' 0.5", // both are supported 1091 "'PRIV' 1.0, 'BBBB' 0.4", // 'BBBB' is unsupported 1092 }; 1093 1094 for (String effectiveSetting : effectiveSettings) { 1095 assertTrue("Must return true for " + effectiveSetting, 1096 p.setFontVariationSettings(effectiveSetting)); 1097 assertEquals(effectiveSetting, p.getFontVariationSettings()); 1098 } 1099 1100 p.setFontVariationSettings(""); 1101 assertNull(p.getFontVariationSettings()); 1102 } 1103 1104 @Test 1105 public void testGetTextBounds() { 1106 Paint p = new Paint(); 1107 p.setTextSize(10); 1108 String text1 = "hello"; 1109 Rect bounds1 = new Rect(); 1110 Rect bounds2 = new Rect(); 1111 Rect bounds3 = new Rect(); 1112 p.getTextBounds(text1, 0, text1.length(), bounds1); 1113 char[] textChars1 = text1.toCharArray(); 1114 p.getTextBounds(textChars1, 0, textChars1.length, bounds2); 1115 CharSequence charSequence1 = new StringBuilder(text1); 1116 p.getTextBounds(charSequence1, 0, textChars1.length, bounds3); 1117 // verify that string and char array methods produce consistent results 1118 assertEquals(bounds1, bounds2); 1119 assertEquals(bounds2, bounds3); 1120 String text2 = "hello world"; 1121 1122 // verify substring produces consistent results 1123 p.getTextBounds(text2, 0, text1.length(), bounds2); 1124 assertEquals(bounds1, bounds2); 1125 1126 // longer string is expected to have same left edge but be wider 1127 p.getTextBounds(text2, 0, text2.length(), bounds2); 1128 assertEquals(bounds1.left, bounds2.left); 1129 assertTrue(bounds2.right > bounds1.right); 1130 1131 // bigger size implies bigger bounding rect 1132 p.setTextSize(20); 1133 p.getTextBounds(text1, 0, text1.length(), bounds2); 1134 assertTrue(bounds2.right > bounds1.right); 1135 assertTrue(bounds2.bottom - bounds2.top > bounds1.bottom - bounds1.top); 1136 } 1137 1138 @Test testReset()1139 public void testReset() { 1140 Paint p = new Paint(); 1141 ColorFilter c = new ColorFilter(); 1142 MaskFilter m = new MaskFilter(); 1143 PathEffect e = new PathEffect(); 1144 Shader s = new Shader(); 1145 Typeface t = Typeface.DEFAULT; 1146 Xfermode x = new Xfermode(); 1147 1148 p.setColorFilter(c); 1149 p.setMaskFilter(m); 1150 p.setPathEffect(e); 1151 p.setShader(s); 1152 p.setTypeface(t); 1153 p.setXfermode(x); 1154 p.setFlags(Paint.ANTI_ALIAS_FLAG); 1155 assertEquals(c, p.getColorFilter()); 1156 assertEquals(m, p.getMaskFilter()); 1157 assertEquals(e, p.getPathEffect()); 1158 assertEquals(s, p.getShader()); 1159 assertEquals(t, p.getTypeface()); 1160 assertEquals(x, p.getXfermode()); 1161 assertEquals(Paint.ANTI_ALIAS_FLAG, p.getFlags()); 1162 1163 p.reset(); 1164 assertEquals(Paint.FILTER_BITMAP_FLAG | Paint.DEV_KERN_TEXT_FLAG 1165 | Paint.EMBEDDED_BITMAP_TEXT_FLAG | Paint.ANTI_ALIAS_FLAG, 1166 p.getFlags()); 1167 assertEquals(null, p.getColorFilter()); 1168 assertEquals(null, p.getMaskFilter()); 1169 assertEquals(null, p.getPathEffect()); 1170 assertEquals(null, p.getShader()); 1171 assertEquals(null, p.getTypeface()); 1172 assertEquals(null, p.getXfermode()); 1173 } 1174 1175 @Test testSetLinearText()1176 public void testSetLinearText() { 1177 Paint p = new Paint(); 1178 1179 p.setLinearText(true); 1180 assertTrue(p.isLinearText()); 1181 1182 p.setLinearText(false); 1183 assertFalse(p.isLinearText()); 1184 } 1185 1186 @Test testGetFontMetricsInt1()1187 public void testGetFontMetricsInt1() { 1188 Paint p = new Paint(); 1189 Paint.FontMetricsInt fmi = new Paint.FontMetricsInt(); 1190 1191 for (Typeface typeface : TYPEFACES) { 1192 p.setTypeface(typeface); 1193 1194 p.setTextSize(10); 1195 p.getFontMetricsInt(fmi); 1196 assertEquals(Math.round(p.ascent()), fmi.ascent); 1197 assertEquals(Math.round(p.descent()), fmi.descent); 1198 1199 p.setTextSize(20); 1200 p.getFontMetricsInt(fmi); 1201 assertEquals(Math.round(p.ascent()), fmi.ascent); 1202 assertEquals(Math.round(p.descent()), fmi.descent); 1203 } 1204 } 1205 1206 @Test testGetFontMetricsInt2()1207 public void testGetFontMetricsInt2() { 1208 Paint p = new Paint(); 1209 Paint.FontMetricsInt fmi; 1210 1211 for (Typeface typeface : TYPEFACES) { 1212 p.setTypeface(typeface); 1213 1214 p.setTextSize(10); 1215 fmi = p.getFontMetricsInt(); 1216 assertEquals(Math.round(p.ascent()), fmi.ascent); 1217 assertEquals(Math.round(p.descent()), fmi.descent); 1218 1219 p.setTextSize(20); 1220 fmi = p.getFontMetricsInt(); 1221 assertEquals(Math.round(p.ascent()), fmi.ascent); 1222 assertEquals(Math.round(p.descent()), fmi.descent); 1223 } 1224 } 1225 1226 @Test testMeasureText()1227 public void testMeasureText() { 1228 String text = "HIJKLMN"; 1229 char[] textChars = text.toCharArray(); 1230 SpannedString textSpan = new SpannedString(text); 1231 1232 Paint p = new Paint(); 1233 1234 // We need to turn off kerning in order to get accurate comparisons 1235 p.setFlags(p.getFlags() & ~Paint.DEV_KERN_TEXT_FLAG); 1236 1237 float[] widths = new float[text.length()]; 1238 for (int i = 0; i < widths.length; i++) { 1239 widths[i] = p.measureText(text, i, i + 1); 1240 } 1241 1242 float totalWidth = 0; 1243 for (int i = 0; i < widths.length; i++) { 1244 totalWidth += widths[i]; 1245 } 1246 1247 // Test measuring the widths of the entire text 1248 verifyMeasureText(text, textChars, textSpan, 0, 7, totalWidth); 1249 1250 // Test measuring a substring of the text 1251 verifyMeasureText(text, textChars, textSpan, 1, 3, widths[1] + widths[2]); 1252 1253 // Test measuring a substring of zero length. 1254 verifyMeasureText(text, textChars, textSpan, 3, 3, 0); 1255 1256 // Test measuring substrings from the front and back 1257 verifyMeasureText(text, textChars, textSpan, 0, 2, widths[0] + widths[1]); 1258 verifyMeasureText(text, textChars, textSpan, 4, 7, widths[4] + widths[5] + widths[6]); 1259 } 1260 1261 @Test testMeasureTextContext()1262 public void testMeasureTextContext() { 1263 Paint p = new Paint(); 1264 // Arabic LAM, which is different width depending on context 1265 String shortString = "\u0644"; 1266 String longString = "\u0644\u0644\u0644"; 1267 char[] longChars = longString.toCharArray(); 1268 SpannedString longSpanned = new SpannedString(longString); 1269 float width = p.measureText(shortString); 1270 // Verify that measurement of substring is consistent no matter what surrounds it. 1271 verifyMeasureText(longString, longChars, longSpanned, 0, 1, width); 1272 verifyMeasureText(longString, longChars, longSpanned, 1, 2, width); 1273 verifyMeasureText(longString, longChars, longSpanned, 2, 3, width); 1274 } 1275 1276 @Test testMeasureTextWithLongText()1277 public void testMeasureTextWithLongText() { 1278 final int MAX_COUNT = 65535; 1279 char[] longText = new char[MAX_COUNT]; 1280 for (int n = 0; n < MAX_COUNT; n++) { 1281 longText[n] = 'm'; 1282 } 1283 1284 Paint p = new Paint(); 1285 float width = p.measureText(longText, 0, 1); 1286 assertEquals(true, width > 0); 1287 } 1288 1289 /** Tests that all four overloads of measureText are the same and match some value. */ verifyMeasureText(String text, char[] textChars, SpannedString textSpan, int start, int end, float expectedWidth)1290 private void verifyMeasureText(String text, char[] textChars, SpannedString textSpan, 1291 int start, int end, float expectedWidth) { 1292 Paint p = new Paint(); 1293 1294 // We need to turn off kerning in order to get accurate comparisons 1295 p.setFlags(p.getFlags() & ~Paint.DEV_KERN_TEXT_FLAG); 1296 1297 int count = end - start; 1298 float[] widths = new float[] {-1, -1, -1, -1}; 1299 1300 String textSlice = text.substring(start, end); 1301 widths[0] = p.measureText(textSlice); 1302 widths[1] = p.measureText(textChars, start, count); 1303 widths[2] = p.measureText(textSpan, start, end); 1304 widths[3] = p.measureText(text, start, end); 1305 1306 // Check that the widths returned by the overloads are the same. 1307 assertEquals(widths[0], widths[1], 0.0f); 1308 assertEquals(widths[1], widths[2], 0.0f); 1309 assertEquals(widths[2], widths[3], 0.0f); 1310 assertEquals(widths[3], expectedWidth, 0.0f); 1311 } 1312 1313 @Test testGetTextPathCharArray()1314 public void testGetTextPathCharArray() { 1315 Path path = new Path(); 1316 1317 assertTrue(path.isEmpty()); 1318 new Paint().getTextPath(new char[] {'H', 'I', 'J', 'K', 'L', 'M', 'N'}, 0, 7, 0, 0, path); 1319 assertFalse(path.isEmpty()); 1320 } 1321 1322 @Test(expected=RuntimeException.class) testGetTextPathCharArrayNegativeIndex()1323 public void testGetTextPathCharArrayNegativeIndex() { 1324 new Paint().getTextPath(new char[] {'H', 'I', 'J', 'K', 'L', 'M', 'N'}, -2, 7, 0, 0, 1325 new Path()); 1326 } 1327 1328 @Test(expected=RuntimeException.class) testGetTextPathCharArrayNegativeCount()1329 public void testGetTextPathCharArrayNegativeCount() { 1330 new Paint().getTextPath(new char[] {'H', 'I', 'J', 'K', 'L', 'M', 'N'}, 0, -3, 0, 0, 1331 new Path()); 1332 } 1333 1334 @Test(expected=RuntimeException.class) testGetTextPathCharArrayCountTooHigh()1335 public void testGetTextPathCharArrayCountTooHigh() { 1336 new Paint().getTextPath(new char[] {'H', 'I', 'J', 'K', 'L', 'M', 'N'}, 3, 7, 0, 0, 1337 new Path()); 1338 } 1339 1340 @Test testGetTextPathString()1341 public void testGetTextPathString() { 1342 Path path = new Path(); 1343 1344 assertTrue(path.isEmpty()); 1345 new Paint().getTextPath("HIJKLMN", 0, 7, 0, 0, path); 1346 assertFalse(path.isEmpty()); 1347 } 1348 1349 @Test(expected=RuntimeException.class) testGetTextPathStringNegativeIndex()1350 public void testGetTextPathStringNegativeIndex() { 1351 new Paint().getTextPath("HIJKLMN", -2, 7, 0, 0, new Path()); 1352 } 1353 1354 @Test(expected=RuntimeException.class) testGetTextPathStringNegativeCount()1355 public void testGetTextPathStringNegativeCount() { 1356 new Paint().getTextPath("HIJKLMN", 0, -3, 0, 0, new Path()); 1357 } 1358 1359 @Test(expected=RuntimeException.class) testGetTextPathStringStartTooHigh()1360 public void testGetTextPathStringStartTooHigh() { 1361 new Paint().getTextPath("HIJKLMN", 7, 3, 0, 0, new Path()); 1362 } 1363 1364 @Test(expected=RuntimeException.class) testGetTextPathStringCountTooHigh()1365 public void testGetTextPathStringCountTooHigh() { 1366 new Paint().getTextPath("HIJKLMN", 3, 9, 0, 0, new Path()); 1367 } 1368 1369 @CddTest(requirement="3.8.13/C-1-2") 1370 @Test testHasGlyph()1371 public void testHasGlyph() { 1372 Paint p = new Paint(); 1373 1374 // This method tests both the logic of hasGlyph and the validity of fonts present 1375 // on the device. 1376 assertTrue(p.hasGlyph("A")); 1377 assertFalse(p.hasGlyph("\uFFFE")); // U+FFFE is guaranteed to be a noncharacter 1378 1379 // Roboto 2 (the default typeface) does have an "fi" glyph and is mandated by CDD 1380 assertTrue(p.hasGlyph("fi")); 1381 assertFalse(p.hasGlyph("ab")); // but it does not contain an "ab" glyph 1382 assertTrue(p.hasGlyph("\u02E5\u02E9")); // IPA tone mark ligature 1383 1384 // variation selectors 1385 assertFalse(p.hasGlyph("a\uFE0F")); 1386 assertFalse(p.hasGlyph("a\uDB40\uDDEF")); // UTF-16 encoding of U+E01EF 1387 assertFalse(p.hasGlyph("\u2229\uFE0F")); // base character is in mathematical symbol font 1388 // Note: U+FE0F is variation selection, unofficially reserved for emoji 1389 1390 // regional indicator symbols 1391 assertTrue(p.hasGlyph("\uD83C\uDDEF\uD83C\uDDF5")); // "JP" U+1F1EF U+1F1F5 1392 assertFalse(p.hasGlyph("\uD83C\uDDFF\uD83C\uDDFF")); // "ZZ" U+1F1FF U+1F1FF 1393 1394 // Mongolian, which is an optional font, but if present, should support FVS 1395 if (p.hasGlyph("\u182D")) { 1396 assertTrue(p.hasGlyph("\u182D\u180B")); 1397 } 1398 1399 // Emoji with variation selector support for both text and emoji presentation 1400 assertTrue(p.hasGlyph("\u231A\uFE0E")); // WATCH + VS15 1401 assertTrue(p.hasGlyph("\u231A\uFE0F")); // WATCH + VS16 1402 1403 // Unicode 7.0, 8.0, and 9.0 emoji should be supported. 1404 assertTrue(p.hasGlyph("\uD83D\uDD75")); // SLEUTH OR SPY is introduced in Unicode 7.0 1405 assertTrue(p.hasGlyph("\uD83C\uDF2E")); // TACO is introduced in Unicode 8.0 1406 assertTrue(p.hasGlyph("\uD83E\uDD33")); // SELFIE is introduced in Unicode 9.0 1407 1408 // We don't require gender-neutral emoji, but if present, results must be consistent 1409 // whether VS is present or not. 1410 assertTrue(p.hasGlyph("\uD83D\uDC69\u200D\u2695") == // WOMAN, ZWJ, STAFF OF AESCULAPIUS 1411 p.hasGlyph("\uD83D\uDC69\u200D\u2695\uFE0F")); // above + VS16 1412 } 1413 1414 @Test testGetRunAdvance()1415 public void testGetRunAdvance() { 1416 Paint p = new Paint(); 1417 { 1418 // LTR 1419 String string = "abcdef"; 1420 { 1421 final float width = p.getRunAdvance(string, 0, string.length(), 0, 1422 string.length(), false, 0); 1423 assertEquals(0.0f, width, 0.0f); 1424 } 1425 { 1426 for (int i = 0; i < string.length(); i++) { 1427 final float width = p.getRunAdvance(string, i, i + 1, 0, string.length(), 1428 false, i); 1429 assertEquals(0.0f, width, 0.0f); 1430 } 1431 } 1432 { 1433 final float widthToMid = p.getRunAdvance(string, 0, string.length(), 0, 1434 string.length(), false, string.length() / 2); 1435 final float widthToTail = p.getRunAdvance(string, 0, string.length(), 0, 1436 string.length(), false, string.length()); 1437 assertTrue(widthToMid > 0.0f); 1438 assertTrue(widthToTail > widthToMid); 1439 } 1440 { 1441 final float widthFromHead = p.getRunAdvance(string, 0, string.length(), 0, 1442 string.length(), false, string.length()); 1443 final float widthFromSecond = p.getRunAdvance(string, 1, string.length(), 0, 1444 string.length(), false, string.length()); 1445 assertTrue(widthFromHead > widthFromSecond); 1446 } 1447 { 1448 float width = 0.0f; 1449 for (int i = 0; i < string.length(); i++) { 1450 width += p.getRunAdvance(string, i, i + 1, 0, string.length(), false, i + 1); 1451 } 1452 final float totalWidth = p.getRunAdvance(string, 0, string.length(), 0, 1453 string.length(), false, string.length()); 1454 assertEquals(totalWidth, width, 1.0f); 1455 } 1456 } 1457 { 1458 // RTL 1459 String string = "\u0644\u063A\u0629 \u0639\u0631\u0628\u064A\u0629"; // Arabic 1460 { 1461 final float width = p.getRunAdvance(string, 0, string.length(), 0, 1462 string.length(), true, 0); 1463 assertEquals(0.0f, width, 0.0f); 1464 } 1465 { 1466 for (int i = 0; i < string.length(); i++) { 1467 final float width = p.getRunAdvance(string, i, i + 1, 0, string.length(), 1468 true, i); 1469 assertEquals(0.0f, width, 0.0f); 1470 } 1471 } 1472 { 1473 final float widthToMid = p.getRunAdvance(string, 0, string.length(), 0, 1474 string.length(), true, string.length() / 2); 1475 final float widthToTail = p.getRunAdvance(string, 0, string.length(), 0, 1476 string.length(), true, string.length()); 1477 assertTrue(widthToMid > 0.0f); 1478 assertTrue(widthToTail > widthToMid); 1479 } 1480 { 1481 final float widthFromHead = p.getRunAdvance(string, 0, string.length(), 0, 1482 string.length(), true, string.length()); 1483 final float widthFromSecond = p.getRunAdvance(string, 1, string.length(), 0, 1484 string.length(), true, string.length()); 1485 assertTrue(widthFromHead > widthFromSecond); 1486 } 1487 } 1488 } 1489 1490 @Test(expected=IllegalArgumentException.class) testGetRunAdvanceNullCharSequence()1491 public void testGetRunAdvanceNullCharSequence() { 1492 new Paint().getRunAdvance((CharSequence) null, 0, 0, 0, 0, false, 0); 1493 } 1494 1495 @Test(expected=IllegalArgumentException.class) testGetRunAdvanceNullCharArray()1496 public void testGetRunAdvanceNullCharArray() { 1497 new Paint().getRunAdvance((char[]) null, 0, 0, 0, 0, false, 0); 1498 } 1499 1500 @Test(expected=IndexOutOfBoundsException.class) testGetRunAdvanceTextLengthLessThenContextEnd()1501 public void testGetRunAdvanceTextLengthLessThenContextEnd() { 1502 final String string = "abcde"; 1503 1504 // text length < context end 1505 new Paint().getRunAdvance(string, 0, string.length(), 0, string.length() + 1, false, 1506 string.length()); 1507 } 1508 1509 @Test(expected=IndexOutOfBoundsException.class) testGetRunAdvanceContextEndLessThanEnd()1510 public void testGetRunAdvanceContextEndLessThanEnd() { 1511 final String string = "abcde"; 1512 1513 // context end < end 1514 new Paint().getRunAdvance(string, 0, string.length(), 0, string.length() - 1, false, 0); 1515 } 1516 1517 @Test(expected=IndexOutOfBoundsException.class) testGetRunAdvanceEndLessThanOffset()1518 public void testGetRunAdvanceEndLessThanOffset() { 1519 final String string = "abcde"; 1520 1521 // end < offset 1522 new Paint().getRunAdvance(string, 0, string.length() - 1, 0, string.length() - 1, false, 1523 string.length()); 1524 } 1525 1526 @Test(expected=IndexOutOfBoundsException.class) testGetRunAdvanceOffsetLessThanStart()1527 public void testGetRunAdvanceOffsetLessThanStart() { 1528 final String string = "abcde"; 1529 1530 // offset < start 1531 new Paint().getRunAdvance(string, 1, string.length(), 1, string.length(), false, 0); 1532 } 1533 1534 @Test(expected=IndexOutOfBoundsException.class) testGetRunAdvanceStartLessThanContextStart()1535 public void testGetRunAdvanceStartLessThanContextStart() { 1536 final String string = "abcde"; 1537 1538 // start < context start 1539 new Paint().getRunAdvance(string, 0, string.length(), 1, string.length(), false, 1); 1540 } 1541 1542 @Test(expected=IndexOutOfBoundsException.class) testGetRunAdvanceContextStartNegative()1543 public void testGetRunAdvanceContextStartNegative() { 1544 final String string = "abcde"; 1545 1546 // context start < 0 1547 new Paint().getRunAdvance(string, 0, string.length(), -1, string.length(), false, 0); 1548 } 1549 1550 @Test testGetRunAdvance_nonzeroIndex()1551 public void testGetRunAdvance_nonzeroIndex() { 1552 Paint p = new Paint(); 1553 final String text = "Android powers hundreds of millions of mobile " + 1554 "devices in more than 190 countries around the world. It's" + 1555 "the largest installed base of any mobile platform and" + 1556 "growing fast—every day another million users power up their" + 1557 "Android devices for the first time and start looking for" + 1558 "apps, games, and other digital content."; 1559 // Test offset index does not affect width. 1560 final float widthAndroidFirst = p.getRunAdvance( 1561 text, 0, 7, 0, text.length(), false, 7); 1562 final float widthAndroidSecond = p.getRunAdvance( 1563 text, 215, 222, 0, text.length(), false, 222); 1564 assertTrue(Math.abs(widthAndroidFirst - widthAndroidSecond) < 1); 1565 } 1566 1567 @Test 1568 public void testGetRunAdvance_glyphDependingContext() { 1569 Paint p = new Paint(); 1570 // Test the context change the character shape. 1571 // First character should be isolated form because the context ends at index 1. 1572 final float isolatedFormWidth = p.getRunAdvance("\u0644\u0644", 0, 1, 0, 1, true, 1); 1573 // First character should be initial form because the context ends at index 2. 1574 final float initialFormWidth = p.getRunAdvance("\u0644\u0644", 0, 1, 0, 2, true, 1); 1575 assertTrue(isolatedFormWidth > initialFormWidth); 1576 } 1577 1578 @Test testGetRunAdvance_arabic()1579 public void testGetRunAdvance_arabic() { 1580 Paint p = new Paint(); 1581 // Test total width is equals to sum of each character's width. 1582 // "What is Unicode?" in Arabic. 1583 final String text = 1584 "\u0645\u0627\u0020\u0647\u064A\u0020\u0627\u0644\u0634" + 1585 "\u0641\u0631\u0629\u0020\u0627\u0644\u0645\u0648\u062D" + 1586 "\u062F\u0629\u0020\u064A\u0648\u0646\u064A\u0643\u0648" + 1587 "\u062F\u061F"; 1588 final float totalWidth = p.getRunAdvance( 1589 text, 0, text.length(), 0, text.length(), true, text.length()); 1590 float sumOfCharactersWidth = 0; 1591 for (int i = 0; i < text.length(); i++) { 1592 sumOfCharactersWidth += p.getRunAdvance( 1593 text, i, i + 1, 0, text.length(), true, i + 1); 1594 } 1595 assertTrue(Math.abs(totalWidth - sumOfCharactersWidth) < 1); 1596 } 1597 1598 @Test 1599 public void testGetOffsetForAdvance() { 1600 Paint p = new Paint(); 1601 { 1602 // LTR 1603 String string = "abcdef"; 1604 { 1605 for (int offset = 0; offset <= string.length(); ++offset) { 1606 final float widthToOffset = p.getRunAdvance(string, 0, 1607 string.length(), 0, string.length(), false, offset); 1608 final int restoredOffset = p.getOffsetForAdvance(string, 0, 1609 string.length(), 0, string.length(), false, widthToOffset); 1610 assertEquals(offset, restoredOffset); 1611 } 1612 } 1613 { 1614 final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0, 1615 string.length(), false, -10.0f); 1616 assertEquals(0, offset); 1617 } 1618 { 1619 final float widthToEnd = p.getRunAdvance(string, 0, string.length(), 0, 1620 string.length(), true, string.length()); 1621 final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0, 1622 string.length(), true, widthToEnd + 10.0f); 1623 assertEquals(string.length(), offset); 1624 } 1625 } 1626 { 1627 // RTL 1628 String string = "\u0639\u0631\u0628\u0649"; // Arabic 1629 { 1630 for (int offset = 0; offset <= string.length(); ++offset) { 1631 final float widthToOffset = p.getRunAdvance(string, 0, 1632 string.length(), 0, string.length(), true, offset); 1633 final int restoredOffset = p.getOffsetForAdvance(string, 0, 1634 string.length(), 0, string.length(), true, widthToOffset); 1635 assertEquals(offset, restoredOffset); 1636 } 1637 } 1638 { 1639 final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0, 1640 string.length(), true, -10.0f); 1641 assertEquals(0, offset); 1642 } 1643 { 1644 final float widthToEnd = p.getRunAdvance(string, 0, string.length(), 0, 1645 string.length(), true, string.length()); 1646 final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0, 1647 string.length(), true, widthToEnd + 10.0f); 1648 assertEquals(string.length(), offset); 1649 } 1650 } 1651 } 1652 1653 @Test(expected=IllegalArgumentException.class) 1654 public void testGetOffsetForAdvanceNullCharSequence() { 1655 new Paint().getOffsetForAdvance((CharSequence) null, 0, 0, 0, 0, false, 0.0f); 1656 } 1657 1658 @Test(expected=IllegalArgumentException.class) 1659 public void testGetOffsetForAdvanceNullCharArray() { 1660 new Paint().getOffsetForAdvance((char[]) null, 0, 0, 0, 0, false, 0.0f); 1661 } 1662 1663 @Test(expected=IndexOutOfBoundsException.class) 1664 public void testGetOffsetForAdvanceContextStartNegative() { 1665 final String string = "abcde"; 1666 1667 // context start < 0 1668 new Paint().getOffsetForAdvance(string, -1, string.length(), 0, string.length(), false, 1669 0.0f); 1670 } 1671 1672 @Test(expected=IndexOutOfBoundsException.class) 1673 public void testGetOffsetForAdvanceStartLessThanContextStart() { 1674 final String string = "abcde"; 1675 1676 // start < context start 1677 new Paint().getOffsetForAdvance(string, 0, string.length(), 1, string.length(), false, 1678 0.0f); 1679 } 1680 1681 @Test(expected=IndexOutOfBoundsException.class) 1682 public void testGetOffsetForAdvanceEndLessThanStart() { 1683 final String string = "abcde"; 1684 1685 // end < start 1686 new Paint().getOffsetForAdvance(string, 1, 0, 0, 0, false, 0); 1687 } 1688 1689 @Test(expected=IndexOutOfBoundsException.class) 1690 public void testGetOffsetForAdvanceContextEndLessThanEnd() { 1691 final String string = "abcde"; 1692 1693 // context end < end 1694 new Paint().getOffsetForAdvance(string, 0, string.length(), 0, string.length() - 1, false, 1695 0.0f); 1696 } 1697 1698 @Test(expected=IndexOutOfBoundsException.class) 1699 public void testGetOffsetForAdvanceTextLengthLessThanContextEnd() { 1700 final String string = "abcde"; 1701 1702 // text length < context end 1703 new Paint().getOffsetForAdvance(string, 0, string.length(), 0, string.length() + 1, false, 1704 0.0f); 1705 } 1706 1707 @Test 1708 public void testGetOffsetForAdvance_graphemeCluster() { 1709 Paint p = new Paint(); 1710 { 1711 String string = "\uD83C\uDF37"; // U+1F337: TULIP 1712 { 1713 final float widthToOffset = p.getRunAdvance(string, 0, 1714 string.length(), 0, string.length(), false, 1); 1715 final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0, 1716 string.length(), false, widthToOffset); 1717 assertFalse(1 == offset); 1718 assertTrue(0 == offset || string.length() == offset); 1719 } 1720 } 1721 { 1722 String string = "\uD83C\uDDFA\uD83C\uDDF8"; // US flag 1723 { 1724 final float widthToOffset = p.getRunAdvance(string, 0, 1725 string.length(), 0, string.length(), false, 2); 1726 final int offset = p.getOffsetForAdvance(string, 0, string.length(), 0, 1727 string.length(), false, widthToOffset); 1728 assertFalse(2 == offset); 1729 assertTrue(0 == offset || string.length() == offset); 1730 } 1731 { 1732 final float widthToOffset = p.getRunAdvance(string, 0, 2, 0, 2, false, 2); 1733 final int offset = p.getOffsetForAdvance(string, 0, 2, 1734 0, 2, false, widthToOffset); 1735 assertEquals(2, offset); 1736 } 1737 } 1738 { 1739 // HANGUL CHOSEONG KIYEOK, HANGUL JUNGSEONG A, HANDUL JONGSEONG KIYEOK 1740 String string = "\u1100\u1161\u11A8"; 1741 { 1742 for (int offset = 0; offset <= string.length(); ++offset) { 1743 final float widthToOffset = p.getRunAdvance(string, 0, 1744 string.length(), 0, string.length(), false, offset); 1745 final int offsetForAdvance = p.getOffsetForAdvance(string, 0, string.length(), 1746 0, string.length(), false, widthToOffset); 1747 assertTrue(0 == offsetForAdvance || string.length() == offsetForAdvance); 1748 } 1749 for (int offset = 0; offset <= string.length(); ++offset) { 1750 final float widthToOffset = p.getRunAdvance(string, 0, offset, 0, offset, 1751 false, offset); 1752 final int offsetForAdvance = p.getOffsetForAdvance(string, 0, string.length(), 1753 0, string.length(), false, widthToOffset); 1754 assertTrue(0 == offsetForAdvance || string.length() == offsetForAdvance); 1755 } 1756 for (int offset = 0; offset <= string.length(); ++offset) { 1757 final float widthToOffset = p.getRunAdvance(string, 0, offset, 0, offset, 1758 false, offset); 1759 final int offsetForAdvance = p.getOffsetForAdvance(string, 0, offset, 0, 1760 offset, false, widthToOffset); 1761 assertEquals(offset, offsetForAdvance); 1762 } 1763 } 1764 } 1765 } 1766 1767 @Test 1768 public void testElegantText() { 1769 final Paint p = new Paint(); 1770 p.setTextSize(10); 1771 assertFalse(p.isElegantTextHeight()); 1772 final float nonElegantTop = p.getFontMetrics().top; 1773 final float nonElegantBottom = p.getFontMetrics().bottom; 1774 1775 p.setElegantTextHeight(true); 1776 assertTrue(p.isElegantTextHeight()); 1777 final float elegantTop = p.getFontMetrics().top; 1778 final float elegantBottom = p.getFontMetrics().bottom; 1779 1780 assertTrue(elegantTop < nonElegantTop); 1781 assertTrue(elegantBottom > nonElegantBottom); 1782 1783 p.setElegantTextHeight(false); 1784 assertFalse(p.isElegantTextHeight()); 1785 } 1786 1787 @Test 1788 public void testEqualsForTextMeasurment() { 1789 Paint p1 = new Paint(); 1790 Paint p2 = new Paint(); 1791 1792 assertTrue(p1.equalsForTextMeasurement(p2)); 1793 } 1794 1795 @Test 1796 public void testEqualsForTextMeasurment_textSize() { 1797 Paint p1 = new Paint(); 1798 Paint p2 = new Paint(); 1799 1800 p1.setTextSize(p2.getTextSize() * 2.0f); 1801 assertFalse(p1.equalsForTextMeasurement(p2)); 1802 p1.setTextSize(p2.getTextSize()); 1803 assertTrue(p1.equalsForTextMeasurement(p2)); 1804 } 1805 1806 @Test 1807 public void testEqualsForTextMeasurment_textSkew() { 1808 Paint p1 = new Paint(); 1809 Paint p2 = new Paint(); 1810 1811 p1.setTextSkewX(p2.getTextSkewX() + 2.0f); 1812 assertFalse(p1.equalsForTextMeasurement(p2)); 1813 p1.setTextSkewX(p2.getTextSkewX()); 1814 assertTrue(p1.equalsForTextMeasurement(p2)); 1815 } 1816 1817 @Test 1818 public void testEqualsForTextMeasurment_textScale() { 1819 Paint p1 = new Paint(); 1820 Paint p2 = new Paint(); 1821 1822 p1.setTextScaleX(p2.getTextScaleX() * 2.0f); 1823 assertFalse(p1.equalsForTextMeasurement(p2)); 1824 p1.setTextScaleX(p2.getTextScaleX()); 1825 assertTrue(p1.equalsForTextMeasurement(p2)); 1826 } 1827 1828 @Test 1829 public void testEqualsForTextMeasurment_letterSpacing() { 1830 Paint p1 = new Paint(); 1831 Paint p2 = new Paint(); 1832 1833 p1.setLetterSpacing(p2.getLetterSpacing() + 2.0f); 1834 assertFalse(p1.equalsForTextMeasurement(p2)); 1835 p1.setLetterSpacing(p2.getLetterSpacing()); 1836 assertTrue(p1.equalsForTextMeasurement(p2)); 1837 } 1838 1839 @Test 1840 public void testEqualsForTextMeasurment_localeList() { 1841 Paint p1 = new Paint(); 1842 Paint p2 = new Paint(); 1843 1844 LocaleList enUS = LocaleList.forLanguageTags("en-US"); 1845 LocaleList jaJP = LocaleList.forLanguageTags("ja-JP"); 1846 LocaleList differentLocale = p2.getTextLocales().equals(enUS) ? jaJP : enUS; 1847 p1.setTextLocales(differentLocale); 1848 assertFalse(p1.equalsForTextMeasurement(p2)); 1849 p1.setTextLocales(p2.getTextLocales()); 1850 assertTrue(p1.equalsForTextMeasurement(p2)); 1851 } 1852 1853 @Test 1854 public void testEqualsForTextMeasurment_typeface() { 1855 Paint p1 = new Paint(); 1856 Paint p2 = new Paint(); 1857 1858 p1.setTypeface(Typeface.DEFAULT); 1859 p2.setTypeface(Typeface.SERIF); 1860 assertFalse(p1.equalsForTextMeasurement(p2)); 1861 p1.setTypeface(p2.getTypeface()); 1862 assertTrue(p1.equalsForTextMeasurement(p2)); 1863 } 1864 1865 @Test 1866 public void testWordSpacing() { 1867 Paint p = new Paint(); 1868 assertEquals(0.0f, p.getWordSpacing(), 0.0f); // The default value is 0. 1869 p.setWordSpacing(10.0f); 1870 assertEquals(10.0f, p.getWordSpacing(), 0.0f); 1871 p.setWordSpacing(20.0f); 1872 assertEquals(20.0f, p.getWordSpacing(), 0.0f); 1873 } 1874 1875 @Test 1876 public void testStrikeThruPosition_notCrashes() { 1877 // We can't expect any values of strike-through position in CTS. 1878 // Just make sure calling that method doesn't crash the app. 1879 new Paint().getStrikeThruPosition(); 1880 } 1881 1882 @Test 1883 public void testStrikeThruThickness_notCrashes() { 1884 // We can't expect any values of strike-through thickness in CTS. 1885 // Just make sure calling that method doesn't crash the app. 1886 new Paint().getStrikeThruThickness(); 1887 } 1888 1889 @Test 1890 public void testUnderlinePosition_notCrashes() { 1891 // We can't expect any values of underline position in CTS. 1892 // Just make sure calling that method doesn't crash the app. 1893 new Paint().getUnderlinePosition(); 1894 } 1895 1896 @Test 1897 public void testUnderlineThickness_notCrashes() { 1898 // We can't expect any values of underline thickness in CTS. 1899 // Just make sure calling that method doesn't crash the app. 1900 new Paint().getUnderlineThickness(); 1901 } 1902 1903 @Test 1904 public void testSetGetHyphenEdit() { 1905 Paint paint = new Paint(); 1906 1907 // By default, no hyphen edit is specified. 1908 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, paint.getStartHyphenEdit()); 1909 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, paint.getEndHyphenEdit()); 1910 1911 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_INSERT_HYPHEN); 1912 assertEquals(Paint.START_HYPHEN_EDIT_INSERT_HYPHEN, paint.getStartHyphenEdit()); 1913 assertEquals(Paint.END_HYPHEN_EDIT_NO_EDIT, paint.getEndHyphenEdit()); 1914 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1915 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN); 1916 1917 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN); 1918 assertEquals(Paint.START_HYPHEN_EDIT_NO_EDIT, paint.getStartHyphenEdit()); 1919 assertEquals(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN, paint.getEndHyphenEdit()); 1920 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1921 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN); 1922 1923 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_INSERT_HYPHEN); 1924 assertEquals(Paint.START_HYPHEN_EDIT_INSERT_HYPHEN, paint.getStartHyphenEdit()); 1925 assertEquals(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN, paint.getEndHyphenEdit()); 1926 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1927 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN); 1928 } 1929 1930 @Test 1931 public void testHyphenEdit() { 1932 final Paint paint = new Paint(); 1933 final Context context = InstrumentationRegistry.getTargetContext(); 1934 // The hyphenation.ttf font supports following characters 1935 // - U+0061..U+007A (a..z): The glyph has 1em width. 1936 // - U+2010 (HYPHEN): The glyph has 2em width. 1937 // - U+058A (ARMENIAN HYPHEN): The glyph has 3em width. 1938 // - U+05BE (MAQAF): The glyph has 4em width. 1939 // - U+1400 (UCAS HYPHEN): The glyph has 5em width. 1940 paint.setTypeface(Typeface.createFromAsset(context.getAssets(), 1941 "fonts/layout/hyphenation.ttf")); 1942 paint.setTextSize(10.0f); // Make 1em = 10px 1943 1944 assertEquals(30.0f, paint.measureText("abc", 0, 3), 0.0f); 1945 1946 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1947 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN); 1948 assertEquals(50.0f, paint.measureText("abc", 0, 3), 0.0f); // "abc-" in visual. 1949 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1950 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_NO_EDIT); 1951 1952 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_INSERT_HYPHEN); 1953 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_HYPHEN); 1954 assertEquals(70.0f, paint.measureText("abc", 0, 3), 0.0f); // "-abc-" in visual. 1955 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1956 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_NO_EDIT); 1957 1958 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1959 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_ARMENIAN_HYPHEN); 1960 assertEquals(60.0f, paint.measureText("abc", 0, 3), 0.0f); // "abcU+058A" in visual. 1961 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1962 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_NO_EDIT); 1963 1964 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1965 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_MAQAF); 1966 assertEquals(70.0f, paint.measureText("abc", 0, 3), 0.0f); // "abcU+05BE" in visual. 1967 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1968 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_NO_EDIT); 1969 1970 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1971 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_UCAS_HYPHEN); 1972 assertEquals(80.0f, paint.measureText("abc", 0, 3), 0.0f); // "abcU+1400" in visual. 1973 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1974 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_NO_EDIT); 1975 1976 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1977 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_INSERT_ZWJ_AND_HYPHEN); 1978 // "abcU+200D-" in visual. Note that ZWJ is zero width. 1979 assertEquals(50.0f, paint.measureText("abc", 0, 3), 0.0f); 1980 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1981 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_NO_EDIT); 1982 1983 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1984 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_REPLACE_WITH_HYPHEN); 1985 assertEquals(40.0f, paint.measureText("abc", 0, 3), 0.0f); // "ab-" in visual. 1986 paint.setStartHyphenEdit(Paint.START_HYPHEN_EDIT_NO_EDIT); 1987 paint.setEndHyphenEdit(Paint.END_HYPHEN_EDIT_NO_EDIT); 1988 } 1989 1990 @Test 1991 public void testGetTextRunAdvances() { 1992 final Paint paint = new Paint(); 1993 final Context context = InstrumentationRegistry.getTargetContext(); 1994 paint.setTypeface(Typeface.createFromAsset(context.getAssets(), 1995 "fonts/layout/textrunadvances.ttf")); 1996 // The textrunadvances.ttf font supports following characters 1997 // - U+0061 (a): The glyph has 3em width. 1998 // - U+0062..U+0065 (b..e): The glyph has 1em width. 1999 // - U+1F600 (GRINNING FACE): The glyph has 3em width. 2000 paint.setTextSize(10.0f); // Make 1em = 10px 2001 2002 final char[] chars = { 'a', 'b', 'a', 'b' }; 2003 final float[] buffer = new float[32]; 2004 2005 assertEquals(80.0f, 2006 paint.getTextRunAdvances(chars, 0, 4, 0, 4, false /* isRtl */, buffer, 0), 0.0f); 2007 assertEquals(30.0f, buffer[0], 0.0f); 2008 assertEquals(10.0f, buffer[1], 0.0f); 2009 assertEquals(30.0f, buffer[2], 0.0f); 2010 assertEquals(10.0f, buffer[3], 0.0f); 2011 2012 // Output offset test 2013 assertEquals(40.0f, 2014 paint.getTextRunAdvances(chars, 1, 2, 1, 2, false /* isRtl */, buffer, 5), 0.0f); 2015 assertEquals(10.0f, buffer[5], 0.0f); 2016 assertEquals(30.0f, buffer[6], 0.0f); 2017 2018 // Surrogate pairs 2019 final char[] chars2 = Character.toChars(0x1F600); 2020 assertEquals(30.0f, 2021 paint.getTextRunAdvances(chars2, 0, 2, 0, 2, false /* isRtl */, buffer, 0), 0.0f); 2022 assertEquals(30.0f, buffer[0], 0.0f); 2023 assertEquals(0.0f, buffer[1], 0.0f); 2024 } 2025 2026 private int getTextRunCursor(String text, int offset, int cursorOpt) { 2027 final int contextStart = 0; 2028 final int contextEnd = text.length(); 2029 final int contextCount = text.length(); 2030 Paint p = new Paint(); 2031 int result = p.getTextRunCursor(new StringBuilder(text), // as a CharSequence 2032 contextStart, contextEnd, false /* isRtl */, offset, cursorOpt); 2033 assertEquals(result, p.getTextRunCursor(text.toCharArray(), 2034 contextStart, contextCount, false /* isRtl */, offset, cursorOpt)); 2035 assertEquals(result, p.getTextRunCursor(new StringBuilder(text), // as a CharSequence 2036 contextStart, contextCount, true /* isRtl */, offset, cursorOpt)); 2037 assertEquals(result, p.getTextRunCursor(text.toCharArray(), 2038 contextStart, contextCount, true, offset, cursorOpt)); 2039 return result; 2040 } 2041 2042 @Test 2043 public void testGetRunCursor_CURSOR_AFTER() { 2044 assertEquals(1, getTextRunCursor("abc", 0, CURSOR_AFTER)); 2045 assertEquals(2, getTextRunCursor("abc", 1, CURSOR_AFTER)); 2046 assertEquals(3, getTextRunCursor("abc", 2, CURSOR_AFTER)); 2047 assertEquals(3, getTextRunCursor("abc", 3, CURSOR_AFTER)); 2048 2049 // Surrogate pairs 2050 assertEquals(1, getTextRunCursor("a\uD83D\uDE00c", 0, CURSOR_AFTER)); 2051 assertEquals(3, getTextRunCursor("a\uD83D\uDE00c", 1, CURSOR_AFTER)); 2052 assertEquals(3, getTextRunCursor("a\uD83D\uDE00c", 2, CURSOR_AFTER)); 2053 assertEquals(4, getTextRunCursor("a\uD83D\uDE00c", 3, CURSOR_AFTER)); 2054 assertEquals(4, getTextRunCursor("a\uD83D\uDE00c", 4, CURSOR_AFTER)); 2055 2056 // Combining marks 2057 assertEquals(1, getTextRunCursor("a\u0061\u0302c", 0, CURSOR_AFTER)); 2058 assertEquals(3, getTextRunCursor("a\u0061\u0302c", 1, CURSOR_AFTER)); 2059 assertEquals(3, getTextRunCursor("a\u0061\u0302c", 2, CURSOR_AFTER)); 2060 assertEquals(4, getTextRunCursor("a\u0061\u0302c", 3, CURSOR_AFTER)); 2061 assertEquals(4, getTextRunCursor("a\u0061\u0302c", 4, CURSOR_AFTER)); 2062 } 2063 2064 @Test 2065 public void testGetRunCursor_CURSOR_AT() { 2066 assertEquals(0, getTextRunCursor("abc", 0, CURSOR_AT)); 2067 assertEquals(1, getTextRunCursor("abc", 1, CURSOR_AT)); 2068 assertEquals(2, getTextRunCursor("abc", 2, CURSOR_AT)); 2069 assertEquals(3, getTextRunCursor("abc", 3, CURSOR_AT)); 2070 2071 // Surrogate pairs 2072 assertEquals(0, getTextRunCursor("a\uD83D\uDE00c", 0, CURSOR_AT)); 2073 assertEquals(1, getTextRunCursor("a\uD83D\uDE00c", 1, CURSOR_AT)); 2074 assertEquals(-1, getTextRunCursor("a\uD83D\uDE00c", 2, CURSOR_AT)); 2075 assertEquals(3, getTextRunCursor("a\uD83D\uDE00c", 3, CURSOR_AT)); 2076 assertEquals(4, getTextRunCursor("a\uD83D\uDE00c", 4, CURSOR_AT)); 2077 2078 // Combining marks 2079 assertEquals(0, getTextRunCursor("a\u0061\u0302c", 0, CURSOR_AT)); 2080 assertEquals(1, getTextRunCursor("a\u0061\u0302c", 1, CURSOR_AT)); 2081 assertEquals(-1, getTextRunCursor("a\u0061\u0302c", 2, CURSOR_AT)); 2082 assertEquals(3, getTextRunCursor("a\u0061\u0302c", 3, CURSOR_AT)); 2083 assertEquals(4, getTextRunCursor("a\u0061\u0302c", 4, CURSOR_AT)); 2084 } 2085 2086 @Test 2087 public void testGetRunCursor_CURSOR_AT_OR_AFTER() { 2088 assertEquals(0, getTextRunCursor("abc", 0, CURSOR_AT_OR_AFTER)); 2089 assertEquals(1, getTextRunCursor("abc", 1, CURSOR_AT_OR_AFTER)); 2090 assertEquals(2, getTextRunCursor("abc", 2, CURSOR_AT_OR_AFTER)); 2091 assertEquals(3, getTextRunCursor("abc", 3, CURSOR_AT_OR_AFTER)); 2092 2093 // Surrogate pairs 2094 assertEquals(0, getTextRunCursor("a\uD83D\uDE00c", 0, CURSOR_AT_OR_AFTER)); 2095 assertEquals(1, getTextRunCursor("a\uD83D\uDE00c", 1, CURSOR_AT_OR_AFTER)); 2096 assertEquals(3, getTextRunCursor("a\uD83D\uDE00c", 2, CURSOR_AT_OR_AFTER)); 2097 assertEquals(3, getTextRunCursor("a\uD83D\uDE00c", 3, CURSOR_AT_OR_AFTER)); 2098 assertEquals(4, getTextRunCursor("a\uD83D\uDE00c", 4, CURSOR_AT_OR_AFTER)); 2099 2100 // Combining marks 2101 assertEquals(0, getTextRunCursor("a\u0061\u0302c", 0, CURSOR_AT_OR_AFTER)); 2102 assertEquals(1, getTextRunCursor("a\u0061\u0302c", 1, CURSOR_AT_OR_AFTER)); 2103 assertEquals(3, getTextRunCursor("a\u0061\u0302c", 2, CURSOR_AT_OR_AFTER)); 2104 assertEquals(3, getTextRunCursor("a\u0061\u0302c", 3, CURSOR_AT_OR_AFTER)); 2105 assertEquals(4, getTextRunCursor("a\u0061\u0302c", 4, CURSOR_AT_OR_AFTER)); 2106 } 2107 2108 @Test 2109 public void testGetRunCursor_CURSOR_AT_OR_BEFORE() { 2110 assertEquals(0, getTextRunCursor("abc", 0, CURSOR_AT_OR_BEFORE)); 2111 assertEquals(1, getTextRunCursor("abc", 1, CURSOR_AT_OR_BEFORE)); 2112 assertEquals(2, getTextRunCursor("abc", 2, CURSOR_AT_OR_BEFORE)); 2113 assertEquals(3, getTextRunCursor("abc", 3, CURSOR_AT_OR_BEFORE)); 2114 2115 // Surrogate pairs 2116 assertEquals(0, getTextRunCursor("a\uD83D\uDE00c", 0, CURSOR_AT_OR_BEFORE)); 2117 assertEquals(1, getTextRunCursor("a\uD83D\uDE00c", 1, CURSOR_AT_OR_BEFORE)); 2118 assertEquals(1, getTextRunCursor("a\uD83D\uDE00c", 2, CURSOR_AT_OR_BEFORE)); 2119 assertEquals(3, getTextRunCursor("a\uD83D\uDE00c", 3, CURSOR_AT_OR_BEFORE)); 2120 assertEquals(4, getTextRunCursor("a\uD83D\uDE00c", 4, CURSOR_AT_OR_BEFORE)); 2121 2122 // Combining marks 2123 assertEquals(0, getTextRunCursor("a\u0061\u0302c", 0, CURSOR_AT_OR_BEFORE)); 2124 assertEquals(1, getTextRunCursor("a\u0061\u0302c", 1, CURSOR_AT_OR_BEFORE)); 2125 assertEquals(1, getTextRunCursor("a\u0061\u0302c", 2, CURSOR_AT_OR_BEFORE)); 2126 assertEquals(3, getTextRunCursor("a\u0061\u0302c", 3, CURSOR_AT_OR_BEFORE)); 2127 assertEquals(4, getTextRunCursor("a\u0061\u0302c", 4, CURSOR_AT_OR_BEFORE)); 2128 } 2129 2130 @Test 2131 public void testGetRunCursor_CURSOR_BEFORE() { 2132 assertEquals(0, getTextRunCursor("abc", 0, CURSOR_BEFORE)); 2133 assertEquals(0, getTextRunCursor("abc", 1, CURSOR_BEFORE)); 2134 assertEquals(1, getTextRunCursor("abc", 2, CURSOR_BEFORE)); 2135 assertEquals(2, getTextRunCursor("abc", 3, CURSOR_BEFORE)); 2136 2137 // Surrogate pairs 2138 assertEquals(0, getTextRunCursor("a\uD83D\uDE00c", 0, CURSOR_BEFORE)); 2139 assertEquals(0, getTextRunCursor("a\uD83D\uDE00c", 1, CURSOR_BEFORE)); 2140 assertEquals(1, getTextRunCursor("a\uD83D\uDE00c", 2, CURSOR_BEFORE)); 2141 assertEquals(1, getTextRunCursor("a\uD83D\uDE00c", 3, CURSOR_BEFORE)); 2142 assertEquals(3, getTextRunCursor("a\uD83D\uDE00c", 4, CURSOR_BEFORE)); 2143 2144 // Combining marks 2145 assertEquals(0, getTextRunCursor("a\u0061\u0302c", 0, CURSOR_BEFORE)); 2146 assertEquals(0, getTextRunCursor("a\u0061\u0302c", 1, CURSOR_BEFORE)); 2147 assertEquals(1, getTextRunCursor("a\u0061\u0302c", 2, CURSOR_BEFORE)); 2148 assertEquals(1, getTextRunCursor("a\u0061\u0302c", 3, CURSOR_BEFORE)); 2149 assertEquals(3, getTextRunCursor("a\u0061\u0302c", 4, CURSOR_BEFORE)); 2150 } 2151 2152 @Test 2153 public void testGetBlendModeFromPorterDuffMode() { 2154 Paint p = new Paint(); 2155 PorterDuff.Mode[] porterDuffModes = PorterDuff.Mode.values(); 2156 for (PorterDuff.Mode mode : porterDuffModes) { 2157 p.setXfermode(new PorterDuffXfermode(mode)); 2158 assertEquals(getBlendModeFromPorterDuffMode(mode), p.getBlendMode()); 2159 } 2160 2161 } 2162 2163 private BlendMode getBlendModeFromPorterDuffMode(PorterDuff.Mode mode) { 2164 switch (mode) { 2165 case CLEAR: return BlendMode.CLEAR; 2166 case SRC: return BlendMode.SRC; 2167 case DST: return BlendMode.DST; 2168 case SRC_OVER: return BlendMode.SRC_OVER; 2169 case DST_OVER: return BlendMode.DST_OVER; 2170 case SRC_IN: return BlendMode.SRC_IN; 2171 case DST_IN: return BlendMode.DST_IN; 2172 case SRC_OUT: return BlendMode.SRC_OUT; 2173 case DST_OUT: return BlendMode.DST_OUT; 2174 case SRC_ATOP: return BlendMode.SRC_ATOP; 2175 case DST_ATOP: return BlendMode.DST_ATOP; 2176 case XOR: return BlendMode.XOR; 2177 case DARKEN: return BlendMode.DARKEN; 2178 case LIGHTEN: return BlendMode.LIGHTEN; 2179 // The odd one out, see b/73224934. PorterDuff.Mode.MULTIPLY was improperly mapped 2180 // to Skia's modulate 2181 case MULTIPLY: return BlendMode.MODULATE; 2182 case SCREEN: return BlendMode.SCREEN; 2183 case ADD: return BlendMode.PLUS; 2184 case OVERLAY: return BlendMode.OVERLAY; 2185 default: throw new IllegalArgumentException("Unknown PorterDuffmode: " + mode); 2186 } 2187 } 2188 2189 private void testColorLongs(String methodName, BiConsumer<Paint, Long> setColor, 2190 Function<Paint, Integer> getColor, 2191 Function<Paint, Long> getColorLong) { 2192 // Pack SRGB colors into ColorLongs 2193 for (int color : new int[]{ Color.RED, Color.BLUE, Color.GREEN, Color.BLACK, 2194 Color.WHITE, Color.TRANSPARENT }) { 2195 final Paint p = new Paint(); 2196 final long longColor = Color.pack(color); 2197 setColor.accept(p, longColor); 2198 2199 assertEquals(color, getColor.apply(p).intValue()); 2200 assertEquals(longColor, getColorLong.apply(p).longValue()); 2201 } 2202 2203 // Arbitrary colors in various ColorSpaces 2204 for (int srgbColor : new int[]{ Color.argb(1.0f, .5f, .5f, .5f), 2205 Color.argb(1.0f, .3f, .6f, .9f), 2206 Color.argb(0.5f, .2f, .8f, .7f) }) { 2207 for (ColorSpace.Named e : ColorSpace.Named.values()) { 2208 ColorSpace cs = ColorSpace.get(e); 2209 if (cs.getModel() != ColorSpace.Model.RGB) { 2210 continue; 2211 } 2212 if (((ColorSpace.Rgb) cs).getTransferParameters() == null) { 2213 continue; 2214 } 2215 2216 final long longColor = Color.convert(srgbColor, cs); 2217 Paint p = new Paint(); 2218 setColor.accept(p, longColor); 2219 assertEquals(longColor, getColorLong.apply(p).longValue()); 2220 2221 // These tolerances were chosen by trial and error. It is expected that 2222 // some conversions do not round-trip perfectly. 2223 int tolerance = 0; 2224 if (cs.equals(ColorSpace.get(ColorSpace.Named.SMPTE_C))) { 2225 tolerance = 2; 2226 } 2227 int color = getColor.apply(p); 2228 ColorUtils.verifyColor("Paint#" + methodName + " mismatch for " + cs, srgbColor, 2229 color, tolerance); 2230 } 2231 } 2232 } 2233 2234 @Test 2235 public void testSetColorLong() { 2236 testColorLongs("setColor", (p, c) -> p.setColor(c), (p) -> p.getColor(), 2237 (p) -> p.getColorLong()); 2238 } 2239 2240 @Test(expected = IllegalArgumentException.class) 2241 public void testSetColorXYZ() { 2242 Paint p = new Paint(); 2243 p.setColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ))); 2244 } 2245 2246 @Test(expected = IllegalArgumentException.class) 2247 public void testSetColorLAB() { 2248 Paint p = new Paint(); 2249 p.setColor(Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB))); 2250 } 2251 2252 @Test(expected = IllegalArgumentException.class) 2253 public void testSetColorUnknown() { 2254 Paint p = new Paint(); 2255 p.setColor(-1L); 2256 } 2257 2258 @Test 2259 public void testSetShadowLayerLong() { 2260 testColorLongs("setShadowLayer", (p, c) -> p.setShadowLayer(10.0f, 1.0f, 1.0f, c), 2261 (p) -> p.getShadowLayerColor(), (p) -> p.getShadowLayerColorLong()); 2262 } 2263 2264 @Test(expected = IllegalArgumentException.class) testSetShadowLayerXYZ()2265 public void testSetShadowLayerXYZ() { 2266 Paint p = new Paint(); 2267 p.setShadowLayer(10.0f, 1.0f, 1.0f, 2268 Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_XYZ))); 2269 } 2270 2271 @Test(expected = IllegalArgumentException.class) testSetShadowLayerLAB()2272 public void testSetShadowLayerLAB() { 2273 Paint p = new Paint(); 2274 p.setShadowLayer(10.0f, 1.0f, 1.0f, 2275 Color.convert(Color.BLUE, ColorSpace.get(ColorSpace.Named.CIE_LAB))); 2276 } 2277 2278 @Test(expected = IllegalArgumentException.class) testSetShadowLayerUnknown()2279 public void testSetShadowLayerUnknown() { 2280 Paint p = new Paint(); 2281 p.setShadowLayer(10.0f, 1.0f, 1.0f, -1L); 2282 } 2283 } 2284