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