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 package android.graphics.cts; 17 18 import static org.junit.Assert.assertArrayEquals; 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNull; 22 import static org.junit.Assert.assertTrue; 23 24 import android.content.res.Resources; 25 import android.graphics.Bitmap; 26 import android.graphics.Bitmap.Config; 27 import android.graphics.BitmapFactory; 28 import android.graphics.BitmapShader; 29 import android.graphics.Canvas; 30 import android.graphics.Canvas.EdgeType; 31 import android.graphics.Canvas.VertexMode; 32 import android.graphics.Color; 33 import android.graphics.ComposeShader; 34 import android.graphics.DrawFilter; 35 import android.graphics.Matrix; 36 import android.graphics.Paint; 37 import android.graphics.Path; 38 import android.graphics.Path.Direction; 39 import android.graphics.Picture; 40 import android.graphics.PorterDuff.Mode; 41 import android.graphics.RadialGradient; 42 import android.graphics.Rect; 43 import android.graphics.RectF; 44 import android.graphics.Region.Op; 45 import android.graphics.Shader; 46 import android.support.test.InstrumentationRegistry; 47 import android.support.test.filters.SmallTest; 48 import android.support.test.runner.AndroidJUnit4; 49 import android.text.SpannableString; 50 import android.text.SpannableStringBuilder; 51 import android.text.SpannedString; 52 import android.util.DisplayMetrics; 53 54 import com.android.compatibility.common.util.ColorUtils; 55 56 import java.io.IOException; 57 import java.io.InputStream; 58 import java.util.Vector; 59 60 import org.junit.Assert; 61 import org.junit.Before; 62 import org.junit.Test; 63 import org.junit.runner.RunWith; 64 65 @SmallTest 66 @RunWith(AndroidJUnit4.class) 67 public class CanvasTest { 68 private final static int PAINT_COLOR = 0xff00ff00; 69 private final static int BITMAP_WIDTH = 10; 70 private final static int BITMAP_HEIGHT = 28; 71 private final static int FLOAT_ARRAY_LEN = 9; 72 73 // used for save related methods tests 74 private final float[] values1 = { 75 1, 2, 3, 4, 5, 6, 7, 8, 9 76 }; 77 78 private final float[] values2 = { 79 9, 8, 7, 6, 5, 4, 3, 2, 1 80 }; 81 82 private Paint mPaint; 83 private Canvas mCanvas; 84 private Bitmap mImmutableBitmap; 85 private Bitmap mMutableBitmap; 86 87 @Before 88 public void setup() { 89 mPaint = new Paint(); 90 mPaint.setColor(PAINT_COLOR); 91 92 final Resources res = InstrumentationRegistry.getTargetContext().getResources(); 93 BitmapFactory.Options opt = new BitmapFactory.Options(); 94 opt.inScaled = false; // bitmap will only be immutable if not scaled during load 95 mImmutableBitmap = BitmapFactory.decodeResource(res, R.drawable.start, opt); 96 assertFalse(mImmutableBitmap.isMutable()); 97 mMutableBitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888); 98 mCanvas = new Canvas(mMutableBitmap); 99 } 100 101 @Test 102 public void testCanvas() { 103 new Canvas(); 104 105 mMutableBitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Config.ARGB_8888); 106 new Canvas(mMutableBitmap); 107 } 108 109 @Test(expected=IllegalStateException.class) 110 public void testCanvasFromImmutableBitmap() { 111 // Should throw out IllegalStateException when creating Canvas with an ImmutableBitmap 112 new Canvas(mImmutableBitmap); 113 } 114 115 @Test(expected=RuntimeException.class) 116 public void testCanvasFromRecycledBitmap() { 117 // Should throw out RuntimeException when creating Canvas with a MutableBitmap which 118 // is recycled 119 mMutableBitmap.recycle(); 120 new Canvas(mMutableBitmap); 121 } 122 123 @Test(expected=IllegalStateException.class) 124 public void testSetBitmapToImmutableBitmap() { 125 // Should throw out IllegalStateException when setting an ImmutableBitmap to a Canvas 126 mCanvas.setBitmap(mImmutableBitmap); 127 } 128 129 @Test(expected=RuntimeException.class) 130 public void testSetBitmapToRecycledBitmap() { 131 // Should throw out RuntimeException when setting Bitmap which is recycled to a Canvas 132 mMutableBitmap.recycle(); 133 mCanvas.setBitmap(mMutableBitmap); 134 } 135 136 @Test 137 public void testSetBitmap() { 138 mMutableBitmap = Bitmap.createBitmap(BITMAP_WIDTH, 31, Config.ARGB_8888); 139 mCanvas.setBitmap(mMutableBitmap); 140 assertEquals(BITMAP_WIDTH, mCanvas.getWidth()); 141 assertEquals(31, mCanvas.getHeight()); 142 } 143 144 @Test 145 public void testSetBitmapFromEmpty() { 146 Canvas canvas = new Canvas(); 147 assertEquals(0, canvas.getWidth()); 148 assertEquals(0, canvas.getHeight()); 149 150 // now ensure that we can "grow" the canvas 151 152 Bitmap normal = Bitmap.createBitmap(10, 10, Config.ARGB_8888); 153 canvas.setBitmap(normal); 154 assertEquals(10, canvas.getWidth()); 155 assertEquals(10, canvas.getHeight()); 156 157 // now draw, and check that the clip was "open" 158 canvas.drawColor(0xFFFF0000); 159 assertEquals(0xFFFF0000, normal.getPixel(5, 5)); 160 } 161 162 @Test 163 public void testSetBitmapCleanClip() { 164 mCanvas.setBitmap(Bitmap.createBitmap(10, 10, Config.ARGB_8888)); 165 Rect r = new Rect(2, 2, 8, 8); 166 mCanvas.save(); 167 mCanvas.clipRect(r); 168 assertEquals(r, mCanvas.getClipBounds()); 169 170 // "reset" the canvas, and then check that the clip is wide open 171 // and not the previous value 172 173 mCanvas.setBitmap(Bitmap.createBitmap(20, 20, Config.ARGB_8888)); 174 r = new Rect(0, 0, 20, 20); 175 assertEquals(r, mCanvas.getClipBounds()); 176 } 177 178 @Test 179 public void testSetBitmapSaveCount() { 180 Canvas c = new Canvas(Bitmap.createBitmap(10, 10, Config.ARGB_8888)); 181 int initialSaveCount = c.getSaveCount(); 182 183 c.save(); 184 assertEquals(c.getSaveCount(), initialSaveCount + 1); 185 186 // setBitmap should restore the saveCount to its original/base value 187 c.setBitmap(Bitmap.createBitmap(10, 10, Config.ARGB_8888)); 188 assertEquals(c.getSaveCount(), initialSaveCount); 189 } 190 191 @Test 192 public void testIsOpaque() { 193 assertFalse(mCanvas.isOpaque()); 194 } 195 196 @Test(expected=IllegalStateException.class) 197 public void testRestoreWithoutSave() { 198 // Should throw out IllegalStateException because cannot restore Canvas before save 199 mCanvas.restore(); 200 } 201 202 @Test 203 public void testRestore() { 204 mCanvas.save(); 205 mCanvas.restore(); 206 } 207 208 @Test 209 public void testSave1() { 210 final Matrix m1 = new Matrix(); 211 m1.setValues(values1); 212 mCanvas.setMatrix(m1); 213 mCanvas.save(); 214 215 final Matrix m2 = new Matrix(); 216 m2.setValues(values2); 217 mCanvas.setMatrix(m2); 218 219 final float[] values3 = new float[FLOAT_ARRAY_LEN]; 220 final Matrix m3 = mCanvas.getMatrix(); 221 m3.getValues(values3); 222 223 assertArrayEquals(values2, values3, 0.0f); 224 225 mCanvas.restore(); 226 final float[] values4 = new float[FLOAT_ARRAY_LEN]; 227 final Matrix m4 = mCanvas.getMatrix(); 228 m4.getValues(values4); 229 230 assertArrayEquals(values1, values4, 0.0f); 231 } 232 233 @Test 234 public void testSave2() { 235 // test save current matrix only 236 Matrix m1 = new Matrix(); 237 m1.setValues(values1); 238 mCanvas.setMatrix(m1); 239 mCanvas.save(Canvas.MATRIX_SAVE_FLAG); 240 241 Matrix m2 = new Matrix(); 242 m2.setValues(values2); 243 mCanvas.setMatrix(m2); 244 245 float[] values3 = new float[FLOAT_ARRAY_LEN]; 246 Matrix m3 = mCanvas.getMatrix(); 247 m3.getValues(values3); 248 249 assertArrayEquals(values2, values3, 0.0f); 250 251 mCanvas.restore(); 252 float[] values4 = new float[FLOAT_ARRAY_LEN]; 253 Matrix m4 = mCanvas.getMatrix(); 254 m4.getValues(values4); 255 256 assertArrayEquals(values1, values4, 0.0f); 257 258 // test save current clip only, don't know how to get clip saved, 259 // but can make sure Matrix can't be saved in this case 260 m1 = new Matrix(); 261 m1.setValues(values1); 262 mCanvas.setMatrix(m1); 263 mCanvas.save(Canvas.CLIP_SAVE_FLAG); 264 265 m2 = new Matrix(); 266 m2.setValues(values2); 267 mCanvas.setMatrix(m2); 268 269 values3 = new float[FLOAT_ARRAY_LEN]; 270 m3 = mCanvas.getMatrix(); 271 m3.getValues(values3); 272 273 assertArrayEquals(values2, values3, 0.0f); 274 275 mCanvas.restore(); 276 values4 = new float[FLOAT_ARRAY_LEN]; 277 m4 = mCanvas.getMatrix(); 278 m4.getValues(values4); 279 280 assertArrayEquals(values2, values4, 0.0f); 281 282 // test save everything 283 m1 = new Matrix(); 284 m1.setValues(values1); 285 mCanvas.setMatrix(m1); 286 mCanvas.save(Canvas.ALL_SAVE_FLAG); 287 288 m2 = new Matrix(); 289 m2.setValues(values2); 290 mCanvas.setMatrix(m2); 291 292 values3 = new float[FLOAT_ARRAY_LEN]; 293 m3 = mCanvas.getMatrix(); 294 m3.getValues(values3); 295 296 assertArrayEquals(values2, values3, 0.0f); 297 298 mCanvas.restore(); 299 values4 = new float[FLOAT_ARRAY_LEN]; 300 m4 = mCanvas.getMatrix(); 301 m4.getValues(values4); 302 303 assertArrayEquals(values1, values4, 0.0f); 304 } 305 306 @Test 307 public void testSaveFlags1() { 308 int[] flags = { 309 Canvas.MATRIX_SAVE_FLAG, 310 }; 311 verifySaveFlagsSequence(flags); 312 } 313 314 @Test 315 public void testSaveFlags2() { 316 int[] flags = { 317 Canvas.CLIP_SAVE_FLAG, 318 }; 319 verifySaveFlagsSequence(flags); 320 } 321 322 @Test 323 public void testSaveFlags3() { 324 int[] flags = { 325 Canvas.ALL_SAVE_FLAG, 326 Canvas.MATRIX_SAVE_FLAG, 327 Canvas.MATRIX_SAVE_FLAG, 328 }; 329 verifySaveFlagsSequence(flags); 330 } 331 332 @Test 333 public void testSaveFlags4() { 334 int[] flags = { 335 Canvas.ALL_SAVE_FLAG, 336 Canvas.CLIP_SAVE_FLAG, 337 Canvas.CLIP_SAVE_FLAG, 338 }; 339 verifySaveFlagsSequence(flags); 340 } 341 342 @Test 343 public void testSaveFlags5() { 344 int[] flags = { 345 Canvas.MATRIX_SAVE_FLAG, 346 Canvas.MATRIX_SAVE_FLAG, 347 Canvas.CLIP_SAVE_FLAG, 348 Canvas.CLIP_SAVE_FLAG, 349 Canvas.MATRIX_SAVE_FLAG, 350 Canvas.MATRIX_SAVE_FLAG, 351 }; 352 verifySaveFlagsSequence(flags); 353 } 354 355 @Test 356 public void testSaveFlags6() { 357 int[] flags = { 358 Canvas.CLIP_SAVE_FLAG, 359 Canvas.CLIP_SAVE_FLAG, 360 Canvas.MATRIX_SAVE_FLAG, 361 Canvas.MATRIX_SAVE_FLAG, 362 Canvas.CLIP_SAVE_FLAG, 363 Canvas.CLIP_SAVE_FLAG, 364 }; 365 verifySaveFlagsSequence(flags); 366 } 367 368 @Test 369 public void testSaveFlags7() { 370 int[] flags = { 371 Canvas.MATRIX_SAVE_FLAG, 372 Canvas.MATRIX_SAVE_FLAG, 373 Canvas.ALL_SAVE_FLAG, 374 Canvas.ALL_SAVE_FLAG, 375 Canvas.CLIP_SAVE_FLAG, 376 Canvas.CLIP_SAVE_FLAG, 377 }; 378 verifySaveFlagsSequence(flags); 379 } 380 381 @Test 382 public void testSaveFlags8() { 383 int[] flags = { 384 Canvas.MATRIX_SAVE_FLAG, 385 Canvas.CLIP_SAVE_FLAG, 386 Canvas.ALL_SAVE_FLAG, 387 Canvas.MATRIX_SAVE_FLAG, 388 Canvas.CLIP_SAVE_FLAG, 389 Canvas.ALL_SAVE_FLAG, 390 }; 391 verifySaveFlagsSequence(flags); 392 } 393 394 // This test exercises the saveLayer flag that preserves the clip 395 // state across the matching restore call boundary. This is a vanilla 396 // test and doesn't exercise any interaction between the clip stack 397 // and SkCanvas' deferred save/restore system. 398 @Test 399 public void testSaveFlags9() { 400 Rect clip0 = new Rect(); 401 assertTrue(mCanvas.getClipBounds(clip0)); 402 403 mCanvas.save(Canvas.MATRIX_SAVE_FLAG); 404 405 // All clip elements should be preserved after restore 406 mCanvas.clipRect(0, 0, BITMAP_WIDTH / 2, BITMAP_HEIGHT); 407 Path path = new Path(); 408 path.addOval(0.25f * BITMAP_WIDTH, 0.25f * BITMAP_HEIGHT, 409 0.75f * BITMAP_WIDTH, 0.75f * BITMAP_HEIGHT, 410 Path.Direction.CW); 411 mCanvas.clipPath(path); 412 mCanvas.clipRect(0, 0, BITMAP_WIDTH, BITMAP_HEIGHT / 2); 413 414 Rect clip1 = new Rect(); 415 assertTrue(mCanvas.getClipBounds(clip1)); 416 assertTrue(clip1 != clip0); 417 assertTrue(clip0.contains(clip1)); 418 419 mCanvas.restore(); 420 421 Rect clip2 = new Rect(); 422 assertTrue(mCanvas.getClipBounds(clip2)); 423 assertEquals(clip2, clip1); 424 } 425 426 // This test exercises the saveLayer MATRIX_SAVE_FLAG flag and its 427 // interaction with the clip stack and SkCanvas deferred save/restore 428 // system. 429 @Test 430 public void testSaveFlags10() { 431 RectF rect1 = new RectF(0, 0, BITMAP_WIDTH / 2, BITMAP_HEIGHT); 432 RectF rect2 = new RectF(0, 0, BITMAP_WIDTH, BITMAP_HEIGHT / 2); 433 Path path = new Path(); 434 path.addOval(0.25f * BITMAP_WIDTH, 0.25f * BITMAP_HEIGHT, 435 0.75f * BITMAP_WIDTH, 0.75f * BITMAP_HEIGHT, 436 Path.Direction.CW); 437 438 Rect clip0 = new Rect(); 439 assertTrue(mCanvas.getClipBounds(clip0)); 440 441 // Exercise various Canvas lazy-save interactions. 442 mCanvas.save(); 443 mCanvas.save(); 444 mCanvas.clipRect(rect1); 445 mCanvas.clipPath(path); 446 447 Rect clip1 = new Rect(); 448 assertTrue(mCanvas.getClipBounds(clip1)); 449 assertTrue(clip1 != clip0); 450 451 mCanvas.save(Canvas.MATRIX_SAVE_FLAG); 452 mCanvas.save(Canvas.MATRIX_SAVE_FLAG); 453 mCanvas.clipRect(rect2); 454 mCanvas.clipPath(path); 455 456 Rect clip2 = new Rect(); 457 assertTrue(mCanvas.getClipBounds(clip2)); 458 assertTrue(clip2 != clip1); 459 assertTrue(clip2 != clip0); 460 461 mCanvas.save(); 462 mCanvas.translate(10, 5); 463 mCanvas.save(Canvas.MATRIX_SAVE_FLAG); 464 // An uncommitted save/restore frame: exercises 465 // the partial save emulation, ensuring there 466 // are no side effects. 467 Rect clip3 = new Rect(); 468 assertTrue(mCanvas.getClipBounds(clip3)); 469 clip3.offset(10, 5); // adjust for local offset 470 assertEquals(clip3, clip2); 471 mCanvas.restore(); 472 473 Rect clip4 = new Rect(); 474 assertTrue(mCanvas.getClipBounds(clip4)); 475 clip4.offset(10, 5); // adjust for local offset 476 assertEquals(clip4, clip2); 477 mCanvas.restore(); 478 479 Rect clip5 = new Rect(); 480 assertTrue(mCanvas.getClipBounds(clip5)); 481 assertEquals(clip5, clip2); 482 mCanvas.restore(); 483 484 // clip2 survives the preceding restore 485 Rect clip6 = new Rect(); 486 assertTrue(mCanvas.getClipBounds(clip6)); 487 assertEquals(clip6, clip2); 488 mCanvas.restore(); 489 490 // clip2 also survives the preceding restore 491 Rect clip7 = new Rect(); 492 assertTrue(mCanvas.getClipBounds(clip7)); 493 assertEquals(clip7, clip2); 494 mCanvas.restore(); 495 496 // clip1 does _not_ survive the preceding restore 497 Rect clip8 = new Rect(); 498 assertTrue(mCanvas.getClipBounds(clip8)); 499 assertEquals(clip8, clip0); 500 mCanvas.restore(); 501 502 Rect clip9 = new Rect(); 503 assertTrue(mCanvas.getClipBounds(clip9)); 504 assertEquals(clip9, clip0); 505 } 506 507 @Test 508 public void testSaveLayer1() { 509 final Paint p = new Paint(); 510 final RectF rF = new RectF(0, 10, 31, 0); 511 512 // test save current matrix only 513 Matrix m1 = new Matrix(); 514 m1.setValues(values1); 515 mCanvas.setMatrix(m1); 516 mCanvas.saveLayer(rF, p, Canvas.MATRIX_SAVE_FLAG); 517 518 Matrix m2 = new Matrix(); 519 m2.setValues(values2); 520 mCanvas.setMatrix(m2); 521 522 float[] values3 = new float[FLOAT_ARRAY_LEN]; 523 Matrix m3 = mCanvas.getMatrix(); 524 m3.getValues(values3); 525 526 assertArrayEquals(values2, values3, 0.0f); 527 528 mCanvas.restore(); 529 float[] values4 = new float[FLOAT_ARRAY_LEN]; 530 Matrix m4 = mCanvas.getMatrix(); 531 m4.getValues(values4); 532 533 assertArrayEquals(values1, values4, 0.0f); 534 535 // test save current clip flag only: this should save matrix as well 536 m1 = new Matrix(); 537 m1.setValues(values1); 538 mCanvas.setMatrix(m1); 539 mCanvas.saveLayer(rF, p, Canvas.CLIP_SAVE_FLAG); 540 541 m2 = new Matrix(); 542 m2.setValues(values2); 543 mCanvas.setMatrix(m2); 544 545 values3 = new float[FLOAT_ARRAY_LEN]; 546 m3 = mCanvas.getMatrix(); 547 m3.getValues(values3); 548 549 assertArrayEquals(values2, values3, 0.0f); 550 551 mCanvas.restore(); 552 values4 = new float[FLOAT_ARRAY_LEN]; 553 m4 = mCanvas.getMatrix(); 554 m4.getValues(values4); 555 556 assertArrayEquals(values1, values4, 0.0f); 557 558 // test save everything 559 m1 = new Matrix(); 560 m1.setValues(values1); 561 mCanvas.setMatrix(m1); 562 mCanvas.saveLayer(rF, p, Canvas.ALL_SAVE_FLAG); 563 564 m2 = new Matrix(); 565 m2.setValues(values2); 566 mCanvas.setMatrix(m2); 567 568 values3 = new float[FLOAT_ARRAY_LEN]; 569 m3 = mCanvas.getMatrix(); 570 m3.getValues(values3); 571 572 assertArrayEquals(values2, values3, 0.0f); 573 574 mCanvas.restore(); 575 values4 = new float[FLOAT_ARRAY_LEN]; 576 m4 = mCanvas.getMatrix(); 577 m4.getValues(values4); 578 579 assertArrayEquals(values1, values4, 0.0f); 580 } 581 582 @Test 583 public void testSaveLayer2() { 584 final Paint p = new Paint(); 585 586 // test save current matrix only 587 Matrix m1 = new Matrix(); 588 m1.setValues(values1); 589 mCanvas.setMatrix(m1); 590 mCanvas.saveLayer(10, 0, 0, 31, p, Canvas.MATRIX_SAVE_FLAG); 591 592 Matrix m2 = new Matrix(); 593 m2.setValues(values2); 594 mCanvas.setMatrix(m2); 595 596 float[] values3 = new float[FLOAT_ARRAY_LEN]; 597 Matrix m3 = mCanvas.getMatrix(); 598 m3.getValues(values3); 599 600 assertArrayEquals(values2, values3, 0.0f); 601 602 mCanvas.restore(); 603 float[] values4 = new float[FLOAT_ARRAY_LEN]; 604 Matrix m4 = mCanvas.getMatrix(); 605 m4.getValues(values4); 606 607 assertArrayEquals(values1, values4, 0.0f); 608 609 // test save current clip flag only: this should save matrix as well 610 m1 = new Matrix(); 611 m1.setValues(values1); 612 mCanvas.setMatrix(m1); 613 mCanvas.saveLayer(10, 0, 0, 31, p, Canvas.CLIP_SAVE_FLAG); 614 615 m2 = new Matrix(); 616 m2.setValues(values2); 617 mCanvas.setMatrix(m2); 618 619 values3 = new float[FLOAT_ARRAY_LEN]; 620 m3 = mCanvas.getMatrix(); 621 m3.getValues(values3); 622 623 assertArrayEquals(values2, values3, 0.0f); 624 625 mCanvas.restore(); 626 values4 = new float[FLOAT_ARRAY_LEN]; 627 m4 = mCanvas.getMatrix(); 628 m4.getValues(values4); 629 630 assertArrayEquals(values1, values4, 0.0f); 631 632 // test save everything 633 m1 = new Matrix(); 634 m1.setValues(values1); 635 mCanvas.setMatrix(m1); 636 mCanvas.saveLayer(10, 0, 0, 31, p, Canvas.ALL_SAVE_FLAG); 637 638 m2 = new Matrix(); 639 m2.setValues(values2); 640 mCanvas.setMatrix(m2); 641 642 values3 = new float[FLOAT_ARRAY_LEN]; 643 m3 = mCanvas.getMatrix(); 644 m3.getValues(values3); 645 646 assertArrayEquals(values2, values3, 0.0f); 647 648 mCanvas.restore(); 649 values4 = new float[FLOAT_ARRAY_LEN]; 650 m4 = mCanvas.getMatrix(); 651 m4.getValues(values4); 652 653 assertArrayEquals(values1, values4, 0.0f); 654 } 655 656 @Test 657 public void testSaveLayerAlpha1() { 658 final RectF rF = new RectF(0, 10, 31, 0); 659 660 // test save current matrix only 661 Matrix m1 = new Matrix(); 662 m1.setValues(values1); 663 mCanvas.setMatrix(m1); 664 mCanvas.saveLayerAlpha(rF, 0xff, Canvas.MATRIX_SAVE_FLAG); 665 666 Matrix m2 = new Matrix(); 667 m2.setValues(values2); 668 mCanvas.setMatrix(m2); 669 670 float[] values3 = new float[FLOAT_ARRAY_LEN]; 671 Matrix m3 = mCanvas.getMatrix(); 672 m3.getValues(values3); 673 674 assertArrayEquals(values2, values3, 0.0f); 675 676 mCanvas.restore(); 677 float[] values4 = new float[FLOAT_ARRAY_LEN]; 678 Matrix m4 = mCanvas.getMatrix(); 679 m4.getValues(values4); 680 681 assertArrayEquals(values1, values4, 0.0f); 682 683 // test save current clip flag only: this should save matrix as well 684 m1 = new Matrix(); 685 m1.setValues(values1); 686 mCanvas.setMatrix(m1); 687 mCanvas.saveLayerAlpha(rF, 0xff, Canvas.CLIP_SAVE_FLAG); 688 689 m2 = new Matrix(); 690 m2.setValues(values2); 691 mCanvas.setMatrix(m2); 692 693 values3 = new float[FLOAT_ARRAY_LEN]; 694 m3 = mCanvas.getMatrix(); 695 m3.getValues(values3); 696 697 assertArrayEquals(values2, values3, 0.0f); 698 699 mCanvas.restore(); 700 values4 = new float[FLOAT_ARRAY_LEN]; 701 m4 = mCanvas.getMatrix(); 702 m4.getValues(values4); 703 704 assertArrayEquals(values1, values4, 0.0f); 705 706 // test save everything 707 m1 = new Matrix(); 708 m1.setValues(values1); 709 mCanvas.setMatrix(m1); 710 mCanvas.saveLayerAlpha(rF, 0xff, Canvas.ALL_SAVE_FLAG); 711 712 m2 = new Matrix(); 713 m2.setValues(values2); 714 mCanvas.setMatrix(m2); 715 716 values3 = new float[FLOAT_ARRAY_LEN]; 717 m3 = mCanvas.getMatrix(); 718 m3.getValues(values3); 719 720 assertArrayEquals(values2, values3, 0.0f); 721 722 mCanvas.restore(); 723 values4 = new float[FLOAT_ARRAY_LEN]; 724 m4 = mCanvas.getMatrix(); 725 m4.getValues(values4); 726 727 assertArrayEquals(values1, values4, 0.0f); 728 } 729 730 @Test 731 public void testSaveLayerAlpha2() { 732 // test save current matrix only 733 Matrix m1 = new Matrix(); 734 m1.setValues(values1); 735 mCanvas.setMatrix(m1); 736 mCanvas.saveLayerAlpha(0, 10, 31, 0, 0xff, Canvas.MATRIX_SAVE_FLAG); 737 738 Matrix m2 = new Matrix(); 739 m2.setValues(values2); 740 mCanvas.setMatrix(m2); 741 742 float[] values3 = new float[FLOAT_ARRAY_LEN]; 743 Matrix m3 = mCanvas.getMatrix(); 744 m3.getValues(values3); 745 746 assertArrayEquals(values2, values3, 0.0f); 747 748 mCanvas.restore(); 749 float[] values4 = new float[FLOAT_ARRAY_LEN]; 750 Matrix m4 = mCanvas.getMatrix(); 751 m4.getValues(values4); 752 753 assertArrayEquals(values1, values4, 0.0f); 754 755 // test save current clip flag only: this should save matrix as well 756 m1 = new Matrix(); 757 m1.setValues(values1); 758 mCanvas.setMatrix(m1); 759 mCanvas.saveLayerAlpha(0, 10, 31, 0, 0xff, Canvas.CLIP_SAVE_FLAG); 760 761 m2 = new Matrix(); 762 m2.setValues(values2); 763 mCanvas.setMatrix(m2); 764 765 values3 = new float[FLOAT_ARRAY_LEN]; 766 m3 = mCanvas.getMatrix(); 767 m3.getValues(values3); 768 769 assertArrayEquals(values2, values3, 0.0f); 770 771 mCanvas.restore(); 772 values4 = new float[FLOAT_ARRAY_LEN]; 773 m4 = mCanvas.getMatrix(); 774 m4.getValues(values4); 775 776 assertArrayEquals(values1, values4, 0.0f); 777 778 // test save everything 779 m1 = new Matrix(); 780 m1.setValues(values1); 781 mCanvas.setMatrix(m1); 782 mCanvas.saveLayerAlpha(0, 10, 31, 0, 0xff, Canvas.ALL_SAVE_FLAG); 783 784 m2 = new Matrix(); 785 m2.setValues(values2); 786 mCanvas.setMatrix(m2); 787 788 values3 = new float[FLOAT_ARRAY_LEN]; 789 m3 = mCanvas.getMatrix(); 790 m3.getValues(values3); 791 792 assertArrayEquals(values2, values3, 0.0f); 793 794 mCanvas.restore(); 795 values4 = new float[FLOAT_ARRAY_LEN]; 796 m4 = mCanvas.getMatrix(); 797 m4.getValues(values4); 798 799 assertArrayEquals(values1, values4, 0.0f); 800 } 801 802 @Test 803 public void testGetSaveCount() { 804 // why is 1 not 0 805 assertEquals(1, mCanvas.getSaveCount()); 806 mCanvas.save(); 807 assertEquals(2, mCanvas.getSaveCount()); 808 mCanvas.save(); 809 assertEquals(3, mCanvas.getSaveCount()); 810 mCanvas.saveLayer(new RectF(), new Paint(), Canvas.ALL_SAVE_FLAG); 811 assertEquals(4, mCanvas.getSaveCount()); 812 mCanvas.saveLayerAlpha(new RectF(), 0, Canvas.ALL_SAVE_FLAG); 813 assertEquals(5, mCanvas.getSaveCount()); 814 } 815 816 @Test(expected=IllegalArgumentException.class) 817 public void testRestoreToCountIllegalSaveCount() { 818 // Should throw out IllegalArgumentException because saveCount is less than 1 819 mCanvas.restoreToCount(0); 820 } 821 822 @Test 823 public void testRestoreToCountExceptionBehavior() { 824 int restoreTo = mCanvas.save(); 825 mCanvas.save(); 826 int beforeCount = mCanvas.getSaveCount(); 827 828 boolean exceptionObserved = false; 829 try { 830 mCanvas.restoreToCount(restoreTo - 1); 831 } catch (IllegalArgumentException e) { 832 exceptionObserved = true; 833 } 834 835 // restore to count threw, AND did no restoring 836 assertTrue(exceptionObserved); 837 assertEquals(beforeCount, mCanvas.getSaveCount()); 838 } 839 840 @Test 841 public void testRestoreToCount() { 842 final Matrix m1 = new Matrix(); 843 m1.setValues(values1); 844 mCanvas.setMatrix(m1); 845 final int count = mCanvas.save(); 846 assertTrue(count > 0); 847 848 final Matrix m2 = new Matrix(); 849 m2.setValues(values2); 850 mCanvas.setMatrix(m2); 851 852 final float[] values3 = new float[FLOAT_ARRAY_LEN]; 853 final Matrix m3 = mCanvas.getMatrix(); 854 m3.getValues(values3); 855 856 assertArrayEquals(values2, values3, 0.0f); 857 858 mCanvas.restoreToCount(count); 859 final float[] values4 = new float[FLOAT_ARRAY_LEN]; 860 final Matrix m4 = mCanvas.getMatrix(); 861 m4.getValues(values4); 862 863 assertArrayEquals(values1, values4, 0.0f); 864 } 865 866 @Test 867 public void testGetMatrix1() { 868 final float[] f1 = { 869 1, 2, 3, 4, 5, 6, 7, 8, 9 870 }; 871 final Matrix m1 = new Matrix(); 872 m1.setValues(f1); 873 mCanvas.setMatrix(m1); 874 875 final Matrix m2 = new Matrix(m1); 876 mCanvas.getMatrix(m2); 877 878 assertTrue(m1.equals(m2)); 879 880 final float[] f2 = new float[FLOAT_ARRAY_LEN]; 881 m2.getValues(f2); 882 883 assertArrayEquals(f1, f2, 0.0f); 884 } 885 886 @Test 887 public void testGetMatrix2() { 888 final float[] f1 = { 889 1, 2, 3, 4, 5, 6, 7, 8, 9 890 }; 891 final Matrix m1 = new Matrix(); 892 m1.setValues(f1); 893 894 mCanvas.setMatrix(m1); 895 final Matrix m2 = mCanvas.getMatrix(); 896 897 assertTrue(m1.equals(m2)); 898 899 final float[] f2 = new float[FLOAT_ARRAY_LEN]; 900 m2.getValues(f2); 901 902 assertArrayEquals(f1, f2, 0.0f); 903 } 904 905 @Test 906 public void testTranslate() { 907 preCompare(); 908 909 mCanvas.translate(0.10f, 0.28f); 910 911 final float[] values = new float[FLOAT_ARRAY_LEN]; 912 mCanvas.getMatrix().getValues(values); 913 assertArrayEquals(new float[] { 914 1.0f, 0.0f, 0.1f, 0.0f, 1.0f, 0.28f, 0.0f, 0.0f, 1.0f 915 }, values, 0.0f); 916 } 917 918 @Test 919 public void testScale1() { 920 preCompare(); 921 922 mCanvas.scale(0.5f, 0.5f); 923 924 final float[] values = new float[FLOAT_ARRAY_LEN]; 925 mCanvas.getMatrix().getValues(values); 926 assertArrayEquals(new float[] { 927 0.5f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f 928 }, values, 0.0f); 929 } 930 931 @Test 932 public void testScale2() { 933 preCompare(); 934 935 mCanvas.scale(3.0f, 3.0f, 1.0f, 1.0f); 936 937 final float[] values = new float[FLOAT_ARRAY_LEN]; 938 mCanvas.getMatrix().getValues(values); 939 assertArrayEquals(new float[] { 940 3.0f, 0.0f, -2.0f, 0.0f, 3.0f, -2.0f, 0.0f, 0.0f, 1.0f 941 }, values, 0.0f); 942 } 943 944 @Test 945 public void testRotate1() { 946 preCompare(); 947 948 mCanvas.rotate(90); 949 950 final float[] values = new float[FLOAT_ARRAY_LEN]; 951 mCanvas.getMatrix().getValues(values); 952 assertArrayEquals(new float[] { 953 0.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f 954 }, values, 0.0f); 955 } 956 957 @Test 958 public void testRotate2() { 959 preCompare(); 960 961 mCanvas.rotate(30, 1.0f, 0.0f); 962 963 final float[] values = new float[FLOAT_ARRAY_LEN]; 964 mCanvas.getMatrix().getValues(values); 965 assertArrayEquals(new float[] { 966 0.8660254f, -0.5f, 0.13397461f, 0.5f, 0.8660254f, -0.5f, 0.0f, 0.0f, 1.0f 967 }, values, 0.0f); 968 } 969 970 @Test 971 public void testSkew() { 972 preCompare(); 973 974 mCanvas.skew(1.0f, 3.0f); 975 976 final float[] values = new float[FLOAT_ARRAY_LEN]; 977 mCanvas.getMatrix().getValues(values); 978 assertArrayEquals(new float[] { 979 1.0f, 1.0f, 0.0f, 3.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f 980 }, values, 0.0f); 981 } 982 983 @Test 984 public void testConcat() { 985 preCompare(); 986 987 final Matrix m = new Matrix(); 988 final float[] values = {0, 1, 2, 3, 4, 5, 6, 7, 8}; 989 990 m.setValues(values); 991 mCanvas.concat(m); 992 993 mCanvas.getMatrix().getValues(values); 994 assertArrayEquals(new float[] { 995 0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f 996 }, values, 0.0f); 997 } 998 999 @Test 1000 public void testClipRectF() { 1001 // intersect with clip larger than canvas 1002 assertTrue(mCanvas.clipRect(new RectF(0, 0, 10, 31), Op.INTERSECT)); 1003 // intersect with clip outside of canvas bounds 1004 assertFalse(mCanvas.clipRect(new RectF(10, 31, 11, 32), Op.INTERSECT)); 1005 // replace with clip that is larger than canvas 1006 assertTrue(mCanvas.clipRect(new RectF(0, 0, 10, 31), Op.REPLACE)); 1007 // intersect with clip that covers top portion of canvas 1008 assertTrue(mCanvas.clipRect(new RectF(0, 0, 20, 10), Op.INTERSECT)); 1009 // intersect with clip that covers bottom portion of canvas 1010 assertFalse(mCanvas.clipRect(new RectF(0, 10, 20, 32), Op.INTERSECT)); 1011 // ensure that difference doesn't widen already closed clip 1012 assertFalse(mCanvas.clipRect(new RectF(0, 0, 10, 31), Op.DIFFERENCE)); 1013 } 1014 1015 @Test 1016 public void testClipRect() { 1017 // intersect with clip larger than canvas 1018 assertTrue(mCanvas.clipRect(new Rect(0, 0, 10, 31), Op.INTERSECT)); 1019 // intersect with clip outside of canvas bounds 1020 assertFalse(mCanvas.clipRect(new Rect(10, 31, 11, 32), Op.INTERSECT)); 1021 // replace with clip that is larger than canvas 1022 assertTrue(mCanvas.clipRect(new Rect(0, 0, 10, 31), Op.REPLACE)); 1023 // intersect with clip that covers top portion of canvas 1024 assertTrue(mCanvas.clipRect(new Rect(0, 0, 20, 10), Op.INTERSECT)); 1025 // intersect with clip that covers bottom portion of canvas 1026 assertFalse(mCanvas.clipRect(new Rect(0, 10, 20, 32), Op.INTERSECT)); 1027 // ensure that difference doesn't widen already closed clip 1028 assertFalse(mCanvas.clipRect(new Rect(0, 0, 10, 31), Op.DIFFERENCE)); 1029 } 1030 1031 @Test 1032 public void testClipRect4I() { 1033 // intersect with clip larger than canvas 1034 assertTrue(mCanvas.clipRect(0, 0, 10, 31, Op.INTERSECT)); 1035 // intersect with clip outside of canvas bounds 1036 assertFalse(mCanvas.clipRect(10, 31, 11, 32, Op.INTERSECT)); 1037 // replace with clip that is larger than canvas 1038 assertTrue(mCanvas.clipRect(0, 0, 10, 31, Op.REPLACE)); 1039 // intersect with clip that covers top portion of canvas 1040 assertTrue(mCanvas.clipRect(0, 0, 20, 10, Op.INTERSECT)); 1041 // intersect with clip that covers bottom portion of canvas 1042 assertFalse(mCanvas.clipRect(0, 10, 20, 32, Op.INTERSECT)); 1043 // ensure that difference doesn't widen already closed clip 1044 assertFalse(mCanvas.clipRect(0, 0, 10, 31, Op.DIFFERENCE)); 1045 } 1046 1047 @Test 1048 public void testClipRect4F() { 1049 // intersect with clip larger than canvas 1050 assertTrue(mCanvas.clipRect(0f, 0f, 10f, 31f, Op.INTERSECT)); 1051 // intersect with clip outside of canvas bounds 1052 assertFalse(mCanvas.clipRect(10f, 31f, 11f, 32f, Op.INTERSECT)); 1053 // replace with clip that is larger than canvas 1054 assertTrue(mCanvas.clipRect(0f, 0f, 10f, 31f, Op.REPLACE)); 1055 // intersect with clip that covers top portion of canvas 1056 assertTrue(mCanvas.clipRect(0f, 0f, 20f, 10f, Op.INTERSECT)); 1057 // intersect with clip that covers bottom portion of canvas 1058 assertFalse(mCanvas.clipRect(0f, 10f, 20f, 32f, Op.INTERSECT)); 1059 // ensure that difference doesn't widen already closed clip 1060 assertFalse(mCanvas.clipRect(0f, 0f, 10f, 31f, Op.DIFFERENCE)); 1061 } 1062 1063 @Test 1064 public void testClipOutRectF() { 1065 // remove center, clip not empty 1066 assertTrue(mCanvas.clipOutRect(new RectF(1, 1, 9, 27))); 1067 // replace clip, verify difference doesn't widen 1068 assertFalse(mCanvas.clipRect(new RectF(0, 0, 0, 0), Op.REPLACE)); 1069 assertFalse(mCanvas.clipOutRect(new RectF(0, 0, 100, 100))); 1070 } 1071 1072 @Test 1073 public void testClipOutRect() { 1074 // remove center, clip not empty 1075 assertTrue(mCanvas.clipOutRect(new Rect(1, 1, 9, 27))); 1076 // replace clip, verify difference doesn't widen 1077 assertFalse(mCanvas.clipRect(new Rect(0, 0, 0, 0), Op.REPLACE)); 1078 assertFalse(mCanvas.clipOutRect(new Rect(0, 0, 100, 100))); 1079 } 1080 1081 @Test 1082 public void testClipOutRect4I() { 1083 // remove center, clip not empty 1084 assertTrue(mCanvas.clipOutRect(1, 1, 9, 27)); 1085 // replace clip, verify difference doesn't widen 1086 assertFalse(mCanvas.clipRect(0, 0, 0, 0, Op.REPLACE)); 1087 assertFalse(mCanvas.clipOutRect(0, 0, 100, 100)); 1088 } 1089 1090 @Test 1091 public void testClipOutRect4F() { 1092 // remove center, clip not empty 1093 assertTrue(mCanvas.clipOutRect(1f, 1f, 9f, 27f)); 1094 // replace clip, verify difference doesn't widen 1095 assertFalse(mCanvas.clipRect(0f, 0f, 0f, 0f, Op.REPLACE)); 1096 assertFalse(mCanvas.clipOutRect(0f, 0f, 100f, 100f)); 1097 } 1098 1099 @Test 1100 public void testIntersectClipRectF() { 1101 // intersect with clip larger than canvas 1102 assertTrue(mCanvas.clipRect(new RectF(0, 0, 10, 31))); 1103 // intersect with clip outside of canvas bounds 1104 assertFalse(mCanvas.clipRect(new RectF(10, 31, 11, 32))); 1105 } 1106 1107 @Test 1108 public void testIntersectClipRect() { 1109 // intersect with clip larger than canvas 1110 assertTrue(mCanvas.clipRect(new Rect(0, 0, 10, 31))); 1111 // intersect with clip outside of canvas bounds 1112 assertFalse(mCanvas.clipRect(new Rect(10, 31, 11, 32))); 1113 } 1114 1115 @Test 1116 public void testIntersectClipRect4F() { 1117 // intersect with clip larger than canvas 1118 assertTrue(mCanvas.clipRect(0, 0, 10, 31)); 1119 // intersect with clip outside of canvas bounds 1120 assertFalse(mCanvas.clipRect(10, 31, 11, 32)); 1121 } 1122 1123 @Test 1124 public void testClipPath1() { 1125 final Path p = new Path(); 1126 p.addRect(new RectF(0, 0, 10, 31), Direction.CCW); 1127 assertTrue(mCanvas.clipPath(p)); 1128 } 1129 1130 @Test 1131 public void testClipPath2() { 1132 final Path p = new Path(); 1133 p.addRect(new RectF(0, 0, 10, 31), Direction.CW); 1134 1135 final Path pIn = new Path(); 1136 pIn.addOval(new RectF(0, 0, 20, 10), Direction.CW); 1137 1138 final Path pOut = new Path(); 1139 pOut.addRoundRect(new RectF(10, 31, 11, 32), 0.5f, 0.5f, Direction.CW); 1140 1141 // intersect with clip larger than canvas 1142 assertTrue(mCanvas.clipPath(p, Op.INTERSECT)); 1143 // intersect with clip outside of canvas bounds 1144 assertFalse(mCanvas.clipPath(pOut, Op.INTERSECT)); 1145 // replace with clip that is larger than canvas 1146 assertTrue(mCanvas.clipPath(p, Op.REPLACE)); 1147 // intersect with clip that covers top portion of canvas 1148 assertTrue(mCanvas.clipPath(pIn, Op.INTERSECT)); 1149 // intersect with clip outside of canvas bounds 1150 assertFalse(mCanvas.clipPath(pOut, Op.INTERSECT)); 1151 // ensure that difference doesn't widen already closed clip 1152 assertFalse(mCanvas.clipPath(p, Op.DIFFERENCE)); 1153 } 1154 1155 @Test 1156 public void testClipOutPath() { 1157 final Path p = new Path(); 1158 p.addRect(new RectF(5, 5, 10, 10), Direction.CW); 1159 assertTrue(mCanvas.clipOutPath(p)); 1160 } 1161 1162 @Test 1163 public void testClipInversePath() { 1164 final Path p = new Path(); 1165 p.addRoundRect(new RectF(0, 0, 10, 10), 0.5f, 0.5f, Direction.CW); 1166 p.setFillType(Path.FillType.INVERSE_WINDING); 1167 assertTrue(mCanvas.clipPath(p, Op.INTERSECT)); 1168 1169 mCanvas.drawColor(PAINT_COLOR); 1170 1171 assertEquals(Color.TRANSPARENT, mMutableBitmap.getPixel(0, 0)); 1172 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 20)); 1173 } 1174 1175 @Test 1176 public void testGetDrawFilter() { 1177 assertNull(mCanvas.getDrawFilter()); 1178 final DrawFilter dF = new DrawFilter(); 1179 mCanvas.setDrawFilter(dF); 1180 1181 assertTrue(dF.equals(mCanvas.getDrawFilter())); 1182 } 1183 1184 @Test 1185 public void testQuickReject1() { 1186 assertFalse(mCanvas.quickReject(new RectF(0, 0, 10, 31), EdgeType.AA)); 1187 assertFalse(mCanvas.quickReject(new RectF(0, 0, 10, 31), EdgeType.BW)); 1188 } 1189 1190 @Test 1191 public void testQuickReject2() { 1192 final Path p = new Path(); 1193 p.addRect(new RectF(0, 0, 10, 31), Direction.CCW); 1194 1195 assertFalse(mCanvas.quickReject(p, EdgeType.AA)); 1196 assertFalse(mCanvas.quickReject(p, EdgeType.BW)); 1197 } 1198 1199 @Test 1200 public void testQuickReject3() { 1201 assertFalse(mCanvas.quickReject(0, 0, 10, 31, EdgeType.AA)); 1202 assertFalse(mCanvas.quickReject(0, 0, 10, 31, EdgeType.BW)); 1203 } 1204 1205 @Test 1206 public void testGetClipBounds1() { 1207 final Rect r = new Rect(); 1208 1209 assertTrue(mCanvas.getClipBounds(r)); 1210 assertEquals(BITMAP_WIDTH, r.width()); 1211 assertEquals(BITMAP_HEIGHT, r.height()); 1212 } 1213 1214 @Test 1215 public void testGetClipBounds2() { 1216 final Rect r = mCanvas.getClipBounds(); 1217 1218 assertEquals(BITMAP_WIDTH, r.width()); 1219 assertEquals(BITMAP_HEIGHT, r.height()); 1220 } 1221 1222 private void verifyDrewColor(int color) { 1223 assertEquals(color, mMutableBitmap.getPixel(0, 0)); 1224 assertEquals(color, mMutableBitmap.getPixel(BITMAP_WIDTH / 2, BITMAP_HEIGHT / 2)); 1225 assertEquals(color, mMutableBitmap.getPixel(BITMAP_WIDTH - 1, BITMAP_HEIGHT - 1)); 1226 } 1227 1228 @Test 1229 public void testDrawRGB() { 1230 final int alpha = 0xff; 1231 final int red = 0xff; 1232 final int green = 0xff; 1233 final int blue = 0xff; 1234 1235 mCanvas.drawRGB(red, green, blue); 1236 1237 final int color = alpha << 24 | red << 16 | green << 8 | blue; 1238 verifyDrewColor(color); 1239 } 1240 1241 @Test 1242 public void testDrawARGB() { 1243 final int alpha = 0xff; 1244 final int red = 0x22; 1245 final int green = 0x33; 1246 final int blue = 0x44; 1247 1248 mCanvas.drawARGB(alpha, red, green, blue); 1249 final int color = alpha << 24 | red << 16 | green << 8 | blue; 1250 verifyDrewColor(color); 1251 } 1252 1253 @Test 1254 public void testDrawColor1() { 1255 final int color = Color.RED; 1256 1257 mCanvas.drawColor(color); 1258 verifyDrewColor(color); 1259 } 1260 1261 @Test 1262 public void testDrawColor2() { 1263 mCanvas.drawColor(Color.RED, Mode.CLEAR); 1264 mCanvas.drawColor(Color.RED, Mode.DARKEN); 1265 mCanvas.drawColor(Color.RED, Mode.DST); 1266 mCanvas.drawColor(Color.RED, Mode.DST_ATOP); 1267 mCanvas.drawColor(Color.RED, Mode.DST_IN); 1268 mCanvas.drawColor(Color.RED, Mode.DST_OUT); 1269 mCanvas.drawColor(Color.RED, Mode.DST_OVER); 1270 mCanvas.drawColor(Color.RED, Mode.LIGHTEN); 1271 mCanvas.drawColor(Color.RED, Mode.MULTIPLY); 1272 mCanvas.drawColor(Color.RED, Mode.SCREEN); 1273 mCanvas.drawColor(Color.RED, Mode.SRC); 1274 mCanvas.drawColor(Color.RED, Mode.SRC_ATOP); 1275 mCanvas.drawColor(Color.RED, Mode.SRC_IN); 1276 mCanvas.drawColor(Color.RED, Mode.SRC_OUT); 1277 mCanvas.drawColor(Color.RED, Mode.SRC_OVER); 1278 mCanvas.drawColor(Color.RED, Mode.XOR); 1279 } 1280 1281 @Test 1282 public void testDrawPaint() { 1283 mCanvas.drawPaint(mPaint); 1284 1285 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 0)); 1286 } 1287 1288 @Test(expected=ArrayIndexOutOfBoundsException.class) 1289 public void testDrawPointsInvalidOffset() { 1290 // Should throw out ArrayIndexOutOfBoundsException because of invalid offset 1291 mCanvas.drawPoints(new float[]{ 1292 10.0f, 29.0f 1293 }, -1, 2, mPaint); 1294 } 1295 1296 @Test(expected=ArrayIndexOutOfBoundsException.class) 1297 public void testDrawPointsInvalidCount() { 1298 // Should throw out ArrayIndexOutOfBoundsException because of invalid count 1299 mCanvas.drawPoints(new float[]{ 1300 10.0f, 29.0f 1301 }, 0, 31, mPaint); 1302 } 1303 1304 @Test 1305 public void testDrawPoints1() { 1306 // normal case 1307 mCanvas.drawPoints(new float[] { 1308 0, 0 1309 }, 0, 2, mPaint); 1310 1311 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 0)); 1312 } 1313 1314 @Test 1315 public void testDrawPoints2() { 1316 mCanvas.drawPoints(new float[]{0, 0}, mPaint); 1317 1318 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 0)); 1319 } 1320 1321 @Test 1322 public void testDrawPoint() { 1323 mCanvas.drawPoint(0, 0, mPaint); 1324 1325 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 0)); 1326 } 1327 1328 @Test 1329 public void testDrawLine() { 1330 mCanvas.drawLine(0, 0, 10, 12, mPaint); 1331 1332 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 0)); 1333 } 1334 1335 @Test(expected=ArrayIndexOutOfBoundsException.class) 1336 public void testDrawLinesInvalidOffset() { 1337 // Should throw out ArrayIndexOutOfBoundsException because of invalid offset 1338 mCanvas.drawLines(new float[]{ 1339 0, 0, 10, 31 1340 }, 2, 4, new Paint()); 1341 } 1342 1343 @Test(expected=ArrayIndexOutOfBoundsException.class) 1344 public void testDrawLinesInvalidCount() { 1345 // Should throw out ArrayIndexOutOfBoundsException because of invalid count 1346 mCanvas.drawLines(new float[]{ 1347 0, 0, 10, 31 1348 }, 0, 8, new Paint()); 1349 } 1350 1351 @Test 1352 public void testDrawLines1() { 1353 // normal case 1354 mCanvas.drawLines(new float[] { 1355 0, 0, 10, 12 1356 }, 0, 4, mPaint); 1357 1358 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 0)); 1359 } 1360 1361 @Test 1362 public void testDrawLines2() { 1363 mCanvas.drawLines(new float[] { 1364 0, 0, 10, 12 1365 }, mPaint); 1366 1367 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 0)); 1368 } 1369 1370 private void verifyDrewPaint() { 1371 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(0, 0)); 1372 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(5, 6)); 1373 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(9, 11)); 1374 } 1375 1376 @Test 1377 public void testDrawRect1() { 1378 mCanvas.drawRect(new RectF(0, 0, 10, 12), mPaint); 1379 1380 verifyDrewPaint(); 1381 } 1382 1383 @Test 1384 public void testDrawRect2() { 1385 mCanvas.drawRect(new Rect(0, 0, 10, 12), mPaint); 1386 1387 verifyDrewPaint(); 1388 } 1389 1390 @Test 1391 public void testDrawRect3() { 1392 mCanvas.drawRect(0, 0, 10, 12, mPaint); 1393 1394 verifyDrewPaint(); 1395 } 1396 1397 @Test(expected=NullPointerException.class) 1398 public void testDrawOvalNull() { 1399 // Should throw out NullPointerException because oval is null 1400 mCanvas.drawOval(null, mPaint); 1401 } 1402 1403 @Test 1404 public void testDrawOval() { 1405 // normal case 1406 mCanvas.drawOval(new RectF(0, 0, 10, 12), mPaint); 1407 } 1408 1409 @Test 1410 public void testDrawCircle() { 1411 // special case: circle's radius <= 0 1412 mCanvas.drawCircle(10.0f, 10.0f, -1.0f, mPaint); 1413 1414 // normal case 1415 mCanvas.drawCircle(10, 12, 3, mPaint); 1416 1417 assertEquals(PAINT_COLOR, mMutableBitmap.getPixel(9, 11)); 1418 } 1419 1420 @Test(expected=NullPointerException.class) 1421 public void testDrawArcNullOval() { 1422 // Should throw NullPointerException because oval is null 1423 mCanvas.drawArc(null, 10.0f, 29.0f, true, mPaint); 1424 } 1425 1426 @Test 1427 public void testDrawArc() { 1428 // normal case 1429 mCanvas.drawArc(new RectF(0, 0, 10, 12), 10, 11, false, mPaint); 1430 mCanvas.drawArc(new RectF(0, 0, 10, 12), 10, 11, true, mPaint); 1431 } 1432 1433 @Test(expected=NullPointerException.class) 1434 public void testDrawRoundRectNull() { 1435 // Should throw out NullPointerException because RoundRect is null 1436 mCanvas.drawRoundRect(null, 10.0f, 29.0f, mPaint); 1437 } 1438 1439 @Test 1440 public void testDrawRoundRect() { 1441 mCanvas.drawRoundRect(new RectF(0, 0, 10, 12), 8, 8, mPaint); 1442 } 1443 1444 @Test 1445 public void testDrawPath() { 1446 mCanvas.drawPath(new Path(), mPaint); 1447 } 1448 1449 @Test(expected=RuntimeException.class) 1450 public void testDrawBitmapAtPointRecycled() { 1451 Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1452 b.recycle(); 1453 1454 // Should throw out RuntimeException because bitmap has been recycled 1455 mCanvas.drawBitmap(b, 10.0f, 29.0f, mPaint); 1456 } 1457 1458 @Test 1459 public void testDrawBitmapAtPoint() { 1460 Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 12, Config.ARGB_8888); 1461 mCanvas.drawBitmap(b, 10, 12, null); 1462 mCanvas.drawBitmap(b, 5, 12, mPaint); 1463 } 1464 1465 @Test(expected=RuntimeException.class) 1466 public void testDrawBitmapSrcDstFloatRecycled() { 1467 Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1468 b.recycle(); 1469 1470 // Should throw out RuntimeException because bitmap has been recycled 1471 mCanvas.drawBitmap(b, null, new RectF(), mPaint); 1472 } 1473 1474 @Test 1475 public void testDrawBitmapSrcDstFloat() { 1476 Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1477 mCanvas.drawBitmap(b, new Rect(), new RectF(), null); 1478 mCanvas.drawBitmap(b, new Rect(), new RectF(), mPaint); 1479 } 1480 1481 @Test(expected=RuntimeException.class) 1482 public void testDrawBitmapSrcDstIntRecycled() { 1483 Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1484 b.recycle(); 1485 1486 // Should throw out RuntimeException because bitmap has been recycled 1487 mCanvas.drawBitmap(b, null, new Rect(), mPaint); 1488 } 1489 1490 @Test 1491 public void testDrawBitmapSrcDstInt() { 1492 Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1493 mCanvas.drawBitmap(b, new Rect(), new Rect(), null); 1494 mCanvas.drawBitmap(b, new Rect(), new Rect(), mPaint); 1495 } 1496 1497 @Test(expected=IllegalArgumentException.class) 1498 public void testDrawBitmapIntsNegativeWidth() { 1499 // Should throw out IllegalArgumentException because width is less than 0 1500 mCanvas.drawBitmap(new int[2008], 10, 10, 10, 10, -1, 10, true, null); 1501 } 1502 1503 @Test(expected=IllegalArgumentException.class) 1504 public void testDrawBitmapIntsNegativeHeight() { 1505 // Should throw out IllegalArgumentException because height is less than 0 1506 mCanvas.drawBitmap(new int[2008], 10, 10, 10, 10, 10, -1, true, null); 1507 } 1508 1509 @Test(expected=IllegalArgumentException.class) 1510 public void testDrawBitmapIntsBadStride() { 1511 // Should throw out IllegalArgumentException because stride less than width and 1512 // bigger than -width 1513 mCanvas.drawBitmap(new int[2008], 10, 5, 10, 10, 10, 10, true, null); 1514 } 1515 1516 @Test(expected=ArrayIndexOutOfBoundsException.class) 1517 public void testDrawBitmapIntsNegativeOffset() { 1518 // Should throw out ArrayIndexOutOfBoundsException because offset less than 0 1519 mCanvas.drawBitmap(new int[2008], -1, 10, 10, 10, 10, 10, true, null); 1520 } 1521 1522 @Test(expected=ArrayIndexOutOfBoundsException.class) 1523 public void testDrawBitmapIntsBadOffset() { 1524 // Should throw out ArrayIndexOutOfBoundsException because sum of offset and width 1525 // is bigger than colors' length 1526 mCanvas.drawBitmap(new int[29], 10, 29, 10, 10, 20, 10, true, null); 1527 } 1528 1529 @Test 1530 public void testDrawBitmapInts() { 1531 final int[] colors = new int[2008]; 1532 1533 // special case: width equals to 0 1534 mCanvas.drawBitmap(colors, 10, 10, 10, 10, 0, 10, true, null); 1535 1536 // special case: height equals to 0 1537 mCanvas.drawBitmap(colors, 10, 10, 10, 10, 10, 0, true, null); 1538 1539 // normal case 1540 mCanvas.drawBitmap(colors, 10, 10, 10, 10, 10, 29, true, null); 1541 mCanvas.drawBitmap(colors, 10, 10, 10, 10, 10, 29, true, mPaint); 1542 } 1543 1544 @Test(expected=IllegalArgumentException.class) 1545 public void testDrawBitmapFloatsNegativeWidth() { 1546 // Should throw out IllegalArgumentException because width is less than 0 1547 mCanvas.drawBitmap(new int[2008], 10, 10, 10.0f, 10.0f, -1, 10, true, null); 1548 } 1549 1550 @Test(expected=IllegalArgumentException.class) 1551 public void testDrawBitmapFloatsNegativeHeight() { 1552 // Should throw out IllegalArgumentException because height is less than 0 1553 mCanvas.drawBitmap(new int[2008], 10, 10, 10.0f, 10.0f, 10, -1, true, null); 1554 } 1555 1556 @Test(expected=IllegalArgumentException.class) 1557 public void testDrawBitmapFloatsBadStride() { 1558 // Should throw out IllegalArgumentException because stride less than width and 1559 // bigger than -width 1560 mCanvas.drawBitmap(new int[2008], 10, 5, 10.0f, 10.0f, 10, 10, true, null); 1561 } 1562 1563 @Test(expected=ArrayIndexOutOfBoundsException.class) 1564 public void testDrawBitmapFloatsNegativeOffset() { 1565 // Should throw out ArrayIndexOutOfBoundsException because offset less than 0 1566 mCanvas.drawBitmap(new int[2008], -1, 10, 10.0f, 10.0f, 10, 10, true, null); 1567 } 1568 1569 @Test(expected=ArrayIndexOutOfBoundsException.class) 1570 public void testDrawBitmapFloatsBadOffset() { 1571 // Should throw out ArrayIndexOutOfBoundsException because sum of offset and width 1572 // is bigger than colors' length 1573 mCanvas.drawBitmap(new int[29], 10, 29, 10.0f, 10.0f, 20, 10, true, null); 1574 } 1575 1576 @Test 1577 public void testDrawBitmapFloats() { 1578 final int[] colors = new int[2008]; 1579 1580 // special case: width equals to 0 1581 mCanvas.drawBitmap(colors, 10, 10, 10.0f, 10.0f, 0, 10, true, null); 1582 1583 // special case: height equals to 0 1584 mCanvas.drawBitmap(colors, 10, 10, 10.0f, 10.0f, 10, 0, true, null); 1585 1586 // normal case 1587 mCanvas.drawBitmap(colors, 10, 10, 10.0f, 10.0f, 10, 29, true, null); 1588 mCanvas.drawBitmap(colors, 10, 10, 10.0f, 10.0f, 10, 29, true, mPaint); 1589 } 1590 1591 @Test 1592 public void testDrawBitmapMatrix() { 1593 final Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1594 mCanvas.drawBitmap(b, new Matrix(), null); 1595 mCanvas.drawBitmap(b, new Matrix(), mPaint); 1596 } 1597 1598 @Test(expected=ArrayIndexOutOfBoundsException.class) 1599 public void testDrawBitmapMeshNegativeWidth() { 1600 final Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1601 1602 // Should throw out ArrayIndexOutOfBoundsException because meshWidth less than 0 1603 mCanvas.drawBitmapMesh(b, -1, 10, null, 0, null, 0, null); 1604 } 1605 1606 @Test(expected=ArrayIndexOutOfBoundsException.class) 1607 public void testDrawBitmapMeshNegativeHeight() { 1608 final Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1609 1610 // Should throw out ArrayIndexOutOfBoundsException because meshHeight is less than 0 1611 mCanvas.drawBitmapMesh(b, 10, -1, null, 0, null, 0, null); 1612 } 1613 1614 @Test(expected=ArrayIndexOutOfBoundsException.class) 1615 public void testDrawBitmapMeshNegativeVertOffset() { 1616 final Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1617 1618 // Should throw out ArrayIndexOutOfBoundsException because vertOffset is less than 0 1619 mCanvas.drawBitmapMesh(b, 10, 10, null, -1, null, 0, null); 1620 } 1621 1622 @Test(expected=ArrayIndexOutOfBoundsException.class) 1623 public void testDrawBitmapMeshNegativeColorOffset() { 1624 final Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1625 1626 // Should throw out ArrayIndexOutOfBoundsException because colorOffset is less than 0 1627 mCanvas.drawBitmapMesh(b, 10, 10, null, 10, null, -1, null); 1628 } 1629 1630 @Test(expected=ArrayIndexOutOfBoundsException.class) 1631 public void testDrawBitmapMeshTooFewVerts() { 1632 final Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1633 1634 // Should throw out ArrayIndexOutOfBoundsException because verts' length is too short 1635 mCanvas.drawBitmapMesh(b, 10, 10, new float[] { 1636 10.0f, 29.0f 1637 }, 10, null, 10, null); 1638 } 1639 1640 @Test(expected=ArrayIndexOutOfBoundsException.class) 1641 public void testDrawBitmapMeshTooFewColors() { 1642 final Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1643 1644 // Should throw out ArrayIndexOutOfBoundsException because colors' length is too short 1645 // abnormal case: colors' length is too short 1646 final float[] verts = new float[2008]; 1647 mCanvas.drawBitmapMesh(b, 10, 10, verts, 10, new int[] { 1648 10, 29 1649 }, 10, null); 1650 } 1651 1652 @Test 1653 public void testDrawBitmapMesh() { 1654 final Bitmap b = Bitmap.createBitmap(BITMAP_WIDTH, 29, Config.ARGB_8888); 1655 1656 // special case: meshWidth equals to 0 1657 mCanvas.drawBitmapMesh(b, 0, 10, null, 10, null, 10, null); 1658 1659 // special case: meshHeight equals to 0 1660 mCanvas.drawBitmapMesh(b, 10, 0, null, 10, null, 10, null); 1661 1662 // normal case 1663 final float[] verts = new float[2008]; 1664 final int[] colors = new int[2008]; 1665 mCanvas.drawBitmapMesh(b, 10, 10, verts, 10, colors, 10, null); 1666 mCanvas.drawBitmapMesh(b, 10, 10, verts, 10, colors, 10, mPaint); 1667 } 1668 1669 @Test(expected=ArrayIndexOutOfBoundsException.class) 1670 public void testDrawVerticesTooFewVerts() { 1671 final float[] verts = new float[10]; 1672 final float[] texs = new float[10]; 1673 final int[] colors = new int[10]; 1674 final short[] indices = { 1675 0, 1, 2, 3, 4, 1 1676 }; 1677 1678 // Should throw out ArrayIndexOutOfBoundsException because sum of vertOffset and 1679 // vertexCount is bigger than verts' length 1680 mCanvas.drawVertices(VertexMode.TRIANGLES, 10, verts, 8, texs, 0, colors, 0, indices, 1681 0, 4, mPaint); 1682 } 1683 1684 @Test(expected=ArrayIndexOutOfBoundsException.class) 1685 public void testDrawVerticesTooFewTexs() { 1686 final float[] verts = new float[10]; 1687 final float[] texs = new float[10]; 1688 final int[] colors = new int[10]; 1689 final short[] indices = { 1690 0, 1, 2, 3, 4, 1 1691 }; 1692 1693 // Should throw out ArrayIndexOutOfBoundsException because sum of texOffset and 1694 // vertexCount is bigger thatn texs' length 1695 mCanvas.drawVertices(VertexMode.TRIANGLES, 10, verts, 0, texs, 30, colors, 0, indices, 1696 0, 4, mPaint); 1697 } 1698 1699 @Test(expected=ArrayIndexOutOfBoundsException.class) 1700 public void testDrawVerticesTooFewColors() { 1701 final float[] verts = new float[10]; 1702 final float[] texs = new float[10]; 1703 final int[] colors = new int[10]; 1704 final short[] indices = { 1705 0, 1, 2, 3, 4, 1 1706 }; 1707 1708 // Should throw out ArrayIndexOutOfBoundsException because sum of colorOffset and 1709 // vertexCount is bigger than colors' length 1710 mCanvas.drawVertices(VertexMode.TRIANGLES, 10, verts, 0, texs, 0, colors, 30, indices, 1711 0, 4, mPaint); 1712 } 1713 1714 @Test(expected=ArrayIndexOutOfBoundsException.class) 1715 public void testDrawVerticesTooFewIndices() { 1716 final float[] verts = new float[10]; 1717 final float[] texs = new float[10]; 1718 final int[] colors = new int[10]; 1719 final short[] indices = { 1720 0, 1, 2, 3, 4, 1 1721 }; 1722 1723 // Should throw out ArrayIndexOutOfBoundsException because sum of indexOffset and 1724 // indexCount is bigger than indices' length 1725 mCanvas.drawVertices(VertexMode.TRIANGLES, 10, verts, 0, texs, 0, colors, 0, indices, 1726 10, 30, mPaint); 1727 } 1728 1729 @Test 1730 public void testDrawVertices() { 1731 final float[] verts = new float[10]; 1732 final float[] texs = new float[10]; 1733 final int[] colors = new int[10]; 1734 final short[] indices = { 1735 0, 1, 2, 3, 4, 1 1736 }; 1737 1738 // special case: in texs, colors, indices, one of them, two of them and 1739 // all are null 1740 mCanvas.drawVertices(VertexMode.TRIANGLES, 0, verts, 0, null, 0, colors, 0, indices, 0, 0, 1741 mPaint); 1742 1743 mCanvas.drawVertices(VertexMode.TRIANGLE_STRIP, 0, verts, 0, null, 0, null, 0, indices, 0, 1744 0, mPaint); 1745 1746 mCanvas.drawVertices(VertexMode.TRIANGLE_FAN, 0, verts, 0, null, 0, null, 0, null, 0, 0, 1747 mPaint); 1748 1749 // normal case: texs, colors, indices are not null 1750 mCanvas.drawVertices(VertexMode.TRIANGLES, 10, verts, 0, texs, 0, colors, 0, indices, 0, 6, 1751 mPaint); 1752 1753 mCanvas.drawVertices(VertexMode.TRIANGLE_STRIP, 10, verts, 0, texs, 0, colors, 0, indices, 1754 0, 6, mPaint); 1755 1756 mCanvas.drawVertices(VertexMode.TRIANGLE_FAN, 10, verts, 0, texs, 0, colors, 0, indices, 0, 1757 6, mPaint); 1758 } 1759 1760 @Test(expected=IndexOutOfBoundsException.class) 1761 public void testDrawArrayTextNegativeIndex() { 1762 final char[] text = { 'a', 'n', 'd', 'r', 'o', 'i', 'd' }; 1763 1764 // Should throw out IndexOutOfBoundsException because index is less than 0 1765 mCanvas.drawText(text, -1, 7, 10, 10, mPaint); 1766 } 1767 1768 @Test(expected=IndexOutOfBoundsException.class) 1769 public void testDrawArrayTextNegativeCount() { 1770 final char[] text = { 'a', 'n', 'd', 'r', 'o', 'i', 'd' }; 1771 1772 // Should throw out IndexOutOfBoundsException because count is less than 0 1773 mCanvas.drawText(text, 0, -1, 10, 10, mPaint); 1774 } 1775 1776 @Test(expected=IndexOutOfBoundsException.class) 1777 public void testDrawArrayTextTextLengthTooSmall() { 1778 final char[] text = { 'a', 'n', 'd', 'r', 'o', 'i', 'd' }; 1779 1780 // Should throw out IndexOutOfBoundsException because sum of index and count 1781 // is bigger than text's length 1782 mCanvas.drawText(text, 0, 10, 10, 10, mPaint); 1783 } 1784 1785 @Test 1786 public void testDrawArrayText() { 1787 final char[] text = { 'a', 'n', 'd', 'r', 'o', 'i', 'd' }; 1788 1789 // normal case 1790 mCanvas.drawText(text, 0, 7, 10, 10, mPaint); 1791 } 1792 1793 @Test 1794 public void testDrawStringTextAtPosition() { 1795 mCanvas.drawText("android", 10, 30, mPaint); 1796 } 1797 1798 @Test(expected=IndexOutOfBoundsException.class) 1799 public void testDrawTextTextAtPositionWithOffsetsNegativeStart() { 1800 // Should throw out IndexOutOfBoundsException because start is less than 0 1801 mCanvas.drawText("android", -1, 7, 10, 30, mPaint); 1802 } 1803 1804 @Test(expected=IndexOutOfBoundsException.class) 1805 public void testDrawTextTextAtPositionWithOffsetsNegativeEnd() { 1806 // Should throw out IndexOutOfBoundsException because end is less than 0 1807 mCanvas.drawText("android", 0, -1, 10, 30, mPaint); 1808 } 1809 1810 @Test(expected=IndexOutOfBoundsException.class) 1811 public void testDrawTextTextAtPositionWithOffsetsStartEndMismatch() { 1812 // Should throw out IndexOutOfBoundsException because start is bigger than end 1813 mCanvas.drawText("android", 3, 1, 10, 30, mPaint); 1814 } 1815 1816 @Test(expected=IndexOutOfBoundsException.class) 1817 public void testDrawTextTextAtPositionWithOffsetsTextTooLong() { 1818 // Should throw out IndexOutOfBoundsException because end subtracts start should 1819 // bigger than text's length 1820 mCanvas.drawText("android", 0, 10, 10, 30, mPaint); 1821 } 1822 1823 @Test 1824 public void testDrawTextTextAtPositionWithOffsets() { 1825 final String t1 = "android"; 1826 mCanvas.drawText(t1, 0, 7, 10, 30, mPaint); 1827 1828 final SpannedString t2 = new SpannedString(t1); 1829 mCanvas.drawText(t2, 0, 7, 10, 30, mPaint); 1830 1831 final SpannableString t3 = new SpannableString(t2); 1832 mCanvas.drawText(t3, 0, 7, 10, 30, mPaint); 1833 1834 final SpannableStringBuilder t4 = new SpannableStringBuilder(t1); 1835 mCanvas.drawText(t4, 0, 7, 10, 30, mPaint); 1836 1837 final StringBuffer t5 = new StringBuffer(t1); 1838 mCanvas.drawText(t5, 0, 7, 10, 30, mPaint); 1839 } 1840 1841 @Test 1842 public void testDrawTextRun() { 1843 final String text = "android"; 1844 final Paint paint = new Paint(); 1845 1846 mCanvas.drawTextRun(text, 0, 0, 0, 0, 0.0f, 0.0f, false, paint); 1847 mCanvas.drawTextRun(text, 0, text.length(), 0, text.length(), 0.0f, 0.0f, false, paint); 1848 mCanvas.drawTextRun(text, text.length(), text.length(), text.length(), text.length(), 1849 0.0f, 0.0f, false, paint); 1850 } 1851 1852 @Test(expected=NullPointerException.class) 1853 public void testDrawTextRunNullCharArray() { 1854 // Should throw out NullPointerException because text is null 1855 mCanvas.drawTextRun((char[]) null, 0, 0, 0, 0, 0.0f, 0.0f, false, new Paint()); 1856 } 1857 1858 @Test(expected=NullPointerException.class) 1859 public void testDrawTextRunNullCharSequence() { 1860 // Should throw out NullPointerException because text is null 1861 mCanvas.drawTextRun((CharSequence) null, 0, 0, 0, 0, 0.0f, 0.0f, false, new Paint()); 1862 } 1863 1864 @Test(expected=NullPointerException.class) 1865 public void testDrawTextRunCharArrayNullPaint() { 1866 // Should throw out NullPointerException because paint is null 1867 mCanvas.drawTextRun("android".toCharArray(), 0, 0, 0, 0, 0.0f, 0.0f, false, null); 1868 } 1869 1870 @Test(expected=NullPointerException.class) 1871 public void testDrawTextRunCharSequenceNullPaint() { 1872 // Should throw out NullPointerException because paint is null 1873 mCanvas.drawTextRun("android", 0, 0, 0, 0, 0.0f, 0.0f, false, null); 1874 } 1875 1876 @Test(expected=IndexOutOfBoundsException.class) 1877 public void testDrawTextRunNegativeIndex() { 1878 final String text = "android"; 1879 final Paint paint = new Paint(); 1880 1881 // Should throw out IndexOutOfBoundsException because index is less than 0 1882 mCanvas.drawTextRun(text.toCharArray(), -1, text.length(), 0, text.length(), 0.0f, 0.0f, 1883 false, new Paint()); 1884 } 1885 1886 @Test(expected=IndexOutOfBoundsException.class) 1887 public void testDrawTextRunNegativeCount() { 1888 final String text = "android"; 1889 1890 // Should throw out IndexOutOfBoundsException because count is less than 0 1891 mCanvas.drawTextRun(text.toCharArray(), 0, -1, 0, text.length(), 0.0f, 0.0f, false, 1892 new Paint()); 1893 } 1894 1895 @Test(expected=IndexOutOfBoundsException.class) 1896 public void testDrawTextRunContestIndexTooLarge() { 1897 final String text = "android"; 1898 1899 // Should throw out IndexOutOfBoundsException because contextIndex is bigger than index 1900 mCanvas.drawTextRun(text.toCharArray(), 0, text.length(), 1, text.length(), 0.0f, 0.0f, 1901 false, new Paint()); 1902 } 1903 1904 @Test(expected=IndexOutOfBoundsException.class) 1905 public void testDrawTextRunContestIndexTooSmall() { 1906 final String text = "android"; 1907 1908 // Should throw out IndexOutOfBoundsException because contextIndex + contextCount 1909 // is less than index + count 1910 mCanvas.drawTextRun(text, 0, text.length(), 0, text.length() - 1, 0.0f, 0.0f, false, 1911 new Paint()); 1912 } 1913 1914 @Test(expected=IndexOutOfBoundsException.class) 1915 public void testDrawTextRunIndexTooLarge() { 1916 final String text = "android"; 1917 final Paint paint = new Paint(); 1918 1919 // Should throw out IndexOutOfBoundsException because index + count is bigger than 1920 // text length 1921 mCanvas.drawTextRun(text.toCharArray(), 0, text.length() + 1, 0, text.length() + 1, 1922 0.0f, 0.0f, false, new Paint()); 1923 } 1924 1925 @Test(expected=IndexOutOfBoundsException.class) 1926 public void testDrawTextRunNegativeContextStart() { 1927 final String text = "android"; 1928 final Paint paint = new Paint(); 1929 1930 // Should throw out IndexOutOfBoundsException because contextStart is less than 0 1931 mCanvas.drawTextRun(text, 0, text.length(), -1, text.length(), 0.0f, 0.0f, false, 1932 new Paint()); 1933 } 1934 1935 @Test(expected=IndexOutOfBoundsException.class) 1936 public void testDrawTextRunStartLessThanContextStart() { 1937 final String text = "android"; 1938 1939 // Should throw out IndexOutOfBoundsException because start is less than contextStart 1940 mCanvas.drawTextRun(text, 0, text.length(), 1, text.length(), 0.0f, 0.0f, false, 1941 new Paint()); 1942 } 1943 1944 @Test(expected=IndexOutOfBoundsException.class) 1945 public void testDrawTextRunEndLessThanStart() { 1946 final String text = "android"; 1947 1948 // Should throw out IndexOutOfBoundsException because end is less than start 1949 mCanvas.drawTextRun(text, 1, 0, 0, text.length(), 0.0f, 0.0f, false, new Paint()); 1950 } 1951 1952 @Test(expected=IndexOutOfBoundsException.class) 1953 public void testDrawTextRunContextEndLessThanEnd() { 1954 final String text = "android"; 1955 1956 // Should throw out IndexOutOfBoundsException because contextEnd is less than end 1957 mCanvas.drawTextRun(text, 0, text.length(), 0, text.length() - 1, 0.0f, 0.0f, false, 1958 new Paint()); 1959 } 1960 1961 @Test(expected=IndexOutOfBoundsException.class) 1962 public void testDrawTextRunContextEndLargerThanTextLength() { 1963 final String text = "android"; 1964 1965 // Should throw out IndexOutOfBoundsException because contextEnd is bigger than 1966 // text length 1967 mCanvas.drawTextRun(text, 0, text.length(), 0, text.length() + 1, 0.0f, 0.0f, false, 1968 new Paint()); 1969 } 1970 1971 @Test(expected=IndexOutOfBoundsException.class) 1972 public void testDrawPosTextWithIndexAndCountNegativeIndex() { 1973 final char[] text = { 1974 'a', 'n', 'd', 'r', 'o', 'i', 'd' 1975 }; 1976 final float[] pos = new float[]{ 1977 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f, 1978 7.0f, 7.0f 1979 }; 1980 1981 // Should throw out IndexOutOfBoundsException because index is less than 0 1982 mCanvas.drawPosText(text, -1, 7, pos, mPaint); 1983 } 1984 1985 1986 @Test(expected=IndexOutOfBoundsException.class) 1987 public void testDrawPosTextWithIndexAndCountTextTooShort() { 1988 final char[] text = { 1989 'a', 'n', 'd', 'r', 'o', 'i', 'd' 1990 }; 1991 final float[] pos = new float[]{ 1992 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f, 1993 7.0f, 7.0f 1994 }; 1995 1996 // Should throw out IndexOutOfBoundsException because sum of index and count is 1997 // bigger than text's length 1998 mCanvas.drawPosText(text, 1, 10, pos, mPaint); 1999 } 2000 2001 @Test(expected=IndexOutOfBoundsException.class) 2002 public void testDrawPosTextWithIndexAndCountCountTooLarge() { 2003 final char[] text = { 2004 'a', 'n', 'd', 'r', 'o', 'i', 'd' 2005 }; 2006 2007 // Should throw out IndexOutOfBoundsException because 2 times of count is 2008 // bigger than pos' length 2009 mCanvas.drawPosText(text, 1, 10, new float[] { 2010 10.0f, 30.f 2011 }, mPaint); 2012 } 2013 2014 @Test 2015 public void testDrawPosTextWithIndexAndCount() { 2016 final char[] text = { 2017 'a', 'n', 'd', 'r', 'o', 'i', 'd' 2018 }; 2019 final float[] pos = new float[]{ 2020 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f, 2021 7.0f, 7.0f 2022 }; 2023 2024 // normal case 2025 mCanvas.drawPosText(text, 0, 7, pos, mPaint); 2026 } 2027 2028 @Test(expected=IndexOutOfBoundsException.class) 2029 public void testDrawPosTextCountTooLarge() { 2030 final String text = "android"; 2031 2032 // Should throw out IndexOutOfBoundsException because 2 times of count is 2033 // bigger than pos' length 2034 mCanvas.drawPosText(text, new float[]{ 2035 10.0f, 30.f 2036 }, mPaint); 2037 } 2038 2039 @Test 2040 public void testDrawPosText() { 2041 final String text = "android"; 2042 final float[] pos = new float[]{ 2043 0.0f, 0.0f, 1.0f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 4.0f, 5.0f, 5.0f, 6.0f, 6.0f, 2044 7.0f, 7.0f 2045 }; 2046 // normal case 2047 mCanvas.drawPosText(text, pos, mPaint); 2048 } 2049 2050 @Test(expected=ArrayIndexOutOfBoundsException.class) 2051 public void testDrawTextOnPathWithIndexAndCountNegativeIndex() { 2052 final char[] text = { 'a', 'n', 'd', 'r', 'o', 'i', 'd' }; 2053 2054 // Should throw out ArrayIndexOutOfBoundsException because index is smaller than 0 2055 mCanvas.drawTextOnPath(text, -1, 7, new Path(), 10.0f, 10.0f, mPaint); 2056 } 2057 2058 @Test(expected=ArrayIndexOutOfBoundsException.class) 2059 public void testDrawTextOnPathWithIndexAndCountTextTooShort() { 2060 final char[] text = { 'a', 'n', 'd', 'r', 'o', 'i', 'd' }; 2061 2062 // Should throw out ArrayIndexOutOfBoundsException because sum of index and 2063 // count is bigger than text's length 2064 mCanvas.drawTextOnPath(text, 0, 10, new Path(), 10.0f, 10.0f, mPaint); 2065 } 2066 2067 @Test 2068 public void testDrawTextOnPathWithIndexAndCount() { 2069 final char[] text = { 'a', 'n', 'd', 'r', 'o', 'i', 'd' }; 2070 2071 // normal case 2072 mCanvas.drawTextOnPath(text, 0, 7, new Path(), 10.0f, 10.0f, mPaint); 2073 } 2074 2075 @Test 2076 public void testDrawTextOnPathtestDrawTextRunNegativeCount() { 2077 final Path path = new Path(); 2078 2079 // no character in text 2080 mCanvas.drawTextOnPath("", path, 10.0f, 10.0f, mPaint); 2081 2082 // There are characters in text 2083 mCanvas.drawTextOnPath("android", path, 10.0f, 10.0f, mPaint); 2084 } 2085 2086 @Test 2087 public void testDrawPicture1() { 2088 mCanvas.drawPicture(new Picture()); 2089 } 2090 2091 @Test 2092 public void testDrawPicture2() { 2093 final RectF dst = new RectF(0, 0, 10, 31); 2094 final Picture p = new Picture(); 2095 2096 // picture width or length not bigger than 0 2097 mCanvas.drawPicture(p, dst); 2098 2099 p.beginRecording(10, 30); 2100 mCanvas.drawPicture(p, dst); 2101 } 2102 2103 @Test 2104 public void testDrawPicture3() { 2105 final Rect dst = new Rect(0, 10, 30, 0); 2106 final Picture p = new Picture(); 2107 2108 // picture width or length not bigger than 0 2109 mCanvas.drawPicture(p, dst); 2110 2111 p.beginRecording(10, 30); 2112 mCanvas.drawPicture(p, dst); 2113 } 2114 2115 @Test 2116 public void testDensity() { 2117 // set Density 2118 mCanvas.setDensity(DisplayMetrics.DENSITY_DEFAULT); 2119 assertEquals(DisplayMetrics.DENSITY_DEFAULT, mCanvas.getDensity()); 2120 2121 // set Density 2122 mCanvas.setDensity(DisplayMetrics.DENSITY_HIGH); 2123 assertEquals(DisplayMetrics.DENSITY_HIGH, mCanvas.getDensity()); 2124 } 2125 2126 @Test(expected = IllegalStateException.class) 2127 public void testDrawHwBitmapInSwCanvas() { 2128 Bitmap hwBitmap = mImmutableBitmap.copy(Config.HARDWARE, false); 2129 mCanvas.drawBitmap(hwBitmap, 0, 0, null); 2130 } 2131 2132 @Test(expected = IllegalStateException.class) 2133 public void testHwBitmapShaderInSwCanvas1() { 2134 Bitmap hwBitmap = mImmutableBitmap.copy(Config.HARDWARE, false); 2135 BitmapShader bitmapShader = new BitmapShader(hwBitmap, Shader.TileMode.REPEAT, 2136 Shader.TileMode.REPEAT); 2137 RadialGradient gradientShader = new RadialGradient(10, 10, 30, Color.BLACK, Color.CYAN, 2138 Shader.TileMode.REPEAT); 2139 Shader shader = new ComposeShader(gradientShader, bitmapShader, Mode.OVERLAY); 2140 Paint p = new Paint(); 2141 p.setShader(shader); 2142 mCanvas.drawRect(0, 0, 10, 10, p); 2143 } 2144 2145 @Test(expected = IllegalStateException.class) 2146 public void testHwBitmapShaderInSwCanvas2() { 2147 Bitmap hwBitmap = mImmutableBitmap.copy(Config.HARDWARE, false); 2148 BitmapShader bitmapShader = new BitmapShader(hwBitmap, Shader.TileMode.REPEAT, 2149 Shader.TileMode.REPEAT); 2150 RadialGradient gradientShader = new RadialGradient(10, 10, 30, Color.BLACK, Color.CYAN, 2151 Shader.TileMode.REPEAT); 2152 Shader shader = new ComposeShader(bitmapShader, gradientShader, Mode.OVERLAY); 2153 Paint p = new Paint(); 2154 p.setShader(shader); 2155 mCanvas.drawRect(0, 0, 10, 10, p); 2156 } 2157 2158 private void preCompare() { 2159 final float[] values = new float[FLOAT_ARRAY_LEN]; 2160 mCanvas.getMatrix().getValues(values); 2161 assertArrayEquals(new float[] { 2162 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f 2163 }, values, 0.0f); 2164 } 2165 2166 private RectF getDeviceClip() { 2167 final RectF clip = new RectF(mCanvas.getClipBounds()); 2168 mCanvas.getMatrix().mapRect(clip); 2169 return clip; 2170 } 2171 2172 // Loops through the passed flags, applying each in order with successive calls 2173 // to save, verifying the clip and matrix values when restoring. 2174 private void verifySaveFlagsSequence(int[] saveFlags) { 2175 final Vector<RectF> clips = new Vector<RectF>(); 2176 final Vector<Matrix> matrices = new Vector<Matrix>(); 2177 2178 assertTrue(BITMAP_WIDTH > saveFlags.length); 2179 assertTrue(BITMAP_HEIGHT > saveFlags.length); 2180 2181 for (int i = 0; i < saveFlags.length; ++i) { 2182 clips.add(getDeviceClip()); 2183 matrices.add(mCanvas.getMatrix()); 2184 mCanvas.save(saveFlags[i]); 2185 2186 mCanvas.translate(1, 1); 2187 mCanvas.clipRect(0, 0, BITMAP_WIDTH - i - 1, BITMAP_HEIGHT - i - 1); 2188 2189 if (i > 0) { 2190 // We are mutating the state on each iteration. 2191 assertFalse(clips.elementAt(i).equals(clips.elementAt(i - 1))); 2192 assertFalse(matrices.elementAt(i).equals(matrices.elementAt(i - 1))); 2193 } 2194 } 2195 2196 for (int i = saveFlags.length - 1; i >= 0; --i) { 2197 // If clip/matrix flags are not set, the associated state should be preserved. 2198 if ((saveFlags[i] & Canvas.CLIP_SAVE_FLAG) == 0) { 2199 clips.elementAt(i).set(getDeviceClip()); 2200 } 2201 if ((saveFlags[i] & Canvas.MATRIX_SAVE_FLAG) == 0) { 2202 matrices.elementAt(i).set(mCanvas.getMatrix()); 2203 } 2204 2205 mCanvas.restore(); 2206 assertEquals(clips.elementAt(i), getDeviceClip()); 2207 assertEquals(matrices.elementAt(i), mCanvas.getMatrix()); 2208 } 2209 } 2210 2211 @Test 2212 public void testDrawBitmapColorBehavior() { 2213 try { 2214 // Create a wide gamut bitmap where the pixel value is slightly less than max red. 2215 Resources resources = InstrumentationRegistry.getTargetContext().getResources(); 2216 InputStream in = resources.getAssets().open("almost-red-adobe.png"); 2217 Bitmap bitmap = BitmapFactory.decodeStream(in); 2218 2219 // Draw the bitmap to an sRGB canvas. 2220 Bitmap canvasBitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); 2221 Canvas canvas = new Canvas(canvasBitmap); 2222 canvas.drawBitmap(bitmap, 0, 0, null); 2223 2224 // Verify that the pixel is now max red. 2225 Assert.assertEquals(0xFFFF0000, canvasBitmap.getPixel(0, 0)); 2226 } catch (IOException e) { 2227 Assert.fail(); 2228 } 2229 } 2230 2231 @Test 2232 public void testShadowLayer_paintColorPreserved() { 2233 Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888); 2234 Canvas canvas = new Canvas(bitmap); 2235 Paint paint = new Paint(); 2236 2237 paint.setShadowLayer(5.0f, 10.0f, 10.0f, 0xFFFF0000); 2238 paint.setColor(0xFF0000FF); 2239 canvas.drawPaint(paint); 2240 2241 // Since the shadow is in the background, the canvas should be blue. 2242 ColorUtils.verifyColor(0xFF0000FF, bitmap.getPixel(50, 50)); 2243 } 2244 } 2245