1 7 8 package java.awt.geom; 9 10 import java.awt.Shape ; 11 12 34 public class AffineTransform implements Cloneable , java.io.Serializable { 35 39 private static final int TYPE_UNKNOWN = -1; 40 41 59 public static final int TYPE_IDENTITY = 0; 60 61 76 public static final int TYPE_TRANSLATION = 1; 77 78 95 public static final int TYPE_UNIFORM_SCALE = 2; 96 97 114 public static final int TYPE_GENERAL_SCALE = 4; 115 116 121 public static final int TYPE_MASK_SCALE = (TYPE_UNIFORM_SCALE | 122 TYPE_GENERAL_SCALE); 123 124 148 public static final int TYPE_FLIP = 64; 149 154 155 172 public static final int TYPE_QUADRANT_ROTATION = 8; 173 174 192 public static final int TYPE_GENERAL_ROTATION = 16; 193 194 199 public static final int TYPE_MASK_ROTATION = (TYPE_QUADRANT_ROTATION | 200 TYPE_GENERAL_ROTATION); 201 202 218 public static final int TYPE_GENERAL_TRANSFORM = 32; 219 220 230 static final int APPLY_IDENTITY = 0; 231 232 241 static final int APPLY_TRANSLATE = 1; 242 243 260 static final int APPLY_SCALE = 2; 261 262 274 static final int APPLY_SHEAR = 4; 275 276 285 private static final int HI_SHIFT = 3; 286 private static final int HI_IDENTITY = APPLY_IDENTITY << HI_SHIFT; 287 private static final int HI_TRANSLATE = APPLY_TRANSLATE << HI_SHIFT; 288 private static final int HI_SCALE = APPLY_SCALE << HI_SHIFT; 289 private static final int HI_SHEAR = APPLY_SHEAR << HI_SHIFT; 290 291 297 double m00; 298 299 305 double m10; 306 307 313 double m01; 314 315 321 double m11; 322 323 329 double m02; 330 331 337 double m12; 338 339 347 transient int state; 348 349 362 private transient int type; 363 364 private AffineTransform(double m00, double m10, 365 double m01, double m11, 366 double m02, double m12, 367 int state) { 368 this.m00 = m00; 369 this.m10 = m10; 370 this.m01 = m01; 371 this.m11 = m11; 372 this.m02 = m02; 373 this.m12 = m12; 374 this.state = state; 375 this.type = TYPE_UNKNOWN; 376 } 377 378 382 public AffineTransform() { 383 m00 = m11 = 1.0; 384 } 388 389 394 public AffineTransform(AffineTransform Tx) { 395 this.m00 = Tx.m00; 396 this.m10 = Tx.m10; 397 this.m01 = Tx.m01; 398 this.m11 = Tx.m11; 399 this.m02 = Tx.m02; 400 this.m12 = Tx.m12; 401 this.state = Tx.state; 402 this.type = Tx.type; 403 } 404 405 412 public AffineTransform(float m00, float m10, 413 float m01, float m11, 414 float m02, float m12) { 415 this.m00 = m00; 416 this.m10 = m10; 417 this.m01 = m01; 418 this.m11 = m11; 419 this.m02 = m02; 420 this.m12 = m12; 421 updateState(); 422 } 423 424 436 public AffineTransform(float[] flatmatrix) { 437 m00 = flatmatrix[0]; 438 m10 = flatmatrix[1]; 439 m01 = flatmatrix[2]; 440 m11 = flatmatrix[3]; 441 if (flatmatrix.length > 5) { 442 m02 = flatmatrix[4]; 443 m12 = flatmatrix[5]; 444 } 445 updateState(); 446 } 447 448 455 public AffineTransform(double m00, double m10, 456 double m01, double m11, 457 double m02, double m12) { 458 this.m00 = m00; 459 this.m10 = m10; 460 this.m01 = m01; 461 this.m11 = m11; 462 this.m02 = m02; 463 this.m12 = m12; 464 updateState(); 465 } 466 467 479 public AffineTransform(double[] flatmatrix) { 480 m00 = flatmatrix[0]; 481 m10 = flatmatrix[1]; 482 m01 = flatmatrix[2]; 483 m11 = flatmatrix[3]; 484 if (flatmatrix.length > 5) { 485 m02 = flatmatrix[4]; 486 m12 = flatmatrix[5]; 487 } 488 updateState(); 489 } 490 491 506 public static AffineTransform getTranslateInstance(double tx, double ty) { 507 AffineTransform Tx = new AffineTransform (); 508 Tx.setToTranslation(tx, ty); 509 return Tx; 510 } 511 512 526 public static AffineTransform getRotateInstance(double theta) { 527 AffineTransform Tx = new AffineTransform (); 528 Tx.setToRotation(theta); 529 return Tx; 530 } 531 532 562 public static AffineTransform getRotateInstance(double theta, 563 double x, double y) { 564 AffineTransform Tx = new AffineTransform (); 565 Tx.setToRotation(theta, x, y); 566 return Tx; 567 } 568 569 584 public static AffineTransform getScaleInstance(double sx, double sy) { 585 AffineTransform Tx = new AffineTransform (); 586 Tx.setToScale(sx, sy); 587 return Tx; 588 } 589 590 605 public static AffineTransform getShearInstance(double shx, double shy) { 606 AffineTransform Tx = new AffineTransform (); 607 Tx.setToShear(shx, shy); 608 return Tx; 609 } 610 611 634 public int getType() { 635 if (type == TYPE_UNKNOWN) { 636 calculateType(); 637 } 638 return type; 639 } 640 641 646 private void calculateType() { 647 int ret = TYPE_IDENTITY; 648 boolean sgn0, sgn1; 649 double M0, M1, M2, M3; 650 updateState(); 651 switch (state) { 652 default: 653 stateError(); 654 655 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 656 ret = TYPE_TRANSLATION; 657 658 case (APPLY_SHEAR | APPLY_SCALE): 659 if ((M0 = m00) * (M2 = m01) + (M3 = m10) * (M1 = m11) != 0) { 660 this.type = TYPE_GENERAL_TRANSFORM; 662 return; 663 } 664 sgn0 = (M0 >= 0.0); 665 sgn1 = (M1 >= 0.0); 666 if (sgn0 == sgn1) { 667 if (M0 != M1 || M2 != -M3) { 670 ret |= (TYPE_GENERAL_ROTATION | TYPE_GENERAL_SCALE); 671 } else if (M0 * M1 - M2 * M3 != 1.0) { 672 ret |= (TYPE_GENERAL_ROTATION | TYPE_UNIFORM_SCALE); 673 } else { 674 ret |= TYPE_GENERAL_ROTATION; 675 } 676 } else { 677 if (M0 != -M1 || M2 != M3) { 680 ret |= (TYPE_GENERAL_ROTATION | 681 TYPE_FLIP | 682 TYPE_GENERAL_SCALE); 683 } else if (M0 * M1 - M2 * M3 != 1.0) { 684 ret |= (TYPE_GENERAL_ROTATION | 685 TYPE_FLIP | 686 TYPE_UNIFORM_SCALE); 687 } else { 688 ret |= (TYPE_GENERAL_ROTATION | TYPE_FLIP); 689 } 690 } 691 break; 692 case (APPLY_SHEAR | APPLY_TRANSLATE): 693 ret = TYPE_TRANSLATION; 694 695 case (APPLY_SHEAR): 696 sgn0 = ((M0 = m01) >= 0.0); 697 sgn1 = ((M1 = m10) >= 0.0); 698 if (sgn0 != sgn1) { 699 if (M0 != -M1) { 701 ret |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE); 702 } else if (M0 != 1.0 && M0 != -1.0) { 703 ret |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE); 704 } else { 705 ret |= TYPE_QUADRANT_ROTATION; 706 } 707 } else { 708 if (M0 == M1) { 710 ret |= (TYPE_QUADRANT_ROTATION | 711 TYPE_FLIP | 712 TYPE_UNIFORM_SCALE); 713 } else { 714 ret |= (TYPE_QUADRANT_ROTATION | 715 TYPE_FLIP | 716 TYPE_GENERAL_SCALE); 717 } 718 } 719 break; 720 case (APPLY_SCALE | APPLY_TRANSLATE): 721 ret = TYPE_TRANSLATION; 722 723 case (APPLY_SCALE): 724 sgn0 = ((M0 = m00) >= 0.0); 725 sgn1 = ((M1 = m11) >= 0.0); 726 if (sgn0 == sgn1) { 727 if (sgn0) { 728 if (M0 == M1) { 731 ret |= TYPE_UNIFORM_SCALE; 732 } else { 733 ret |= TYPE_GENERAL_SCALE; 734 } 735 } else { 736 if (M0 != M1) { 738 ret |= (TYPE_QUADRANT_ROTATION | TYPE_GENERAL_SCALE); 739 } else if (M0 != -1.0) { 740 ret |= (TYPE_QUADRANT_ROTATION | TYPE_UNIFORM_SCALE); 741 } else { 742 ret |= TYPE_QUADRANT_ROTATION; 743 } 744 } 745 } else { 746 if (M0 == -M1) { 748 if (M0 == 1.0 || M0 == -1.0) { 749 ret |= TYPE_FLIP; 750 } else { 751 ret |= (TYPE_FLIP | TYPE_UNIFORM_SCALE); 752 } 753 } else { 754 ret |= (TYPE_FLIP | TYPE_GENERAL_SCALE); 755 } 756 } 757 break; 758 case (APPLY_TRANSLATE): 759 ret = TYPE_TRANSLATION; 760 break; 761 case (APPLY_IDENTITY): 762 break; 763 } 764 this.type = ret; 765 } 766 767 807 public double getDeterminant() { 808 switch (state) { 809 default: 810 stateError(); 811 812 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 813 case (APPLY_SHEAR | APPLY_SCALE): 814 return m00 * m11 - m01 * m10; 815 case (APPLY_SHEAR | APPLY_TRANSLATE): 816 case (APPLY_SHEAR): 817 return -(m01 * m10); 818 case (APPLY_SCALE | APPLY_TRANSLATE): 819 case (APPLY_SCALE): 820 return m00 * m11; 821 case (APPLY_TRANSLATE): 822 case (APPLY_IDENTITY): 823 return 1.0; 824 } 825 } 826 827 849 void updateState() { 850 if (m01 == 0.0 && m10 == 0.0) { 851 if (m00 == 1.0 && m11 == 1.0) { 852 if (m02 == 0.0 && m12 == 0.0) { 853 state = APPLY_IDENTITY; 854 type = TYPE_IDENTITY; 855 } else { 856 state = APPLY_TRANSLATE; 857 type = TYPE_TRANSLATION; 858 } 859 } else { 860 if (m02 == 0.0 && m12 == 0.0) { 861 state = APPLY_SCALE; 862 type = TYPE_UNKNOWN; 863 } else { 864 state = (APPLY_SCALE | APPLY_TRANSLATE); 865 type = TYPE_UNKNOWN; 866 } 867 } 868 } else { 869 if (m00 == 0.0 && m11 == 0.0) { 870 if (m02 == 0.0 && m12 == 0.0) { 871 state = APPLY_SHEAR; 872 type = TYPE_UNKNOWN; 873 } else { 874 state = (APPLY_SHEAR | APPLY_TRANSLATE); 875 type = TYPE_UNKNOWN; 876 } 877 } else { 878 if (m02 == 0.0 && m12 == 0.0) { 879 state = (APPLY_SHEAR | APPLY_SCALE); 880 type = TYPE_UNKNOWN; 881 } else { 882 state = (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE); 883 type = TYPE_UNKNOWN; 884 } 885 } 886 } 887 } 888 889 893 private void stateError() { 894 throw new InternalError ("missing case in transform state switch"); 895 } 896 897 915 public void getMatrix(double[] flatmatrix) { 916 flatmatrix[0] = m00; 917 flatmatrix[1] = m10; 918 flatmatrix[2] = m01; 919 flatmatrix[3] = m11; 920 if (flatmatrix.length > 5) { 921 flatmatrix[4] = m02; 922 flatmatrix[5] = m12; 923 } 924 } 925 926 933 public double getScaleX() { 934 return m00; 935 } 936 937 944 public double getScaleY() { 945 return m11; 946 } 947 948 955 public double getShearX() { 956 return m01; 957 } 958 959 966 public double getShearY() { 967 return m10; 968 } 969 970 977 public double getTranslateX() { 978 return m02; 979 } 980 981 988 public double getTranslateY() { 989 return m12; 990 } 991 992 1006 public void translate(double tx, double ty) { 1007 switch (state) { 1008 default: 1009 stateError(); 1010 1011 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1012 m02 = tx * m00 + ty * m01 + m02; 1013 m12 = tx * m10 + ty * m11 + m12; 1014 if (m02 == 0.0 && m12 == 0.0) { 1015 state = APPLY_SHEAR | APPLY_SCALE; 1016 if (type != TYPE_UNKNOWN) { 1017 type -= TYPE_TRANSLATION; 1018 } 1019 } 1020 return; 1021 case (APPLY_SHEAR | APPLY_SCALE): 1022 m02 = tx * m00 + ty * m01; 1023 m12 = tx * m10 + ty * m11; 1024 if (m02 != 0.0 || m12 != 0.0) { 1025 state = APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE; 1026 type |= TYPE_TRANSLATION; 1027 } 1028 return; 1029 case (APPLY_SHEAR | APPLY_TRANSLATE): 1030 m02 = ty * m01 + m02; 1031 m12 = tx * m10 + m12; 1032 if (m02 == 0.0 && m12 == 0.0) { 1033 state = APPLY_SHEAR; 1034 if (type != TYPE_UNKNOWN) { 1035 type -= TYPE_TRANSLATION; 1036 } 1037 } 1038 return; 1039 case (APPLY_SHEAR): 1040 m02 = ty * m01; 1041 m12 = tx * m10; 1042 if (m02 != 0.0 || m12 != 0.0) { 1043 state = APPLY_SHEAR | APPLY_TRANSLATE; 1044 type |= TYPE_TRANSLATION; 1045 } 1046 return; 1047 case (APPLY_SCALE | APPLY_TRANSLATE): 1048 m02 = tx * m00 + m02; 1049 m12 = ty * m11 + m12; 1050 if (m02 == 0.0 && m12 == 0.0) { 1051 state = APPLY_SCALE; 1052 if (type != TYPE_UNKNOWN) { 1053 type -= TYPE_TRANSLATION; 1054 } 1055 } 1056 return; 1057 case (APPLY_SCALE): 1058 m02 = tx * m00; 1059 m12 = ty * m11; 1060 if (m02 != 0.0 || m12 != 0.0) { 1061 state = APPLY_SCALE | APPLY_TRANSLATE; 1062 type |= TYPE_TRANSLATION; 1063 } 1064 return; 1065 case (APPLY_TRANSLATE): 1066 m02 = tx + m02; 1067 m12 = ty + m12; 1068 if (m02 == 0.0 && m12 == 0.0) { 1069 state = APPLY_IDENTITY; 1070 type = TYPE_IDENTITY; 1071 } 1072 return; 1073 case (APPLY_IDENTITY): 1074 m02 = tx; 1075 m12 = ty; 1076 if (tx != 0.0 || ty != 0.0) { 1077 state = APPLY_TRANSLATE; 1078 type = TYPE_TRANSLATION; 1079 } 1080 return; 1081 } 1082 } 1083 1084 1097 public void rotate(double theta) { 1098 double sin = Math.sin(theta); 1099 double cos = Math.cos(theta); 1100 if (Math.abs(sin) < 1E-15) { 1101 if (cos < 0.0) { 1102 m00 = -m00; 1103 m11 = -m11; 1104 int state = this.state; 1105 if ((state & (APPLY_SHEAR)) != 0) { 1106 m01 = -m01; 1109 m10 = -m10; 1110 } else { 1111 if (m00 == 1.0 && m11 == 1.0) { 1114 this.state = state & ~APPLY_SCALE; 1115 } else { 1116 this.state = state | APPLY_SCALE; 1117 } 1118 } 1119 type = TYPE_UNKNOWN; 1120 } 1121 return; 1122 } 1123 if (Math.abs(cos) < 1E-15) { 1124 if (sin < 0.0) { 1125 double M0 = m00; 1126 m00 = -m01; 1127 m01 = M0; 1128 M0 = m10; 1129 m10 = -m11; 1130 m11 = M0; 1131 } else { 1132 double M0 = m00; 1133 m00 = m01; 1134 m01 = -M0; 1135 M0 = m10; 1136 m10 = m11; 1137 m11 = -M0; 1138 } 1139 int state = rot90conversion[this.state]; 1140 if ((state & (APPLY_SHEAR | APPLY_SCALE)) == APPLY_SCALE && 1141 m00 == 1.0 && m11 == 1.0) 1142 { 1143 state -= APPLY_SCALE; 1144 } 1145 this.state = state; 1146 type = TYPE_UNKNOWN; 1147 return; 1148 } 1149 double M0, M1; 1150 M0 = m00; 1151 M1 = m01; 1152 m00 = cos * M0 + sin * M1; 1153 m01 = -sin * M0 + cos * M1; 1154 M0 = m10; 1155 M1 = m11; 1156 m10 = cos * M0 + sin * M1; 1157 m11 = -sin * M0 + cos * M1; 1158 updateState(); 1159 } 1160 private static int rot90conversion[] = { 1161 APPLY_SHEAR, APPLY_SHEAR | APPLY_TRANSLATE, 1162 APPLY_SHEAR, APPLY_SHEAR | APPLY_TRANSLATE, 1163 APPLY_SCALE, APPLY_SCALE | APPLY_TRANSLATE, 1164 APPLY_SHEAR | APPLY_SCALE, 1165 APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE, 1166 }; 1167 1168 1189 public void rotate(double theta, double x, double y) { 1190 translate(x, y); 1192 rotate(theta); 1193 translate(-x, -y); 1194 } 1195 1196 1210 public void scale(double sx, double sy) { 1211 int state = this.state; 1212 switch (state) { 1213 default: 1214 stateError(); 1215 1216 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1217 case (APPLY_SHEAR | APPLY_SCALE): 1218 m00 *= sx; 1219 m11 *= sy; 1220 1221 case (APPLY_SHEAR | APPLY_TRANSLATE): 1222 case (APPLY_SHEAR): 1223 m01 *= sy; 1224 m10 *= sx; 1225 if (m01 == 0 && m10 == 0) { 1226 this.state = state - APPLY_SHEAR; 1227 } 1229 this.type = TYPE_UNKNOWN; 1230 return; 1231 case (APPLY_SCALE | APPLY_TRANSLATE): 1232 case (APPLY_SCALE): 1233 m00 *= sx; 1234 m11 *= sy; 1235 if (m00 == 1.0 && m11 == 1.0) { 1236 this.state = (state &= APPLY_TRANSLATE); 1237 this.type = (state == APPLY_IDENTITY 1238 ? TYPE_IDENTITY 1239 : TYPE_TRANSLATION); 1240 } else { 1241 this.type = TYPE_UNKNOWN; 1242 } 1243 return; 1244 case (APPLY_TRANSLATE): 1245 case (APPLY_IDENTITY): 1246 m00 = sx; 1247 m11 = sy; 1248 if (sx != 1.0 || sy != 1.0) { 1249 this.state = state | APPLY_SCALE; 1250 this.type = TYPE_UNKNOWN; 1251 } 1252 return; 1253 } 1254 } 1255 1256 1270 public void shear(double shx, double shy) { 1271 int state = this.state; 1272 switch (state) { 1273 default: 1274 stateError(); 1275 1276 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1277 case (APPLY_SHEAR | APPLY_SCALE): 1278 double M0, M1; 1279 M0 = m00; 1280 M1 = m01; 1281 m00 = M0 + M1 * shy; 1282 m01 = M0 * shx + M1; 1283 1284 M0 = m10; 1285 M1 = m11; 1286 m10 = M0 + M1 * shy; 1287 m11 = M0 * shx + M1; 1288 updateState(); 1289 return; 1290 case (APPLY_SHEAR | APPLY_TRANSLATE): 1291 case (APPLY_SHEAR): 1292 m00 = m01 * shy; 1293 m11 = m10 * shx; 1294 if (m00 != 0.0 || m11 != 0.0) { 1295 this.state = state | APPLY_SCALE; 1296 } 1297 this.type = TYPE_UNKNOWN; 1298 return; 1299 case (APPLY_SCALE | APPLY_TRANSLATE): 1300 case (APPLY_SCALE): 1301 m01 = m00 * shx; 1302 m10 = m11 * shy; 1303 if (m01 != 0.0 || m10 != 0.0) { 1304 this.state = state | APPLY_SHEAR; 1305 } 1306 this.type = TYPE_UNKNOWN; 1307 return; 1308 case (APPLY_TRANSLATE): 1309 case (APPLY_IDENTITY): 1310 m01 = shx; 1311 m10 = shy; 1312 if (m01 != 0.0 || m10 != 0.0) { 1313 this.state = state | APPLY_SCALE | APPLY_SHEAR; 1314 this.type = TYPE_UNKNOWN; 1315 } 1316 return; 1317 } 1318 } 1319 1320 1323 public void setToIdentity() { 1324 m00 = m11 = 1.0; 1325 m10 = m01 = m02 = m12 = 0.0; 1326 state = APPLY_IDENTITY; 1327 type = TYPE_IDENTITY; 1328 } 1329 1330 1343 public void setToTranslation(double tx, double ty) { 1344 m00 = 1.0; 1345 m10 = 0.0; 1346 m01 = 0.0; 1347 m11 = 1.0; 1348 m02 = tx; 1349 m12 = ty; 1350 if (tx != 0.0 || ty != 0.0) { 1351 state = APPLY_TRANSLATE; 1352 type = TYPE_TRANSLATION; 1353 } else { 1354 state = APPLY_IDENTITY; 1355 type = TYPE_IDENTITY; 1356 } 1357 } 1358 1359 1371 public void setToRotation(double theta) { 1372 m02 = 0.0; 1373 m12 = 0.0; 1374 double sin = Math.sin(theta); 1375 double cos = Math.cos(theta); 1376 if (Math.abs(sin) < 1E-15) { 1377 m01 = m10 = 0.0; 1378 if (cos < 0) { 1379 m00 = m11 = -1.0; 1380 state = APPLY_SCALE; 1381 type = TYPE_QUADRANT_ROTATION; 1382 } else { 1383 m00 = m11 = 1.0; 1384 state = APPLY_IDENTITY; 1385 type = TYPE_IDENTITY; 1386 } 1387 return; 1388 } 1389 if (Math.abs(cos) < 1E-15) { 1390 m00 = m11 = 0.0; 1391 if (sin < 0.0) { 1392 m01 = 1.0; 1393 m10 = -1.0; 1394 } else { 1395 m01 = -1.0; 1396 m10 = 1.0; 1397 } 1398 state = APPLY_SHEAR; 1399 type = TYPE_QUADRANT_ROTATION; 1400 return; 1401 } 1402 m00 = cos; 1403 m01 = -sin; 1404 m10 = sin; 1405 m11 = cos; 1406 state = APPLY_SHEAR | APPLY_SCALE; 1407 type = TYPE_GENERAL_ROTATION; 1408 return; 1409 } 1410 1411 1437 public void setToRotation(double theta, double x, double y) { 1438 setToRotation(theta); 1439 double sin = m10; 1440 double oneMinusCos = 1.0 - m00; 1441 m02 = x * oneMinusCos + y * sin; 1442 m12 = y * oneMinusCos - x * sin; 1443 if (m02 != 0.0 || m12 != 0.0) { 1444 state |= APPLY_TRANSLATE; 1445 type |= TYPE_TRANSLATION; 1446 } 1447 return; 1448 } 1449 1450 1463 public void setToScale(double sx, double sy) { 1464 m00 = sx; 1465 m10 = 0.0; 1466 m01 = 0.0; 1467 m11 = sy; 1468 m02 = 0.0; 1469 m12 = 0.0; 1470 if (sx != 1.0 || sy != 1.0) { 1471 state = APPLY_SCALE; 1472 type = TYPE_UNKNOWN; 1473 } else { 1474 state = APPLY_IDENTITY; 1475 type = TYPE_IDENTITY; 1476 } 1477 } 1478 1479 1492 public void setToShear(double shx, double shy) { 1493 m00 = 1.0; 1494 m01 = shx; 1495 m10 = shy; 1496 m11 = 1.0; 1497 m02 = 0.0; 1498 m12 = 0.0; 1499 if (shx != 0.0 || shy != 0.0) { 1500 state = (APPLY_SHEAR | APPLY_SCALE); 1501 type = TYPE_UNKNOWN; 1502 } else { 1503 state = APPLY_IDENTITY; 1504 type = TYPE_IDENTITY; 1505 } 1506 } 1507 1508 1514 public void setTransform(AffineTransform Tx) { 1515 this.m00 = Tx.m00; 1516 this.m10 = Tx.m10; 1517 this.m01 = Tx.m01; 1518 this.m11 = Tx.m11; 1519 this.m02 = Tx.m02; 1520 this.m12 = Tx.m12; 1521 this.state = Tx.state; 1522 this.type = Tx.type; 1523 } 1524 1525 1531 public void setTransform(double m00, double m10, 1532 double m01, double m11, 1533 double m02, double m12) { 1534 this.m00 = m00; 1535 this.m10 = m10; 1536 this.m01 = m01; 1537 this.m11 = m11; 1538 this.m02 = m02; 1539 this.m12 = m12; 1540 updateState(); 1541 } 1542 1543 1563 public void concatenate(AffineTransform Tx) { 1564 double M0, M1; 1565 double T00, T01, T10, T11; 1566 double T02, T12; 1567 int mystate = state; 1568 int txstate = Tx.state; 1569 switch ((txstate << HI_SHIFT) | mystate) { 1570 1571 1572 case (HI_IDENTITY | APPLY_IDENTITY): 1573 case (HI_IDENTITY | APPLY_TRANSLATE): 1574 case (HI_IDENTITY | APPLY_SCALE): 1575 case (HI_IDENTITY | APPLY_SCALE | APPLY_TRANSLATE): 1576 case (HI_IDENTITY | APPLY_SHEAR): 1577 case (HI_IDENTITY | APPLY_SHEAR | APPLY_TRANSLATE): 1578 case (HI_IDENTITY | APPLY_SHEAR | APPLY_SCALE): 1579 case (HI_IDENTITY | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1580 return; 1581 1582 1583 case (HI_SHEAR | HI_SCALE | HI_TRANSLATE | APPLY_IDENTITY): 1584 m01 = Tx.m01; 1585 m10 = Tx.m10; 1586 1587 case (HI_SCALE | HI_TRANSLATE | APPLY_IDENTITY): 1588 m00 = Tx.m00; 1589 m11 = Tx.m11; 1590 1591 case (HI_TRANSLATE | APPLY_IDENTITY): 1592 m02 = Tx.m02; 1593 m12 = Tx.m12; 1594 state = txstate; 1595 type = Tx.type; 1596 return; 1597 case (HI_SHEAR | HI_SCALE | APPLY_IDENTITY): 1598 m01 = Tx.m01; 1599 m10 = Tx.m10; 1600 1601 case (HI_SCALE | APPLY_IDENTITY): 1602 m00 = Tx.m00; 1603 m11 = Tx.m11; 1604 state = txstate; 1605 type = Tx.type; 1606 return; 1607 case (HI_SHEAR | HI_TRANSLATE | APPLY_IDENTITY): 1608 m02 = Tx.m02; 1609 m12 = Tx.m12; 1610 1611 case (HI_SHEAR | APPLY_IDENTITY): 1612 m01 = Tx.m01; 1613 m10 = Tx.m10; 1614 m00 = m11 = 0.0; 1615 state = txstate; 1616 type = Tx.type; 1617 return; 1618 1619 1620 case (HI_TRANSLATE | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1621 case (HI_TRANSLATE | APPLY_SHEAR | APPLY_SCALE): 1622 case (HI_TRANSLATE | APPLY_SHEAR | APPLY_TRANSLATE): 1623 case (HI_TRANSLATE | APPLY_SHEAR): 1624 case (HI_TRANSLATE | APPLY_SCALE | APPLY_TRANSLATE): 1625 case (HI_TRANSLATE | APPLY_SCALE): 1626 case (HI_TRANSLATE | APPLY_TRANSLATE): 1627 translate(Tx.m02, Tx.m12); 1628 return; 1629 1630 1631 case (HI_SCALE | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1632 case (HI_SCALE | APPLY_SHEAR | APPLY_SCALE): 1633 case (HI_SCALE | APPLY_SHEAR | APPLY_TRANSLATE): 1634 case (HI_SCALE | APPLY_SHEAR): 1635 case (HI_SCALE | APPLY_SCALE | APPLY_TRANSLATE): 1636 case (HI_SCALE | APPLY_SCALE): 1637 case (HI_SCALE | APPLY_TRANSLATE): 1638 scale(Tx.m00, Tx.m11); 1639 return; 1640 1641 1642 case (HI_SHEAR | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1643 case (HI_SHEAR | APPLY_SHEAR | APPLY_SCALE): 1644 T01 = Tx.m01; T10 = Tx.m10; 1645 M0 = m00; 1646 m00 = m01 * T10; 1647 m01 = M0 * T01; 1648 M0 = m10; 1649 m10 = m11 * T10; 1650 m11 = M0 * T01; 1651 type = TYPE_UNKNOWN; 1652 return; 1653 case (HI_SHEAR | APPLY_SHEAR | APPLY_TRANSLATE): 1654 case (HI_SHEAR | APPLY_SHEAR): 1655 m00 = m01 * Tx.m10; 1656 m01 = 0.0; 1657 m11 = m10 * Tx.m01; 1658 m10 = 0.0; 1659 state = mystate ^ (APPLY_SHEAR | APPLY_SCALE); 1660 type = TYPE_UNKNOWN; 1661 return; 1662 case (HI_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1663 case (HI_SHEAR | APPLY_SCALE): 1664 m01 = m00 * Tx.m01; 1665 m00 = 0.0; 1666 m10 = m11 * Tx.m10; 1667 m11 = 0.0; 1668 state = mystate ^ (APPLY_SHEAR | APPLY_SCALE); 1669 type = TYPE_UNKNOWN; 1670 return; 1671 case (HI_SHEAR | APPLY_TRANSLATE): 1672 m00 = 0.0; 1673 m01 = Tx.m01; 1674 m10 = Tx.m10; 1675 m11 = 0.0; 1676 state = APPLY_TRANSLATE | APPLY_SHEAR; 1677 type = TYPE_UNKNOWN; 1678 return; 1679 } 1680 T00 = Tx.m00; T01 = Tx.m01; T02 = Tx.m02; 1683 T10 = Tx.m10; T11 = Tx.m11; T12 = Tx.m12; 1684 switch (mystate) { 1685 default: 1686 stateError(); 1687 1688 case (APPLY_SHEAR | APPLY_SCALE): 1689 state = mystate | txstate; 1690 1691 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1692 M0 = m00; 1693 M1 = m01; 1694 m00 = T00 * M0 + T10 * M1; 1695 m01 = T01 * M0 + T11 * M1; 1696 m02 += T02 * M0 + T12 * M1; 1697 1698 M0 = m10; 1699 M1 = m11; 1700 m10 = T00 * M0 + T10 * M1; 1701 m11 = T01 * M0 + T11 * M1; 1702 m12 += T02 * M0 + T12 * M1; 1703 type = TYPE_UNKNOWN; 1704 return; 1705 1706 case (APPLY_SHEAR | APPLY_TRANSLATE): 1707 case (APPLY_SHEAR): 1708 M0 = m01; 1709 m00 = T10 * M0; 1710 m01 = T11 * M0; 1711 m02 += T12 * M0; 1712 1713 M0 = m10; 1714 m10 = T00 * M0; 1715 m11 = T01 * M0; 1716 m12 += T02 * M0; 1717 break; 1718 1719 case (APPLY_SCALE | APPLY_TRANSLATE): 1720 case (APPLY_SCALE): 1721 M0 = m00; 1722 m00 = T00 * M0; 1723 m01 = T01 * M0; 1724 m02 += T02 * M0; 1725 1726 M0 = m11; 1727 m10 = T10 * M0; 1728 m11 = T11 * M0; 1729 m12 += T12 * M0; 1730 break; 1731 1732 case (APPLY_TRANSLATE): 1733 m00 = T00; 1734 m01 = T01; 1735 m02 += T02; 1736 1737 m10 = T10; 1738 m11 = T11; 1739 m12 += T12; 1740 state = txstate | APPLY_TRANSLATE; 1741 type = TYPE_UNKNOWN; 1742 return; 1743 } 1744 updateState(); 1745 } 1746 1747 1770 public void preConcatenate(AffineTransform Tx) { 1771 double M0, M1; 1772 double T00, T01, T10, T11; 1773 double T02, T12; 1774 int mystate = state; 1775 int txstate = Tx.state; 1776 switch ((txstate << HI_SHIFT) | mystate) { 1777 case (HI_IDENTITY | APPLY_IDENTITY): 1778 case (HI_IDENTITY | APPLY_TRANSLATE): 1779 case (HI_IDENTITY | APPLY_SCALE): 1780 case (HI_IDENTITY | APPLY_SCALE | APPLY_TRANSLATE): 1781 case (HI_IDENTITY | APPLY_SHEAR): 1782 case (HI_IDENTITY | APPLY_SHEAR | APPLY_TRANSLATE): 1783 case (HI_IDENTITY | APPLY_SHEAR | APPLY_SCALE): 1784 case (HI_IDENTITY | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1785 return; 1787 1788 case (HI_TRANSLATE | APPLY_IDENTITY): 1789 case (HI_TRANSLATE | APPLY_SCALE): 1790 case (HI_TRANSLATE | APPLY_SHEAR): 1791 case (HI_TRANSLATE | APPLY_SHEAR | APPLY_SCALE): 1792 m02 = Tx.m02; 1794 m12 = Tx.m12; 1795 state = mystate | APPLY_TRANSLATE; 1796 type |= TYPE_TRANSLATION; 1797 return; 1798 1799 case (HI_TRANSLATE | APPLY_TRANSLATE): 1800 case (HI_TRANSLATE | APPLY_SCALE | APPLY_TRANSLATE): 1801 case (HI_TRANSLATE | APPLY_SHEAR | APPLY_TRANSLATE): 1802 case (HI_TRANSLATE | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1803 m02 = m02 + Tx.m02; 1805 m12 = m12 + Tx.m12; 1806 return; 1807 1808 case (HI_SCALE | APPLY_TRANSLATE): 1809 case (HI_SCALE | APPLY_IDENTITY): 1810 state = mystate | APPLY_SCALE; 1812 1813 case (HI_SCALE | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1814 case (HI_SCALE | APPLY_SHEAR | APPLY_SCALE): 1815 case (HI_SCALE | APPLY_SHEAR | APPLY_TRANSLATE): 1816 case (HI_SCALE | APPLY_SHEAR): 1817 case (HI_SCALE | APPLY_SCALE | APPLY_TRANSLATE): 1818 case (HI_SCALE | APPLY_SCALE): 1819 T00 = Tx.m00; 1821 T11 = Tx.m11; 1822 if ((mystate & APPLY_SHEAR) != 0) { 1823 m01 = m01 * T00; 1824 m10 = m10 * T11; 1825 if ((mystate & APPLY_SCALE) != 0) { 1826 m00 = m00 * T00; 1827 m11 = m11 * T11; 1828 } 1829 } else { 1830 m00 = m00 * T00; 1831 m11 = m11 * T11; 1832 } 1833 if ((mystate & APPLY_TRANSLATE) != 0) { 1834 m02 = m02 * T00; 1835 m12 = m12 * T11; 1836 } 1837 type = TYPE_UNKNOWN; 1838 return; 1839 case (HI_SHEAR | APPLY_SHEAR | APPLY_TRANSLATE): 1840 case (HI_SHEAR | APPLY_SHEAR): 1841 mystate = mystate | APPLY_SCALE; 1842 1843 case (HI_SHEAR | APPLY_TRANSLATE): 1844 case (HI_SHEAR | APPLY_IDENTITY): 1845 case (HI_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1846 case (HI_SHEAR | APPLY_SCALE): 1847 state = mystate ^ APPLY_SHEAR; 1848 1849 case (HI_SHEAR | APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1850 case (HI_SHEAR | APPLY_SHEAR | APPLY_SCALE): 1851 T01 = Tx.m01; 1853 T10 = Tx.m10; 1854 1855 M0 = m00; 1856 m00 = m10 * T01; 1857 m10 = M0 * T10; 1858 1859 M0 = m01; 1860 m01 = m11 * T01; 1861 m11 = M0 * T10; 1862 1863 M0 = m02; 1864 m02 = m12 * T01; 1865 m12 = M0 * T10; 1866 type = TYPE_UNKNOWN; 1867 return; 1868 } 1869 T00 = Tx.m00; T01 = Tx.m01; T02 = Tx.m02; 1872 T10 = Tx.m10; T11 = Tx.m11; T12 = Tx.m12; 1873 switch (mystate) { 1874 default: 1875 stateError(); 1876 1877 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1878 M0 = m02; 1879 M1 = m12; 1880 T02 += M0 * T00 + M1 * T01; 1881 T12 += M0 * T10 + M1 * T11; 1882 1883 1884 case (APPLY_SHEAR | APPLY_SCALE): 1885 m02 = T02; 1886 m12 = T12; 1887 1888 M0 = m00; 1889 M1 = m10; 1890 m00 = M0 * T00 + M1 * T01; 1891 m10 = M0 * T10 + M1 * T11; 1892 1893 M0 = m01; 1894 M1 = m11; 1895 m01 = M0 * T00 + M1 * T01; 1896 m11 = M0 * T10 + M1 * T11; 1897 break; 1898 1899 case (APPLY_SHEAR | APPLY_TRANSLATE): 1900 M0 = m02; 1901 M1 = m12; 1902 T02 += M0 * T00 + M1 * T01; 1903 T12 += M0 * T10 + M1 * T11; 1904 1905 1906 case (APPLY_SHEAR): 1907 m02 = T02; 1908 m12 = T12; 1909 1910 M0 = m10; 1911 m00 = M0 * T01; 1912 m10 = M0 * T11; 1913 1914 M0 = m01; 1915 m01 = M0 * T00; 1916 m11 = M0 * T10; 1917 break; 1918 1919 case (APPLY_SCALE | APPLY_TRANSLATE): 1920 M0 = m02; 1921 M1 = m12; 1922 T02 += M0 * T00 + M1 * T01; 1923 T12 += M0 * T10 + M1 * T11; 1924 1925 1926 case (APPLY_SCALE): 1927 m02 = T02; 1928 m12 = T12; 1929 1930 M0 = m00; 1931 m00 = M0 * T00; 1932 m10 = M0 * T10; 1933 1934 M0 = m11; 1935 m01 = M0 * T01; 1936 m11 = M0 * T11; 1937 break; 1938 1939 case (APPLY_TRANSLATE): 1940 M0 = m02; 1941 M1 = m12; 1942 T02 += M0 * T00 + M1 * T01; 1943 T12 += M0 * T10 + M1 * T11; 1944 1945 1946 case (APPLY_IDENTITY): 1947 m02 = T02; 1948 m12 = T12; 1949 1950 m00 = T00; 1951 m10 = T10; 1952 1953 m01 = T01; 1954 m11 = T11; 1955 1956 state = mystate | txstate; 1957 type = TYPE_UNKNOWN; 1958 return; 1959 } 1960 updateState(); 1961 } 1962 1963 1984 public AffineTransform createInverse() 1985 throws NoninvertibleTransformException 1986 { 1987 double det; 1988 switch (state) { 1989 default: 1990 stateError(); 1991 1992 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 1993 det = m00 * m11 - m01 * m10; 1994 if (Math.abs(det) <= Double.MIN_VALUE) { 1995 throw new NoninvertibleTransformException ("Determinant is "+ 1996 det); 1997 } 1998 return new AffineTransform ( m11 / det, -m10 / det, 1999 -m01 / det, m00 / det, 2000 (m01 * m12 - m11 * m02) / det, 2001 (m10 * m02 - m00 * m12) / det, 2002 (APPLY_SHEAR | 2003 APPLY_SCALE | 2004 APPLY_TRANSLATE)); 2005 case (APPLY_SHEAR | APPLY_SCALE): 2006 det = m00 * m11 - m01 * m10; 2007 if (Math.abs(det) <= Double.MIN_VALUE) { 2008 throw new NoninvertibleTransformException ("Determinant is "+ 2009 det); 2010 } 2011 return new AffineTransform ( m11 / det, -m10 / det, 2012 -m01 / det, m00 / det, 2013 0.0, 0.0, 2014 (APPLY_SHEAR | APPLY_SCALE)); 2015 case (APPLY_SHEAR | APPLY_TRANSLATE): 2016 if (m01 == 0.0 || m10 == 0.0) { 2017 throw new NoninvertibleTransformException ("Determinant is 0"); 2018 } 2019 return new AffineTransform ( 0.0, 1.0 / m01, 2020 1.0 / m10, 0.0, 2021 -m12 / m10, -m02 / m01, 2022 (APPLY_SHEAR | APPLY_TRANSLATE)); 2023 case (APPLY_SHEAR): 2024 if (m01 == 0.0 || m10 == 0.0) { 2025 throw new NoninvertibleTransformException ("Determinant is 0"); 2026 } 2027 return new AffineTransform (0.0, 1.0 / m01, 2028 1.0 / m10, 0.0, 2029 0.0, 0.0, 2030 (APPLY_SHEAR)); 2031 case (APPLY_SCALE | APPLY_TRANSLATE): 2032 if (m00 == 0.0 || m11 == 0.0) { 2033 throw new NoninvertibleTransformException ("Determinant is 0"); 2034 } 2035 return new AffineTransform ( 1.0 / m00, 0.0, 2036 0.0, 1.0 / m11, 2037 -m02 / m00, -m12 / m11, 2038 (APPLY_SCALE | APPLY_TRANSLATE)); 2039 case (APPLY_SCALE): 2040 if (m00 == 0.0 || m11 == 0.0) { 2041 throw new NoninvertibleTransformException ("Determinant is 0"); 2042 } 2043 return new AffineTransform (1.0 / m00, 0.0, 2044 0.0, 1.0 / m11, 2045 0.0, 0.0, 2046 (APPLY_SCALE)); 2047 case (APPLY_TRANSLATE): 2048 return new AffineTransform ( 1.0, 0.0, 2049 0.0, 1.0, 2050 -m02, -m12, 2051 (APPLY_TRANSLATE)); 2052 case (APPLY_IDENTITY): 2053 return new AffineTransform (); 2054 } 2055 2056 2057 } 2058 2059 2076 public Point2D transform(Point2D ptSrc, Point2D ptDst) { 2077 if (ptDst == null) { 2078 if (ptSrc instanceof Point2D.Double ) { 2079 ptDst = new Point2D.Double (); 2080 } else { 2081 ptDst = new Point2D.Float (); 2082 } 2083 } 2084 double x = ptSrc.getX(); 2086 double y = ptSrc.getY(); 2087 switch (state) { 2088 default: 2089 stateError(); 2090 2091 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2092 ptDst.setLocation(x * m00 + y * m01 + m02, 2093 x * m10 + y * m11 + m12); 2094 return ptDst; 2095 case (APPLY_SHEAR | APPLY_SCALE): 2096 ptDst.setLocation(x * m00 + y * m01, x * m10 + y * m11); 2097 return ptDst; 2098 case (APPLY_SHEAR | APPLY_TRANSLATE): 2099 ptDst.setLocation(y * m01 + m02, x * m10 + m12); 2100 return ptDst; 2101 case (APPLY_SHEAR): 2102 ptDst.setLocation(y * m01, x * m10); 2103 return ptDst; 2104 case (APPLY_SCALE | APPLY_TRANSLATE): 2105 ptDst.setLocation(x * m00 + m02, y * m11 + m12); 2106 return ptDst; 2107 case (APPLY_SCALE): 2108 ptDst.setLocation(x * m00, y * m11); 2109 return ptDst; 2110 case (APPLY_TRANSLATE): 2111 ptDst.setLocation(x + m02, y + m12); 2112 return ptDst; 2113 case (APPLY_IDENTITY): 2114 ptDst.setLocation(x, y); 2115 return ptDst; 2116 } 2117 2118 2119 } 2120 2121 2151 public void transform(Point2D [] ptSrc, int srcOff, 2152 Point2D [] ptDst, int dstOff, 2153 int numPts) { 2154 int state = this.state; 2155 while (--numPts >= 0) { 2156 Point2D src = ptSrc[srcOff++]; 2158 double x = src.getX(); 2159 double y = src.getY(); 2160 Point2D dst = ptDst[dstOff++]; 2161 if (dst == null) { 2162 if (src instanceof Point2D.Double ) { 2163 dst = new Point2D.Double (); 2164 } else { 2165 dst = new Point2D.Float (); 2166 } 2167 ptDst[dstOff - 1] = dst; 2168 } 2169 switch (state) { 2170 default: 2171 stateError(); 2172 2173 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2174 dst.setLocation(x * m00 + y * m01 + m02, 2175 x * m10 + y * m11 + m12); 2176 break; 2177 case (APPLY_SHEAR | APPLY_SCALE): 2178 dst.setLocation(x * m00 + y * m01, x * m10 + y * m11); 2179 break; 2180 case (APPLY_SHEAR | APPLY_TRANSLATE): 2181 dst.setLocation(y * m01 + m02, x * m10 + m12); 2182 break; 2183 case (APPLY_SHEAR): 2184 dst.setLocation(y * m01, x * m10); 2185 break; 2186 case (APPLY_SCALE | APPLY_TRANSLATE): 2187 dst.setLocation(x * m00 + m02, y * m11 + m12); 2188 break; 2189 case (APPLY_SCALE): 2190 dst.setLocation(x * m00, y * m11); 2191 break; 2192 case (APPLY_TRANSLATE): 2193 dst.setLocation(x + m02, y + m12); 2194 break; 2195 case (APPLY_IDENTITY): 2196 dst.setLocation(x, y); 2197 break; 2198 } 2199 } 2200 2201 2202 } 2203 2204 2224 public void transform(float[] srcPts, int srcOff, 2225 float[] dstPts, int dstOff, 2226 int numPts) { 2227 double M00, M01, M02, M10, M11, M12; if (dstPts == srcPts && 2229 dstOff > srcOff && dstOff < srcOff + numPts * 2) 2230 { 2231 System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); 2240 srcOff = dstOff; 2242 } 2243 switch (state) { 2244 default: 2245 stateError(); 2246 2247 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2248 M00 = m00; M01 = m01; M02 = m02; 2249 M10 = m10; M11 = m11; M12 = m12; 2250 while (--numPts >= 0) { 2251 double x = srcPts[srcOff++]; 2252 double y = srcPts[srcOff++]; 2253 dstPts[dstOff++] = (float) (M00 * x + M01 * y + M02); 2254 dstPts[dstOff++] = (float) (M10 * x + M11 * y + M12); 2255 } 2256 return; 2257 case (APPLY_SHEAR | APPLY_SCALE): 2258 M00 = m00; M01 = m01; 2259 M10 = m10; M11 = m11; 2260 while (--numPts >= 0) { 2261 double x = srcPts[srcOff++]; 2262 double y = srcPts[srcOff++]; 2263 dstPts[dstOff++] = (float) (M00 * x + M01 * y); 2264 dstPts[dstOff++] = (float) (M10 * x + M11 * y); 2265 } 2266 return; 2267 case (APPLY_SHEAR | APPLY_TRANSLATE): 2268 M01 = m01; M02 = m02; 2269 M10 = m10; M12 = m12; 2270 while (--numPts >= 0) { 2271 double x = srcPts[srcOff++]; 2272 dstPts[dstOff++] = (float) (M01 * srcPts[srcOff++] + M02); 2273 dstPts[dstOff++] = (float) (M10 * x + M12); 2274 } 2275 return; 2276 case (APPLY_SHEAR): 2277 M01 = m01; M10 = m10; 2278 while (--numPts >= 0) { 2279 double x = srcPts[srcOff++]; 2280 dstPts[dstOff++] = (float) (M01 * srcPts[srcOff++]); 2281 dstPts[dstOff++] = (float) (M10 * x); 2282 } 2283 return; 2284 case (APPLY_SCALE | APPLY_TRANSLATE): 2285 M00 = m00; M02 = m02; 2286 M11 = m11; M12 = m12; 2287 while (--numPts >= 0) { 2288 dstPts[dstOff++] = (float) (M00 * srcPts[srcOff++] + M02); 2289 dstPts[dstOff++] = (float) (M11 * srcPts[srcOff++] + M12); 2290 } 2291 return; 2292 case (APPLY_SCALE): 2293 M00 = m00; M11 = m11; 2294 while (--numPts >= 0) { 2295 dstPts[dstOff++] = (float) (M00 * srcPts[srcOff++]); 2296 dstPts[dstOff++] = (float) (M11 * srcPts[srcOff++]); 2297 } 2298 return; 2299 case (APPLY_TRANSLATE): 2300 M02 = m02; M12 = m12; 2301 while (--numPts >= 0) { 2302 dstPts[dstOff++] = (float) (srcPts[srcOff++] + M02); 2303 dstPts[dstOff++] = (float) (srcPts[srcOff++] + M12); 2304 } 2305 return; 2306 case (APPLY_IDENTITY): 2307 if (srcPts != dstPts || srcOff != dstOff) { 2308 System.arraycopy(srcPts, srcOff, dstPts, dstOff, 2309 numPts * 2); 2310 } 2311 return; 2312 } 2313 2314 2315 } 2316 2317 2337 public void transform(double[] srcPts, int srcOff, 2338 double[] dstPts, int dstOff, 2339 int numPts) { 2340 double M00, M01, M02, M10, M11, M12; if (dstPts == srcPts && 2342 dstOff > srcOff && dstOff < srcOff + numPts * 2) 2343 { 2344 System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); 2353 srcOff = dstOff; 2355 } 2356 switch (state) { 2357 default: 2358 stateError(); 2359 2360 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2361 M00 = m00; M01 = m01; M02 = m02; 2362 M10 = m10; M11 = m11; M12 = m12; 2363 while (--numPts >= 0) { 2364 double x = srcPts[srcOff++]; 2365 double y = srcPts[srcOff++]; 2366 dstPts[dstOff++] = M00 * x + M01 * y + M02; 2367 dstPts[dstOff++] = M10 * x + M11 * y + M12; 2368 } 2369 return; 2370 case (APPLY_SHEAR | APPLY_SCALE): 2371 M00 = m00; M01 = m01; 2372 M10 = m10; M11 = m11; 2373 while (--numPts >= 0) { 2374 double x = srcPts[srcOff++]; 2375 double y = srcPts[srcOff++]; 2376 dstPts[dstOff++] = M00 * x + M01 * y; 2377 dstPts[dstOff++] = M10 * x + M11 * y; 2378 } 2379 return; 2380 case (APPLY_SHEAR | APPLY_TRANSLATE): 2381 M01 = m01; M02 = m02; 2382 M10 = m10; M12 = m12; 2383 while (--numPts >= 0) { 2384 double x = srcPts[srcOff++]; 2385 dstPts[dstOff++] = M01 * srcPts[srcOff++] + M02; 2386 dstPts[dstOff++] = M10 * x + M12; 2387 } 2388 return; 2389 case (APPLY_SHEAR): 2390 M01 = m01; M10 = m10; 2391 while (--numPts >= 0) { 2392 double x = srcPts[srcOff++]; 2393 dstPts[dstOff++] = M01 * srcPts[srcOff++]; 2394 dstPts[dstOff++] = M10 * x; 2395 } 2396 return; 2397 case (APPLY_SCALE | APPLY_TRANSLATE): 2398 M00 = m00; M02 = m02; 2399 M11 = m11; M12 = m12; 2400 while (--numPts >= 0) { 2401 dstPts[dstOff++] = M00 * srcPts[srcOff++] + M02; 2402 dstPts[dstOff++] = M11 * srcPts[srcOff++] + M12; 2403 } 2404 return; 2405 case (APPLY_SCALE): 2406 M00 = m00; M11 = m11; 2407 while (--numPts >= 0) { 2408 dstPts[dstOff++] = M00 * srcPts[srcOff++]; 2409 dstPts[dstOff++] = M11 * srcPts[srcOff++]; 2410 } 2411 return; 2412 case (APPLY_TRANSLATE): 2413 M02 = m02; M12 = m12; 2414 while (--numPts >= 0) { 2415 dstPts[dstOff++] = srcPts[srcOff++] + M02; 2416 dstPts[dstOff++] = srcPts[srcOff++] + M12; 2417 } 2418 return; 2419 case (APPLY_IDENTITY): 2420 if (srcPts != dstPts || srcOff != dstOff) { 2421 System.arraycopy(srcPts, srcOff, dstPts, dstOff, 2422 numPts * 2); 2423 } 2424 return; 2425 } 2426 2427 2428 } 2429 2430 2446 public void transform(float[] srcPts, int srcOff, 2447 double[] dstPts, int dstOff, 2448 int numPts) { 2449 double M00, M01, M02, M10, M11, M12; switch (state) { 2451 default: 2452 stateError(); 2453 2454 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2455 M00 = m00; M01 = m01; M02 = m02; 2456 M10 = m10; M11 = m11; M12 = m12; 2457 while (--numPts >= 0) { 2458 double x = srcPts[srcOff++]; 2459 double y = srcPts[srcOff++]; 2460 dstPts[dstOff++] = M00 * x + M01 * y + M02; 2461 dstPts[dstOff++] = M10 * x + M11 * y + M12; 2462 } 2463 return; 2464 case (APPLY_SHEAR | APPLY_SCALE): 2465 M00 = m00; M01 = m01; 2466 M10 = m10; M11 = m11; 2467 while (--numPts >= 0) { 2468 double x = srcPts[srcOff++]; 2469 double y = srcPts[srcOff++]; 2470 dstPts[dstOff++] = M00 * x + M01 * y; 2471 dstPts[dstOff++] = M10 * x + M11 * y; 2472 } 2473 return; 2474 case (APPLY_SHEAR | APPLY_TRANSLATE): 2475 M01 = m01; M02 = m02; 2476 M10 = m10; M12 = m12; 2477 while (--numPts >= 0) { 2478 double x = srcPts[srcOff++]; 2479 dstPts[dstOff++] = M01 * srcPts[srcOff++] + M02; 2480 dstPts[dstOff++] = M10 * x + M12; 2481 } 2482 return; 2483 case (APPLY_SHEAR): 2484 M01 = m01; M10 = m10; 2485 while (--numPts >= 0) { 2486 double x = srcPts[srcOff++]; 2487 dstPts[dstOff++] = M01 * srcPts[srcOff++]; 2488 dstPts[dstOff++] = M10 * x; 2489 } 2490 return; 2491 case (APPLY_SCALE | APPLY_TRANSLATE): 2492 M00 = m00; M02 = m02; 2493 M11 = m11; M12 = m12; 2494 while (--numPts >= 0) { 2495 dstPts[dstOff++] = M00 * srcPts[srcOff++] + M02; 2496 dstPts[dstOff++] = M11 * srcPts[srcOff++] + M12; 2497 } 2498 return; 2499 case (APPLY_SCALE): 2500 M00 = m00; M11 = m11; 2501 while (--numPts >= 0) { 2502 dstPts[dstOff++] = M00 * srcPts[srcOff++]; 2503 dstPts[dstOff++] = M11 * srcPts[srcOff++]; 2504 } 2505 return; 2506 case (APPLY_TRANSLATE): 2507 M02 = m02; M12 = m12; 2508 while (--numPts >= 0) { 2509 dstPts[dstOff++] = srcPts[srcOff++] + M02; 2510 dstPts[dstOff++] = srcPts[srcOff++] + M12; 2511 } 2512 return; 2513 case (APPLY_IDENTITY): 2514 while (--numPts >= 0) { 2515 dstPts[dstOff++] = srcPts[srcOff++]; 2516 dstPts[dstOff++] = srcPts[srcOff++]; 2517 } 2518 return; 2519 } 2520 2521 2522 } 2523 2524 2540 public void transform(double[] srcPts, int srcOff, 2541 float[] dstPts, int dstOff, 2542 int numPts) { 2543 double M00, M01, M02, M10, M11, M12; switch (state) { 2545 default: 2546 stateError(); 2547 2548 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2549 M00 = m00; M01 = m01; M02 = m02; 2550 M10 = m10; M11 = m11; M12 = m12; 2551 while (--numPts >= 0) { 2552 double x = srcPts[srcOff++]; 2553 double y = srcPts[srcOff++]; 2554 dstPts[dstOff++] = (float) (M00 * x + M01 * y + M02); 2555 dstPts[dstOff++] = (float) (M10 * x + M11 * y + M12); 2556 } 2557 return; 2558 case (APPLY_SHEAR | APPLY_SCALE): 2559 M00 = m00; M01 = m01; 2560 M10 = m10; M11 = m11; 2561 while (--numPts >= 0) { 2562 double x = srcPts[srcOff++]; 2563 double y = srcPts[srcOff++]; 2564 dstPts[dstOff++] = (float) (M00 * x + M01 * y); 2565 dstPts[dstOff++] = (float) (M10 * x + M11 * y); 2566 } 2567 return; 2568 case (APPLY_SHEAR | APPLY_TRANSLATE): 2569 M01 = m01; M02 = m02; 2570 M10 = m10; M12 = m12; 2571 while (--numPts >= 0) { 2572 double x = srcPts[srcOff++]; 2573 dstPts[dstOff++] = (float) (M01 * srcPts[srcOff++] + M02); 2574 dstPts[dstOff++] = (float) (M10 * x + M12); 2575 } 2576 return; 2577 case (APPLY_SHEAR): 2578 M01 = m01; M10 = m10; 2579 while (--numPts >= 0) { 2580 double x = srcPts[srcOff++]; 2581 dstPts[dstOff++] = (float) (M01 * srcPts[srcOff++]); 2582 dstPts[dstOff++] = (float) (M10 * x); 2583 } 2584 return; 2585 case (APPLY_SCALE | APPLY_TRANSLATE): 2586 M00 = m00; M02 = m02; 2587 M11 = m11; M12 = m12; 2588 while (--numPts >= 0) { 2589 dstPts[dstOff++] = (float) (M00 * srcPts[srcOff++] + M02); 2590 dstPts[dstOff++] = (float) (M11 * srcPts[srcOff++] + M12); 2591 } 2592 return; 2593 case (APPLY_SCALE): 2594 M00 = m00; M11 = m11; 2595 while (--numPts >= 0) { 2596 dstPts[dstOff++] = (float) (M00 * srcPts[srcOff++]); 2597 dstPts[dstOff++] = (float) (M11 * srcPts[srcOff++]); 2598 } 2599 return; 2600 case (APPLY_TRANSLATE): 2601 M02 = m02; M12 = m12; 2602 while (--numPts >= 0) { 2603 dstPts[dstOff++] = (float) (srcPts[srcOff++] + M02); 2604 dstPts[dstOff++] = (float) (srcPts[srcOff++] + M12); 2605 } 2606 return; 2607 case (APPLY_IDENTITY): 2608 while (--numPts >= 0) { 2609 dstPts[dstOff++] = (float) (srcPts[srcOff++]); 2610 dstPts[dstOff++] = (float) (srcPts[srcOff++]); 2611 } 2612 return; 2613 } 2614 2615 2616 } 2617 2618 2636 public Point2D inverseTransform(Point2D ptSrc, Point2D ptDst) 2637 throws NoninvertibleTransformException 2638 { 2639 if (ptDst == null) { 2640 if (ptSrc instanceof Point2D.Double ) { 2641 ptDst = new Point2D.Double (); 2642 } else { 2643 ptDst = new Point2D.Float (); 2644 } 2645 } 2646 double x = ptSrc.getX(); 2648 double y = ptSrc.getY(); 2649 switch (state) { 2650 default: 2651 stateError(); 2652 2653 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2654 x -= m02; 2655 y -= m12; 2656 2657 case (APPLY_SHEAR | APPLY_SCALE): 2658 double det = m00 * m11 - m01 * m10; 2659 if (Math.abs(det) <= Double.MIN_VALUE) { 2660 throw new NoninvertibleTransformException ("Determinant is "+ 2661 det); 2662 } 2663 ptDst.setLocation((x * m11 - y * m01) / det, 2664 (y * m00 - x * m10) / det); 2665 return ptDst; 2666 case (APPLY_SHEAR | APPLY_TRANSLATE): 2667 x -= m02; 2668 y -= m12; 2669 2670 case (APPLY_SHEAR): 2671 if (m01 == 0.0 || m10 == 0.0) { 2672 throw new NoninvertibleTransformException ("Determinant is 0"); 2673 } 2674 ptDst.setLocation(y / m10, x / m01); 2675 return ptDst; 2676 case (APPLY_SCALE | APPLY_TRANSLATE): 2677 x -= m02; 2678 y -= m12; 2679 2680 case (APPLY_SCALE): 2681 if (m00 == 0.0 || m11 == 0.0) { 2682 throw new NoninvertibleTransformException ("Determinant is 0"); 2683 } 2684 ptDst.setLocation(x / m00, y / m11); 2685 return ptDst; 2686 case (APPLY_TRANSLATE): 2687 ptDst.setLocation(x - m02, y - m12); 2688 return ptDst; 2689 case (APPLY_IDENTITY): 2690 ptDst.setLocation(x, y); 2691 return ptDst; 2692 } 2693 2694 2695 } 2696 2697 2720 public void inverseTransform(double[] srcPts, int srcOff, 2721 double[] dstPts, int dstOff, 2722 int numPts) 2723 throws NoninvertibleTransformException 2724 { 2725 double M00, M01, M02, M10, M11, M12; double det; 2727 if (dstPts == srcPts && 2728 dstOff > srcOff && dstOff < srcOff + numPts * 2) 2729 { 2730 System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); 2739 srcOff = dstOff; 2741 } 2742 switch (state) { 2743 default: 2744 stateError(); 2745 2746 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2747 M00 = m00; M01 = m01; M02 = m02; 2748 M10 = m10; M11 = m11; M12 = m12; 2749 det = M00 * M11 - M01 * M10; 2750 if (Math.abs(det) <= Double.MIN_VALUE) { 2751 throw new NoninvertibleTransformException ("Determinant is "+ 2752 det); 2753 } 2754 while (--numPts >= 0) { 2755 double x = srcPts[srcOff++] - M02; 2756 double y = srcPts[srcOff++] - M12; 2757 dstPts[dstOff++] = (x * M11 - y * M01) / det; 2758 dstPts[dstOff++] = (y * M00 - x * M10) / det; 2759 } 2760 return; 2761 case (APPLY_SHEAR | APPLY_SCALE): 2762 M00 = m00; M01 = m01; 2763 M10 = m10; M11 = m11; 2764 det = M00 * M11 - M01 * M10; 2765 if (Math.abs(det) <= Double.MIN_VALUE) { 2766 throw new NoninvertibleTransformException ("Determinant is "+ 2767 det); 2768 } 2769 while (--numPts >= 0) { 2770 double x = srcPts[srcOff++]; 2771 double y = srcPts[srcOff++]; 2772 dstPts[dstOff++] = (x * M11 - y * M01) / det; 2773 dstPts[dstOff++] = (y * M00 - x * M10) / det; 2774 } 2775 return; 2776 case (APPLY_SHEAR | APPLY_TRANSLATE): 2777 M01 = m01; M02 = m02; 2778 M10 = m10; M12 = m12; 2779 if (M01 == 0.0 || M10 == 0.0) { 2780 throw new NoninvertibleTransformException ("Determinant is 0"); 2781 } 2782 while (--numPts >= 0) { 2783 double x = srcPts[srcOff++] - M02; 2784 dstPts[dstOff++] = (srcPts[srcOff++] - M12) / M10; 2785 dstPts[dstOff++] = x / M01; 2786 } 2787 return; 2788 case (APPLY_SHEAR): 2789 M01 = m01; M10 = m10; 2790 if (M01 == 0.0 || M10 == 0.0) { 2791 throw new NoninvertibleTransformException ("Determinant is 0"); 2792 } 2793 while (--numPts >= 0) { 2794 double x = srcPts[srcOff++]; 2795 dstPts[dstOff++] = srcPts[srcOff++] / M10; 2796 dstPts[dstOff++] = x / M01; 2797 } 2798 return; 2799 case (APPLY_SCALE | APPLY_TRANSLATE): 2800 M00 = m00; M02 = m02; 2801 M11 = m11; M12 = m12; 2802 if (M00 == 0.0 || M11 == 0.0) { 2803 throw new NoninvertibleTransformException ("Determinant is 0"); 2804 } 2805 while (--numPts >= 0) { 2806 dstPts[dstOff++] = (srcPts[srcOff++] - M02) / M00; 2807 dstPts[dstOff++] = (srcPts[srcOff++] - M12) / M11; 2808 } 2809 return; 2810 case (APPLY_SCALE): 2811 M00 = m00; M11 = m11; 2812 if (M00 == 0.0 || M11 == 0.0) { 2813 throw new NoninvertibleTransformException ("Determinant is 0"); 2814 } 2815 while (--numPts >= 0) { 2816 dstPts[dstOff++] = srcPts[srcOff++] / M00; 2817 dstPts[dstOff++] = srcPts[srcOff++] / M11; 2818 } 2819 return; 2820 case (APPLY_TRANSLATE): 2821 M02 = m02; M12 = m12; 2822 while (--numPts >= 0) { 2823 dstPts[dstOff++] = srcPts[srcOff++] - M02; 2824 dstPts[dstOff++] = srcPts[srcOff++] - M12; 2825 } 2826 return; 2827 case (APPLY_IDENTITY): 2828 if (srcPts != dstPts || srcOff != dstOff) { 2829 System.arraycopy(srcPts, srcOff, dstPts, dstOff, 2830 numPts * 2); 2831 } 2832 return; 2833 } 2834 2835 2836 } 2837 2838 2862 public Point2D deltaTransform(Point2D ptSrc, Point2D ptDst) { 2863 if (ptDst == null) { 2864 if (ptSrc instanceof Point2D.Double ) { 2865 ptDst = new Point2D.Double (); 2866 } else { 2867 ptDst = new Point2D.Float (); 2868 } 2869 } 2870 double x = ptSrc.getX(); 2872 double y = ptSrc.getY(); 2873 switch (state) { 2874 default: 2875 stateError(); 2876 2877 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2878 case (APPLY_SHEAR | APPLY_SCALE): 2879 ptDst.setLocation(x * m00 + y * m01, x * m10 + y * m11); 2880 return ptDst; 2881 case (APPLY_SHEAR | APPLY_TRANSLATE): 2882 case (APPLY_SHEAR): 2883 ptDst.setLocation(y * m01, x * m10); 2884 return ptDst; 2885 case (APPLY_SCALE | APPLY_TRANSLATE): 2886 case (APPLY_SCALE): 2887 ptDst.setLocation(x * m00, y * m11); 2888 return ptDst; 2889 case (APPLY_TRANSLATE): 2890 case (APPLY_IDENTITY): 2891 ptDst.setLocation(x, y); 2892 return ptDst; 2893 } 2894 2895 2896 } 2897 2898 2928 public void deltaTransform(double[] srcPts, int srcOff, 2929 double[] dstPts, int dstOff, 2930 int numPts) { 2931 double M00, M01, M10, M11; if (dstPts == srcPts && 2933 dstOff > srcOff && dstOff < srcOff + numPts * 2) 2934 { 2935 System.arraycopy(srcPts, srcOff, dstPts, dstOff, numPts * 2); 2944 srcOff = dstOff; 2946 } 2947 switch (state) { 2948 default: 2949 stateError(); 2950 2951 case (APPLY_SHEAR | APPLY_SCALE | APPLY_TRANSLATE): 2952 case (APPLY_SHEAR | APPLY_SCALE): 2953 M00 = m00; M01 = m01; 2954 M10 = m10; M11 = m11; 2955 while (--numPts >= 0) { 2956 double x = srcPts[srcOff++]; 2957 double y = srcPts[srcOff++]; 2958 dstPts[dstOff++] = x * M00 + y * M01; 2959 dstPts[dstOff++] = x * M10 + y * M11; 2960 } 2961 return; 2962 case (APPLY_SHEAR | APPLY_TRANSLATE): 2963 case (APPLY_SHEAR): 2964 M01 = m01; M10 = m10; 2965 while (--numPts >= 0) { 2966 double x = srcPts[srcOff++]; 2967 dstPts[dstOff++] = srcPts[srcOff++] * M01; 2968 dstPts[dstOff++] = x * M10; 2969 } 2970 return; 2971 case (APPLY_SCALE | APPLY_TRANSLATE): 2972 case (APPLY_SCALE): 2973 M00 = m00; M11 = m11; 2974 while (--numPts >= 0) { 2975 dstPts[dstOff++] = srcPts[srcOff++] * M00; 2976 dstPts[dstOff++] = srcPts[srcOff++] * M11; 2977 } 2978 return; 2979 case (APPLY_TRANSLATE): 2980 case (APPLY_IDENTITY): 2981 if (srcPts != dstPts || srcOff != dstOff) { 2982 System.arraycopy(srcPts, srcOff, dstPts, dstOff, 2983 numPts * 2); 2984 } 2985 return; 2986 } 2987 2988 2989 } 2990 2991 3000 public Shape createTransformedShape(Shape pSrc) { 3001 if (pSrc == null) { 3002 return null; 3003 } 3004 3005 if (pSrc instanceof GeneralPath ) { 3006 return ((GeneralPath )pSrc).createTransformedShape(this); 3007 } else { 3008 PathIterator pi = pSrc.getPathIterator(this); 3009 GeneralPath gp = new GeneralPath (pi.getWindingRule()); 3010 gp.append(pi, false); 3011 return gp; 3012 } 3013 3014 3015 } 3016 3017 private static double _matround(double matval) { 3020 return Math.rint(matval * 1E15) / 1E15; 3021 } 3022 3023 3029 public String toString() { 3030 return ("AffineTransform[[" 3031 + _matround(m00) + ", " 3032 + _matround(m01) + ", " 3033 + _matround(m02) + "], [" 3034 + _matround(m10) + ", " 3035 + _matround(m11) + ", " 3036 + _matround(m12) + "]]"); 3037 } 3038 3039 3045 public boolean isIdentity() { 3046 return (state == APPLY_IDENTITY || (getType() == TYPE_IDENTITY)); 3047 } 3048 3049 3054 public Object clone() { 3055 try { 3056 return super.clone(); 3057 } catch (CloneNotSupportedException e) { 3058 throw new InternalError (); 3060 } 3061 } 3062 3063 3067 public int hashCode() { 3068 long bits = Double.doubleToLongBits(m00); 3069 bits = bits * 31 + Double.doubleToLongBits(m01); 3070 bits = bits * 31 + Double.doubleToLongBits(m02); 3071 bits = bits * 31 + Double.doubleToLongBits(m10); 3072 bits = bits * 31 + Double.doubleToLongBits(m11); 3073 bits = bits * 31 + Double.doubleToLongBits(m12); 3074 return (((int) bits) ^ ((int) (bits >> 32))); 3075 } 3076 3077 3086 public boolean equals(Object obj) { 3087 if (!(obj instanceof AffineTransform )) { 3088 return false; 3089 } 3090 3091 AffineTransform a = (AffineTransform )obj; 3092 3093 return ((m00 == a.m00) && (m01 == a.m01) && (m02 == a.m02) && 3094 (m10 == a.m10) && (m11 == a.m11) && (m12 == a.m12)); 3095 } 3096 3097 3103 3104 private void writeObject(java.io.ObjectOutputStream s) 3105 throws java.lang.ClassNotFoundException , java.io.IOException 3106 { 3107 s.defaultWriteObject(); 3108 } 3109 3110 private void readObject(java.io.ObjectInputStream s) 3111 throws java.lang.ClassNotFoundException , java.io.IOException 3112 { 3113 s.defaultReadObject(); 3114 updateState(); 3115 } 3116} 3117 | Popular Tags |