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 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 int 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 * Returns true if will map a rectangle to another rectangle. This can be 249 * true if the matrix is identity, scale-only, or rotates a multiple of 90 250 * degrees. 251 */ rectStaysRect()252 public boolean rectStaysRect() { 253 return native_rectStaysRect(native_instance); 254 } 255 256 /** 257 * (deep) copy the src matrix into this matrix. If src is null, reset this 258 * matrix to the identity matrix. 259 */ set(Matrix src)260 public void set(Matrix src) { 261 if (src == null) { 262 reset(); 263 } else { 264 native_set(native_instance, src.native_instance); 265 } 266 } 267 268 /** Returns true iff obj is a Matrix and its values equal our values. 269 */ 270 @Override equals(Object obj)271 public boolean equals(Object obj) { 272 //if (obj == this) return true; -- NaN value would mean matrix != itself 273 if (!(obj instanceof Matrix)) return false; 274 return native_equals(native_instance, ((Matrix)obj).native_instance); 275 } 276 277 @Override hashCode()278 public int hashCode() { 279 // This should generate the hash code by performing some arithmetic operation on all 280 // the matrix elements -- our equals() does an element-by-element comparison, and we 281 // need to ensure that the hash code for two equal objects is the same. We're not 282 // really using this at the moment, so we take the easy way out. 283 return 44; 284 } 285 286 /** Set the matrix to identity */ reset()287 public void reset() { 288 native_reset(native_instance); 289 } 290 291 /** Set the matrix to translate by (dx, dy). */ setTranslate(float dx, float dy)292 public void setTranslate(float dx, float dy) { 293 native_setTranslate(native_instance, dx, dy); 294 } 295 296 /** 297 * Set the matrix to scale by sx and sy, with a pivot point at (px, py). 298 * The pivot point is the coordinate that should remain unchanged by the 299 * specified transformation. 300 */ setScale(float sx, float sy, float px, float py)301 public void setScale(float sx, float sy, float px, float py) { 302 native_setScale(native_instance, sx, sy, px, py); 303 } 304 305 /** Set the matrix to scale by sx and sy. */ setScale(float sx, float sy)306 public void setScale(float sx, float sy) { 307 native_setScale(native_instance, sx, sy); 308 } 309 310 /** 311 * Set the matrix to rotate by the specified number of degrees, with a pivot 312 * point at (px, py). The pivot point is the coordinate that should remain 313 * unchanged by the specified transformation. 314 */ setRotate(float degrees, float px, float py)315 public void setRotate(float degrees, float px, float py) { 316 native_setRotate(native_instance, degrees, px, py); 317 } 318 319 /** 320 * Set the matrix to rotate about (0,0) by the specified number of degrees. 321 */ setRotate(float degrees)322 public void setRotate(float degrees) { 323 native_setRotate(native_instance, degrees); 324 } 325 326 /** 327 * Set the matrix to rotate by the specified sine and cosine values, with a 328 * pivot point at (px, py). The pivot point is the coordinate that should 329 * remain unchanged by the specified transformation. 330 */ setSinCos(float sinValue, float cosValue, float px, float py)331 public void setSinCos(float sinValue, float cosValue, float px, float py) { 332 native_setSinCos(native_instance, sinValue, cosValue, px, py); 333 } 334 335 /** Set the matrix to rotate by the specified sine and cosine values. */ setSinCos(float sinValue, float cosValue)336 public void setSinCos(float sinValue, float cosValue) { 337 native_setSinCos(native_instance, sinValue, cosValue); 338 } 339 340 /** 341 * Set the matrix to skew by sx and sy, with a pivot point at (px, py). 342 * The pivot point is the coordinate that should remain unchanged by the 343 * specified transformation. 344 */ setSkew(float kx, float ky, float px, float py)345 public void setSkew(float kx, float ky, float px, float py) { 346 native_setSkew(native_instance, kx, ky, px, py); 347 } 348 349 /** Set the matrix to skew by sx and sy. */ setSkew(float kx, float ky)350 public void setSkew(float kx, float ky) { 351 native_setSkew(native_instance, kx, ky); 352 } 353 354 /** 355 * Set the matrix to the concatenation of the two specified matrices, 356 * returning true if the the result can be represented. Either of the two 357 * matrices may also be the target matrix. this = a * b 358 */ setConcat(Matrix a, Matrix b)359 public boolean setConcat(Matrix a, Matrix b) { 360 return native_setConcat(native_instance, a.native_instance, 361 b.native_instance); 362 } 363 364 /** 365 * Preconcats the matrix with the specified translation. 366 * M' = M * T(dx, dy) 367 */ preTranslate(float dx, float dy)368 public boolean preTranslate(float dx, float dy) { 369 return native_preTranslate(native_instance, dx, dy); 370 } 371 372 /** 373 * Preconcats the matrix with the specified scale. 374 * M' = M * S(sx, sy, px, py) 375 */ preScale(float sx, float sy, float px, float py)376 public boolean preScale(float sx, float sy, float px, float py) { 377 return native_preScale(native_instance, sx, sy, px, py); 378 } 379 380 /** 381 * Preconcats the matrix with the specified scale. 382 * M' = M * S(sx, sy) 383 */ preScale(float sx, float sy)384 public boolean preScale(float sx, float sy) { 385 return native_preScale(native_instance, sx, sy); 386 } 387 388 /** 389 * Preconcats the matrix with the specified rotation. 390 * M' = M * R(degrees, px, py) 391 */ preRotate(float degrees, float px, float py)392 public boolean preRotate(float degrees, float px, float py) { 393 return native_preRotate(native_instance, degrees, px, py); 394 } 395 396 /** 397 * Preconcats the matrix with the specified rotation. 398 * M' = M * R(degrees) 399 */ preRotate(float degrees)400 public boolean preRotate(float degrees) { 401 return native_preRotate(native_instance, degrees); 402 } 403 404 /** 405 * Preconcats the matrix with the specified skew. 406 * M' = M * K(kx, ky, px, py) 407 */ preSkew(float kx, float ky, float px, float py)408 public boolean preSkew(float kx, float ky, float px, float py) { 409 return native_preSkew(native_instance, kx, ky, px, py); 410 } 411 412 /** 413 * Preconcats the matrix with the specified skew. 414 * M' = M * K(kx, ky) 415 */ preSkew(float kx, float ky)416 public boolean preSkew(float kx, float ky) { 417 return native_preSkew(native_instance, kx, ky); 418 } 419 420 /** 421 * Preconcats the matrix with the specified matrix. 422 * M' = M * other 423 */ preConcat(Matrix other)424 public boolean preConcat(Matrix other) { 425 return native_preConcat(native_instance, other.native_instance); 426 } 427 428 /** 429 * Postconcats the matrix with the specified translation. 430 * M' = T(dx, dy) * M 431 */ postTranslate(float dx, float dy)432 public boolean postTranslate(float dx, float dy) { 433 return native_postTranslate(native_instance, dx, dy); 434 } 435 436 /** 437 * Postconcats the matrix with the specified scale. 438 * M' = S(sx, sy, px, py) * M 439 */ postScale(float sx, float sy, float px, float py)440 public boolean postScale(float sx, float sy, float px, float py) { 441 return native_postScale(native_instance, sx, sy, px, py); 442 } 443 444 /** 445 * Postconcats the matrix with the specified scale. 446 * M' = S(sx, sy) * M 447 */ postScale(float sx, float sy)448 public boolean postScale(float sx, float sy) { 449 return native_postScale(native_instance, sx, sy); 450 } 451 452 /** 453 * Postconcats the matrix with the specified rotation. 454 * M' = R(degrees, px, py) * M 455 */ postRotate(float degrees, float px, float py)456 public boolean postRotate(float degrees, float px, float py) { 457 return native_postRotate(native_instance, degrees, px, py); 458 } 459 460 /** 461 * Postconcats the matrix with the specified rotation. 462 * M' = R(degrees) * M 463 */ postRotate(float degrees)464 public boolean postRotate(float degrees) { 465 return native_postRotate(native_instance, degrees); 466 } 467 468 /** 469 * Postconcats the matrix with the specified skew. 470 * M' = K(kx, ky, px, py) * M 471 */ postSkew(float kx, float ky, float px, float py)472 public boolean postSkew(float kx, float ky, float px, float py) { 473 return native_postSkew(native_instance, kx, ky, px, py); 474 } 475 476 /** 477 * Postconcats the matrix with the specified skew. 478 * M' = K(kx, ky) * M 479 */ postSkew(float kx, float ky)480 public boolean postSkew(float kx, float ky) { 481 return native_postSkew(native_instance, kx, ky); 482 } 483 484 /** 485 * Postconcats the matrix with the specified matrix. 486 * M' = other * M 487 */ postConcat(Matrix other)488 public boolean postConcat(Matrix other) { 489 return native_postConcat(native_instance, other.native_instance); 490 } 491 492 /** Controlls how the src rect should align into the dst rect for 493 setRectToRect(). 494 */ 495 public enum ScaleToFit { 496 /** 497 * Scale in X and Y independently, so that src matches dst exactly. 498 * This may change the aspect ratio of the src. 499 */ 500 FILL (0), 501 /** 502 * Compute a scale that will maintain the original src aspect ratio, 503 * but will also ensure that src fits entirely inside dst. At least one 504 * axis (X or Y) will fit exactly. START aligns the result to the 505 * left and top edges of dst. 506 */ 507 START (1), 508 /** 509 * Compute a scale that will maintain the original src aspect ratio, 510 * but will also ensure that src fits entirely inside dst. At least one 511 * axis (X or Y) will fit exactly. The result is centered inside dst. 512 */ 513 CENTER (2), 514 /** 515 * Compute a scale that will maintain the original src aspect ratio, 516 * but will also ensure that src fits entirely inside dst. At least one 517 * axis (X or Y) will fit exactly. END aligns the result to the 518 * right and bottom edges of dst. 519 */ 520 END (3); 521 522 // the native values must match those in SkMatrix.h ScaleToFit(int nativeInt)523 ScaleToFit(int nativeInt) { 524 this.nativeInt = nativeInt; 525 } 526 final int nativeInt; 527 } 528 529 /** 530 * Set the matrix to the scale and translate values that map the source 531 * rectangle to the destination rectangle, returning true if the the result 532 * can be represented. 533 * 534 * @param src the source rectangle to map from. 535 * @param dst the destination rectangle to map to. 536 * @param stf the ScaleToFit option 537 * @return true if the matrix can be represented by the rectangle mapping. 538 */ setRectToRect(RectF src, RectF dst, ScaleToFit stf)539 public boolean setRectToRect(RectF src, RectF dst, ScaleToFit stf) { 540 if (dst == null || src == null) { 541 throw new NullPointerException(); 542 } 543 return native_setRectToRect(native_instance, src, dst, stf.nativeInt); 544 } 545 546 // private helper to perform range checks on arrays of "points" checkPointArrays(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)547 private static void checkPointArrays(float[] src, int srcIndex, 548 float[] dst, int dstIndex, 549 int pointCount) { 550 // check for too-small and too-big indices 551 int srcStop = srcIndex + (pointCount << 1); 552 int dstStop = dstIndex + (pointCount << 1); 553 if ((pointCount | srcIndex | dstIndex | srcStop | dstStop) < 0 || 554 srcStop > src.length || dstStop > dst.length) { 555 throw new ArrayIndexOutOfBoundsException(); 556 } 557 } 558 559 /** 560 * Set the matrix such that the specified src points would map to the 561 * specified dst points. The "points" are represented as an array of floats, 562 * order [x0, y0, x1, y1, ...], where each "point" is 2 float values. 563 * 564 * @param src The array of src [x,y] pairs (points) 565 * @param srcIndex Index of the first pair of src values 566 * @param dst The array of dst [x,y] pairs (points) 567 * @param dstIndex Index of the first pair of dst values 568 * @param pointCount The number of pairs/points to be used. Must be [0..4] 569 * @return true if the matrix was set to the specified transformation 570 */ setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)571 public boolean setPolyToPoly(float[] src, int srcIndex, 572 float[] dst, int dstIndex, 573 int pointCount) { 574 if (pointCount > 4) { 575 throw new IllegalArgumentException(); 576 } 577 checkPointArrays(src, srcIndex, dst, dstIndex, pointCount); 578 return native_setPolyToPoly(native_instance, src, srcIndex, 579 dst, dstIndex, pointCount); 580 } 581 582 /** 583 * If this matrix can be inverted, return true and if inverse is not null, 584 * set inverse to be the inverse of this matrix. If this matrix cannot be 585 * inverted, ignore inverse and return false. 586 */ invert(Matrix inverse)587 public boolean invert(Matrix inverse) { 588 return native_invert(native_instance, inverse.native_instance); 589 } 590 591 /** 592 * Apply this matrix to the array of 2D points specified by src, and write 593 * the transformed points into the array of points specified by dst. The 594 * two arrays represent their "points" as pairs of floats [x, y]. 595 * 596 * @param dst The array of dst points (x,y pairs) 597 * @param dstIndex The index of the first [x,y] pair of dst floats 598 * @param src The array of src points (x,y pairs) 599 * @param srcIndex The index of the first [x,y] pair of src floats 600 * @param pointCount The number of points (x,y pairs) to transform 601 */ mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, int pointCount)602 public void mapPoints(float[] dst, int dstIndex, float[] src, int srcIndex, 603 int pointCount) { 604 checkPointArrays(src, srcIndex, dst, dstIndex, pointCount); 605 native_mapPoints(native_instance, dst, dstIndex, src, srcIndex, 606 pointCount, true); 607 } 608 609 /** 610 * Apply this matrix to the array of 2D vectors specified by src, and write 611 * the transformed vectors into the array of vectors specified by dst. The 612 * two arrays represent their "vectors" as pairs of floats [x, y]. 613 * 614 * Note: this method does not apply the translation associated with the matrix. Use 615 * {@link Matrix#mapPoints(float[], int, float[], int, int)} if you want the translation 616 * to be applied. 617 * 618 * @param dst The array of dst vectors (x,y pairs) 619 * @param dstIndex The index of the first [x,y] pair of dst floats 620 * @param src The array of src vectors (x,y pairs) 621 * @param srcIndex The index of the first [x,y] pair of src floats 622 * @param vectorCount The number of vectors (x,y pairs) to transform 623 */ mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int vectorCount)624 public void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, 625 int vectorCount) { 626 checkPointArrays(src, srcIndex, dst, dstIndex, vectorCount); 627 native_mapPoints(native_instance, dst, dstIndex, src, srcIndex, 628 vectorCount, false); 629 } 630 631 /** 632 * Apply this matrix to the array of 2D points specified by src, and write 633 * the transformed points into the array of points specified by dst. The 634 * two arrays represent their "points" as pairs of floats [x, y]. 635 * 636 * @param dst The array of dst points (x,y pairs) 637 * @param src The array of src points (x,y pairs) 638 */ mapPoints(float[] dst, float[] src)639 public void mapPoints(float[] dst, float[] src) { 640 if (dst.length != src.length) { 641 throw new ArrayIndexOutOfBoundsException(); 642 } 643 mapPoints(dst, 0, src, 0, dst.length >> 1); 644 } 645 646 /** 647 * Apply this matrix to the array of 2D vectors specified by src, and write 648 * the transformed vectors into the array of vectors specified by dst. The 649 * two arrays represent their "vectors" as pairs of floats [x, y]. 650 * 651 * Note: this method does not apply the translation associated with the matrix. Use 652 * {@link Matrix#mapPoints(float[], float[])} if you want the translation to be applied. 653 * 654 * @param dst The array of dst vectors (x,y pairs) 655 * @param src The array of src vectors (x,y pairs) 656 */ mapVectors(float[] dst, float[] src)657 public void mapVectors(float[] dst, float[] src) { 658 if (dst.length != src.length) { 659 throw new ArrayIndexOutOfBoundsException(); 660 } 661 mapVectors(dst, 0, src, 0, dst.length >> 1); 662 } 663 664 /** 665 * Apply this matrix to the array of 2D points, and write the transformed 666 * points back into the array 667 * 668 * @param pts The array [x0, y0, x1, y1, ...] of points to transform. 669 */ mapPoints(float[] pts)670 public void mapPoints(float[] pts) { 671 mapPoints(pts, 0, pts, 0, pts.length >> 1); 672 } 673 674 /** 675 * Apply this matrix to the array of 2D vectors, and write the transformed 676 * vectors back into the array. 677 * 678 * Note: this method does not apply the translation associated with the matrix. Use 679 * {@link Matrix#mapPoints(float[])} if you want the translation to be applied. 680 * 681 * @param vecs The array [x0, y0, x1, y1, ...] of vectors to transform. 682 */ mapVectors(float[] vecs)683 public void mapVectors(float[] vecs) { 684 mapVectors(vecs, 0, vecs, 0, vecs.length >> 1); 685 } 686 687 /** 688 * Apply this matrix to the src rectangle, and write the transformed 689 * rectangle into dst. This is accomplished by transforming the 4 corners of 690 * src, and then setting dst to the bounds of those points. 691 * 692 * @param dst Where the transformed rectangle is written. 693 * @param src The original rectangle to be transformed. 694 * @return the result of calling rectStaysRect() 695 */ mapRect(RectF dst, RectF src)696 public boolean mapRect(RectF dst, RectF src) { 697 if (dst == null || src == null) { 698 throw new NullPointerException(); 699 } 700 return native_mapRect(native_instance, dst, src); 701 } 702 703 /** 704 * Apply this matrix to the rectangle, and write the transformed rectangle 705 * back into it. This is accomplished by transforming the 4 corners of rect, 706 * and then setting it to the bounds of those points 707 * 708 * @param rect The rectangle to transform. 709 * @return the result of calling rectStaysRect() 710 */ mapRect(RectF rect)711 public boolean mapRect(RectF rect) { 712 return mapRect(rect, rect); 713 } 714 715 /** 716 * Return the mean radius of a circle after it has been mapped by 717 * this matrix. NOTE: in perspective this value assumes the circle 718 * has its center at the origin. 719 */ mapRadius(float radius)720 public float mapRadius(float radius) { 721 return native_mapRadius(native_instance, radius); 722 } 723 724 /** Copy 9 values from the matrix into the array. 725 */ getValues(float[] values)726 public void getValues(float[] values) { 727 if (values.length < 9) { 728 throw new ArrayIndexOutOfBoundsException(); 729 } 730 native_getValues(native_instance, values); 731 } 732 733 /** Copy 9 values from the array into the matrix. 734 Depending on the implementation of Matrix, these may be 735 transformed into 16.16 integers in the Matrix, such that 736 a subsequent call to getValues() will not yield exactly 737 the same values. 738 */ setValues(float[] values)739 public void setValues(float[] values) { 740 if (values.length < 9) { 741 throw new ArrayIndexOutOfBoundsException(); 742 } 743 native_setValues(native_instance, values); 744 } 745 746 @Override toString()747 public String toString() { 748 StringBuilder sb = new StringBuilder(64); 749 sb.append("Matrix{"); 750 toShortString(sb); 751 sb.append('}'); 752 return sb.toString(); 753 754 } 755 toShortString()756 public String toShortString() { 757 StringBuilder sb = new StringBuilder(64); 758 toShortString(sb); 759 return sb.toString(); 760 } 761 762 /** 763 * @hide 764 */ toShortString(StringBuilder sb)765 public void toShortString(StringBuilder sb) { 766 float[] values = new float[9]; 767 getValues(values); 768 sb.append('['); 769 sb.append(values[0]); sb.append(", "); sb.append(values[1]); sb.append(", "); 770 sb.append(values[2]); sb.append("]["); 771 sb.append(values[3]); sb.append(", "); sb.append(values[4]); sb.append(", "); 772 sb.append(values[5]); sb.append("]["); 773 sb.append(values[6]); sb.append(", "); sb.append(values[7]); sb.append(", "); 774 sb.append(values[8]); sb.append(']'); 775 } 776 777 /** 778 * Print short string, to optimize dumping. 779 * @hide 780 */ printShortString(PrintWriter pw)781 public void printShortString(PrintWriter pw) { 782 float[] values = new float[9]; 783 getValues(values); 784 pw.print('['); 785 pw.print(values[0]); pw.print(", "); pw.print(values[1]); pw.print(", "); 786 pw.print(values[2]); pw.print("]["); 787 pw.print(values[3]); pw.print(", "); pw.print(values[4]); pw.print(", "); 788 pw.print(values[5]); pw.print("]["); 789 pw.print(values[6]); pw.print(", "); pw.print(values[7]); pw.print(", "); 790 pw.print(values[8]); pw.print(']'); 791 792 } 793 794 @Override finalize()795 protected void finalize() throws Throwable { 796 try { 797 finalizer(native_instance); 798 } finally { 799 super.finalize(); 800 } 801 } 802 ni()803 /*package*/ final int ni() { 804 return native_instance; 805 } 806 native_create(int native_src_or_zero)807 private static native int native_create(int native_src_or_zero); native_isIdentity(int native_object)808 private static native boolean native_isIdentity(int native_object); native_rectStaysRect(int native_object)809 private static native boolean native_rectStaysRect(int native_object); native_reset(int native_object)810 private static native void native_reset(int native_object); native_set(int native_object, int other)811 private static native void native_set(int native_object, int other); native_setTranslate(int native_object, float dx, float dy)812 private static native void native_setTranslate(int native_object, 813 float dx, float dy); native_setScale(int native_object, float sx, float sy, float px, float py)814 private static native void native_setScale(int native_object, 815 float sx, float sy, float px, float py); native_setScale(int native_object, float sx, float sy)816 private static native void native_setScale(int native_object, 817 float sx, float sy); native_setRotate(int native_object, float degrees, float px, float py)818 private static native void native_setRotate(int native_object, 819 float degrees, float px, float py); native_setRotate(int native_object, float degrees)820 private static native void native_setRotate(int native_object, 821 float degrees); native_setSinCos(int native_object, float sinValue, float cosValue, float px, float py)822 private static native void native_setSinCos(int native_object, 823 float sinValue, float cosValue, float px, float py); native_setSinCos(int native_object, float sinValue, float cosValue)824 private static native void native_setSinCos(int native_object, 825 float sinValue, float cosValue); native_setSkew(int native_object, float kx, float ky, float px, float py)826 private static native void native_setSkew(int native_object, 827 float kx, float ky, float px, float py); native_setSkew(int native_object, float kx, float ky)828 private static native void native_setSkew(int native_object, 829 float kx, float ky); native_setConcat(int native_object, int a, int b)830 private static native boolean native_setConcat(int native_object, 831 int a, int b); native_preTranslate(int native_object, float dx, float dy)832 private static native boolean native_preTranslate(int native_object, 833 float dx, float dy); native_preScale(int native_object, float sx, float sy, float px, float py)834 private static native boolean native_preScale(int native_object, 835 float sx, float sy, float px, float py); native_preScale(int native_object, float sx, float sy)836 private static native boolean native_preScale(int native_object, 837 float sx, float sy); native_preRotate(int native_object, float degrees, float px, float py)838 private static native boolean native_preRotate(int native_object, 839 float degrees, float px, float py); native_preRotate(int native_object, float degrees)840 private static native boolean native_preRotate(int native_object, 841 float degrees); native_preSkew(int native_object, float kx, float ky, float px, float py)842 private static native boolean native_preSkew(int native_object, 843 float kx, float ky, float px, float py); native_preSkew(int native_object, float kx, float ky)844 private static native boolean native_preSkew(int native_object, 845 float kx, float ky); native_preConcat(int native_object, int other_matrix)846 private static native boolean native_preConcat(int native_object, 847 int other_matrix); native_postTranslate(int native_object, float dx, float dy)848 private static native boolean native_postTranslate(int native_object, 849 float dx, float dy); native_postScale(int native_object, float sx, float sy, float px, float py)850 private static native boolean native_postScale(int native_object, 851 float sx, float sy, float px, float py); native_postScale(int native_object, float sx, float sy)852 private static native boolean native_postScale(int native_object, 853 float sx, float sy); native_postRotate(int native_object, float degrees, float px, float py)854 private static native boolean native_postRotate(int native_object, 855 float degrees, float px, float py); native_postRotate(int native_object, float degrees)856 private static native boolean native_postRotate(int native_object, 857 float degrees); native_postSkew(int native_object, float kx, float ky, float px, float py)858 private static native boolean native_postSkew(int native_object, 859 float kx, float ky, float px, float py); native_postSkew(int native_object, float kx, float ky)860 private static native boolean native_postSkew(int native_object, 861 float kx, float ky); native_postConcat(int native_object, int other_matrix)862 private static native boolean native_postConcat(int native_object, 863 int other_matrix); native_setRectToRect(int native_object, RectF src, RectF dst, int stf)864 private static native boolean native_setRectToRect(int native_object, 865 RectF src, RectF dst, int stf); native_setPolyToPoly(int native_object, float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount)866 private static native boolean native_setPolyToPoly(int native_object, 867 float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount); native_invert(int native_object, int inverse)868 private static native boolean native_invert(int native_object, int inverse); native_mapPoints(int native_object, float[] dst, int dstIndex, float[] src, int srcIndex, int ptCount, boolean isPts)869 private static native void native_mapPoints(int native_object, 870 float[] dst, int dstIndex, float[] src, int srcIndex, 871 int ptCount, boolean isPts); native_mapRect(int native_object, RectF dst, RectF src)872 private static native boolean native_mapRect(int native_object, 873 RectF dst, RectF src); native_mapRadius(int native_object, float radius)874 private static native float native_mapRadius(int native_object, 875 float radius); native_getValues(int native_object, float[] values)876 private static native void native_getValues(int native_object, 877 float[] values); native_setValues(int native_object, float[] values)878 private static native void native_setValues(int native_object, 879 float[] values); native_equals(int native_a, int native_b)880 private static native boolean native_equals(int native_a, int native_b); finalizer(int native_instance)881 private static native void finalizer(int native_instance); 882 } 883