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