1 /* 2 * Copyright (C) 2006 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; 18 19 import java.io.PrintWriter; 20 21 22 /** 23 * The Matrix class holds a 3x3 matrix for transforming coordinates. 24 */ 25 public class Matrix { 26 27 public static final int MSCALE_X = 0; //!< use with getValues/setValues 28 public static final int MSKEW_X = 1; //!< use with getValues/setValues 29 public static final int MTRANS_X = 2; //!< use with getValues/setValues 30 public static final int MSKEW_Y = 3; //!< use with getValues/setValues 31 public static final int MSCALE_Y = 4; //!< use with getValues/setValues 32 public static final int MTRANS_Y = 5; //!< use with getValues/setValues 33 public static final int MPERSP_0 = 6; //!< use with getValues/setValues 34 public static final int MPERSP_1 = 7; //!< use with getValues/setValues 35 public static final int MPERSP_2 = 8; //!< use with getValues/setValues 36 37 /** @hide */ 38 public final static Matrix IDENTITY_MATRIX = new Matrix() { 39 void oops() { 40 throw new IllegalStateException("Matrix can not be modified"); 41 } 42 43 @Override 44 public void set(Matrix src) { 45 oops(); 46 } 47 48 @Override 49 public void reset() { 50 oops(); 51 } 52 53 @Override 54 public void setTranslate(float dx, float dy) { 55 oops(); 56 } 57 58 @Override 59 public void setScale(float sx, float sy, float px, float py) { 60 oops(); 61 } 62 63 @Override 64 public void setScale(float sx, float sy) { 65 oops(); 66 } 67 68 @Override 69 public void setRotate(float degrees, float px, float py) { 70 oops(); 71 } 72 73 @Override 74 public void setRotate(float degrees) { 75 oops(); 76 } 77 78 @Override 79 public void setSinCos(float sinValue, float cosValue, float px, float py) { 80 oops(); 81 } 82 83 @Override 84 public void setSinCos(float sinValue, float cosValue) { 85 oops(); 86 } 87 88 @Override 89 public void setSkew(float kx, float ky, float px, float py) { 90 oops(); 91 } 92 93 @Override 94 public void setSkew(float kx, float ky) { 95 oops(); 96 } 97 98 @Override 99 public boolean setConcat(Matrix a, Matrix b) { 100 oops(); 101 return false; 102 } 103 104 @Override 105 public boolean preTranslate(float dx, float dy) { 106 oops(); 107 return false; 108 } 109 110 @Override 111 public boolean preScale(float sx, float sy, float px, float py) { 112 oops(); 113 return false; 114 } 115 116 @Override 117 public boolean preScale(float sx, float sy) { 118 oops(); 119 return false; 120 } 121 122 @Override 123 public boolean preRotate(float degrees, float px, float py) { 124 oops(); 125 return false; 126 } 127 128 @Override 129 public boolean preRotate(float degrees) { 130 oops(); 131 return false; 132 } 133 134 @Override 135 public boolean preSkew(float kx, float ky, float px, float py) { 136 oops(); 137 return false; 138 } 139 140 @Override 141 public boolean preSkew(float kx, float ky) { 142 oops(); 143 return false; 144 } 145 146 @Override 147 public boolean preConcat(Matrix other) { 148 oops(); 149 return false; 150 } 151 152 @Override 153 public boolean postTranslate(float dx, float dy) { 154 oops(); 155 return false; 156 } 157 158 @Override 159 public boolean postScale(float sx, float sy, float px, float py) { 160 oops(); 161 return false; 162 } 163 164 @Override 165 public boolean postScale(float sx, float sy) { 166 oops(); 167 return false; 168 } 169 170 @Override 171 public boolean postRotate(float degrees, float px, float py) { 172 oops(); 173 return false; 174 } 175 176 @Override 177 public boolean postRotate(float degrees) { 178 oops(); 179 return false; 180 } 181 182 @Override 183 public boolean postSkew(float kx, float ky, float px, float py) { 184 oops(); 185 return false; 186 } 187 188 @Override 189 public boolean postSkew(float kx, float ky) { 190 oops(); 191 return false; 192 } 193 194 @Override 195 public boolean postConcat(Matrix other) { 196 oops(); 197 return false; 198 } 199 200 @Override 201 public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) { 202 oops(); 203 return false; 204 } 205 206 @Override 207 public boolean setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, 208 int pointCount) { 209 oops(); 210 return false; 211 } 212 213 @Override 214 public void setValues(float[] values) { 215 oops(); 216 } 217 }; 218 219 /** 220 * @hide 221 */ 222 public long native_instance; 223 224 /** 225 * Create an identity matrix 226 */ Matrix()227 public Matrix() { 228 native_instance = native_create(0); 229 } 230 231 /** 232 * Create a matrix that is a (deep) copy of src 233 * @param src The matrix to copy into this matrix 234 */ Matrix(Matrix src)235 public Matrix(Matrix src) { 236 native_instance = native_create(src != null ? src.native_instance : 0); 237 } 238 239 /** 240 * Returns true if the matrix is identity. 241 * This maybe faster than testing if (getType() == 0) 242 */ isIdentity()243 public boolean isIdentity() { 244 return native_isIdentity(native_instance); 245 } 246 247 /** 248 * Gets whether this matrix is affine. An affine matrix preserves 249 * straight lines and has no perspective. 250 * 251 * @return Whether the matrix is affine. 252 */ isAffine()253 public boolean isAffine() { 254 return native_isAffine(native_instance); 255 } 256 257 /** 258 * Returns true if will map a rectangle to another rectangle. This can be 259 * true if the matrix is identity, scale-only, or rotates a multiple of 90 260 * degrees. 261 */ rectStaysRect()262 public boolean rectStaysRect() { 263 return native_rectStaysRect(native_instance); 264 } 265 266 /** 267 * (deep) copy the src matrix into this matrix. If src is null, reset this 268 * matrix to the identity matrix. 269 */ set(Matrix src)270 public void set(Matrix src) { 271 if (src == null) { 272 reset(); 273 } else { 274 native_set(native_instance, src.native_instance); 275 } 276 } 277 278 /** Returns true iff obj is a Matrix and its values equal our values. 279 */ 280 @Override equals(Object obj)281 public boolean equals(Object obj) { 282 //if (obj == this) return true; -- NaN value would mean matrix != itself 283 if (!(obj instanceof Matrix)) return false; 284 return native_equals(native_instance, ((Matrix)obj).native_instance); 285 } 286 287 @Override hashCode()288 public int hashCode() { 289 // This should generate the hash code by performing some arithmetic operation on all 290 // the matrix elements -- our equals() does an element-by-element comparison, and we 291 // need to ensure that the hash code for two equal objects is the same. We're not 292 // really using this at the moment, so we take the easy way out. 293 return 44; 294 } 295 296 /** Set the matrix to identity */ reset()297 public void reset() { 298 native_reset(native_instance); 299 } 300 301 /** Set the matrix to translate by (dx, dy). */ setTranslate(float dx, float dy)302 public void setTranslate(float dx, float dy) { 303 native_setTranslate(native_instance, dx, dy); 304 } 305 306 /** 307 * Set the matrix to scale by sx and sy, with a pivot point at (px, py). 308 * The pivot point is the coordinate that should remain unchanged by the 309 * specified transformation. 310 */ setScale(float sx, float sy, float px, float py)311 public void setScale(float sx, float sy, float px, float py) { 312 native_setScale(native_instance, sx, sy, px, py); 313 } 314 315 /** Set the matrix to scale by sx and sy. */ setScale(float sx, float sy)316 public void setScale(float sx, float sy) { 317 native_setScale(native_instance, sx, sy); 318 } 319 320 /** 321 * Set the matrix to rotate by the specified number of degrees, with a pivot 322 * point at (px, py). The pivot point is the coordinate that should remain 323 * unchanged by the specified transformation. 324 */ setRotate(float degrees, float px, float py)325 public void setRotate(float degrees, float px, float py) { 326 native_setRotate(native_instance, degrees, px, py); 327 } 328 329 /** 330 * Set the matrix to rotate about (0,0) by the specified number of degrees. 331 */ setRotate(float degrees)332 public void setRotate(float degrees) { 333 native_setRotate(native_instance, degrees); 334 } 335 336 /** 337 * Set the matrix to rotate by the specified sine and cosine values, with a 338 * pivot point at (px, py). The pivot point is the coordinate that should 339 * remain unchanged by the specified transformation. 340 */ setSinCos(float sinValue, float cosValue, float px, float py)341 public void setSinCos(float sinValue, float cosValue, float px, float py) { 342 native_setSinCos(native_instance, sinValue, cosValue, px, py); 343 } 344 345 /** Set the matrix to rotate by the specified sine and cosine values. */ setSinCos(float sinValue, float cosValue)346 public void setSinCos(float sinValue, float cosValue) { 347 native_setSinCos(native_instance, sinValue, cosValue); 348 } 349 350 /** 351 * Set the matrix to skew by sx and sy, with a pivot point at (px, py). 352 * The pivot point is the coordinate that should remain unchanged by the 353 * specified transformation. 354 */ setSkew(float kx, float ky, float px, float py)355 public void setSkew(float kx, float ky, float px, float py) { 356 native_setSkew(native_instance, kx, ky, px, py); 357 } 358 359 /** Set the matrix to skew by sx and sy. */ setSkew(float kx, float ky)360 public void setSkew(float kx, float ky) { 361 native_setSkew(native_instance, kx, ky); 362 } 363 364 /** 365 * Set the matrix to the concatenation of the two specified matrices and 366 * return true. 367 * 368 * <p>Either of the two matrices may also be the target matrix, that is 369 * <code>matrixA.setConcat(matrixA, matrixB);</code> is valid.</p> 370 * 371 * <p class="note">In {@link android.os.Build.VERSION_CODES#GINGERBREAD_MR1} and below, this 372 * function returns true only if the result can be represented. In 373 * {@link android.os.Build.VERSION_CODES#HONEYCOMB} and above, it always returns true.</p> 374 */ setConcat(Matrix a, Matrix b)375 public boolean setConcat(Matrix a, Matrix b) { 376 native_setConcat(native_instance, a.native_instance, b.native_instance); 377 return true; 378 } 379 380 /** 381 * Preconcats the matrix with the specified translation. 382 * M' = M * T(dx, dy) 383 */ preTranslate(float dx, float dy)384 public boolean preTranslate(float dx, float dy) { 385 native_preTranslate(native_instance, dx, dy); 386 return true; 387 } 388 389 /** 390 * Preconcats the matrix with the specified scale. 391 * M' = M * S(sx, sy, px, py) 392 */ preScale(float sx, float sy, float px, float py)393 public boolean preScale(float sx, float sy, float px, float py) { 394 native_preScale(native_instance, sx, sy, px, py); 395 return true; 396 } 397 398 /** 399 * Preconcats the matrix with the specified scale. 400 * M' = M * S(sx, sy) 401 */ preScale(float sx, float sy)402 public boolean preScale(float sx, float sy) { 403 native_preScale(native_instance, sx, sy); 404 return true; 405 } 406 407 /** 408 * Preconcats the matrix with the specified rotation. 409 * M' = M * R(degrees, px, py) 410 */ preRotate(float degrees, float px, float py)411 public boolean preRotate(float degrees, float px, float py) { 412 native_preRotate(native_instance, degrees, px, py); 413 return true; 414 } 415 416 /** 417 * Preconcats the matrix with the specified rotation. 418 * M' = M * R(degrees) 419 */ preRotate(float degrees)420 public boolean preRotate(float degrees) { 421 native_preRotate(native_instance, degrees); 422 return true; 423 } 424 425 /** 426 * Preconcats the matrix with the specified skew. 427 * M' = M * K(kx, ky, px, py) 428 */ preSkew(float kx, float ky, float px, float py)429 public boolean preSkew(float kx, float ky, float px, float py) { 430 native_preSkew(native_instance, kx, ky, px, py); 431 return true; 432 } 433 434 /** 435 * Preconcats the matrix with the specified skew. 436 * M' = M * K(kx, ky) 437 */ preSkew(float kx, float ky)438 public boolean preSkew(float kx, float ky) { 439 native_preSkew(native_instance, kx, ky); 440 return true; 441 } 442 443 /** 444 * Preconcats the matrix with the specified matrix. 445 * M' = M * other 446 */ preConcat(Matrix other)447 public boolean preConcat(Matrix other) { 448 native_preConcat(native_instance, other.native_instance); 449 return true; 450 } 451 452 /** 453 * Postconcats the matrix with the specified translation. 454 * M' = T(dx, dy) * M 455 */ postTranslate(float dx, float dy)456 public boolean postTranslate(float dx, float dy) { 457 native_postTranslate(native_instance, dx, dy); 458 return true; 459 } 460 461 /** 462 * Postconcats the matrix with the specified scale. 463 * M' = S(sx, sy, px, py) * M 464 */ postScale(float sx, float sy, float px, float py)465 public boolean postScale(float sx, float sy, float px, float py) { 466 native_postScale(native_instance, sx, sy, px, py); 467 return true; 468 } 469 470 /** 471 * Postconcats the matrix with the specified scale. 472 * M' = S(sx, sy) * M 473 */ postScale(float sx, float sy)474 public boolean postScale(float sx, float sy) { 475 native_postScale(native_instance, sx, sy); 476 return true; 477 } 478 479 /** 480 * Postconcats the matrix with the specified rotation. 481 * M' = R(degrees, px, py) * M 482 */ postRotate(float degrees, float px, float py)483 public boolean postRotate(float degrees, float px, float py) { 484 native_postRotate(native_instance, degrees, px, py); 485 return true; 486 } 487 488 /** 489 * Postconcats the matrix with the specified rotation. 490 * M' = R(degrees) * M 491 */ postRotate(float degrees)492 public boolean postRotate(float degrees) { 493 native_postRotate(native_instance, degrees); 494 return true; 495 } 496 497 /** 498 * Postconcats the matrix with the specified skew. 499 * M' = K(kx, ky, px, py) * M 500 */ postSkew(float kx, float ky, float px, float py)501 public boolean postSkew(float kx, float ky, float px, float py) { 502 native_postSkew(native_instance, kx, ky, px, py); 503 return true; 504 } 505 506 /** 507 * Postconcats the matrix with the specified skew. 508 * M' = K(kx, ky) * M 509 */ postSkew(float kx, float ky)510 public boolean postSkew(float kx, float ky) { 511 native_postSkew(native_instance, kx, ky); 512 return true; 513 } 514 515 /** 516 * Postconcats the matrix with the specified matrix. 517 * M' = other * M 518 */ postConcat(Matrix other)519 public boolean postConcat(Matrix other) { 520 native_postConcat(native_instance, other.native_instance); 521 return true; 522 } 523 524 /** Controlls how the src rect should align into the dst rect for 525 setRectToRect(). 526 */ 527 public enum ScaleToFit { 528 /** 529 * Scale in X and Y independently, so that src matches dst exactly. 530 * This may change the aspect ratio of the src. 531 */ 532 FILL (0), 533 /** 534 * Compute a scale that will maintain the original src aspect ratio, 535 * but will also ensure that src fits entirely inside dst. At least one 536 * axis (X or Y) will fit exactly. START aligns the result to the 537 * left and top edges of dst. 538 */ 539 START (1), 540 /** 541 * Compute a scale that will maintain the original src aspect ratio, 542 * but will also ensure that src fits entirely inside dst. At least one 543 * axis (X or Y) will fit exactly. The result is centered inside dst. 544 */ 545 CENTER (2), 546 /** 547 * Compute a scale that will maintain the original src aspect ratio, 548 * but will also ensure that src fits entirely inside dst. At least one 549 * axis (X or Y) will fit exactly. END aligns the result to the 550 * right and bottom edges of dst. 551 */ 552 END (3); 553 554 // the native values must match those in SkMatrix.h ScaleToFit(int nativeInt)555 ScaleToFit(int nativeInt) { 556 this.nativeInt = nativeInt; 557 } 558 final int nativeInt; 559 } 560 561 /** 562 * Set the matrix to the scale and translate values that map the source 563 * rectangle to the destination rectangle, returning true if the the result 564 * can be represented. 565 * 566 * @param src the source rectangle to map from. 567 * @param dst the destination rectangle to map to. 568 * @param stf the ScaleToFit option 569 * @return true if the matrix can be represented by the rectangle mapping. 570 */ setRectToRect(RectF src, RectF dst, ScaleToFit stf)571 public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) { 572 if (dst == null || src == null) { 573 throw new NullPointerException(); 574 } 575 return native_setRectToRect(native_instance, src, dst, stf.nativeInt); 576 } 577 578 // private helper to perform range checks on arrays of "points" checkPointArrays(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)579 private static void checkPointArrays(float[] src, int srcIndex, 580 float[] dst, int dstIndex, 581 int pointCount) { 582 // check for too-small and too-big indices 583 int srcStop = srcIndex + (pointCount << 1); 584 int dstStop = dstIndex + (pointCount << 1); 585 if ((pointCount | srcIndex | dstIndex | srcStop | dstStop) < 0 || 586 srcStop > src.length || dstStop > dst.length) { 587 throw new ArrayIndexOutOfBoundsException(); 588 } 589 } 590 591 /** 592 * Set the matrix such that the specified src points would map to the 593 * specified dst points. The "points" are represented as an array of floats, 594 * order [x0, y0, x1, y1, ...], where each "point" is 2 float values. 595 * 596 * @param src The array of src [x,y] pairs (points) 597 * @param srcIndex Index of the first pair of src values 598 * @param dst The array of dst [x,y] pairs (points) 599 * @param dstIndex Index of the first pair of dst values 600 * @param pointCount The number of pairs/points to be used. Must be [0..4] 601 * @return true if the matrix was set to the specified transformation 602 */ setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)603 public boolean setPolyToPoly(float[] src, int srcIndex, 604 float[] dst, int dstIndex, 605 int pointCount) { 606 if (pointCount > 4) { 607 throw new IllegalArgumentException(); 608 } 609 checkPointArrays(src, srcIndex, dst, dstIndex, pointCount); 610 return native_setPolyToPoly(native_instance, src, srcIndex, 611 dst, dstIndex, pointCount); 612 } 613 614 /** 615 * If this matrix can be inverted, return true and if inverse is not null, 616 * set inverse to be the inverse of this matrix. If this matrix cannot be 617 * inverted, ignore inverse and return false. 618 */ invert(Matrix inverse)619 public boolean invert(Matrix inverse) { 620 return native_invert(native_instance, inverse.native_instance); 621 } 622 623 /** 624 * Apply this matrix to the array of 2D points specified by src, and write 625 * the transformed points into the array of points specified by dst. The 626 * two arrays represent their "points" as pairs of floats [x, y]. 627 * 628 * @param dst The array of dst points (x,y pairs) 629 * @param dstIndex The index of the first [x,y] pair of dst floats 630 * @param src The array of src points (x,y pairs) 631 * @param srcIndex The index of the first [x,y] pair of src floats 632 * @param pointCount The number of points (x,y pairs) to transform 633 */ mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, int pointCount)634 public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, 635 int pointCount) { 636 checkPointArrays(src, srcIndex, dst, dstIndex, pointCount); 637 native_mapPoints(native_instance, dst, dstIndex, src, srcIndex, 638 pointCount, true); 639 } 640 641 /** 642 * Apply this matrix to the array of 2D vectors specified by src, and write 643 * the transformed vectors into the array of vectors specified by dst. The 644 * two arrays represent their "vectors" as pairs of floats [x, y]. 645 * 646 * Note: this method does not apply the translation associated with the matrix. Use 647 * {@link Matrix#mapPoints(float[], int, float[], int, int)} if you want the translation 648 * to be applied. 649 * 650 * @param dst The array of dst vectors (x,y pairs) 651 * @param dstIndex The index of the first [x,y] pair of dst floats 652 * @param src The array of src vectors (x,y pairs) 653 * @param srcIndex The index of the first [x,y] pair of src floats 654 * @param vectorCount The number of vectors (x,y pairs) to transform 655 */ mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int vectorCount)656 public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, 657 int vectorCount) { 658 checkPointArrays(src, srcIndex, dst, dstIndex, vectorCount); 659 native_mapPoints(native_instance, dst, dstIndex, src, srcIndex, 660 vectorCount, false); 661 } 662 663 /** 664 * Apply this matrix to the array of 2D points specified by src, and write 665 * the transformed points into the array of points specified by dst. The 666 * two arrays represent their "points" as pairs of floats [x, y]. 667 * 668 * @param dst The array of dst points (x,y pairs) 669 * @param src The array of src points (x,y pairs) 670 */ mapPoints(float[] dst, float[] src)671 public void mapPoints(float[] dst, float[] src) { 672 if (dst.length != src.length) { 673 throw new ArrayIndexOutOfBoundsException(); 674 } 675 mapPoints(dst, 0, src, 0, dst.length >> 1); 676 } 677 678 /** 679 * Apply this matrix to the array of 2D vectors specified by src, and write 680 * the transformed vectors into the array of vectors specified by dst. The 681 * two arrays represent their "vectors" as pairs of floats [x, y]. 682 * 683 * Note: this method does not apply the translation associated with the matrix. Use 684 * {@link Matrix#mapPoints(float[], float[])} if you want the translation to be applied. 685 * 686 * @param dst The array of dst vectors (x,y pairs) 687 * @param src The array of src vectors (x,y pairs) 688 */ mapVectors(float[] dst, float[] src)689 public void mapVectors(float[] dst, float[] src) { 690 if (dst.length != src.length) { 691 throw new ArrayIndexOutOfBoundsException(); 692 } 693 mapVectors(dst, 0, src, 0, dst.length >> 1); 694 } 695 696 /** 697 * Apply this matrix to the array of 2D points, and write the transformed 698 * points back into the array 699 * 700 * @param pts The array [x0, y0, x1, y1, ...] of points to transform. 701 */ mapPoints(float[] pts)702 public void mapPoints(float[] pts) { 703 mapPoints(pts, 0, pts, 0, pts.length >> 1); 704 } 705 706 /** 707 * Apply this matrix to the array of 2D vectors, and write the transformed 708 * vectors back into the array. 709 * 710 * Note: this method does not apply the translation associated with the matrix. Use 711 * {@link Matrix#mapPoints(float[])} if you want the translation to be applied. 712 * 713 * @param vecs The array [x0, y0, x1, y1, ...] of vectors to transform. 714 */ mapVectors(float[] vecs)715 public void mapVectors(float[] vecs) { 716 mapVectors(vecs, 0, vecs, 0, vecs.length >> 1); 717 } 718 719 /** 720 * Apply this matrix to the src rectangle, and write the transformed 721 * rectangle into dst. This is accomplished by transforming the 4 corners of 722 * src, and then setting dst to the bounds of those points. 723 * 724 * @param dst Where the transformed rectangle is written. 725 * @param src The original rectangle to be transformed. 726 * @return the result of calling rectStaysRect() 727 */ mapRect(RectF dst, RectF src)728 public boolean mapRect(RectF dst, RectF src) { 729 if (dst == null || src == null) { 730 throw new NullPointerException(); 731 } 732 return native_mapRect(native_instance, dst, src); 733 } 734 735 /** 736 * Apply this matrix to the rectangle, and write the transformed rectangle 737 * back into it. This is accomplished by transforming the 4 corners of rect, 738 * and then setting it to the bounds of those points 739 * 740 * @param rect The rectangle to transform. 741 * @return the result of calling rectStaysRect() 742 */ mapRect(RectF rect)743 public boolean mapRect(RectF rect) { 744 return mapRect(rect, rect); 745 } 746 747 /** 748 * Return the mean radius of a circle after it has been mapped by 749 * this matrix. NOTE: in perspective this value assumes the circle 750 * has its center at the origin. 751 */ mapRadius(float radius)752 public float mapRadius(float radius) { 753 return native_mapRadius(native_instance, radius); 754 } 755 756 /** Copy 9 values from the matrix into the array. 757 */ getValues(float[] values)758 public void getValues(float[] values) { 759 if (values.length < 9) { 760 throw new ArrayIndexOutOfBoundsException(); 761 } 762 native_getValues(native_instance, values); 763 } 764 765 /** Copy 9 values from the array into the matrix. 766 Depending on the implementation of Matrix, these may be 767 transformed into 16.16 integers in the Matrix, such that 768 a subsequent call to getValues() will not yield exactly 769 the same values. 770 */ setValues(float[] values)771 public void setValues(float[] values) { 772 if (values.length < 9) { 773 throw new ArrayIndexOutOfBoundsException(); 774 } 775 native_setValues(native_instance, values); 776 } 777 778 @Override toString()779 public String toString() { 780 StringBuilder sb = new StringBuilder(64); 781 sb.append("Matrix{"); 782 toShortString(sb); 783 sb.append('}'); 784 return sb.toString(); 785 786 } 787 toShortString()788 public String toShortString() { 789 StringBuilder sb = new StringBuilder(64); 790 toShortString(sb); 791 return sb.toString(); 792 } 793 794 /** 795 * @hide 796 */ toShortString(StringBuilder sb)797 public void toShortString(StringBuilder sb) { 798 float[] values = new float[9]; 799 getValues(values); 800 sb.append('['); 801 sb.append(values[0]); sb.append(", "); sb.append(values[1]); sb.append(", "); 802 sb.append(values[2]); sb.append("]["); 803 sb.append(values[3]); sb.append(", "); sb.append(values[4]); sb.append(", "); 804 sb.append(values[5]); sb.append("]["); 805 sb.append(values[6]); sb.append(", "); sb.append(values[7]); sb.append(", "); 806 sb.append(values[8]); sb.append(']'); 807 } 808 809 /** 810 * Print short string, to optimize dumping. 811 * @hide 812 */ printShortString(PrintWriter pw)813 public void printShortString(PrintWriter pw) { 814 float[] values = new float[9]; 815 getValues(values); 816 pw.print('['); 817 pw.print(values[0]); pw.print(", "); pw.print(values[1]); pw.print(", "); 818 pw.print(values[2]); pw.print("]["); 819 pw.print(values[3]); pw.print(", "); pw.print(values[4]); pw.print(", "); 820 pw.print(values[5]); pw.print("]["); 821 pw.print(values[6]); pw.print(", "); pw.print(values[7]); pw.print(", "); 822 pw.print(values[8]); pw.print(']'); 823 824 } 825 826 @Override finalize()827 protected void finalize() throws Throwable { 828 try { 829 finalizer(native_instance); 830 native_instance = 0; // Other finalizers can still call us. 831 } finally { 832 super.finalize(); 833 } 834 } 835 ni()836 /*package*/ final long ni() { 837 return native_instance; 838 } 839 native_create(long native_src_or_zero)840 private static native long native_create(long native_src_or_zero); native_isIdentity(long native_object)841 private static native boolean native_isIdentity(long native_object); native_isAffine(long native_object)842 private static native boolean native_isAffine(long native_object); native_rectStaysRect(long native_object)843 private static native boolean native_rectStaysRect(long native_object); native_reset(long native_object)844 private static native void native_reset(long native_object); native_set(long native_object, long native_other)845 private static native void native_set(long native_object, 846 long native_other); native_setTranslate(long native_object, float dx, float dy)847 private static native void native_setTranslate(long native_object, 848 float dx, float dy); native_setScale(long native_object, float sx, float sy, float px, float py)849 private static native void native_setScale(long native_object, 850 float sx, float sy, float px, float py); native_setScale(long native_object, float sx, float sy)851 private static native void native_setScale(long native_object, 852 float sx, float sy); native_setRotate(long native_object, float degrees, float px, float py)853 private static native void native_setRotate(long native_object, 854 float degrees, float px, float py); native_setRotate(long native_object, float degrees)855 private static native void native_setRotate(long native_object, 856 float degrees); native_setSinCos(long native_object, float sinValue, float cosValue, float px, float py)857 private static native void native_setSinCos(long native_object, 858 float sinValue, float cosValue, float px, float py); native_setSinCos(long native_object, float sinValue, float cosValue)859 private static native void native_setSinCos(long native_object, 860 float sinValue, float cosValue); native_setSkew(long native_object, float kx, float ky, float px, float py)861 private static native void native_setSkew(long native_object, 862 float kx, float ky, float px, float py); native_setSkew(long native_object, float kx, float ky)863 private static native void native_setSkew(long native_object, 864 float kx, float ky); native_setConcat(long native_object, long native_a, long native_b)865 private static native void native_setConcat(long native_object, 866 long native_a, 867 long native_b); native_preTranslate(long native_object, float dx, float dy)868 private static native void native_preTranslate(long native_object, 869 float dx, float dy); native_preScale(long native_object, float sx, float sy, float px, float py)870 private static native void native_preScale(long native_object, 871 float sx, float sy, float px, float py); native_preScale(long native_object, float sx, float sy)872 private static native void native_preScale(long native_object, 873 float sx, float sy); native_preRotate(long native_object, float degrees, float px, float py)874 private static native void native_preRotate(long native_object, 875 float degrees, float px, float py); native_preRotate(long native_object, float degrees)876 private static native void native_preRotate(long native_object, 877 float degrees); native_preSkew(long native_object, float kx, float ky, float px, float py)878 private static native void native_preSkew(long native_object, 879 float kx, float ky, float px, float py); native_preSkew(long native_object, float kx, float ky)880 private static native void native_preSkew(long native_object, 881 float kx, float ky); native_preConcat(long native_object, long native_other_matrix)882 private static native void native_preConcat(long native_object, 883 long native_other_matrix); native_postTranslate(long native_object, float dx, float dy)884 private static native void native_postTranslate(long native_object, 885 float dx, float dy); native_postScale(long native_object, float sx, float sy, float px, float py)886 private static native void native_postScale(long native_object, 887 float sx, float sy, float px, float py); native_postScale(long native_object, float sx, float sy)888 private static native void native_postScale(long native_object, 889 float sx, float sy); native_postRotate(long native_object, float degrees, float px, float py)890 private static native void native_postRotate(long native_object, 891 float degrees, float px, float py); native_postRotate(long native_object, float degrees)892 private static native void native_postRotate(long native_object, 893 float degrees); native_postSkew(long native_object, float kx, float ky, float px, float py)894 private static native void native_postSkew(long native_object, 895 float kx, float ky, float px, float py); native_postSkew(long native_object, float kx, float ky)896 private static native void native_postSkew(long native_object, 897 float kx, float ky); native_postConcat(long native_object, long native_other_matrix)898 private static native void native_postConcat(long native_object, 899 long native_other_matrix); native_setRectToRect(long native_object, RectF src, RectF dst, int stf)900 private static native boolean native_setRectToRect(long native_object, 901 RectF src, RectF dst, int stf); native_setPolyToPoly(long native_object, float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)902 private static native boolean native_setPolyToPoly(long native_object, 903 float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount); native_invert(long native_object, long native_inverse)904 private static native boolean native_invert(long native_object, 905 long native_inverse); native_mapPoints(long native_object, float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount, boolean isPts)906 private static native void native_mapPoints(long native_object, 907 float[] dst, int dstIndex, float[] src, int srcIndex, 908 int ptCount, boolean isPts); native_mapRect(long native_object, RectF dst, RectF src)909 private static native boolean native_mapRect(long native_object, 910 RectF dst, RectF src); native_mapRadius(long native_object, float radius)911 private static native float native_mapRadius(long native_object, 912 float radius); native_getValues(long native_object, float[] values)913 private static native void native_getValues(long native_object, 914 float[] values); native_setValues(long native_object, float[] values)915 private static native void native_setValues(long native_object, 916 float[] values); native_equals(long native_a, long native_b)917 private static native boolean native_equals(long native_a, long native_b); finalizer(long native_instance)918 private static native void finalizer(long native_instance); 919 } 920