--- /dev/null
+package awt2swing;
+
+import javax.swing.JButton;
+
+
+public class Button extends JButton {
+
+ public Button() {
+ super();
+ }
+
+ public Button(String text) {
+ super(text);
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+
+public class Canvas extends Panel {
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JCheckBox;
+
+public class Checkbox extends JCheckBox {
+
+ public Checkbox(String string, boolean b) {
+ super(string, b);
+ }
+
+ public Checkbox() {
+ super();
+ }
+
+ public boolean getState() {
+ return isSelected();
+ }
+
+ public void setState(boolean b) {
+ setSelected(b);
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JCheckBoxMenuItem;
+
+public class CheckboxMenuItem extends JCheckBoxMenuItem {
+
+ public CheckboxMenuItem(String string) {
+ super(string);
+ }
+
+ public CheckboxMenuItem() {
+ }
+
+ public CheckboxMenuItem(String string, boolean b) {
+ super(string, b);
+ }
+
+ public boolean getState() {
+ return isSelected();
+ }
+
+
+ public void setState(boolean tf) {
+ setSelected(tf);
+ }
+
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JComboBox;
+
+
+public class Choice extends JComboBox {
+
+ public void select(Object key) {
+ setSelectedItem(key);
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JFrame;
+
+public class Frame extends JFrame {
+
+ public Frame(String title) {
+ super(title);
+ /**
+ * @j2sNative
+ *
+ * xxxf = this;
+ */
+ {}
+ }
+
+ public Frame() {
+ super();
+ /**
+ * @j2sNative
+ *
+ * xxxf = this;
+ */
+ {}
+ }
+
+ public void remove(int i) {
+ /**
+ * SwingJ has a somewhat reduced method set; we just use
+ * this interface to add ones we feel we need.
+ *
+ * @j2sNative
+ *
+ * this.removeInt(i);
+ *
+ */
+ {
+ super.remove(i);
+ }
+ }
+
+ public void setMenuBar(MenuBar m) {
+ setJMenuBar(m);
+ }
+
+ public void unsetMenuBar() {
+ setJMenuBar(null);
+ }
+
+
+ public MenuBar getMenubar() {
+ return (MenuBar) getJMenuBar();
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JLabel;
+
+public class Label extends JLabel {
+
+ public Label() {
+ super();
+ }
+
+ public Label(String text) {
+ super(text);
+ }
+
+ public Label(String text, int center) {
+ super(text, center);
+ }
+
+ public void setAlignment(int alignment) {
+ setAlignmentX(alignment);
+
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JMenu;
+
+public class Menu extends JMenu {
+
+ public Menu(String title) {
+ super(title);
+ title=null;
+ }
+
+ public Menu() {
+ super();
+ String s = null;
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JMenuBar;
+
+public class MenuBar extends JMenuBar {
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JMenuItem;
+
+public class MenuItem extends JMenuItem {
+
+ public MenuItem(String string) {
+ super(string);
+ }
+
+ public MenuItem() {
+ super();
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import java.awt.Graphics;
+import java.awt.LayoutManager;
+
+import javax.swing.JPanel;
+
+public class Panel extends JPanel {
+
+ public Panel(LayoutManager layout) {
+ super(layout);
+ }
+
+ public Panel() {
+ super();
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JPopupMenu;
+
+public class PopupMenu extends JPopupMenu {
+
+ public PopupMenu() {
+ super();
+ }
+
+ public PopupMenu(String string) {
+ super(string);
+ }
+
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JScrollPane;
+
+public class ScrollPane extends JScrollPane {
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JScrollBar;
+
+public class Scrollbar extends JScrollBar {
+
+ public Scrollbar(int direction) {
+ super(direction);
+ }
+
+ public Scrollbar() {
+ super();
+ }
+
+ public Scrollbar(int orientation, int value, int extent, int min, int max) {
+ super(orientation, value, extent, min, max);
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import javax.swing.JTextArea;
+
+public class TextArea extends JTextArea {
+
+ public TextArea(int rows, int cols) {
+ super(rows, cols);
+ }
+
+ public TextArea() {
+ super();
+ }
+
+}
--- /dev/null
+package awt2swing;
+
+import jalview.structures.models.AAStructureBindingModel;
+
+import java.awt.event.TextEvent;
+import java.awt.event.TextListener;
+
+import javax.swing.JTextField;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+public class TextField extends JTextField {
+
+ public TextField(int width) {
+ super(width);
+ }
+
+ public TextField() {
+ super();
+ }
+
+ public TextField(String text, int width) {
+ super(text, width);
+ }
+
+ public void addTextListener(final TextListener textListener) {
+ getDocument().addDocumentListener(new DocumentListener() {
+
+ @Override
+ public void insertUpdate(DocumentEvent e) {
+ }
+
+ @Override
+ public void removeUpdate(DocumentEvent e) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void changedUpdate(DocumentEvent e) {
+ textListener.textValueChanged(new TextEvent(this, 0));
+ }
+ });
+ }
+
+}
public void apply(StringBufferLike sb, RegRes res)
{
- String x = res.stringMatched(n);
+ String x = res.stringMatchedI(n);
sb.append(x == null ? "" : x);
}
*/
public interface BasicStringBufferLike
{
- public void append(char c);
+ public void appendC(char c);
public void append(String s);
final static boolean java_1_0 = false;
/** Convert a character to upper case . */
- public static char toUpperCase(char c)
+ public static char toUpperCaseC(char c)
{
- if (java_1_0)
- {
- int ret = (int) c;
- switch (c)
- {
- case 97:
- ret = 65;
- break;
- case 98:
- ret = 66;
- break;
- case 99:
- ret = 67;
- break;
- case 100:
- ret = 68;
- break;
- case 101:
- ret = 69;
- break;
- case 102:
- ret = 70;
- break;
- case 103:
- ret = 71;
- break;
- case 104:
- ret = 72;
- break;
- case 105:
- ret = 73;
- break;
- case 106:
- ret = 74;
- break;
- case 107:
- ret = 75;
- break;
- case 108:
- ret = 76;
- break;
- case 109:
- ret = 77;
- break;
- case 110:
- ret = 78;
- break;
- case 111:
- ret = 79;
- break;
- case 112:
- ret = 80;
- break;
- case 113:
- ret = 81;
- break;
- case 114:
- ret = 82;
- break;
- case 115:
- ret = 83;
- break;
- case 116:
- ret = 84;
- break;
- case 117:
- ret = 85;
- break;
- case 118:
- ret = 86;
- break;
- case 119:
- ret = 87;
- break;
- case 120:
- ret = 88;
- break;
- case 121:
- ret = 89;
- break;
- case 122:
- ret = 90;
- break;
- case 224:
- ret = 192;
- break;
- case 225:
- ret = 193;
- break;
- case 226:
- ret = 194;
- break;
- case 227:
- ret = 195;
- break;
- case 228:
- ret = 196;
- break;
- case 229:
- ret = 197;
- break;
- case 230:
- ret = 198;
- break;
- case 231:
- ret = 199;
- break;
- case 232:
- ret = 200;
- break;
- case 233:
- ret = 201;
- break;
- case 234:
- ret = 202;
- break;
- case 235:
- ret = 203;
- break;
- case 236:
- ret = 204;
- break;
- case 237:
- ret = 205;
- break;
- case 238:
- ret = 206;
- break;
- case 239:
- ret = 207;
- break;
- case 240:
- ret = 208;
- break;
- case 241:
- ret = 209;
- break;
- case 242:
- ret = 210;
- break;
- case 243:
- ret = 211;
- break;
- case 244:
- ret = 212;
- break;
- case 245:
- ret = 213;
- break;
- case 246:
- ret = 214;
- break;
- case 248:
- ret = 216;
- break;
- case 249:
- ret = 217;
- break;
- case 250:
- ret = 218;
- break;
- case 251:
- ret = 219;
- break;
- case 252:
- ret = 220;
- break;
- case 253:
- ret = 221;
- break;
- case 254:
- ret = 222;
- break;
- case 255:
- ret = 376;
- break;
- case 257:
- ret = 256;
- break;
- case 259:
- ret = 258;
- break;
- case 261:
- ret = 260;
- break;
- case 263:
- ret = 262;
- break;
- case 265:
- ret = 264;
- break;
- case 267:
- ret = 266;
- break;
- case 269:
- ret = 268;
- break;
- case 271:
- ret = 270;
- break;
- case 273:
- ret = 272;
- break;
- case 275:
- ret = 274;
- break;
- case 277:
- ret = 276;
- break;
- case 279:
- ret = 278;
- break;
- case 281:
- ret = 280;
- break;
- case 283:
- ret = 282;
- break;
- case 285:
- ret = 284;
- break;
- case 287:
- ret = 286;
- break;
- case 289:
- ret = 288;
- break;
- case 291:
- ret = 290;
- break;
- case 293:
- ret = 292;
- break;
- case 295:
- ret = 294;
- break;
- case 297:
- ret = 296;
- break;
- case 299:
- ret = 298;
- break;
- case 301:
- ret = 300;
- break;
- case 303:
- ret = 302;
- break;
- case 305:
- ret = 73;
- break;
- case 307:
- ret = 306;
- break;
- case 309:
- ret = 308;
- break;
- case 311:
- ret = 310;
- break;
- case 314:
- ret = 313;
- break;
- case 316:
- ret = 315;
- break;
- case 318:
- ret = 317;
- break;
- case 320:
- ret = 319;
- break;
- case 322:
- ret = 321;
- break;
- case 324:
- ret = 323;
- break;
- case 326:
- ret = 325;
- break;
- case 328:
- ret = 327;
- break;
- case 331:
- ret = 330;
- break;
- case 333:
- ret = 332;
- break;
- case 335:
- ret = 334;
- break;
- case 337:
- ret = 336;
- break;
- case 339:
- ret = 338;
- break;
- case 341:
- ret = 340;
- break;
- case 343:
- ret = 342;
- break;
- case 345:
- ret = 344;
- break;
- case 347:
- ret = 346;
- break;
- case 349:
- ret = 348;
- break;
- case 351:
- ret = 350;
- break;
- case 353:
- ret = 352;
- break;
- case 355:
- ret = 354;
- break;
- case 357:
- ret = 356;
- break;
- case 359:
- ret = 358;
- break;
- case 361:
- ret = 360;
- break;
- case 363:
- ret = 362;
- break;
- case 365:
- ret = 364;
- break;
- case 367:
- ret = 366;
- break;
- case 369:
- ret = 368;
- break;
- case 371:
- ret = 370;
- break;
- case 373:
- ret = 372;
- break;
- case 375:
- ret = 374;
- break;
- case 378:
- ret = 377;
- break;
- case 380:
- ret = 379;
- break;
- case 382:
- ret = 381;
- break;
- case 383:
- ret = 83;
- break;
- case 387:
- ret = 386;
- break;
- case 389:
- ret = 388;
- break;
- case 392:
- ret = 391;
- break;
- case 396:
- ret = 395;
- break;
- case 402:
- ret = 401;
- break;
- case 409:
- ret = 408;
- break;
- case 417:
- ret = 416;
- break;
- case 419:
- ret = 418;
- break;
- case 421:
- ret = 420;
- break;
- case 424:
- ret = 423;
- break;
- case 429:
- ret = 428;
- break;
- case 432:
- ret = 431;
- break;
- case 436:
- ret = 435;
- break;
- case 438:
- ret = 437;
- break;
- case 441:
- ret = 440;
- break;
- case 445:
- ret = 444;
- break;
- case 453:
- ret = 452;
- break;
- case 454:
- ret = 452;
- break;
- case 456:
- ret = 455;
- break;
- case 457:
- ret = 455;
- break;
- case 459:
- ret = 458;
- break;
- case 460:
- ret = 458;
- break;
- case 462:
- ret = 461;
- break;
- case 464:
- ret = 463;
- break;
- case 466:
- ret = 465;
- break;
- case 468:
- ret = 467;
- break;
- case 470:
- ret = 469;
- break;
- case 472:
- ret = 471;
- break;
- case 474:
- ret = 473;
- break;
- case 476:
- ret = 475;
- break;
- case 479:
- ret = 478;
- break;
- case 481:
- ret = 480;
- break;
- case 483:
- ret = 482;
- break;
- case 485:
- ret = 484;
- break;
- case 487:
- ret = 486;
- break;
- case 489:
- ret = 488;
- break;
- case 491:
- ret = 490;
- break;
- case 493:
- ret = 492;
- break;
- case 495:
- ret = 494;
- break;
- case 498:
- ret = 497;
- break;
- case 499:
- ret = 497;
- break;
- case 501:
- ret = 500;
- break;
- case 507:
- ret = 506;
- break;
- case 509:
- ret = 508;
- break;
- case 511:
- ret = 510;
- break;
- case 513:
- ret = 512;
- break;
- case 515:
- ret = 514;
- break;
- case 517:
- ret = 516;
- break;
- case 519:
- ret = 518;
- break;
- case 521:
- ret = 520;
- break;
- case 523:
- ret = 522;
- break;
- case 525:
- ret = 524;
- break;
- case 527:
- ret = 526;
- break;
- case 529:
- ret = 528;
- break;
- case 531:
- ret = 530;
- break;
- case 533:
- ret = 532;
- break;
- case 535:
- ret = 534;
- break;
- case 595:
- ret = 385;
- break;
- case 596:
- ret = 390;
- break;
- case 598:
- ret = 393;
- break;
- case 599:
- ret = 394;
- break;
- case 600:
- ret = 398;
- break;
- case 601:
- ret = 399;
- break;
- case 603:
- ret = 400;
- break;
- case 608:
- ret = 403;
- break;
- case 611:
- ret = 404;
- break;
- case 616:
- ret = 407;
- break;
- case 617:
- ret = 406;
- break;
- case 623:
- ret = 412;
- break;
- case 626:
- ret = 413;
- break;
- case 643:
- ret = 425;
- break;
- case 648:
- ret = 430;
- break;
- case 650:
- ret = 433;
- break;
- case 651:
- ret = 434;
- break;
- case 658:
- ret = 439;
- break;
- case 940:
- ret = 902;
- break;
- case 941:
- ret = 904;
- break;
- case 942:
- ret = 905;
- break;
- case 943:
- ret = 906;
- break;
- case 945:
- ret = 913;
- break;
- case 946:
- ret = 914;
- break;
- case 947:
- ret = 915;
- break;
- case 948:
- ret = 916;
- break;
- case 949:
- ret = 917;
- break;
- case 950:
- ret = 918;
- break;
- case 951:
- ret = 919;
- break;
- case 952:
- ret = 920;
- break;
- case 953:
- ret = 921;
- break;
- case 954:
- ret = 922;
- break;
- case 955:
- ret = 923;
- break;
- case 956:
- ret = 924;
- break;
- case 957:
- ret = 925;
- break;
- case 958:
- ret = 926;
- break;
- case 959:
- ret = 927;
- break;
- case 960:
- ret = 928;
- break;
- case 961:
- ret = 929;
- break;
- case 963:
- ret = 931;
- break;
- case 964:
- ret = 932;
- break;
- case 965:
- ret = 933;
- break;
- case 966:
- ret = 934;
- break;
- case 967:
- ret = 935;
- break;
- case 968:
- ret = 936;
- break;
- case 969:
- ret = 937;
- break;
- case 970:
- ret = 938;
- break;
- case 971:
- ret = 939;
- break;
- case 972:
- ret = 908;
- break;
- case 973:
- ret = 910;
- break;
- case 974:
- ret = 911;
- break;
- case 976:
- ret = 914;
- break;
- case 977:
- ret = 920;
- break;
- case 981:
- ret = 934;
- break;
- case 982:
- ret = 928;
- break;
- case 995:
- ret = 994;
- break;
- case 997:
- ret = 996;
- break;
- case 999:
- ret = 998;
- break;
- case 1001:
- ret = 1000;
- break;
- case 1003:
- ret = 1002;
- break;
- case 1005:
- ret = 1004;
- break;
- case 1007:
- ret = 1006;
- break;
- case 1008:
- ret = 922;
- break;
- case 1009:
- ret = 929;
- break;
- case 1072:
- ret = 1040;
- break;
- case 1073:
- ret = 1041;
- break;
- case 1074:
- ret = 1042;
- break;
- case 1075:
- ret = 1043;
- break;
- case 1076:
- ret = 1044;
- break;
- case 1077:
- ret = 1045;
- break;
- case 1078:
- ret = 1046;
- break;
- case 1079:
- ret = 1047;
- break;
- case 1080:
- ret = 1048;
- break;
- case 1081:
- ret = 1049;
- break;
- case 1082:
- ret = 1050;
- break;
- case 1083:
- ret = 1051;
- break;
- case 1084:
- ret = 1052;
- break;
- case 1085:
- ret = 1053;
- break;
- case 1086:
- ret = 1054;
- break;
- case 1087:
- ret = 1055;
- break;
- case 1088:
- ret = 1056;
- break;
- case 1089:
- ret = 1057;
- break;
- case 1090:
- ret = 1058;
- break;
- case 1091:
- ret = 1059;
- break;
- case 1092:
- ret = 1060;
- break;
- case 1093:
- ret = 1061;
- break;
- case 1094:
- ret = 1062;
- break;
- case 1095:
- ret = 1063;
- break;
- case 1096:
- ret = 1064;
- break;
- case 1097:
- ret = 1065;
- break;
- case 1098:
- ret = 1066;
- break;
- case 1099:
- ret = 1067;
- break;
- case 1100:
- ret = 1068;
- break;
- case 1101:
- ret = 1069;
- break;
- case 1102:
- ret = 1070;
- break;
- case 1103:
- ret = 1071;
- break;
- case 1105:
- ret = 1025;
- break;
- case 1106:
- ret = 1026;
- break;
- case 1107:
- ret = 1027;
- break;
- case 1108:
- ret = 1028;
- break;
- case 1109:
- ret = 1029;
- break;
- case 1110:
- ret = 1030;
- break;
- case 1111:
- ret = 1031;
- break;
- case 1112:
- ret = 1032;
- break;
- case 1113:
- ret = 1033;
- break;
- case 1114:
- ret = 1034;
- break;
- case 1115:
- ret = 1035;
- break;
- case 1116:
- ret = 1036;
- break;
- case 1118:
- ret = 1038;
- break;
- case 1119:
- ret = 1039;
- break;
- case 1121:
- ret = 1120;
- break;
- case 1123:
- ret = 1122;
- break;
- case 1125:
- ret = 1124;
- break;
- case 1127:
- ret = 1126;
- break;
- case 1129:
- ret = 1128;
- break;
- case 1131:
- ret = 1130;
- break;
- case 1133:
- ret = 1132;
- break;
- case 1135:
- ret = 1134;
- break;
- case 1137:
- ret = 1136;
- break;
- case 1139:
- ret = 1138;
- break;
- case 1141:
- ret = 1140;
- break;
- case 1143:
- ret = 1142;
- break;
- case 1145:
- ret = 1144;
- break;
- case 1147:
- ret = 1146;
- break;
- case 1149:
- ret = 1148;
- break;
- case 1151:
- ret = 1150;
- break;
- case 1153:
- ret = 1152;
- break;
- case 1169:
- ret = 1168;
- break;
- case 1171:
- ret = 1170;
- break;
- case 1173:
- ret = 1172;
- break;
- case 1175:
- ret = 1174;
- break;
- case 1177:
- ret = 1176;
- break;
- case 1179:
- ret = 1178;
- break;
- case 1181:
- ret = 1180;
- break;
- case 1183:
- ret = 1182;
- break;
- case 1185:
- ret = 1184;
- break;
- case 1187:
- ret = 1186;
- break;
- case 1189:
- ret = 1188;
- break;
- case 1191:
- ret = 1190;
- break;
- case 1193:
- ret = 1192;
- break;
- case 1195:
- ret = 1194;
- break;
- case 1197:
- ret = 1196;
- break;
- case 1199:
- ret = 1198;
- break;
- case 1201:
- ret = 1200;
- break;
- case 1203:
- ret = 1202;
- break;
- case 1205:
- ret = 1204;
- break;
- case 1207:
- ret = 1206;
- break;
- case 1209:
- ret = 1208;
- break;
- case 1211:
- ret = 1210;
- break;
- case 1213:
- ret = 1212;
- break;
- case 1215:
- ret = 1214;
- break;
- case 1218:
- ret = 1217;
- break;
- case 1220:
- ret = 1219;
- break;
- case 1224:
- ret = 1223;
- break;
- case 1228:
- ret = 1227;
- break;
- case 1233:
- ret = 1232;
- break;
- case 1235:
- ret = 1234;
- break;
- case 1237:
- ret = 1236;
- break;
- case 1239:
- ret = 1238;
- break;
- case 1241:
- ret = 1240;
- break;
- case 1243:
- ret = 1242;
- break;
- case 1245:
- ret = 1244;
- break;
- case 1247:
- ret = 1246;
- break;
- case 1249:
- ret = 1248;
- break;
- case 1251:
- ret = 1250;
- break;
- case 1253:
- ret = 1252;
- break;
- case 1255:
- ret = 1254;
- break;
- case 1257:
- ret = 1256;
- break;
- case 1259:
- ret = 1258;
- break;
- case 1263:
- ret = 1262;
- break;
- case 1265:
- ret = 1264;
- break;
- case 1267:
- ret = 1266;
- break;
- case 1269:
- ret = 1268;
- break;
- case 1273:
- ret = 1272;
- break;
- case 1377:
- ret = 1329;
- break;
- case 1378:
- ret = 1330;
- break;
- case 1379:
- ret = 1331;
- break;
- case 1380:
- ret = 1332;
- break;
- case 1381:
- ret = 1333;
- break;
- case 1382:
- ret = 1334;
- break;
- case 1383:
- ret = 1335;
- break;
- case 1384:
- ret = 1336;
- break;
- case 1385:
- ret = 1337;
- break;
- case 1386:
- ret = 1338;
- break;
- case 1387:
- ret = 1339;
- break;
- case 1388:
- ret = 1340;
- break;
- case 1389:
- ret = 1341;
- break;
- case 1390:
- ret = 1342;
- break;
- case 1391:
- ret = 1343;
- break;
- case 1392:
- ret = 1344;
- break;
- case 1393:
- ret = 1345;
- break;
- case 1394:
- ret = 1346;
- break;
- case 1395:
- ret = 1347;
- break;
- case 1396:
- ret = 1348;
- break;
- case 1397:
- ret = 1349;
- break;
- case 1398:
- ret = 1350;
- break;
- case 1399:
- ret = 1351;
- break;
- case 1400:
- ret = 1352;
- break;
- case 1401:
- ret = 1353;
- break;
- case 1402:
- ret = 1354;
- break;
- case 1403:
- ret = 1355;
- break;
- case 1404:
- ret = 1356;
- break;
- case 1405:
- ret = 1357;
- break;
- case 1406:
- ret = 1358;
- break;
- case 1407:
- ret = 1359;
- break;
- case 1408:
- ret = 1360;
- break;
- case 1409:
- ret = 1361;
- break;
- case 1410:
- ret = 1362;
- break;
- case 1411:
- ret = 1363;
- break;
- case 1412:
- ret = 1364;
- break;
- case 1413:
- ret = 1365;
- break;
- case 1414:
- ret = 1366;
- break;
- case 7681:
- ret = 7680;
- break;
- case 7683:
- ret = 7682;
- break;
- case 7685:
- ret = 7684;
- break;
- case 7687:
- ret = 7686;
- break;
- case 7689:
- ret = 7688;
- break;
- case 7691:
- ret = 7690;
- break;
- case 7693:
- ret = 7692;
- break;
- case 7695:
- ret = 7694;
- break;
- case 7697:
- ret = 7696;
- break;
- case 7699:
- ret = 7698;
- break;
- case 7701:
- ret = 7700;
- break;
- case 7703:
- ret = 7702;
- break;
- case 7705:
- ret = 7704;
- break;
- case 7707:
- ret = 7706;
- break;
- case 7709:
- ret = 7708;
- break;
- case 7711:
- ret = 7710;
- break;
- case 7713:
- ret = 7712;
- break;
- case 7715:
- ret = 7714;
- break;
- case 7717:
- ret = 7716;
- break;
- case 7719:
- ret = 7718;
- break;
- case 7721:
- ret = 7720;
- break;
- case 7723:
- ret = 7722;
- break;
- case 7725:
- ret = 7724;
- break;
- case 7727:
- ret = 7726;
- break;
- case 7729:
- ret = 7728;
- break;
- case 7731:
- ret = 7730;
- break;
- case 7733:
- ret = 7732;
- break;
- case 7735:
- ret = 7734;
- break;
- case 7737:
- ret = 7736;
- break;
- case 7739:
- ret = 7738;
- break;
- case 7741:
- ret = 7740;
- break;
- case 7743:
- ret = 7742;
- break;
- case 7745:
- ret = 7744;
- break;
- case 7747:
- ret = 7746;
- break;
- case 7749:
- ret = 7748;
- break;
- case 7751:
- ret = 7750;
- break;
- case 7753:
- ret = 7752;
- break;
- case 7755:
- ret = 7754;
- break;
- case 7757:
- ret = 7756;
- break;
- case 7759:
- ret = 7758;
- break;
- case 7761:
- ret = 7760;
- break;
- case 7763:
- ret = 7762;
- break;
- case 7765:
- ret = 7764;
- break;
- case 7767:
- ret = 7766;
- break;
- case 7769:
- ret = 7768;
- break;
- case 7771:
- ret = 7770;
- break;
- case 7773:
- ret = 7772;
- break;
- case 7775:
- ret = 7774;
- break;
- case 7777:
- ret = 7776;
- break;
- case 7779:
- ret = 7778;
- break;
- case 7781:
- ret = 7780;
- break;
- case 7783:
- ret = 7782;
- break;
- case 7785:
- ret = 7784;
- break;
- case 7787:
- ret = 7786;
- break;
- case 7789:
- ret = 7788;
- break;
- case 7791:
- ret = 7790;
- break;
- case 7793:
- ret = 7792;
- break;
- case 7795:
- ret = 7794;
- break;
- case 7797:
- ret = 7796;
- break;
- case 7799:
- ret = 7798;
- break;
- case 7801:
- ret = 7800;
- break;
- case 7803:
- ret = 7802;
- break;
- case 7805:
- ret = 7804;
- break;
- case 7807:
- ret = 7806;
- break;
- case 7809:
- ret = 7808;
- break;
- case 7811:
- ret = 7810;
- break;
- case 7813:
- ret = 7812;
- break;
- case 7815:
- ret = 7814;
- break;
- case 7817:
- ret = 7816;
- break;
- case 7819:
- ret = 7818;
- break;
- case 7821:
- ret = 7820;
- break;
- case 7823:
- ret = 7822;
- break;
- case 7825:
- ret = 7824;
- break;
- case 7827:
- ret = 7826;
- break;
- case 7829:
- ret = 7828;
- break;
- case 7841:
- ret = 7840;
- break;
- case 7843:
- ret = 7842;
- break;
- case 7845:
- ret = 7844;
- break;
- case 7847:
- ret = 7846;
- break;
- case 7849:
- ret = 7848;
- break;
- case 7851:
- ret = 7850;
- break;
- case 7853:
- ret = 7852;
- break;
- case 7855:
- ret = 7854;
- break;
- case 7857:
- ret = 7856;
- break;
- case 7859:
- ret = 7858;
- break;
- case 7861:
- ret = 7860;
- break;
- case 7863:
- ret = 7862;
- break;
- case 7865:
- ret = 7864;
- break;
- case 7867:
- ret = 7866;
- break;
- case 7869:
- ret = 7868;
- break;
- case 7871:
- ret = 7870;
- break;
- case 7873:
- ret = 7872;
- break;
- case 7875:
- ret = 7874;
- break;
- case 7877:
- ret = 7876;
- break;
- case 7879:
- ret = 7878;
- break;
- case 7881:
- ret = 7880;
- break;
- case 7883:
- ret = 7882;
- break;
- case 7885:
- ret = 7884;
- break;
- case 7887:
- ret = 7886;
- break;
- case 7889:
- ret = 7888;
- break;
- case 7891:
- ret = 7890;
- break;
- case 7893:
- ret = 7892;
- break;
- case 7895:
- ret = 7894;
- break;
- case 7897:
- ret = 7896;
- break;
- case 7899:
- ret = 7898;
- break;
- case 7901:
- ret = 7900;
- break;
- case 7903:
- ret = 7902;
- break;
- case 7905:
- ret = 7904;
- break;
- case 7907:
- ret = 7906;
- break;
- case 7909:
- ret = 7908;
- break;
- case 7911:
- ret = 7910;
- break;
- case 7913:
- ret = 7912;
- break;
- case 7915:
- ret = 7914;
- break;
- case 7917:
- ret = 7916;
- break;
- case 7919:
- ret = 7918;
- break;
- case 7921:
- ret = 7920;
- break;
- case 7923:
- ret = 7922;
- break;
- case 7925:
- ret = 7924;
- break;
- case 7927:
- ret = 7926;
- break;
- case 7929:
- ret = 7928;
- break;
- case 7936:
- ret = 7944;
- break;
- case 7937:
- ret = 7945;
- break;
- case 7938:
- ret = 7946;
- break;
- case 7939:
- ret = 7947;
- break;
- case 7940:
- ret = 7948;
- break;
- case 7941:
- ret = 7949;
- break;
- case 7942:
- ret = 7950;
- break;
- case 7943:
- ret = 7951;
- break;
- case 7952:
- ret = 7960;
- break;
- case 7953:
- ret = 7961;
- break;
- case 7954:
- ret = 7962;
- break;
- case 7955:
- ret = 7963;
- break;
- case 7956:
- ret = 7964;
- break;
- case 7957:
- ret = 7965;
- break;
- case 7968:
- ret = 7976;
- break;
- case 7969:
- ret = 7977;
- break;
- case 7970:
- ret = 7978;
- break;
- case 7971:
- ret = 7979;
- break;
- case 7972:
- ret = 7980;
- break;
- case 7973:
- ret = 7981;
- break;
- case 7974:
- ret = 7982;
- break;
- case 7975:
- ret = 7983;
- break;
- case 7984:
- ret = 7992;
- break;
- case 7985:
- ret = 7993;
- break;
- case 7986:
- ret = 7994;
- break;
- case 7987:
- ret = 7995;
- break;
- case 7988:
- ret = 7996;
- break;
- case 7989:
- ret = 7997;
- break;
- case 7990:
- ret = 7998;
- break;
- case 7991:
- ret = 7999;
- break;
- case 8000:
- ret = 8008;
- break;
- case 8001:
- ret = 8009;
- break;
- case 8002:
- ret = 8010;
- break;
- case 8003:
- ret = 8011;
- break;
- case 8004:
- ret = 8012;
- break;
- case 8005:
- ret = 8013;
- break;
- case 8017:
- ret = 8025;
- break;
- case 8019:
- ret = 8027;
- break;
- case 8021:
- ret = 8029;
- break;
- case 8023:
- ret = 8031;
- break;
- case 8032:
- ret = 8040;
- break;
- case 8033:
- ret = 8041;
- break;
- case 8034:
- ret = 8042;
- break;
- case 8035:
- ret = 8043;
- break;
- case 8036:
- ret = 8044;
- break;
- case 8037:
- ret = 8045;
- break;
- case 8038:
- ret = 8046;
- break;
- case 8039:
- ret = 8047;
- break;
- case 8048:
- ret = 8122;
- break;
- case 8049:
- ret = 8123;
- break;
- case 8050:
- ret = 8136;
- break;
- case 8051:
- ret = 8137;
- break;
- case 8052:
- ret = 8138;
- break;
- case 8053:
- ret = 8139;
- break;
- case 8054:
- ret = 8154;
- break;
- case 8055:
- ret = 8155;
- break;
- case 8056:
- ret = 8184;
- break;
- case 8057:
- ret = 8185;
- break;
- case 8058:
- ret = 8170;
- break;
- case 8059:
- ret = 8171;
- break;
- case 8060:
- ret = 8186;
- break;
- case 8061:
- ret = 8187;
- break;
- case 8064:
- ret = 8072;
- break;
- case 8065:
- ret = 8073;
- break;
- case 8066:
- ret = 8074;
- break;
- case 8067:
- ret = 8075;
- break;
- case 8068:
- ret = 8076;
- break;
- case 8069:
- ret = 8077;
- break;
- case 8070:
- ret = 8078;
- break;
- case 8071:
- ret = 8079;
- break;
- case 8080:
- ret = 8088;
- break;
- case 8081:
- ret = 8089;
- break;
- case 8082:
- ret = 8090;
- break;
- case 8083:
- ret = 8091;
- break;
- case 8084:
- ret = 8092;
- break;
- case 8085:
- ret = 8093;
- break;
- case 8086:
- ret = 8094;
- break;
- case 8087:
- ret = 8095;
- break;
- case 8096:
- ret = 8104;
- break;
- case 8097:
- ret = 8105;
- break;
- case 8098:
- ret = 8106;
- break;
- case 8099:
- ret = 8107;
- break;
- case 8100:
- ret = 8108;
- break;
- case 8101:
- ret = 8109;
- break;
- case 8102:
- ret = 8110;
- break;
- case 8103:
- ret = 8111;
- break;
- case 8112:
- ret = 8120;
- break;
- case 8113:
- ret = 8121;
- break;
- case 8115:
- ret = 8124;
- break;
- case 8131:
- ret = 8140;
- break;
- case 8144:
- ret = 8152;
- break;
- case 8145:
- ret = 8153;
- break;
- case 8160:
- ret = 8168;
- break;
- case 8161:
- ret = 8169;
- break;
- case 8165:
- ret = 8172;
- break;
- case 8179:
- ret = 8188;
- break;
- case 8560:
- ret = 8544;
- break;
- case 8561:
- ret = 8545;
- break;
- case 8562:
- ret = 8546;
- break;
- case 8563:
- ret = 8547;
- break;
- case 8564:
- ret = 8548;
- break;
- case 8565:
- ret = 8549;
- break;
- case 8566:
- ret = 8550;
- break;
- case 8567:
- ret = 8551;
- break;
- case 8568:
- ret = 8552;
- break;
- case 8569:
- ret = 8553;
- break;
- case 8570:
- ret = 8554;
- break;
- case 8571:
- ret = 8555;
- break;
- case 8572:
- ret = 8556;
- break;
- case 8573:
- ret = 8557;
- break;
- case 8574:
- ret = 8558;
- break;
- case 8575:
- ret = 8559;
- break;
- case 9424:
- ret = 9398;
- break;
- case 9425:
- ret = 9399;
- break;
- case 9426:
- ret = 9400;
- break;
- case 9427:
- ret = 9401;
- break;
- case 9428:
- ret = 9402;
- break;
- case 9429:
- ret = 9403;
- break;
- case 9430:
- ret = 9404;
- break;
- case 9431:
- ret = 9405;
- break;
- case 9432:
- ret = 9406;
- break;
- case 9433:
- ret = 9407;
- break;
- case 9434:
- ret = 9408;
- break;
- case 9435:
- ret = 9409;
- break;
- case 9436:
- ret = 9410;
- break;
- case 9437:
- ret = 9411;
- break;
- case 9438:
- ret = 9412;
- break;
- case 9439:
- ret = 9413;
- break;
- case 9440:
- ret = 9414;
- break;
- case 9441:
- ret = 9415;
- break;
- case 9442:
- ret = 9416;
- break;
- case 9443:
- ret = 9417;
- break;
- case 9444:
- ret = 9418;
- break;
- case 9445:
- ret = 9419;
- break;
- case 9446:
- ret = 9420;
- break;
- case 9447:
- ret = 9421;
- break;
- case 9448:
- ret = 9422;
- break;
- case 9449:
- ret = 9423;
- break;
- case 65345:
- ret = 65313;
- break;
- case 65346:
- ret = 65314;
- break;
- case 65347:
- ret = 65315;
- break;
- case 65348:
- ret = 65316;
- break;
- case 65349:
- ret = 65317;
- break;
- case 65350:
- ret = 65318;
- break;
- case 65351:
- ret = 65319;
- break;
- case 65352:
- ret = 65320;
- break;
- case 65353:
- ret = 65321;
- break;
- case 65354:
- ret = 65322;
- break;
- case 65355:
- ret = 65323;
- break;
- case 65356:
- ret = 65324;
- break;
- case 65357:
- ret = 65325;
- break;
- case 65358:
- ret = 65326;
- break;
- case 65359:
- ret = 65327;
- break;
- case 65360:
- ret = 65328;
- break;
- case 65361:
- ret = 65329;
- break;
- case 65362:
- ret = 65330;
- break;
- case 65363:
- ret = 65331;
- break;
- case 65364:
- ret = 65332;
- break;
- case 65365:
- ret = 65333;
- break;
- case 65366:
- ret = 65334;
- break;
- case 65367:
- ret = 65335;
- break;
- case 65368:
- ret = 65336;
- break;
- case 65369:
- ret = 65337;
- break;
- case 65370:
- ret = 65338;
- break;
- }
- return (char) ret;
- }
+// if (java_1_0)
+// {
+// int ret = (int) c;
+// switch (c)
+// {
+// case 97:
+// ret = 65;
+// break;
+// case 98:
+// ret = 66;
+// break;
+// case 99:
+// ret = 67;
+// break;
+// case 100:
+// ret = 68;
+// break;
+// case 101:
+// ret = 69;
+// break;
+// case 102:
+// ret = 70;
+// break;
+// case 103:
+// ret = 71;
+// break;
+// case 104:
+// ret = 72;
+// break;
+// case 105:
+// ret = 73;
+// break;
+// case 106:
+// ret = 74;
+// break;
+// case 107:
+// ret = 75;
+// break;
+// case 108:
+// ret = 76;
+// break;
+// case 109:
+// ret = 77;
+// break;
+// case 110:
+// ret = 78;
+// break;
+// case 111:
+// ret = 79;
+// break;
+// case 112:
+// ret = 80;
+// break;
+// case 113:
+// ret = 81;
+// break;
+// case 114:
+// ret = 82;
+// break;
+// case 115:
+// ret = 83;
+// break;
+// case 116:
+// ret = 84;
+// break;
+// case 117:
+// ret = 85;
+// break;
+// case 118:
+// ret = 86;
+// break;
+// case 119:
+// ret = 87;
+// break;
+// case 120:
+// ret = 88;
+// break;
+// case 121:
+// ret = 89;
+// break;
+// case 122:
+// ret = 90;
+// break;
+// case 224:
+// ret = 192;
+// break;
+// case 225:
+// ret = 193;
+// break;
+// case 226:
+// ret = 194;
+// break;
+// case 227:
+// ret = 195;
+// break;
+// case 228:
+// ret = 196;
+// break;
+// case 229:
+// ret = 197;
+// break;
+// case 230:
+// ret = 198;
+// break;
+// case 231:
+// ret = 199;
+// break;
+// case 232:
+// ret = 200;
+// break;
+// case 233:
+// ret = 201;
+// break;
+// case 234:
+// ret = 202;
+// break;
+// case 235:
+// ret = 203;
+// break;
+// case 236:
+// ret = 204;
+// break;
+// case 237:
+// ret = 205;
+// break;
+// case 238:
+// ret = 206;
+// break;
+// case 239:
+// ret = 207;
+// break;
+// case 240:
+// ret = 208;
+// break;
+// case 241:
+// ret = 209;
+// break;
+// case 242:
+// ret = 210;
+// break;
+// case 243:
+// ret = 211;
+// break;
+// case 244:
+// ret = 212;
+// break;
+// case 245:
+// ret = 213;
+// break;
+// case 246:
+// ret = 214;
+// break;
+// case 248:
+// ret = 216;
+// break;
+// case 249:
+// ret = 217;
+// break;
+// case 250:
+// ret = 218;
+// break;
+// case 251:
+// ret = 219;
+// break;
+// case 252:
+// ret = 220;
+// break;
+// case 253:
+// ret = 221;
+// break;
+// case 254:
+// ret = 222;
+// break;
+// case 255:
+// ret = 376;
+// break;
+// case 257:
+// ret = 256;
+// break;
+// case 259:
+// ret = 258;
+// break;
+// case 261:
+// ret = 260;
+// break;
+// case 263:
+// ret = 262;
+// break;
+// case 265:
+// ret = 264;
+// break;
+// case 267:
+// ret = 266;
+// break;
+// case 269:
+// ret = 268;
+// break;
+// case 271:
+// ret = 270;
+// break;
+// case 273:
+// ret = 272;
+// break;
+// case 275:
+// ret = 274;
+// break;
+// case 277:
+// ret = 276;
+// break;
+// case 279:
+// ret = 278;
+// break;
+// case 281:
+// ret = 280;
+// break;
+// case 283:
+// ret = 282;
+// break;
+// case 285:
+// ret = 284;
+// break;
+// case 287:
+// ret = 286;
+// break;
+// case 289:
+// ret = 288;
+// break;
+// case 291:
+// ret = 290;
+// break;
+// case 293:
+// ret = 292;
+// break;
+// case 295:
+// ret = 294;
+// break;
+// case 297:
+// ret = 296;
+// break;
+// case 299:
+// ret = 298;
+// break;
+// case 301:
+// ret = 300;
+// break;
+// case 303:
+// ret = 302;
+// break;
+// case 305:
+// ret = 73;
+// break;
+// case 307:
+// ret = 306;
+// break;
+// case 309:
+// ret = 308;
+// break;
+// case 311:
+// ret = 310;
+// break;
+// case 314:
+// ret = 313;
+// break;
+// case 316:
+// ret = 315;
+// break;
+// case 318:
+// ret = 317;
+// break;
+// case 320:
+// ret = 319;
+// break;
+// case 322:
+// ret = 321;
+// break;
+// case 324:
+// ret = 323;
+// break;
+// case 326:
+// ret = 325;
+// break;
+// case 328:
+// ret = 327;
+// break;
+// case 331:
+// ret = 330;
+// break;
+// case 333:
+// ret = 332;
+// break;
+// case 335:
+// ret = 334;
+// break;
+// case 337:
+// ret = 336;
+// break;
+// case 339:
+// ret = 338;
+// break;
+// case 341:
+// ret = 340;
+// break;
+// case 343:
+// ret = 342;
+// break;
+// case 345:
+// ret = 344;
+// break;
+// case 347:
+// ret = 346;
+// break;
+// case 349:
+// ret = 348;
+// break;
+// case 351:
+// ret = 350;
+// break;
+// case 353:
+// ret = 352;
+// break;
+// case 355:
+// ret = 354;
+// break;
+// case 357:
+// ret = 356;
+// break;
+// case 359:
+// ret = 358;
+// break;
+// case 361:
+// ret = 360;
+// break;
+// case 363:
+// ret = 362;
+// break;
+// case 365:
+// ret = 364;
+// break;
+// case 367:
+// ret = 366;
+// break;
+// case 369:
+// ret = 368;
+// break;
+// case 371:
+// ret = 370;
+// break;
+// case 373:
+// ret = 372;
+// break;
+// case 375:
+// ret = 374;
+// break;
+// case 378:
+// ret = 377;
+// break;
+// case 380:
+// ret = 379;
+// break;
+// case 382:
+// ret = 381;
+// break;
+// case 383:
+// ret = 83;
+// break;
+// case 387:
+// ret = 386;
+// break;
+// case 389:
+// ret = 388;
+// break;
+// case 392:
+// ret = 391;
+// break;
+// case 396:
+// ret = 395;
+// break;
+// case 402:
+// ret = 401;
+// break;
+// case 409:
+// ret = 408;
+// break;
+// case 417:
+// ret = 416;
+// break;
+// case 419:
+// ret = 418;
+// break;
+// case 421:
+// ret = 420;
+// break;
+// case 424:
+// ret = 423;
+// break;
+// case 429:
+// ret = 428;
+// break;
+// case 432:
+// ret = 431;
+// break;
+// case 436:
+// ret = 435;
+// break;
+// case 438:
+// ret = 437;
+// break;
+// case 441:
+// ret = 440;
+// break;
+// case 445:
+// ret = 444;
+// break;
+// case 453:
+// ret = 452;
+// break;
+// case 454:
+// ret = 452;
+// break;
+// case 456:
+// ret = 455;
+// break;
+// case 457:
+// ret = 455;
+// break;
+// case 459:
+// ret = 458;
+// break;
+// case 460:
+// ret = 458;
+// break;
+// case 462:
+// ret = 461;
+// break;
+// case 464:
+// ret = 463;
+// break;
+// case 466:
+// ret = 465;
+// break;
+// case 468:
+// ret = 467;
+// break;
+// case 470:
+// ret = 469;
+// break;
+// case 472:
+// ret = 471;
+// break;
+// case 474:
+// ret = 473;
+// break;
+// case 476:
+// ret = 475;
+// break;
+// case 479:
+// ret = 478;
+// break;
+// case 481:
+// ret = 480;
+// break;
+// case 483:
+// ret = 482;
+// break;
+// case 485:
+// ret = 484;
+// break;
+// case 487:
+// ret = 486;
+// break;
+// case 489:
+// ret = 488;
+// break;
+// case 491:
+// ret = 490;
+// break;
+// case 493:
+// ret = 492;
+// break;
+// case 495:
+// ret = 494;
+// break;
+// case 498:
+// ret = 497;
+// break;
+// case 499:
+// ret = 497;
+// break;
+// case 501:
+// ret = 500;
+// break;
+// case 507:
+// ret = 506;
+// break;
+// case 509:
+// ret = 508;
+// break;
+// case 511:
+// ret = 510;
+// break;
+// case 513:
+// ret = 512;
+// break;
+// case 515:
+// ret = 514;
+// break;
+// case 517:
+// ret = 516;
+// break;
+// case 519:
+// ret = 518;
+// break;
+// case 521:
+// ret = 520;
+// break;
+// case 523:
+// ret = 522;
+// break;
+// case 525:
+// ret = 524;
+// break;
+// case 527:
+// ret = 526;
+// break;
+// case 529:
+// ret = 528;
+// break;
+// case 531:
+// ret = 530;
+// break;
+// case 533:
+// ret = 532;
+// break;
+// case 535:
+// ret = 534;
+// break;
+// case 595:
+// ret = 385;
+// break;
+// case 596:
+// ret = 390;
+// break;
+// case 598:
+// ret = 393;
+// break;
+// case 599:
+// ret = 394;
+// break;
+// case 600:
+// ret = 398;
+// break;
+// case 601:
+// ret = 399;
+// break;
+// case 603:
+// ret = 400;
+// break;
+// case 608:
+// ret = 403;
+// break;
+// case 611:
+// ret = 404;
+// break;
+// case 616:
+// ret = 407;
+// break;
+// case 617:
+// ret = 406;
+// break;
+// case 623:
+// ret = 412;
+// break;
+// case 626:
+// ret = 413;
+// break;
+// case 643:
+// ret = 425;
+// break;
+// case 648:
+// ret = 430;
+// break;
+// case 650:
+// ret = 433;
+// break;
+// case 651:
+// ret = 434;
+// break;
+// case 658:
+// ret = 439;
+// break;
+// case 940:
+// ret = 902;
+// break;
+// case 941:
+// ret = 904;
+// break;
+// case 942:
+// ret = 905;
+// break;
+// case 943:
+// ret = 906;
+// break;
+// case 945:
+// ret = 913;
+// break;
+// case 946:
+// ret = 914;
+// break;
+// case 947:
+// ret = 915;
+// break;
+// case 948:
+// ret = 916;
+// break;
+// case 949:
+// ret = 917;
+// break;
+// case 950:
+// ret = 918;
+// break;
+// case 951:
+// ret = 919;
+// break;
+// case 952:
+// ret = 920;
+// break;
+// case 953:
+// ret = 921;
+// break;
+// case 954:
+// ret = 922;
+// break;
+// case 955:
+// ret = 923;
+// break;
+// case 956:
+// ret = 924;
+// break;
+// case 957:
+// ret = 925;
+// break;
+// case 958:
+// ret = 926;
+// break;
+// case 959:
+// ret = 927;
+// break;
+// case 960:
+// ret = 928;
+// break;
+// case 961:
+// ret = 929;
+// break;
+// case 963:
+// ret = 931;
+// break;
+// case 964:
+// ret = 932;
+// break;
+// case 965:
+// ret = 933;
+// break;
+// case 966:
+// ret = 934;
+// break;
+// case 967:
+// ret = 935;
+// break;
+// case 968:
+// ret = 936;
+// break;
+// case 969:
+// ret = 937;
+// break;
+// case 970:
+// ret = 938;
+// break;
+// case 971:
+// ret = 939;
+// break;
+// case 972:
+// ret = 908;
+// break;
+// case 973:
+// ret = 910;
+// break;
+// case 974:
+// ret = 911;
+// break;
+// case 976:
+// ret = 914;
+// break;
+// case 977:
+// ret = 920;
+// break;
+// case 981:
+// ret = 934;
+// break;
+// case 982:
+// ret = 928;
+// break;
+// case 995:
+// ret = 994;
+// break;
+// case 997:
+// ret = 996;
+// break;
+// case 999:
+// ret = 998;
+// break;
+// case 1001:
+// ret = 1000;
+// break;
+// case 1003:
+// ret = 1002;
+// break;
+// case 1005:
+// ret = 1004;
+// break;
+// case 1007:
+// ret = 1006;
+// break;
+// case 1008:
+// ret = 922;
+// break;
+// case 1009:
+// ret = 929;
+// break;
+// case 1072:
+// ret = 1040;
+// break;
+// case 1073:
+// ret = 1041;
+// break;
+// case 1074:
+// ret = 1042;
+// break;
+// case 1075:
+// ret = 1043;
+// break;
+// case 1076:
+// ret = 1044;
+// break;
+// case 1077:
+// ret = 1045;
+// break;
+// case 1078:
+// ret = 1046;
+// break;
+// case 1079:
+// ret = 1047;
+// break;
+// case 1080:
+// ret = 1048;
+// break;
+// case 1081:
+// ret = 1049;
+// break;
+// case 1082:
+// ret = 1050;
+// break;
+// case 1083:
+// ret = 1051;
+// break;
+// case 1084:
+// ret = 1052;
+// break;
+// case 1085:
+// ret = 1053;
+// break;
+// case 1086:
+// ret = 1054;
+// break;
+// case 1087:
+// ret = 1055;
+// break;
+// case 1088:
+// ret = 1056;
+// break;
+// case 1089:
+// ret = 1057;
+// break;
+// case 1090:
+// ret = 1058;
+// break;
+// case 1091:
+// ret = 1059;
+// break;
+// case 1092:
+// ret = 1060;
+// break;
+// case 1093:
+// ret = 1061;
+// break;
+// case 1094:
+// ret = 1062;
+// break;
+// case 1095:
+// ret = 1063;
+// break;
+// case 1096:
+// ret = 1064;
+// break;
+// case 1097:
+// ret = 1065;
+// break;
+// case 1098:
+// ret = 1066;
+// break;
+// case 1099:
+// ret = 1067;
+// break;
+// case 1100:
+// ret = 1068;
+// break;
+// case 1101:
+// ret = 1069;
+// break;
+// case 1102:
+// ret = 1070;
+// break;
+// case 1103:
+// ret = 1071;
+// break;
+// case 1105:
+// ret = 1025;
+// break;
+// case 1106:
+// ret = 1026;
+// break;
+// case 1107:
+// ret = 1027;
+// break;
+// case 1108:
+// ret = 1028;
+// break;
+// case 1109:
+// ret = 1029;
+// break;
+// case 1110:
+// ret = 1030;
+// break;
+// case 1111:
+// ret = 1031;
+// break;
+// case 1112:
+// ret = 1032;
+// break;
+// case 1113:
+// ret = 1033;
+// break;
+// case 1114:
+// ret = 1034;
+// break;
+// case 1115:
+// ret = 1035;
+// break;
+// case 1116:
+// ret = 1036;
+// break;
+// case 1118:
+// ret = 1038;
+// break;
+// case 1119:
+// ret = 1039;
+// break;
+// case 1121:
+// ret = 1120;
+// break;
+// case 1123:
+// ret = 1122;
+// break;
+// case 1125:
+// ret = 1124;
+// break;
+// case 1127:
+// ret = 1126;
+// break;
+// case 1129:
+// ret = 1128;
+// break;
+// case 1131:
+// ret = 1130;
+// break;
+// case 1133:
+// ret = 1132;
+// break;
+// case 1135:
+// ret = 1134;
+// break;
+// case 1137:
+// ret = 1136;
+// break;
+// case 1139:
+// ret = 1138;
+// break;
+// case 1141:
+// ret = 1140;
+// break;
+// case 1143:
+// ret = 1142;
+// break;
+// case 1145:
+// ret = 1144;
+// break;
+// case 1147:
+// ret = 1146;
+// break;
+// case 1149:
+// ret = 1148;
+// break;
+// case 1151:
+// ret = 1150;
+// break;
+// case 1153:
+// ret = 1152;
+// break;
+// case 1169:
+// ret = 1168;
+// break;
+// case 1171:
+// ret = 1170;
+// break;
+// case 1173:
+// ret = 1172;
+// break;
+// case 1175:
+// ret = 1174;
+// break;
+// case 1177:
+// ret = 1176;
+// break;
+// case 1179:
+// ret = 1178;
+// break;
+// case 1181:
+// ret = 1180;
+// break;
+// case 1183:
+// ret = 1182;
+// break;
+// case 1185:
+// ret = 1184;
+// break;
+// case 1187:
+// ret = 1186;
+// break;
+// case 1189:
+// ret = 1188;
+// break;
+// case 1191:
+// ret = 1190;
+// break;
+// case 1193:
+// ret = 1192;
+// break;
+// case 1195:
+// ret = 1194;
+// break;
+// case 1197:
+// ret = 1196;
+// break;
+// case 1199:
+// ret = 1198;
+// break;
+// case 1201:
+// ret = 1200;
+// break;
+// case 1203:
+// ret = 1202;
+// break;
+// case 1205:
+// ret = 1204;
+// break;
+// case 1207:
+// ret = 1206;
+// break;
+// case 1209:
+// ret = 1208;
+// break;
+// case 1211:
+// ret = 1210;
+// break;
+// case 1213:
+// ret = 1212;
+// break;
+// case 1215:
+// ret = 1214;
+// break;
+// case 1218:
+// ret = 1217;
+// break;
+// case 1220:
+// ret = 1219;
+// break;
+// case 1224:
+// ret = 1223;
+// break;
+// case 1228:
+// ret = 1227;
+// break;
+// case 1233:
+// ret = 1232;
+// break;
+// case 1235:
+// ret = 1234;
+// break;
+// case 1237:
+// ret = 1236;
+// break;
+// case 1239:
+// ret = 1238;
+// break;
+// case 1241:
+// ret = 1240;
+// break;
+// case 1243:
+// ret = 1242;
+// break;
+// case 1245:
+// ret = 1244;
+// break;
+// case 1247:
+// ret = 1246;
+// break;
+// case 1249:
+// ret = 1248;
+// break;
+// case 1251:
+// ret = 1250;
+// break;
+// case 1253:
+// ret = 1252;
+// break;
+// case 1255:
+// ret = 1254;
+// break;
+// case 1257:
+// ret = 1256;
+// break;
+// case 1259:
+// ret = 1258;
+// break;
+// case 1263:
+// ret = 1262;
+// break;
+// case 1265:
+// ret = 1264;
+// break;
+// case 1267:
+// ret = 1266;
+// break;
+// case 1269:
+// ret = 1268;
+// break;
+// case 1273:
+// ret = 1272;
+// break;
+// case 1377:
+// ret = 1329;
+// break;
+// case 1378:
+// ret = 1330;
+// break;
+// case 1379:
+// ret = 1331;
+// break;
+// case 1380:
+// ret = 1332;
+// break;
+// case 1381:
+// ret = 1333;
+// break;
+// case 1382:
+// ret = 1334;
+// break;
+// case 1383:
+// ret = 1335;
+// break;
+// case 1384:
+// ret = 1336;
+// break;
+// case 1385:
+// ret = 1337;
+// break;
+// case 1386:
+// ret = 1338;
+// break;
+// case 1387:
+// ret = 1339;
+// break;
+// case 1388:
+// ret = 1340;
+// break;
+// case 1389:
+// ret = 1341;
+// break;
+// case 1390:
+// ret = 1342;
+// break;
+// case 1391:
+// ret = 1343;
+// break;
+// case 1392:
+// ret = 1344;
+// break;
+// case 1393:
+// ret = 1345;
+// break;
+// case 1394:
+// ret = 1346;
+// break;
+// case 1395:
+// ret = 1347;
+// break;
+// case 1396:
+// ret = 1348;
+// break;
+// case 1397:
+// ret = 1349;
+// break;
+// case 1398:
+// ret = 1350;
+// break;
+// case 1399:
+// ret = 1351;
+// break;
+// case 1400:
+// ret = 1352;
+// break;
+// case 1401:
+// ret = 1353;
+// break;
+// case 1402:
+// ret = 1354;
+// break;
+// case 1403:
+// ret = 1355;
+// break;
+// case 1404:
+// ret = 1356;
+// break;
+// case 1405:
+// ret = 1357;
+// break;
+// case 1406:
+// ret = 1358;
+// break;
+// case 1407:
+// ret = 1359;
+// break;
+// case 1408:
+// ret = 1360;
+// break;
+// case 1409:
+// ret = 1361;
+// break;
+// case 1410:
+// ret = 1362;
+// break;
+// case 1411:
+// ret = 1363;
+// break;
+// case 1412:
+// ret = 1364;
+// break;
+// case 1413:
+// ret = 1365;
+// break;
+// case 1414:
+// ret = 1366;
+// break;
+// case 7681:
+// ret = 7680;
+// break;
+// case 7683:
+// ret = 7682;
+// break;
+// case 7685:
+// ret = 7684;
+// break;
+// case 7687:
+// ret = 7686;
+// break;
+// case 7689:
+// ret = 7688;
+// break;
+// case 7691:
+// ret = 7690;
+// break;
+// case 7693:
+// ret = 7692;
+// break;
+// case 7695:
+// ret = 7694;
+// break;
+// case 7697:
+// ret = 7696;
+// break;
+// case 7699:
+// ret = 7698;
+// break;
+// case 7701:
+// ret = 7700;
+// break;
+// case 7703:
+// ret = 7702;
+// break;
+// case 7705:
+// ret = 7704;
+// break;
+// case 7707:
+// ret = 7706;
+// break;
+// case 7709:
+// ret = 7708;
+// break;
+// case 7711:
+// ret = 7710;
+// break;
+// case 7713:
+// ret = 7712;
+// break;
+// case 7715:
+// ret = 7714;
+// break;
+// case 7717:
+// ret = 7716;
+// break;
+// case 7719:
+// ret = 7718;
+// break;
+// case 7721:
+// ret = 7720;
+// break;
+// case 7723:
+// ret = 7722;
+// break;
+// case 7725:
+// ret = 7724;
+// break;
+// case 7727:
+// ret = 7726;
+// break;
+// case 7729:
+// ret = 7728;
+// break;
+// case 7731:
+// ret = 7730;
+// break;
+// case 7733:
+// ret = 7732;
+// break;
+// case 7735:
+// ret = 7734;
+// break;
+// case 7737:
+// ret = 7736;
+// break;
+// case 7739:
+// ret = 7738;
+// break;
+// case 7741:
+// ret = 7740;
+// break;
+// case 7743:
+// ret = 7742;
+// break;
+// case 7745:
+// ret = 7744;
+// break;
+// case 7747:
+// ret = 7746;
+// break;
+// case 7749:
+// ret = 7748;
+// break;
+// case 7751:
+// ret = 7750;
+// break;
+// case 7753:
+// ret = 7752;
+// break;
+// case 7755:
+// ret = 7754;
+// break;
+// case 7757:
+// ret = 7756;
+// break;
+// case 7759:
+// ret = 7758;
+// break;
+// case 7761:
+// ret = 7760;
+// break;
+// case 7763:
+// ret = 7762;
+// break;
+// case 7765:
+// ret = 7764;
+// break;
+// case 7767:
+// ret = 7766;
+// break;
+// case 7769:
+// ret = 7768;
+// break;
+// case 7771:
+// ret = 7770;
+// break;
+// case 7773:
+// ret = 7772;
+// break;
+// case 7775:
+// ret = 7774;
+// break;
+// case 7777:
+// ret = 7776;
+// break;
+// case 7779:
+// ret = 7778;
+// break;
+// case 7781:
+// ret = 7780;
+// break;
+// case 7783:
+// ret = 7782;
+// break;
+// case 7785:
+// ret = 7784;
+// break;
+// case 7787:
+// ret = 7786;
+// break;
+// case 7789:
+// ret = 7788;
+// break;
+// case 7791:
+// ret = 7790;
+// break;
+// case 7793:
+// ret = 7792;
+// break;
+// case 7795:
+// ret = 7794;
+// break;
+// case 7797:
+// ret = 7796;
+// break;
+// case 7799:
+// ret = 7798;
+// break;
+// case 7801:
+// ret = 7800;
+// break;
+// case 7803:
+// ret = 7802;
+// break;
+// case 7805:
+// ret = 7804;
+// break;
+// case 7807:
+// ret = 7806;
+// break;
+// case 7809:
+// ret = 7808;
+// break;
+// case 7811:
+// ret = 7810;
+// break;
+// case 7813:
+// ret = 7812;
+// break;
+// case 7815:
+// ret = 7814;
+// break;
+// case 7817:
+// ret = 7816;
+// break;
+// case 7819:
+// ret = 7818;
+// break;
+// case 7821:
+// ret = 7820;
+// break;
+// case 7823:
+// ret = 7822;
+// break;
+// case 7825:
+// ret = 7824;
+// break;
+// case 7827:
+// ret = 7826;
+// break;
+// case 7829:
+// ret = 7828;
+// break;
+// case 7841:
+// ret = 7840;
+// break;
+// case 7843:
+// ret = 7842;
+// break;
+// case 7845:
+// ret = 7844;
+// break;
+// case 7847:
+// ret = 7846;
+// break;
+// case 7849:
+// ret = 7848;
+// break;
+// case 7851:
+// ret = 7850;
+// break;
+// case 7853:
+// ret = 7852;
+// break;
+// case 7855:
+// ret = 7854;
+// break;
+// case 7857:
+// ret = 7856;
+// break;
+// case 7859:
+// ret = 7858;
+// break;
+// case 7861:
+// ret = 7860;
+// break;
+// case 7863:
+// ret = 7862;
+// break;
+// case 7865:
+// ret = 7864;
+// break;
+// case 7867:
+// ret = 7866;
+// break;
+// case 7869:
+// ret = 7868;
+// break;
+// case 7871:
+// ret = 7870;
+// break;
+// case 7873:
+// ret = 7872;
+// break;
+// case 7875:
+// ret = 7874;
+// break;
+// case 7877:
+// ret = 7876;
+// break;
+// case 7879:
+// ret = 7878;
+// break;
+// case 7881:
+// ret = 7880;
+// break;
+// case 7883:
+// ret = 7882;
+// break;
+// case 7885:
+// ret = 7884;
+// break;
+// case 7887:
+// ret = 7886;
+// break;
+// case 7889:
+// ret = 7888;
+// break;
+// case 7891:
+// ret = 7890;
+// break;
+// case 7893:
+// ret = 7892;
+// break;
+// case 7895:
+// ret = 7894;
+// break;
+// case 7897:
+// ret = 7896;
+// break;
+// case 7899:
+// ret = 7898;
+// break;
+// case 7901:
+// ret = 7900;
+// break;
+// case 7903:
+// ret = 7902;
+// break;
+// case 7905:
+// ret = 7904;
+// break;
+// case 7907:
+// ret = 7906;
+// break;
+// case 7909:
+// ret = 7908;
+// break;
+// case 7911:
+// ret = 7910;
+// break;
+// case 7913:
+// ret = 7912;
+// break;
+// case 7915:
+// ret = 7914;
+// break;
+// case 7917:
+// ret = 7916;
+// break;
+// case 7919:
+// ret = 7918;
+// break;
+// case 7921:
+// ret = 7920;
+// break;
+// case 7923:
+// ret = 7922;
+// break;
+// case 7925:
+// ret = 7924;
+// break;
+// case 7927:
+// ret = 7926;
+// break;
+// case 7929:
+// ret = 7928;
+// break;
+// case 7936:
+// ret = 7944;
+// break;
+// case 7937:
+// ret = 7945;
+// break;
+// case 7938:
+// ret = 7946;
+// break;
+// case 7939:
+// ret = 7947;
+// break;
+// case 7940:
+// ret = 7948;
+// break;
+// case 7941:
+// ret = 7949;
+// break;
+// case 7942:
+// ret = 7950;
+// break;
+// case 7943:
+// ret = 7951;
+// break;
+// case 7952:
+// ret = 7960;
+// break;
+// case 7953:
+// ret = 7961;
+// break;
+// case 7954:
+// ret = 7962;
+// break;
+// case 7955:
+// ret = 7963;
+// break;
+// case 7956:
+// ret = 7964;
+// break;
+// case 7957:
+// ret = 7965;
+// break;
+// case 7968:
+// ret = 7976;
+// break;
+// case 7969:
+// ret = 7977;
+// break;
+// case 7970:
+// ret = 7978;
+// break;
+// case 7971:
+// ret = 7979;
+// break;
+// case 7972:
+// ret = 7980;
+// break;
+// case 7973:
+// ret = 7981;
+// break;
+// case 7974:
+// ret = 7982;
+// break;
+// case 7975:
+// ret = 7983;
+// break;
+// case 7984:
+// ret = 7992;
+// break;
+// case 7985:
+// ret = 7993;
+// break;
+// case 7986:
+// ret = 7994;
+// break;
+// case 7987:
+// ret = 7995;
+// break;
+// case 7988:
+// ret = 7996;
+// break;
+// case 7989:
+// ret = 7997;
+// break;
+// case 7990:
+// ret = 7998;
+// break;
+// case 7991:
+// ret = 7999;
+// break;
+// case 8000:
+// ret = 8008;
+// break;
+// case 8001:
+// ret = 8009;
+// break;
+// case 8002:
+// ret = 8010;
+// break;
+// case 8003:
+// ret = 8011;
+// break;
+// case 8004:
+// ret = 8012;
+// break;
+// case 8005:
+// ret = 8013;
+// break;
+// case 8017:
+// ret = 8025;
+// break;
+// case 8019:
+// ret = 8027;
+// break;
+// case 8021:
+// ret = 8029;
+// break;
+// case 8023:
+// ret = 8031;
+// break;
+// case 8032:
+// ret = 8040;
+// break;
+// case 8033:
+// ret = 8041;
+// break;
+// case 8034:
+// ret = 8042;
+// break;
+// case 8035:
+// ret = 8043;
+// break;
+// case 8036:
+// ret = 8044;
+// break;
+// case 8037:
+// ret = 8045;
+// break;
+// case 8038:
+// ret = 8046;
+// break;
+// case 8039:
+// ret = 8047;
+// break;
+// case 8048:
+// ret = 8122;
+// break;
+// case 8049:
+// ret = 8123;
+// break;
+// case 8050:
+// ret = 8136;
+// break;
+// case 8051:
+// ret = 8137;
+// break;
+// case 8052:
+// ret = 8138;
+// break;
+// case 8053:
+// ret = 8139;
+// break;
+// case 8054:
+// ret = 8154;
+// break;
+// case 8055:
+// ret = 8155;
+// break;
+// case 8056:
+// ret = 8184;
+// break;
+// case 8057:
+// ret = 8185;
+// break;
+// case 8058:
+// ret = 8170;
+// break;
+// case 8059:
+// ret = 8171;
+// break;
+// case 8060:
+// ret = 8186;
+// break;
+// case 8061:
+// ret = 8187;
+// break;
+// case 8064:
+// ret = 8072;
+// break;
+// case 8065:
+// ret = 8073;
+// break;
+// case 8066:
+// ret = 8074;
+// break;
+// case 8067:
+// ret = 8075;
+// break;
+// case 8068:
+// ret = 8076;
+// break;
+// case 8069:
+// ret = 8077;
+// break;
+// case 8070:
+// ret = 8078;
+// break;
+// case 8071:
+// ret = 8079;
+// break;
+// case 8080:
+// ret = 8088;
+// break;
+// case 8081:
+// ret = 8089;
+// break;
+// case 8082:
+// ret = 8090;
+// break;
+// case 8083:
+// ret = 8091;
+// break;
+// case 8084:
+// ret = 8092;
+// break;
+// case 8085:
+// ret = 8093;
+// break;
+// case 8086:
+// ret = 8094;
+// break;
+// case 8087:
+// ret = 8095;
+// break;
+// case 8096:
+// ret = 8104;
+// break;
+// case 8097:
+// ret = 8105;
+// break;
+// case 8098:
+// ret = 8106;
+// break;
+// case 8099:
+// ret = 8107;
+// break;
+// case 8100:
+// ret = 8108;
+// break;
+// case 8101:
+// ret = 8109;
+// break;
+// case 8102:
+// ret = 8110;
+// break;
+// case 8103:
+// ret = 8111;
+// break;
+// case 8112:
+// ret = 8120;
+// break;
+// case 8113:
+// ret = 8121;
+// break;
+// case 8115:
+// ret = 8124;
+// break;
+// case 8131:
+// ret = 8140;
+// break;
+// case 8144:
+// ret = 8152;
+// break;
+// case 8145:
+// ret = 8153;
+// break;
+// case 8160:
+// ret = 8168;
+// break;
+// case 8161:
+// ret = 8169;
+// break;
+// case 8165:
+// ret = 8172;
+// break;
+// case 8179:
+// ret = 8188;
+// break;
+// case 8560:
+// ret = 8544;
+// break;
+// case 8561:
+// ret = 8545;
+// break;
+// case 8562:
+// ret = 8546;
+// break;
+// case 8563:
+// ret = 8547;
+// break;
+// case 8564:
+// ret = 8548;
+// break;
+// case 8565:
+// ret = 8549;
+// break;
+// case 8566:
+// ret = 8550;
+// break;
+// case 8567:
+// ret = 8551;
+// break;
+// case 8568:
+// ret = 8552;
+// break;
+// case 8569:
+// ret = 8553;
+// break;
+// case 8570:
+// ret = 8554;
+// break;
+// case 8571:
+// ret = 8555;
+// break;
+// case 8572:
+// ret = 8556;
+// break;
+// case 8573:
+// ret = 8557;
+// break;
+// case 8574:
+// ret = 8558;
+// break;
+// case 8575:
+// ret = 8559;
+// break;
+// case 9424:
+// ret = 9398;
+// break;
+// case 9425:
+// ret = 9399;
+// break;
+// case 9426:
+// ret = 9400;
+// break;
+// case 9427:
+// ret = 9401;
+// break;
+// case 9428:
+// ret = 9402;
+// break;
+// case 9429:
+// ret = 9403;
+// break;
+// case 9430:
+// ret = 9404;
+// break;
+// case 9431:
+// ret = 9405;
+// break;
+// case 9432:
+// ret = 9406;
+// break;
+// case 9433:
+// ret = 9407;
+// break;
+// case 9434:
+// ret = 9408;
+// break;
+// case 9435:
+// ret = 9409;
+// break;
+// case 9436:
+// ret = 9410;
+// break;
+// case 9437:
+// ret = 9411;
+// break;
+// case 9438:
+// ret = 9412;
+// break;
+// case 9439:
+// ret = 9413;
+// break;
+// case 9440:
+// ret = 9414;
+// break;
+// case 9441:
+// ret = 9415;
+// break;
+// case 9442:
+// ret = 9416;
+// break;
+// case 9443:
+// ret = 9417;
+// break;
+// case 9444:
+// ret = 9418;
+// break;
+// case 9445:
+// ret = 9419;
+// break;
+// case 9446:
+// ret = 9420;
+// break;
+// case 9447:
+// ret = 9421;
+// break;
+// case 9448:
+// ret = 9422;
+// break;
+// case 9449:
+// ret = 9423;
+// break;
+// case 65345:
+// ret = 65313;
+// break;
+// case 65346:
+// ret = 65314;
+// break;
+// case 65347:
+// ret = 65315;
+// break;
+// case 65348:
+// ret = 65316;
+// break;
+// case 65349:
+// ret = 65317;
+// break;
+// case 65350:
+// ret = 65318;
+// break;
+// case 65351:
+// ret = 65319;
+// break;
+// case 65352:
+// ret = 65320;
+// break;
+// case 65353:
+// ret = 65321;
+// break;
+// case 65354:
+// ret = 65322;
+// break;
+// case 65355:
+// ret = 65323;
+// break;
+// case 65356:
+// ret = 65324;
+// break;
+// case 65357:
+// ret = 65325;
+// break;
+// case 65358:
+// ret = 65326;
+// break;
+// case 65359:
+// ret = 65327;
+// break;
+// case 65360:
+// ret = 65328;
+// break;
+// case 65361:
+// ret = 65329;
+// break;
+// case 65362:
+// ret = 65330;
+// break;
+// case 65363:
+// ret = 65331;
+// break;
+// case 65364:
+// ret = 65332;
+// break;
+// case 65365:
+// ret = 65333;
+// break;
+// case 65366:
+// ret = 65334;
+// break;
+// case 65367:
+// ret = 65335;
+// break;
+// case 65368:
+// ret = 65336;
+// break;
+// case 65369:
+// ret = 65337;
+// break;
+// case 65370:
+// ret = 65338;
+// break;
+// }
+// return (char) ret;
+// }
return Character.toUpperCase(c);
}
/** Convert a character to lower case. */
- public static char toLowerCase(char c)
+ public static char toLowerCaseC(char c)
{
- if (java_1_0)
- {
- int ret = (int) c;
- switch (c)
- {
- case 65:
- ret = 97;
- break;
- case 66:
- ret = 98;
- break;
- case 67:
- ret = 99;
- break;
- case 68:
- ret = 100;
- break;
- case 69:
- ret = 101;
- break;
- case 70:
- ret = 102;
- break;
- case 71:
- ret = 103;
- break;
- case 72:
- ret = 104;
- break;
- case 73:
- ret = 105;
- break;
- case 74:
- ret = 106;
- break;
- case 75:
- ret = 107;
- break;
- case 76:
- ret = 108;
- break;
- case 77:
- ret = 109;
- break;
- case 78:
- ret = 110;
- break;
- case 79:
- ret = 111;
- break;
- case 80:
- ret = 112;
- break;
- case 81:
- ret = 113;
- break;
- case 82:
- ret = 114;
- break;
- case 83:
- ret = 115;
- break;
- case 84:
- ret = 116;
- break;
- case 85:
- ret = 117;
- break;
- case 86:
- ret = 118;
- break;
- case 87:
- ret = 119;
- break;
- case 88:
- ret = 120;
- break;
- case 89:
- ret = 121;
- break;
- case 90:
- ret = 122;
- break;
- case 192:
- ret = 224;
- break;
- case 193:
- ret = 225;
- break;
- case 194:
- ret = 226;
- break;
- case 195:
- ret = 227;
- break;
- case 196:
- ret = 228;
- break;
- case 197:
- ret = 229;
- break;
- case 198:
- ret = 230;
- break;
- case 199:
- ret = 231;
- break;
- case 200:
- ret = 232;
- break;
- case 201:
- ret = 233;
- break;
- case 202:
- ret = 234;
- break;
- case 203:
- ret = 235;
- break;
- case 204:
- ret = 236;
- break;
- case 205:
- ret = 237;
- break;
- case 206:
- ret = 238;
- break;
- case 207:
- ret = 239;
- break;
- case 208:
- ret = 240;
- break;
- case 209:
- ret = 241;
- break;
- case 210:
- ret = 242;
- break;
- case 211:
- ret = 243;
- break;
- case 212:
- ret = 244;
- break;
- case 213:
- ret = 245;
- break;
- case 214:
- ret = 246;
- break;
- case 216:
- ret = 248;
- break;
- case 217:
- ret = 249;
- break;
- case 218:
- ret = 250;
- break;
- case 219:
- ret = 251;
- break;
- case 220:
- ret = 252;
- break;
- case 221:
- ret = 253;
- break;
- case 222:
- ret = 254;
- break;
- case 256:
- ret = 257;
- break;
- case 258:
- ret = 259;
- break;
- case 260:
- ret = 261;
- break;
- case 262:
- ret = 263;
- break;
- case 264:
- ret = 265;
- break;
- case 266:
- ret = 267;
- break;
- case 268:
- ret = 269;
- break;
- case 270:
- ret = 271;
- break;
- case 272:
- ret = 273;
- break;
- case 274:
- ret = 275;
- break;
- case 276:
- ret = 277;
- break;
- case 278:
- ret = 279;
- break;
- case 280:
- ret = 281;
- break;
- case 282:
- ret = 283;
- break;
- case 284:
- ret = 285;
- break;
- case 286:
- ret = 287;
- break;
- case 288:
- ret = 289;
- break;
- case 290:
- ret = 291;
- break;
- case 292:
- ret = 293;
- break;
- case 294:
- ret = 295;
- break;
- case 296:
- ret = 297;
- break;
- case 298:
- ret = 299;
- break;
- case 300:
- ret = 301;
- break;
- case 302:
- ret = 303;
- break;
- case 304:
- ret = 105;
- break;
- case 306:
- ret = 307;
- break;
- case 308:
- ret = 309;
- break;
- case 310:
- ret = 311;
- break;
- case 313:
- ret = 314;
- break;
- case 315:
- ret = 316;
- break;
- case 317:
- ret = 318;
- break;
- case 319:
- ret = 320;
- break;
- case 321:
- ret = 322;
- break;
- case 323:
- ret = 324;
- break;
- case 325:
- ret = 326;
- break;
- case 327:
- ret = 328;
- break;
- case 330:
- ret = 331;
- break;
- case 332:
- ret = 333;
- break;
- case 334:
- ret = 335;
- break;
- case 336:
- ret = 337;
- break;
- case 338:
- ret = 339;
- break;
- case 340:
- ret = 341;
- break;
- case 342:
- ret = 343;
- break;
- case 344:
- ret = 345;
- break;
- case 346:
- ret = 347;
- break;
- case 348:
- ret = 349;
- break;
- case 350:
- ret = 351;
- break;
- case 352:
- ret = 353;
- break;
- case 354:
- ret = 355;
- break;
- case 356:
- ret = 357;
- break;
- case 358:
- ret = 359;
- break;
- case 360:
- ret = 361;
- break;
- case 362:
- ret = 363;
- break;
- case 364:
- ret = 365;
- break;
- case 366:
- ret = 367;
- break;
- case 368:
- ret = 369;
- break;
- case 370:
- ret = 371;
- break;
- case 372:
- ret = 373;
- break;
- case 374:
- ret = 375;
- break;
- case 376:
- ret = 255;
- break;
- case 377:
- ret = 378;
- break;
- case 379:
- ret = 380;
- break;
- case 381:
- ret = 382;
- break;
- case 385:
- ret = 595;
- break;
- case 386:
- ret = 387;
- break;
- case 388:
- ret = 389;
- break;
- case 390:
- ret = 596;
- break;
- case 391:
- ret = 392;
- break;
- case 393:
- ret = 598;
- break;
- case 394:
- ret = 599;
- break;
- case 395:
- ret = 396;
- break;
- case 398:
- ret = 600;
- break;
- case 399:
- ret = 601;
- break;
- case 400:
- ret = 603;
- break;
- case 401:
- ret = 402;
- break;
- case 403:
- ret = 608;
- break;
- case 404:
- ret = 611;
- break;
- case 406:
- ret = 617;
- break;
- case 407:
- ret = 616;
- break;
- case 408:
- ret = 409;
- break;
- case 412:
- ret = 623;
- break;
- case 413:
- ret = 626;
- break;
- case 416:
- ret = 417;
- break;
- case 418:
- ret = 419;
- break;
- case 420:
- ret = 421;
- break;
- case 423:
- ret = 424;
- break;
- case 425:
- ret = 643;
- break;
- case 428:
- ret = 429;
- break;
- case 430:
- ret = 648;
- break;
- case 431:
- ret = 432;
- break;
- case 433:
- ret = 650;
- break;
- case 434:
- ret = 651;
- break;
- case 435:
- ret = 436;
- break;
- case 437:
- ret = 438;
- break;
- case 439:
- ret = 658;
- break;
- case 440:
- ret = 441;
- break;
- case 444:
- ret = 445;
- break;
- case 452:
- ret = 454;
- break;
- case 453:
- ret = 454;
- break;
- case 455:
- ret = 457;
- break;
- case 456:
- ret = 457;
- break;
- case 458:
- ret = 460;
- break;
- case 459:
- ret = 460;
- break;
- case 461:
- ret = 462;
- break;
- case 463:
- ret = 464;
- break;
- case 465:
- ret = 466;
- break;
- case 467:
- ret = 468;
- break;
- case 469:
- ret = 470;
- break;
- case 471:
- ret = 472;
- break;
- case 473:
- ret = 474;
- break;
- case 475:
- ret = 476;
- break;
- case 478:
- ret = 479;
- break;
- case 480:
- ret = 481;
- break;
- case 482:
- ret = 483;
- break;
- case 484:
- ret = 485;
- break;
- case 486:
- ret = 487;
- break;
- case 488:
- ret = 489;
- break;
- case 490:
- ret = 491;
- break;
- case 492:
- ret = 493;
- break;
- case 494:
- ret = 495;
- break;
- case 497:
- ret = 499;
- break;
- case 498:
- ret = 499;
- break;
- case 500:
- ret = 501;
- break;
- case 506:
- ret = 507;
- break;
- case 508:
- ret = 509;
- break;
- case 510:
- ret = 511;
- break;
- case 512:
- ret = 513;
- break;
- case 514:
- ret = 515;
- break;
- case 516:
- ret = 517;
- break;
- case 518:
- ret = 519;
- break;
- case 520:
- ret = 521;
- break;
- case 522:
- ret = 523;
- break;
- case 524:
- ret = 525;
- break;
- case 526:
- ret = 527;
- break;
- case 528:
- ret = 529;
- break;
- case 530:
- ret = 531;
- break;
- case 532:
- ret = 533;
- break;
- case 534:
- ret = 535;
- break;
- case 902:
- ret = 940;
- break;
- case 904:
- ret = 941;
- break;
- case 905:
- ret = 942;
- break;
- case 906:
- ret = 943;
- break;
- case 908:
- ret = 972;
- break;
- case 910:
- ret = 973;
- break;
- case 911:
- ret = 974;
- break;
- case 913:
- ret = 945;
- break;
- case 914:
- ret = 946;
- break;
- case 915:
- ret = 947;
- break;
- case 916:
- ret = 948;
- break;
- case 917:
- ret = 949;
- break;
- case 918:
- ret = 950;
- break;
- case 919:
- ret = 951;
- break;
- case 920:
- ret = 952;
- break;
- case 921:
- ret = 953;
- break;
- case 922:
- ret = 954;
- break;
- case 923:
- ret = 955;
- break;
- case 924:
- ret = 956;
- break;
- case 925:
- ret = 957;
- break;
- case 926:
- ret = 958;
- break;
- case 927:
- ret = 959;
- break;
- case 928:
- ret = 960;
- break;
- case 929:
- ret = 961;
- break;
- case 931:
- ret = 963;
- break;
- case 932:
- ret = 964;
- break;
- case 933:
- ret = 965;
- break;
- case 934:
- ret = 966;
- break;
- case 935:
- ret = 967;
- break;
- case 936:
- ret = 968;
- break;
- case 937:
- ret = 969;
- break;
- case 938:
- ret = 970;
- break;
- case 939:
- ret = 971;
- break;
- case 994:
- ret = 995;
- break;
- case 996:
- ret = 997;
- break;
- case 998:
- ret = 999;
- break;
- case 1000:
- ret = 1001;
- break;
- case 1002:
- ret = 1003;
- break;
- case 1004:
- ret = 1005;
- break;
- case 1006:
- ret = 1007;
- break;
- case 1025:
- ret = 1105;
- break;
- case 1026:
- ret = 1106;
- break;
- case 1027:
- ret = 1107;
- break;
- case 1028:
- ret = 1108;
- break;
- case 1029:
- ret = 1109;
- break;
- case 1030:
- ret = 1110;
- break;
- case 1031:
- ret = 1111;
- break;
- case 1032:
- ret = 1112;
- break;
- case 1033:
- ret = 1113;
- break;
- case 1034:
- ret = 1114;
- break;
- case 1035:
- ret = 1115;
- break;
- case 1036:
- ret = 1116;
- break;
- case 1038:
- ret = 1118;
- break;
- case 1039:
- ret = 1119;
- break;
- case 1040:
- ret = 1072;
- break;
- case 1041:
- ret = 1073;
- break;
- case 1042:
- ret = 1074;
- break;
- case 1043:
- ret = 1075;
- break;
- case 1044:
- ret = 1076;
- break;
- case 1045:
- ret = 1077;
- break;
- case 1046:
- ret = 1078;
- break;
- case 1047:
- ret = 1079;
- break;
- case 1048:
- ret = 1080;
- break;
- case 1049:
- ret = 1081;
- break;
- case 1050:
- ret = 1082;
- break;
- case 1051:
- ret = 1083;
- break;
- case 1052:
- ret = 1084;
- break;
- case 1053:
- ret = 1085;
- break;
- case 1054:
- ret = 1086;
- break;
- case 1055:
- ret = 1087;
- break;
- case 1056:
- ret = 1088;
- break;
- case 1057:
- ret = 1089;
- break;
- case 1058:
- ret = 1090;
- break;
- case 1059:
- ret = 1091;
- break;
- case 1060:
- ret = 1092;
- break;
- case 1061:
- ret = 1093;
- break;
- case 1062:
- ret = 1094;
- break;
- case 1063:
- ret = 1095;
- break;
- case 1064:
- ret = 1096;
- break;
- case 1065:
- ret = 1097;
- break;
- case 1066:
- ret = 1098;
- break;
- case 1067:
- ret = 1099;
- break;
- case 1068:
- ret = 1100;
- break;
- case 1069:
- ret = 1101;
- break;
- case 1070:
- ret = 1102;
- break;
- case 1071:
- ret = 1103;
- break;
- case 1120:
- ret = 1121;
- break;
- case 1122:
- ret = 1123;
- break;
- case 1124:
- ret = 1125;
- break;
- case 1126:
- ret = 1127;
- break;
- case 1128:
- ret = 1129;
- break;
- case 1130:
- ret = 1131;
- break;
- case 1132:
- ret = 1133;
- break;
- case 1134:
- ret = 1135;
- break;
- case 1136:
- ret = 1137;
- break;
- case 1138:
- ret = 1139;
- break;
- case 1140:
- ret = 1141;
- break;
- case 1142:
- ret = 1143;
- break;
- case 1144:
- ret = 1145;
- break;
- case 1146:
- ret = 1147;
- break;
- case 1148:
- ret = 1149;
- break;
- case 1150:
- ret = 1151;
- break;
- case 1152:
- ret = 1153;
- break;
- case 1168:
- ret = 1169;
- break;
- case 1170:
- ret = 1171;
- break;
- case 1172:
- ret = 1173;
- break;
- case 1174:
- ret = 1175;
- break;
- case 1176:
- ret = 1177;
- break;
- case 1178:
- ret = 1179;
- break;
- case 1180:
- ret = 1181;
- break;
- case 1182:
- ret = 1183;
- break;
- case 1184:
- ret = 1185;
- break;
- case 1186:
- ret = 1187;
- break;
- case 1188:
- ret = 1189;
- break;
- case 1190:
- ret = 1191;
- break;
- case 1192:
- ret = 1193;
- break;
- case 1194:
- ret = 1195;
- break;
- case 1196:
- ret = 1197;
- break;
- case 1198:
- ret = 1199;
- break;
- case 1200:
- ret = 1201;
- break;
- case 1202:
- ret = 1203;
- break;
- case 1204:
- ret = 1205;
- break;
- case 1206:
- ret = 1207;
- break;
- case 1208:
- ret = 1209;
- break;
- case 1210:
- ret = 1211;
- break;
- case 1212:
- ret = 1213;
- break;
- case 1214:
- ret = 1215;
- break;
- case 1217:
- ret = 1218;
- break;
- case 1219:
- ret = 1220;
- break;
- case 1223:
- ret = 1224;
- break;
- case 1227:
- ret = 1228;
- break;
- case 1232:
- ret = 1233;
- break;
- case 1234:
- ret = 1235;
- break;
- case 1236:
- ret = 1237;
- break;
- case 1238:
- ret = 1239;
- break;
- case 1240:
- ret = 1241;
- break;
- case 1242:
- ret = 1243;
- break;
- case 1244:
- ret = 1245;
- break;
- case 1246:
- ret = 1247;
- break;
- case 1248:
- ret = 1249;
- break;
- case 1250:
- ret = 1251;
- break;
- case 1252:
- ret = 1253;
- break;
- case 1254:
- ret = 1255;
- break;
- case 1256:
- ret = 1257;
- break;
- case 1258:
- ret = 1259;
- break;
- case 1262:
- ret = 1263;
- break;
- case 1264:
- ret = 1265;
- break;
- case 1266:
- ret = 1267;
- break;
- case 1268:
- ret = 1269;
- break;
- case 1272:
- ret = 1273;
- break;
- case 1329:
- ret = 1377;
- break;
- case 1330:
- ret = 1378;
- break;
- case 1331:
- ret = 1379;
- break;
- case 1332:
- ret = 1380;
- break;
- case 1333:
- ret = 1381;
- break;
- case 1334:
- ret = 1382;
- break;
- case 1335:
- ret = 1383;
- break;
- case 1336:
- ret = 1384;
- break;
- case 1337:
- ret = 1385;
- break;
- case 1338:
- ret = 1386;
- break;
- case 1339:
- ret = 1387;
- break;
- case 1340:
- ret = 1388;
- break;
- case 1341:
- ret = 1389;
- break;
- case 1342:
- ret = 1390;
- break;
- case 1343:
- ret = 1391;
- break;
- case 1344:
- ret = 1392;
- break;
- case 1345:
- ret = 1393;
- break;
- case 1346:
- ret = 1394;
- break;
- case 1347:
- ret = 1395;
- break;
- case 1348:
- ret = 1396;
- break;
- case 1349:
- ret = 1397;
- break;
- case 1350:
- ret = 1398;
- break;
- case 1351:
- ret = 1399;
- break;
- case 1352:
- ret = 1400;
- break;
- case 1353:
- ret = 1401;
- break;
- case 1354:
- ret = 1402;
- break;
- case 1355:
- ret = 1403;
- break;
- case 1356:
- ret = 1404;
- break;
- case 1357:
- ret = 1405;
- break;
- case 1358:
- ret = 1406;
- break;
- case 1359:
- ret = 1407;
- break;
- case 1360:
- ret = 1408;
- break;
- case 1361:
- ret = 1409;
- break;
- case 1362:
- ret = 1410;
- break;
- case 1363:
- ret = 1411;
- break;
- case 1364:
- ret = 1412;
- break;
- case 1365:
- ret = 1413;
- break;
- case 1366:
- ret = 1414;
- break;
- case 4256:
- ret = 4304;
- break;
- case 4257:
- ret = 4305;
- break;
- case 4258:
- ret = 4306;
- break;
- case 4259:
- ret = 4307;
- break;
- case 4260:
- ret = 4308;
- break;
- case 4261:
- ret = 4309;
- break;
- case 4262:
- ret = 4310;
- break;
- case 4263:
- ret = 4311;
- break;
- case 4264:
- ret = 4312;
- break;
- case 4265:
- ret = 4313;
- break;
- case 4266:
- ret = 4314;
- break;
- case 4267:
- ret = 4315;
- break;
- case 4268:
- ret = 4316;
- break;
- case 4269:
- ret = 4317;
- break;
- case 4270:
- ret = 4318;
- break;
- case 4271:
- ret = 4319;
- break;
- case 4272:
- ret = 4320;
- break;
- case 4273:
- ret = 4321;
- break;
- case 4274:
- ret = 4322;
- break;
- case 4275:
- ret = 4323;
- break;
- case 4276:
- ret = 4324;
- break;
- case 4277:
- ret = 4325;
- break;
- case 4278:
- ret = 4326;
- break;
- case 4279:
- ret = 4327;
- break;
- case 4280:
- ret = 4328;
- break;
- case 4281:
- ret = 4329;
- break;
- case 4282:
- ret = 4330;
- break;
- case 4283:
- ret = 4331;
- break;
- case 4284:
- ret = 4332;
- break;
- case 4285:
- ret = 4333;
- break;
- case 4286:
- ret = 4334;
- break;
- case 4287:
- ret = 4335;
- break;
- case 4288:
- ret = 4336;
- break;
- case 4289:
- ret = 4337;
- break;
- case 4290:
- ret = 4338;
- break;
- case 4291:
- ret = 4339;
- break;
- case 4292:
- ret = 4340;
- break;
- case 4293:
- ret = 4341;
- break;
- case 7680:
- ret = 7681;
- break;
- case 7682:
- ret = 7683;
- break;
- case 7684:
- ret = 7685;
- break;
- case 7686:
- ret = 7687;
- break;
- case 7688:
- ret = 7689;
- break;
- case 7690:
- ret = 7691;
- break;
- case 7692:
- ret = 7693;
- break;
- case 7694:
- ret = 7695;
- break;
- case 7696:
- ret = 7697;
- break;
- case 7698:
- ret = 7699;
- break;
- case 7700:
- ret = 7701;
- break;
- case 7702:
- ret = 7703;
- break;
- case 7704:
- ret = 7705;
- break;
- case 7706:
- ret = 7707;
- break;
- case 7708:
- ret = 7709;
- break;
- case 7710:
- ret = 7711;
- break;
- case 7712:
- ret = 7713;
- break;
- case 7714:
- ret = 7715;
- break;
- case 7716:
- ret = 7717;
- break;
- case 7718:
- ret = 7719;
- break;
- case 7720:
- ret = 7721;
- break;
- case 7722:
- ret = 7723;
- break;
- case 7724:
- ret = 7725;
- break;
- case 7726:
- ret = 7727;
- break;
- case 7728:
- ret = 7729;
- break;
- case 7730:
- ret = 7731;
- break;
- case 7732:
- ret = 7733;
- break;
- case 7734:
- ret = 7735;
- break;
- case 7736:
- ret = 7737;
- break;
- case 7738:
- ret = 7739;
- break;
- case 7740:
- ret = 7741;
- break;
- case 7742:
- ret = 7743;
- break;
- case 7744:
- ret = 7745;
- break;
- case 7746:
- ret = 7747;
- break;
- case 7748:
- ret = 7749;
- break;
- case 7750:
- ret = 7751;
- break;
- case 7752:
- ret = 7753;
- break;
- case 7754:
- ret = 7755;
- break;
- case 7756:
- ret = 7757;
- break;
- case 7758:
- ret = 7759;
- break;
- case 7760:
- ret = 7761;
- break;
- case 7762:
- ret = 7763;
- break;
- case 7764:
- ret = 7765;
- break;
- case 7766:
- ret = 7767;
- break;
- case 7768:
- ret = 7769;
- break;
- case 7770:
- ret = 7771;
- break;
- case 7772:
- ret = 7773;
- break;
- case 7774:
- ret = 7775;
- break;
- case 7776:
- ret = 7777;
- break;
- case 7778:
- ret = 7779;
- break;
- case 7780:
- ret = 7781;
- break;
- case 7782:
- ret = 7783;
- break;
- case 7784:
- ret = 7785;
- break;
- case 7786:
- ret = 7787;
- break;
- case 7788:
- ret = 7789;
- break;
- case 7790:
- ret = 7791;
- break;
- case 7792:
- ret = 7793;
- break;
- case 7794:
- ret = 7795;
- break;
- case 7796:
- ret = 7797;
- break;
- case 7798:
- ret = 7799;
- break;
- case 7800:
- ret = 7801;
- break;
- case 7802:
- ret = 7803;
- break;
- case 7804:
- ret = 7805;
- break;
- case 7806:
- ret = 7807;
- break;
- case 7808:
- ret = 7809;
- break;
- case 7810:
- ret = 7811;
- break;
- case 7812:
- ret = 7813;
- break;
- case 7814:
- ret = 7815;
- break;
- case 7816:
- ret = 7817;
- break;
- case 7818:
- ret = 7819;
- break;
- case 7820:
- ret = 7821;
- break;
- case 7822:
- ret = 7823;
- break;
- case 7824:
- ret = 7825;
- break;
- case 7826:
- ret = 7827;
- break;
- case 7828:
- ret = 7829;
- break;
- case 7840:
- ret = 7841;
- break;
- case 7842:
- ret = 7843;
- break;
- case 7844:
- ret = 7845;
- break;
- case 7846:
- ret = 7847;
- break;
- case 7848:
- ret = 7849;
- break;
- case 7850:
- ret = 7851;
- break;
- case 7852:
- ret = 7853;
- break;
- case 7854:
- ret = 7855;
- break;
- case 7856:
- ret = 7857;
- break;
- case 7858:
- ret = 7859;
- break;
- case 7860:
- ret = 7861;
- break;
- case 7862:
- ret = 7863;
- break;
- case 7864:
- ret = 7865;
- break;
- case 7866:
- ret = 7867;
- break;
- case 7868:
- ret = 7869;
- break;
- case 7870:
- ret = 7871;
- break;
- case 7872:
- ret = 7873;
- break;
- case 7874:
- ret = 7875;
- break;
- case 7876:
- ret = 7877;
- break;
- case 7878:
- ret = 7879;
- break;
- case 7880:
- ret = 7881;
- break;
- case 7882:
- ret = 7883;
- break;
- case 7884:
- ret = 7885;
- break;
- case 7886:
- ret = 7887;
- break;
- case 7888:
- ret = 7889;
- break;
- case 7890:
- ret = 7891;
- break;
- case 7892:
- ret = 7893;
- break;
- case 7894:
- ret = 7895;
- break;
- case 7896:
- ret = 7897;
- break;
- case 7898:
- ret = 7899;
- break;
- case 7900:
- ret = 7901;
- break;
- case 7902:
- ret = 7903;
- break;
- case 7904:
- ret = 7905;
- break;
- case 7906:
- ret = 7907;
- break;
- case 7908:
- ret = 7909;
- break;
- case 7910:
- ret = 7911;
- break;
- case 7912:
- ret = 7913;
- break;
- case 7914:
- ret = 7915;
- break;
- case 7916:
- ret = 7917;
- break;
- case 7918:
- ret = 7919;
- break;
- case 7920:
- ret = 7921;
- break;
- case 7922:
- ret = 7923;
- break;
- case 7924:
- ret = 7925;
- break;
- case 7926:
- ret = 7927;
- break;
- case 7928:
- ret = 7929;
- break;
- case 7944:
- ret = 7936;
- break;
- case 7945:
- ret = 7937;
- break;
- case 7946:
- ret = 7938;
- break;
- case 7947:
- ret = 7939;
- break;
- case 7948:
- ret = 7940;
- break;
- case 7949:
- ret = 7941;
- break;
- case 7950:
- ret = 7942;
- break;
- case 7951:
- ret = 7943;
- break;
- case 7960:
- ret = 7952;
- break;
- case 7961:
- ret = 7953;
- break;
- case 7962:
- ret = 7954;
- break;
- case 7963:
- ret = 7955;
- break;
- case 7964:
- ret = 7956;
- break;
- case 7965:
- ret = 7957;
- break;
- case 7976:
- ret = 7968;
- break;
- case 7977:
- ret = 7969;
- break;
- case 7978:
- ret = 7970;
- break;
- case 7979:
- ret = 7971;
- break;
- case 7980:
- ret = 7972;
- break;
- case 7981:
- ret = 7973;
- break;
- case 7982:
- ret = 7974;
- break;
- case 7983:
- ret = 7975;
- break;
- case 7992:
- ret = 7984;
- break;
- case 7993:
- ret = 7985;
- break;
- case 7994:
- ret = 7986;
- break;
- case 7995:
- ret = 7987;
- break;
- case 7996:
- ret = 7988;
- break;
- case 7997:
- ret = 7989;
- break;
- case 7998:
- ret = 7990;
- break;
- case 7999:
- ret = 7991;
- break;
- case 8008:
- ret = 8000;
- break;
- case 8009:
- ret = 8001;
- break;
- case 8010:
- ret = 8002;
- break;
- case 8011:
- ret = 8003;
- break;
- case 8012:
- ret = 8004;
- break;
- case 8013:
- ret = 8005;
- break;
- case 8025:
- ret = 8017;
- break;
- case 8027:
- ret = 8019;
- break;
- case 8029:
- ret = 8021;
- break;
- case 8031:
- ret = 8023;
- break;
- case 8040:
- ret = 8032;
- break;
- case 8041:
- ret = 8033;
- break;
- case 8042:
- ret = 8034;
- break;
- case 8043:
- ret = 8035;
- break;
- case 8044:
- ret = 8036;
- break;
- case 8045:
- ret = 8037;
- break;
- case 8046:
- ret = 8038;
- break;
- case 8047:
- ret = 8039;
- break;
- case 8072:
- ret = 8064;
- break;
- case 8073:
- ret = 8065;
- break;
- case 8074:
- ret = 8066;
- break;
- case 8075:
- ret = 8067;
- break;
- case 8076:
- ret = 8068;
- break;
- case 8077:
- ret = 8069;
- break;
- case 8078:
- ret = 8070;
- break;
- case 8079:
- ret = 8071;
- break;
- case 8088:
- ret = 8080;
- break;
- case 8089:
- ret = 8081;
- break;
- case 8090:
- ret = 8082;
- break;
- case 8091:
- ret = 8083;
- break;
- case 8092:
- ret = 8084;
- break;
- case 8093:
- ret = 8085;
- break;
- case 8094:
- ret = 8086;
- break;
- case 8095:
- ret = 8087;
- break;
- case 8104:
- ret = 8096;
- break;
- case 8105:
- ret = 8097;
- break;
- case 8106:
- ret = 8098;
- break;
- case 8107:
- ret = 8099;
- break;
- case 8108:
- ret = 8100;
- break;
- case 8109:
- ret = 8101;
- break;
- case 8110:
- ret = 8102;
- break;
- case 8111:
- ret = 8103;
- break;
- case 8120:
- ret = 8112;
- break;
- case 8121:
- ret = 8113;
- break;
- case 8122:
- ret = 8048;
- break;
- case 8123:
- ret = 8049;
- break;
- case 8124:
- ret = 8115;
- break;
- case 8136:
- ret = 8050;
- break;
- case 8137:
- ret = 8051;
- break;
- case 8138:
- ret = 8052;
- break;
- case 8139:
- ret = 8053;
- break;
- case 8140:
- ret = 8131;
- break;
- case 8152:
- ret = 8144;
- break;
- case 8153:
- ret = 8145;
- break;
- case 8154:
- ret = 8054;
- break;
- case 8155:
- ret = 8055;
- break;
- case 8168:
- ret = 8160;
- break;
- case 8169:
- ret = 8161;
- break;
- case 8170:
- ret = 8058;
- break;
- case 8171:
- ret = 8059;
- break;
- case 8172:
- ret = 8165;
- break;
- case 8184:
- ret = 8056;
- break;
- case 8185:
- ret = 8057;
- break;
- case 8186:
- ret = 8060;
- break;
- case 8187:
- ret = 8061;
- break;
- case 8188:
- ret = 8179;
- break;
- case 8544:
- ret = 8560;
- break;
- case 8545:
- ret = 8561;
- break;
- case 8546:
- ret = 8562;
- break;
- case 8547:
- ret = 8563;
- break;
- case 8548:
- ret = 8564;
- break;
- case 8549:
- ret = 8565;
- break;
- case 8550:
- ret = 8566;
- break;
- case 8551:
- ret = 8567;
- break;
- case 8552:
- ret = 8568;
- break;
- case 8553:
- ret = 8569;
- break;
- case 8554:
- ret = 8570;
- break;
- case 8555:
- ret = 8571;
- break;
- case 8556:
- ret = 8572;
- break;
- case 8557:
- ret = 8573;
- break;
- case 8558:
- ret = 8574;
- break;
- case 8559:
- ret = 8575;
- break;
- case 9398:
- ret = 9424;
- break;
- case 9399:
- ret = 9425;
- break;
- case 9400:
- ret = 9426;
- break;
- case 9401:
- ret = 9427;
- break;
- case 9402:
- ret = 9428;
- break;
- case 9403:
- ret = 9429;
- break;
- case 9404:
- ret = 9430;
- break;
- case 9405:
- ret = 9431;
- break;
- case 9406:
- ret = 9432;
- break;
- case 9407:
- ret = 9433;
- break;
- case 9408:
- ret = 9434;
- break;
- case 9409:
- ret = 9435;
- break;
- case 9410:
- ret = 9436;
- break;
- case 9411:
- ret = 9437;
- break;
- case 9412:
- ret = 9438;
- break;
- case 9413:
- ret = 9439;
- break;
- case 9414:
- ret = 9440;
- break;
- case 9415:
- ret = 9441;
- break;
- case 9416:
- ret = 9442;
- break;
- case 9417:
- ret = 9443;
- break;
- case 9418:
- ret = 9444;
- break;
- case 9419:
- ret = 9445;
- break;
- case 9420:
- ret = 9446;
- break;
- case 9421:
- ret = 9447;
- break;
- case 9422:
- ret = 9448;
- break;
- case 9423:
- ret = 9449;
- break;
- case 65313:
- ret = 65345;
- break;
- case 65314:
- ret = 65346;
- break;
- case 65315:
- ret = 65347;
- break;
- case 65316:
- ret = 65348;
- break;
- case 65317:
- ret = 65349;
- break;
- case 65318:
- ret = 65350;
- break;
- case 65319:
- ret = 65351;
- break;
- case 65320:
- ret = 65352;
- break;
- case 65321:
- ret = 65353;
- break;
- case 65322:
- ret = 65354;
- break;
- case 65323:
- ret = 65355;
- break;
- case 65324:
- ret = 65356;
- break;
- case 65325:
- ret = 65357;
- break;
- case 65326:
- ret = 65358;
- break;
- case 65327:
- ret = 65359;
- break;
- case 65328:
- ret = 65360;
- break;
- case 65329:
- ret = 65361;
- break;
- case 65330:
- ret = 65362;
- break;
- case 65331:
- ret = 65363;
- break;
- case 65332:
- ret = 65364;
- break;
- case 65333:
- ret = 65365;
- break;
- case 65334:
- ret = 65366;
- break;
- case 65335:
- ret = 65367;
- break;
- case 65336:
- ret = 65368;
- break;
- case 65337:
- ret = 65369;
- break;
- case 65338:
- ret = 65370;
- break;
- }
- return (char) ret;
- }
+// if (java_1_0)
+// {
+// int ret = (int) c;
+// switch (c)
+// {
+// case 65:
+// ret = 97;
+// break;
+// case 66:
+// ret = 98;
+// break;
+// case 67:
+// ret = 99;
+// break;
+// case 68:
+// ret = 100;
+// break;
+// case 69:
+// ret = 101;
+// break;
+// case 70:
+// ret = 102;
+// break;
+// case 71:
+// ret = 103;
+// break;
+// case 72:
+// ret = 104;
+// break;
+// case 73:
+// ret = 105;
+// break;
+// case 74:
+// ret = 106;
+// break;
+// case 75:
+// ret = 107;
+// break;
+// case 76:
+// ret = 108;
+// break;
+// case 77:
+// ret = 109;
+// break;
+// case 78:
+// ret = 110;
+// break;
+// case 79:
+// ret = 111;
+// break;
+// case 80:
+// ret = 112;
+// break;
+// case 81:
+// ret = 113;
+// break;
+// case 82:
+// ret = 114;
+// break;
+// case 83:
+// ret = 115;
+// break;
+// case 84:
+// ret = 116;
+// break;
+// case 85:
+// ret = 117;
+// break;
+// case 86:
+// ret = 118;
+// break;
+// case 87:
+// ret = 119;
+// break;
+// case 88:
+// ret = 120;
+// break;
+// case 89:
+// ret = 121;
+// break;
+// case 90:
+// ret = 122;
+// break;
+// case 192:
+// ret = 224;
+// break;
+// case 193:
+// ret = 225;
+// break;
+// case 194:
+// ret = 226;
+// break;
+// case 195:
+// ret = 227;
+// break;
+// case 196:
+// ret = 228;
+// break;
+// case 197:
+// ret = 229;
+// break;
+// case 198:
+// ret = 230;
+// break;
+// case 199:
+// ret = 231;
+// break;
+// case 200:
+// ret = 232;
+// break;
+// case 201:
+// ret = 233;
+// break;
+// case 202:
+// ret = 234;
+// break;
+// case 203:
+// ret = 235;
+// break;
+// case 204:
+// ret = 236;
+// break;
+// case 205:
+// ret = 237;
+// break;
+// case 206:
+// ret = 238;
+// break;
+// case 207:
+// ret = 239;
+// break;
+// case 208:
+// ret = 240;
+// break;
+// case 209:
+// ret = 241;
+// break;
+// case 210:
+// ret = 242;
+// break;
+// case 211:
+// ret = 243;
+// break;
+// case 212:
+// ret = 244;
+// break;
+// case 213:
+// ret = 245;
+// break;
+// case 214:
+// ret = 246;
+// break;
+// case 216:
+// ret = 248;
+// break;
+// case 217:
+// ret = 249;
+// break;
+// case 218:
+// ret = 250;
+// break;
+// case 219:
+// ret = 251;
+// break;
+// case 220:
+// ret = 252;
+// break;
+// case 221:
+// ret = 253;
+// break;
+// case 222:
+// ret = 254;
+// break;
+// case 256:
+// ret = 257;
+// break;
+// case 258:
+// ret = 259;
+// break;
+// case 260:
+// ret = 261;
+// break;
+// case 262:
+// ret = 263;
+// break;
+// case 264:
+// ret = 265;
+// break;
+// case 266:
+// ret = 267;
+// break;
+// case 268:
+// ret = 269;
+// break;
+// case 270:
+// ret = 271;
+// break;
+// case 272:
+// ret = 273;
+// break;
+// case 274:
+// ret = 275;
+// break;
+// case 276:
+// ret = 277;
+// break;
+// case 278:
+// ret = 279;
+// break;
+// case 280:
+// ret = 281;
+// break;
+// case 282:
+// ret = 283;
+// break;
+// case 284:
+// ret = 285;
+// break;
+// case 286:
+// ret = 287;
+// break;
+// case 288:
+// ret = 289;
+// break;
+// case 290:
+// ret = 291;
+// break;
+// case 292:
+// ret = 293;
+// break;
+// case 294:
+// ret = 295;
+// break;
+// case 296:
+// ret = 297;
+// break;
+// case 298:
+// ret = 299;
+// break;
+// case 300:
+// ret = 301;
+// break;
+// case 302:
+// ret = 303;
+// break;
+// case 304:
+// ret = 105;
+// break;
+// case 306:
+// ret = 307;
+// break;
+// case 308:
+// ret = 309;
+// break;
+// case 310:
+// ret = 311;
+// break;
+// case 313:
+// ret = 314;
+// break;
+// case 315:
+// ret = 316;
+// break;
+// case 317:
+// ret = 318;
+// break;
+// case 319:
+// ret = 320;
+// break;
+// case 321:
+// ret = 322;
+// break;
+// case 323:
+// ret = 324;
+// break;
+// case 325:
+// ret = 326;
+// break;
+// case 327:
+// ret = 328;
+// break;
+// case 330:
+// ret = 331;
+// break;
+// case 332:
+// ret = 333;
+// break;
+// case 334:
+// ret = 335;
+// break;
+// case 336:
+// ret = 337;
+// break;
+// case 338:
+// ret = 339;
+// break;
+// case 340:
+// ret = 341;
+// break;
+// case 342:
+// ret = 343;
+// break;
+// case 344:
+// ret = 345;
+// break;
+// case 346:
+// ret = 347;
+// break;
+// case 348:
+// ret = 349;
+// break;
+// case 350:
+// ret = 351;
+// break;
+// case 352:
+// ret = 353;
+// break;
+// case 354:
+// ret = 355;
+// break;
+// case 356:
+// ret = 357;
+// break;
+// case 358:
+// ret = 359;
+// break;
+// case 360:
+// ret = 361;
+// break;
+// case 362:
+// ret = 363;
+// break;
+// case 364:
+// ret = 365;
+// break;
+// case 366:
+// ret = 367;
+// break;
+// case 368:
+// ret = 369;
+// break;
+// case 370:
+// ret = 371;
+// break;
+// case 372:
+// ret = 373;
+// break;
+// case 374:
+// ret = 375;
+// break;
+// case 376:
+// ret = 255;
+// break;
+// case 377:
+// ret = 378;
+// break;
+// case 379:
+// ret = 380;
+// break;
+// case 381:
+// ret = 382;
+// break;
+// case 385:
+// ret = 595;
+// break;
+// case 386:
+// ret = 387;
+// break;
+// case 388:
+// ret = 389;
+// break;
+// case 390:
+// ret = 596;
+// break;
+// case 391:
+// ret = 392;
+// break;
+// case 393:
+// ret = 598;
+// break;
+// case 394:
+// ret = 599;
+// break;
+// case 395:
+// ret = 396;
+// break;
+// case 398:
+// ret = 600;
+// break;
+// case 399:
+// ret = 601;
+// break;
+// case 400:
+// ret = 603;
+// break;
+// case 401:
+// ret = 402;
+// break;
+// case 403:
+// ret = 608;
+// break;
+// case 404:
+// ret = 611;
+// break;
+// case 406:
+// ret = 617;
+// break;
+// case 407:
+// ret = 616;
+// break;
+// case 408:
+// ret = 409;
+// break;
+// case 412:
+// ret = 623;
+// break;
+// case 413:
+// ret = 626;
+// break;
+// case 416:
+// ret = 417;
+// break;
+// case 418:
+// ret = 419;
+// break;
+// case 420:
+// ret = 421;
+// break;
+// case 423:
+// ret = 424;
+// break;
+// case 425:
+// ret = 643;
+// break;
+// case 428:
+// ret = 429;
+// break;
+// case 430:
+// ret = 648;
+// break;
+// case 431:
+// ret = 432;
+// break;
+// case 433:
+// ret = 650;
+// break;
+// case 434:
+// ret = 651;
+// break;
+// case 435:
+// ret = 436;
+// break;
+// case 437:
+// ret = 438;
+// break;
+// case 439:
+// ret = 658;
+// break;
+// case 440:
+// ret = 441;
+// break;
+// case 444:
+// ret = 445;
+// break;
+// case 452:
+// ret = 454;
+// break;
+// case 453:
+// ret = 454;
+// break;
+// case 455:
+// ret = 457;
+// break;
+// case 456:
+// ret = 457;
+// break;
+// case 458:
+// ret = 460;
+// break;
+// case 459:
+// ret = 460;
+// break;
+// case 461:
+// ret = 462;
+// break;
+// case 463:
+// ret = 464;
+// break;
+// case 465:
+// ret = 466;
+// break;
+// case 467:
+// ret = 468;
+// break;
+// case 469:
+// ret = 470;
+// break;
+// case 471:
+// ret = 472;
+// break;
+// case 473:
+// ret = 474;
+// break;
+// case 475:
+// ret = 476;
+// break;
+// case 478:
+// ret = 479;
+// break;
+// case 480:
+// ret = 481;
+// break;
+// case 482:
+// ret = 483;
+// break;
+// case 484:
+// ret = 485;
+// break;
+// case 486:
+// ret = 487;
+// break;
+// case 488:
+// ret = 489;
+// break;
+// case 490:
+// ret = 491;
+// break;
+// case 492:
+// ret = 493;
+// break;
+// case 494:
+// ret = 495;
+// break;
+// case 497:
+// ret = 499;
+// break;
+// case 498:
+// ret = 499;
+// break;
+// case 500:
+// ret = 501;
+// break;
+// case 506:
+// ret = 507;
+// break;
+// case 508:
+// ret = 509;
+// break;
+// case 510:
+// ret = 511;
+// break;
+// case 512:
+// ret = 513;
+// break;
+// case 514:
+// ret = 515;
+// break;
+// case 516:
+// ret = 517;
+// break;
+// case 518:
+// ret = 519;
+// break;
+// case 520:
+// ret = 521;
+// break;
+// case 522:
+// ret = 523;
+// break;
+// case 524:
+// ret = 525;
+// break;
+// case 526:
+// ret = 527;
+// break;
+// case 528:
+// ret = 529;
+// break;
+// case 530:
+// ret = 531;
+// break;
+// case 532:
+// ret = 533;
+// break;
+// case 534:
+// ret = 535;
+// break;
+// case 902:
+// ret = 940;
+// break;
+// case 904:
+// ret = 941;
+// break;
+// case 905:
+// ret = 942;
+// break;
+// case 906:
+// ret = 943;
+// break;
+// case 908:
+// ret = 972;
+// break;
+// case 910:
+// ret = 973;
+// break;
+// case 911:
+// ret = 974;
+// break;
+// case 913:
+// ret = 945;
+// break;
+// case 914:
+// ret = 946;
+// break;
+// case 915:
+// ret = 947;
+// break;
+// case 916:
+// ret = 948;
+// break;
+// case 917:
+// ret = 949;
+// break;
+// case 918:
+// ret = 950;
+// break;
+// case 919:
+// ret = 951;
+// break;
+// case 920:
+// ret = 952;
+// break;
+// case 921:
+// ret = 953;
+// break;
+// case 922:
+// ret = 954;
+// break;
+// case 923:
+// ret = 955;
+// break;
+// case 924:
+// ret = 956;
+// break;
+// case 925:
+// ret = 957;
+// break;
+// case 926:
+// ret = 958;
+// break;
+// case 927:
+// ret = 959;
+// break;
+// case 928:
+// ret = 960;
+// break;
+// case 929:
+// ret = 961;
+// break;
+// case 931:
+// ret = 963;
+// break;
+// case 932:
+// ret = 964;
+// break;
+// case 933:
+// ret = 965;
+// break;
+// case 934:
+// ret = 966;
+// break;
+// case 935:
+// ret = 967;
+// break;
+// case 936:
+// ret = 968;
+// break;
+// case 937:
+// ret = 969;
+// break;
+// case 938:
+// ret = 970;
+// break;
+// case 939:
+// ret = 971;
+// break;
+// case 994:
+// ret = 995;
+// break;
+// case 996:
+// ret = 997;
+// break;
+// case 998:
+// ret = 999;
+// break;
+// case 1000:
+// ret = 1001;
+// break;
+// case 1002:
+// ret = 1003;
+// break;
+// case 1004:
+// ret = 1005;
+// break;
+// case 1006:
+// ret = 1007;
+// break;
+// case 1025:
+// ret = 1105;
+// break;
+// case 1026:
+// ret = 1106;
+// break;
+// case 1027:
+// ret = 1107;
+// break;
+// case 1028:
+// ret = 1108;
+// break;
+// case 1029:
+// ret = 1109;
+// break;
+// case 1030:
+// ret = 1110;
+// break;
+// case 1031:
+// ret = 1111;
+// break;
+// case 1032:
+// ret = 1112;
+// break;
+// case 1033:
+// ret = 1113;
+// break;
+// case 1034:
+// ret = 1114;
+// break;
+// case 1035:
+// ret = 1115;
+// break;
+// case 1036:
+// ret = 1116;
+// break;
+// case 1038:
+// ret = 1118;
+// break;
+// case 1039:
+// ret = 1119;
+// break;
+// case 1040:
+// ret = 1072;
+// break;
+// case 1041:
+// ret = 1073;
+// break;
+// case 1042:
+// ret = 1074;
+// break;
+// case 1043:
+// ret = 1075;
+// break;
+// case 1044:
+// ret = 1076;
+// break;
+// case 1045:
+// ret = 1077;
+// break;
+// case 1046:
+// ret = 1078;
+// break;
+// case 1047:
+// ret = 1079;
+// break;
+// case 1048:
+// ret = 1080;
+// break;
+// case 1049:
+// ret = 1081;
+// break;
+// case 1050:
+// ret = 1082;
+// break;
+// case 1051:
+// ret = 1083;
+// break;
+// case 1052:
+// ret = 1084;
+// break;
+// case 1053:
+// ret = 1085;
+// break;
+// case 1054:
+// ret = 1086;
+// break;
+// case 1055:
+// ret = 1087;
+// break;
+// case 1056:
+// ret = 1088;
+// break;
+// case 1057:
+// ret = 1089;
+// break;
+// case 1058:
+// ret = 1090;
+// break;
+// case 1059:
+// ret = 1091;
+// break;
+// case 1060:
+// ret = 1092;
+// break;
+// case 1061:
+// ret = 1093;
+// break;
+// case 1062:
+// ret = 1094;
+// break;
+// case 1063:
+// ret = 1095;
+// break;
+// case 1064:
+// ret = 1096;
+// break;
+// case 1065:
+// ret = 1097;
+// break;
+// case 1066:
+// ret = 1098;
+// break;
+// case 1067:
+// ret = 1099;
+// break;
+// case 1068:
+// ret = 1100;
+// break;
+// case 1069:
+// ret = 1101;
+// break;
+// case 1070:
+// ret = 1102;
+// break;
+// case 1071:
+// ret = 1103;
+// break;
+// case 1120:
+// ret = 1121;
+// break;
+// case 1122:
+// ret = 1123;
+// break;
+// case 1124:
+// ret = 1125;
+// break;
+// case 1126:
+// ret = 1127;
+// break;
+// case 1128:
+// ret = 1129;
+// break;
+// case 1130:
+// ret = 1131;
+// break;
+// case 1132:
+// ret = 1133;
+// break;
+// case 1134:
+// ret = 1135;
+// break;
+// case 1136:
+// ret = 1137;
+// break;
+// case 1138:
+// ret = 1139;
+// break;
+// case 1140:
+// ret = 1141;
+// break;
+// case 1142:
+// ret = 1143;
+// break;
+// case 1144:
+// ret = 1145;
+// break;
+// case 1146:
+// ret = 1147;
+// break;
+// case 1148:
+// ret = 1149;
+// break;
+// case 1150:
+// ret = 1151;
+// break;
+// case 1152:
+// ret = 1153;
+// break;
+// case 1168:
+// ret = 1169;
+// break;
+// case 1170:
+// ret = 1171;
+// break;
+// case 1172:
+// ret = 1173;
+// break;
+// case 1174:
+// ret = 1175;
+// break;
+// case 1176:
+// ret = 1177;
+// break;
+// case 1178:
+// ret = 1179;
+// break;
+// case 1180:
+// ret = 1181;
+// break;
+// case 1182:
+// ret = 1183;
+// break;
+// case 1184:
+// ret = 1185;
+// break;
+// case 1186:
+// ret = 1187;
+// break;
+// case 1188:
+// ret = 1189;
+// break;
+// case 1190:
+// ret = 1191;
+// break;
+// case 1192:
+// ret = 1193;
+// break;
+// case 1194:
+// ret = 1195;
+// break;
+// case 1196:
+// ret = 1197;
+// break;
+// case 1198:
+// ret = 1199;
+// break;
+// case 1200:
+// ret = 1201;
+// break;
+// case 1202:
+// ret = 1203;
+// break;
+// case 1204:
+// ret = 1205;
+// break;
+// case 1206:
+// ret = 1207;
+// break;
+// case 1208:
+// ret = 1209;
+// break;
+// case 1210:
+// ret = 1211;
+// break;
+// case 1212:
+// ret = 1213;
+// break;
+// case 1214:
+// ret = 1215;
+// break;
+// case 1217:
+// ret = 1218;
+// break;
+// case 1219:
+// ret = 1220;
+// break;
+// case 1223:
+// ret = 1224;
+// break;
+// case 1227:
+// ret = 1228;
+// break;
+// case 1232:
+// ret = 1233;
+// break;
+// case 1234:
+// ret = 1235;
+// break;
+// case 1236:
+// ret = 1237;
+// break;
+// case 1238:
+// ret = 1239;
+// break;
+// case 1240:
+// ret = 1241;
+// break;
+// case 1242:
+// ret = 1243;
+// break;
+// case 1244:
+// ret = 1245;
+// break;
+// case 1246:
+// ret = 1247;
+// break;
+// case 1248:
+// ret = 1249;
+// break;
+// case 1250:
+// ret = 1251;
+// break;
+// case 1252:
+// ret = 1253;
+// break;
+// case 1254:
+// ret = 1255;
+// break;
+// case 1256:
+// ret = 1257;
+// break;
+// case 1258:
+// ret = 1259;
+// break;
+// case 1262:
+// ret = 1263;
+// break;
+// case 1264:
+// ret = 1265;
+// break;
+// case 1266:
+// ret = 1267;
+// break;
+// case 1268:
+// ret = 1269;
+// break;
+// case 1272:
+// ret = 1273;
+// break;
+// case 1329:
+// ret = 1377;
+// break;
+// case 1330:
+// ret = 1378;
+// break;
+// case 1331:
+// ret = 1379;
+// break;
+// case 1332:
+// ret = 1380;
+// break;
+// case 1333:
+// ret = 1381;
+// break;
+// case 1334:
+// ret = 1382;
+// break;
+// case 1335:
+// ret = 1383;
+// break;
+// case 1336:
+// ret = 1384;
+// break;
+// case 1337:
+// ret = 1385;
+// break;
+// case 1338:
+// ret = 1386;
+// break;
+// case 1339:
+// ret = 1387;
+// break;
+// case 1340:
+// ret = 1388;
+// break;
+// case 1341:
+// ret = 1389;
+// break;
+// case 1342:
+// ret = 1390;
+// break;
+// case 1343:
+// ret = 1391;
+// break;
+// case 1344:
+// ret = 1392;
+// break;
+// case 1345:
+// ret = 1393;
+// break;
+// case 1346:
+// ret = 1394;
+// break;
+// case 1347:
+// ret = 1395;
+// break;
+// case 1348:
+// ret = 1396;
+// break;
+// case 1349:
+// ret = 1397;
+// break;
+// case 1350:
+// ret = 1398;
+// break;
+// case 1351:
+// ret = 1399;
+// break;
+// case 1352:
+// ret = 1400;
+// break;
+// case 1353:
+// ret = 1401;
+// break;
+// case 1354:
+// ret = 1402;
+// break;
+// case 1355:
+// ret = 1403;
+// break;
+// case 1356:
+// ret = 1404;
+// break;
+// case 1357:
+// ret = 1405;
+// break;
+// case 1358:
+// ret = 1406;
+// break;
+// case 1359:
+// ret = 1407;
+// break;
+// case 1360:
+// ret = 1408;
+// break;
+// case 1361:
+// ret = 1409;
+// break;
+// case 1362:
+// ret = 1410;
+// break;
+// case 1363:
+// ret = 1411;
+// break;
+// case 1364:
+// ret = 1412;
+// break;
+// case 1365:
+// ret = 1413;
+// break;
+// case 1366:
+// ret = 1414;
+// break;
+// case 4256:
+// ret = 4304;
+// break;
+// case 4257:
+// ret = 4305;
+// break;
+// case 4258:
+// ret = 4306;
+// break;
+// case 4259:
+// ret = 4307;
+// break;
+// case 4260:
+// ret = 4308;
+// break;
+// case 4261:
+// ret = 4309;
+// break;
+// case 4262:
+// ret = 4310;
+// break;
+// case 4263:
+// ret = 4311;
+// break;
+// case 4264:
+// ret = 4312;
+// break;
+// case 4265:
+// ret = 4313;
+// break;
+// case 4266:
+// ret = 4314;
+// break;
+// case 4267:
+// ret = 4315;
+// break;
+// case 4268:
+// ret = 4316;
+// break;
+// case 4269:
+// ret = 4317;
+// break;
+// case 4270:
+// ret = 4318;
+// break;
+// case 4271:
+// ret = 4319;
+// break;
+// case 4272:
+// ret = 4320;
+// break;
+// case 4273:
+// ret = 4321;
+// break;
+// case 4274:
+// ret = 4322;
+// break;
+// case 4275:
+// ret = 4323;
+// break;
+// case 4276:
+// ret = 4324;
+// break;
+// case 4277:
+// ret = 4325;
+// break;
+// case 4278:
+// ret = 4326;
+// break;
+// case 4279:
+// ret = 4327;
+// break;
+// case 4280:
+// ret = 4328;
+// break;
+// case 4281:
+// ret = 4329;
+// break;
+// case 4282:
+// ret = 4330;
+// break;
+// case 4283:
+// ret = 4331;
+// break;
+// case 4284:
+// ret = 4332;
+// break;
+// case 4285:
+// ret = 4333;
+// break;
+// case 4286:
+// ret = 4334;
+// break;
+// case 4287:
+// ret = 4335;
+// break;
+// case 4288:
+// ret = 4336;
+// break;
+// case 4289:
+// ret = 4337;
+// break;
+// case 4290:
+// ret = 4338;
+// break;
+// case 4291:
+// ret = 4339;
+// break;
+// case 4292:
+// ret = 4340;
+// break;
+// case 4293:
+// ret = 4341;
+// break;
+// case 7680:
+// ret = 7681;
+// break;
+// case 7682:
+// ret = 7683;
+// break;
+// case 7684:
+// ret = 7685;
+// break;
+// case 7686:
+// ret = 7687;
+// break;
+// case 7688:
+// ret = 7689;
+// break;
+// case 7690:
+// ret = 7691;
+// break;
+// case 7692:
+// ret = 7693;
+// break;
+// case 7694:
+// ret = 7695;
+// break;
+// case 7696:
+// ret = 7697;
+// break;
+// case 7698:
+// ret = 7699;
+// break;
+// case 7700:
+// ret = 7701;
+// break;
+// case 7702:
+// ret = 7703;
+// break;
+// case 7704:
+// ret = 7705;
+// break;
+// case 7706:
+// ret = 7707;
+// break;
+// case 7708:
+// ret = 7709;
+// break;
+// case 7710:
+// ret = 7711;
+// break;
+// case 7712:
+// ret = 7713;
+// break;
+// case 7714:
+// ret = 7715;
+// break;
+// case 7716:
+// ret = 7717;
+// break;
+// case 7718:
+// ret = 7719;
+// break;
+// case 7720:
+// ret = 7721;
+// break;
+// case 7722:
+// ret = 7723;
+// break;
+// case 7724:
+// ret = 7725;
+// break;
+// case 7726:
+// ret = 7727;
+// break;
+// case 7728:
+// ret = 7729;
+// break;
+// case 7730:
+// ret = 7731;
+// break;
+// case 7732:
+// ret = 7733;
+// break;
+// case 7734:
+// ret = 7735;
+// break;
+// case 7736:
+// ret = 7737;
+// break;
+// case 7738:
+// ret = 7739;
+// break;
+// case 7740:
+// ret = 7741;
+// break;
+// case 7742:
+// ret = 7743;
+// break;
+// case 7744:
+// ret = 7745;
+// break;
+// case 7746:
+// ret = 7747;
+// break;
+// case 7748:
+// ret = 7749;
+// break;
+// case 7750:
+// ret = 7751;
+// break;
+// case 7752:
+// ret = 7753;
+// break;
+// case 7754:
+// ret = 7755;
+// break;
+// case 7756:
+// ret = 7757;
+// break;
+// case 7758:
+// ret = 7759;
+// break;
+// case 7760:
+// ret = 7761;
+// break;
+// case 7762:
+// ret = 7763;
+// break;
+// case 7764:
+// ret = 7765;
+// break;
+// case 7766:
+// ret = 7767;
+// break;
+// case 7768:
+// ret = 7769;
+// break;
+// case 7770:
+// ret = 7771;
+// break;
+// case 7772:
+// ret = 7773;
+// break;
+// case 7774:
+// ret = 7775;
+// break;
+// case 7776:
+// ret = 7777;
+// break;
+// case 7778:
+// ret = 7779;
+// break;
+// case 7780:
+// ret = 7781;
+// break;
+// case 7782:
+// ret = 7783;
+// break;
+// case 7784:
+// ret = 7785;
+// break;
+// case 7786:
+// ret = 7787;
+// break;
+// case 7788:
+// ret = 7789;
+// break;
+// case 7790:
+// ret = 7791;
+// break;
+// case 7792:
+// ret = 7793;
+// break;
+// case 7794:
+// ret = 7795;
+// break;
+// case 7796:
+// ret = 7797;
+// break;
+// case 7798:
+// ret = 7799;
+// break;
+// case 7800:
+// ret = 7801;
+// break;
+// case 7802:
+// ret = 7803;
+// break;
+// case 7804:
+// ret = 7805;
+// break;
+// case 7806:
+// ret = 7807;
+// break;
+// case 7808:
+// ret = 7809;
+// break;
+// case 7810:
+// ret = 7811;
+// break;
+// case 7812:
+// ret = 7813;
+// break;
+// case 7814:
+// ret = 7815;
+// break;
+// case 7816:
+// ret = 7817;
+// break;
+// case 7818:
+// ret = 7819;
+// break;
+// case 7820:
+// ret = 7821;
+// break;
+// case 7822:
+// ret = 7823;
+// break;
+// case 7824:
+// ret = 7825;
+// break;
+// case 7826:
+// ret = 7827;
+// break;
+// case 7828:
+// ret = 7829;
+// break;
+// case 7840:
+// ret = 7841;
+// break;
+// case 7842:
+// ret = 7843;
+// break;
+// case 7844:
+// ret = 7845;
+// break;
+// case 7846:
+// ret = 7847;
+// break;
+// case 7848:
+// ret = 7849;
+// break;
+// case 7850:
+// ret = 7851;
+// break;
+// case 7852:
+// ret = 7853;
+// break;
+// case 7854:
+// ret = 7855;
+// break;
+// case 7856:
+// ret = 7857;
+// break;
+// case 7858:
+// ret = 7859;
+// break;
+// case 7860:
+// ret = 7861;
+// break;
+// case 7862:
+// ret = 7863;
+// break;
+// case 7864:
+// ret = 7865;
+// break;
+// case 7866:
+// ret = 7867;
+// break;
+// case 7868:
+// ret = 7869;
+// break;
+// case 7870:
+// ret = 7871;
+// break;
+// case 7872:
+// ret = 7873;
+// break;
+// case 7874:
+// ret = 7875;
+// break;
+// case 7876:
+// ret = 7877;
+// break;
+// case 7878:
+// ret = 7879;
+// break;
+// case 7880:
+// ret = 7881;
+// break;
+// case 7882:
+// ret = 7883;
+// break;
+// case 7884:
+// ret = 7885;
+// break;
+// case 7886:
+// ret = 7887;
+// break;
+// case 7888:
+// ret = 7889;
+// break;
+// case 7890:
+// ret = 7891;
+// break;
+// case 7892:
+// ret = 7893;
+// break;
+// case 7894:
+// ret = 7895;
+// break;
+// case 7896:
+// ret = 7897;
+// break;
+// case 7898:
+// ret = 7899;
+// break;
+// case 7900:
+// ret = 7901;
+// break;
+// case 7902:
+// ret = 7903;
+// break;
+// case 7904:
+// ret = 7905;
+// break;
+// case 7906:
+// ret = 7907;
+// break;
+// case 7908:
+// ret = 7909;
+// break;
+// case 7910:
+// ret = 7911;
+// break;
+// case 7912:
+// ret = 7913;
+// break;
+// case 7914:
+// ret = 7915;
+// break;
+// case 7916:
+// ret = 7917;
+// break;
+// case 7918:
+// ret = 7919;
+// break;
+// case 7920:
+// ret = 7921;
+// break;
+// case 7922:
+// ret = 7923;
+// break;
+// case 7924:
+// ret = 7925;
+// break;
+// case 7926:
+// ret = 7927;
+// break;
+// case 7928:
+// ret = 7929;
+// break;
+// case 7944:
+// ret = 7936;
+// break;
+// case 7945:
+// ret = 7937;
+// break;
+// case 7946:
+// ret = 7938;
+// break;
+// case 7947:
+// ret = 7939;
+// break;
+// case 7948:
+// ret = 7940;
+// break;
+// case 7949:
+// ret = 7941;
+// break;
+// case 7950:
+// ret = 7942;
+// break;
+// case 7951:
+// ret = 7943;
+// break;
+// case 7960:
+// ret = 7952;
+// break;
+// case 7961:
+// ret = 7953;
+// break;
+// case 7962:
+// ret = 7954;
+// break;
+// case 7963:
+// ret = 7955;
+// break;
+// case 7964:
+// ret = 7956;
+// break;
+// case 7965:
+// ret = 7957;
+// break;
+// case 7976:
+// ret = 7968;
+// break;
+// case 7977:
+// ret = 7969;
+// break;
+// case 7978:
+// ret = 7970;
+// break;
+// case 7979:
+// ret = 7971;
+// break;
+// case 7980:
+// ret = 7972;
+// break;
+// case 7981:
+// ret = 7973;
+// break;
+// case 7982:
+// ret = 7974;
+// break;
+// case 7983:
+// ret = 7975;
+// break;
+// case 7992:
+// ret = 7984;
+// break;
+// case 7993:
+// ret = 7985;
+// break;
+// case 7994:
+// ret = 7986;
+// break;
+// case 7995:
+// ret = 7987;
+// break;
+// case 7996:
+// ret = 7988;
+// break;
+// case 7997:
+// ret = 7989;
+// break;
+// case 7998:
+// ret = 7990;
+// break;
+// case 7999:
+// ret = 7991;
+// break;
+// case 8008:
+// ret = 8000;
+// break;
+// case 8009:
+// ret = 8001;
+// break;
+// case 8010:
+// ret = 8002;
+// break;
+// case 8011:
+// ret = 8003;
+// break;
+// case 8012:
+// ret = 8004;
+// break;
+// case 8013:
+// ret = 8005;
+// break;
+// case 8025:
+// ret = 8017;
+// break;
+// case 8027:
+// ret = 8019;
+// break;
+// case 8029:
+// ret = 8021;
+// break;
+// case 8031:
+// ret = 8023;
+// break;
+// case 8040:
+// ret = 8032;
+// break;
+// case 8041:
+// ret = 8033;
+// break;
+// case 8042:
+// ret = 8034;
+// break;
+// case 8043:
+// ret = 8035;
+// break;
+// case 8044:
+// ret = 8036;
+// break;
+// case 8045:
+// ret = 8037;
+// break;
+// case 8046:
+// ret = 8038;
+// break;
+// case 8047:
+// ret = 8039;
+// break;
+// case 8072:
+// ret = 8064;
+// break;
+// case 8073:
+// ret = 8065;
+// break;
+// case 8074:
+// ret = 8066;
+// break;
+// case 8075:
+// ret = 8067;
+// break;
+// case 8076:
+// ret = 8068;
+// break;
+// case 8077:
+// ret = 8069;
+// break;
+// case 8078:
+// ret = 8070;
+// break;
+// case 8079:
+// ret = 8071;
+// break;
+// case 8088:
+// ret = 8080;
+// break;
+// case 8089:
+// ret = 8081;
+// break;
+// case 8090:
+// ret = 8082;
+// break;
+// case 8091:
+// ret = 8083;
+// break;
+// case 8092:
+// ret = 8084;
+// break;
+// case 8093:
+// ret = 8085;
+// break;
+// case 8094:
+// ret = 8086;
+// break;
+// case 8095:
+// ret = 8087;
+// break;
+// case 8104:
+// ret = 8096;
+// break;
+// case 8105:
+// ret = 8097;
+// break;
+// case 8106:
+// ret = 8098;
+// break;
+// case 8107:
+// ret = 8099;
+// break;
+// case 8108:
+// ret = 8100;
+// break;
+// case 8109:
+// ret = 8101;
+// break;
+// case 8110:
+// ret = 8102;
+// break;
+// case 8111:
+// ret = 8103;
+// break;
+// case 8120:
+// ret = 8112;
+// break;
+// case 8121:
+// ret = 8113;
+// break;
+// case 8122:
+// ret = 8048;
+// break;
+// case 8123:
+// ret = 8049;
+// break;
+// case 8124:
+// ret = 8115;
+// break;
+// case 8136:
+// ret = 8050;
+// break;
+// case 8137:
+// ret = 8051;
+// break;
+// case 8138:
+// ret = 8052;
+// break;
+// case 8139:
+// ret = 8053;
+// break;
+// case 8140:
+// ret = 8131;
+// break;
+// case 8152:
+// ret = 8144;
+// break;
+// case 8153:
+// ret = 8145;
+// break;
+// case 8154:
+// ret = 8054;
+// break;
+// case 8155:
+// ret = 8055;
+// break;
+// case 8168:
+// ret = 8160;
+// break;
+// case 8169:
+// ret = 8161;
+// break;
+// case 8170:
+// ret = 8058;
+// break;
+// case 8171:
+// ret = 8059;
+// break;
+// case 8172:
+// ret = 8165;
+// break;
+// case 8184:
+// ret = 8056;
+// break;
+// case 8185:
+// ret = 8057;
+// break;
+// case 8186:
+// ret = 8060;
+// break;
+// case 8187:
+// ret = 8061;
+// break;
+// case 8188:
+// ret = 8179;
+// break;
+// case 8544:
+// ret = 8560;
+// break;
+// case 8545:
+// ret = 8561;
+// break;
+// case 8546:
+// ret = 8562;
+// break;
+// case 8547:
+// ret = 8563;
+// break;
+// case 8548:
+// ret = 8564;
+// break;
+// case 8549:
+// ret = 8565;
+// break;
+// case 8550:
+// ret = 8566;
+// break;
+// case 8551:
+// ret = 8567;
+// break;
+// case 8552:
+// ret = 8568;
+// break;
+// case 8553:
+// ret = 8569;
+// break;
+// case 8554:
+// ret = 8570;
+// break;
+// case 8555:
+// ret = 8571;
+// break;
+// case 8556:
+// ret = 8572;
+// break;
+// case 8557:
+// ret = 8573;
+// break;
+// case 8558:
+// ret = 8574;
+// break;
+// case 8559:
+// ret = 8575;
+// break;
+// case 9398:
+// ret = 9424;
+// break;
+// case 9399:
+// ret = 9425;
+// break;
+// case 9400:
+// ret = 9426;
+// break;
+// case 9401:
+// ret = 9427;
+// break;
+// case 9402:
+// ret = 9428;
+// break;
+// case 9403:
+// ret = 9429;
+// break;
+// case 9404:
+// ret = 9430;
+// break;
+// case 9405:
+// ret = 9431;
+// break;
+// case 9406:
+// ret = 9432;
+// break;
+// case 9407:
+// ret = 9433;
+// break;
+// case 9408:
+// ret = 9434;
+// break;
+// case 9409:
+// ret = 9435;
+// break;
+// case 9410:
+// ret = 9436;
+// break;
+// case 9411:
+// ret = 9437;
+// break;
+// case 9412:
+// ret = 9438;
+// break;
+// case 9413:
+// ret = 9439;
+// break;
+// case 9414:
+// ret = 9440;
+// break;
+// case 9415:
+// ret = 9441;
+// break;
+// case 9416:
+// ret = 9442;
+// break;
+// case 9417:
+// ret = 9443;
+// break;
+// case 9418:
+// ret = 9444;
+// break;
+// case 9419:
+// ret = 9445;
+// break;
+// case 9420:
+// ret = 9446;
+// break;
+// case 9421:
+// ret = 9447;
+// break;
+// case 9422:
+// ret = 9448;
+// break;
+// case 9423:
+// ret = 9449;
+// break;
+// case 65313:
+// ret = 65345;
+// break;
+// case 65314:
+// ret = 65346;
+// break;
+// case 65315:
+// ret = 65347;
+// break;
+// case 65316:
+// ret = 65348;
+// break;
+// case 65317:
+// ret = 65349;
+// break;
+// case 65318:
+// ret = 65350;
+// break;
+// case 65319:
+// ret = 65351;
+// break;
+// case 65320:
+// ret = 65352;
+// break;
+// case 65321:
+// ret = 65353;
+// break;
+// case 65322:
+// ret = 65354;
+// break;
+// case 65323:
+// ret = 65355;
+// break;
+// case 65324:
+// ret = 65356;
+// break;
+// case 65325:
+// ret = 65357;
+// break;
+// case 65326:
+// ret = 65358;
+// break;
+// case 65327:
+// ret = 65359;
+// break;
+// case 65328:
+// ret = 65360;
+// break;
+// case 65329:
+// ret = 65361;
+// break;
+// case 65330:
+// ret = 65362;
+// break;
+// case 65331:
+// ret = 65363;
+// break;
+// case 65332:
+// ret = 65364;
+// break;
+// case 65333:
+// ret = 65365;
+// break;
+// case 65334:
+// ret = 65366;
+// break;
+// case 65335:
+// ret = 65367;
+// break;
+// case 65336:
+// ret = 65368;
+// break;
+// case 65337:
+// ret = 65369;
+// break;
+// case 65338:
+// ret = 65370;
+// break;
+// }
+// return (char) ret;
+// }
return Character.toLowerCase(c);
}
- /** Convert a String to title case. */
+ /** Convert a String to title case.
+ *
+ * @j2sIgnore
+ *
+ *
+ */
public static String toTitleCase(String s)
{
- StringBuffer sb = new StringBuffer();
+ StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++)
{
- sb.append(CaseMgr.toTitleCase(s.charAt(i)));
+ sb.append(CaseMgr.toTitleCaseC(s.charAt(i)));
}
return sb.toString();
}
/** Convert a String to upper case. */
public static String toUpperCase(String s)
{
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < s.length(); i++)
- {
- sb.append(CaseMgr.toUpperCase(s.charAt(i)));
- }
- return sb.toString();
+ return s.toUpperCase();
+// StringBuffer sb = new StringBuffer();
+// for (int i = 0; i < s.length(); i++)
+// {
+// sb.append(CaseMgr.toUpperCaseC(s.charAt(i)));
+// }
+// return sb.toString();
}
/** Convert a String to lower case. */
public static String toLowerCase(String s)
{
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < s.length(); i++)
- {
- sb.append(CaseMgr.toLowerCase(s.charAt(i)));
- }
- return sb.toString();
+ return s.toLowerCase();
+// StringBuffer sb = new StringBuffer();
+// for (int i = 0; i < s.length(); i++)
+// {
+// sb.append(CaseMgr.toLowerCaseC(s.charAt(i)));
+// }
+// return sb.toString();
}
- /** Convert a character to title case. */
- public static char toTitleCase(char c)
+ /** Convert a character to title case.
+ *
+ * SwingJS -- BH -- ignoring title case.
+ *
+ * */
+ public static char toTitleCaseC(char c)
{
- if (java_1_0)
- {
- int ret = (int) toUpperCase(c);
- switch (c)
- {
- case 452:
- ret = 453;
- break;
- case 453:
- ret = 453;
- break;
- case 454:
- ret = 453;
- break;
- case 455:
- ret = 456;
- break;
- case 456:
- ret = 456;
- break;
- case 457:
- ret = 456;
- break;
- case 458:
- ret = 459;
- break;
- case 459:
- ret = 459;
- break;
- case 460:
- ret = 459;
- break;
- case 497:
- ret = 498;
- break;
- case 498:
- ret = 498;
- break;
- case 499:
- ret = 498;
- break;
- }
- return (char) ret;
- }
- return Character.toTitleCase(c);
+ return Character.toUpperCase(c);
+// if (java_1_0)
+// {
+// int ret = (int) toUpperCaseC(c);
+// switch (c)
+// {
+// case 452:
+// ret = 453;
+// break;
+// case 453:
+// ret = 453;
+// break;
+// case 454:
+// ret = 453;
+// break;
+// case 455:
+// ret = 456;
+// break;
+// case 456:
+// ret = 456;
+// break;
+// case 457:
+// ret = 456;
+// break;
+// case 458:
+// ret = 459;
+// break;
+// case 459:
+// ret = 459;
+// break;
+// case 460:
+// ret = 459;
+// break;
+// case 497:
+// ret = 498;
+// break;
+// case 498:
+// ret = 498;
+// break;
+// case 499:
+// ret = 498;
+// break;
+// }
+// return (char) ret;
+// }
+// return Character.toTitleCase(c);
}
/**
* definitions of upper, lower, and title case in this class when ignoreCase
* is set.
*/
- public static boolean regionMatches(StringLike s1, boolean ign, int i1,
+ public static boolean regionMatchesLike(StringLike s1, boolean ign, int i1,
StringLike s2, int i2, int i3)
{
int itot = i2 + i3;
{
for (int i = i2; i < itot; i++)
{
- if (toLowerCase(s2.charAt(i)) != toLowerCase(s1.charAt(i1++)))
+ if (toLowerCaseC(s2.charAt(i)) != toLowerCaseC(s1.charAt(i1++)))
{
return false;
}
{
for (int i = i2; i < itot; i++)
{
- if (toLowerCase(s2.charAt(i)) != toLowerCase(s1.charAt(i1++)))
+ if (toLowerCaseC(s2.charAt(i)) != toLowerCaseC(s1.charAt(i1++)))
{
return false;
}
* definitions of upper, lower, and title case in this class when ignoreCase
* is set.
*/
- public static boolean regionMatches(StringLike s1, boolean ign, int i1,
+ public static boolean regionMatchesLike2(StringLike s1, boolean ign, int i1,
String s2, int i2, int i3)
{
int itot = i2 + i3;
{
for (int i = i2; i < itot; i++)
{
- if (toLowerCase(s2.charAt(i)) != toLowerCase(s1.charAt(i1++)))
+ if (toLowerCaseC(s2.charAt(i)) != toLowerCaseC(s1.charAt(i1++)))
{
return false;
}
* definitions of upper, lower, and title case in this class when ignoreCase
* is set.
*/
- public static boolean regionMatches(String s1, boolean ign, int i1,
+ public static boolean regionMatches2(String s1, boolean ign, int i1,
String s2, int i2, int i3)
{
int itot = i2 + i3;
{
for (int i = i2; i < itot; i++)
{
- if (toLowerCase(s2.charAt(i)) != toLowerCase(s1.charAt(i1++)))
+ if (toLowerCaseC(s2.charAt(i)) != toLowerCaseC(s1.charAt(i1++)))
{
return false;
}
*/
public class DirFileRegex extends FileRegex
{
- public DirFileRegex()
- {
- dirflag = DIR;
- }
-
- public DirFileRegex(String fp)
- {
- super(fp);
- dirflag = DIR;
- }
-
- public static String[] list(String f)
- {
- return list(f, DIR);
- }
+// public DirFileRegex()
+// {
+// dirflag = DIR;
+// }
+//
+// public DirFileRegex(String fp)
+// {
+// super(fp);
+// dirflag = DIR;
+// }
+//
+// public static String[] list(String f)
+// {
+// return list(f, DIR);
+// }
}
*/
public class FileRegex extends Regex
{
- /** Build an unitialized FileRegex. */
- public FileRegex()
- {
- dirflag = EITHER;
- }
-
- /** Build a FileRegex form String s. */
- public FileRegex(String s)
- {
- super(s);
- dirflag = EITHER;
- }
-
- /**
- * Compile a new pattern. Throws
- *
- * @exception com.stevesoft.pat.RegSyntax
- * for nonsensical patterns like "[9-0]+" just as Regex
- * does.
- * @see com.stevesoft.pat#compile(java.lang.String)
- */
- public void compile(String s) throws RegSyntax
- {
- String npat = toFileRegex(s);
- super.compile(npat);
- if (File.separatorChar == '\\') // MS-DOS
- {
- ignoreCase = true;
- }
- }
-
- /**
- * This is the method required by FileNameFilter. To get a listing of files in
- * the current directory ending in .java, do this:
- *
- * <pre>
- * File dot = new File(".");
- *
- * FileRegex java_files = new FileRegex("*.java");
- *
- * String[] file_list = dot.list(java_files);
- * </pre>
- */
- public boolean accept(File dir, String s)
- {
- if (dirflag != EITHER)
- {
- File f = new File(s);
- if (f.isDirectory() && dirflag == NONDIR)
- {
- return false;
- }
- if (!f.isDirectory() && dirflag == DIR)
- {
- return false;
- }
- }
- return matchAt(s, 0);
- }
-
- int dirflag = 0;
-
- final static int EITHER = 0, DIR = 1, NONDIR = 2;
-
- /**
- * Provides an alternative to File.list -- this separates its argument
- * according to File.pathSeparator. To each path, it splits off a directory --
- * all characters up to and including the first instance of File.separator --
- * and a file pattern -- the part that comes after the directory. It then
- * produces a list of all the pattern matches on all the paths. Thus
- * "*.java:../*.java" would produce a list of all the java files in this
- * directory and in the ".." directory on a Unix machine. "*.java;..\\*.java"
- * would do the same thing on a Dos machine.
- */
- public static String[] list(String f)
- {
- return list(f, EITHER);
- }
-
- static String[] list(String f, int df)
- {
- // return list_(f,new FileRegex());
- StringTokenizer st = new StringTokenizer(f, File.pathSeparator);
- Vector v = new Vector();
- while (st.hasMoreTokens())
- {
- String path = st.nextToken();
- list1(path, v, df, true);
- }
- String[] sa = new String[v.size()];
- v.copyInto(sa);
- return sa;
- }
-
- final static Regex root = new Regex(File.separatorChar == '/' ? "/$"
- : "(?:.:|)\\\\$");
-
- static void list1(String path, Vector v, int df, boolean rec)
- {
- // if path looks like a/b/c/ or d:\ then add .
- if (root.matchAt(path, 0))
- {
- v.addElement(path + ".");
- return;
- }
- File f = new File(path);
- if (f.getParent() != null && rec)
- {
- Vector v2 = new Vector();
- list1(f.getParent(), v2, DIR, true);
- for (int i = 0; i < v2.size(); i++)
- {
- String path2 = ((String) v2.elementAt(i)) + File.separator
- + f.getName();
- list1(path2, v, df, false);
- }
- }
- else
- {
- File base = new File(path);
-
- String dir_s = base.getParent();
- if (dir_s == null)
- {
- dir_s = ".";
- }
- File dir = new File(dir_s);
-
- FileRegex fr = new FileRegex(base.getName());
- if (fr.isLiteral())
- {
- v.addElement(dir_s + File.separator + base.getName());
- return;
- }
- fr.dirflag = df;
- String[] sa = dir.list(fr);
- if (sa == null)
- {
- return;
- }
- for (int i = 0; i < sa.length; i++)
- {
- v.addElement(dir_s + File.separator + sa[i]);
- }
- }
- }
-
- /**
- * This method takes a file regular expression, and translates it into the
- * type of pattern used by a normal Regex.
- */
- public static String toFileRegex(String s)
- {
- StrPos sp = new StrPos(s, 0);
- StringBuffer sb = new StringBuffer();
- if (sp.incMatch("{?e="))
- {
- char e = sp.thisChar();
- sp.inc();
- if (sp.incMatch("}"))
- {
- sb.append("(?e=" + e + ")^");
- }
- else
- {
- sb.append("^(?e=");
- }
- sp.esc = e;
- }
- int ParenLvl = 0;
- while (!sp.eos())
- {
- if (File.separatorChar == '\\')
- {
- if (sp.escaped())
- {
- sb.append("\\\\");
- }
- sp.dontMatch = false;
- }
- if (sp.incMatch("?"))
- {
- sb.append(".");
- }
- else if (sp.incMatch("."))
- {
- sb.append(sp.esc);
- sb.append('.');
- }
- else if (sp.incMatch("{??"))
- {
- sb.append("(??");
- ParenLvl++;
- // allow negative lookahead to work
- }
- else if (sp.incMatch("{?!"))
- {
- sb.append("(?!");
- ParenLvl++;
- // allow positive lookahead to work
- }
- else if (sp.incMatch("{?="))
- {
- sb.append("(?=");
- ParenLvl++;
- }
- else if (sp.incMatch("{"))
- {
- sb.append("(?:");
- ParenLvl++;
- }
- else if (sp.incMatch("}"))
- {
- sb.append(')');
- ParenLvl--;
- }
- else if (ParenLvl != 0 && sp.incMatch(","))
- {
- sb.append('|');
- }
- else if (sp.incMatch("*"))
- {
- sb.append(".*");
- }
- else
- {
- sb.append(sp.thisChar());
- sp.inc();
- }
- }
- sb.append("$");
- return sb.toString();
- }
-
- public boolean isLiteral()
- {
- Pattern x = thePattern;
- while (x != null && !(x instanceof End))
- {
- if (x instanceof oneChar)
- {
- ;
- }
- else if (x instanceof Skipped)
- {
- ;
- }
- else
- {
- return false;
- }
- x = x.next;
- }
- return true;
- }
+// /** Build an unitialized FileRegex. */
+// public FileRegex()
+// {
+// dirflag = EITHER;
+// }
+//
+// /** Build a FileRegex form String s. */
+// public FileRegex(String s)
+// {
+// super(s);
+// dirflag = EITHER;
+// }
+//
+// /**
+// * Compile a new pattern. Throws
+// *
+// * @exception com.stevesoft.pat.RegSyntax
+// * for nonsensical patterns like "[9-0]+" just as Regex
+// * does.
+// * @see com.stevesoft.pat#compile(java.lang.String)
+// */
+// public void compile(String s) throws RegSyntax
+// {
+// String npat = toFileRegex(s);
+// super.compile(npat);
+// if (File.separatorChar == '\\') // MS-DOS
+// {
+// ignoreCase = true;
+// }
+// }
+//
+// /**
+// * This is the method required by FileNameFilter. To get a listing of files in
+// * the current directory ending in .java, do this:
+// *
+// * <pre>
+// * File dot = new File(".");
+// *
+// * FileRegex java_files = new FileRegex("*.java");
+// *
+// * String[] file_list = dot.list(java_files);
+// * </pre>
+// */
+// public boolean accept(File dir, String s)
+// {
+// if (dirflag != EITHER)
+// {
+// File f = new File(s);
+// if (f.isDirectory() && dirflag == NONDIR)
+// {
+// return false;
+// }
+// if (!f.isDirectory() && dirflag == DIR)
+// {
+// return false;
+// }
+// }
+// return matchAt(s, 0);
+// }
+//
+// int dirflag = 0;
+//
+// final static int EITHER = 0, DIR = 1, NONDIR = 2;
+//
+// /**
+// * Provides an alternative to File.list -- this separates its argument
+// * according to File.pathSeparator. To each path, it splits off a directory --
+// * all characters up to and including the first instance of File.separator --
+// * and a file pattern -- the part that comes after the directory. It then
+// * produces a list of all the pattern matches on all the paths. Thus
+// * "*.java:../*.java" would produce a list of all the java files in this
+// * directory and in the ".." directory on a Unix machine. "*.java;..\\*.java"
+// * would do the same thing on a Dos machine.
+// */
+// public static String[] list(String f)
+// {
+// return list(f, EITHER);
+// }
+//
+// static String[] list(String f, int df)
+// {
+// // return list_(f,new FileRegex());
+// StringTokenizer st = new StringTokenizer(f, File.pathSeparator);
+// Vector v = new Vector();
+// while (st.hasMoreTokens())
+// {
+// String path = st.nextToken();
+// list1(path, v, df, true);
+// }
+// String[] sa = new String[v.size()];
+// v.copyInto(sa);
+// return sa;
+// }
+//
+// final static Regex root = new Regex(File.separatorChar == '/' ? "/$"
+// : "(?:.:|)\\\\$");
+//
+// static void list1(String path, Vector v, int df, boolean rec)
+// {
+// // if path looks like a/b/c/ or d:\ then add .
+// if (root.matchAt(path, 0))
+// {
+// v.addElement(path + ".");
+// return;
+// }
+// File f = new File(path);
+// if (f.getParent() != null && rec)
+// {
+// Vector v2 = new Vector();
+// list1(f.getParent(), v2, DIR, true);
+// for (int i = 0; i < v2.size(); i++)
+// {
+// String path2 = ((String) v2.elementAt(i)) + File.separator
+// + f.getName();
+// list1(path2, v, df, false);
+// }
+// }
+// else
+// {
+// File base = new File(path);
+//
+// String dir_s = base.getParent();
+// if (dir_s == null)
+// {
+// dir_s = ".";
+// }
+// File dir = new File(dir_s);
+//
+// FileRegex fr = new FileRegex(base.getName());
+// if (fr.isLiteral())
+// {
+// v.addElement(dir_s + File.separator + base.getName());
+// return;
+// }
+// fr.dirflag = df;
+// String[] sa = dir.list(fr);
+// if (sa == null)
+// {
+// return;
+// }
+// for (int i = 0; i < sa.length; i++)
+// {
+// v.addElement(dir_s + File.separator + sa[i]);
+// }
+// }
+// }
+//
+// /**
+// * This method takes a file regular expression, and translates it into the
+// * type of pattern used by a normal Regex.
+// */
+// public static String toFileRegex(String s)
+// {
+// StrPos sp = new StrPos(s, 0);
+// StringBuffer sb = new StringBuffer();
+// if (sp.incMatch("{?e="))
+// {
+// char e = sp.thisChar();
+// sp.inc();
+// if (sp.incMatch("}"))
+// {
+// sb.append("(?e=" + e + ")^");
+// }
+// else
+// {
+// sb.append("^(?e=");
+// }
+// sp.esc = e;
+// }
+// int ParenLvl = 0;
+// while (!sp.eos())
+// {
+// if (File.separatorChar == '\\')
+// {
+// if (sp.escaped())
+// {
+// sb.append("\\\\");
+// }
+// sp.dontMatch = false;
+// }
+// if (sp.incMatch("?"))
+// {
+// sb.append(".");
+// }
+// else if (sp.incMatch("."))
+// {
+// sb.append(sp.esc);
+// sb.append('.');
+// }
+// else if (sp.incMatch("{??"))
+// {
+// sb.append("(??");
+// ParenLvl++;
+// // allow negative lookahead to work
+// }
+// else if (sp.incMatch("{?!"))
+// {
+// sb.append("(?!");
+// ParenLvl++;
+// // allow positive lookahead to work
+// }
+// else if (sp.incMatch("{?="))
+// {
+// sb.append("(?=");
+// ParenLvl++;
+// }
+// else if (sp.incMatch("{"))
+// {
+// sb.append("(?:");
+// ParenLvl++;
+// }
+// else if (sp.incMatch("}"))
+// {
+// sb.append(')');
+// ParenLvl--;
+// }
+// else if (ParenLvl != 0 && sp.incMatch(","))
+// {
+// sb.append('|');
+// }
+// else if (sp.incMatch("*"))
+// {
+// sb.append(".*");
+// }
+// else
+// {
+// sb.append(sp.thisChar());
+// sp.inc();
+// }
+// }
+// sb.append("$");
+// return sb.toString();
+// }
+//
+// public boolean isLiteral()
+// {
+// Pattern x = thePattern;
+// while (x != null && !(x instanceof End))
+// {
+// if (x instanceof oneChar)
+// {
+// ;
+// }
+// else if (x instanceof Skipped)
+// {
+// ;
+// }
+// else
+// {
+// return false;
+// }
+// x = x.next;
+// }
+// return true;
+// }
}
--- /dev/null
+package com.stevesoft.pat;
+
+/**
+ * just a temporary implementation to avoid cross-referencing to jalview.
+ * @author Bob Hanson
+ *
+ */
+public class MessageManager {
+
+ public static String getString(String string) {
+ return string;
+ }
+
+ public static String formatMessage(String s, String...fields) {
+ // just a super super simple implementation to get us rolling
+ for (int i = 0; i < fields.length; i++)
+ s += " " + fields[i];
+ return s;
+ }
+
+}
*/
public class NonDirFileRegex extends FileRegex
{
- public NonDirFileRegex()
- {
- dirflag = NONDIR;
- }
-
- public NonDirFileRegex(String fp)
- {
- super(fp);
- dirflag = NONDIR;
- }
-
- public static String[] list(String f)
- {
- return list(f, NONDIR);
- }
+// public NonDirFileRegex()
+// {
+// dirflag = NONDIR;
+// }
+//
+// public NonDirFileRegex(String fp)
+// {
+// super(fp);
+// dirflag = NONDIR;
+// }
+//
+// public static String[] list(String f)
+// {
+// return list(f, NONDIR);
+// }
}
//
package com.stevesoft.pat;
-import jalview.util.MessageManager;
+import com.stevesoft.pat.MessageManager;
import java.util.*;
/**
* Clones this pattern elements without cloning others in the linked list.
*/
- Pattern clone1(Hashtable h)
+ Pattern clone1(Hashtable<Object, Object> h)
{
throw new Error(MessageManager.formatMessage("error.no_such_method_as_clone1_for", new String[]{getClass().getName()}));
}
- Pattern clone(Hashtable h)
+ Pattern clone(Hashtable<Object, Object> h)
{
Pattern p = (Pattern) h.get(this);
if (p != null)
/**
* This class is used to store a result from Regex
*/
-public class RegRes implements Cloneable
+public class RegRes
{
protected int[] marks = null;
{
int n = i + 1;
sb
- .append(" sub(" + n + ")=" + matchedFrom(n) + ":"
- + charsMatched(n));
+ .append(" sub(" + n + ")=" + matchedFromI(n) + ":"
+ + charsMatchedI(n));
}
return sb.toString();
}
- public RegRes()
- {
- }
-
- public RegRes(RegRes r)
- {
- copyOutOf(r);
- }
+// public RegRes()
+// {
+// }
+//
+// public RegRes(RegRes r)
+// {
+// copyOutOf(r);
+// }
public void copyOutOf(RegRes r)
{
numSubs_ = r.numSubs_;
}
- public Object clone()
- {
- return new RegRes(this);
- }
-
+// public Object clone()
+// {
+// return new RegRes(this);
+// }
+//
public boolean equals(RegRes r)
{
if (charsMatched_ != r.charsMatched_ || matchFrom_ != r.matchFrom_
}
for (int i = 1; i <= numSubs_; i++)
{
- if (matchedFrom(i) != r.matchedFrom(i))
+ if (matchedFromI(i) != r.matchedFromI(i))
{
return false;
}
- else if (charsMatched(i) != r.charsMatched(i))
+ else if (charsMatchedI(i) != r.charsMatchedI(i))
{
return false;
}
* Obtains the position backreference number i begins to match, or -1 if
* backreference i was not matched.
*/
- public int matchedFrom(int i)
+ public int matchedFromI(int i)
{
if (marks == null || i > numSubs_)
{
* Obtains the number of characters matched by backreference i, or -1 if
* backreference i was not matched.
*/
- public int charsMatched(int i)
+ public int charsMatchedI(int i)
{
if (marks == null || i > numSubs_ || !didMatch_)
{
}
// Integer in = (Integer)marks.get("right"+i);
// int i2 = in==null ? -1 : in.intValue();
- int mf = matchedFrom(i);
- return mf < 0 ? -1 : marks[i + numSubs_] - matchedFrom(i);
+ int mf = matchedFromI(i);
+ return mf < 0 ? -1 : marks[i + numSubs_] - matchedFromI(i);
}
/**
* This is either equal to matchedFrom(i)+charsMatched(i) if the match was
* successful, or -1 if it was not.
*/
- public int matchedTo(int i)
+ public int matchedToI(int i)
{
if (marks == null || i > numSubs_ || !didMatch_)
{
* Obtains a substring matching the nth set of parenthesis from the pattern.
* See numSubs(void), or null if the nth backrefence did not match.
*/
- public String stringMatched(int i)
+ public String stringMatchedI(int i)
{
- int mf = matchedFrom(i), cm = charsMatched(i);
+ int mf = matchedFromI(i), cm = charsMatchedI(i);
return !didMatch_ || mf < 0 || cm < 0 ? null : src.substring(mf, mf
+ cm);
}
* This returns the part of the string that follows the ith backreference, or
* null if the backreference did not match.
*/
- public String left(int i)
+ public String leftI(int i)
{
- int mf = matchedFrom(i);
+ int mf = matchedFromI(i);
return !didMatch_ || (mf < 0) ? null : src.substring(0, mf);
}
* This returns the string to the right of the ith backreference, or null if
* the backreference did not match.
*/
- public String right(int i)
+ public String rightI(int i)
{
- int mf = matchedFrom(i), cm = charsMatched(i);
+ int mf = matchedFromI(i), cm = charsMatchedI(i);
return !didMatch_ || mf < 0 || cm < 0 ? null : src.substring(mf + cm,
src.length());
}
}
/** An older name for matchedFrom. */
- public int matchFrom(int i)
+ public int matchFromI(int i)
{
- return matchedFrom(i);
+ return matchedFromI(i);
}
/** An older name for stringMatched. */
- public String substring(int i)
+ public String substringI(int i)
{
- return stringMatched(i);
+ return stringMatchedI(i);
}
}
//
package com.stevesoft.pat;
-import jalview.util.MessageManager;
+import com.stevesoft.pat.MessageManager;
-import java.io.*;
-import java.util.*;
+import jalview.jsdev.api.RegExpInterface;
-import com.stevesoft.pat.wrap.*;
+import java.io.File;
+import java.util.BitSet;
+import java.util.Hashtable;
+
+import com.stevesoft.pat.wrap.StringWrap;
/** Matches a Unicode punctuation character. */
class UnicodePunct extends UniValidator
final boolean isUpper(char c)
{
- return c == CaseMgr.toUpperCase(c) && c != CaseMgr.toLowerCase(c);
+ return c == CaseMgr.toUpperCaseC(c) && c != CaseMgr.toLowerCaseC(c);
}
}
final boolean isLower(char c)
{
- return c != CaseMgr.toUpperCase(c) && c == CaseMgr.toLowerCase(c);
+ return c != CaseMgr.toUpperCaseC(c) && c == CaseMgr.toLowerCaseC(c);
}
}
* @version package com.stevesoft.pat, release 1.5.3
* @see Pattern
*/
-public class Regex extends RegRes implements FilenameFilter
+public class Regex extends RegRes implements RegExpInterface, Cloneable //implements FilenameFilter
{
/**
* BackRefOffset gives the identity number of the first pattern. Version 1.0
patInt minMatch = new patInt(0);
- static Hashtable validators = new Hashtable();
+ static Hashtable<Object, Object> validators = new Hashtable<Object, Object>();
static
{
- define("p", "(?>1)", new UnicodePunct());
- define("P", "(?>1)", new NUnicodePunct());
- define("s", "(?>1)", new UnicodeWhite());
- define("S", "(?>1)", new NUnicodeWhite());
- define("w", "(?>1)", new UnicodeW());
- define("W", "(?>1)", new NUnicodeW());
- define("d", "(?>1)", new UnicodeDigit());
- define("D", "(?>1)", new NUnicodeDigit());
- define("m", "(?>1)", new UnicodeMath());
- define("M", "(?>1)", new NUnicodeMath());
- define("c", "(?>1)", new UnicodeCurrency());
- define("C", "(?>1)", new NUnicodeCurrency());
- define("a", "(?>1)", new UnicodeAlpha());
- define("A", "(?>1)", new NUnicodeAlpha());
- define("uc", "(?>1)", new UnicodeUpper());
- define("lc", "(?>1)", new UnicodeLower());
+ defineV("p", "(?>1)", new UnicodePunct());
+ defineV("P", "(?>1)", new NUnicodePunct());
+ defineV("s", "(?>1)", new UnicodeWhite());
+ defineV("S", "(?>1)", new NUnicodeWhite());
+ defineV("w", "(?>1)", new UnicodeW());
+ defineV("W", "(?>1)", new NUnicodeW());
+ defineV("d", "(?>1)", new UnicodeDigit());
+ defineV("D", "(?>1)", new NUnicodeDigit());
+ defineV("m", "(?>1)", new UnicodeMath());
+ defineV("M", "(?>1)", new NUnicodeMath());
+ defineV("c", "(?>1)", new UnicodeCurrency());
+ defineV("C", "(?>1)", new NUnicodeCurrency());
+ defineV("a", "(?>1)", new UnicodeAlpha());
+ defineV("A", "(?>1)", new NUnicodeAlpha());
+ defineV("uc", "(?>1)", new UnicodeUpper());
+ defineV("lc", "(?>1)", new UnicodeLower());
+ }
+
+ ReplaceRule rep = null;
+
+
+ /**
+ * Initializes the object without a Pattern. To supply a Pattern use
+ * compile(String s).
+ *
+ * @j2sIgnore
+ *
+ * @see com.stevesoft.pat.Regex#compile(java.lang.String)
+ */
+ @Deprecated
+ public Regex()
+ {
+ }
+
+ /**
+ * Create and compile both a Regex and a ReplaceRule.
+ *
+ * @see com.stevesoft.pat.ReplaceRule
+ * @see com.stevesoft.pat.Regex#compile(java.lang.String)
+ */
+ public Regex(String s, String strRp)
+ {
+ try
+ {
+ if (s != null)
+ compile(s);
+ if (strRp.length() > 0)
+ rep = ReplaceRule.perlCode(strRp);
+ } catch (RegSyntax rs)
+ {
+ }
+ }
+
+ /**
+ * Create and compile a Regex, but give it the ReplaceRule specified. This
+ * allows the user finer control of the Replacement process, if that is
+ * desired.
+ *
+ * @j2sIgnore
+ *
+ * @see com.stevesoft.pat.ReplaceRule
+ * @see com.stevesoft.pat.Regex#compile(java.lang.String)
+ */
+ public Regex(String s, ReplaceRule rp)
+ {
+ this(s, "");
+ rep = rp;
+ }
+
+ /**
+ * Create and compile a Regex, but do not throw any exceptions. If you wish to
+ * have exceptions thrown for syntax errors, you must use the Regex(void)
+ * constructor to create the Regex object, and then call the compile method.
+ * Therefore, you should only call this method when you know your pattern is
+ * right. I will probably become more like
+ *
+ * @j2sIgnore
+ *
+ * @see com.stevesoft.pat.Regex#search(java.lang.String)
+ * @see com.stevesoft.pat.Regex#compile(java.lang.String)
+ */
+ @Deprecated
+ public Regex(String s)
+ {
+ this(s, "");
+ }
+
+ /** A clone by any other name would smell as sweet. */
+ public Object clone()
+ {
+ return new Regex(null, "").cloneFrom(this);
+ }
+
+// /** Return a clone of the underlying RegRes object. */
+// public RegRes result()
+// {
+// return (RegRes) super.clone();
+// }
+
+ /** Essentially clones the Regex object */
+ public Regex cloneFrom(Regex r)
+ {
+ copyOutOf(r);
+// super((RegRes) r);
+ dontMatchInQuotes = r.dontMatchInQuotes;
+ esc = r.esc;
+ ignoreCase = r.ignoreCase;
+ gFlag = r.gFlag;
+ if (r.rep == null)
+ {
+ rep = null;
+ }
+ else
+ {
+ rep = (ReplaceRule) r.rep.clone();
+ }
+ /*
+ * try { compile(r.toString()); } catch(RegSyntax r_) {}
+ */
+ thePattern = r.thePattern.clone(new Hashtable<Object, Object>());
+ minMatch = r.minMatch;
+ skipper = r.skipper;
+ return this;
}
/** Set the dontMatch in quotes flag. */
}
/**
- * Initializes the object without a Pattern. To supply a Pattern use
- * compile(String s).
- *
- * @see com.stevesoft.pat.Regex#compile(java.lang.String)
- */
- public Regex()
- {
- }
-
- /**
- * Create and compile a Regex, but do not throw any exceptions. If you wish to
- * have exceptions thrown for syntax errors, you must use the Regex(void)
- * constructor to create the Regex object, and then call the compile method.
- * Therefore, you should only call this method when you know your pattern is
- * right. I will probably become more like
- *
- * @see com.stevesoft.pat.Regex#search(java.lang.String)
- * @see com.stevesoft.pat.Regex#compile(java.lang.String)
- */
- public Regex(String s)
- {
- try
- {
- compile(s);
- } catch (RegSyntax rs)
- {
- }
- }
-
- ReplaceRule rep = null;
-
- /**
- * Create and compile both a Regex and a ReplaceRule.
- *
- * @see com.stevesoft.pat.ReplaceRule
- * @see com.stevesoft.pat.Regex#compile(java.lang.String)
- */
- public Regex(String s, String rp)
- {
- this(s);
- rep = ReplaceRule.perlCode(rp);
- }
-
- /**
- * Create and compile a Regex, but give it the ReplaceRule specified. This
- * allows the user finer control of the Replacement process, if that is
- * desired.
- *
- * @see com.stevesoft.pat.ReplaceRule
- * @see com.stevesoft.pat.Regex#compile(java.lang.String)
- */
- public Regex(String s, ReplaceRule rp)
- {
- this(s);
- rep = rp;
- }
-
- /**
* Change the ReplaceRule of this Regex by compiling a new one using String
* rp.
*/
- public void setReplaceRule(String rp)
+ public void setReplaceRuleStr(String rp)
{
rep = ReplaceRule.perlCode(rp);
repr = null; // Clear Replacer history
/**
* Test to see if a custom defined rule exists.
*
- * @see com.stevesoft.pat#define(java.lang.String,java.lang.String,Validator)
+ * @see com.stevesoft.pat#defineV(java.lang.String,java.lang.String,Validator)
*/
public static boolean isDefined(String nm)
{
/**
* Removes a custom defined rule.
*
- * @see com.stevesoft.pat#define(java.lang.String,java.lang.String,Validator)
+ * @see com.stevesoft.pat#defineV(java.lang.String,java.lang.String,Validator)
*/
public static void undefine(String nm)
{
* Defines a method to create a new rule. See test/deriv2.java and
* test/deriv3.java for examples of how to use it.
*/
- public static void define(String nm, String pat, Validator v)
+ public static void defineV(String nm, String pat, Validator v)
{
v.pattern = pat;
validators.put(nm, v);
.toString();
}
- public StringLike replaceAll(StringLike s)
+ public StringLike replaceAllLike(StringLike s)
{
return _getReplacer().replaceAllRegion(s, this, 0, s.length());
}
return _getReplacer().replaceAllRegion(s, this, start, end).toString();
}
- /** Essentially clones the Regex object */
- public Regex(Regex r)
- {
- super((RegRes) r);
- dontMatchInQuotes = r.dontMatchInQuotes;
- esc = r.esc;
- ignoreCase = r.ignoreCase;
- gFlag = r.gFlag;
- if (r.rep == null)
- {
- rep = null;
- }
- else
- {
- rep = (ReplaceRule) r.rep.clone();
- }
- /*
- * try { compile(r.toString()); } catch(RegSyntax r_) {}
- */
- thePattern = r.thePattern.clone(new Hashtable());
- minMatch = r.minMatch;
- skipper = r.skipper;
- }
-
/**
* By default, the escape character is the backslash, but you can make it
* anything you want by setting this variable.
}
}
- /** A clone by any other name would smell as sweet. */
- public Object clone()
- {
- return new Regex(this);
- }
-
- /** Return a clone of the underlying RegRes object. */
- public RegRes result()
- {
- return (RegRes) super.clone();
- }
-
// prep sets global variables of class
// Pattern so that it can access them
// during an attempt at a match
*
* @see com.stevesoft.pat.Regex#search
*/
- public boolean matchAt(StringLike s, int start_pos)
+ public boolean matchAtLike(StringLike s, int start_pos)
{
- return _search(s, start_pos, start_pos);
+ return _searchLike(s, start_pos, start_pos);
}
/**
return _search(s, 0, s.length());
}
- public boolean search(StringLike sl)
+ public boolean searchLike(StringLike sl)
{
if (sl == null)
{
throw new NullPointerException(MessageManager.getString("exception.null_string_like_given_to_regex_search"));
}
- return _search(sl, 0, sl.length());
+ return _searchLike(sl, 0, sl.length());
}
public boolean reverseSearch(String s)
return _reverseSearch(s, 0, s.length());
}
- public boolean reverseSearch(StringLike sl)
+ public boolean reverseSearchLike(StringLike sl)
{
if (sl == null)
{
throw new NullPointerException(MessageManager.getString("exception.null_string_like_given_to_regex_reverse_search"));
}
- return _reverseSearch(sl, 0, sl.length());
+ return _reverseSearchLike(sl, 0, sl.length());
}
/**
return _search(s, start, s.length());
}
- public boolean searchFrom(StringLike s, int start)
+ public boolean searchFromLike(StringLike s, int start)
{
if (s == null)
{
throw new NullPointerException(MessageManager.getString("exception.null_string_like_given_to_regex_search_from"));
}
- return _search(s, start, s.length());
+ return _searchLike(s, start, s.length());
}
/**
final boolean _search(String s, int start, int end)
{
- return _search(new StringWrap(s), start, end);
+ return _searchLike(new StringWrap(s), start, end);
}
- final boolean _search(StringLike s, int start, int end)
+ final boolean _searchLike(StringLike s, int start, int end)
{
if (gFlag && gFlagto > 0 && gFlags != null
&& s.unwrap() == gFlags.unwrap())
boolean _reverseSearch(String s, int start, int end)
{
- return _reverseSearch(new StringWrap(s), start, end);
+ return _reverseSearchLike(new StringWrap(s), start, end);
}
- boolean _reverseSearch(StringLike s, int start, int end)
+ boolean _reverseSearchLike(StringLike s, int start, int end)
{
if (gFlag && gFlagto > 0 && s.unwrap() == gFlags.unwrap())
{
lasts = s;
}
- // Wanted user to over-ride this in alpha version,
- // but it wasn't really necessary because of this trick:
- Regex newRegex()
- {
- try
- {
- return (Regex) getClass().newInstance();
- } catch (InstantiationException ie)
- {
- return null;
- } catch (IllegalAccessException iae)
- {
- return null;
- }
- }
+// // Wanted user to over-ride this in alpha version,
+// // but it wasn't really necessary because of this trick:
+// Regex newRegex()
+// {
+// try
+// {
+// return (Regex) getClass().newInstance();
+// } catch (InstantiationException ie)
+// {
+// return null;
+// } catch (IllegalAccessException iae)
+// {
+// return null;
+// }
+// }
/**
* Only needed for creating your own extensions of Regex. This method adds the
* is thrown when a nonsensensical pattern is supplied. For
* example, a pattern beginning with *.
*/
- protected void compile1(StrPos sp, Rthings mk) throws RegSyntax
+ protected void compileSP(StrPos sp, Rthings mk) throws RegSyntax
{
if (sp.match('['))
{
}
else if (sp.dontMatch && sp.c == 'B')
{
- Regex r = new Regex();
+ Regex r = new Regex(null, "");
r._compile("(?!" + back_slash + "b)", mk);
add(r.thePattern);
}
if (validators.get(sbs) instanceof String)
{
String pat = (String) validators.get(sbs);
- Regex r = newRegex();
+ Regex r = new Regex(null, "");
Rthings rth = new Rthings(this);
rth.noBackRefs = true;
r._compile(pat, rth);
cm.v = v2;
v2.pattern = p;
}
- Regex r = newRegex();
+ Regex r = new Regex(null, "");
Rthings rth = new Rthings(this);
rth.noBackRefs = true;
r._compile(cm.v.pattern, rth);
else if (sp.match('('))
{
mk.parenLevel++;
- Regex r = newRegex();
+ Regex r = new Regex(null, "");
// r.or = new Or();
sp.inc();
if (sp.incMatch("?:"))
}
if (r != null)
{
- add(r._compile(sp, mk));
+ add(r._compileSP(sp, mk));
}
}
else if (sp.match('^'))
minMatch = null;
sFlag = mFlag = ignoreCase = gFlag = false;
StrPos sp = new StrPos(pat, 0);
- thePattern = _compile(sp, mk);
+ thePattern = _compileSP(sp, mk);
pt.marks = null;
return thePattern;
}
Or or = null;
- Pattern _compile(StrPos sp, Rthings mk) throws RegSyntax
+ Pattern _compileSP(StrPos sp, Rthings mk) throws RegSyntax
{
while (!(sp.eos || (or != null && sp.match(')'))))
{
- compile1(sp, mk);
+ compileSP(sp, mk);
sp.inc();
}
if (sp.match(')'))
*/
public String toString()
{
- if (false && thePattern == null)
- {
- return "";
- }
- else
+// if (false && thePattern == null)
+// {
+// return "";
+// }
+// else
{
StringBuffer sb = new StringBuffer();
if (esc != Pattern.ESC)
}
minMatch = new patInt(0); // thePattern.countMinChars();
thePattern = RegOpt.opt(thePattern, ignoreCase, dontMatchInQuotes);
- skipper = Skip.findSkip(this);
+ skipper = Skip.findSkipRegex(this);
// RegOpt.setParents(this);
return;
}
{
readData();
}
- else if (rp.getRegex().matchAt(wrap, rb.epos))
+ else if (rp.getRegex().matchAtLike(wrap, rb.epos))
{
if (wrap.overRun)
{
{
if (r.substring() != null)
{
- v.addElement(r.substring(i + offset));
- vi.addElement(new Integer(r.matchFrom(i + offset)
- + r.charsMatched(i + offset)));
+ v.addElement(r.substringI(i + offset));
+ vi.addElement(new Integer(r.matchFromI(i + offset)
+ + r.charsMatchedI(i + offset)));
}
}
pos = r.matchFrom() + r.charsMatched();
public RegexTokenizer(String txt, String ptrn)
{
toParse = txt;
- r = new Regex(ptrn);
+ r = new Regex(ptrn, "");
offset = Regex.BackRefOffset;
getMore();
}
{
Regex rex = repr.getRegex();
int eposOld = epos;
- if (rex.matchAt(wrap, epos) && !wrap.overRun)
+ if (rex.matchAtLike(wrap, epos) && !wrap.overRun)
{
while (pos < epos)
{
static Regex getvar = null;
- final static Regex getv()
+ private static Regex getv()
{
// Thanks to Michael Jimenez for pointing out the need
// to clone getvar rather than simply returning it.
"\\\\c([\u0000-\uFFFF])|" + // ref 8
"\\\\x([A-Fa-f0-9]{2})|" + // ref 9
"\\\\([\u0000-\uFFFF])" + // ref 10
- ")");
+ ")", "");
getvar.optimize();
return getvar;
}
head = add(head, new StringRule(s.substring(mt, mf)));
}
String var = null;
- if ((var = gv.stringMatched(1 + off)) != null
- || (var = gv.stringMatched(2 + off)) != null
- || (var = gv.stringMatched(5 + off)) != null)
+ if ((var = gv.stringMatchedI(1 + off)) != null
+ || (var = gv.stringMatchedI(2 + off)) != null
+ || (var = gv.stringMatchedI(5 + off)) != null)
{
int d = 0;
for (int i = 0; i < var.length(); i++)
head = new StringRule("" + (char) d);
}
}
- else if ((var = gv.stringMatched(10 + off)) != null)
+ else if ((var = gv.stringMatchedI(10 + off)) != null)
{
if ("QELlUu".indexOf(var) >= 0)
{
head = add(head, new StringRule(var));
}
}
- else if ((var = gv.stringMatched(3 + off)) != null
- || (var = gv.stringMatched(4 + off)) != null
- || (var = gv.stringMatched(6 + off)) != null)
+ else if ((var = gv.stringMatchedI(3 + off)) != null
+ || (var = gv.stringMatchedI(4 + off)) != null
+ || (var = gv.stringMatchedI(6 + off)) != null)
{
String arg = "";
int pc;
head = add(head, new StringRule("${" + var + "}"));
}
}
- else if ((var = gv.stringMatched(7 + off)) != null)
+ else if ((var = gv.stringMatchedI(7 + off)) != null)
{
char c = var.charAt(0);
if (c == 'n')
head = add(head, new StringRule("" + (char) 12));
}
}
- else if ((var = gv.stringMatched(8 + off)) != null)
+ else if ((var = gv.stringMatchedI(8 + off)) != null)
{
char c = var.charAt(0);
if (c < Ctrl.cmap.length)
}
head = add(head, new StringRule("" + c));
}
- else if ((var = gv.stringMatched(9 + off)) != null)
+ else if ((var = gv.stringMatchedI(9 + off)) != null)
{
int d = 16 * getHexDigit(var.charAt(0))
+ getHexDigit(var.charAt(1));
//
package com.stevesoft.pat;
-import jalview.util.MessageManager;
+import com.stevesoft.pat.MessageManager;
import com.stevesoft.pat.wrap.*;
{
throw new NullPointerException(MessageManager.getString("exception.replace_null_regex_pointer"));
}
- if (rh.me._search(s, start, end))
+ if (rh.me._searchLike(s, start, end))
{
int rmn = rh.me.matchedTo();
if (rh.me.charsMatched() == 0 && !isSpecial(rh.me.getReplaceRule()))
apply(rh.me);
if (!first)
{
- for (int i = rmn; !want_more_text && rh.me._search(s, i, end); i = rmn)
+ for (int i = rmn; !want_more_text && rh.me._searchLike(s, i, end); i = rmn)
{
rmn = rh.me.matchedTo();
if (rh.me.charsMatched() == 0)
int rmf = r.matchedFrom();
for (int ii = pos; ii < rmf; ii++)
{
- sb.append(src.charAt(ii));
+ sb.appendC(src.charAt(ii));
}
for (ReplaceRule x = rp; x != null; x = x.next)
int s_end = src.length();
for (int ii = pos; ii < s_end; ii++)
{
- sb.append(src.charAt(ii));
+ sb.appendC(src.charAt(ii));
}
src = null;
lastMatchedTo = pos;
static int mkmask(int c)
{
char x = (char) c;
- return ~(CaseMgr.toUpperCase(x) | CaseMgr.toLowerCase(x) | CaseMgr
- .toTitleCase(x));
+ return ~(CaseMgr.toUpperCaseC(x) | CaseMgr.toLowerCaseC(x) | CaseMgr
+ .toTitleCaseC(x));
}
String src;
if (0 == (s.charAt(i) & mask))
{
// if(m1||s.regionMatches(ign,i,src,0,src.length()) )
- if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))
+ if (m1 || CaseMgr.regionMatchesLike2(s, ign, i, src, 0, src.length()))
{
return i - offset;
}
if (c == s.charAt(i))
{
// if(m1||s.regionMatches(ign,i,src,0,src.length()) )
- if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))
+ if (m1 || CaseMgr.regionMatchesLike2(s, ign, i, src, 0, src.length()))
{
return i - offset;
}
return -1;
}
- static Skip findSkip(Regex r)
+ static Skip findSkipRegex(Regex r)
{
return findSkip(r.thePattern, r.ignoreCase, !r.dontMatchInQuotes);
}
if (0 == (s.charAt(i) & mask) && 0 == (s.charAt(i + 1) & mask1))
{
// if(m1||s.regionMatches(ign,i,src,0,src.length()) )
- if (m1 || CaseMgr.regionMatches(s, ign, i, src, 0, src.length()))
+ if (m1 || CaseMgr.regionMatchesLike2(s, ign, i, src, 0, src.length()))
{
return i - offset;
}
sm1 = src.length() - 1;
x = src.charAt(sm1);
- uc = CaseMgr.toUpperCase(x);
- lc = CaseMgr.toLowerCase(x);
- tc = CaseMgr.toTitleCase(x);
+ uc = CaseMgr.toUpperCaseC(x);
+ lc = CaseMgr.toLowerCaseC(x);
+ tc = CaseMgr.toTitleCaseC(x);
// We don't really want 65536 long arrays in skip[],
// so we mask of the higher bits. This can be combined
char x_ = src.charAt(k);
if (ign)
{
- char uc_ = CaseMgr.toUpperCase(x_);
- char lc_ = CaseMgr.toLowerCase(x_);
- char tc_ = CaseMgr.toTitleCase(x_);
+ char uc_ = CaseMgr.toUpperCaseC(x_);
+ char lc_ = CaseMgr.toLowerCaseC(x_);
+ char tc_ = CaseMgr.toTitleCaseC(x_);
skip[uc_ & (MAX_CHAR - 1)] = (char) (src.length() - k - 1);
skip[lc_ & (MAX_CHAR - 1)] = (char) (src.length() - k - 1);
skip[tc_ & (MAX_CHAR - 1)] = (char) (src.length() - k - 1);
// table look-up is expensive, avoid it if possible
if (anyc(s.charAt(k)))
{
- if (CaseMgr.regionMatches(src, ign, 0, s, k - sm1, sm1))
+ if (CaseMgr.regionMatches2(src, ign, 0, s, k - sm1, sm1))
{
return k - sm1 - offset;
}
// table look-up is expensive, avoid it if possible
if (anyc(s.charAt(k)))
{
- if (CaseMgr.regionMatches(src, ign, 0, s, k - sm1, sm1))
+ if (CaseMgr.regionMatches2(src, ign, 0, s, k - sm1, sm1))
{
return k - sm1 - offset;
}
if (x == s.charAt(k))
{
// if(src.regionMatches(0,s,k-sm1,sm1))
- if (CaseMgr.regionMatches(src, false, 0, s, k - sm1, sm1))
+ if (CaseMgr.regionMatches2(src, false, 0, s, k - sm1, sm1))
{
return k - sm1 - offset;
}
if (x == s.charAt(k))
{
// if(src.regionMatches(0,s,k-sm1,sm1))
- if (CaseMgr.regionMatches(src, false, 0, s, k - sm1, sm1))
+ if (CaseMgr.regionMatches2(src, false, 0, s, k - sm1, sm1))
{
return k - sm1 - offset;
}
return sbl.toString();
}
- public void append(char c)
+ public void appendC(char c)
{
switch (mode)
mode = altMode;
altMode = ' ';
case 'U':
- sbl.append(CaseMgr.toUpperCase(c));
+ sbl.appendC(CaseMgr.toUpperCaseC(c));
break;
case 'l':
mode = altMode;
altMode = ' ';
case 'L':
- sbl.append(CaseMgr.toLowerCase(c));
+ sbl.appendC(CaseMgr.toLowerCaseC(c));
break;
case 'Q':
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
}
else
{
- sbl.append('\\');
+ sbl.appendC('\\');
}
default:
- sbl.append(c);
+ sbl.appendC(c);
break;
}
}
{
for (int i = 0; i < s.length(); i++)
{
- append(s.charAt(i));
+ appendC(s.charAt(i));
}
}
//
package com.stevesoft.pat;
-import jalview.util.MessageManager;
-
-import com.stevesoft.pat.wrap.*;
+import com.stevesoft.pat.wrap.StringWrap;
/**
* Replacement rule used by the Transformer.
{
TransPat tp;
- Regex rp = new Regex();
+ Regex rp;
boolean auto_optimize;
/** Instantiate a new Transformer object. */
public Transformer(boolean auto)
{
+ rp = new Regex(null, "");
auto_optimize = auto;
tp = new TransPat();
rp.setReplaceRule(new TransRepRule(this));
--- /dev/null
+//
+// This software is now distributed according to
+// the Lesser Gnu Public License. Please see
+// http://www.gnu.org/copyleft/lesser.txt for
+// the details.
+// -- Happy Computing!
+//
+package com.stevesoft.pat;
+
+
+public abstract class Util
+{
+}
*
* By default, this method just returns end and thus does nothing.
*
- * @see com.stevesoft.pat.Regex#define(java.lang.String,java.lang.String,com.stevesoft.pat.Validator)
+ * @see com.stevesoft.pat.Regex#defineV(java.lang.String,java.lang.String,com.stevesoft.pat.Validator)
*/
public int validate(StringLike src, int start, int end)
{
{
c = ci;
char cu, cl, ct;
- cu = CaseMgr.toUpperCase(c);
- cl = CaseMgr.toLowerCase(c);
- ct = CaseMgr.toTitleCase(c);
+ cu = CaseMgr.toUpperCaseC(c);
+ cl = CaseMgr.toLowerCaseC(c);
+ ct = CaseMgr.toTitleCaseC(c);
if (c == cu)
{
altc = cl;
final public static String codify(String s, boolean keepbs)
{
- return codify(s, 0, s.length(), keepbs);
+ return codifyRange(s, 0, s.length(), keepbs);
}
- final public static String codify(String s, int i0, int iN, boolean keepbs)
+ final public static String codifyRange(String s, int i0, int iN, boolean keepbs)
{
StringBuffer sb = new StringBuffer();
boolean ucmode = false, lcmode = false, litmode = false;
final static char uc(char c)
{
- return CaseMgr.toUpperCase(c);
+ return CaseMgr.toUpperCaseC(c);
}
final static char lc(char c)
{
- return CaseMgr.toLowerCase(c);
+ return CaseMgr.toLowerCaseC(c);
}
final static boolean needbs(char c)
return null;
}
}
- Regex r = new Regex();
+ Regex r = new Regex(null, "");
try
{
String pat = s1.toString(), reprul = s2.toString();
{
StringBuffer sb = new StringBuffer();
- public void append(char c)
+ public void appendC(char c)
{
sb.append(c);
}
//
package com.stevesoft.pat.wrap;
-import jalview.util.MessageManager;
-
-import java.io.*;
-
-import com.stevesoft.pat.*;
/**
* Provides a wrapper for a RandomAccessFile so that it can be searched by
* Regex.
*/
-public class RandomAccessFileWrap implements StringLike
+public class RandomAccessFileWrap //implements StringLike
{
-
- long offset = 0;
-
- public void setOffset(long o)
- {
- offset = o;
- i0 = iend = 0;
- }
-
- public long getOffset()
- {
- return offset;
- }
-
- RandomAccessFile raf;
-
- int i0 = 0, iend = 0;
-
- byte[] buf = new byte[1024];
-
- public int getBufferSize()
- {
- return buf.length;
- }
-
- public void setBufferSize(int bs)
- {
- buf = new byte[bs];
- i0 = iend = 0;
- }
-
- public RandomAccessFileWrap(String file) throws IOException
- {
- this.raf = new RandomAccessFile(file, "r");
- }
-
- public RandomAccessFileWrap(RandomAccessFile raf)
- {
- this.raf = raf;
- }
-
- public char charAt(int i)
- {
- if (i >= i0 && i < iend)
- {
- return (char) buf[i - i0];
- }
-
- try
- {
- i0 = i - 5;
- // if(i0+offset<0) i0=(int)(-offset);
- if (i0 < 0)
- {
- i0 = 0;
- }
- raf.seek(i0 + offset);
- iend = i0 + raf.read(buf, 0, buf.length);
-
- if (i >= i0 && i < iend)
- {
- return (char) buf[i - i0];
- }
- } catch (Throwable t)
- {
- }
-
- throw new ArrayIndexOutOfBoundsException(MessageManager.formatMessage("exception.out_of_bounds_for_file", new String[]{
- Integer.valueOf(i).toString(),
- Integer.valueOf(i0).toString(),
- Integer.valueOf(iend).toString()
- }));
- }
-
- public String toString()
- {
- throw new Error(MessageManager.getString("error.not_implemented"));
- }
-
- public int length()
- {
- try
- {
- long len = raf.length() - offset;
- if (len > Integer.MAX_VALUE)
- {
- return Integer.MAX_VALUE;
- }
- return (int) len;
- } catch (IOException ioe)
- {
- return 0;
- }
- }
-
- public String substring(int i1, int i2)
- {
- StringBuffer sb = new StringBuffer();
- for (int i = i1; i < i2; i++)
- {
- sb.append(charAt(i));
- }
- return sb.toString();
- }
-
- public Object unwrap()
- {
- return raf;
- }
-
- public static void main(String[] files) throws IOException
- {
- for (int i = 0; i < files.length; i++)
- {
- RandomAccessFileWrap fw = new RandomAccessFileWrap(
- new RandomAccessFile(files[i], "r"));
- Regex r = new Regex("toString\\(\\) *(?@{})");
- r.setGFlag(true);
- r.optimize();
- System.out.print(files[i] + " ");
- int j = 0;
- do
- {
- if (r.searchFrom(fw, j))
- {
- System.out.println("Matched at index: " + r.matchedFrom());
- j = r.matchedTo();
- }
- else
- {
- System.out.println("not found");
- }
- System.out.println(r.stringMatched());
- } while (r.didMatch());
- }
- }
-
- public BasicStringBufferLike newStringBufferLike()
- {
- return new StringBufferWrap();
- }
-
- public int indexOf(char c)
- {
- for (int i = 0; i < length(); i++)
- {
- if (charAt(i) == c)
- {
- return i;
- }
- }
- return -1;
- }
+//
+// long offset = 0;
+//
+// public void setOffset(long o)
+// {
+// offset = o;
+// i0 = iend = 0;
+// }
+//
+// public long getOffset()
+// {
+// return offset;
+// }
+//
+// RandomAccessFile raf;
+//
+// int i0 = 0, iend = 0;
+//
+// byte[] buf = new byte[1024];
+//
+// public int getBufferSize()
+// {
+// return buf.length;
+// }
+//
+// public void setBufferSize(int bs)
+// {
+// buf = new byte[bs];
+// i0 = iend = 0;
+// }
+//
+// public RandomAccessFileWrap(String file) throws IOException
+// {
+// this.raf = new RandomAccessFile(file, "r");
+// }
+//
+// public RandomAccessFileWrap(RandomAccessFile raf)
+// {
+// this.raf = raf;
+// }
+//
+// public char charAt(int i)
+// {
+// if (i >= i0 && i < iend)
+// {
+// return (char) buf[i - i0];
+// }
+//
+// try
+// {
+// i0 = i - 5;
+// // if(i0+offset<0) i0=(int)(-offset);
+// if (i0 < 0)
+// {
+// i0 = 0;
+// }
+// raf.seek(i0 + offset);
+// iend = i0 + raf.read(buf, 0, buf.length);
+//
+// if (i >= i0 && i < iend)
+// {
+// return (char) buf[i - i0];
+// }
+// } catch (Throwable t)
+// {
+// }
+//
+// throw new ArrayIndexOutOfBoundsException(MessageManager.formatMessage("exception.out_of_bounds_for_file", new String[]{
+// Integer.valueOf(i).toString(),
+// Integer.valueOf(i0).toString(),
+// Integer.valueOf(iend).toString()
+// }));
+// }
+//
+// public String toString()
+// {
+// throw new Error(MessageManager.getString("error.not_implemented"));
+// }
+//
+// public int length()
+// {
+// try
+// {
+// long len = raf.length() - offset;
+// if (len > Integer.MAX_VALUE)
+// {
+// return Integer.MAX_VALUE;
+// }
+// return (int) len;
+// } catch (IOException ioe)
+// {
+// return 0;
+// }
+// }
+//
+// public String substring(int i1, int i2)
+// {
+// StringBuffer sb = new StringBuffer();
+// for (int i = i1; i < i2; i++)
+// {
+// sb.append(charAt(i));
+// }
+// return sb.toString();
+// }
+//
+// public Object unwrap()
+// {
+// return raf;
+// }
+//
+// public static void main(String[] files) throws IOException
+// {
+// for (int i = 0; i < files.length; i++)
+// {
+// RandomAccessFileWrap fw = new RandomAccessFileWrap(
+// new RandomAccessFile(files[i], "r"));
+// Regex r = new Regex("toString\\(\\) *(?@{})");
+// r.setGFlag(true);
+// r.optimize();
+// System.out.print(files[i] + " ");
+// int j = 0;
+// do
+// {
+// if (r.searchFromLike(fw, j))
+// {
+// System.out.println("Matched at index: " + r.matchedFrom());
+// j = r.matchedTo();
+// }
+// else
+// {
+// System.out.println("not found");
+// }
+// System.out.println(r.stringMatched());
+// } while (r.didMatch());
+// }
+// }
+//
+// public BasicStringBufferLike newStringBufferLike()
+// {
+// return new StringBufferWrap();
+// }
+//
+// public int indexOf(char c)
+// {
+// for (int i = 0; i < length(); i++)
+// {
+// if (charAt(i) == c)
+// {
+// return i;
+// }
+// }
+// return -1;
+// }
}
{
StringBuffer sb = new StringBuffer();
- public void append(char c)
+ public void appendC(char c)
{
sb.append(c);
}
this.w = w;
}
- public void append(char c)
+ public void appendC(char c)
{
try
{
--- /dev/null
+package fr.orsay.lri.varna.models.rna;
+
+public class RNA {
+
+ public int getSize() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ public String getStructDBN(boolean b) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
// { (char) c };
vl[c] = profile[0][c];
}
- QuickSort.sortFloat(vl, ca);
+ QuickSort.sortFloatChar(vl, ca);
for (int p = 0, c = ca.length - 1; profile[0][ca[c]] > 0; c--)
{
final char residue = ca[c];
ca[c] = (char) c;
vl[c] = profile[0][c];
}
- QuickSort.sortFloat(vl, ca);
+ QuickSort.sortFloatChar(vl, ca);
int nextArrayPos = 2;
int totalPercentage = 0;
int distinctValuesCount = 0;
{
codons[i] = (char) i;
}
- QuickSort.sortInt(sortedCounts, codons);
+ QuickSort.sortIntChar(sortedCounts, codons);
int totalPercentage = 0;
int distinctValuesCount = 0;
int j = 3;
int[] sortedCodonCounts = new int[codonCounts.length - 2];
System.arraycopy(codonCounts, 2, sortedCodonCounts, 0,
codonCounts.length - 2);
- QuickSort.sortInt(sortedCodonCounts, codons);
+ QuickSort.sortIntChar(sortedCodonCounts, codons);
int modalCodonEncoded = codons[codons.length - 1];
int modalCodonCount = sortedCodonCounts[codons.length - 1];
import java.util.List;
import java.util.Map;
+import javajs.J2SIgnoreImport;
+
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.SequenceI;
import jalview.renderer.AnnotationRenderer;
+@J2SIgnoreImport({jalview.renderer.AnnotationRenderer.class})
public class AlignmentAnnotationUtils
{
seqs[i] = align.getSequenceAt(i);
}
- QuickSort.sortFloat(scores, seqs);
+ QuickSort.sortFloatObject(scores, seqs);
setReverseOrder(align, seqs);
}
length[i] = (seqs[i].getEnd() - seqs[i].getStart());
}
- QuickSort.sortFloat(length, seqs);
+ QuickSort.sortFloatObject(length, seqs);
if (sortLengthAscending)
{
.floatValue();
}
- QuickSort.sortFloat(ids, alignment);
+ QuickSort.sortFloatObject(ids, alignment);
}
/**
import jalview.datamodel.SearchResults;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
+import jalview.jsdev.RegExp;
+import jalview.jsdev.api.RegExpInterface;
import jalview.util.Comparison;
import java.util.Vector;
-import com.stevesoft.pat.Regex;
+//import com.stevesoft.pat.Regex;
public class Finder
{
boolean findAll = false;
- Regex regex = null;
+ RegExpInterface regex = null;
/**
* hold's last-searched position between calles to find(false)
{
searchString = searchString.toUpperCase();
}
- regex = new Regex(searchString);
+ regex = RegExp.newRegex(searchString);
regex.setIgnoreCase(!caseSensitive);
searchResults = new SearchResults();
idMatch = new Vector();
/**
* @return the regex
*/
- public Regex getRegex()
+ public RegExpInterface getRegex()
{
return regex;
}
import java.util.Vector;
/**
- * DOCUMENT ME!
+ * NeighborJoining tree
*
* @author $author$
* @version $Revision$
*/
package jalview.analysis;
-import com.stevesoft.pat.Regex;
+//import com.stevesoft.pat.Regex;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceI;
+import jalview.jsdev.RegExp;
+import jalview.jsdev.api.RegExpInterface;
public class ParseProperties
{
* description for each numeric field in regex match
* @param regex
* Regular Expression string for passing to
- * <code>new com.stevesoft.patt.Regex(regex)</code>
+ * <code>new jalview.jsdevt.Regex(regex)</code>
* @param repeat
* true means the regex will be applied multiple times along the
* description string of each sequence
boolean repeat)
{
int count = 0;
- Regex pattern = new Regex(regex);
+ RegExpInterface pattern = RegExp.newRegex(regex);
if (pattern.numSubs() > ScoreNames.length)
{
// Check that we have enough labels and descriptions for any parsed
pos = pattern.matchedTo();
for (int cols = 0; cols < pattern.numSubs(); cols++)
{
- String sstring = pattern.stringMatched(cols + 1);
+ String sstring = pattern.stringMatchedI(cols + 1);
double score = Double.NaN;
try
{
private static HashSet<Character> closingParsSet = new HashSet<Character>(
Arrays.asList(closingPars));
- private static Hashtable<Character, Character> closingToOpening = new Hashtable<Character, Character>()
- // Initializing final data structure
- {
- private static final long serialVersionUID = 1L;
- {
+ private static Hashtable<Character, Character> closingToOpening = new Hashtable<Character, Character>();
+
+
+ static {
+ // Initializing final data structure
for (int i = 0; i < openingPars.length; i++)
{
// System.out.println(closingPars[i] + "->" + openingPars[i]);
- put(closingPars[i], openingPars[i]);
+ closingToOpening.put(closingPars[i], openingPars[i]);
}
- }
};
private static boolean isOpeningParenthesis(char c)
* ((c == 0) ? "" : "; ") + alphabet[c] + " " + ((int) tval) + "%"; } }
* else {
*/
- int[][] ca = new int[625][];
+ int[][] ca = javajs.util.AU.newInt2(625);// BH new int[625][];
float[] vl = new float[625];
int x = 0;
for (int c = 65; c < 90; c++)
x++;
}
}
- QuickSort.sortFloat(vl, ca);
+ QuickSort.sortFloatObject(vl, ca);
int p = 0;
/*
// TODO fix the object length, also do it in completeConsensus
// Object[] ca = new Object[625];
- int[][] ca = new int[625][];
+ int[][] ca = javajs.util.AU.newInt2(625);// BH new int[625][];
float[] vl = new float[625];
int x = 0;
for (int c = 65; c < 90; c++)
x++;
}
}
- QuickSort.sortFloat(vl, ca);
+ QuickSort.sortFloatObject(vl, ca);
int valuesCount = 0;
rtnval[1] = 0;
return result;
}
+ /**
+ * @j2sIgnore
+ *
+ * @param args
+ */
public static void main(String args[])
{
// Short test to see if checkBpType works
package jalview.api.analysis;
-import jalview.api.AlignViewportI;
import jalview.api.AlignmentViewPanel;
public interface ViewBasedAnalysisI
import jalview.util.MessageManager;
import jalview.util.UrlLink;
-import java.awt.CheckboxMenuItem;
-import java.awt.Frame;
-import java.awt.Menu;
-import java.awt.MenuItem;
+import awt2swing.CheckboxMenuItem;
+import awt2swing.Frame;
+import awt2swing.Menu;
+import awt2swing.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.util.TreeMap;
import java.util.Vector;
-public class APopupMenu extends java.awt.PopupMenu implements
+public class APopupMenu extends awt2swing.PopupMenu implements
ActionListener, ItemListener
{
private static final String ALL_ANNOTATIONS = "All";
}
}
- /**
+ /**
* Build menus for annotation types that may be shown or hidden, and for
* 'reference annotations' that may be added to the alignment.
*/
new AppletJmol(entry, new SequenceI[]
{ seq }, null, ap, AppletFormatAdapter.URL);
}
- else
- {
- new MCview.AppletPDBViewer(entry, new SequenceI[]
- { seq }, null, ap, AppletFormatAdapter.URL);
- }
+// else
+// {
+// new MCview.AppletPDBViewer(entry, new SequenceI[]
+// { seq }, null, ap, AppletFormatAdapter.URL);
+// }
}
else
import jalview.io.AppletFormatAdapter;
import jalview.io.FeaturesFile;
import jalview.io.NewickFile;
+import jalview.io.AlignFile;
import jalview.io.TCoffeeScoreFile;
+import jalview.jsdev.GenericFileAdapter;
import jalview.schemes.Blosum62ColourScheme;
import jalview.schemes.BuriedColourScheme;
import jalview.schemes.ClustalxColourScheme;
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
-import java.awt.Canvas;
-import java.awt.CheckboxMenuItem;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
-import java.awt.Frame;
import java.awt.Graphics;
-import java.awt.Label;
-import java.awt.Menu;
-import java.awt.MenuBar;
-import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.util.StringTokenizer;
import java.util.Vector;
-import org.jmol.viewer.Viewer;
+import awt2swing.Canvas;
+import awt2swing.CheckboxMenuItem;
+import awt2swing.Frame;
+import awt2swing.Label;
+import awt2swing.Menu;
+import awt2swing.MenuBar;
+import awt2swing.MenuItem;
+
+//import org.jmol.viewer.Viewer;
public class AlignFrame extends EmbmenuFrame implements ActionListener,
ItemListener, KeyListener, AlignViewControllerGuiI
}
@Override
- public void paint(Graphics g)
+ public void paintComponent(Graphics g)
{
g.setColor(Color.white);
g.fillRect(0, 0, getSize().width, getSize().height);
FontMetrics fm = g.getFontMetrics();
int fh = fm.getHeight();
int y = 5, x = 7;
- g.setColor(Color.black);
+ g.setColor(Color.black);
// TODO: update this text for each release or centrally store it for
// lite and application
g.setFont(new Font("Helvetica", Font.BOLD, 14));
this.add(statusBar, BorderLayout.SOUTH);
}
- public void setStatus(String string)
+ public void setStatus(String string)
{
statusBar.setText(string);
};
theApplet.validate();
}
- /**
- * create a new binding between structures in an existing jmol viewer instance
- * and an alignpanel with sequences that have existing PDBFile entries. Note,
- * this does not open a new Jmol window, or modify the display of the
- * structures in the original jmol window. Note This method doesn't work
- * without an additional javascript library to exchange messages between the
- * distinct applets. See http://issues.jalview.org/browse/JAL-621
- *
- * @param viewer
- * JmolViewer instance
- * @param sequenceIds
- * - sequence Ids to search for associations
- */
- public SequenceStructureBinding addStructureViewInstance(
- Object jmolviewer, String[] sequenceIds)
- {
- Viewer viewer = null;
- try
- {
- viewer = (Viewer) jmolviewer;
- } catch (ClassCastException ex)
- {
- System.err.println("Unsupported viewer object :"
- + jmolviewer.getClass());
- }
- if (viewer == null)
- {
- System.err.println("Can't use this object as a structure viewer:"
- + jmolviewer.getClass());
- return null;
- }
- SequenceI[] seqs = null;
- if (sequenceIds == null || sequenceIds.length == 0)
- {
- seqs = viewport.getAlignment().getSequencesArray();
- }
- else
- {
- Vector sqi = new Vector();
- AlignmentI al = viewport.getAlignment();
- for (int sid = 0; sid < sequenceIds.length; sid++)
- {
- SequenceI sq = al.findName(sequenceIds[sid]);
- if (sq != null)
- {
- sqi.addElement(sq);
- }
- }
- if (sqi.size() > 0)
- {
- seqs = new SequenceI[sqi.size()];
- for (int sid = 0, sSize = sqi.size(); sid < sSize; sid++)
- {
- seqs[sid] = (SequenceI) sqi.elementAt(sid);
- }
- }
- else
- {
- return null;
- }
- }
- AAStructureBindingModel jmv = null;
- // TODO: search for a jmv that involves viewer
- if (jmv == null)
- { // create a new viewer/jalview binding.
- jmv = new ExtJmol(viewer, alignPanel, new SequenceI[][]
- { seqs });
- }
- return jmv;
-
- }
+ /**
+ * create a new binding between structures in an existing jmol viewer instance
+ * and an alignpanel with sequences that have existing PDBFile entries. Note,
+ * this does not open a new Jmol window, or modify the display of the
+ * structures in the original jmol window. Note This method doesn't work
+ * without an additional javascript library to exchange messages between the
+ * distinct applets. See http://issues.jalview.org/browse/JAL-621
+ *
+ * @param viewer
+ * JmolViewer instance
+ * @param sequenceIds
+ * - sequence Ids to search for associations
+ */
+ public SequenceStructureBinding addStructureViewInstance(Object jmolviewer,
+ String[] sequenceIds) {
+ return null;
+ // Viewer viewer = null;
+ // try
+ // {
+ // viewer = (Viewer) jmolviewer;
+ // } catch (ClassCastException ex)
+ // {
+ // System.err.println("Unsupported viewer object :"
+ // + jmolviewer.getClass());
+ // }
+ // if (viewer == null)
+ // {
+ // System.err.println("Can't use this object as a structure viewer:"
+ // + jmolviewer.getClass());
+ // return null;
+ // }
+ // SequenceI[] seqs = null;
+ // if (sequenceIds == null || sequenceIds.length == 0)
+ // {
+ // seqs = viewport.getAlignment().getSequencesArray();
+ // }
+ // else
+ // {
+ // Vector sqi = new Vector();
+ // AlignmentI al = viewport.getAlignment();
+ // for (int sid = 0; sid < sequenceIds.length; sid++)
+ // {
+ // SequenceI sq = al.findName(sequenceIds[sid]);
+ // if (sq != null)
+ // {
+ // sqi.addElement(sq);
+ // }
+ // }
+ // if (sqi.size() > 0)
+ // {
+ // seqs = new SequenceI[sqi.size()];
+ // for (int sid = 0, sSize = sqi.size(); sid < sSize; sid++)
+ // {
+ // seqs[sid] = (SequenceI) sqi.elementAt(sid);
+ // }
+ // }
+ // else
+ // {
+ // return null;
+ // }
+ // }
+ // AAStructureBindingModel jmv = null;
+ // // TODO: search for a jmv that involves viewer
+ // if (jmv == null)
+ // { // create a new viewer/jalview binding.
+ // jmv = new ExtJmol(viewer, alignPanel, new SequenceI[][]
+ // { seqs });
+ // }
+ // return jmv;
+ //
+ }
/**
* bind a pdb file to a sequence in the current view
}
- public void newStructureView(JalviewLite applet, PDBEntry pdb,
- SequenceI[] seqs, String[] chains, String protocol)
- {
- // Scrub any null sequences from the array
- Object[] sqch = cleanSeqChainArrays(seqs, chains);
- seqs = (SequenceI[]) sqch[0];
- chains = (String[]) sqch[1];
- if (seqs == null || seqs.length == 0)
- {
- System.err
- .println("JalviewLite.AlignFrame:newStructureView: No sequence to bind structure to.");
- }
- if (protocol == null || protocol.trim().length() == 0
- || protocol.equals("null"))
- {
- protocol = (String) pdb.getProperty().get("protocol");
- if (protocol == null)
- {
- System.err.println("Couldn't work out protocol to open structure: "
- + pdb.getId());
- return;
- }
- }
- if (applet.useXtrnalSviewer)
- {
- // register the association(s) and quit, don't create any windows.
- if (StructureSelectionManager.getStructureSelectionManager(applet)
- .setMapping(seqs, chains, pdb.getFile(), protocol) == null)
- {
- System.err.println("Failed to map " + pdb.getFile() + " ("
- + protocol + ") to any sequences");
- }
- return;
- }
- if (applet.isAlignPdbStructures() && applet.jmolAvailable)
- {
- // can only do alignments with Jmol
- // find the last jmol window assigned to this alignment
- AppletJmol ajm = null, tajm;
- Vector jmols = applet
-.getAppletWindow(AppletJmol.class);
- for (int i = 0, iSize = jmols.size(); i < iSize; i++)
- {
- tajm = (AppletJmol) jmols.elementAt(i);
- if (tajm.ap.alignFrame == this)
- {
- ajm = tajm;
- break;
- }
- }
- if (ajm != null)
- {
- System.err
- .println("Incremental adding and aligning structure to existing Jmol view not yet implemented.");
- // try and add the pdb structure
- // ajm.addS
- ajm = null;
- }
- }
- // otherwise, create a new window
- if (applet.jmolAvailable)
- {
- new AppletJmol(pdb, seqs, chains, alignPanel, protocol);
- applet.lastFrameX += 40;
- applet.lastFrameY += 40;
- }
- else
- {
- new MCview.AppletPDBViewer(pdb, seqs, chains, alignPanel, protocol);
- }
-
- }
+ public void newStructureView(JalviewLite applet, PDBEntry pdb,
+ SequenceI[] seqs, String[] chains, String protocol) {
+ // Scrub any null sequences from the array
+ Object[] sqch = cleanSeqChainArrays(seqs, chains);
+ seqs = (SequenceI[]) sqch[0];
+ chains = (String[]) sqch[1];
+ if (seqs == null || seqs.length == 0) {
+ System.err
+ .println("JalviewLite.AlignFrame:newStructureView: No sequence to bind structure to.");
+ }
+ if (protocol == null || protocol.trim().length() == 0
+ || protocol.equals("null")) {
+ protocol = (String) pdb.getProperty().get("protocol");
+ if (protocol == null) {
+ System.err.println("Couldn't work out protocol to open structure: "
+ + pdb.getId());
+ return;
+ }
+ }
+ if (applet.useXtrnalSviewer) {
+ // register the association(s) and quit, don't create any windows.
+ if (StructureSelectionManager.getStructureSelectionManager(applet)
+ .setMapping(seqs, chains, pdb.getFile(), protocol) == null) {
+ System.err.println("Failed to map " + pdb.getFile() + " (" + protocol
+ + ") to any sequences");
+ }
+ return;
+ }
+ if (applet.isAlignPdbStructures() && applet.jmolAvailable) {
+ // can only do alignments with Jmol
+ // find the last jmol window assigned to this alignment
+ AppletJmol ajm = null, tajm;
+ Vector jmols = applet.getAppletWindow(AppletJmol.class);
+ for (int i = 0, iSize = jmols.size(); i < iSize; i++) {
+ tajm = (AppletJmol) jmols.elementAt(i);
+ if (tajm.ap.alignFrame == this) {
+ ajm = tajm;
+ break;
+ }
+ }
+ if (ajm != null) {
+ System.err
+ .println("Incremental adding and aligning structure to existing Jmol view not yet implemented.");
+ // try and add the pdb structure
+ // ajm.addS
+ ajm = null;
+ }
+ }
+ // otherwise, create a new window
+ // if (applet.jmolAvailable)
+ // {
+ new AppletJmol(pdb, seqs, chains, alignPanel, protocol);
+ applet.lastFrameX += 40;
+ applet.lastFrameY += 40;
+ // }
+ // else
+ // {
+ // new MCview.AppletPDBViewer(pdb, seqs, chains, alignPanel, protocol);
+ // }
+
+ }
public void alignedStructureView(JalviewLite applet, PDBEntry[] pdb,
SequenceI[][] seqs, String[][] chains, String[] protocols)
/**
* Load the (T-Coffee) score file from the specified url
*
- * @param source
+ * @param inFile
* File/URL/T-COFFEE score file contents
* @throws IOException
* @return true if alignment was annotated with data from source
*/
- public boolean loadScoreFile(String source) throws IOException
+ public boolean loadScoreFile(String inFile) throws IOException
{
- TCoffeeScoreFile file = new TCoffeeScoreFile(source,
- AppletFormatAdapter.checkProtocol(source));
+ TCoffeeScoreFile file = (TCoffeeScoreFile) GenericFileAdapter.getFile("TCoffeeScoreFile", inFile,
+ AppletFormatAdapter.checkProtocol(inFile));
if (!file.isValid())
{
// TODO: raise dialog for gui
System.err.println("Problems parsing T-Coffee scores: "
+ file.getWarningMessage());
- System.err.println("Origin was:\n" + source);
+ System.err.println("Origin was:\n" + inFile);
return false;
}
return sq;
}
- java.awt.Frame nullFrame;
+ awt2swing.Frame nullFrame;
protected FeatureSettings featureSettings = null;
font = f;
if (nullFrame == null)
{
- nullFrame = new java.awt.Frame();
+ nullFrame = new awt2swing.Frame();
nullFrame.addNotify();
+ nullFrame.setFont(font);
}
java.awt.FontMetrics fm = nullFrame.getGraphics().getFontMetrics(font);
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.Graphics;
-import java.awt.Panel;
-import java.awt.Scrollbar;
+import awt2swing.Panel;
+import awt2swing.Scrollbar;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.ComponentAdapter;
{
av.nullFrame = new Frame();
av.nullFrame.addNotify();
+ av.nullFrame.setFont(av.font);
}
-
Graphics g = av.nullFrame.getGraphics();
-
FontMetrics fm = g.getFontMetrics(av.font);
AlignmentI al = av.getAlignment();
public void adjustmentValueChanged(AdjustmentEvent evt)
{
+ if (annotationPanel == null)
+ return; // BH in process of loading
int oldX = av.getStartRes();
int oldY = av.getStartSeq();
paint(g);
}
- public void paint(Graphics g)
+ public void paintComponent(Graphics g)
{
invalidate();
Dimension d = idPanel.idCanvas.getSize();
import jalview.util.MessageManager;
import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Checkbox;
-import java.awt.Choice;
+import awt2swing.Button;
+import awt2swing.Checkbox;
+import awt2swing.Choice;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
-import java.awt.Frame;
-import java.awt.Panel;
-import java.awt.Scrollbar;
-import java.awt.TextField;
+import awt2swing.Frame;
+import awt2swing.Panel;
+import awt2swing.Scrollbar;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.BorderLayout;
import java.awt.CardLayout;
-import java.awt.Checkbox;
-import java.awt.Choice;
+import awt2swing.Checkbox;
+import awt2swing.Choice;
import java.awt.Color;
import java.awt.Dimension;
-import java.awt.Frame;
-import java.awt.Panel;
-import java.awt.TextField;
+import awt2swing.Frame;
+import awt2swing.Panel;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
public void itemStateChanged(ItemEvent e)
{
aColChooser.setCurrentFutherActionPanel(this);
- if (furtherAction.getSelectedItem().equalsIgnoreCase("Select"))
+ if (furtherAction.getSelectedItem().toString().equalsIgnoreCase("Select")) // BH added "toString()"
{
setActionOption(ACTION_OPTION_SELECT);
updateView();
public void textValueChanged(TextEvent e)
{
searchStringAction();
-
}
});
import jalview.util.MessageManager;
import jalview.util.ParseHtmlBodyAndLinks;
-import java.awt.Checkbox;
-import java.awt.CheckboxMenuItem;
+import awt2swing.Checkbox;
+import awt2swing.CheckboxMenuItem;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.MenuItem;
-import java.awt.Panel;
-import java.awt.PopupMenu;
+import awt2swing.MenuItem;
+import awt2swing.Panel;
+import awt2swing.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
paint(g);
}
- public void paint(Graphics g)
+ public void paintComponent(Graphics g)
{
int w = getSize().width;
int h = getSize().height;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.MenuItem;
-import java.awt.Panel;
-import java.awt.PopupMenu;
+import awt2swing.MenuItem;
+import awt2swing.Panel;
+import awt2swing.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
}
@Override
- public void paint(Graphics g)
+ public void paintComponent(Graphics g)
{
Dimension d = getSize();
imgWidth = d.width;
import jalview.schemes.AnnotationColourGradient;
import jalview.util.MessageManager;
-import java.awt.Button;
-import java.awt.Checkbox;
-import java.awt.Choice;
-import java.awt.Frame;
-import java.awt.Panel;
-import java.awt.Scrollbar;
-import java.awt.TextField;
+import awt2swing.Button;
+import awt2swing.Checkbox;
+import awt2swing.Choice;
+import awt2swing.Frame;
+import awt2swing.Panel;
+import awt2swing.Scrollbar;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.util.Vector;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
-import java.awt.CheckboxMenuItem;
+import awt2swing.CheckboxMenuItem;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.Graphics;
-import java.awt.Menu;
-import java.awt.MenuBar;
-import java.awt.MenuItem;
-import java.awt.Panel;
-import java.awt.TextArea;
-import java.awt.TextField;
+import awt2swing.Menu;
+import awt2swing.MenuBar;
+import awt2swing.MenuItem;
+import awt2swing.Panel;
+import awt2swing.TextArea;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.util.List;
import java.util.Vector;
-public class AppletJmol extends EmbmenuFrame implements
-// StructureListener,
- KeyListener, ActionListener, ItemListener
+public class AppletJmol //extends EmbmenuFrame implements
+// KeyListener, ActionListener, ItemListener
{
- Menu fileMenu = new Menu(MessageManager.getString("action.file"));
-
- Menu viewMenu = new Menu(MessageManager.getString("action.view"));
-
- Menu coloursMenu = new Menu(MessageManager.getString("action.colour"));
-
- Menu chainMenu = new Menu(MessageManager.getString("action.show_chain"));
-
- Menu helpMenu = new Menu(MessageManager.getString("action.help"));
-
- MenuItem mappingMenuItem = new MenuItem(
- MessageManager.getString("label.view_mapping"));
-
- CheckboxMenuItem seqColour = new CheckboxMenuItem(
- MessageManager.getString("action.by_sequence"), true);
-
- CheckboxMenuItem jmolColour = new CheckboxMenuItem(
- MessageManager.getString("action.using_jmol"), false);
-
- MenuItem chain = new MenuItem(MessageManager.getString("action.by_chain"));
-
- MenuItem charge = new MenuItem(
- MessageManager.getString("label.charge_cysteine"));
-
- MenuItem zappo = new MenuItem(MessageManager.getString("label.zappo"));
-
- MenuItem taylor = new MenuItem(MessageManager.getString("label.taylor"));
-
- MenuItem hydro = new MenuItem(
- MessageManager.getString("label.hydrophobicity"));
-
- MenuItem helix = new MenuItem(
- MessageManager.getString("label.helix_propensity"));
-
- MenuItem strand = new MenuItem(
- MessageManager.getString("label.strand_propensity"));
-
- MenuItem turn = new MenuItem(
- MessageManager.getString("label.turn_propensity"));
-
- MenuItem buried = new MenuItem(
- MessageManager.getString("label.buried_index"));
-
- MenuItem purinepyrimidine = new MenuItem(
- MessageManager.getString("label.purine_pyrimidine"));
-
- MenuItem user = new MenuItem(
- MessageManager.getString("label.user_defined_colours"));
-
- MenuItem jmolHelp = new MenuItem(
- MessageManager.getString("label.jmol_help"));
Panel scriptWindow;
AppletJmolBinding jmb;
- /**
- * datasource protocol for access to PDBEntry
- */
- String protocol = null;
-
- /**
- * Load a bunch of pdb entries associated with sequences in the alignment and
- * display them - aligning them if necessary.
- *
- * @param pdbentries
- * each pdb file (at least one needed)
- * @param boundseqs
- * each set of sequences for each pdb file (must match number of pdb
- * files)
- * @param boundchains
- * the target pdb chain corresponding with each sequence associated
- * with each pdb file (may be null at any level)
- * @param align
- * true/false
- * @param ap
- * associated alignment
- * @param protocol
- * how to get pdb data
- */
- public AppletJmol(PDBEntry[] pdbentries, SequenceI[][] boundseqs,
- String[][] boundchains, boolean align, AlignmentPanel ap,
- String protocol)
- {
- throw new Error(MessageManager.getString("error.not_yet_implemented"));
- }
-
- public AppletJmol(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
- AlignmentPanel ap, String protocol)
- {
- this.ap = ap;
- jmb = new AppletJmolBinding(this, ap.getStructureSelectionManager(),
- new PDBEntry[]
- { pdbentry }, new SequenceI[][]
- { seq }, new String[][]
- { chains }, protocol);
- jmb.setColourBySequence(true);
- if (pdbentry.getId() == null || pdbentry.getId().length() < 1)
- {
- if (protocol.equals(AppletFormatAdapter.PASTE))
- {
- pdbentry.setId("PASTED PDB"
- + (chains == null ? "_" : chains.toString()));
- }
- else
- {
- pdbentry.setId(pdbentry.getFile());
- }
- }
-
- if (JalviewLite.debug)
- {
- System.err
- .println("AppletJmol: PDB ID is '" + pdbentry.getId() + "'");
- }
-
- String alreadyMapped = StructureSelectionManager
- .getStructureSelectionManager(ap.av.applet)
- .alreadyMappedToFile(pdbentry.getId());
- MCview.PDBfile reader = null;
- if (alreadyMapped != null)
- {
- reader = StructureSelectionManager.getStructureSelectionManager(
- ap.av.applet).setMapping(seq, chains, pdbentry.getFile(),
- protocol);
- // PROMPT USER HERE TO ADD TO NEW OR EXISTING VIEW?
- // FOR NOW, LETS JUST OPEN A NEW WINDOW
- }
- MenuBar menuBar = new MenuBar();
- menuBar.add(fileMenu);
- fileMenu.add(mappingMenuItem);
- menuBar.add(viewMenu);
- mappingMenuItem.addActionListener(this);
- viewMenu.add(chainMenu);
- menuBar.add(coloursMenu);
- menuBar.add(helpMenu);
-
- charge.addActionListener(this);
- hydro.addActionListener(this);
- chain.addActionListener(this);
- seqColour.addItemListener(this);
- jmolColour.addItemListener(this);
- zappo.addActionListener(this);
- taylor.addActionListener(this);
- helix.addActionListener(this);
- strand.addActionListener(this);
- turn.addActionListener(this);
- buried.addActionListener(this);
- purinepyrimidine.addActionListener(this);
- user.addActionListener(this);
-
- jmolHelp.addActionListener(this);
-
- coloursMenu.add(seqColour);
- coloursMenu.add(chain);
- coloursMenu.add(charge);
- coloursMenu.add(zappo);
- coloursMenu.add(taylor);
- coloursMenu.add(hydro);
- coloursMenu.add(helix);
- coloursMenu.add(strand);
- coloursMenu.add(turn);
- coloursMenu.add(buried);
- coloursMenu.add(purinepyrimidine);
- coloursMenu.add(user);
- coloursMenu.add(jmolColour);
- helpMenu.add(jmolHelp);
- this.setLayout(new BorderLayout());
-
- setMenuBar(menuBar);
-
- renderPanel = new RenderPanel();
- embedMenuIfNeeded(renderPanel);
- this.add(renderPanel, BorderLayout.CENTER);
- scriptWindow = new Panel();
- scriptWindow.setVisible(false);
- // this.add(scriptWindow, BorderLayout.SOUTH);
-
- try
- {
- jmb.allocateViewer(renderPanel, true, ap.av.applet.getName()
- + "_jmol_", ap.av.applet.getDocumentBase(),
- ap.av.applet.getCodeBase(), "-applet", scriptWindow, null);
- } catch (Exception e)
- {
- System.err
- .println("Couldn't create a jmol viewer. Args to allocate viewer were:\nDocumentBase="
- + ap.av.applet.getDocumentBase()
- + "\nCodebase="
- + ap.av.applet.getCodeBase());
- e.printStackTrace();
- dispose();
- return;
- }
- // jmb.newJmolPopup(true, "Jmol", true);
-
- this.addWindowListener(new WindowAdapter()
- {
- public void windowClosing(WindowEvent evt)
- {
- closeViewer();
- }
- });
- if (pdbentry.getProperty() == null)
- {
- pdbentry.setProperty(new Hashtable());
- pdbentry.getProperty().put("protocol", protocol);
- }
- if (pdbentry.getFile() != null)
- {
- // import structure data from pdbentry.getFile based on given protocol
- if (protocol.equals(AppletFormatAdapter.PASTE))
- {
- // TODO: JAL-623 : correctly record file contents for matching up later
- // pdbentry.getProperty().put("pdbfilehash",""+pdbentry.getFile().hashCode());
- loadInline(pdbentry.getFile());
- }
- else if (protocol.equals(AppletFormatAdapter.FILE)
- || protocol.equals(AppletFormatAdapter.URL))
- {
- jmb.viewer.openFile(pdbentry.getFile());
- }
- else
- {
- // probably CLASSLOADER based datasource..
- // Try and get a reader on the datasource, and pass that to Jmol
- try
- {
- java.io.Reader freader = null;
- if (reader != null)
- {
- if (JalviewLite.debug)
- {
- System.err
- .println("AppletJmol:Trying to reuse existing PDBfile IO parser.");
- }
- // re-use the one we opened earlier
- freader = reader.getReader();
- }
- if (freader == null)
- {
- if (JalviewLite.debug)
- {
- System.err
- .println("AppletJmol:Creating new PDBfile IO parser.");
- }
- FileParse fp = new FileParse(pdbentry.getFile(), protocol);
- fp.mark();
- // reader = new MCview.PDBfile(fp);
- // could set ID, etc.
- // if (!reader.isValid())
- // {
- // throw new Exception("Invalid datasource.
- // "+reader.getWarningMessage());
- // }
- // fp.reset();
- freader = fp.getReader();
- }
- if (freader == null)
- {
- throw new Exception(MessageManager.getString("exception.invalid_datasource_couldnt_obtain_reader"));
- }
- jmb.viewer.openReader(pdbentry.getFile(), pdbentry.getId(),
- freader);
- } catch (Exception e)
- {
- // give up!
- System.err.println("Couldn't access pdbentry id="
- + pdbentry.getId() + " and file=" + pdbentry.getFile()
- + " using protocol=" + protocol);
- e.printStackTrace();
- }
- }
- }
-
- JalviewLite.addFrame(this, jmb.getViewerTitle(), 400, 400);
- }
-
- public void loadInline(String string)
- {
- loadedInline = true;
- jmb.loadInline(string);
- }
-
- void setChainMenuItems(Vector<String> chains)
- {
- chainMenu.removeAll();
-
- MenuItem menuItem = new MenuItem(MessageManager.getString("label.all"));
- menuItem.addActionListener(this);
-
- chainMenu.add(menuItem);
-
- CheckboxMenuItem menuItemCB;
- for (String ch : chains)
- {
- menuItemCB = new CheckboxMenuItem(ch, true);
- menuItemCB.addItemListener(this);
- chainMenu.add(menuItemCB);
- }
- }
-
- boolean allChainsSelected = false;
-
- void centerViewer()
- {
- Vector<String> toshow = new Vector<String>();
- for (int i = 0; i < chainMenu.getItemCount(); i++)
- {
- if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
- {
- CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);
- if (item.getState())
- {
- toshow.addElement(item.getLabel());
- }
- }
- }
- jmb.centerViewer(toshow);
- }
-
- void closeViewer()
- {
- jmb.closeViewer();
- jmb = null;
- this.setVisible(false);
- }
-
- public void actionPerformed(ActionEvent evt)
- {
- if (evt.getSource() == mappingMenuItem)
- {
- CutAndPasteTransfer cap = new CutAndPasteTransfer(
- false, null);
- Frame frame = new Frame();
- frame.add(cap);
-
- StringBuffer sb = new StringBuffer();
- try
- {
- cap.setText(jmb.printMappings());
- } catch (OutOfMemoryError ex)
- {
- frame.dispose();
- System.err
- .println("Out of memory when trying to create dialog box with sequence-structure mapping.");
- return;
- }
- JalviewLite.addFrame(frame,
- MessageManager.getString("label.pdb_sequence_mapping"), 550,
- 600);
- }
- else if (evt.getSource() == charge)
- {
- setEnabled(charge);
- jmb.colourByCharge();
- }
-
- else if (evt.getSource() == chain)
- {
- setEnabled(chain);
- jmb.colourByChain();
- }
- else if (evt.getSource() == zappo)
- {
- setEnabled(zappo);
- jmb.setJalviewColourScheme(new ZappoColourScheme());
- }
- else if (evt.getSource() == taylor)
- {
- setEnabled(taylor);
- jmb.setJalviewColourScheme(new TaylorColourScheme());
- }
- else if (evt.getSource() == hydro)
- {
- setEnabled(hydro);
- jmb.setJalviewColourScheme(new HydrophobicColourScheme());
- }
- else if (evt.getSource() == helix)
- {
- setEnabled(helix);
- jmb.setJalviewColourScheme(new HelixColourScheme());
- }
- else if (evt.getSource() == strand)
- {
- setEnabled(strand);
- jmb.setJalviewColourScheme(new StrandColourScheme());
- }
- else if (evt.getSource() == turn)
- {
- setEnabled(turn);
- jmb.setJalviewColourScheme(new TurnColourScheme());
- }
- else if (evt.getSource() == buried)
- {
- setEnabled(buried);
- jmb.setJalviewColourScheme(new BuriedColourScheme());
- }
- else if (evt.getSource() == purinepyrimidine)
- {
- jmb.setJalviewColourScheme(new PurinePyrimidineColourScheme());
- }
- else if (evt.getSource() == user)
- {
- setEnabled(user);
- new UserDefinedColours(this);
- }
- else if (evt.getSource() == jmolHelp)
- {
- try
- {
- ap.av.applet.getAppletContext().showDocument(
- new java.net.URL(
- "http://jmol.sourceforge.net/docs/JmolUserGuide/"),
- "jmolHelp");
- } catch (java.net.MalformedURLException ex)
- {
- }
- }
- else
- {
- allChainsSelected = true;
- for (int i = 0; i < chainMenu.getItemCount(); i++)
- {
- if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
- {
- ((CheckboxMenuItem) chainMenu.getItem(i)).setState(true);
- }
- }
-
- centerViewer();
- allChainsSelected = false;
- }
- }
-
- /**
- * tick or untick the seqColour menu entry or jmoColour entry depending upon
- * if it was selected or not.
- *
- * @param itm
- */
- private void setEnabled(MenuItem itm)
- {
- jmolColour.setState(itm == jmolColour);
- seqColour.setState(itm == seqColour);
- jmb.setColourBySequence(itm == seqColour);
- }
-
- public void itemStateChanged(ItemEvent evt)
- {
- if (evt.getSource() == jmolColour)
- {
- setEnabled(jmolColour);
- jmb.setColourBySequence(false);
- }
- else if (evt.getSource() == seqColour)
- {
- setEnabled(seqColour);
- jmb.colourBySequence(ap);
- }
- else if (!allChainsSelected)
- {
- centerViewer();
- }
- }
-
- public void keyPressed(KeyEvent evt)
- {
- if (evt.getKeyCode() == KeyEvent.VK_ENTER && scriptWindow.isVisible())
- {
- jmb.eval(inputLine.getText());
- history.append("\n$ " + inputLine.getText());
- inputLine.setText("");
- }
-
- }
-
- public void keyTyped(KeyEvent evt)
- {
- }
-
- public void keyReleased(KeyEvent evt)
- {
- }
-
- public void updateColours(Object source)
- {
- AlignmentPanel panel = (AlignmentPanel) source;
- jmb.colourBySequence(panel);
- }
-
- public void updateTitleAndMenus()
- {
- if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0)
- {
- repaint();
- return;
- }
- setChainMenuItems(jmb.chainNames);
- jmb.colourBySequence(ap);
-
- setTitle(jmb.getViewerTitle());
- }
-
- public void showUrl(String url)
- {
- try
- {
- ap.av.applet.getAppletContext().showDocument(new java.net.URL(url),
- "jmolOutput");
- } catch (java.net.MalformedURLException ex)
- {
- }
- }
-
- Panel splitPane = null;
-
- public void showConsole(boolean showConsole)
- {
- if (showConsole)
- {
- remove(renderPanel);
- splitPane = new Panel();
-
- splitPane.setLayout(new java.awt.GridLayout(2, 1));
- splitPane.add(renderPanel);
- splitPane.add(scriptWindow);
- scriptWindow.setVisible(true);
- this.add(splitPane, BorderLayout.CENTER);
- splitPane.setVisible(true);
- splitPane.validate();
- }
- else
- {
- scriptWindow.setVisible(false);
- remove(splitPane);
- add(renderPanel, BorderLayout.CENTER);
- splitPane = null;
- }
- validate();
- }
-
- public float[][] functionXY(String functionName, int x, int y)
- {
- return null;
- }
-
- // /End JmolStatusListener
- // /////////////////////////////
+ public AppletJmol(PDBEntry entry, SequenceI[] sequenceIs, Object object,
+ AlignmentPanel ap2, String uRL) {
+ // TODO Auto-generated constructor stub
+ }
+
+
+ public void setJalviewColourScheme(UserColourScheme ucs) {
+ // TODO Auto-generated method stub
+
+ }
+
+
+ // Menu fileMenu = new Menu(MessageManager.getString("action.file"));
+//
+// Menu viewMenu = new Menu(MessageManager.getString("action.view"));
+//
+// Menu coloursMenu = new Menu(MessageManager.getString("action.colour"));
+//
+// Menu chainMenu = new Menu(MessageManager.getString("action.show_chain"));
+//
+// Menu helpMenu = new Menu(MessageManager.getString("action.help"));
+//
+// MenuItem mappingMenuItem = new MenuItem(
+// MessageManager.getString("label.view_mapping"));
+//
+// CheckboxMenuItem seqColour = new CheckboxMenuItem(
+// MessageManager.getString("action.by_sequence"), true);
+//
+// CheckboxMenuItem jmolColour = new CheckboxMenuItem(
+// MessageManager.getString("action.using_jmol"), false);
+//
+// MenuItem chain = new MenuItem(MessageManager.getString("action.by_chain"));
+//
+// MenuItem charge = new MenuItem(
+// MessageManager.getString("label.charge_cysteine"));
+//
+// MenuItem zappo = new MenuItem(MessageManager.getString("label.zappo"));
+//
+// MenuItem taylor = new MenuItem(MessageManager.getString("label.taylor"));
+//
+// MenuItem hydro = new MenuItem(
+// MessageManager.getString("label.hydrophobicity"));
+//
+// MenuItem helix = new MenuItem(
+// MessageManager.getString("label.helix_propensity"));
+//
+// MenuItem strand = new MenuItem(
+// MessageManager.getString("label.strand_propensity"));
+//
+// MenuItem turn = new MenuItem(
+// MessageManager.getString("label.turn_propensity"));
+//
+// MenuItem buried = new MenuItem(
+// MessageManager.getString("label.buried_index"));
+//
+// MenuItem purinepyrimidine = new MenuItem(
+// MessageManager.getString("label.purine_pyrimidine"));
+//
+// MenuItem user = new MenuItem(
+// MessageManager.getString("label.user_defined_colours"));
+//
+// MenuItem jmolHelp = new MenuItem(
+// MessageManager.getString("label.jmol_help"));
+//
+// /**
+// * datasource protocol for access to PDBEntry
+// */
+// String protocol = null;
+//
+// /**
+// * Load a bunch of pdb entries associated with sequences in the alignment and
+// * display them - aligning them if necessary.
+// *
+// * @param pdbentries
+// * each pdb file (at least one needed)
+// * @param boundseqs
+// * each set of sequences for each pdb file (must match number of pdb
+// * files)
+// * @param boundchains
+// * the target pdb chain corresponding with each sequence associated
+// * with each pdb file (may be null at any level)
+// * @param align
+// * true/false
+// * @param ap
+// * associated alignment
+// * @param protocol
+// * how to get pdb data
+// */
+// public AppletJmol(PDBEntry[] pdbentries, SequenceI[][] boundseqs,
+// String[][] boundchains, boolean align, AlignmentPanel ap,
+// String protocol)
+// {
+// throw new Error(MessageManager.getString("error.not_yet_implemented"));
+// }
+//
+// public AppletJmol(PDBEntry pdbentry, SequenceI[] seq, String[] chains,
+// AlignmentPanel ap, String protocol)
+// {
+// this.ap = ap;
+// jmb = new AppletJmolBinding(this, ap.getStructureSelectionManager(),
+// new PDBEntry[]
+// { pdbentry }, new SequenceI[][]
+// { seq }, new String[][]
+// { chains }, protocol);
+// jmb.setColourBySequence(true);
+// if (pdbentry.getId() == null || pdbentry.getId().length() < 1)
+// {
+// if (protocol.equals(AppletFormatAdapter.PASTE))
+// {
+// pdbentry.setId("PASTED PDB"
+// + (chains == null ? "_" : chains.toString()));
+// }
+// else
+// {
+// pdbentry.setId(pdbentry.getFile());
+// }
+// }
+//
+// if (JalviewLite.debug)
+// {
+// System.err
+// .println("AppletJmol: PDB ID is '" + pdbentry.getId() + "'");
+// }
+//
+// String alreadyMapped = StructureSelectionManager
+// .getStructureSelectionManager(ap.av.applet)
+// .alreadyMappedToFile(pdbentry.getId());
+// MCview.PDBfile reader = null;
+// if (alreadyMapped != null)
+// {
+// reader = StructureSelectionManager.getStructureSelectionManager(
+// ap.av.applet).setMapping(seq, chains, pdbentry.getFile(),
+// protocol);
+// // PROMPT USER HERE TO ADD TO NEW OR EXISTING VIEW?
+// // FOR NOW, LETS JUST OPEN A NEW WINDOW
+// }
+// MenuBar menuBar = new MenuBar();
+// menuBar.add(fileMenu);
+// fileMenu.add(mappingMenuItem);
+// menuBar.add(viewMenu);
+// mappingMenuItem.addActionListener(this);
+// viewMenu.add(chainMenu);
+// menuBar.add(coloursMenu);
+// menuBar.add(helpMenu);
+//
+// charge.addActionListener(this);
+// hydro.addActionListener(this);
+// chain.addActionListener(this);
+// seqColour.addItemListener(this);
+// jmolColour.addItemListener(this);
+// zappo.addActionListener(this);
+// taylor.addActionListener(this);
+// helix.addActionListener(this);
+// strand.addActionListener(this);
+// turn.addActionListener(this);
+// buried.addActionListener(this);
+// purinepyrimidine.addActionListener(this);
+// user.addActionListener(this);
+//
+// jmolHelp.addActionListener(this);
+//
+// coloursMenu.add(seqColour);
+// coloursMenu.add(chain);
+// coloursMenu.add(charge);
+// coloursMenu.add(zappo);
+// coloursMenu.add(taylor);
+// coloursMenu.add(hydro);
+// coloursMenu.add(helix);
+// coloursMenu.add(strand);
+// coloursMenu.add(turn);
+// coloursMenu.add(buried);
+// coloursMenu.add(purinepyrimidine);
+// coloursMenu.add(user);
+// coloursMenu.add(jmolColour);
+// helpMenu.add(jmolHelp);
+// this.setLayout(new BorderLayout());
+//
+// setMenuBar(menuBar);
+//
+// renderPanel = new RenderPanel();
+// embedMenuIfNeeded(renderPanel);
+// this.add(renderPanel, BorderLayout.CENTER);
+// scriptWindow = new Panel();
+// scriptWindow.setVisible(false);
+// // this.add(scriptWindow, BorderLayout.SOUTH);
+//
+// try
+// {
+// jmb.allocateViewer(renderPanel, true, ap.av.applet.getName()
+// + "_jmol_", ap.av.applet.getDocumentBase(),
+// ap.av.applet.getCodeBase(), "-applet", scriptWindow, null);
+// } catch (Exception e)
+// {
+// System.err
+// .println("Couldn't create a jmol viewer. Args to allocate viewer were:\nDocumentBase="
+// + ap.av.applet.getDocumentBase()
+// + "\nCodebase="
+// + ap.av.applet.getCodeBase());
+// e.printStackTrace();
+// dispose();
+// return;
+// }
+// // jmb.newJmolPopup(true, "Jmol", true);
+//
+// this.addWindowListener(new WindowAdapter()
+// {
+// public void windowClosing(WindowEvent evt)
+// {
+// closeViewer();
+// }
+// });
+// if (pdbentry.getProperty() == null)
+// {
+// pdbentry.setProperty(new Hashtable());
+// pdbentry.getProperty().put("protocol", protocol);
+// }
+// if (pdbentry.getFile() != null)
+// {
+// // import structure data from pdbentry.getFile based on given protocol
+// if (protocol.equals(AppletFormatAdapter.PASTE))
+// {
+// // TODO: JAL-623 : correctly record file contents for matching up later
+// // pdbentry.getProperty().put("pdbfilehash",""+pdbentry.getFile().hashCode());
+// loadInline(pdbentry.getFile());
+// }
+// else if (protocol.equals(AppletFormatAdapter.FILE)
+// || protocol.equals(AppletFormatAdapter.URL))
+// {
+// jmb.viewer.openFile(pdbentry.getFile());
+// }
+// else
+// {
+// // probably CLASSLOADER based datasource..
+// // Try and get a reader on the datasource, and pass that to Jmol
+// try
+// {
+// java.io.Reader freader = null;
+// if (reader != null)
+// {
+// if (JalviewLite.debug)
+// {
+// System.err
+// .println("AppletJmol:Trying to reuse existing PDBfile IO parser.");
+// }
+// // re-use the one we opened earlier
+// freader = reader.getReader();
+// }
+// if (freader == null)
+// {
+// if (JalviewLite.debug)
+// {
+// System.err
+// .println("AppletJmol:Creating new PDBfile IO parser.");
+// }
+// FileParse fp = new FileParse(pdbentry.getFile(), protocol);
+// fp.mark();
+// // reader = new MCview.PDBfile(fp);
+// // could set ID, etc.
+// // if (!reader.isValid())
+// // {
+// // throw new Exception("Invalid datasource.
+// // "+reader.getWarningMessage());
+// // }
+// // fp.reset();
+// freader = fp.getReader();
+// }
+// if (freader == null)
+// {
+// throw new Exception(MessageManager.getString("exception.invalid_datasource_couldnt_obtain_reader"));
+// }
+// jmb.viewer.openReader(pdbentry.getFile(), pdbentry.getId(),
+// freader);
+// } catch (Exception e)
+// {
+// // give up!
+// System.err.println("Couldn't access pdbentry id="
+// + pdbentry.getId() + " and file=" + pdbentry.getFile()
+// + " using protocol=" + protocol);
+// e.printStackTrace();
+// }
+// }
+// }
+//
+// JalviewLite.addFrame(this, jmb.getViewerTitle(), 400, 400);
+// }
+//
+// public void loadInline(String string)
+// {
+// loadedInline = true;
+// jmb.loadInline(string);
+// }
+//
+// void setChainMenuItems(Vector<String> chains)
+// {
+// chainMenu.removeAll();
+//
+// MenuItem menuItem = new MenuItem(MessageManager.getString("label.all"));
+// menuItem.addActionListener(this);
+//
+// chainMenu.add(menuItem);
+//
+// CheckboxMenuItem menuItemCB;
+// for (String ch : chains)
+// {
+// menuItemCB = new CheckboxMenuItem(ch, true);
+// menuItemCB.addItemListener(this);
+// chainMenu.add(menuItemCB);
+// }
+// }
+//
+// boolean allChainsSelected = false;
+//
+// void centerViewer()
+// {
+// Vector<String> toshow = new Vector<String>();
+// for (int i = 0; i < chainMenu.getItemCount(); i++)
+// {
+// if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
+// {
+// CheckboxMenuItem item = (CheckboxMenuItem) chainMenu.getItem(i);
+// if (item.getState())
+// {
+// toshow.addElement(item.getLabel());
+// }
+// }
+// }
+// jmb.centerViewer(toshow);
+// }
+//
+// void closeViewer()
+// {
+// jmb.closeViewer();
+// jmb = null;
+// this.setVisible(false);
+// }
+//
+// public void actionPerformed(ActionEvent evt)
+// {
+// if (evt.getSource() == mappingMenuItem)
+// {
+// CutAndPasteTransfer cap = new CutAndPasteTransfer(
+// false, null);
+// Frame frame = new Frame();
+// frame.add(cap);
+//
+// StringBuffer sb = new StringBuffer();
+// try
+// {
+// cap.setText(jmb.printMappings());
+// } catch (OutOfMemoryError ex)
+// {
+// frame.dispose();
+// System.err
+// .println("Out of memory when trying to create dialog box with sequence-structure mapping.");
+// return;
+// }
+// JalviewLite.addFrame(frame,
+// MessageManager.getString("label.pdb_sequence_mapping"), 550,
+// 600);
+// }
+// else if (evt.getSource() == charge)
+// {
+// setEnabled(charge);
+// jmb.colourByCharge();
+// }
+//
+// else if (evt.getSource() == chain)
+// {
+// setEnabled(chain);
+// jmb.colourByChain();
+// }
+// else if (evt.getSource() == zappo)
+// {
+// setEnabled(zappo);
+// jmb.setJalviewColourScheme(new ZappoColourScheme());
+// }
+// else if (evt.getSource() == taylor)
+// {
+// setEnabled(taylor);
+// jmb.setJalviewColourScheme(new TaylorColourScheme());
+// }
+// else if (evt.getSource() == hydro)
+// {
+// setEnabled(hydro);
+// jmb.setJalviewColourScheme(new HydrophobicColourScheme());
+// }
+// else if (evt.getSource() == helix)
+// {
+// setEnabled(helix);
+// jmb.setJalviewColourScheme(new HelixColourScheme());
+// }
+// else if (evt.getSource() == strand)
+// {
+// setEnabled(strand);
+// jmb.setJalviewColourScheme(new StrandColourScheme());
+// }
+// else if (evt.getSource() == turn)
+// {
+// setEnabled(turn);
+// jmb.setJalviewColourScheme(new TurnColourScheme());
+// }
+// else if (evt.getSource() == buried)
+// {
+// setEnabled(buried);
+// jmb.setJalviewColourScheme(new BuriedColourScheme());
+// }
+// else if (evt.getSource() == purinepyrimidine)
+// {
+// jmb.setJalviewColourScheme(new PurinePyrimidineColourScheme());
+// }
+// else if (evt.getSource() == user)
+// {
+// setEnabled(user);
+// new UserDefinedColours(this);
+// }
+// else if (evt.getSource() == jmolHelp)
+// {
+// try
+// {
+// ap.av.applet.getAppletContext().showDocument(
+// new java.net.URL(
+// "http://jmol.sourceforge.net/docs/JmolUserGuide/"),
+// "jmolHelp");
+// } catch (java.net.MalformedURLException ex)
+// {
+// }
+// }
+// else
+// {
+// allChainsSelected = true;
+// for (int i = 0; i < chainMenu.getItemCount(); i++)
+// {
+// if (chainMenu.getItem(i) instanceof CheckboxMenuItem)
+// {
+// ((CheckboxMenuItem) chainMenu.getItem(i)).setState(true);
+// }
+// }
+//
+// centerViewer();
+// allChainsSelected = false;
+// }
+// }
+//
+// /**
+// * tick or untick the seqColour menu entry or jmoColour entry depending upon
+// * if it was selected or not.
+// *
+// * @param itm
+// */
+// private void setEnabled(Object itm) // BH MenuItem not superclass of CheckBoxMenuItem
+// {
+// jmolColour.setState(itm == jmolColour);
+// seqColour.setState(itm == seqColour);
+// jmb.setColourBySequence(itm == seqColour);
+// }
+//
+// public void itemStateChanged(ItemEvent evt)
+// {
+// if (evt.getSource() == jmolColour)
+// {
+// setEnabled(jmolColour);
+// jmb.setColourBySequence(false);
+// }
+// else if (evt.getSource() == seqColour)
+// {
+// setEnabled(seqColour);
+// jmb.colourBySequence(ap);
+// }
+// else if (!allChainsSelected)
+// {
+// centerViewer();
+// }
+// }
+//
+// public void keyPressed(KeyEvent evt)
+// {
+// if (evt.getKeyCode() == KeyEvent.VK_ENTER && scriptWindow.isVisible())
+// {
+// jmb.eval(inputLine.getText());
+// history.append("\n$ " + inputLine.getText());
+// inputLine.setText("");
+// }
+//
+// }
+//
+// public void keyTyped(KeyEvent evt)
+// {
+// }
+//
+// public void keyReleased(KeyEvent evt)
+// {
+// }
+//
+// public void updateColours(Object source)
+// {
+// AlignmentPanel panel = (AlignmentPanel) source;
+// jmb.colourBySequence(panel);
+// }
+//
+// public void updateTitleAndMenus()
+// {
+// if (jmb.fileLoadingError != null && jmb.fileLoadingError.length() > 0)
+// {
+// repaint();
+// return;
+// }
+// setChainMenuItems(jmb.chainNames);
+// jmb.colourBySequence(ap);
+//
+// setTitle(jmb.getViewerTitle());
+// }
+//
+// public void showUrl(String url)
+// {
+// try
+// {
+// ap.av.applet.getAppletContext().showDocument(new java.net.URL(url),
+// "jmolOutput");
+// } catch (java.net.MalformedURLException ex)
+// {
+// }
+// }
+//
+// Panel splitPane = null;
+//
+// public void showConsole(boolean showConsole)
+// {
+// if (showConsole)
+// {
+// remove(renderPanel);
+// splitPane = new Panel();
+//
+// splitPane.setLayout(new java.awt.GridLayout(2, 1));
+// splitPane.add(renderPanel);
+// splitPane.add(scriptWindow);
+// scriptWindow.setVisible(true);
+// this.add(splitPane, BorderLayout.CENTER);
+// splitPane.setVisible(true);
+// splitPane.validate();
+// }
+// else
+// {
+// scriptWindow.setVisible(false);
+// remove(splitPane);
+// add(renderPanel, BorderLayout.CENTER);
+// splitPane = null;
+// }
+// validate();
+// }
+//
+// public float[][] functionXY(String functionName, int x, int y)
+// {
+// return null;
+// }
+//
+// // /End JmolStatusListener
+// // /////////////////////////////
+//
class RenderPanel extends Panel
{
Dimension currentSize = new Dimension();
paint(g);
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
currentSize = this.getSize();
- if (jmb.viewer == null)
- {
- g.setColor(Color.black);
- g.fillRect(0, 0, currentSize.width, currentSize.height);
- g.setColor(Color.white);
- g.setFont(new Font("Verdana", Font.BOLD, 14));
- g.drawString(MessageManager.getString("label.retrieving_pdb_data"),
- 20, currentSize.height / 2);
- }
- else
- {
- jmb.viewer.renderScreenImage(g, currentSize.width,
- currentSize.height);
- }
- }
- }
-
- /*
- * @Override public Color getColour(int atomIndex, int pdbResNum, String
- * chain, String pdbId) { return jmb.getColour(atomIndex, pdbResNum, chain,
- * pdbId); }
- *
- * @Override public String[] getPdbFile() { return jmb.getPdbFile(); }
- *
- * @Override public void highlightAtom(int atomIndex, int pdbResNum, String
- * chain, String pdbId) { jmb.highlightAtom(atomIndex, pdbResNum, chain,
- * pdbId);
- *
- * }
- *
- * @Override public void mouseOverStructure(int atomIndex, String strInfo) {
- * jmb.mouseOverStructure(atomIndex, strInfo);
- *
- * }
- */
- public void setJalviewColourScheme(UserColourScheme ucs)
- {
- jmb.setJalviewColourScheme(ucs);
- }
-
- public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment)
- {
- for (int i = 0; i < _aps.size(); i++)
- {
- if (_aps.get(i).av.getAlignment() == alignment)
- {
- return (_aps.get(i));
- }
+// if (jmb.viewer == null)
+// {
+// g.setColor(Color.black);
+// g.fillRect(0, 0, currentSize.width, currentSize.height);
+// g.setColor(Color.white);
+// g.setFont(new Font("Verdana", Font.BOLD, 14));
+// g.drawString(MessageManager.getString("label.retrieving_pdb_data"),
+// 20, currentSize.height / 2);
+// }
+// else
+// {
+// jmb.viewer.renderScreenImage(g, currentSize.width,
+// currentSize.height);
+// }
}
- return ap;
}
+//
+// /*
+// * @Override public Color getColour(int atomIndex, int pdbResNum, String
+// * chain, String pdbId) { return jmb.getColour(atomIndex, pdbResNum, chain,
+// * pdbId); }
+// *
+// * @Override public String[] getPdbFile() { return jmb.getPdbFile(); }
+// *
+// * @Override public void highlightAtom(int atomIndex, int pdbResNum, String
+// * chain, String pdbId) { jmb.highlightAtom(atomIndex, pdbResNum, chain,
+// * pdbId);
+// *
+// * }
+// *
+// * @Override public void mouseOverStructure(int atomIndex, String strInfo) {
+// * jmb.mouseOverStructure(atomIndex, strInfo);
+// *
+// * }
+// */
+// public void setJalviewColourScheme(UserColourScheme ucs)
+// {
+// jmb.setJalviewColourScheme(ucs);
+// }
+//
+// public AlignmentPanel getAlignmentPanelFor(AlignmentI alignment)
+// {
+// for (int i = 0; i < _aps.size(); i++)
+// {
+// if (_aps.get(i).av.getAlignment() == alignment)
+// {
+// return (_aps.get(i));
+// }
+// }
+// return ap;
+// }
}
import jalview.api.AlignmentViewPanel;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
-import jalview.ext.jmol.JalviewJmolBinding;
+//import jalview.ext.jmol.JalviewJmolBinding;
import jalview.structure.StructureSelectionManager;
import java.awt.Container;
import javajs.awt.Dimension;
-import org.jmol.api.JmolAppConsoleInterface;
-import org.jmol.console.AppletConsole;
-import org.jmol.java.BS;
+//import org.jmol.api.JmolAppConsoleInterface;
+//import org.jmol.console.AppletConsole;
+//import org.jmol.java.BS;
-class AppletJmolBinding extends JalviewJmolBinding
+class AppletJmolBinding //extends JalviewJmolBinding
{
- /**
- * Window that contains the bound Jmol instance
- */
- private AppletJmol appletJmolBinding;
-
- public AppletJmolBinding(AppletJmol appletJmol,
- StructureSelectionManager sSm, PDBEntry[] pdbentry,
- SequenceI[][] seq, String[][] chains, String protocol)
- {
- super(sSm, pdbentry, seq, chains, protocol);
- appletJmolBinding = appletJmol;
- }
-
- @Override
- public jalview.api.FeatureRenderer getFeatureRenderer(
- AlignmentViewPanel alignment)
- {
- AlignmentPanel ap = (AlignmentPanel) alignment;
- if (appletJmolBinding.ap.av.isShowSequenceFeatures())
- {
- if (appletJmolBinding.fr == null)
- {
- appletJmolBinding.fr = new jalview.appletgui.FeatureRenderer(
- appletJmolBinding.ap.av);
- }
-
- appletJmolBinding.fr
- .transferSettings(appletJmolBinding.ap.seqPanel.seqCanvas
- .getFeatureRenderer());
- }
-
- return appletJmolBinding.fr;
- }
-
- @Override
- public jalview.api.SequenceRenderer getSequenceRenderer(
- AlignmentViewPanel alignment)
- {
- return new SequenceRenderer(((AlignmentPanel) alignment).av);
- }
-
- @Override
- public void sendConsoleEcho(String strEcho)
- {
- if (appletJmolBinding.scriptWindow == null)
- {
- appletJmolBinding.showConsole(true);
- }
-
- appletJmolBinding.history.append("\n" + strEcho);
- }
-
- @Override
- public void sendConsoleMessage(String strStatus)
- {
- if (appletJmolBinding.history != null && strStatus != null
- && !strStatus.equals("Script completed"))
- {
- appletJmolBinding.history.append("\n" + strStatus);
- }
- }
-
- @Override
- public void showUrl(String url, String target)
- {
- appletJmolBinding.ap.alignFrame.showURL(url, target);
-
- }
-
- @Override
- public void refreshGUI()
- {
- appletJmolBinding.updateTitleAndMenus();
- }
-
- public void updateColours(Object source)
- {
- AlignmentPanel ap = (AlignmentPanel) source;
- colourBySequence(ap);
- }
-
- public void showUrl(String url)
- {
- try
- {
- appletJmolBinding.ap.av.applet.getAppletContext().showDocument(
- new java.net.URL(url), "jmol");
- } catch (java.net.MalformedURLException ex)
- {
- }
- }
-
- public void newJmolPopup(boolean translateLocale, String menuName,
- boolean asPopup)
- {
- // jmolpopup = new JmolAwtPopup(); // is this used?
- // jmolpopup.jpiInitialize((viewer), menuName);
- }
-
- @Override
- public void notifyScriptTermination(String strStatus, int msWalltime)
- {
- // do nothing.
- }
-
- public void selectionChanged(BS arg0)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public void refreshPdbEntries()
- {
- // noop
- }
-
- @Override
- public void showConsole(boolean show)
- {
- appletJmolBinding.showConsole(show);
- }
-
- @Override
- protected JmolAppConsoleInterface createJmolConsole(
- Container consolePanel, String buttonsToShow)
- {
- JmolAppConsoleInterface appc = new AppletConsole();
- appc.start(viewer);
- return appc;
- }
-
- @Override
- protected void releaseUIResources()
- {
- appletJmolBinding = null;
- closeConsole();
- }
-
- @Override
- public void releaseReferences(Object svl)
- {
- }
-
- @Override
- public Dimension resizeInnerPanel(String data)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- public Map<String, Object> getJSpecViewProperty(String arg0)
- {
- // TODO Auto-generated method stub
- return null;
- }
+// /**
+// * Window that contains the bound Jmol instance
+// */
+// private AppletJmol appletJmolBinding;
+//
+// public AppletJmolBinding(AppletJmol appletJmol,
+// StructureSelectionManager sSm, PDBEntry[] pdbentry,
+// SequenceI[][] seq, String[][] chains, String protocol)
+// {
+// super(sSm, pdbentry, seq, chains, protocol);
+// appletJmolBinding = appletJmol;
+// }
+//
+// @Override
+// public jalview.api.FeatureRenderer getFeatureRenderer(
+// AlignmentViewPanel alignment)
+// {
+// AlignmentPanel ap = (AlignmentPanel) alignment;
+// if (appletJmolBinding.ap.av.isShowSequenceFeatures())
+// {
+// if (appletJmolBinding.fr == null)
+// {
+// appletJmolBinding.fr = new jalview.appletgui.FeatureRenderer(
+// appletJmolBinding.ap.av);
+// }
+//
+// appletJmolBinding.fr
+// .transferSettings(appletJmolBinding.ap.seqPanel.seqCanvas
+// .getFeatureRenderer());
+// }
+//
+// return appletJmolBinding.fr;
+// }
+//
+// @Override
+// public jalview.api.SequenceRenderer getSequenceRenderer(
+// AlignmentViewPanel alignment)
+// {
+// return new SequenceRenderer(((AlignmentPanel) alignment).av);
+// }
+//
+// @Override
+// public void sendConsoleEcho(String strEcho)
+// {
+// if (appletJmolBinding.scriptWindow == null)
+// {
+// appletJmolBinding.showConsole(true);
+// }
+//
+// appletJmolBinding.history.append("\n" + strEcho);
+// }
+//
+// @Override
+// public void sendConsoleMessage(String strStatus)
+// {
+// if (appletJmolBinding.history != null && strStatus != null
+// && !strStatus.equals("Script completed"))
+// {
+// appletJmolBinding.history.append("\n" + strStatus);
+// }
+// }
+//
+// @Override
+// public void showUrl(String url, String target)
+// {
+// appletJmolBinding.ap.alignFrame.showURL(url, target);
+//
+// }
+//
+// @Override
+// public void refreshGUI()
+// {
+// appletJmolBinding.updateTitleAndMenus();
+// }
+//
+// public void updateColours(Object source)
+// {
+// AlignmentPanel ap = (AlignmentPanel) source;
+// colourBySequence(ap);
+// }
+//
+// public void showUrl(String url)
+// {
+// try
+// {
+// appletJmolBinding.ap.av.applet.getAppletContext().showDocument(
+// new java.net.URL(url), "jmol");
+// } catch (java.net.MalformedURLException ex)
+// {
+// }
+// }
+//
+// public void newJmolPopup(boolean translateLocale, String menuName,
+// boolean asPopup)
+// {
+// // jmolpopup = new JmolAwtPopup(); // is this used?
+// // jmolpopup.jpiInitialize((viewer), menuName);
+// }
+//
+// @Override
+// public void notifyScriptTermination(String strStatus, int msWalltime)
+// {
+// // do nothing.
+// }
+//
+// public void selectionChanged(BS arg0)
+// {
+// // TODO Auto-generated method stub
+//
+// }
+//
+// @Override
+// public void refreshPdbEntries()
+// {
+// // noop
+// }
+//
+// @Override
+// public void showConsole(boolean show)
+// {
+// appletJmolBinding.showConsole(show);
+// }
+//
+// @Override
+// protected JmolAppConsoleInterface createJmolConsole(
+// Container consolePanel, String buttonsToShow)
+// {
+// JmolAppConsoleInterface appc = new AppletConsole();
+// appc.start(viewer);
+// return appc;
+// }
+//
+// @Override
+// protected void releaseUIResources()
+// {
+// appletJmolBinding = null;
+// closeConsole();
+// }
+//
+// @Override
+// public void releaseReferences(Object svl)
+// {
+// }
+//
+// @Override
+// public Dimension resizeInnerPanel(String data)
+// {
+// // TODO Auto-generated method stub
+// return null;
+// }
+//
+// @Override
+// public Map<String, Object> getJSpecViewProperty(String arg0)
+// {
+// // TODO Auto-generated method stub
+// return null;
+// }
}
import jalview.io.FileParse;
import jalview.io.IdentifyFile;
import jalview.io.NewickFile;
+import jalview.io.AlignFile;
import jalview.io.TCoffeeScoreFile;
+import jalview.jsdev.GenericFileAdapter;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.TCoffeeColourScheme;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
-import java.awt.Button;
+import awt2swing.Button;
import java.awt.Dialog;
import java.awt.Font;
-import java.awt.Frame;
-import java.awt.Label;
-import java.awt.Panel;
-import java.awt.TextArea;
+import awt2swing.Frame;
+import awt2swing.Label;
+import awt2swing.Panel;
+import awt2swing.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
TCoffeeScoreFile tcf = null;
try
{
- tcf = new TCoffeeScoreFile(textarea.getText(),
+ tcf = (TCoffeeScoreFile) GenericFileAdapter.getFile("TCoffeeScoreFile", textarea.getText(),
AppletFormatAdapter.PASTE);
if (tcf.isValid())
{
PDBEntry pdb = new PDBEntry();
pdb.setFile(text);
- if (alignFrame.alignPanel.av.applet.jmolAvailable)
- {
+// if (alignFrame.alignPanel.av.applet.jmolAvailable)
+// {
new AppletJmol(pdb, new SequenceI[]
{ seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE);
- }
- else
- {
- new MCview.AppletPDBViewer(pdb, new SequenceI[]
- { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE);
- }
+// }
+// else
+// {
+// new MCview.AppletPDBViewer(pdb, new SequenceI[]
+// { seq }, null, alignFrame.alignPanel, AppletFormatAdapter.PASTE);
+// }
}
protected void cancel()
import java.awt.BorderLayout;
import java.awt.Font;
-import java.awt.Frame;
-import java.awt.Label;
-import java.awt.Panel;
-import java.awt.TextField;
+import awt2swing.Frame;
+import awt2swing.Label;
+import awt2swing.Panel;
+import awt2swing.TextField;
public class EditNameDialog extends JVDialog
{
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.HeadlessException;
-import java.awt.Label;
-import java.awt.Menu;
-import java.awt.MenuBar;
-import java.awt.Panel;
-import java.awt.PopupMenu;
+import awt2swing.Label;
+import awt2swing.Menu;
+import awt2swing.MenuBar;
+import awt2swing.MenuItem;
+import awt2swing.Panel;
+import awt2swing.PopupMenu;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.HashMap;
import java.util.Map;
+import javax.swing.JMenuItem;
+
/**
* This class implements a pattern for embedding toolbars as a panel with popups
* for situations where the system menu bar is either invisible or
*/
protected boolean embedMenuIfNeeded(Panel tobeAdjusted)
{
- MenuBar topMenuBar = getMenuBar();
+ MenuBar topMenuBar = (MenuBar) getJMenuBar();
if (topMenuBar == null)
{
return false;
{
// Build the embedded menu panel, allowing override with system font
embeddedMenu = makeEmbeddedPopupMenu(topMenuBar, true, false);
- setMenuBar(null);
+ unsetMenuBar();
// add the components to the Panel area.
add(embeddedMenu, BorderLayout.NORTH);
tobeAdjusted.setSize(getSize().width,
Panel embeddedMenu,
MouseListener clickHandler)
{
+
if (overrideFonts)
{
Font mbf = menuBar.getFont();
// loop thru
for (int mbi = 0, nMbi = menuBar.getMenuCount(); mbi < nMbi; mbi++)
{
- Menu mi = menuBar.getMenu(mbi);
+ Menu mi = (Menu) menuBar.getMenu(mbi);
Label elab = new Label(mi.getLabel());
elab.setFont(font);
// add the menu entries
int m, mSize = mi.getItemCount();
for (m = 0; m < mSize; m++)
{
- popup.add(mi.getItem(m));
+ // BH slight difference in Swing -- no actual item separator, just null
+ if (mi.getItem(m) == null)
+ popup.addSeparator();
+ else
+ popup.add(mi.getItem(m));
mSize--;
m--;
}
import jalview.api.SequenceRenderer;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
-import jalview.ext.jmol.JalviewJmolBinding;
+//import jalview.ext.jmol.JalviewJmolBinding;
+import jalview.structure.AtomSpec;
+import jalview.structure.StructureSelectionManager;
+import jalview.structures.models.AAStructureBindingModel;
import java.awt.Container;
import java.util.ArrayList;
import java.util.Map;
import java.util.Vector;
-import org.jmol.api.JmolAppConsoleInterface;
-import org.jmol.java.BS;
+//import org.jmol.api.JmolAppConsoleInterface;
+//import org.jmol.java.BS;
import org.jmol.viewer.Viewer;
/**
* @author JimP
*
*/
-public class ExtJmol extends JalviewJmolBinding
+public class ExtJmol extends AAStructureBindingModel //extends JalviewJmolBinding
{
- private AlignmentPanel ap;
-
- protected ExtJmol(jalview.appletgui.AlignFrame alframe,
- PDBEntry[] pdbentry, SequenceI[][] seq, String[][] chains,
- String protocol)
- {
- super(alframe.alignPanel.getStructureSelectionManager(), pdbentry, seq,
- chains, protocol);
- }
-
- public ExtJmol(Viewer viewer, AlignmentPanel alignPanel,
- SequenceI[][] seqs)
- {
- super(alignPanel.getStructureSelectionManager(), seqs, viewer);
- ap = alignPanel;
- notifyFileLoaded(null, null, null, null, 0);
- }
-
- public void updateColours(Object source)
- {
-
- // TODO Auto-generated method stub
-
- }
-
- public void showUrl(String arg0)
- {
- showUrl(arg0, "jmol");
- }
-
- @Override
- public FeatureRenderer getFeatureRenderer(AlignmentViewPanel alignment)
- {
- AlignmentPanel ap = (AlignmentPanel) alignment;
- if (ap.av.isShowSequenceFeatures())
- {
- return ap.getFeatureRenderer();
- }
- else
- {
- return null;
- }
- }
-
- @Override
- public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
- {
- return ((AlignmentPanel) alignment).getSequenceRenderer();
- }
-
- @Override
- public void notifyScriptTermination(String strStatus, int msWalltime)
- {
- // ignore
- }
-
- @Override
- public void sendConsoleEcho(String strEcho)
- {
- // ignore
- }
-
- @Override
- public void sendConsoleMessage(String strStatus)
- {
- // ignore
- }
-
- @Override
- public void showUrl(String url, String target)
- {
- ap.alignFrame.showURL(url, target);
- }
-
- @Override
- public void refreshGUI()
- {
- // ignore
- }
-
- public void selectionChanged(BS arg0)
- {
- System.out.println(arg0);
- }
-
- @Override
- public void refreshPdbEntries()
- {
- List<PDBEntry> pdbe = new ArrayList<PDBEntry>();
- List<String> fileids = new ArrayList<String>();
- SequenceI[] sq = ap.av.getAlignment().getSequencesArray();
- for (int s = 0; s < sq.length; s++)
- {
- Vector<PDBEntry> pdbids = sq[s].getPDBId();
- if (pdbids != null)
- {
- for (int pe = 0, peSize = pdbids.size(); pe < peSize; pe++)
- {
- PDBEntry pentry = pdbids.elementAt(pe);
- if (!fileids.contains(pentry.getId()))
- {
- pdbe.add(pentry);
- }
- else
- {
- fileids.add(pentry.getId());
- }
- }
- }
- }
- PDBEntry[] newEntries = new PDBEntry[pdbe.size()];
- for (int pe = 0; pe < pdbe.size(); pe++)
- {
- newEntries[pe] = pdbe.get(pe);
- }
- setPdbentry(newEntries);
- }
-
- @Override
- public void showConsole(boolean show)
- {
- // This never gets called because we haven't overriden the associated Jmol's
- // console
- System.err
- .println("WARNING: unexpected call to ExtJmol's showConsole method. (showConsole="
- + show);
- }
-
- @Override
- protected JmolAppConsoleInterface createJmolConsole(
- Container consolePanel, String buttonsToShow)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- @Override
- protected void releaseUIResources()
- {
- ap = null;
- closeConsole();
-
- }
-
- @Override
- public void releaseReferences(Object svl)
- {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- public Map<String, Object> getJSpecViewProperty(String arg0)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
+ public ExtJmol(StructureSelectionManager ssm, PDBEntry[] pdbentry,
+ SequenceI[][] sequenceIs, String[][] chains, String protocol) {
+ super(ssm, pdbentry, sequenceIs, chains, protocol);
+ // TODO Auto-generated constructor stub
+ }
+
+ @Override
+ public String[] getPdbFile() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public void updateColours(Object source) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void releaseReferences(Object svl) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void highlightAtoms(List<AtomSpec> atoms) {
+ // TODO Auto-generated method stub
+
+ }
+
+// private AlignmentPanel ap;
+//
+// protected ExtJmol(jalview.appletgui.AlignFrame alframe,
+// PDBEntry[] pdbentry, SequenceI[][] seq, String[][] chains,
+// String protocol)
+// {
+// super(alframe.alignPanel.getStructureSelectionManager(), pdbentry, seq,
+// chains, protocol);
+// }
+//
+// public ExtJmol(Viewer viewer, AlignmentPanel alignPanel,
+// SequenceI[][] seqs)
+// {
+// super(alignPanel.getStructureSelectionManager(), seqs, viewer);
+// ap = alignPanel;
+// notifyFileLoaded(null, null, null, null, 0);
+// }
+//
+// public void updateColours(Object source)
+// {
+//
+// // TODO Auto-generated method stub
+//
+// }
+//
+// public void showUrl(String arg0)
+// {
+// showUrl(arg0, "jmol");
+// }
+//
+// @Override
+// public FeatureRenderer getFeatureRenderer(AlignmentViewPanel alignment)
+// {
+// AlignmentPanel ap = (AlignmentPanel) alignment;
+// if (ap.av.isShowSequenceFeatures())
+// {
+// return ap.getFeatureRenderer();
+// }
+// else
+// {
+// return null;
+// }
+// }
+//
+// @Override
+// public SequenceRenderer getSequenceRenderer(AlignmentViewPanel alignment)
+// {
+// return ((AlignmentPanel) alignment).getSequenceRenderer();
+// }
+//
+// @Override
+// public void notifyScriptTermination(String strStatus, int msWalltime)
+// {
+// // ignore
+// }
+//
+// @Override
+// public void sendConsoleEcho(String strEcho)
+// {
+// // ignore
+// }
+//
+// @Override
+// public void sendConsoleMessage(String strStatus)
+// {
+// // ignore
+// }
+//
+// @Override
+// public void showUrl(String url, String target)
+// {
+// ap.alignFrame.showURL(url, target);
+// }
+//
+// @Override
+// public void refreshGUI()
+// {
+// // ignore
+// }
+//
+// public void selectionChanged(BS arg0)
+// {
+// System.out.println(arg0);
+// }
+//
+// @Override
+// public void refreshPdbEntries()
+// {
+// List<PDBEntry> pdbe = new ArrayList<PDBEntry>();
+// List<String> fileids = new ArrayList<String>();
+// SequenceI[] sq = ap.av.getAlignment().getSequencesArray();
+// for (int s = 0; s < sq.length; s++)
+// {
+// Vector<PDBEntry> pdbids = sq[s].getPDBId();
+// if (pdbids != null)
+// {
+// for (int pe = 0, peSize = pdbids.size(); pe < peSize; pe++)
+// {
+// PDBEntry pentry = pdbids.elementAt(pe);
+// if (!fileids.contains(pentry.getId()))
+// {
+// pdbe.add(pentry);
+// }
+// else
+// {
+// fileids.add(pentry.getId());
+// }
+// }
+// }
+// }
+// PDBEntry[] newEntries = new PDBEntry[pdbe.size()];
+// for (int pe = 0; pe < pdbe.size(); pe++)
+// {
+// newEntries[pe] = pdbe.get(pe);
+// }
+// setPdbentry(newEntries);
+// }
+//
+// @Override
+// public void showConsole(boolean show)
+// {
+// // This never gets called because we haven't overriden the associated Jmol's
+// // console
+// System.err
+// .println("WARNING: unexpected call to ExtJmol's showConsole method. (showConsole="
+// + show);
+// }
+//
+// @Override
+// protected JmolAppConsoleInterface createJmolConsole(
+// Container consolePanel, String buttonsToShow)
+// {
+// // TODO Auto-generated method stub
+// return null;
+// }
+//
+// @Override
+// protected void releaseUIResources()
+// {
+// ap = null;
+// closeConsole();
+//
+// }
+//
+// @Override
+// public void releaseReferences(Object svl)
+// {
+// // TODO Auto-generated method stub
+//
+// }
+//
+// @Override
+// public Map<String, Object> getJSpecViewProperty(String arg0)
+// {
+// // TODO Auto-generated method stub
+// return null;
+// }
+//
}
import jalview.schemes.GraduatedColor;
import jalview.util.MessageManager;
-import java.awt.Checkbox;
-import java.awt.Choice;
+import awt2swing.Checkbox;
+import awt2swing.Choice;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.GridLayout;
-import java.awt.Label;
-import java.awt.Panel;
-import java.awt.Scrollbar;
-import java.awt.TextField;
+import awt2swing.Label;
+import awt2swing.Panel;
+import awt2swing.Scrollbar;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Choice;
+import awt2swing.Button;
+import awt2swing.Choice;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
-import java.awt.Label;
-import java.awt.Panel;
-import java.awt.ScrollPane;
-import java.awt.TextArea;
-import java.awt.TextField;
+import awt2swing.Label;
+import awt2swing.Panel;
+import awt2swing.ScrollPane;
+import awt2swing.TextArea;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Hashtable;
super(null);
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
Dimension d = getSize();
if (isGcol)
import jalview.util.MessageManager;
import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Checkbox;
+import awt2swing.Button;
+import awt2swing.Checkbox;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
-import java.awt.Label;
-import java.awt.MenuItem;
-import java.awt.Panel;
-import java.awt.PopupMenu;
-import java.awt.ScrollPane;
-import java.awt.Scrollbar;
+import awt2swing.Label;
+import awt2swing.MenuItem;
+import awt2swing.Panel;
+import awt2swing.PopupMenu;
+import awt2swing.ScrollPane;
+import awt2swing.Scrollbar;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
height);
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
g.setColor(Color.black);
g.drawString(MessageManager
{
final String type = check.type;
final Object typeCol = fr.getFeatureStyle(type);
- java.awt.PopupMenu men = new PopupMenu(MessageManager.formatMessage(
+ awt2swing.PopupMenu men = new PopupMenu(MessageManager.formatMessage(
"label.settings_for_type", new String[]
{ type }));
- java.awt.MenuItem scr = new MenuItem(
+ awt2swing.MenuItem scr = new MenuItem(
MessageManager.getString("label.sort_by_score"));
men.add(scr);
final FeatureSettings me = this;
{
final Object typeMinMax = minmax.get(type);
/*
- * final java.awt.CheckboxMenuItem chb = new
- * java.awt.CheckboxMenuItem("Vary Height"); // this is broken at the
+ * final awt2swing.CheckboxMenuItem chb = new
+ * awt2swing.CheckboxMenuItem("Vary Height"); // this is broken at the
* moment chb.setState(minmax.get(type) != null);
* chb.addActionListener(new ActionListener() {
*
updateColor(featureStyle);
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
Dimension d = getSize();
if (gcol != null)
import jalview.util.MessageManager;
import jalview.viewmodel.AlignmentViewport;
-import java.awt.Button;
-import java.awt.Checkbox;
+import awt2swing.Button;
+import awt2swing.Checkbox;
import java.awt.Font;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.GridLayout;
-import java.awt.Label;
-import java.awt.Panel;
+import awt2swing.Label;
+import awt2swing.Panel;
import java.awt.Rectangle;
-import java.awt.TextField;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Checkbox;
-import java.awt.Choice;
+import awt2swing.Button;
+import awt2swing.Checkbox;
+import awt2swing.Choice;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
-import java.awt.Frame;
-import java.awt.Label;
-import java.awt.Panel;
+import awt2swing.Frame;
+import awt2swing.Label;
+import awt2swing.Panel;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.Panel;
+import awt2swing.Panel;
import java.util.List;
public class IdCanvas extends Panel
paint(g);
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
if (getSize().height < 0 || getSize().width < 0)
{
import jalview.viewmodel.AlignmentViewport;
import java.awt.BorderLayout;
-import java.awt.Panel;
+import awt2swing.Panel;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.Panel;
+import awt2swing.Panel;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
{
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
g.setColor(Color.white);
g.fillRect(0, 0, getSize().width, getSize().height);
package jalview.appletgui;
import java.awt.BorderLayout;
-import java.awt.Button;
+import awt2swing.Button;
import java.awt.Dialog;
import java.awt.FlowLayout;
-import java.awt.Frame;
-import java.awt.Panel;
+import awt2swing.Frame;
+import awt2swing.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Color;
import java.awt.Dimension;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.Panel;
+import awt2swing.Panel;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
}
@Override
- public void paint(Graphics g)
+ public void paintComponent(Graphics g)
{
Graphics og = offscreen.getGraphics();
if (miniMe != null)
import jalview.viewmodel.PCAModel;
import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.CheckboxMenuItem;
-import java.awt.Choice;
+import awt2swing.Button;
+import awt2swing.CheckboxMenuItem;
+import awt2swing.Choice;
import java.awt.Color;
import java.awt.FlowLayout;
-import java.awt.Frame;
-import java.awt.Label;
-import java.awt.Menu;
-import java.awt.MenuBar;
-import java.awt.MenuItem;
-import java.awt.Panel;
+import awt2swing.Frame;
+import awt2swing.Label;
+import awt2swing.Menu;
+import awt2swing.MenuBar;
+import awt2swing.MenuItem;
+import awt2swing.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Panel;
-import java.awt.ScrollPane;
-import java.awt.TextArea;
+import awt2swing.Button;
+import awt2swing.Panel;
+import awt2swing.ScrollPane;
+import awt2swing.TextArea;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
import jalview.datamodel.SequenceI;
import jalview.util.MessageManager;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.Panel;
+import awt2swing.Panel;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
paint(g);
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
if (points == null)
{
import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics;
-import java.awt.MenuItem;
-import java.awt.Panel;
-import java.awt.PopupMenu;
+import awt2swing.MenuItem;
+import awt2swing.Panel;
+import awt2swing.PopupMenu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
paint(g);
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
drawScale(g, av.getStartRes(), av.getEndRes(), getSize().width,
getSize().height);
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Image;
-import java.awt.Panel;
+import awt2swing.Panel;
public class SeqCanvas extends Panel
{
}
@Override
- public void paint(Graphics g)
+ public void paintComponent(Graphics g)
{
if (img != null
import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.FontMetrics;
-import java.awt.Panel;
+import awt2swing.Panel;
import java.awt.Point;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import jalview.util.MessageManager;
import java.awt.BorderLayout;
-import java.awt.Button;
-import java.awt.Checkbox;
+import awt2swing.Button;
+import awt2swing.Checkbox;
import java.awt.Color;
import java.awt.FlowLayout;
-import java.awt.Frame;
-import java.awt.Label;
-import java.awt.Panel;
-import java.awt.Scrollbar;
-import java.awt.TextField;
+import awt2swing.Frame;
+import awt2swing.Label;
+import awt2swing.Panel;
+import awt2swing.Scrollbar;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
-import java.awt.Panel;
+
+import awt2swing.MenuBar;
+import awt2swing.Panel;
public class SplitFrame extends EmbmenuFrame
{
*/
protected void constructSplit()
{
- setMenuBar(null);
+ unsetMenuBar();
outermost = new Panel(new GridLayout(2, 1));
Panel topPanel = new Panel();
addAlignFrameComponents(bottomFrame, bottomPanel);
}
- /**
+ /**
* Make any adjustments to the layout
*/
protected void adjustLayout()
{
panel.setLayout(new BorderLayout());
Panel menuPanel = af
- .makeEmbeddedPopupMenu(af.getMenuBar(), true, false);
+ .makeEmbeddedPopupMenu((MenuBar) af.getJMenuBar(), true, false);
panel.add(menuPanel, BorderLayout.NORTH);
panel.add(af.statusBar, BorderLayout.SOUTH);
panel.add(af.alignPanel, BorderLayout.CENTER);
package jalview.appletgui;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.Graphics;
import java.awt.Insets;
-import java.awt.Label;
-import java.awt.Panel;
+import awt2swing.Label;
+import awt2swing.Panel;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
return insets;
}
- public void paint(Graphics g)
+ public void paintComponent(Graphics g)
{
- super.paint(g);
+ super.paintComponent(g);
g.setColor(getForeground());
g.drawRect(5, 5, getWidth() - 10, getHeight() - 10);
int width = g.getFontMetrics().stringWidth(getTitle());
g.drawString(getTitle(), 10, 10);
}
+ /**
+ * @j2sIgnore
+ *
+ * @param args
+ */
public static void main(String[] args)
{
Frame f = new Frame("TitledPanel Tester");
package jalview.appletgui;
import java.applet.Applet;
-import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FontMetrics;
-import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.LayoutManager;
import java.awt.event.MouseMotionListener;
import java.util.StringTokenizer;
+import awt2swing.Canvas;
+import awt2swing.Frame;
+
public class Tooltip extends Canvas implements MouseListener,
MouseMotionListener
{
}
}
- public void paint(Graphics g)
+ public void PaintComponent(Graphics g)
{
int w = getSize().width;
int h = getSize().height;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
-import java.awt.Panel;
+import awt2swing.Panel;
import java.awt.Point;
import java.awt.Rectangle;
-import java.awt.ScrollPane;
+import awt2swing.ScrollPane;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
}
@Override
- public void paint(Graphics g)
+ public void paintComponent(Graphics g)
{
if (tree == null)
{
import jalview.util.MessageManager;
import java.awt.BorderLayout;
-import java.awt.CheckboxMenuItem;
+import awt2swing.CheckboxMenuItem;
import java.awt.Color;
-import java.awt.Menu;
-import java.awt.MenuBar;
-import java.awt.MenuItem;
-import java.awt.ScrollPane;
+import awt2swing.Menu;
+import awt2swing.MenuBar;
+import awt2swing.MenuItem;
+import awt2swing.ScrollPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
String output = fout.print(false, true);
CutAndPasteTransfer cap = new CutAndPasteTransfer(false, null);
cap.setText(output);
- java.awt.Frame frame = new java.awt.Frame();
+ awt2swing.Frame frame = new awt2swing.Frame();
frame.add(cap);
JalviewLite.addFrame(frame, type + " " + pwtype, 500, 100);
}
import jalview.schemes.UserColourScheme;
import jalview.util.MessageManager;
-import java.awt.Button;
+import awt2swing.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Font;
-import java.awt.Frame;
+import awt2swing.Frame;
import java.awt.GridLayout;
-import java.awt.Label;
-import java.awt.Panel;
+import awt2swing.Label;
+import awt2swing.Panel;
import java.awt.Rectangle;
-import java.awt.Scrollbar;
-import java.awt.TextField;
+import awt2swing.Scrollbar;
+import awt2swing.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
Frame frame;
- MCview.AppletPDBCanvas pdbcanvas;
+// MCview.AppletPDBCanvas pdbcanvas;
AppletJmol jmol;
init();
}
- public UserDefinedColours(MCview.AppletPDBCanvas pdb)
- {
- this.pdbcanvas = pdb;
- init();
- }
+// public UserDefinedColours(MCview.AppletPDBCanvas pdb)
+// {
+// this.pdbcanvas = pdb;
+// init();
+// }
public UserDefinedColours(AppletJmol jmol)
{
{
jmol.setJalviewColourScheme(ucs);
}
- else if (pdbcanvas != null)
- {
- pdbcanvas.setColours(ucs);
- }
+// else if (pdbcanvas != null)
+// {
+// pdbcanvas.setColours(ucs);
+// }
}
protected void cancelButton_actionPerformed()
{
jmol.setJalviewColourScheme(ucs);
}
- else if (pdbcanvas != null)
- {
- pdbcanvas.pdb.setColours(ucs);
- }
+// else if (pdbcanvas != null)
+// {
+// pdbcanvas.pdb.setColours(ucs);
+// }
frame.setVisible(false);
}
-/*
- * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
- * Copyright (C) $$Year-Rel$$ The Jalview Authors
- *
- * This file is part of Jalview.
- *
- * Jalview is free software: you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation, either version 3
- * of the License, or (at your option) any later version.
- *
- * Jalview is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
- * The Jalview Authors are detailed in the 'AUTHORS' file.
- */
package jalview.bin;
-import jalview.gui.UserDefinedColours;
-import jalview.io.PIRFile;
-import jalview.jbgui.GDesktop;
-import jalview.schemes.ColourSchemeProperty;
-import jalview.schemes.UserColourScheme;
-import jalview.util.Format;
-import jalview.ws.dbsources.das.api.DasSourceRegistryI;
-import jalview.ws.dbsources.das.datamodel.DasSourceRegistry;
-
-import java.awt.Color;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.text.DateFormat;
-import java.text.SimpleDateFormat;
-import java.util.Collections;
-import java.util.Date;
-import java.util.Enumeration;
-import java.util.Properties;
-import java.util.TreeSet;
-
-import org.apache.log4j.ConsoleAppender;
-import org.apache.log4j.Level;
-import org.apache.log4j.Logger;
-import org.apache.log4j.SimpleLayout;
-
-/**
- * Stores and retrieves Jalview Application Properties Lists and fields within
- * list entries are separated by '|' symbols unless otherwise stated (|) clauses
- * are alternative values for a tag. <br>
- * <br>
- * Current properties include:
- * <ul>
- * <br>
- * logs.Axis.Level - one of the stringified Levels for log4j controlling the
- * logging level for axis (used for web services) <br>
- * </li>
- * <li>logs.Castor.Level - one of the stringified Levels for log4j controlling
- * the logging level for castor (used for serialization) <br>
- * </li>
- * <li>logs.Jalview.Level - Cache.log stringified level. <br>
- * </li>
- * <li>SCREEN_WIDTH</li>
- * <li>SCREEN_HEIGHT</li>
- * <li>SCREEN_Y=285</li>
- * <li>SCREEN_X=371</li>
- * <li>SHOW_FULLSCREEN boolean</li>
- * <li>FONT_NAME java font name for alignment text display</li>
- * <li>FONT_SIZE size of displayed alignment text</li>
- * <li>FONT_STYLE style of font displayed (sequence labels are always italic)</li>
- * <li>GAP_SYMBOL character to treat as gap symbol (usually -,.,' ')</li>
- * <li>LAST_DIRECTORY last directory for browsing alignment</li>
- * <li>USER_DEFINED_COLOURS list of user defined colour scheme files</li>
- * <li>SHOW_FULL_ID show id with '/start-end' numbers appended</li>
- * <li>SHOW_IDENTITY show percentage identity annotation</li>
- * <li>SHOW_QUALITY show alignment quality annotation</li>
- * <li>SHOW_ANNOTATIONS show alignment annotation rows</li>
- * <li>SHOW_CONSERVATION show alignment conservation annotation</li>
- * <li>SORT_ANNOTATIONS currently either SEQUENCE_AND_LABEL or
- * LABEL_AND_SEQUENCE</li>
- * <li>SHOW_AUTOCALC_ABOVE true to show autocalculated annotations above
- * sequence annotations</li>
- * <li>CENTRE_COLUMN_LABELS centre the labels at each column in a displayed
- * annotation row</li>
- * <li>DEFAULT_COLOUR default colour scheme to apply for a new alignment</li>
- * <li>DEFAULT_FILE_FORMAT file format used to save</li>
- * <li>STARTUP_FILE file loaded on startup (may be a fully qualified url)</li>
- * <li>SHOW_STARTUP_FILE flag to control loading of startup file</li>
- * <li>VERSION the version of the jalview build</li>
- * <li>BUILD_DATE date of this build</li>
- * <li>LATEST_VERSION the latest jalview version advertised on the
- * www.jalview.org</li>
- * <li>PIR_MODELLER boolean indicating if PIR files are written with MODELLER
- * descriptions</li>
- * <li>(FASTA,MSF,PILEUP,CLUSTAL,BLC,PIR,PFAM)_JVSUFFIX boolean for adding jv
- * suffix to file</li>
- * <li>RECENT_URL list of recently retrieved URLs</li>
- * <li>RECENT_FILE list of recently opened files</li>
- * <li>USE_PROXY flag for whether a http proxy is to be used</li>
- * <li>PROXY_SERVER the proxy</li>
- * <li>PROXY_PORT</li>
- * <li>NOQUESTIONNAIRES true to prevent jalview from checking the questionnaire
- * service</li>
- * <li>QUESTIONNAIRE last questionnaire:responder id string from questionnaire
- * service</li>
- * <li>USAGESTATS (false - user prompted) Enable google analytics tracker for
- * collecting usage statistics</li>
- * <li>DAS_LOCAL_SOURCE list of local das sources</li>
- * <li>SHOW_OVERVIEW boolean for overview window display</li>
- * <li>ANTI_ALIAS boolean for smooth fonts</li>
- * <li>RIGHT_ALIGN_IDS boolean</li>
- * <li>AUTO_CALC_CONSENSUS boolean for automatic recalculation of consensus</li>
- * <li>PAD_GAPS boolean</li>
- * <li>ID_ITALICS boolean</li>
- * <li>SHOW_JV_SUFFIX</li>
- * <li>WRAP_ALIGNMENT</li>
- * <li>EPS_RENDERING (Prompt each time|Lineart|Text) default for EPS rendering
- * style check</li>
- * <li>SORT_ALIGNMENT (No sort|Id|Pairwise Identity)</li>
- * <li>SEQUENCE_LINKS list of name|URL pairs for opening a url with
- * $SEQUENCE_ID$</li>
- * <li>GROUP_LINKS list of name|URL[|<separator>] tuples - see
- * jalview.utils.GroupURLLink for more info</li>
- * <li>DAS_REGISTRY_URL the registry to query</li>
- * <li>DEFAULT_BROWSER for unix</li>
- * <li>DAS_ACTIVE_SOURCE list of active sources</li>
- * <li>SHOW_MEMUSAGE boolean show memory usage and warning indicator on desktop
- * (false)</li>
- * <li>VERSION_CHECK (true) check for the latest release version from
- * www.jalview.org (or the alias given by the www.jalview.org property)</li>
- * <li>SHOW_NPFEATS_TOOLTIP (true) show non-positional features in the Sequence
- * ID tooltip</li>
- * <li>SHOW_DBREFS_TOOLTIP (true) show Database Cross References in the Sequence
- * ID tooltip</li>
- * <li>SHOW_UNCONSERVED (false) only render unconserved residues - conserved
- * displayed as '.'</li>
- * <li>SORT_BY_TREE (false) sort the current alignment view according to the
- * order of a newly displayed tree</li>
- * <li>DBFETCH_USEPICR (false) use PICR to recover valid DB references from
- * sequence ID strings before attempting retrieval from any datasource</li>
- * <li>SHOW_GROUP_CONSENSUS (false) Show consensus annotation for groups in the
- * alignment.</li>
- * <li>SHOW_GROUP_CONSERVATION (false) Show conservation annotation for groups
- * in the alignment.</li>
- * <li>SHOW_CONSENSUS_HISTOGRAM (false) Show consensus annotation row's
- * histogram.</li>
- * <li>SHOW_CONSENSUS_LOGO (false) Show consensus annotation row's sequence
- * logo.</li>
- * <li>NORMALISE_CONSENSUS_LOGO (false) Show consensus annotation row's sequence
- * logo normalised to row height rather than histogram height.</li>
- * <li>FOLLOW_SELECTIONS (true) Controls whether a new alignment view should
- * respond to selections made in other alignments containing the same sequences.
- * </li>
- * <li>JWS2HOSTURLS comma-separated list of URLs to try for JABAWS services</li>
- * <li>SHOW_WSDISCOVERY_ERRORS (true) Controls if the web service URL discovery
- * warning dialog box is displayed.</li>
- * <li>ANNOTATIONCOLOUR_MIN (orange) Shade used for minimum value of annotation
- * when shading by annotation</li>
- * <li>ANNOTATIONCOLOUR_MAX (red) Shade used for maximum value of annotation
- * when shading by annotation</li>
- * <li>www.jalview.org (http://www.jalview.org) a property enabling all HTTP
- * requests to be redirected to a mirror of http://www.jalview.org</li>
- * <li>FIGURE_AUTOIDWIDTH (false) Expand the left hand column of an exported
- * alignment figure to accommodate even the longest sequence ID or annotation
- * label.</li>
- * <li>FIGURE_FIXEDIDWIDTH Specifies the width to use for the left-hand column
- * when exporting an alignment as a figure (setting FIGURE_AUTOIDWIDTH to true
- * will override this).</li>
- * <li>STRUCT_FROM_PDB (false) derive secondary structure annotation from PDB
- * record</li>
- * <li>USE_RNAVIEW (false) use RNAViewer to derive secondary structure</li>
- * <li>ADD_SS_ANN (false) add secondary structure annotation to alignment
- * display</li>
- * <li>ADD_TEMPFACT_ANN (false) add Temperature Factor annotation to alignment
- * display</li>
- * <li>STRUCTURE_DISPLAY choose from JMOL (default) or CHIMERA for 3D structure
- * display</li>
- * <li>CHIMERA_PATH specify full path to Chimera program (if non-standard)</li>
- *
- * </ul>
- * Deprecated settings:
- * <ul>
- * *
- * <li>DISCOVERY_START - Boolean - controls if discovery services are queried on
- * startup (JWS1 services only)</li>
- * <li>DISCOVERY_URLS - comma separated list of Discovery Service endpoints.
- * (JWS1 services only)</li>
- * <li>SHOW_JWS1_SERVICES (true) enable or disable the original Jalview 2
- * services in the desktop GUI</li>
- * <li>ENABLE_RSBS_EDITOR (false for 2.7 release) enable or disable RSBS editing
- * panel in web service preferences</li>
- * </ul>
- *
- * @author $author$
- * @version $Revision$
- */
-public class Cache
-{
- /**
- * property giving log4j level for CASTOR loggers
- */
- public static final String CASTORLOGLEVEL = "logs.Castor.level";
-
- /**
- * property giving log4j level for AXIS loggers
- */
- public static final String AXISLOGLEVEL = "logs.Axis.level";
-
- /**
- * property giving log4j level for Jalview Log
- */
- public static final String JALVIEWLOGLEVEL = "logs.Jalview.level";
-
- public static final String DAS_LOCAL_SOURCE = "DAS_LOCAL_SOURCE";
-
- public static final String DAS_REGISTRY_URL = "DAS_REGISTRY_URL";
-
- public static final String DAS_ACTIVE_SOURCE = "DAS_ACTIVE_SOURCE";
-
- /**
- * Initialises the Jalview Application Log
- */
- public static Logger log;
-
- /** Jalview Properties */
- public static Properties applicationProperties = new Properties() {
- // override results in properties output in alphabetical order
- @Override
- public synchronized Enumeration<Object> keys() {
- return Collections.enumeration(new TreeSet<Object>(super.keySet()));
- }
- };
-
- /** Default file is ~/.jalview_properties */
- static String propertiesFile;
-
- private static boolean propsAreReadOnly = false;
-
- public static void initLogger()
- {
- if (log != null)
- {
- return;
- }
- try
- {
- // TODO: redirect stdout and stderr here in order to grab the output of
- // the log
-
- ConsoleAppender ap = new ConsoleAppender(new SimpleLayout(),
- "System.err");
- ap.setName("JalviewLogger");
- org.apache.log4j.Logger.getRootLogger().addAppender(ap); // catch all for
- // log output
- Logger laxis = Logger.getLogger("org.apache.axis");
- Logger lcastor = Logger.getLogger("org.exolab.castor");
- Cache.log = Logger.getLogger("jalview.bin.Jalview");
-
- laxis.setLevel(Level.toLevel(Cache.getDefault("logs.Axis.Level",
- Level.INFO.toString())));
- lcastor.setLevel(Level.toLevel(Cache.getDefault("logs.Castor.Level",
- Level.INFO.toString())));
- lcastor = Logger.getLogger("org.exolab.castor.xml");
- lcastor.setLevel(Level.toLevel(Cache.getDefault("logs.Castor.Level",
- Level.INFO.toString())));
- // lcastor = Logger.getLogger("org.exolab.castor.xml.Marshaller");
- // lcastor.setLevel(Level.toLevel(Cache.getDefault("logs.Castor.Level",
- // Level.INFO.toString())));
- Cache.log.setLevel(Level.toLevel(Cache.getDefault(
- "logs.Jalview.level", Level.INFO.toString())));
- // laxis.addAppender(ap);
- // lcastor.addAppender(ap);
- // Cache.log.addAppender(ap);
- // Tell the user that debug is enabled
- Cache.log.debug("Jalview Debugging Output Follows.");
- } catch (Exception ex)
- {
- System.err.println("Problems initializing the log4j system\n");
- ex.printStackTrace(System.err);
- }
- }
-
- /** Called when Jalview is started */
- public static void loadProperties(String propsFile)
- {
- propertiesFile = propsFile;
- if (propsFile == null)
- {
- propertiesFile = System.getProperty("user.home") + File.separatorChar
- + ".jalview_properties";
- }
- else
- {
- // don't corrupt the file we've been given.
- propsAreReadOnly = true;
- }
-
- try
- {
- InputStream fis;
- try
- {
- fis = new java.net.URL(propertiesFile).openStream();
- System.out.println("Loading jalview properties from : "
- + propertiesFile);
- System.out
- .println("Disabling Jalview writing to user's local properties file.");
- propsAreReadOnly = true;
-
- } catch (Exception ex)
- {
- fis = null;
- }
- if (fis == null)
- {
- fis = new FileInputStream(propertiesFile);
- }
- applicationProperties.load(fis);
-
- // remove any old build properties
-
- deleteBuildProperties();
- fis.close();
- } catch (Exception ex)
- {
- System.out.println("Error reading properties file: " + ex);
- }
-
- if (getDefault("USE_PROXY", false))
- {
- String proxyServer = getDefault("PROXY_SERVER", ""), proxyPort = getDefault(
- "PROXY_PORT", "8080");
-
- System.out.println("Using proxyServer: " + proxyServer
- + " proxyPort: " + proxyPort);
-
- System.setProperty("http.proxyHost", proxyServer);
- System.setProperty("http.proxyPort", proxyPort);
- }
-
- // LOAD THE AUTHORS FROM THE authors.props file
- try
- {
- String authorDetails = "jar:".concat(Cache.class
- .getProtectionDomain().getCodeSource().getLocation()
- .toString().concat("!/authors.props"));
-
- java.net.URL localJarFileURL = new java.net.URL(authorDetails);
-
- InputStream in = localJarFileURL.openStream();
- applicationProperties.load(in);
- in.close();
- } catch (Exception ex)
- {
- System.out.println("Error reading author details: " + ex);
- applicationProperties.remove("AUTHORS");
- applicationProperties.remove("AUTHORFNAMES");
- applicationProperties.remove("YEAR");
- }
-
- // FIND THE VERSION NUMBER AND BUILD DATE FROM jalview.jar
- // MUST FOLLOW READING OF LOCAL PROPERTIES FILE AS THE
- // VERSION MAY HAVE CHANGED SINCE LAST USING JALVIEW
- try
- {
- String buildDetails = "jar:".concat(Cache.class.getProtectionDomain()
- .getCodeSource().getLocation().toString()
- .concat("!/.build_properties"));
-
- java.net.URL localJarFileURL = new java.net.URL(buildDetails);
-
- InputStream in = localJarFileURL.openStream();
- applicationProperties.load(in);
- in.close();
- } catch (Exception ex)
- {
- System.out.println("Error reading build details: " + ex);
- applicationProperties.remove("VERSION");
- }
-
- String jnlpVersion = System.getProperty("jalview.version");
- String codeVersion = getProperty("VERSION");
- String codeInstallation = getProperty("INSTALLATION");
- if (codeVersion == null)
- {
- // THIS SHOULD ONLY BE THE CASE WHEN TESTING!!
- codeVersion = "Test";
- jnlpVersion = "Test";
- codeInstallation = "";
- }
- else
- {
- codeInstallation = " (" + codeInstallation + ")";
- }
-
- System.out
- .println("Jalview Version: " + codeVersion + codeInstallation);
-
- // jnlpVersion will be null if we're using InstallAnywhere
- // Dont do this check if running in headless mode
- if (jnlpVersion == null
- && getDefault("VERSION_CHECK", true)
- && (System.getProperty("java.awt.headless") == null || System
- .getProperty("java.awt.headless").equals("false")))
- {
-
- class VersionChecker extends Thread
- {
- public void run()
- {
- String orgtimeout = System
- .getProperty("sun.net.client.defaultConnectTimeout");
- if (orgtimeout == null)
- {
- orgtimeout = "30";
- System.out.println("# INFO: Setting default net timeout to "
- + orgtimeout + " seconds.");
- }
- String jnlpVersion = null;
- try
- {
- System.setProperty("sun.net.client.defaultConnectTimeout",
- "5000");
- java.net.URL url = new java.net.URL(Cache.getDefault(
- "www.jalview.org", "http://www.jalview.org")
- + "/webstart/jalview.jnlp");
- BufferedReader in = new BufferedReader(new InputStreamReader(
- url.openStream()));
- String line = null;
- while ((line = in.readLine()) != null)
- {
- if (line.indexOf("jalview.version") == -1)
- {
- continue;
- }
-
- line = line.substring(line.indexOf("value=") + 7);
- line = line.substring(0, line.lastIndexOf("\""));
- jnlpVersion = line;
- break;
- }
- } catch (Exception ex)
- {
- System.out
- .println("Non-fatal exceptions when checking version at www.jalview.org :");
- System.out.println(ex);
- jnlpVersion = getProperty("VERSION");
- }
- System.setProperty("sun.net.client.defaultConnectTimeout",
- orgtimeout);
-
- setProperty("LATEST_VERSION", jnlpVersion);
- }
- }
-
- VersionChecker vc = new VersionChecker();
- vc.start();
- }
- else
- {
- if (jnlpVersion != null)
- {
- setProperty("LATEST_VERSION", jnlpVersion);
- }
- else
- {
- applicationProperties.remove("LATEST_VERSION");
- }
- }
-
- setProperty("VERSION", codeVersion);
-
- // LOAD USERDEFINED COLOURS
- UserDefinedColours
- .initUserColourSchemes(getProperty("USER_DEFINED_COLOURS"));
- PIRFile.useModellerOutput = Cache.getDefault("PIR_MODELLER",
- false);
- }
-
- private static void deleteBuildProperties()
- {
- applicationProperties.remove("LATEST_VERSION");
- applicationProperties.remove("VERSION");
- applicationProperties.remove("AUTHORS");
- applicationProperties.remove("AUTHORFNAMES");
- applicationProperties.remove("YEAR");
- applicationProperties.remove("BUILD_DATE");
- applicationProperties.remove("INSTALLATION");
- }
-
- /**
- * Gets Jalview application property of given key. Returns null if key not
- * found
- *
- * @param key
- * Name of property
- *
- * @return Property value
- */
- public static String getProperty(String key)
- {
- return applicationProperties.getProperty(key);
- }
-
- /**
- * These methods are used when checking if the saved preference is different
- * to the default setting
- */
-
- public static boolean getDefault(String property, boolean def)
- {
- String string = getProperty(property);
- if (string != null)
- {
- def = Boolean.valueOf(string).booleanValue();
- }
-
- return def;
- }
-
- /**
- * These methods are used when checking if the saved preference is different
- * to the default setting
- */
- public static String getDefault(String property, String def)
- {
- String string = getProperty(property);
- if (string != null)
- {
- return string;
- }
-
- return def;
- }
-
- /**
- * Stores property in the file "HOME_DIR/.jalview_properties"
- *
- * @param key
- * Name of object
- * @param obj
- * String value of property
- *
- * @return String value of property
- */
- public static String setProperty(String key, String obj)
- {
-
- try
- {
- applicationProperties.setProperty(key, obj);
- if (!propsAreReadOnly)
- {
- FileOutputStream out = new FileOutputStream(propertiesFile);
- applicationProperties.store(out, "---JalviewX Properties File---");
- out.close();
- }
- } catch (Exception ex)
- {
- System.out.println("Error setting property: " + key + " " + obj
- + "\n" + ex);
- }
- return obj;
- }
-
- /**
- * remove the specified property from the jalview properties file
- *
- * @param string
- */
- public static void removeProperty(String string)
- {
- applicationProperties.remove(string);
- saveProperties();
- }
-
- /**
- * save the properties to the jalview properties path
- */
- public static void saveProperties()
- {
- if (!propsAreReadOnly)
- {
- try
- {
- FileOutputStream out = new FileOutputStream(propertiesFile);
- applicationProperties.store(out, "---JalviewX Properties File---");
- out.close();
- } catch (Exception ex)
- {
- System.out.println("Error saving properties: " + ex);
- }
- }
- }
-
- /**
- * internal vamsas class discovery state
- */
- private static int vamsasJarsArePresent = -1;
-
- /**
- * Searches for vamsas client classes on class path.
- *
- * @return true if vamsas client is present on classpath
- */
- public static boolean vamsasJarsPresent()
- {
- if (vamsasJarsArePresent == -1)
- {
- try
- {
- if (GDesktop.class.getClassLoader().loadClass(
- "uk.ac.vamsas.client.VorbaId") != null)
- {
- Cache.log
- .debug("Found Vamsas Classes (uk.ac..vamsas.client.VorbaId can be loaded)");
- vamsasJarsArePresent = 1;
- Logger lvclient = Logger.getLogger("uk.ac.vamsas");
- lvclient.setLevel(Level.toLevel(Cache.getDefault(
- "logs.Vamsas.Level", Level.INFO.toString())));
-
- lvclient.addAppender(log.getAppender("JalviewLogger"));
- // Tell the user that debug is enabled
- lvclient.debug("Jalview Vamsas Client Debugging Output Follows.");
- }
- } catch (Exception e)
- {
- vamsasJarsArePresent = 0;
- Cache.log.debug("Vamsas Classes are not present");
- }
- }
- return (vamsasJarsArePresent > 0);
- }
-
- /**
- * internal vamsas class discovery state
- */
- private static int groovyJarsArePresent = -1;
-
- /**
- * Searches for vamsas client classes on class path.
- *
- * @return true if vamsas client is present on classpath
- */
- public static boolean groovyJarsPresent()
- {
- if (groovyJarsArePresent == -1)
- {
- try
- {
- if (Cache.class.getClassLoader().loadClass(
- "groovy.lang.GroovyObject") != null)
- {
- Cache.log
- .debug("Found Groovy (groovy.lang.GroovyObject can be loaded)");
- groovyJarsArePresent = 1;
- Logger lgclient = Logger.getLogger("groovy");
- lgclient.setLevel(Level.toLevel(Cache.getDefault(
- "logs.Groovy.Level", Level.INFO.toString())));
-
- lgclient.addAppender(log.getAppender("JalviewLogger"));
- // Tell the user that debug is enabled
- lgclient.debug("Jalview Groovy Client Debugging Output Follows.");
- }
- } catch (Error e)
- {
- groovyJarsArePresent = 0;
- Cache.log.debug("Groovy Classes are not present", e);
- } catch (Exception e)
- {
- groovyJarsArePresent = 0;
- Cache.log.debug("Groovy Classes are not present");
- }
- }
- return (groovyJarsArePresent > 0);
- }
-
- /**
- * GA tracker object - actually JGoogleAnalyticsTracker null if tracking not
- * enabled.
- */
- protected static Object tracker = null;
-
- protected static Class trackerfocus = null;
-
- protected static Class jgoogleanalyticstracker = null;
-
- /**
- * Initialise the google tracker if it is not done already.
- */
- public static void initGoogleTracker()
- {
- if (tracker == null)
- {
- if (jgoogleanalyticstracker == null)
- {
- // try to get the tracker class
- try
- {
- jgoogleanalyticstracker = Cache.class
- .getClassLoader()
- .loadClass(
- "com.boxysystems.jgoogleanalytics.JGoogleAnalyticsTracker");
- trackerfocus = Cache.class.getClassLoader().loadClass(
- "com.boxysystems.jgoogleanalytics.FocusPoint");
- } catch (Exception e)
- {
- log.debug("com.boxysystems.jgoogleanalytics package is not present - tracking not enabled.");
- tracker = null;
- jgoogleanalyticstracker = null;
- trackerfocus = null;
- return;
- }
- }
- // now initialise tracker
- Exception re = null, ex = null;
- Error err = null;
- String vrs = "No Version Accessible";
- try
- {
- // Google analytics tracking code for Library Finder
- tracker = jgoogleanalyticstracker.getConstructor(new Class[]
- { String.class, String.class, String.class }).newInstance(
- new Object[]
- {
- "Jalview Desktop",
- (vrs = Cache.getProperty("VERSION")
- + "_"
- + Cache.getDefault("BUILD_DATE",
- "unknown")), "UA-9060947-1" });
- jgoogleanalyticstracker.getMethod("trackAsynchronously",
- new Class[]
- { trackerfocus }).invoke(tracker, new Object[]
- { trackerfocus.getConstructor(new Class[]
- { String.class }).newInstance(new Object[]
- { "Application Started." }) });
- } catch (RuntimeException e)
- {
- re = e;
- } catch (Exception e)
- {
- ex = e;
- } catch (Error e)
- {
- err = e;
- }
- if (re != null || ex != null || err != null)
- {
- if (log != null)
- {
- if (re != null)
- {
- log.debug("Caught runtime exception in googletracker init:", re);
- }
- if (ex != null)
- {
- log.warn(
- "Failed to initialise GoogleTracker for Jalview Desktop with version "
- + vrs, ex);
- }
- if (err != null)
- {
- log.error(
- "Whilst initing GoogleTracker for Jalview Desktop version "
- + vrs, err);
- }
- }
- else
- {
- if (re != null)
- {
- System.err
- .println("Debug: Caught runtime exception in googletracker init:"
- + vrs);
- re.printStackTrace();
- }
- if (ex != null)
- {
- System.err
- .println("Warning: Failed to initialise GoogleTracker for Jalview Desktop with version "
- + vrs);
- ex.printStackTrace();
- }
-
- if (err != null)
- {
- System.err
- .println("ERROR: Whilst initing GoogleTracker for Jalview Desktop version "
- + vrs);
- err.printStackTrace();
- }
- }
- }
- else
- {
- log.debug("Successfully initialised tracker.");
- }
- }
- }
-
- /**
- * get the user's default colour if available
- *
- * @param property
- * @param defcolour
- * @return
- */
- public static Color getDefaultColour(String property, Color defcolour)
- {
- String colprop = getProperty(property);
- if (colprop == null)
- {
- return defcolour;
- }
- Color col = ColourSchemeProperty.getAWTColorFromName(colprop);
- if (col == null)
- {
- try
- {
- col = new UserColourScheme(colprop).findColour('A');
- } catch (Exception ex)
- {
- log.warn("Couldn't parse '" + colprop + "' as a colour for "
- + property);
- col = null;
- }
- }
- return (col == null) ? defcolour : col;
- }
-
- /**
- * store a colour as a Jalview user default property
- *
- * @param property
- * @param colour
- */
- public static void setColourProperty(String property, Color colour)
- {
- setProperty(property, Format.getHexString(colour));
- }
-
- public static final DateFormat date_format = SimpleDateFormat
- .getDateTimeInstance();
-
- /**
- * store a date in a jalview property
- *
- * @param string
- * @param time
- */
- public static void setDateProperty(String property, Date time)
- {
- setProperty(property, date_format.format(time));
- }
-
- /**
- * read a date stored in a jalview property
- *
- * @param property
- * @return valid date as stored by setDateProperty, or null
- *
- */
- public static Date getDateProperty(String property)
- {
- String val = getProperty(property);
- if (val != null)
- {
- try
- {
- return date_format.parse(val);
- } catch (Exception ex)
- {
- System.err.println("Invalid or corrupt date in property '"
- + property + "' : value was '" + val + "'");
- }
- }
- return null;
- }
-
- /**
- * get and parse a property as an integer. send any parsing problems to
- * System.err
- *
- * @param property
- * @return null or Integer
- */
- public static Integer getIntegerProperty(String property)
- {
- String val = getProperty(property);
- if (val != null && (val = val.trim()).length() > 0)
- {
- try
- {
- return Integer.valueOf(val);
- } catch (NumberFormatException x)
- {
- System.err.println("Invalid integer in property '" + property
- + "' (value was '" + val + "')");
- }
- }
- return null;
- }
-
- private static DasSourceRegistryI sourceRegistry = null;
-
- /**
- * initialise and ..
- *
- * @return instance of the das source registry
- */
- public static DasSourceRegistryI getDasSourceRegistry()
- {
- if (sourceRegistry == null)
- {
- sourceRegistry = new DasSourceRegistry();
- }
- return sourceRegistry;
- }
-
- /**
- * Set the specified value, or remove it if null or empty. Does not save the
- * properties file.
- *
- * @param propName
- * @param value
- */
- public static void setOrRemove(String propName, String value)
- {
- if (propName == null)
- {
- return;
- }
- if (value == null || value.trim().length() < 1)
- {
- Cache.applicationProperties.remove(propName);
- }
- else
- {
- Cache.applicationProperties.setProperty(propName, value);
- }
- }
+public class Cache {
+ public static final String CASTORLOGLEVEL = null;
+ public static Log log;
+
+ public class Log {
+
+ public void error(String string) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public boolean isDebugEnabled() {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ }
+
+ public static String getDefault(String string, String string2) {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
import jalview.appletgui.EmbmenuFrame;
import jalview.appletgui.FeatureSettings;
import jalview.appletgui.SplitFrame;
+//import jalview.appletgui.AlignViewport;
+//import jalview.appletgui.EmbmenuFrame;
+//import jalview.appletgui.FeatureSettings;
+//import jalview.appletgui.SplitFrame;
import jalview.datamodel.Alignment;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AlignmentOrder;
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.io.AlignFile;
import jalview.io.AnnotationFile;
import jalview.io.AppletFormatAdapter;
import jalview.io.FileParse;
import jalview.io.IdentifyFile;
-import jalview.io.JPredFile;
import jalview.io.JnetAnnotationMaker;
+//import jalview.io.JPredFile;
+//import jalview.io.JnetAnnotationMaker;
import jalview.io.NewickFile;
import jalview.javascript.JSFunctionExec;
import jalview.javascript.JalviewLiteJsApi;
import jalview.javascript.JsSelectionSender;
import jalview.javascript.MouseOverListener;
import jalview.javascript.MouseOverStructureListener;
+import jalview.jsdev.GenericFileAdapter;
+//import jalview.javascript.MouseOverListener;
+//import jalview.javascript.MouseOverStructureListener;
import jalview.schemes.ColourSchemeProperty;
import jalview.schemes.UserColourScheme;
import jalview.structure.SelectionListener;
import jalview.structure.StructureSelectionManager;
import jalview.util.MessageManager;
-import java.applet.Applet;
-import java.awt.Button;
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Font;
-import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.util.StringTokenizer;
import java.util.Vector;
-import netscape.javascript.JSException;
+import javax.swing.JApplet;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+
import netscape.javascript.JSObject;
+//import netscape.javascript.JSObject;
+
/**
* Jalview Applet. Runs in Java 1.18 runtime
*
* @author $author$
* @version $Revision: 1.92 $
*/
-public class JalviewLite extends Applet implements
+public class JalviewLite extends JApplet implements
StructureSelectionManagerProvider, JalviewLiteJsApi
{
public void scrollViewToColumnIn(final AlignFrame alf,
final String leftHandColumn)
{
- java.awt.EventQueue.invokeLater(new Runnable()
+ EventQueue.invokeLater(new Runnable()
{
@Override
String file2 = null;
- Button launcher = new Button(
+ JButton launcher = new JButton(
MessageManager.getString("label.start_jalview"));
/**
* turn on extra applet debugging
*/
debug = TRUE.equalsIgnoreCase(getParameter("debug"));
+
if (debug)
{
if (embedded)
{
LoadingThread loader = new LoadingThread(file, file2, this);
- loader.start();
+ /**
+ * @j2sNative
+ *
+ * loader.run();
+ */
+ {
+ loader.start();
+ }
}
else if (file != null)
{
{
notFailed = true;
}
- } catch (JSException jsex)
+ } catch (Exception jsex)
{
System.err.println("Attempt " + tries
+ " to access LiveConnect javascript failed.");
* @param height
* height of new frame
*/
- public static void addFrame(final Frame frame, String title, int width,
+ public static void addFrame(final JFrame frame, String title, int width,
int height)
{
frame.setLocation(lastFrameX, lastFrameY);
applet = _applet;
}
- public void run()
- {
- LoadJmolThread jmolchecker = new LoadJmolThread();
- jmolchecker.start();
- while (jmolchecker.notFinished())
- {
- // wait around until the Jmol check is complete.
- try
- {
- Thread.sleep(2);
- } catch (Exception e)
- {
- }
- }
- startLoading();
- // applet.callInitCallback();
- }
+ public void run() {
+ /**
+ *
+ * @j2sNative
+ *
+ *
+ * System.out.println("BYPASSING JMOL LOADING FOR NOW. THIS WILL BE DONE ANOTHER WAY")
+ *
+ */
+ {
+ LoadJmolThread jmolchecker = new LoadJmolThread();
+ jmolchecker.start();
+ while (jmolchecker.notFinished()) {
+ // wait around until the Jmol check is complete.
+ try {
+ Thread.sleep(2);
+ } catch (Exception e) {
+ }
+ }
+ }
+ startLoading();
+ // applet.callInitCallback();
+ }
/**
* Load the alignment and any related files as specified by applet
try
{
param = setProtocolState(param);
- JPredFile predictions = new JPredFile(param, protocol);
+ AlignFile predictions = GenericFileAdapter.getFile("JPredFile", param, protocol);
JnetAnnotationMaker.add_annotation(predictions,
alignFrame.viewport.getAlignment(), 0, false);
// false == do not add sequence profile from concise output
private String resolveUrlForLocalOrAbsolute(String url, URL localref)
{
String codebase = localref.toString();
- if (url.indexOf("/") == 0)
- {
- url = codebase.substring(0, codebase.length()
- - localref.getFile().length())
- + url;
- }
- else
- {
- url = localref + url;
- }
- return url;
+ // BH removing file name and query
+ int pt = codebase.indexOf("?");
+ if (pt < 0)
+ pt = codebase.length();
+ codebase = codebase.substring(0, pt);
+ codebase = codebase.substring(0, codebase.lastIndexOf("/") + 1);
+ // codebase is now http://...xxx/
+ if (url.indexOf("/") == 0 && !localref.getProtocol().equals("file"))
+ { // http:// https:// we do NOT allow going to the root file system directory!
+ pt = codebase.indexOf("/", 8);
+ return codebase.substring(0, pt) + url;
+ }
+ return codebase + url;
}
/**
*/
public class EditCommand implements CommandI
{
- public enum Action
+ public enum Action
{
INSERT_GAP
- {
- @Override
- public Action getUndoAction()
- {
- return DELETE_GAP;
- }
- },
+// {
+// @Override
+// public Action getUndoAction()
+// {
+// return DELETE_GAP;
+// }
+// }
+ ,
DELETE_GAP
- {
- @Override
- public Action getUndoAction()
- {
- return INSERT_GAP;
- }
- },
+// {
+// @Override
+// public Action getUndoAction()
+// {
+// return INSERT_GAP;
+// }
+// }
+ ,
CUT
- {
- @Override
- public Action getUndoAction()
- {
- return PASTE;
- }
- },
+// {
+// @Override
+// public Action getUndoAction()
+// {
+// return PASTE;
+// }
+// }
+ ,
PASTE
- {
- @Override
- public Action getUndoAction()
- {
- return CUT;
- }
- },
+// {
+// @Override
+// public Action getUndoAction()
+// {
+// return CUT;
+// }
+// }
+ ,
REPLACE
- {
- @Override
- public Action getUndoAction()
- {
- return REPLACE;
- }
- },
+// {
+// @Override
+// public Action getUndoAction()
+// {
+// return REPLACE;
+// }
+// }
+ ,
INSERT_NUC
- {
- @Override
- public Action getUndoAction()
- {
- return null;
- }
- };
- public abstract Action getUndoAction();
+// {
+// @Override
+// public Action getUndoAction()
+// {
+// return null;
+// }
+// }
+ ;
+ public Action getUndoAction() {
+ switch (this) {
+ case INSERT_GAP:
+ return DELETE_GAP;
+ case CUT:
+ return PASTE;
+ case DELETE_GAP:
+ return INSERT_GAP;
+ case INSERT_NUC:
+ return null;
+ case PASTE:
+ return CUT;
+ case REPLACE:
+ return REPLACE;
+ }
+ return null;
+ }
};
private List<Edit> edits = new ArrayList<Edit>();
import jalview.analysis.AlignmentUtils;
import jalview.io.FastaFile;
+import jalview.jsdev.GenericFileAdapter;
import jalview.util.Comparison;
import jalview.util.MessageManager;
/**
* Make an alignment from an array of Sequences.
*
+ *
* @param sequences
*/
public Alignment(SequenceI[] seqs)
{
initAlignment(seqs);
}
-
+
/**
* Make a new alignment from an array of SeqCigars
*
+ * no references in jalview?
+ *
+ * @j2sIgnore
+ *
* @param seqs
* SeqCigar[]
*/
}
/**
- * Returns the alignment in Fasta format. Behaviour of this method is not
- * guaranteed between versions.
- */
- @Override
- public String toString()
- {
- return new FastaFile().print(getSequencesArray());
- }
-
- /**
* Returns the set of distinct sequence names. No ordering is guaranteed.
*/
@Override
}
return names;
}
+
+ /**
+ * Returns the alignment in Fasta format. Behaviour of this method is not
+ * guaranteed between versions.
+ */
+ @Override
+ public String toString()
+ {
+ SequenceI[] seq = this.getSequencesArray();
+ /**
+ * @j2sNative
+ *
+ * return "" + JSON.stringify(seq);
+ */
+ {
+ return ((FastaFile) GenericFileAdapter.getFile("FastaFile")).print(seq);
+ }
+ }
+
}
}
else
{
- smsa = new SequenceI[1][];
+ smsa = new SequenceI[1][]; // BH this is fine; it's just int[n][], float[n][], etc. that are the problem.
smsa[0] = new SequenceI[sequences.length];
for (int s = 0; s < sequences.length; s++)
{
public Object[] getSequenceAndDeletions(String reference, char GapChar)
{
int rlength = 0;
- int[][] deletions = new int[length][];
+ int[][] deletions = javajs.util.AU.newInt2(length);// BH new int[length][];
int[][] trunc_deletions = null;
StringBuffer sq = new StringBuffer();
int cursor = 0, alcursor = 0, start = 0, startpos = 0, end = 0, endpos = 0, delcount = -1;
package jalview.datamodel;
import jalview.analysis.AlignSeq;
+import jalview.jsdev.api.RegExpInterface;
+import jalview.jsdev.api.VarnaRNA;
import jalview.schemes.ResidueProperties;
import jalview.util.Comparison;
import jalview.util.StringUtils;
import java.util.List;
import java.util.Vector;
-import com.stevesoft.pat.Regex;
+import jalview.jsdev.RegExp;
-import fr.orsay.lri.varna.models.rna.RNA;
+//import fr.orsay.lri.varna.models.rna.RNA;
/**
*
DBRefEntry[] dbrefs;
- RNA rna;
+ VarnaRNA rna;
/**
checkValidRange();
}
- Regex limitrx = new Regex("[/][0-9]{1,}[-][0-9]{1,}$");
+ RegExpInterface limitrx = RegExp.newRegex("[/][0-9]{1,}[-][0-9]{1,}$");
- Regex endrx = new Regex("[0-9]{1,}$");
+ RegExpInterface endrx = RegExp.newRegex("[0-9]{1,}$");
void parseId()
{
index = value;
}
- public void setRNA(RNA r)
+ public void setRNA(VarnaRNA r)
{
rna = r;
}
- public RNA getRNA()
+ public VarnaRNA getRNA()
{
return rna;
}
return result;
}
-
}
*/
package jalview.datamodel;
+import jalview.jsdev.api.VarnaRNA;
+
import java.util.List;
import java.util.Vector;
-import fr.orsay.lri.varna.models.rna.RNA;
+//import fr.orsay.lri.varna.models.rna.RNA;
/**
* Methods for manipulating a sequence, its metadata and related annotation in
* @return The RNA of the sequence in the alignment
*/
- public RNA getRNA();
+ public VarnaRNA getRNA();
/**
* @param rna
* The RNA.
*/
- public void setRNA(RNA rna);
+ public void setRNA(VarnaRNA rna);
/**
*
*/
package jalview.io;
-import java.io.PrintWriter;
-import java.io.StringWriter;
+import java.io.File;
import java.util.Enumeration;
import java.util.Hashtable;
* @param pw
* @param html
*/
- public void writeProperties(PrintWriter pw, boolean html)
+ public void writeProperties(StringBuffer sb, boolean html)
{
final String nl = html ? "<br>" : System.getProperty("line.separator");
float avg = 0;
}
}
avg = avg / alignment.getHeight();
- pw.print(nl);
- pw.print("Sequences: " + alignment.getHeight());
- pw.print(nl);
- pw.print("Minimum Sequence Length: " + min);
- pw.print(nl);
- pw.print("Maximum Sequence Length: " + max);
- pw.print(nl);
- pw.print("Average Length: " + (int) avg);
+ sb.append(nl);
+ sb.append("Sequences: " + alignment.getHeight());
+ sb.append(nl);
+ sb.append("Minimum Sequence Length: " + min);
+ sb.append(nl);
+ sb.append("Maximum Sequence Length: " + max);
+ sb.append(nl);
+ sb.append("Average Length: " + (int) avg);
if (((Alignment) alignment).alignmentProperties != null)
{
- pw.print(nl);
- pw.print(nl);
+ sb.append(nl);
+ sb.append(nl);
if (html)
{
- pw.print("<table border=\"1\">");
+ sb.append("<table border=\"1\">");
}
Hashtable props = ((Alignment) alignment).alignmentProperties;
Enumeration en = props.keys();
}
pos = npos + 1;
} while (npos != -1);
- pw.print("<tr><td>" + key + "</td><td>" + val + "</td></tr>");
+ sb.append("<tr><td>" + key + "</td><td>" + val + "</td></tr>");
}
else
{
- pw.print(nl + key + "\t" + vals);
+ sb.append(nl + key + "\t" + vals);
}
}
if (html)
{
- pw.print("</table>");
+ sb.append("</table>");
}
}
}
protected StringBuffer formatReport(boolean html)
{
- StringWriter content = new StringWriter();
- writeProperties(new PrintWriter(content), html);
- return content.getBuffer();
+ StringBuffer sb = new StringBuffer(); // BH was PrintBuffer
+ writeProperties(sb, html);
+ return sb;
}
/**
{
return formatReport(true);
}
-
+
}
import jalview.datamodel.HiddenSequences;
import jalview.datamodel.SequenceGroup;
import jalview.datamodel.SequenceI;
+import jalview.jsdev.GenericFileAdapter;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.ColourSchemeProperty;
import jalview.schemes.ResidueProperties;
import jalview.util.Format;
import java.io.BufferedReader;
-import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.StringReader;
-import java.net.URL;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Enumeration;
{
if (protocol.equals(AppletFormatAdapter.FILE))
{
- in = new BufferedReader(new FileReader(file));
+ in = GenericFileAdapter.getReader(file, false);
}
else if (protocol.equals(AppletFormatAdapter.URL))
{
- URL url = new URL(file);
- in = new BufferedReader(new InputStreamReader(url.openStream()));
+ in = GenericFileAdapter.getReader(file, true);
}
else if (protocol.equals(AppletFormatAdapter.PASTE))
{
java.io.InputStream is = getClass().getResourceAsStream("/" + file);
if (is != null)
{
- in = new BufferedReader(new java.io.InputStreamReader(is));
+ in = new BufferedReader(new InputStreamReader(is));
}
}
if (in != null)
import java.io.InputStream;
import java.util.List;
+import javajs.J2SIgnoreImport;
+
+import jalview.jsdev.Constants;
+import jalview.jsdev.GenericFileAdapter;
+
/**
* A low level class for alignment and feature IO with alignment formatting
* methods used by both applet and application for generating flat alignment
* @author $author$
* @version $Revision$
*/
+@J2SIgnoreImport({java.io.File.class})
public class AppletFormatAdapter
{
private AlignmentViewPanel viewpanel;
*/
public static final String[] READABLE_FORMATS = new String[]
{ "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "STH",
- "PDB", "JnetFile", "RNAML", PhylipFile.FILE_DESC, JSONFile.FILE_DESC, IdentifyFile.GFF3File,
+ "PDB", "JnetFile", "RNAML", Constants.Phylip_FILE_DESC, Constants.JSON_FILE_DESC, IdentifyFile.GFF3File,
"HTML" };
/**
*/
public static final String[] READABLE_EXTENSIONS = new String[]
{ "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
- "sto,stk", "xml,rnaml", PhylipFile.FILE_EXT, JSONFile.FILE_EXT,
+ "sto,stk", "xml,rnaml", Constants.Phylip_FILE_EXT, Constants.JSON_FILE_EXT,
".gff2,gff3",
- "jar,jvp", HtmlFile.FILE_EXT };
+ "jar,jvp", Constants.Html_FILE_EXT };
/**
* List of readable formats by application in order corresponding to
*/
public static final String[] READABLE_FNAMES = new String[]
{ "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "Stockholm",
- "RNAML", PhylipFile.FILE_DESC, JSONFile.FILE_DESC, IdentifyFile.GFF3File, "Jalview",
- HtmlFile.FILE_DESC };
+ "RNAML", Constants.Phylip_FILE_DESC, Constants.JSON_FILE_DESC, IdentifyFile.GFF3File, "Jalview",
+ Constants.Html_FILE_DESC };
/**
* List of valid format strings for use by callers of the formatSequences
*/
public static final String[] WRITEABLE_FORMATS = new String[]
{ "BLC", "CLUSTAL", "FASTA", "MSF", "PileUp", "PIR", "PFAM", "AMSA",
- "STH", PhylipFile.FILE_DESC, JSONFile.FILE_DESC };
+ "STH", Constants.Phylip_FILE_DESC, Constants.JSON_FILE_DESC };
/**
* List of extensions corresponding to file format types in WRITABLE_FNAMES
*/
public static final String[] WRITABLE_EXTENSIONS = new String[]
{ "fa, fasta, mfa, fastq", "aln", "pfam", "msf", "pir", "blc", "amsa",
- "sto,stk", PhylipFile.FILE_EXT, JSONFile.FILE_EXT, "jvp" };
+ "sto,stk", Constants.Phylip_FILE_EXT, Constants.JSON_FILE_EXT, "jvp" };
/**
* List of writable formats by the application. Order must correspond with the
*/
public static final String[] WRITABLE_FNAMES = new String[]
{ "Fasta", "Clustal", "PFAM", "MSF", "PIR", "BLC", "AMSA", "STH",
- PhylipFile.FILE_DESC, JSONFile.FILE_DESC, "Jalview" };
+ Constants.Phylip_FILE_DESC, Constants.JSON_FILE_DESC, "Jalview" };
public static String INVALID_CHARACTERS = "Contains invalid characters";
{
if (format.equals("FASTA"))
{
- alignFile = new FastaFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("FastaFile", inFile, type);
}
else if (format.equals("MSF"))
{
- alignFile = new MSFfile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("MSFfile", inFile, type);
}
else if (format.equals("PileUp"))
{
- alignFile = new PileUpfile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("PileUpfile", inFile, type);
}
else if (format.equals("CLUSTAL"))
{
- alignFile = new ClustalFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("ClustalFile", inFile, type);
}
else if (format.equals("BLC"))
{
- alignFile = new BLCFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("BLCFile", inFile, type);
}
else if (format.equals("PIR"))
{
- alignFile = new PIRFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("PIRFile", inFile, type);
}
else if (format.equals("PFAM"))
{
- alignFile = new PfamFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("PfamFile", inFile, type);
}
else if (format.equals("JnetFile"))
{
- alignFile = new JPredFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("JPredFile", inFile, type);
((JPredFile) alignFile).removeNonSequences();
}
else if (format.equals("PDB"))
}
else if (format.equals("STH"))
{
- alignFile = new StockholmFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("StockholmFile", inFile, type);
}
else if (format.equals("SimpleBLAST"))
{
- alignFile = new SimpleBlastFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("SimpleBlastFile", inFile, type);
}
else if (format.equals(PhylipFile.FILE_DESC))
{
- alignFile = new PhylipFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("PhylipFile", inFile, type);
}
- else if (format.equals(JSONFile.FILE_DESC))
+ else if (format.equals(Constants.JSON_FILE_DESC))
{
- alignFile = new JSONFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("JSONFile", inFile, type);
}
- else if (format.equals(HtmlFile.FILE_DESC))
+ else if (format.equals(Constants.Html_FILE_DESC))
{
- alignFile = new HtmlFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("HtmlFile", inFile, type);
}
else if (format.equals("RNAML"))
{
- alignFile = new RnamlFile(inFile, type);
+ alignFile = GenericFileAdapter.getFile("RnamlFile", inFile, type);
}
else if (format.equals(IdentifyFile.GFF3File))
{
- alignFile = new Gff3File(inFile, type);
+ alignFile = GenericFileAdapter.getFile("Gff3File", inFile, type);
}
return buildAlignmentFrom(alignFile);
} catch (Exception e)
try
{
// Possible sequence is just residues with no label
- alignFile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");
+ alignFile = GenericFileAdapter.getFile("FastaFile", ">UNKNOWN\n" + inFile, "Paste");
return buildAlignmentFrom(alignFile);
} catch (Exception ex)
{
if (format.equals("FASTA"))
{
- alignFile = new FastaFile(source);
+ alignFile = GenericFileAdapter.getFile("FastaFile", source);
}
else if (format.equals("MSF"))
{
- alignFile = new MSFfile(source);
+ alignFile = GenericFileAdapter.getFile("MSFfile", source);
}
else if (format.equals("PileUp"))
{
- alignFile = new PileUpfile(source);
+ alignFile = GenericFileAdapter.getFile("PileUpfile", source);
}
else if (format.equals("CLUSTAL"))
{
- alignFile = new ClustalFile(source);
+ alignFile = GenericFileAdapter.getFile("ClustalFile", source);
}
else if (format.equals("BLC"))
{
- alignFile = new BLCFile(source);
+ alignFile = GenericFileAdapter.getFile("BLCFile", source);
}
else if (format.equals("PIR"))
{
- alignFile = new PIRFile(source);
+ alignFile = GenericFileAdapter.getFile("PIRFile", source);
}
else if (format.equals("PFAM"))
{
- alignFile = new PfamFile(source);
+ alignFile = GenericFileAdapter.getFile("PfamFile", source);
}
else if (format.equals("JnetFile"))
{
- alignFile = new JPredFile(source);
+ alignFile = GenericFileAdapter.getFile("JPredFile", source);
((JPredFile) alignFile).removeNonSequences();
}
else if (format.equals("PDB"))
}
else if (format.equals("STH"))
{
- alignFile = new StockholmFile(source);
+ alignFile = GenericFileAdapter.getFile("StockholmFile", source);
}
else if (format.equals("RNAML"))
{
- alignFile = new RnamlFile(source);
+ alignFile = GenericFileAdapter.getFile("RnamlFile", source);
}
else if (format.equals("SimpleBLAST"))
{
- alignFile = new SimpleBlastFile(source);
+ alignFile = GenericFileAdapter.getFile("SimpleBlastFile", source);
}
- else if (format.equals(PhylipFile.FILE_DESC))
+ else if (format.equals(Constants.Phylip_FILE_DESC))
{
- alignFile = new PhylipFile(source);
+ alignFile = GenericFileAdapter.getFile("PhylipFile", source);
}
else if (format.equals(IdentifyFile.GFF3File))
{
- alignFile = new Gff3File(inFile, type);
+ alignFile = GenericFileAdapter.getFile("Gff3File", inFile, type);
}
- else if (format.equals(JSONFile.FILE_DESC))
+ else if (format.equals(Constants.JSON_FILE_DESC))
{
- alignFile = new JSONFile(source);
+ alignFile = GenericFileAdapter.getFile("JSONFile", source);
}
- else if (format.equals(HtmlFile.FILE_DESC))
+ else if (format.equals(Constants.Html_FILE_DESC))
{
- alignFile = new HtmlFile(source);
+ alignFile = GenericFileAdapter.getFile("HtmlFile", source);
}
return buildAlignmentFrom(alignFile);
try
{
// Possible sequence is just residues with no label
- alignFile = new FastaFile(">UNKNOWN\n" + inFile, "Paste");
+ alignFile = GenericFileAdapter.getFile("FastaFile", ">UNKNOWN\n" + inFile, "Paste");
return buildAlignmentFrom(alignFile);
} catch (Exception ex)
AlignFile afile = null;
if (format.equalsIgnoreCase("FASTA"))
{
- afile = new FastaFile();
+ afile = GenericFileAdapter.getFile("FastaFile");
}
else if (format.equalsIgnoreCase("MSF"))
{
- afile = new MSFfile();
+ afile = GenericFileAdapter.getFile("MSFfile");
}
else if (format.equalsIgnoreCase("PileUp"))
{
- afile = new PileUpfile();
+ afile = GenericFileAdapter.getFile("PileUpfile"); // BH NOTE LOWER CASE "file"
}
else if (format.equalsIgnoreCase("CLUSTAL"))
{
- afile = new ClustalFile();
+ afile = GenericFileAdapter.getFile("ClustalFile");
}
else if (format.equalsIgnoreCase("BLC"))
{
- afile = new BLCFile();
+ afile = GenericFileAdapter.getFile("BLCFile");
}
else if (format.equalsIgnoreCase("PIR"))
{
- afile = new PIRFile();
+ afile = GenericFileAdapter.getFile("PIRFile");
}
else if (format.equalsIgnoreCase("PFAM"))
{
- afile = new PfamFile();
+ afile = GenericFileAdapter.getFile("PfamFile");
}
else if (format.equalsIgnoreCase("STH"))
{
- afile = new StockholmFile(alignment);
+ afile = GenericFileAdapter.getFile("StockholmFile", alignment);
}
else if (format.equalsIgnoreCase("AMSA"))
{
- afile = new AMSAFile(alignment);
+ afile = GenericFileAdapter.getFile("AMSAFile", alignment);
}
- else if (format.equalsIgnoreCase(PhylipFile.FILE_DESC))
+ else if (format.equalsIgnoreCase(Constants.Phylip_FILE_DESC))
{
- afile = new PhylipFile();
+ afile = GenericFileAdapter.getFile("PhylipFile");
}
- else if (format.equalsIgnoreCase(JSONFile.FILE_DESC))
+ else if (format.equalsIgnoreCase(Constants.JSON_FILE_DESC))
{
- afile = new JSONFile();
+ afile = GenericFileAdapter.getFile("JSONFile");
}
else if (format.equalsIgnoreCase("RNAML"))
{
- afile = new RnamlFile();
+ afile = GenericFileAdapter.getFile("RnamlFile");
}
else
return protocol;
}
+ /**
+ * @j2sIgnore
+ *
+ * @param args
+ */
public static void main(String[] args)
{
int i = 0;
*/
package jalview.io;
-import java.io.*;
+import jalview.datamodel.Alignment;
+import jalview.datamodel.AlignmentAnnotation;
+import jalview.datamodel.Annotation;
+import jalview.datamodel.Sequence;
+import jalview.datamodel.SequenceI;
-import jalview.datamodel.*;
+import java.io.IOException;
/**
* DOCUMENT ME!
import jalview.datamodel.SequenceDummy;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
+import jalview.jsdev.GenericFileAdapter;
import jalview.schemes.AnnotationColourGradient;
import jalview.schemes.GraduatedColor;
import jalview.schemes.UserColourScheme;
} catch (IOException q)
{
}
- FastaFile parser = new FastaFile(this);
+ AlignFile parser = GenericFileAdapter.getFile("FastaFile");
List<SequenceI> includedseqs = parser.getSeqs();
SequenceIdMatcher smatcher = new SequenceIdMatcher(newseqs);
// iterate over includedseqs, and replacing matching ones with newseqs
import java.net.URL;
import java.util.zip.GZIPInputStream;
+import javajs.J2SIgnoreImport;
+
/**
* implements a random access wrapper around a particular datasource, for
* passing to identifyFile and AlignFile objects.
*/
+@J2SIgnoreImport({java.io.File.class, java.io.FileReader.class, java.io.FileInputStream.class })
public class FileParse
{
/**
* Attempt to open a file as a datasource. Sets error and errormessage if
* fileStr was invalid.
*
+ * Not used by applet
+ *
+ * @j2sIgnore
+ *
* @param fileStr
* @return this.error (true if the source was invalid)
*/
}
;
}
-
dataIn = new BufferedReader(new FileReader(fileStr));
dataName = fileStr;
}
return error;
}
+ /**
+ *
+ * @param inputStream
+ * @return
+ * @throws Exception
+ */
private BufferedReader tryAsGzipSource(InputStream inputStream)
throws Exception
{
* @throws MalformedURLException
* @throws IOException
*/
- public FileParse(String fileStr, String type)
- throws MalformedURLException, IOException
- {
- this.type = type;
- error = false;
-
- if (type.equals(AppletFormatAdapter.FILE))
- {
- if (checkFileSource(fileStr))
- {
- String suffixLess = extractSuffix(fileStr);
- if (suffixLess != null)
- {
- if (checkFileSource(suffixLess))
- {
- throw new IOException(MessageManager.formatMessage("exception.problem_opening_file_also_tried", new String[]{inFile.getName(),suffixLess,errormessage}));
- }
- }
- else
- {
- throw new IOException(MessageManager.formatMessage("exception.problem_opening_file", new String[]{inFile.getName(),errormessage}));
- }
- }
- }
- else if (type.equals(AppletFormatAdapter.URL))
- {
- try
- {
- try
- {
- checkURLSource(fileStr);
- if (suffixSeparator == '#')
- {
- extractSuffix(fileStr); // URL lref is stored for later reference.
- }
- } catch (IOException e)
- {
- String suffixLess = extractSuffix(fileStr);
- if (suffixLess == null)
- {
- throw (e);
- }
- else
- {
- try
- {
- checkURLSource(suffixLess);
- } catch (IOException e2)
- {
- errormessage = "BAD URL WITH OR WITHOUT SUFFIX";
- throw (e); // just pass back original - everything was wrong.
- }
- }
- }
- } catch (Exception e)
- {
- errormessage = "CANNOT ACCESS DATA AT URL '" + fileStr + "' ("
- + e.getMessage() + ")";
- error = true;
- }
- }
- else if (type.equals(AppletFormatAdapter.PASTE))
- {
- errormessage = "PASTE INACCESSIBLE!";
- dataIn = new BufferedReader(new StringReader(fileStr));
- dataName = "Paste";
- }
- else if (type.equals(AppletFormatAdapter.CLASSLOADER))
- {
- errormessage = "RESOURCE CANNOT BE LOCATED";
- java.io.InputStream is = getClass()
- .getResourceAsStream("/" + fileStr);
- if (is == null)
- {
- String suffixLess = extractSuffix(fileStr);
- if (suffixLess != null)
- {
- is = getClass().getResourceAsStream("/" + suffixLess);
- }
- }
- if (is != null)
- {
- dataIn = new BufferedReader(new java.io.InputStreamReader(is));
- dataName = fileStr;
- }
- else
- {
- error = true;
- }
- }
- else
- {
- errormessage = "PROBABLE IMPLEMENTATION ERROR : Datasource Type given as '"
- + (type != null ? type : "null") + "'";
- error = true;
- }
- if (dataIn == null || error)
- {
- // pass up the reason why we have no source to read from
- throw new IOException(MessageManager.formatMessage("exception.failed_to_read_data_from_source", new String[]{errormessage}));
- }
- error = false;
- dataIn.mark(READAHEAD_LIMIT);
- }
+ public FileParse(String fileStr, String type) throws MalformedURLException, IOException {
+ this.type = type;
+ error = false;
+
+ if (type.equals(AppletFormatAdapter.FILE)) {
+ /**
+ * @j2sIgnore
+ *
+ */
+ {
+ if (checkFileSource(fileStr)) {
+ String suffixLess = extractSuffix(fileStr);
+ if (suffixLess != null) {
+ if (checkFileSource(suffixLess)) {
+ throw new IOException(MessageManager.formatMessage(
+ "exception.problem_opening_file_also_tried", new String[] {
+ inFile.getName(), suffixLess, errormessage }));
+ }
+ } else {
+ throw new IOException(MessageManager.formatMessage(
+ "exception.problem_opening_file",
+ new String[] { inFile.getName(), errormessage }));
+ }
+ }
+ }
+ } else if (type.equals(AppletFormatAdapter.URL)) {
+ try {
+ try {
+ checkURLSource(fileStr);
+ if (suffixSeparator == '#') {
+ extractSuffix(fileStr); // URL lref is stored for later reference.
+ }
+ } catch (IOException e) {
+ String suffixLess = extractSuffix(fileStr);
+ if (suffixLess == null) {
+ throw (e);
+ } else {
+ try {
+ checkURLSource(suffixLess);
+ } catch (IOException e2) {
+ errormessage = "BAD URL WITH OR WITHOUT SUFFIX";
+ throw (e); // just pass back original - everything was wrong.
+ }
+ }
+ }
+ } catch (Exception e) {
+ errormessage = "CANNOT ACCESS DATA AT URL '" + fileStr + "' ("
+ + e.getMessage() + ")";
+ error = true;
+ }
+ } else if (type.equals(AppletFormatAdapter.PASTE)) {
+ errormessage = "PASTE INACCESSIBLE!";
+ dataIn = new BufferedReader(new StringReader(fileStr));
+ dataName = "Paste";
+ } else if (type.equals(AppletFormatAdapter.CLASSLOADER)) {
+ errormessage = "RESOURCE CANNOT BE LOCATED";
+ java.io.InputStream is = getClass().getResourceAsStream("/" + fileStr);
+ if (is == null) {
+ String suffixLess = extractSuffix(fileStr);
+ if (suffixLess != null) {
+ is = getClass().getResourceAsStream("/" + suffixLess);
+ }
+ }
+ if (is != null) {
+ dataIn = new BufferedReader(new java.io.InputStreamReader(is));
+ dataName = fileStr;
+ } else {
+ error = true;
+ }
+ } else {
+ errormessage = "PROBABLE IMPLEMENTATION ERROR : Datasource Type given as '"
+ + (type != null ? type : "null") + "'";
+ error = true;
+ }
+ if (dataIn == null || error) {
+ // pass up the reason why we have no source to read from
+ throw new IOException(MessageManager.formatMessage(
+ "exception.failed_to_read_data_from_source",
+ new String[] { errormessage }));
+ }
+ error = false;
+ dataIn.mark(READAHEAD_LIMIT);
+ }
/**
* mark the current position in the source as start for the purposes of it
*/
package jalview.io;
+import jalview.jsdev.Constants;
+import jalview.jsdev.GenericFileAdapter;
+
import java.io.IOException;
/**
break;
}
// if (data.matches("<(\"[^\"]*\"|'[^']*'|[^'\">])*>"))
- if (data.matches("<(?i)html(\"[^\"]*\"|'[^']*'|[^'\">])*>"))
+ if (data.matches("<HTML(\"[^\"]*\"|'[^']*'|[^'\">])*>")) // BH was (?i)rnaml, but JavaScript regex does not support (?i); data is already upper case
{
- reply = HtmlFile.FILE_DESC;
+ reply = Constants.Html_FILE_DESC;
break;
}
- if (data.matches("<(?i)rnaml (\"[^\"]*\"|'[^']*'|[^'\">])*>"))
+ if (data.matches("<RNAML (\"[^\"]*\"|'[^']*'|[^'\">])*>")) // BH was (?i)rnaml, but JavaScript regex does not support (?i); data is already upper case
{
reply = "RNAML";
break;
if (data.indexOf("{\"") > -1)
{
- reply = JSONFile.FILE_DESC;
+ reply = Constants.JSON_FILE_DESC;
break;
}
if ((data.length() < 1) || (data.indexOf("#") == 0))
}
else if (data.matches("\\s*\\d+\\s+\\d+\\s*"))
{
- reply = PhylipFile.FILE_DESC;
+ reply = Constants.Phylip_FILE_DESC;
break;
}
return reply;
}
+ /**
+ * @j2sIgnore
+ *
+ * @param args
+ */
public static void main(String[] args)
{
public class JnetAnnotationMaker
{
- public static void add_annotation(JPredFile prediction, AlignmentI al,
+ public static void add_annotation(AlignFile prediction, AlignmentI al,
int firstSeq, boolean noMsa) throws Exception
{
- JnetAnnotationMaker.add_annotation(prediction, al, firstSeq, noMsa,
+ add_annotation(prediction, al, firstSeq, noMsa,
(int[]) null);
}
* mapping from columns in JPredFile prediction to residue number in
* al.getSequence(firstSeq)
*/
- public static void add_annotation(JPredFile prediction, AlignmentI al,
+ public static void add_annotation(AlignFile prediction, AlignmentI al,
int firstSeq, boolean noMsa, int[] delMap) throws Exception
{
int i = 0;
import jalview.datamodel.DBRefEntry;
import jalview.datamodel.DBRefSource;
import jalview.datamodel.SequenceI;
+import jalview.jsdev.RegExp;
+import jalview.jsdev.api.RegExpInterface;
-import com.stevesoft.pat.Regex;
+//import com.stevesoft.pat.Regex;
public class ModellerDescription
{
private resCode validResidueCode(String field)
{
Integer val = null;
- Regex r = new Regex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");
+ RegExpInterface r = RegExp.newRegex("\\s*((([-0-9]+).?)|FIRST|LAST|@)");
if (!r.search(field))
{
return null; // invalid
}
- String value = r.stringMatched(3);
+ String value = r.stringMatchedI(3);
if (value == null)
{
- value = r.stringMatched(1);
+ value = r.stringMatchedI(1);
}
// Cache.log.debug("from '" + field + "' matched '" + value +
// "'");
package jalview.io;
import jalview.datamodel.SequenceNode;
+import jalview.jsdev.RegExp;
+import jalview.jsdev.api.RegExpInterface;
import jalview.util.MessageManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.StringTokenizer;
-import com.stevesoft.pat.Regex;
+import javajs.J2SIgnoreImport;
+
+//import com.stevesoft.pat.Regex;
/**
* Parse a new hanpshire style tree Caveats: NHX files are NOT supported and the
* @author Jim Procter
* @version $Revision$
*/
+@J2SIgnoreImport({java.io.File.class, java.io.FileReader.class})
public class NewickFile extends FileParse
{
SequenceNode root;
boolean printRootInfo = true;
- private Regex[] NodeSafeName = new Regex[]
- { new Regex().perlCode("m/[\\[,:'()]/"), // test for
+ private RegExpInterface[] NodeSafeName = new RegExpInterface[]
+ { RegExp.perlCode("m/[\\[,:'()]/"), // test for
// requiring
// quotes
- new Regex().perlCode("s/'/''/"), // escaping quote
+ RegExp.perlCode("s/'/''/"), // escaping quote
// characters
- new Regex().perlCode("s/\\/w/_/") // unqoted whitespace
+ RegExp.perlCode("s/\\/w/_/") // unqoted whitespace
// transformation
};
return RootHasDistance;
}
- /**
- * parse the filesource as a newick file (new hampshire and/or extended)
- *
- * @throws IOException
- * with a line number and character position for badly formatted NH
- * strings
- */
- public void parse() throws IOException
- {
- String nf;
-
- { // fill nf with complete tree file
-
- StringBuffer file = new StringBuffer();
-
- while ((nf = nextLine()) != null)
- {
- file.append(nf);
- }
-
- nf = file.toString();
- }
-
- root = new SequenceNode();
-
- SequenceNode realroot = null;
- SequenceNode c = root;
-
- int d = -1;
- int cp = 0;
- // int flen = nf.length();
-
- String Error = null;
- String nodename = null;
- String commentString2 = null; // comments after simple node props
-
- float DefDistance = (float) 0.001; // @param Default distance for a node -
- // very very small
- int DefBootstrap = -1; // @param Default bootstrap for a node
-
- float distance = DefDistance;
- int bootstrap = DefBootstrap;
-
- boolean ascending = false; // flag indicating that we are leaving the
- // current node
-
- Regex majorsyms = new Regex(
- "[(\\['),;]");
-
- int nextcp = 0;
- int ncp = cp;
- boolean parsednodename = false;
- while (majorsyms.searchFrom(nf, cp) && (Error == null))
- {
- int fcp = majorsyms.matchedFrom();
- char schar;
- switch (schar = nf.charAt(fcp))
- {
- case '(':
-
- // ascending should not be set
- // New Internal node
- if (ascending)
- {
- Error = ErrorStringrange(Error, "Unexpected '('", 7, fcp, nf);
-
- continue;
- }
-
- ;
- d++;
-
- if (c.right() == null)
- {
- c.setRight(new SequenceNode(null, c, null, DefDistance,
- DefBootstrap, false));
- c = (SequenceNode) c.right();
- }
- else
- {
- if (c.left() != null)
- {
- // Dummy node for polytomy - keeps c.left free for new node
- SequenceNode tmpn = new SequenceNode(null, c, null, 0, 0, true);
- tmpn.SetChildren(c.left(), c.right());
- c.setRight(tmpn);
- }
-
- c.setLeft(new SequenceNode(null, c, null, DefDistance,
- DefBootstrap, false));
- c = (SequenceNode) c.left();
- }
-
- if (realroot == null)
- {
- realroot = c;
- }
-
- nodename = null;
- distance = DefDistance;
- bootstrap = DefBootstrap;
- cp = fcp + 1;
-
- break;
-
- // Deal with quoted fields
- case '\'':
-
- Regex qnodename = new Regex(
- "'([^']|'')+'");
-
- if (qnodename.searchFrom(nf, fcp))
- {
- int nl = qnodename.stringMatched().length();
- nodename = new String(qnodename.stringMatched().substring(1,
- nl - 1));
- // unpack any escaped colons
- Regex xpandquotes = Regex
- .perlCode("s/''/'/");
- String widernodename = xpandquotes.replaceAll(nodename);
- nodename = widernodename;
- // jump to after end of quoted nodename
- nextcp = fcp + nl + 1;
- parsednodename = true;
- }
- else
- {
- Error = ErrorStringrange(Error,
- "Unterminated quotes for nodename", 7, fcp, nf);
- }
-
- break;
-
- default:
- if (schar == ';')
- {
- if (d != -1)
- {
- Error = ErrorStringrange(Error, "Wayward semicolon (depth=" + d
- + ")", 7, fcp, nf);
- }
- // cp advanced at the end of default
- }
- if (schar == '[')
- {
- // node string contains Comment or structured/extended NH format info
- /*
- * if ((fcp-cp>1 && nf.substring(cp,fcp).trim().length()>1)) { // will
- * process in remains System.err.println("skipped text:
- * '"+nf.substring(cp,fcp)+"'"); }
- */
- // verify termination.
- Regex comment = new Regex("]");
- if (comment.searchFrom(nf, fcp))
- {
- // Skip the comment field
- nextcp = comment.matchedFrom() + 1;
- warningMessage = "Tree file contained comments which may confuse input algorithm.";
- break;
-
- // cp advanced at the end of default to nextcp, ncp is unchanged so
- // any node info can be read.
- }
- else
- {
- Error = ErrorStringrange(Error, "Unterminated comment", 3, fcp,
- nf);
- }
-
- ;
- }
- // Parse simpler field strings
- String fstring = nf.substring(ncp, fcp);
- // remove any comments before we parse the node info
- // TODO: test newick file with quoted square brackets in node name (is
- // this allowed?)
- while (fstring.indexOf(']') > -1)
- {
- int cstart = fstring.indexOf('[');
- int cend = fstring.indexOf(']');
- commentString2 = fstring.substring(cstart + 1, cend);
- fstring = fstring.substring(0, cstart)
- + fstring.substring(cend + 1);
-
- }
- Regex uqnodename = new Regex(
- "\\b([^' :;\\](),]+)");
- Regex nbootstrap = new Regex(
- "\\s*([0-9+]+)\\s*:");
- Regex ndist = new Regex(
- ":([-0-9Ee.+]+)");
-
- if (!parsednodename
- && uqnodename.search(fstring)
- && ((uqnodename.matchedFrom(1) == 0) || (fstring
- .charAt(uqnodename.matchedFrom(1) - 1) != ':'))) // JBPNote
- // HACK!
- {
- if (nodename == null)
- {
- if (ReplaceUnderscores)
- {
- nodename = uqnodename.stringMatched(1).replace('_', ' ');
- }
- else
- {
- nodename = uqnodename.stringMatched(1);
- }
- }
- else
- {
- Error = ErrorStringrange(Error,
- "File has broken algorithm - overwritten nodename", 10,
- fcp, nf);
- }
- }
- // get comment bootstraps
-
- if (nbootstrap.search(fstring))
- {
- if (nbootstrap.stringMatched(1).equals(
- uqnodename.stringMatched(1)))
- {
- nodename = null; // no nodename here.
- }
- if (nodename == null
- || nodename.length() == 0
- || nbootstrap.matchedFrom(1) > (uqnodename.matchedFrom(1) + uqnodename
- .stringMatched().length()))
- {
- try
- {
- bootstrap = (new Integer(nbootstrap.stringMatched(1)))
- .intValue();
- HasBootstrap = true;
- } catch (Exception e)
- {
- Error = ErrorStringrange(Error,
- "Can't parse bootstrap value", 4,
- ncp + nbootstrap.matchedFrom(), nf);
- }
- }
- }
-
- boolean nodehasdistance = false;
-
- if (ndist.search(fstring))
- {
- try
- {
- distance = (new Float(ndist.stringMatched(1))).floatValue();
- HasDistances = true;
- nodehasdistance = true;
- } catch (Exception e)
- {
- Error = ErrorStringrange(Error,
- "Can't parse node distance value", 7,
- ncp + ndist.matchedFrom(), nf);
- }
- }
-
- if (ascending)
- {
- // Write node info here
- c.setName(nodename);
- // Trees without distances still need a render distance
- c.dist = (HasDistances) ? distance : DefDistance;
- // be consistent for internal bootstrap defaults too
- c.setBootstrap((HasBootstrap) ? bootstrap : DefBootstrap);
- if (c == realroot)
- {
- RootHasDistance = nodehasdistance; // JBPNote This is really
- // UGLY!!! Ensure root node gets
- // its given distance
- }
- parseNHXNodeProps(c, commentString2);
- commentString2 = null;
- }
- else
- {
- // Find a place to put the leaf
- SequenceNode newnode = new SequenceNode(null, c, nodename,
- (HasDistances) ? distance : DefDistance,
- (HasBootstrap) ? bootstrap : DefBootstrap, false);
- parseNHXNodeProps(c, commentString2);
- commentString2 = null;
-
- if (c.right() == null)
- {
- c.setRight(newnode);
- }
- else
- {
- if (c.left() == null)
- {
- c.setLeft(newnode);
- }
- else
- {
- // Insert a dummy node for polytomy
- // dummy nodes have distances
- SequenceNode newdummy = new SequenceNode(null, c, null,
- (HasDistances ? 0 : DefDistance), 0, true);
- newdummy.SetChildren(c.left(), newnode);
- c.setLeft(newdummy);
- }
- }
- }
-
- if (ascending)
- {
- // move back up the tree from preceding closure
- c = c.AscendTree();
-
- if ((d > -1) && (c == null))
- {
- Error = ErrorStringrange(
- Error,
- "File broke algorithm: Lost place in tree (is there an extra ')' ?)",
- 7, fcp, nf);
- }
- }
-
- if (nf.charAt(fcp) == ')')
- {
- d--;
- ascending = true;
- }
- else
- {
- if (nf.charAt(fcp) == ',')
- {
- if (ascending)
- {
- ascending = false;
- }
- else
- {
- // Just advance focus, if we need to
- if ((c.left() != null) && (!c.left().isLeaf()))
- {
- c = (SequenceNode) c.left();
- }
- }
- }
- }
-
- // Reset new node properties to obvious fakes
- nodename = null;
- distance = DefDistance;
- bootstrap = DefBootstrap;
- commentString2 = null;
- parsednodename = false;
- }
- if (nextcp == 0)
- {
- ncp = cp = fcp + 1;
- }
- else
- {
- cp = nextcp;
- nextcp = 0;
- }
- }
-
- if (Error != null)
- {
- throw (new IOException(MessageManager.formatMessage("exception.newfile", new String[]{Error.toString()})));
- }
- if (root == null)
- {
- throw (new IOException(MessageManager.formatMessage("exception.newfile", new String[]{MessageManager.getString("label.no_tree_read_in")})));
- }
- // THe next line is failing for topali trees - not sure why yet. if
- // (root.right()!=null && root.isDummy())
- root = (SequenceNode) root.right().detach(); // remove the imaginary root.
-
- if (!RootHasDistance)
- {
- root.dist = (HasDistances) ? 0 : DefDistance;
- }
- }
+ /**
+ * parse the filesource as a newick file (new hampshire and/or extended)
+ *
+ * @throws IOException
+ * with a line number and character position for badly formatted NH
+ * strings
+ */
+ public void parse() throws IOException {
+ String nf;
+
+ { // fill nf with complete tree file
+
+ StringBuffer file = new StringBuffer();
+
+ while ((nf = nextLine()) != null) {
+ file.append(nf);
+ }
+
+ nf = file.toString();
+ }
+
+ root = new SequenceNode();
+
+ SequenceNode realroot = null;
+ SequenceNode c = root;
+
+ int d = -1;
+ int cp = 0;
+ // int flen = nf.length();
+
+ String Error = null;
+ String nodename = null;
+ String commentString2 = null; // comments after simple node props
+
+ float DefDistance = (float) 0.001; // @param Default distance for a node -
+ // very very small
+ int DefBootstrap = -1; // @param Default bootstrap for a node
+
+ float distance = DefDistance;
+ int bootstrap = DefBootstrap;
+
+ boolean ascending = false; // flag indicating that we are leaving the
+ // current node
+
+ RegExpInterface majorsyms = RegExp.newRegex("[(\\['),;]");
+
+ int nextcp = 0;
+ int ncp = cp;
+ boolean parsednodename = false;
+ while (majorsyms.searchFrom(nf, cp) && (Error == null)) {
+ int fcp = majorsyms.matchedFrom();
+ char schar;
+ switch (schar = nf.charAt(fcp)) {
+ case '(':
+
+ // ascending should not be set
+ // New Internal node
+ if (ascending) {
+ Error = ErrorStringrange(Error, "Unexpected '('", 7, fcp, nf);
+
+ continue;
+ }
+
+ ;
+ d++;
+
+ if (c.right() == null) {
+ c.setRight(new SequenceNode(null, c, null, DefDistance, DefBootstrap,
+ false));
+ c = (SequenceNode) c.right();
+ } else {
+ if (c.left() != null) {
+ // Dummy node for polytomy - keeps c.left free for new node
+ SequenceNode tmpn = new SequenceNode(null, c, null, 0, 0, true);
+ tmpn.SetChildren(c.left(), c.right());
+ c.setRight(tmpn);
+ }
+
+ c.setLeft(new SequenceNode(null, c, null, DefDistance, DefBootstrap,
+ false));
+ c = (SequenceNode) c.left();
+ }
+
+ if (realroot == null) {
+ realroot = c;
+ }
+
+ nodename = null;
+ distance = DefDistance;
+ bootstrap = DefBootstrap;
+ cp = fcp + 1;
+
+ break;
+
+ // Deal with quoted fields
+ case '\'':
+
+ RegExpInterface qnodename = RegExp.newRegex("'([^']|'')+'");
+
+ if (qnodename.searchFrom(nf, fcp)) {
+ int nl = qnodename.stringMatched().length();
+ nodename = new String(qnodename.stringMatched().substring(1, nl - 1));
+ // unpack any escaped colons
+ RegExpInterface xpandquotes = RegExp.perlCode("s/''/'/");
+ String widernodename = xpandquotes.replaceAll(nodename);
+ nodename = widernodename;
+ // jump to after end of quoted nodename
+ nextcp = fcp + nl + 1;
+ parsednodename = true;
+ } else {
+ Error = ErrorStringrange(Error, "Unterminated quotes for nodename",
+ 7, fcp, nf);
+ }
+
+ break;
+
+ default:
+ if (schar == ';') {
+ if (d != -1) {
+ Error = ErrorStringrange(Error, "Wayward semicolon (depth=" + d
+ + ")", 7, fcp, nf);
+ }
+ // cp advanced at the end of default
+ }
+ if (schar == '[') {
+ // node string contains Comment or structured/extended NH format info
+ /*
+ * if ((fcp-cp>1 && nf.substring(cp,fcp).trim().length()>1)) { // will
+ * process in remains System.err.println("skipped text:
+ * '"+nf.substring(cp,fcp)+"'"); }
+ */
+ // verify termination.
+ RegExpInterface comment = RegExp.newRegex("]");
+ if (comment.searchFrom(nf, fcp)) {
+ // Skip the comment field
+ nextcp = comment.matchedFrom() + 1;
+ warningMessage = "Tree file contained comments which may confuse input algorithm.";
+ break;
+
+ // cp advanced at the end of default to nextcp, ncp is unchanged so
+ // any node info can be read.
+ } else {
+ Error = ErrorStringrange(Error, "Unterminated comment", 3, fcp, nf);
+ }
+
+ ;
+ }
+ // Parse simpler field strings
+ String fstring = nf.substring(ncp, fcp);
+ // remove any comments before we parse the node info
+ // TODO: test newick file with quoted square brackets in node name (is
+ // this allowed?)
+ while (fstring.indexOf(']') > -1) {
+ int cstart = fstring.indexOf('[');
+ int cend = fstring.indexOf(']');
+ commentString2 = fstring.substring(cstart + 1, cend);
+ fstring = fstring.substring(0, cstart) + fstring.substring(cend + 1);
+
+ }
+ RegExpInterface uqnodename = RegExp.newRegex("\\b([^' :;\\](),]+)");
+ RegExpInterface nbootstrap = RegExp.newRegex("\\s*([0-9+]+)\\s*:");
+ RegExpInterface ndist = RegExp.newRegex(":([-0-9Ee.+]+)");
+
+ if (!parsednodename
+ && uqnodename.search(fstring)
+ && ((uqnodename.matchedFromI(1) == 0) || (fstring.charAt(uqnodename
+ .matchedFromI(1) - 1) != ':'))) // JBPNote
+ // HACK!
+ {
+ if (nodename == null) {
+ if (ReplaceUnderscores) {
+ nodename = uqnodename.stringMatchedI(1).replace('_', ' ');
+ } else {
+ nodename = uqnodename.stringMatchedI(1);
+ }
+ } else {
+ Error = ErrorStringrange(Error,
+ "File has broken algorithm - overwritten nodename", 10, fcp, nf);
+ }
+ }
+ // get comment bootstraps
+
+ if (nbootstrap.search(fstring)) {
+ if (nbootstrap.stringMatchedI(1).equals(uqnodename.stringMatchedI(1))) {
+ nodename = null; // no nodename here.
+ }
+ if (nodename == null
+ || nodename.length() == 0
+ || nbootstrap.matchedFromI(1) > (uqnodename.matchedFromI(1) + uqnodename
+ .stringMatched().length())) {
+ try {
+ bootstrap = (new Integer(nbootstrap.stringMatchedI(1)))
+ .intValue();
+ HasBootstrap = true;
+ } catch (Exception e) {
+ Error = ErrorStringrange(Error, "Can't parse bootstrap value", 4,
+ ncp + nbootstrap.matchedFrom(), nf);
+ }
+ }
+ }
+
+ boolean nodehasdistance = false;
+
+ if (ndist.search(fstring)) {
+ try {
+ distance = (new Float(ndist.stringMatchedI(1))).floatValue();
+ HasDistances = true;
+ nodehasdistance = true;
+ } catch (Exception e) {
+ Error = ErrorStringrange(Error, "Can't parse node distance value",
+ 7, ncp + ndist.matchedFrom(), nf);
+ }
+ }
+
+ if (ascending) {
+ // Write node info here
+ c.setName(nodename);
+ // Trees without distances still need a render distance
+ c.dist = (HasDistances) ? distance : DefDistance;
+ // be consistent for internal bootstrap defaults too
+ c.setBootstrap((HasBootstrap) ? bootstrap : DefBootstrap);
+ if (c == realroot) {
+ RootHasDistance = nodehasdistance; // JBPNote This is really
+ // UGLY!!! Ensure root node gets
+ // its given distance
+ }
+ parseNHXNodeProps(c, commentString2);
+ commentString2 = null;
+ } else {
+ // Find a place to put the leaf
+ SequenceNode newnode = new SequenceNode(null, c, nodename,
+ (HasDistances) ? distance : DefDistance,
+ (HasBootstrap) ? bootstrap : DefBootstrap, false);
+ parseNHXNodeProps(c, commentString2);
+ commentString2 = null;
+
+ if (c.right() == null) {
+ c.setRight(newnode);
+ } else {
+ if (c.left() == null) {
+ c.setLeft(newnode);
+ } else {
+ // Insert a dummy node for polytomy
+ // dummy nodes have distances
+ SequenceNode newdummy = new SequenceNode(null, c, null,
+ (HasDistances ? 0 : DefDistance), 0, true);
+ newdummy.SetChildren(c.left(), newnode);
+ c.setLeft(newdummy);
+ }
+ }
+ }
+
+ if (ascending) {
+ // move back up the tree from preceding closure
+ c = c.AscendTree();
+
+ if ((d > -1) && (c == null)) {
+ Error = ErrorStringrange(
+ Error,
+ "File broke algorithm: Lost place in tree (is there an extra ')' ?)",
+ 7, fcp, nf);
+ }
+ }
+
+ if (nf.charAt(fcp) == ')') {
+ d--;
+ ascending = true;
+ } else {
+ if (nf.charAt(fcp) == ',') {
+ if (ascending) {
+ ascending = false;
+ } else {
+ // Just advance focus, if we need to
+ if ((c.left() != null) && (!c.left().isLeaf())) {
+ c = (SequenceNode) c.left();
+ }
+ }
+ }
+ }
+
+ // Reset new node properties to obvious fakes
+ nodename = null;
+ distance = DefDistance;
+ bootstrap = DefBootstrap;
+ commentString2 = null;
+ parsednodename = false;
+ }
+ if (nextcp == 0) {
+ ncp = cp = fcp + 1;
+ } else {
+ cp = nextcp;
+ nextcp = 0;
+ }
+ }
+
+ if (Error != null) {
+ throw (new IOException(MessageManager.formatMessage("exception.newfile",
+ new String[] { Error.toString() })));
+ }
+ if (root == null) {
+ throw (new IOException(MessageManager.formatMessage("exception.newfile",
+ new String[] { MessageManager.getString("label.no_tree_read_in") })));
+ }
+ // THe next line is failing for topali trees - not sure why yet. if
+ // (root.right()!=null && root.isDummy())
+ root = (SequenceNode) root.right().detach(); // remove the imaginary root.
+
+ if (!RootHasDistance) {
+ root.dist = (HasDistances) ? 0 : DefDistance;
+ }
+ }
/**
* parse NHX codes in comment strings and update NewickFile state flags for
}
// Test
+ /**
+ * @J2SIgnore
+ * @param args
+ */
public static void main(String[] args)
{
try
trf.parse();
System.out.println("Original file :\n");
- Regex nonl = new Regex("\n+", "");
+ RegExpInterface nonl = RegExp.newRegex("\n+", "");
System.out.println(nonl.replaceAll(newickfile.toString()) + "\n");
System.out.println("Parsed file.\n");
;
if (scriptObject != null)
{
- if (jvlite.debug && dbgMsg != null)
+ if (JalviewLite.debug && dbgMsg != null)
{
System.err.println(dbgMsg);
}
import jalview.structure.SelectionListener;
import jalview.structure.SelectionSource;
+import netscape.javascript.JSException;
+
public class JsSelectionSender extends JSFunctionExec implements
SelectionListener, JsCallBack
{
--- /dev/null
+package jalview.jsdev;
+
+/**
+ * note: not all file openers have corresponding String inFile and FileParse source options. Why not?
+ *
+ * @author RM
+ *
+ */
+abstract public class Constants {
+
+ public final static String TCOFFEE_SCORE = "TCoffeeScore";
+
+ public static final int Phylip_FILE = 1;
+
+ public static final String Phylip_FILE_EXT = "phy";
+
+ public static final String Phylip_FILE_DESC = "PHYLIP";
+
+ public static final int JSON_FILE = 2;
+
+ public static final String JSON_FILE_EXT = "json";
+
+ public static final String JSON_FILE_DESC = "JSON";
+
+ public static final int Html_FILE = 3;
+
+ public static final String Html_FILE_EXT = "html";
+
+ public static final String Html_FILE_DESC = "HTML";
+
+}
--- /dev/null
+package jalview.jsdev;
+
+import jalview.datamodel.AlignmentI;
+import jalview.io.AlignFile;
+import jalview.io.FileParse;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+
+import javajs.J2SIgnoreImport;
+/**
+ * A class to open files via reflection so that their classes are only loaded as necessary
+ *
+ * note: not all file openers have corresponding String inFile and FileParse
+ * source options. Why not?
+ *
+ * note: Pileupfile does not have a capital "F"; the method below requires that,
+ * so if that file name gets changed, so too does the reflection code here.
+ *
+ * @author Bob Hanson
+ *
+ */
+
+@J2SIgnoreImport({java.io.FileReader.class})
+abstract public class GenericFileAdapter extends AlignFile {
+
+ /**
+ * inFileOrSource class type
+ *
+ * @param inFileOrSource
+ * type will determine constructor -- [], [AlignmentI],
+ * [inFile,type], or [source]
+ * @param type
+ * @param fileName
+ * @return
+ */
+ public static AlignFile getFile(String fileType, Object... params) {
+ Class<?> cl = null;
+ try {
+ cl = Class.forName("jalview.io." + fileType);
+ } catch (ClassNotFoundException e) {
+ System.err.println("did not find file jalview.io." + fileType);
+ return null;
+ }
+ Constructor<?> m;
+ Throwable ex = null;
+ try {
+ switch (params.length) {
+ case 0:
+ return (AlignFile) cl.newInstance();
+ case 1:
+ m = (params[0] instanceof FileParse ? cl
+ .getConstructor(FileParse.class) : cl
+ .getConstructor(AlignmentI.class));
+ break;
+ case 2:
+ m = cl.getConstructor(String.class, String.class);
+ break;
+ default:
+ return null;
+ }
+ return (AlignFile) m.newInstance(params);
+ } catch (InstantiationException e) {
+ ex = e;
+ } catch (IllegalAccessException e) {
+ ex = e;
+ } catch (NoSuchMethodException e) {
+ ex = e;
+ } catch (SecurityException e) {
+ ex = e;
+ } catch (IllegalArgumentException e) {
+ ex = e;
+ } catch (InvocationTargetException e) {
+ ex = e;
+ }
+ if (ex != null) {
+ System.err.println("Error in GenericFileAdapter: " + ex);
+ /**
+ * @j2sNative
+ *
+ * alert(ex)
+ *
+ */
+ {
+ ex.printStackTrace();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Determines whether or not we have a JavaScript applet.
+ *
+ * @return
+ */
+ public static boolean isJS() {
+ /**
+ * @j2sNative
+ *
+ * return true;
+ *
+ */
+ {
+ return false;
+ }
+ }
+
+ /**
+ * opens a file for line-oriented reading via File() or URL()
+ *
+ * @param fileName
+ * @param forceURL
+ * @return
+ * @throws IOException
+ */
+ public static BufferedReader getReader(String fileName, boolean forceURL) throws IOException {
+ if (!forceURL && !isJS())
+ return new BufferedReader(new FileReader(fileName));
+ if (fileName.indexOf("//") < 0)
+ fileName = "file://" + fileName;
+ return new BufferedReader(new InputStreamReader(new URL(fileName).openStream()));
+ }
+
+
+}
--- /dev/null
+package jalview.jsdev;
+
+import jalview.jsdev.api.RegExpInterface;
+
+/**
+ * The JavaScript RegEx methods
+ *
+ * @author Bob Hanson
+ *
+ */
+public class JSRegex implements RegExpInterface {
+
+ @Override
+ public int charsMatched() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public String left() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public int matchedFrom() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int matchedFromI(int pos) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int matchedTo() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int matchedToI(int pos) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public int numSubs() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public String replaceAll(String string) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public boolean search(String str) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean searchFrom(String string, int rematchat) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public void setIgnoreCase(boolean b) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public String stringMatched() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public String stringMatchedI(int i) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+}
--- /dev/null
+package jalview.jsdev;
+
+/**
+ * The JavaScript RegEx methods
+ *
+ * @author Bob Hanson
+ *
+ */
+public interface JavaScriptRegExp {
+
+ String[] exec(String str);
+
+ boolean test(String str);
+
+ String[] match(String str);
+
+}
--- /dev/null
+package jalview.jsdev;
+
+import com.stevesoft.pat.Regex;
+
+import jalview.jsdev.api.RegExpInterface;
+
+/**
+ * an intermediary working class allowing options other than com.stevesoft.pat.Regex
+ *
+ * @author Bob Hanson
+ *
+ */
+public class RegExp {
+
+ RegExpInterface rg;
+
+ public static RegExpInterface newRegex(String... params) {
+ return new Regex(params.length < 1 ? null : params[0],
+ params.length < 2 ? "" : params[1]);
+ }
+
+ public static RegExpInterface perlCode(String s) {
+ return Regex.perlCode(s);
+ }
+
+}
--- /dev/null
+package jalview.jsdev.api;
+
+/**
+ * all methods of com.stevesoft.pat.Regex called within Jalview
+ *
+ * @author Bob Hanson
+ *
+ */
+public interface RegExpInterface {
+
+ public abstract int charsMatched();
+
+ public abstract String left();
+
+ public abstract int matchedFrom();
+
+ public abstract int matchedFromI(int pos);
+
+ public abstract int matchedTo();
+
+ public abstract int matchedToI(int pos);
+
+ public abstract int numSubs();
+
+ public abstract String replaceAll(String string);
+
+ public abstract boolean search(String str);
+
+ public abstract boolean searchFrom(String string, int rematchat);
+
+ public abstract void setIgnoreCase(boolean b);
+
+ public abstract String stringMatched();
+
+ public abstract String stringMatchedI(int i);
+
+}
\ No newline at end of file
--- /dev/null
+package jalview.jsdev.api;
+
+public interface VarnaRNA {
+
+}
}
/**
- * DOCUMENT ME!
+ * @j2sIgnore
*
* @param args
- * DOCUMENT ME!
*/
public static void main(String[] args) throws Exception
{
}
/**
- * DOCUMENT ME!
+ * @j2sIgnore
*
* @param args
- * DOCUMENT ME!
*/
public static void main(String[] args)
{
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.Annotation;
import jalview.datamodel.ColumnSelection;
+import jalview.jsdev.RegExp;
+import jalview.jsdev.api.RegExpInterface;
import jalview.schemes.ColourSchemeI;
import jalview.schemes.NucleotideColourScheme;
import jalview.schemes.ResidueProperties;
import java.util.BitSet;
import java.util.Hashtable;
-import com.stevesoft.pat.Regex;
+//import com.stevesoft.pat.Regex;
public class AnnotationRenderer
{
int sCol = (lastSSX / charWidth) + startRes;
int x1 = lastSSX;
int x2 = (x * charWidth);
- Regex closeparen = new Regex("(\\))");
+ RegExpInterface closeparen = RegExp.newRegex("(\\))");
char dc = (column == 0 || row_annotations[column - 1] == null) ? ' '
: row_annotations[column - 1].secondaryStructure;
int sCol = (lastSSX / charWidth) + startRes;
int x1 = lastSSX;
int x2 = (x * charWidth);
- Regex closeparen = new Regex("}|]|<|[a-z]");
+ RegExpInterface closeparen = RegExp.newRegex("}|]|<|[a-z]");
String dc = (column == 0 || row_annotations[column - 1] == null) ? ""
: row_annotations[column - 1].displayCharacter;
return Color.red;
}
- /**
- * DOCUMENT ME!
- *
- * @param n
- * DOCUMENT ME!
- * @param j
- * DOCUMENT ME!
- *
- * @return DOCUMENT ME!
- */
- @Override
- public Color findColour(char c, int j, SequenceI seq)
- {
- Color currentColour = Color.white;
- AlignmentAnnotation annotation = (seqAssociated && seqannot!=null ? seqannot.get(seq)
- : this.annotation);
- if (annotation == null)
- {
- return currentColour;
- }
- if ((threshold == 0) || aboveThreshold(c, j))
- {
- if (annotation.annotations != null
- && j < annotation.annotations.length
- && annotation.annotations[j] != null
- && !Comparison.isGap(c))
- {
- Annotation aj = annotation.annotations[j];
- // 'use original colours' => colourScheme != null
- // -> look up colour to be used
- // predefined colours => preconfigured shading
- // -> only use original colours reference if thresholding enabled &
- // minmax exists
- // annotation.hasIcons => null or black colours replaced with glyph
- // colours
- // -> reuse original colours if present
- // -> if thresholding enabled then return colour on non-whitespace glyph
-
- if (aboveAnnotationThreshold == NO_THRESHOLD
- || (annotationThreshold != null && (aboveAnnotationThreshold == ABOVE_THRESHOLD ? aj.value >= annotationThreshold.value
- : aj.value <= annotationThreshold.value)))
- {
- if (predefinedColours && aj.colour != null
- && !aj.colour.equals(Color.black))
- {
- currentColour = aj.colour;
- }
- else if (annotation.hasIcons
- && annotation.graph == AlignmentAnnotation.NO_GRAPH)
- {
- if (aj.secondaryStructure > ' ' && aj.secondaryStructure != '.'
- && aj.secondaryStructure != '-')
- {
- if (colourScheme != null)
- {
- currentColour = colourScheme.findColour(c, j, seq);
- }
- else
- {
- if (annotation.isRNA())
- {
- currentColour = ColourSchemeProperty.rnaHelices[(int) aj.value];
- }
- else
- {
- currentColour = annotation.annotations[j].secondaryStructure == 'H' ? AnnotationRenderer.HELIX_COLOUR
- : annotation.annotations[j].secondaryStructure == 'E' ? AnnotationRenderer.SHEET_COLOUR
- : AnnotationRenderer.STEM_COLOUR;
- }
- }
- }
- else
- {
- //
- return Color.white;
- }
- }
- else if (noGradient)
- {
- if (colourScheme != null)
- {
- currentColour = colourScheme.findColour(c, j, seq);
- }
- else
- {
- if (aj.colour != null)
- {
- currentColour = aj.colour;
- }
- }
- }
- else
- {
- currentColour = shadeCalculation(annotation, j);
- }
- }
- if (conservationColouring)
- {
- currentColour = applyConservation(currentColour, j);
- }
- }
- }
- return currentColour;
- }
+ /**
+ * DOCUMENT ME!
+ *
+ * @param n
+ * DOCUMENT ME!
+ * @param j
+ * DOCUMENT ME!
+ *
+ * @return DOCUMENT ME!
+ */
+ @Override
+ public Color findColour(char c, int j, SequenceI seq) {
+ Color currentColour = Color.white;
+ AlignmentAnnotation annotation = (seqAssociated && seqannot != null ? seqannot
+ .get(seq) : this.annotation);
+ if (annotation == null) {
+ return currentColour;
+ }
+ if ((threshold == 0) || aboveThreshold(c, j)) {
+ if (annotation.annotations != null && j < annotation.annotations.length
+ && annotation.annotations[j] != null && !Comparison.isGap(c)) {
+ Annotation aj = annotation.annotations[j];
+ // 'use original colours' => colourScheme != null
+ // -> look up colour to be used
+ // predefined colours => preconfigured shading
+ // -> only use original colours reference if thresholding enabled &
+ // minmax exists
+ // annotation.hasIcons => null or black colours replaced with glyph
+ // colours
+ // -> reuse original colours if present
+ // -> if thresholding enabled then return colour on non-whitespace glyph
+
+ if (aboveAnnotationThreshold == NO_THRESHOLD
+ || (annotationThreshold != null && (aboveAnnotationThreshold == ABOVE_THRESHOLD ? aj.value >= annotationThreshold.value
+ : aj.value <= annotationThreshold.value))) {
+ if (predefinedColours && aj.colour != null
+ && !aj.colour.equals(Color.black)) {
+ currentColour = aj.colour;
+ } else if (annotation.hasIcons
+ && annotation.graph == AlignmentAnnotation.NO_GRAPH) {
+ if (aj.secondaryStructure > ' ' && aj.secondaryStructure != '.'
+ && aj.secondaryStructure != '-') {
+ if (colourScheme != null) {
+ currentColour = colourScheme.findColour(c, j, seq);
+ } else {
+ if (annotation.isRNA()) {
+ currentColour = ColourSchemeProperty.rnaHelices[(int) aj.value];
+ } else {
+ currentColour = annotation.annotations[j].secondaryStructure == 'H' ? AnnotationRenderer.HELIX_COLOUR
+ : annotation.annotations[j].secondaryStructure == 'E' ? AnnotationRenderer.SHEET_COLOUR
+ : AnnotationRenderer.STEM_COLOUR;
+ }
+ }
+ } else {
+ //
+ return Color.white;
+ }
+ } else if (noGradient) {
+ if (colourScheme != null) {
+ currentColour = colourScheme.findColour(c, j, seq);
+ } else {
+ if (aj.colour != null) {
+ currentColour = aj.colour;
+ }
+ }
+ } else {
+ currentColour = shadeCalculation(annotation, j);
+ }
+ }
+ if (conservationColouring) {
+ currentColour = applyConservation(currentColour, j);
+ }
+ }
+ }
+ return currentColour;
+ }
private Color shadeCalculation(AlignmentAnnotation annotation, int j)
{
import java.util.Map;
import java.util.Vector;
+import javajs.J2SRequireImport;
+
import jalview.analysis.scoremodels.FeatureScoreModel;
import jalview.analysis.scoremodels.PIDScoreModel;
import jalview.api.analysis.ScoreModelI;
+// required because of the static defs
+
+@J2SRequireImport({ScoreMatrix.class, PIDScoreModel.class, FeatureScoreModel.class})
public class ResidueProperties
{
public static Hashtable<String, ScoreModelI> scoreMatrices = new Hashtable();
}
// and programmatically add in the ambiguity codes that yield the same amino
// acid
+
+
String[] unambcodons = codonHash2.keySet().toArray(
new String[codonHash2.size()]);
for (String codon : unambcodons)
// main method generates perl representation of residue property hash
// / cut here
+
+ /**
+ * @j2sIgnore
+ *
+ * @param args
+ */
public static void main(String[] args)
{
Hashtable aa = new Hashtable();
*/
package jalview.schemes;
-import jalview.analysis.SequenceIdMatcher;
import jalview.datamodel.AlignmentAnnotation;
import jalview.datamodel.AlignmentI;
import jalview.datamodel.AnnotatedCollectionI;
import jalview.datamodel.Annotation;
import jalview.datamodel.SequenceCollectionI;
import jalview.datamodel.SequenceI;
-import jalview.io.TCoffeeScoreFile;
+import jalview.jsdev.Constants;
import java.awt.Color;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Map;
-import java.util.TreeMap;
+//import jalview.io.TCoffeeScoreFile;
+//import java.util.TreeMap;
/**
* Defines the color score for T-Coffee MSA
: alignment.getContext();
int w = 0;
for (AlignmentAnnotation al : alcontext
- .findAnnotation(TCoffeeScoreFile.TCOFFEE_SCORE))
+ .findAnnotation(Constants.TCOFFEE_SCORE))
{
if (al.sequenceRef != null && !al.belowAlignment)
{
{
this.ssm = ssm;
this.sequence = sequenceIs;
- this.nucleotide = Comparison.isNucleotide(sequenceIs);
+ this.nucleotide = Comparison.isNucleotide2(sequenceIs);
this.chains = chains;
this.pdbEntry = pdbentry;
this.protocol = protocol;
return input;
}
+ /**
+ * @j2sIgnore
+ *
+ * @param args
+ */
public static void main(String[] arg)
{
new AWTConsole(); // create console with not reference
* @param seqs
* @return
*/
- public static boolean isNucleotide(SequenceI[][] seqs)
+ public static boolean isNucleotide2(SequenceI[][] seqs)
{
if (seqs == null)
{
import jalview.datamodel.DBRefSource;
import jalview.datamodel.PDBEntry;
import jalview.datamodel.SequenceI;
+import jalview.jsdev.RegExp;
+import jalview.jsdev.api.RegExpInterface;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import com.stevesoft.pat.Regex;
+//import com.stevesoft.pat.Regex;
public class DBRefUtils
{
* Check for PFAM style stockhom PDB accession id citation e.g.
* "1WRI A; 7-80;"
*/
- Regex r = new Regex(
+ RegExpInterface r = RegExp.newRegex(
"([0-9][0-9A-Za-z]{3})\\s*(.?)\\s*;\\s*([0-9]+)-([0-9]+)");
if (r.search(acn.trim()))
{
- String pdbid = r.stringMatched(1);
- String chaincode = r.stringMatched(2);
+ String pdbid = r.stringMatchedI(1);
+ String chaincode = r.stringMatchedI(2);
if (chaincode==null)
{
chaincode = " ";
import jalview.datamodel.Sequence;
import jalview.datamodel.SequenceI;
+import jalview.jsdev.RegExp;
+import jalview.jsdev.api.RegExpInterface;
import java.util.Hashtable;
-import com.stevesoft.pat.Regex;
+//import com.stevesoft.pat.Regex;
public class GroupUrlLink
{
regexReplace[pass] = link.substring(ptok[pass] + mlength, p);
try
{
- Regex rg = Regex.perlCode("/"
+ RegExpInterface rg = RegExp.perlCode("/"
+ regexReplace[pass] + "/");
if (rg == null)
{
// iterate through input, collating segments to be inserted into url
StringBuffer matched[] = new StringBuffer[idseq.length];
// and precompile regexes
- Regex[] rgxs = new Regex[matched.length];
+ RegExpInterface[] rgxs = new RegExpInterface[matched.length];
for (pass = 0; pass < matched.length; pass++)
{
matched[pass] = new StringBuffer();
if (regexReplace[pass] != null)
{
- rgxs[pass] = Regex.perlCode("/"
+ rgxs[pass] = RegExp.perlCode("/"
+ regexReplace[pass] + "/");
}
else
}
if (rgxs[pass] != null)
{
- Regex rg = rgxs[pass];
+ RegExpInterface rg = rgxs[pass];
int rematchat = 0;
// concatenate all matches of re in the given string!
while (rg.searchFrom(idseq[pass][sq], rematchat))
int s = 0; // 1;
while (s <= ns)
{
- if (s + 1 <= ns && rg.matchedTo(s) > -1
- && rg.matchedTo(s + 1) > -1
- && rg.matchedTo(s + 1) < rg.matchedTo(s))
+ if (s + 1 <= ns && rg.matchedToI(s) > -1
+ && rg.matchedToI(s + 1) > -1
+ && rg.matchedToI(s + 1) < rg.matchedToI(s))
{
// s is top level submatch. search for submatches enclosed by
// this one
int r = s + 1;
StringBuffer rmtch = new StringBuffer();
- while (r <= ns && rg.matchedTo(r) <= rg.matchedTo(s))
+ while (r <= ns && rg.matchedToI(r) <= rg.matchedToI(s))
{
- if (rg.matchedFrom(r) > -1)
+ if (rg.matchedFromI(r) > -1)
{
- rmtch.append(rg.stringMatched(r));
+ rmtch.append(rg.stringMatchedI(r));
}
r++;
}
}
else
{
- if (rg.matchedFrom(s) > -1)
+ if (rg.matchedFromI(s) > -1)
{
- subs.append(rg.stringMatched(s)); // concatenate
+ subs.append(rg.stringMatchedI(s)); // concatenate
}
s++;
}
}
}
+ /**
+ * @j2sIgnore
+ *
+ * @param args
+ */
public static void main(String argv[])
{
// note - JAL-1383 - these services are all dead
import java.util.logging.Level;
import java.util.logging.Logger;
+import javajs.J2SRequireImport;
+
/**
*
* @author David Roldan Martinez
*
*
*/
+@J2SRequireImport ({java.text.MessageFormat.class})
public class MessageManager
{
/* Getting messages for GV */
log.info("Getting messages for lang: " + loc);
rb = ResourceBundle.getBundle("lang.Messages", loc);
- if (log.isLoggable(Level.FINEST))
+ // BH rb == null just throws the exception
+ if (rb == null || log.isLoggable(Level.FINEST))
{
// this might take a while, so we only do it if it will be shown
log.finest("Language keys: " + rb.keySet());
public static String formatMessage(String key, Object... params)
{
- return MessageFormat.format(rb.getString(key), params);
+ return MessageFormat.format(getString(key), params); // BH not rb.getString
}
public static String formatMessage(String key, String[] params)
{
- return MessageFormat.format(rb.getString(key), (Object[]) params);
+ return MessageFormat.format(getString(key), (Object[]) params); // BH not rb.getString
}
/**
@Override
public int compare(Integer o1, Integer o2)
{
- return Float.compare(values[o1], values[o2]);
+ return Float.compare(values[o1.intValue()], values[o2]);
}
}
* @param arr
* @param s
*/
- public static void sortFloat(float[] arr, Object[] s)
+ public static void sortFloatObject(float[] arr, Object[] s)
{
sortFloat(arr, 0, arr.length - 1, s);
}
stringSort(arr, 0, arr.length - 1, s);
}
- static void stringSort(String[] arr, int p, int r, Object[] s)
+ private static void stringSort(String[] arr, int p, int r, Object[] s)
{
int q;
}
}
- static void sortFloat(float[] arr, int p, int r, Object[] s)
+ private static void sortFloat(float[] arr, int p, int r, Object[] s)
{
int q;
}
}
- static void sortDouble(double[] arr, int p, int r, Object[] s)
+ /**
+ * We don't need both of these
+ *
+ * @j2sIgnore
+ *
+ * @param arr
+ * @param p
+ * @param r
+ * @param s
+ */
+ private static void sortDouble(double[] arr, int p, int r, Object[] s)
{
int q;
}
}
- static void sortInt(int[] arr, int p, int r, Object[] s)
+ private static void sortInt(int[] arr, int p, int r, Object[] s)
{
int q;
}
}
- static int partitionFloat(float[] arr, int p, int r, Object[] s)
+ private static int partitionFloat(float[] arr, int p, int r, Object[] s)
{
float x = arr[p];
int i = p - 1;
}
}
- static int partitionFloat(float[] arr, int p, int r, char[] s)
+ private static int partitionFloatChar(float[] arr, int p, int r, char[] s)
{
float x = arr[p];
int i = p - 1;
}
}
- static int partitionInt(int[] arr, int p, int r, Object[] s)
+ private static int partitionInt(int[] arr, int p, int r, Object[] s)
{
int x = arr[p];
int i = p - 1;
}
}
- static int partitionDouble(double[] arr, int p, int r, Object[] s)
+ private static int partitionDouble(double[] arr, int p, int r, Object[] s)
{
double x = arr[p];
int i = p - 1;
}
}
- static int stringPartition(String[] arr, int p, int r, Object[] s)
+ private static int stringPartition(String[] arr, int p, int r, Object[] s)
{
String x = arr[p];
int i = p - 1;
* @param arr
* @param s
*/
- public static void sortFloat(float[] arr, char[] s)
+ public static void sortFloatChar(float[] arr, char[] s)
{
/*
* Sort all zero values to the front
float[] nonZeroFloats = Arrays
.copyOfRange(f1, nextZeroValue, f1.length);
char[] nonZeroChars = Arrays.copyOfRange(s1, nextZeroValue, s1.length);
- externalSort(nonZeroFloats, nonZeroChars);
+ externalSortFloat(nonZeroFloats, nonZeroChars);
// sort(nonZeroFloats, 0, nonZeroFloats.length - 1, nonZeroChars);
/*
* @param arr
* @param s
*/
- protected static void externalSort(float[] arr, char[] s)
+ private static void externalSortFloat(float[] arr, char[] s)
{
final int length = arr.length;
Integer[] indices = makeIndexArray(length);
* @param length
* @return
*/
- protected static Integer[] makeIndexArray(final int length)
+ private static Integer[] makeIndexArray(final int length)
{
Integer[] indices = new Integer[length];
for (int i = 0; i < length; i++)
return indices;
}
- static void sortFloat(float[] arr, int p, int r, char[] s)
- {
- int q;
- if (p < r)
- {
- q = partitionFloat(arr, p, r, s);
- sortFloat(arr, p, q, s);
- sortFloat(arr, q + 1, r, s);
- }
- }
-
+// private static void sortFloat(float[] arr, int p, int r, char[] s)
+// {
+// int q;
+// if (p < r)
+// {
+// q = partitionFloatChar(arr, p, r, s);
+// sortFloat(arr, p, q, s);
+// sortFloat(arr, q + 1, r, s);
+// }
+// }
+//
/**
* Sorts both arrays to give ascending order in the first array, by first
* partitioning into zero and non-zero values before sorting the latter.
* @param arr
* @param s
*/
- public static void sortInt(int[] arr, char[] s)
+ public static void sortIntChar(int[] arr, char[] s)
{
/*
* Sort all zero values to the front
int[] nonZeroInts = Arrays
.copyOfRange(f1, nextZeroValue, f1.length);
char[] nonZeroChars = Arrays.copyOfRange(s1, nextZeroValue, s1.length);
- externalSort(nonZeroInts, nonZeroChars);
+ externalSortInt(nonZeroInts, nonZeroChars);
// sort(nonZeroFloats, 0, nonZeroFloats.length - 1, nonZeroChars);
/*
* @param arr
* @param s
*/
- protected static void externalSort(int[] arr, char[] s)
+ private static void externalSortInt(int[] arr, char[] s)
{
final int length = arr.length;
Integer[] indices = makeIndexArray(length);
*/
package jalview.util;
+import jalview.jsdev.RegExp;
+import jalview.jsdev.api.RegExpInterface;
+
import java.util.Vector;
-import com.stevesoft.pat.Regex;
+//import com.stevesoft.pat.Regex;
public class UrlLink
{
regexReplace = link.substring(psqid + 14, p);
try
{
- Regex rg = Regex.perlCode("/"
+ RegExpInterface rg = RegExp.perlCode("/"
+ regexReplace + "/");
if (rg == null)
{
{
if (regexReplace != null)
{
- Regex rg = Regex.perlCode("/" + regexReplace + "/");
+ RegExpInterface rg = RegExp.perlCode("/" + regexReplace + "/");
if (rg.search(idstring))
{
int ns = rg.numSubs();
{
// take whole regex
return new String[]
- { rg.stringMatched(),
+ { rg.stringMatchedI(ns),
url_prefix + rg.stringMatched() + url_suffix };
} /*
* else if (ns==1) { // take only subgroup match return new String[]
// debug
for (int s = 0; s <= rg.numSubs(); s++)
{
- System.err.println("Sub " + s + " : " + rg.matchedFrom(s)
- + " : " + rg.matchedTo(s) + " : '"
- + rg.stringMatched(s) + "'");
+ System.err.println("Sub " + s + " : " + rg.matchedFromI(s)
+ + " : " + rg.matchedToI(s) + " : '"
+ + rg.stringMatchedI(s) + "'");
}
// try to collate subgroup matches
Vector subs = new Vector();
int s = 0; // 1;
while (s <= ns)
{
- if (s + 1 <= ns && rg.matchedTo(s) > -1
- && rg.matchedTo(s + 1) > -1
- && rg.matchedTo(s + 1) < rg.matchedTo(s))
+ if (s + 1 <= ns && rg.matchedToI(s) > -1
+ && rg.matchedToI(s + 1) > -1
+ && rg.matchedToI(s + 1) < rg.matchedToI(s))
{
// s is top level submatch. search for submatches enclosed by
// this one
int r = s + 1;
String mtch = "";
- while (r <= ns && rg.matchedTo(r) <= rg.matchedTo(s))
+ while (r <= ns && rg.matchedToI(r) <= rg.matchedToI(s))
{
- if (rg.matchedFrom(r) > -1)
+ if (rg.matchedFromI(r) > -1)
{
- mtch += rg.stringMatched(r);
+ mtch += rg.stringMatchedI(r);
}
r++;
}
}
else
{
- if (rg.matchedFrom(s) > -1)
+ if (rg.matchedFromI(s) > -1)
{
- subs.addElement(rg.stringMatched(s));
- subs.addElement(url_prefix + rg.stringMatched(s)
+ subs.addElement(rg.stringMatchedI(s));
+ subs.addElement(url_prefix + rg.stringMatchedI(s)
+ url_suffix);
}
s++;
}
}
+ /**
+ * @j2sIgnore
+ *
+ * @param args
+ */
public static void main(String argv[])
{
String[] links = new String[]
import jalview.datamodel.AlignmentI;
import jalview.datamodel.SequenceFeature;
import jalview.datamodel.SequenceI;
-import jalview.renderer.seqfeatures.FeatureRenderer;
import jalview.schemes.GraduatedColor;
import jalview.schemes.UserColourScheme;
import jalview.util.QuickSort;
*/
public void transferSettings(jalview.api.FeatureRenderer _fr)
{
- FeatureRenderer fr = (FeatureRenderer) _fr;
+ FeatureRendererModel fr = (FeatureRendererModel) _fr;
FeatureRendererSettings frs = new FeatureRendererSettings(fr);
this.renderOrder = frs.renderOrder;
this.featureGroups = frs.featureGroups;
}
if (iSize > 1 && sort)
{
- QuickSort.sortFloat(sortOrder, newf);
+ QuickSort.sortFloatObject(sortOrder, newf);
}
sortOrder = null;
System.arraycopy(newf, 0, renderOrder, opos, newf.length);
@Override
public void run()
{
+
if (calcMan.isPending(this))
{
return;
--- /dev/null
+package javajs;
+
+public @interface J2SIgnoreImport {
+
+ Class<?>[] value();
+
+}
--- /dev/null
+package javajs;
+
+public @interface J2SRequireImport {
+
+ Class<?>[] value();
+
+}
--- /dev/null
+package javajs.api;
+
+public interface BytePoster {
+
+ String postByteArray(String fileName, byte[] bytes);
+
+}
--- /dev/null
+package javajs.api;
+
+import javajs.util.V3;
+
+public interface EigenInterface {
+
+ EigenInterface setM(double[][] n);
+
+ double[] getEigenvalues();
+
+ void fillFloatArrays(V3[] eigenVectors, float[] eigenValues);
+
+ float[][] getEigenvectorsFloatTransposed();
+
+}
--- /dev/null
+package javajs.api;
+
+public interface EventManager {
+
+ boolean keyPressed(int keyCode, int modifiers);
+
+ boolean keyTyped(int keyChar, int modifiers);
+
+ void keyReleased(int keyCode);
+
+ void mouseEnterExit(long time, int x, int y, boolean isExit);
+
+ void mouseAction(int mode, long time, int x, int y, int count,
+ int buttonMods);
+
+}
--- /dev/null
+package javajs.api;
+
+import javajs.awt.Font;
+
+/**
+ * A generic interface for font queries.
+ * In JSmol it is handled by org.jmol.api.ApiPlatform
+ */
+
+public interface FontManager {
+
+ int fontStringWidth(Font font, String text);
+
+ int getFontAscent(Object fontMetrics);
+
+ int getFontDescent(Object fontMetrics);
+
+ Object getFontMetrics(Font font, Object graphics);
+
+ Object newFont(String fontFace, boolean isBold, boolean isItalic, float fontSize);
+
+
+}
--- /dev/null
+package javajs.api;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.util.Map;
+
+
+import javajs.util.OC;
+import javajs.util.SB;
+
+public interface GenericBinaryDocument {
+
+ void setStream(GenericZipTools jzt, BufferedInputStream bis, boolean isBigEndian);
+
+ void setStreamData(DataInputStream dataInputStream, boolean isBigEndian);
+
+ long getPosition();
+
+ SB getAllDataFiles(String binaryFileList, String firstFile);
+
+ void getAllDataMapped(String replace, String string, Map<String, String> fileData);
+
+ int swapBytesI(int nx);
+
+ short swapBytesS(short s);
+
+ void seek(long i);
+
+ byte readByte() throws Exception;
+
+ int readInt() throws Exception;
+
+ int readIntLE() throws Exception;
+
+ long readLong() throws Exception;
+
+ float readFloat() throws Exception;
+
+ double readDouble() throws Exception;
+
+ short readShort() throws Exception;
+
+ int readUnsignedShort() throws Exception;
+
+ String readString(int i) throws Exception;
+
+ int readByteArray(byte[] b, int off, int len) throws Exception;
+
+ void close();
+
+ void setOutputChannel(OC out);
+
+}
--- /dev/null
+package javajs.api;
+
+import java.io.BufferedReader;
+import java.util.Map;
+
+
+public interface GenericCifDataParser {
+
+ static final int NONE = -1;
+
+ String fullTrim(String str);
+
+ Map<String, Object> getAllCifData();
+
+ boolean getData() throws Exception;
+
+ String getField(int i);
+
+ int getFieldCount();
+
+ String getFileHeader();
+
+ String getLoopData(int i);
+
+ String getNextDataToken() throws Exception;
+
+ String getNextToken() throws Exception;
+
+ String getTokenPeeked();
+
+ int parseLoopParameters(String[] fields, int[] fieldOf, int[] propertyOf) throws Exception;
+
+ String peekToken() throws Exception;
+
+ String readLine();
+
+ GenericCifDataParser set(GenericLineReader reader, BufferedReader br);
+
+ String toUnicode(String data);
+
+ String skipLoop(boolean doReport) throws Exception;
+
+ String fixKey(String key);
+
+}
--- /dev/null
+package javajs.api;
+
+/**
+ * GenericColor allows both java.awt.Color and javajs.awt.Color to be
+ * handled by methods that need not distinguish between them. It is used
+ * in the javajs package for the background color of a javajs.swing.JComponent
+ *
+ * @author hansonr
+ *
+ */
+public interface GenericColor {
+
+ int getRGB();
+
+ int getOpacity255();
+
+ void setOpacity255(int a);
+
+}
--- /dev/null
+package javajs.api;
+
+public interface GenericFileInterface {
+
+ String getFullPath();
+
+ String getName();
+
+ long length();
+
+ boolean isDirectory();
+
+ GenericFileInterface getParentAsFile();
+
+}
--- /dev/null
+package javajs.api;
+
+public interface GenericImageDialog {
+
+ void closeMe();
+
+ void setImage(Object image);
+
+}
--- /dev/null
+package javajs.api;
+
+import java.util.Map;
+
+import javajs.util.OC;
+
+public interface GenericImageEncoder {
+
+ public boolean createImage(String type, OC out,
+ Map<String, Object> params) throws Exception;
+
+}
--- /dev/null
+package javajs.api;
+
+public interface GenericLineReader {
+ public String readNextLine() throws Exception;
+}
--- /dev/null
+package javajs.api;
+
+
+public interface GenericMenuInterface {
+
+ public void jpiDispose();
+ public Object jpiGetMenuAsObject();
+ public String jpiGetMenuAsString(String string);
+ public void jpiInitialize(PlatformViewer vwr, String menu);
+ public void jpiShow(int x, int y);
+ public void jpiUpdateComputedMenus();
+
+ public void menuClickCallback(SC source, String actionCommand);
+ public void menuFocusCallback(String name, String actionCommand, boolean b);
+ public void menuCheckBoxCallback(SC source);
+
+
+}
--- /dev/null
+package javajs.api;
+
+public interface GenericMouseInterface {
+
+ boolean processEvent(int id, int x, int y, int modifiers, long time);
+
+ void clear();
+
+ void dispose();
+
+ void processTwoPointGesture(float[][][] touches);
+
+}
--- /dev/null
+package javajs.api;
+
+
+import java.net.URL;
+import java.util.Map;
+
+
+import javajs.awt.Font;
+import javajs.util.P3;
+
+public interface GenericPlatform extends FontManager {
+
+ public final static int CURSOR_DEFAULT = 0;
+ public final static int CURSOR_CROSSHAIR = 1;
+ public final static int CURSOR_WAIT = 3;
+ public final static int CURSOR_ZOOM = 8;
+ public final static int CURSOR_HAND = 12;
+ public final static int CURSOR_MOVE = 13;
+
+ void setViewer(PlatformViewer vwr, Object display);
+
+ /////// Display
+
+ boolean isHeadless();
+
+ void convertPointFromScreen(Object display, P3 ptTemp);
+
+ void getFullScreenDimensions(Object display, int[] widthHeight);
+
+ boolean hasFocus(Object display);
+
+ String prompt(String label, String data, String[] list, boolean asButtons);
+
+ void repaint(Object display);
+
+ void requestFocusInWindow(Object display);
+
+ void setCursor(int i, Object display);
+
+ void setTransparentCursor(Object display);
+
+ //// Mouse
+
+ GenericMouseInterface getMouseManager(double privateKey, Object display);
+
+ ///// core Image handling
+
+ Object allocateRgbImage(int windowWidth, int windowHeight, int[] pBuffer,
+ int windowSize, boolean backgroundTransparent, boolean isImageWrite);
+
+ void disposeGraphics(Object graphicForText);
+
+ void drawImage(Object g, Object img, int x, int y, int width, int height);
+
+ int[] drawImageToBuffer(Object gObj, Object imageOffscreen,
+ Object image, int width, int height, int bgcolor);
+
+ void flushImage(Object imagePixelBuffer);
+
+ Object getStaticGraphics(Object image, boolean backgroundTransparent);
+
+ Object getGraphics(Object image);
+
+ int getImageWidth(Object image);
+
+ int getImageHeight(Object image);
+
+ Object newBufferedImage(Object image, int i, int height);
+
+ Object newOffScreenImage(int w, int h);
+
+ @Deprecated
+ void renderScreenImage(Object g, Object currentSize);
+
+ int[] getTextPixels(String text, Font font3d, Object gObj,
+ Object image, int mapWidth, int height,
+ int ascent);
+
+ ///// Image creation for export (optional for any platform)
+
+ /**
+ * can be ignored (return null) if platform cannot save images
+ *
+ * @param ret
+ * @return null only if this platform cannot save images
+ */
+ Object createImage(Object ret);
+
+ /**
+ *
+ * @param image
+ * @param width
+ * @param height
+ * @param pixels
+ * @param startRow
+ * @param nRows
+ * @return pixels
+ */
+ int[] grabPixels(Object image, int width, int height,
+ int[] pixels, int startRow, int nRows);
+
+ /**
+ * can be ignored (return false) if platform cannot save images
+ *
+ * @param boolIsEcho
+ * @param image
+ * @return false only if this platform cannot save images
+ * @throws InterruptedException
+ */
+ boolean waitForDisplay(Object boolIsEcho, Object image) throws InterruptedException;
+
+ GenericMenuInterface getMenuPopup(String menuStructure, char type);
+
+ Object getJsObjectInfo(Object[] jsObject, String method, Object[] args);
+
+ boolean isSingleThreaded();
+
+ void notifyEndOfRendering();
+
+ String getDateFormat(String isoType);
+
+ GenericFileInterface newFile(String name);
+
+ Object getBufferedFileInputStream(String name);
+
+ /**
+ *
+ * @param url
+ * @param outputBytes
+ * @param post
+ * @param asString
+ * @return may be javajs.util.SB or byte[] or java.io.InputStream
+ */
+ Object getURLContents(URL url, byte[] outputBytes, String post, boolean asString);
+
+ String getLocalUrl(String fileName);
+
+ GenericImageDialog getImageDialog(String title,
+ Map<String, GenericImageDialog> imageMap);
+
+}
--- /dev/null
+package javajs.api;
+
+
+import java.io.InputStream;
+import java.util.zip.ZipInputStream;
+
+public class GenericZipInputStream extends ZipInputStream implements ZInputStream {
+
+ public GenericZipInputStream(InputStream in) {
+ super(in);
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package javajs.api;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import java.util.Map;
+
+
+public interface GenericZipTools {
+
+ public ZInputStream newZipInputStream(InputStream is);
+
+ public String getZipDirectoryAsStringAndClose(BufferedInputStream t);
+
+ public InputStream newGZIPInputStream(InputStream bis) throws IOException;
+
+ public Object getZipFileDirectory(BufferedInputStream bis,
+ String[] subFileList, int listPtr, boolean asBufferedInputStream);
+
+ public String[] getZipDirectoryAndClose(BufferedInputStream t,
+ String manifestID);
+
+ public void getAllZipData(InputStream bis, String[] subFileList,
+ String replace, String string,
+ Map<String, String> fileData);
+
+ public Object getZipFileContentsAsBytes(BufferedInputStream bis,
+ String[] subFileList, int i);
+
+ public void addZipEntry(Object zos, String fileName) throws IOException;
+
+ public void closeZipEntry(Object zos) throws IOException;
+
+ public Object getZipOutputStream(Object bos);
+
+ public int getCrcValue(byte[] bytes);
+
+ public void readFileAsMap(BufferedInputStream is, Map<String, Object> bdata, String name);
+
+ public String cacheZipContents(BufferedInputStream bis, String shortName,
+ Map<String, Object> cache, boolean asByteArray);
+
+ BufferedInputStream getUnGzippedInputStream(byte[] bytes);
+}
--- /dev/null
+package javajs.api;
+
+public interface HTMLElement {
+
+}
--- /dev/null
+package javajs.api;
+
+/**
+ * The window.Event in HTML5
+ * See SwingController.
+ *
+ */
+public interface HTMLWindowEvent {
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Copyright (C) 2006 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package javajs.api;
+
+public class Interface {
+
+ public static Object getInterface(String name) {
+ try {
+ Class<?> x = Class.forName(name);
+ return (x == null ? null : x.newInstance());
+ } catch (Exception e) {
+ System.out.println("Interface.java Error creating instance for " + name + ": \n" + e);
+ return null;
+ }
+ }
+
+}
--- /dev/null
+package javajs.api;
+
+/**
+ * called by JSmol JavaScript methods using
+ *
+ * this._applet.xxxx()
+ *
+ */
+public interface JSInterface {
+
+ int cacheFileByName(String fileName, boolean isAdd);
+ void cachePut(String key, Object data);
+ void destroy();
+ String getFullName();
+ void openFileAsyncSpecial(String fileName, int flags);
+ boolean processMouseEvent(int id, int x, int y, int modifiers, long time);
+ void processTwoPointGesture(float[][][] touches);
+ void setDisplay(Object canvas);
+ void setScreenDimension(int width, int height);
+ boolean setStatusDragDropped(int mode, int x, int y, String fileName);
+ void startHoverWatcher(boolean enable);
+ void update();
+
+ // these are not general methods
+//Object getGLmolView();
+//String loadInlineString(String mol, String script, boolean isAppend);
+//String openFile(String fileName);
+
+}
+
--- /dev/null
+package javajs.api;
+
+public interface JSONEncodable {
+
+ String toJSON();
+
+}
--- /dev/null
+package javajs.api;
+
+/**
+ * methods in JSmol JavaScript accessed in Jmol
+ */
+public interface JmolObjectInterface {
+
+ Object _doAjax(Object url, String postOut, Object bytesOrStringOut);
+
+ void _apply(Object func, Object data);
+
+}
--- /dev/null
+package javajs.api;
+
+public interface PlatformViewer {
+
+// a placeholder for a class that might be used within classes called by Platform.java
+
+}
--- /dev/null
+package javajs.api;
+
+/**
+ * SwingComponent interface common to javax.swing and javajs.swing
+ *
+ * Can be augmented as needed, provided classes of javajs.swing are also
+ * updated. (SwingComponents in javajs are subclasses of AbstractButton.)
+ *
+ */
+
+public interface SC {
+
+ void add(SC item);
+
+ void addActionListener(Object owner);
+
+ void addItemListener(Object owner);
+
+ void addMouseListener(Object owner);
+
+ String getActionCommand();
+
+ Object getComponent(int i);
+
+ int getComponentCount();
+
+ Object[] getComponents();
+
+ String getName();
+
+ Object getParent();
+
+ Object getPopupMenu();
+
+ Object getIcon();
+
+ String getText();
+
+ void init(String text, Object icon, String actionCommand, SC popupMenu);
+
+ void insert(SC subMenu, int index);
+
+ boolean isEnabled();
+
+ boolean isSelected();
+
+ void remove(int i);
+
+ void removeAll();
+
+ void setActionCommand(String script);
+
+ void setAutoscrolls(boolean b);
+
+ void setEnabled(boolean enable);
+
+ void setIcon(Object icon);
+
+ void setName(String string);
+
+ void setSelected(boolean state);
+
+ void setText(String entry);
+
+}
--- /dev/null
+package javajs.api;
+
+import javajs.awt.Component;
+import javajs.awt.Dimension;
+
+/**
+ * SwingController is an interface that javajs.swing classes will need.
+ * It must be implemented as a JavaScript object PRIOR to
+ * any calls to create any components.
+ *
+ * In JSmol it is Jmol.Swing (see JsmolCore.js)
+ *
+ * There should be one and only one SwingController on a page.
+ * It is called by its class name "SwingController" directly.
+ *
+ * @author hansonr
+ *
+ */
+public interface SwingController {
+
+ /**
+ * Fired from clicking an element such as a button or
+ * check box or table entry, or from entering text in a text box.
+ *
+ * SwingController should make the changes in the underlying
+ * "Java" object directly, then send notification of the event to the manager.
+ * For instance:
+ *
+ * var component = Jmol.Swing.htDialogs[element.id];
+ * var info = component.toString();
+ *
+ * if (info.indexOf("JCheck") >= 0)
+ * component.selected = element.checked;
+ * var id = $("div.JDialog:has(#" + element.id + ")")[0].id
+ * var dialog = Jmol.Swing.htDialogs[id];
+ * dialog.manager.actionPerformed(component ? component.name : dialog.registryKey + "/" + element.id);
+ *
+ * @param element
+ * @param event
+ */
+ void click(HTMLElement element, HTMLWindowEvent event);
+
+
+ /**
+ * Remove this component's HTML5 equivalent and clear references to it.
+ *
+ * @param dialog
+ */
+ void dispose(Component dialog);
+
+ /**
+ * Return the width and height of the window in d.
+ * For example:
+ *
+ * d.width = $(window).width();
+ * d.height = $(window).height();
+ *
+ * @param d
+ */
+ void getScreenDimensions(Dimension d);
+
+ /**
+ * Set c's id to a unique identifier
+ * and add it to an associative array that will
+ * associate that id with c.
+ *
+ * @param c
+ * @param type
+ */
+ void register(Component c, String type);
+
+ /**
+ * The HTML for this dialog has been generated.
+ * Now create the HTML on the page for this dialog
+ * based on dialog.html and wrap it appropriately.
+ *
+ * @param dialog
+ */
+ void setDialog(Component dialog);
+
+ /**
+ * Convey to the HTML object that this check box's selection
+ * has been changed.
+ *
+ * $("#" + chk.id).prop('checked', !!chk.selected);
+ *
+ * @param chk
+ */
+ void setSelected(Component chk);
+
+ /**
+ * Convey to the HTML object that this combo box's selected item
+ * has been changed.
+ *
+ * $("#" + cmb.id).prop('selectedIndex', cmb.selectedIndex);
+ *
+ * @param cmb
+ */
+ void setSelectedIndex(Component cmb);
+
+ /**
+ * Convey to the HTML object that this component's text
+ * has been changed.
+ *
+ * $("#" + btn.id).prop('value', btn.text);
+ *
+ * @param text
+ */
+ void setText(String text);
+
+ /**
+ * Convey to the HTML object that this component's text
+ * has been changed.
+ *
+ * if (c.visible)
+ * $("#" + c.id).show();
+ * else
+ * $("#" + c.id).hide();
+ *
+ * @param c
+ */
+ void setVisible(Component c);
+
+ /**
+ * Called by clicking the [x] in the corner of the dialog;
+ * send a notification back to the manager via processWindowClosing(key)
+ *
+ * var id = $("div.JDialog:has(#" + element.id + ")")[0].id
+ * var dialog = Jmol.Swing.htDialogs[id];
+ * dialog.manager.processWindowClosing(dialog.registryKey);
+ *
+ * @param element
+ */
+ void windowClosing(HTMLElement element);
+
+}
--- /dev/null
+package javajs.api;
+
+public interface ZInputStream {
+ // placeholder for ZipInputStream not requiring direct access to java.util.zip
+
+}
--- /dev/null
+package javajs.awt;
+
+
+public class BorderLayout extends LayoutManager {
+
+ public static final String CENTER = "Center";
+ public static final String NORTH = "North";
+ public static final String SOUTH = "South";
+ public static final String EAST = "East";
+ public static final String WEST = "West";
+
+}
--- /dev/null
+package javajs.awt;
+
+import javajs.api.GenericColor;
+
+public class Color implements GenericColor {
+
+ public int argb;
+
+
+ @Override
+ public int getRGB() {
+ return argb & 0x00FFFFFF;
+ }
+
+
+ @Override
+ public int getOpacity255() {
+ return ((argb >> 24) & 0xFF);
+ }
+
+
+ @Override
+ public void setOpacity255(int a) {
+ argb = argb & 0xFFFFFF | ((a & 0xFF) << 24);
+ }
+
+ public static GenericColor get1(int rgb) {
+ Color c = new Color();
+ c.argb = rgb | 0xFF000000;
+ return c;
+ }
+
+ public static GenericColor get3(int r, int g, int b) {
+ return new Color().set4(r, g, b, 0xFF);
+ }
+
+ public static GenericColor get4(int r, int g, int b, int a) {
+ return new Color().set4(r, g, b, a);
+ }
+
+ private GenericColor set4(int r, int g, int b, int a) {
+ argb = ((a << 24) | (r << 16) | (g << 8) | b) & 0xFFFFFFFF;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ String s = ("00000000" + Integer.toHexString(argb));
+ return "[0x" + s.substring(s.length() - 8, s.length()) + "]";
+ }
+
+
+}
--- /dev/null
+package javajs.awt;
+
+import javajs.api.GenericColor;
+import javajs.util.CU;
+
+abstract public class Component {
+
+ protected boolean visible;
+ protected boolean enabled = true;
+ protected String text;
+ protected String name;
+ protected int width;
+ protected int height;
+ protected String id;
+
+ protected Object parent;
+
+ public void setParent(Object p) {
+ parent = p;
+ }
+
+ protected Object mouseListener;
+
+ private GenericColor bgcolor;
+
+ protected Component(String type) {
+ id = newID(type);
+ if (type == null)
+ return;
+ /**
+ * @j2sNative
+ * SwingController.register(this, type);
+ */
+ {
+ }
+
+ }
+
+ public static String newID(String type) {
+ return type + ("" + Math.random()).substring(3, 10);
+ }
+
+ abstract public String toHTML();
+
+ public void setBackground(GenericColor color) {
+ bgcolor = color;
+ }
+
+ public void setText(String text) {
+ this.text = text;
+ /**
+ * @j2sNative
+ *
+ * SwingController.setText(this);
+ *
+ */
+ {
+ }
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Object getParent() {
+ return parent;
+ }
+
+ public void setPreferredSize(Dimension dimension) {
+ this.width = dimension.width;
+ this.height = dimension.height;
+ }
+
+ public void addMouseListener(Object listener) {
+ mouseListener = listener;
+ }
+
+ public String getText() {
+ return text;
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ /**
+ * @j2sNative
+ *
+ * SwingController.setEnabled(this);
+ *
+ */
+ {}
+ }
+
+ public boolean isVisible() {
+ return visible;
+ }
+
+ public void setVisible(boolean visible) {
+ this.visible = visible;
+ /**
+ * @j2sNative
+ *
+ * SwingController.setVisible(this);
+ *
+ */
+ {}
+ }
+
+ public int getHeight() {
+ return height;
+ }
+
+ public int getWidth() {
+ return width;
+ }
+
+ protected int minWidth = 30;
+ protected int minHeight = 30;
+
+ public void setMinimumSize(Dimension d) {
+ minWidth = d.width;
+ minHeight = d.height;
+ }
+
+ public int getSubcomponentWidth() {
+ return width;
+ }
+
+ public int getSubcomponentHeight() {
+ return height;
+ }
+
+ protected int renderWidth;
+ protected int renderHeight;
+
+ protected String getCSSstyle(int defaultPercentW, int defaultPercentH) {
+ int width = (renderWidth > 0 ? renderWidth : getSubcomponentWidth());
+ int height = (renderHeight > 0 ? renderHeight : getSubcomponentHeight());
+ return (width > 0 ? "width:" + width +"px;" : defaultPercentW > 0 ? "width:"+defaultPercentW+"%;" : "")
+ + (height > 0 ?"height:" + height + "px;" : defaultPercentH > 0 ? "height:"+defaultPercentH+"%;" : "")
+ + (bgcolor == null ? "" : "background-color:" + CU.toCSSString(bgcolor) + ";");
+ }
+
+ public void repaint() {
+ // for inheritance
+ }
+
+}
--- /dev/null
+package javajs.awt;
+
+import javajs.util.Lst;
+
+abstract public class Container extends Component {
+
+ protected Lst<Component> list;
+
+ private Component[] cList;
+
+ protected Container(String type) {
+ super(type);
+ }
+
+ public Component getComponent(int i) {
+ return list.get(i);
+ }
+
+ public int getComponentCount() {
+ return (list == null ? 0 : list.size());
+ }
+
+ public Component[] getComponents() {
+ if (cList == null) {
+ if (list == null)
+ return new Component[0];
+ cList = (Component[]) list.toArray();
+ }
+ return cList;
+ }
+
+ public Component add(Component component) {
+ return addComponent(component);
+ }
+
+ protected Component addComponent(Component component) {
+ if (list == null)
+ list = new Lst<Component>();
+ list.addLast(component);
+ cList = null;
+ component.parent = this;
+ return component;
+ }
+
+ protected Component insertComponent(Component component, int index) {
+ if (list == null)
+ return addComponent(component);
+ list.add(index, component);
+ cList = null;
+ component.parent = this;
+ return component;
+ }
+
+ public void remove(int i) {
+ Component c = list.remove(i);
+ c.parent = null;
+ cList = null;
+ }
+
+ public void removeAll() {
+ if (list != null) {
+ for (int i = list.size(); --i >= 0;)
+ list.get(i).parent = null;
+ list.clear();
+ }
+ cList = null;
+ }
+
+ @Override
+ public int getSubcomponentWidth() {
+ return (list != null && list.size() == 1 ? list.get(0).getSubcomponentWidth() : 0);
+ }
+
+ @Override
+ public int getSubcomponentHeight() {
+ return (list != null && list.size() == 1 ? list.get(0).getSubcomponentHeight() : 0);
+ }
+
+}
--- /dev/null
+package javajs.awt;
+
+public class Dimension {
+
+ public int width;
+ public int height;
+
+ public Dimension(int w, int h) {
+ set(w, h);
+ }
+
+ public Dimension set(int w, int h) {
+ width = w;
+ height = h;
+ return this;
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2013-10-30 13:47:37 -0500 (Wed, 30 Oct 2013) $
+ * $Revision: 18874 $
+ *
+ * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.awt;
+
+
+import javajs.api.FontManager;
+import javajs.util.AU;
+
+
+/**
+ *<p>
+ * Provides font support using a byte fid
+ * (<strong>F</strong>ont <strong>ID</strong>) as an index into font table.
+ *</p>
+ *<p>
+ * Supports standard font faces, font styles, and font sizes.
+ *</p>
+ *
+ * @author Miguel, miguel@jmol.org
+ */
+final public class Font {
+
+ public final byte fid;
+ public final String fontFace;
+ public final String fontStyle;
+ public final float fontSizeNominal;
+ public final int idFontFace;
+ public final int idFontStyle;
+ public final float fontSize;
+ public final Object font;
+ private final Object fontMetrics;
+ private FontManager manager;
+ private int ascent;
+ private int descent;
+ private boolean isBold;
+ private boolean isItalic;
+
+ private Font(FontManager manager, byte fid, int idFontFace,
+ int idFontStyle, float fontSize, float fontSizeNominal, Object graphics) {
+ this.manager = manager;
+ this.fid = fid;
+ this.fontFace = fontFaces[idFontFace];
+ this.fontStyle = fontStyles[idFontStyle];
+ this.idFontFace = idFontFace;
+ this.idFontStyle = idFontStyle;
+ this.fontSize = fontSize;
+ this.isBold = (idFontStyle & FONT_STYLE_BOLD) == FONT_STYLE_BOLD;
+ this.isItalic = (idFontStyle & FONT_STYLE_ITALIC) == FONT_STYLE_ITALIC;
+ this.fontSizeNominal = fontSizeNominal;
+ font = manager.newFont(fontFaces[idFontFace], isBold, isItalic,
+ fontSize);
+ fontMetrics = manager.getFontMetrics(this, graphics);
+ descent = manager.getFontDescent(fontMetrics);
+ ascent = manager.getFontAscent(fontMetrics);
+
+ //System.out.println("font3d constructed for fontsizeNominal=" + fontSizeNominal + " and fontSize=" + fontSize);
+ }
+
+ ////////////////////////////////////////////////////////////////
+
+ private final static int FONT_ALLOCATION_UNIT = 8;
+ private static int fontkeyCount = 1;
+ private static int[] fontkeys = new int[FONT_ALLOCATION_UNIT];
+ private static Font[] font3ds = new Font[FONT_ALLOCATION_UNIT];
+
+ public static Font getFont3D(byte fontID) {
+ return font3ds[fontID & 0xFF];
+ }
+
+ public static synchronized Font createFont3D(int fontface, int fontstyle,
+ float fontsize, float fontsizeNominal,
+ FontManager manager, Object graphicsForMetrics) {
+ //if (graphicsForMetrics == null)
+ // return null;
+ if (fontsize > 0xFF)
+ fontsize = 0xFF;
+ int fontsizeX16 = ((int) fontsize) << 4;
+ int fontkey = ((fontface & 3) | ((fontstyle & 3) << 2) | (fontsizeX16 << 4));
+ // watch out for race condition here!
+ for (int i = fontkeyCount; --i > 0;)
+ if (fontkey == fontkeys[i]
+ && font3ds[i].fontSizeNominal == fontsizeNominal)
+ return font3ds[i];
+ int fontIndexNext = fontkeyCount++;
+ if (fontIndexNext == fontkeys.length)
+ fontkeys = AU.arrayCopyI(fontkeys, fontIndexNext + FONT_ALLOCATION_UNIT);
+ font3ds = (Font[]) AU.arrayCopyObject(font3ds, fontIndexNext + FONT_ALLOCATION_UNIT);
+ Font font3d = new Font(manager, (byte) fontIndexNext, fontface, fontstyle,
+ fontsize, fontsizeNominal, graphicsForMetrics);
+ // you must set the font3d before setting the fontkey in order
+ // to prevent a race condition with getFont3D
+ font3ds[fontIndexNext] = font3d;
+ fontkeys[fontIndexNext] = fontkey;
+ return font3d;
+ }
+
+ public final static int FONT_FACE_SANS = 0;
+ public final static int FONT_FACE_SERIF = 1;
+ public final static int FONT_FACE_MONO = 2;
+
+ private final static String[] fontFaces =
+ {"SansSerif", "Serif", "Monospaced", ""};
+
+ public final static int FONT_STYLE_PLAIN = 0;
+ public final static int FONT_STYLE_BOLD = 1;
+ public final static int FONT_STYLE_ITALIC = 2;
+ public final static int FONT_STYLE_BOLDITALIC = 3;
+
+ private final static String[] fontStyles =
+ {"Plain", "Bold", "Italic", "BoldItalic"};
+
+ public static int getFontFaceID(String fontface) {
+ return ("Monospaced".equalsIgnoreCase(fontface) ? FONT_FACE_MONO
+ : "Serif".equalsIgnoreCase(fontface) ? FONT_FACE_SERIF
+ : FONT_FACE_SANS);
+ }
+
+ public static int getFontStyleID(String fontstyle) {
+ for (int i = 4; --i >= 0; )
+ if (fontStyles[i].equalsIgnoreCase(fontstyle))
+ return i;
+ return -1;
+ }
+
+ public int getAscent() {
+ return ascent;
+ }
+
+ public int getDescent() {
+ return descent;
+ }
+
+ public int getHeight() {
+ return getAscent() + getDescent();
+ }
+
+ public Object getFontMetrics() {
+ return fontMetrics;
+ }
+
+ public int stringWidth(String text) {
+ return manager.fontStringWidth(this, text);
+ }
+
+ public String getInfo() {
+ return fontSizeNominal + " " + fontFace + " " + fontStyle;
+ }
+}
+
--- /dev/null
+package javajs.awt;
+
+public class LayoutManager {
+
+}
--- /dev/null
+package javajs.awt.event;
+
+
+public class ActionEvent extends Event {
+
+ private String actionCommand;
+
+ public String getActionCommand() {
+ return actionCommand;
+ }
+
+}
--- /dev/null
+package javajs.awt.event;
+
+
+public interface ActionListener {
+
+ public abstract void actionPerformed(ActionEvent event);
+
+}
--- /dev/null
+package javajs.awt.event;
+
+public class Event {
+
+ private Object source;
+
+ public Object getSource() {
+ return source;
+ }
+
+ public static final int MOUSE_LEFT = 16;
+ public static final int MOUSE_MIDDLE = 8; //Event.ALT_MASK;
+ public static final int MOUSE_RIGHT = 4; //Event.META_MASK;
+ public static final int MOUSE_WHEEL = 32;
+
+ public final static int MAC_COMMAND = MOUSE_LEFT | MOUSE_RIGHT;
+ public final static int BUTTON_MASK = MOUSE_LEFT | MOUSE_MIDDLE | MOUSE_RIGHT;
+
+ public static final int MOUSE_DOWN = 501; //InputEvent.MOUSE_DOWN;
+ public static final int MOUSE_UP = 502; //Event.MOUSE_UP;
+ public static final int MOUSE_MOVE = 503; //Event.MOUSE_MOVE;
+ public static final int MOUSE_ENTER = 504; //Event.MOUSE_ENTER;
+ public static final int MOUSE_EXIT = 505; //Event.MOUSE_EXIT;
+ public static final int MOUSE_DRAG = 506; //Event.MOUSE_DRAG;
+
+
+ public static final int SHIFT_MASK = 1;//InputEvent.SHIFT_MASK;
+ public static final int ALT_MASK = 8;//InputEvent.ALT_MASK;
+ public static final int CTRL_MASK = 2;//InputEvent.CTRL_MASK;
+
+ public final static int CTRL_ALT = CTRL_MASK | ALT_MASK;
+ public final static int CTRL_SHIFT = CTRL_MASK | SHIFT_MASK;
+
+ public static final int META_MASK = 4;//InputEvent.META_MASK;
+ public static final int VK_SHIFT = 16;//KeyEvent.VK_SHIFT;
+ public static final int VK_ALT = 18;//KeyEvent.VK_ALT;
+ public static final int VK_CONTROL = 17;//KeyEvent.VK_CONTROL;
+ public static final int VK_META = 157; // KeyEvent.VK_META;
+ public static final int VK_LEFT = 37;//KeyEvent.VK_LEFT;
+ public static final int VK_RIGHT = 39;//KeyEvent.VK_RIGHT;
+ public static final int VK_PERIOD = 46;//KeyEvent.VK_PERIOD;
+ public static final int VK_SPACE = 32;//KeyEvent.VK_SPACE;
+ public static final int VK_DOWN = 40;//KeyEvent.VK_DOWN;
+ public static final int VK_UP = 38;//KeyEvent.VK_UP;
+ public static final int VK_ESCAPE = 27;//KeyEvent.VK_ESCAPE;
+ public static final int VK_DELETE = 127;//KeyEvent.VK_DELETE;
+ public static final int VK_BACK_SPACE = 8;//KeyEvent.VK_BACK_SPACE;
+ public static final int VK_PAGE_DOWN = 34;//KeyEvent.VK_PAGE_DOWN;
+ public static final int VK_PAGE_UP = 33;//KeyEvent.VK_PAGE_UP;
+
+ // for status messages:
+ public final static int MOVED = 0;
+ public final static int DRAGGED = 1;
+ public final static int CLICKED = 2;
+ public final static int WHEELED = 3;
+ public final static int PRESSED = 4;
+ public final static int RELEASED = 5;
+
+}
--- /dev/null
+package javajs.awt.event;
+
+
+public class ItemEvent extends Event {
+
+}
--- /dev/null
+package javajs.awt.event;
+
+
+public class WindowEvent extends Event {
+
+}
--- /dev/null
+package javajs.awt.event;
+
+import javajs.awt.event.WindowEvent;
+
+public interface WindowListener {
+
+ public void windowClosing(WindowEvent e);
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2009-06-30 18:58:33 -0500 (Tue, 30 Jun 2009) $
+ * $Revision: 11158 $
+ *
+ * Copyright (C) 2002-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.export;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javajs.util.Lst;
+import javajs.util.SB;
+
+
+
+public class PDFCreator {
+
+ private OutputStream os;
+ private Lst<PDFObject> indirectObjects;
+ private PDFObject root;
+ private PDFObject graphics;
+// private PDFObject pageResources;
+// private PDFObject graphicsResources;
+
+ private int pt;
+ private int xrefPt;
+ private int count;
+
+ private int height;
+ private int width;
+
+ private Map<String, PDFObject>fonts;
+
+ public PDFCreator() {
+ // for Class.forName
+ }
+
+ public void setOutputStream(OutputStream os) {
+ this.os = os;
+ }
+
+ public void newDocument(int paperWidth, int paperHeight, boolean isLandscape) {
+ width = (isLandscape ? paperHeight : paperWidth);
+ height = (isLandscape ? paperWidth : paperHeight);
+ System.out.println("Creating PDF with width=" + width + " and height=" + height);
+ fonts = new Hashtable<String, PDFObject>();
+ indirectObjects = new Lst<PDFObject>();
+ //graphicsResources = newObject(null);
+ //pageResources = newObject(null); // will set this to compressed stream later
+ root = newObject("Catalog");
+ PDFObject pages = newObject("Pages");
+ PDFObject page = newObject("Page");
+ PDFObject pageContents = newObject(null);
+ graphics = newObject("XObject");
+
+ root.addDef("Pages", pages.getRef());
+ pages.addDef("Count", "1");
+ pages.addDef("Kids", "[ " + page.getRef() +" ]");
+ page.addDef("Parent", pages.getRef());
+ page.addDef("MediaBox", "[ 0 0 " + paperWidth + " " + paperHeight + " ]");
+ if (isLandscape)
+ page.addDef("Rotate", "90");
+
+ pageContents.addDef("Length", "?");
+ pageContents.append((isLandscape ? "q 0 1 1 0 0 0 " : "q 1 0 0 -1 0 "+(paperHeight))+" cm /" + graphics.getID() + " Do Q");
+ page.addDef("Contents", pageContents.getRef());
+ addProcSet(page);
+ addProcSet(graphics);
+ // will add fonts as well as they are needed
+ graphics.addDef("Subtype", "/Form");
+ graphics.addDef("FormType", "1");
+ graphics.addDef("BBox", "[0 0 " + width + " " + height + "]");
+ graphics.addDef("Matrix", "[1 0 0 1 0 0]");
+ graphics.addDef("Length", "?");
+ page.addResource("XObject", graphics.getID(), graphics.getRef());
+ g("q 1 w 1 J 1 j 10 M []0 d q "); // line width 1, line cap circle, line join circle, miter limit 10, solid
+ clip(0, 0, width, height);
+ }
+
+ private void addProcSet(PDFObject o) {
+ o.addResource(null, "ProcSet", "[/PDF /Text /ImageB /ImageC /ImageI]");
+ }
+
+ private void clip(int x1, int y1, int x2, int y2) {
+ moveto(x1, y1);
+ lineto(x2, y1);
+ lineto(x2, y2);
+ lineto(x1, y2);
+ g("h W n");
+ }
+
+ public void moveto(int x, int y) {
+ g(x + " " + y + " m");
+ }
+
+ public void lineto(int x, int y) {
+ g(x + " " + y + " l");
+ }
+
+ private PDFObject newObject(String type) {
+ PDFObject o = new PDFObject(++count);
+ if (type != null)
+ o.addDef("Type", "/" + type);
+ indirectObjects.addLast(o);
+ return o;
+ }
+
+ public void addInfo(Map<String, String> data) {
+ Hashtable<String, Object> info = new Hashtable<String, Object>();
+ for (Entry<String, String> e: data.entrySet()) {
+ String value = "(" + e.getValue().replace(')','_').replace('(','_')+ ")";
+ info.put(e.getKey(), value);
+ }
+ root.addDef("Info", info);
+ }
+
+ private PDFObject addFontResource(String fname) {
+ PDFObject f = newObject("Font");
+ fonts.put(fname, f);
+ f.addDef("BaseFont", fname);
+ f.addDef("Encoding", "/WinAnsiEncoding");
+ f.addDef("Subtype", "/Type1");
+ graphics.addResource("Font", f.getID(), f.getRef());
+ return f;
+ }
+
+ private Map<Object, PDFObject> images;
+
+ public void addImageResource(Object newImage, int width, int height, int[] buffer, boolean isRGB) {
+ PDFObject imageObj = newObject("XObject");
+ if (images == null)
+ images = new Hashtable<Object, PDFObject>();
+ images.put(newImage, imageObj);
+ imageObj.addDef("Subtype", "/Image");
+ imageObj.addDef("Length", "?");
+ imageObj.addDef("ColorSpace", isRGB ? "/DeviceRGB" : "/DeviceGray");
+ imageObj.addDef("BitsPerComponent", "8");
+ imageObj.addDef("Width", "" + width);
+ imageObj.addDef("Height", "" + height);
+ graphics.addResource("XObject", imageObj.getID(), imageObj.getRef());
+ int n = buffer.length;
+ byte[] stream = new byte[n * (isRGB ? 3 : 1)];
+ if (isRGB) {
+ for (int i = 0, pt = 0; i < n; i++) {
+ stream[pt++] = (byte) ((buffer[i] >> 16) & 0xFF);
+ stream[pt++] = (byte) ((buffer[i] >> 8) & 0xFF);
+ stream[pt++] = (byte) (buffer[i] & 0xFF);
+ }
+ } else {
+ for (int i = 0; i < n; i++)
+ stream[i] = (byte) buffer[i];
+ }
+ imageObj.setStream(stream);
+ graphics.addResource("XObject", imageObj.getID(), imageObj.getRef());
+ }
+
+ public void g(String cmd) {
+ graphics.append(cmd).appendC('\n');
+ }
+
+ private void output(String s) throws IOException {
+ byte[] b = s.getBytes();
+ os.write(b, 0, b.length);
+ pt += b.length;
+ }
+
+ public void closeDocument() throws IOException {
+ g("Q Q");
+ outputHeader();
+ writeObjects();
+ writeXRefTable();
+ writeTrailer();
+ os.flush();
+ os.close();
+ }
+
+ private void outputHeader() throws IOException {
+ output("%PDF-1.3\n%");
+ byte[] b = new byte[] {-1, -1, -1, -1};
+ os.write(b, 0, b.length);
+ pt += 4;
+ output("\n");
+ }
+
+ private void writeTrailer() throws IOException {
+ PDFObject trailer = new PDFObject(-2);
+ output("trailer");
+ trailer.addDef("Size", "" + indirectObjects.size());
+ trailer.addDef("Root", root.getRef());
+ trailer.output(os);
+ output("startxref\n");
+ output("" + xrefPt + "\n");
+ output("%%EOF\n");
+ }
+
+ /**
+ * Write Font objects first.
+ *
+ * @throws IOException
+ */
+ private void writeObjects() throws IOException {
+ int nObj = indirectObjects.size();
+ for (int i = 0; i < nObj; i++) {
+ PDFObject o = indirectObjects.get(i);
+ if (!o.isFont())
+ continue;
+ o.pt = pt;
+ pt += o.output(os);
+ }
+ for (int i = 0; i < nObj; i++) {
+ PDFObject o = indirectObjects.get(i);
+ if (o.isFont())
+ continue;
+ o.pt = pt;
+ pt += o.output(os);
+ }
+ }
+
+ private void writeXRefTable() throws IOException {
+ xrefPt = pt;
+ int nObj = indirectObjects.size();
+ SB sb = new SB();
+ // note trailing space, needed because \n is just one character
+ sb.append("xref\n0 " + (nObj + 1)
+ + "\n0000000000 65535 f\r\n");
+ for (int i = 0; i < nObj; i++) {
+ PDFObject o = indirectObjects.get(i);
+ String s = "0000000000" + o.pt;
+ sb.append(s.substring(s.length() - 10));
+ sb.append(" 00000 n\r\n");
+ }
+ output(sb.toString());
+ }
+
+ public boolean canDoLineTo() {
+ return true;
+ }
+
+ public void fill() {
+ g("f");
+ }
+
+ public void stroke() {
+ g("S");
+ }
+
+ public void doCircle(int x, int y, int r, boolean doFill) {
+ double d = r*4*(Math.sqrt(2)-1)/3;
+ double dx = x;
+ double dy = y;
+ g((dx + r) + " " + dy + " m");
+ g((dx + r) + " " + (dy + d) + " " + (dx + d) + " " + (dy + r) + " " + (dx) + " " + (dy + r) + " " + " c");
+ g((dx - d) + " " + (dy + r) + " " + (dx - r) + " " + (dy + d) + " " + (dx - r) + " " + (dy) + " c");
+ g((dx - r) + " " + (dy - d) + " " + (dx - d) + " " + (dy - r) + " " + (dx) + " " + (dy - r) + " c");
+ g((dx + d) + " " + (dy - r) + " " + (dx + r) + " " + (dy - d) + " " + (dx + r) + " " + (dy) + " c");
+ g(doFill ? "f" : "s");
+ }
+
+ public void doPolygon(int[] axPoints, int[] ayPoints, int nPoints, boolean doFill) {
+ moveto(axPoints[0], ayPoints[0]);
+ for (int i = 1; i < nPoints; i++)
+ lineto(axPoints[i], ayPoints[i]);
+ g(doFill ? "f" : "s");
+ }
+
+ public void doRect(int x, int y, int width, int height, boolean doFill) {
+ g(x + " " + y + " " + width + " " + height + " re " + (doFill ? "f" : "s"));
+ }
+
+ public void drawImage(Object image, int destX0, int destY0,
+ int destX1, int destY1, int srcX0, int srcY0, int srcX1, int srcY1) {
+ PDFObject imageObj = images.get(image);
+ if (imageObj == null)
+ return;
+ g("q");
+ clip(destX0, destY0, destX1, destY1);
+ double iw = Double.parseDouble((String) imageObj.getDef("Width"));
+ double ih = Double.parseDouble((String) imageObj.getDef("Height"));
+ double dw = (destX1 - destX0 + 1);
+ double dh = (destY1 - destY0 + 1);
+ double sw = (srcX1 - srcX0 + 1);
+ double sh = (srcY1 - srcY0 + 1);
+ double scaleX = dw / sw;
+ double scaleY = dh / sh;
+ double transX = destX0 - srcX0 * scaleX;
+ double transY = destY0 + (ih - srcY0) * scaleY;
+ g(scaleX*iw + " 0 0 " + -scaleY*ih + " " + transX + " " + transY + " cm");
+ g("/" + imageObj.getID() + " Do");
+ g("Q");
+ }
+
+ public void drawStringRotated(String s, int x, int y, int angle) {
+ g("q " + getRotation(angle) + " " + x + " " + y
+ + " cm BT(" + s + ")Tj ET Q");
+ }
+
+ public String getRotation(int angle) {
+ float cos = 0, sin = 0;
+ switch (angle) {
+ case 0:
+ cos = 1;
+ break;
+ case 90:
+ sin = 1;
+ break;
+ case -90:
+ sin = -1;
+ break;
+ case 180:
+ cos = -1;
+ break;
+ default:
+ float a = (float) (angle / 180.0 * Math.PI);
+ cos = (float) Math.cos(a);
+ sin = (float) Math.sin(a);
+ if (Math.abs(cos) < 0.0001)
+ cos = 0;
+ if (Math.abs(sin) < 0.0001)
+ sin = 0;
+ }
+ return cos + " " + sin + " " + sin + " " + -cos;
+ }
+
+ public void setColor(float[] rgb, boolean isFill) {
+ g(rgb[0] + " " + rgb[1] + " " + rgb[2] + (isFill ? " rg" : " RG"));
+ }
+
+ public void setFont(String fname, float size) {
+ PDFObject f = fonts.get(fname);
+ if (f == null)
+ f = addFontResource(fname);
+ g("/" + f.getID() + " " + size + " Tf");
+ }
+
+ public void setLineWidth(float width) {
+ g(width + " w");
+ }
+
+ public void translateScale(float x, float y, float scale) {
+ g(scale + " 0 0 " + scale + " " + x + " " + y + " cm");
+ }
+
+}
--- /dev/null
+package javajs.export;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.Hashtable;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+import javajs.util.SB;
+
+
+/**
+ * A rudimentary class for working with PDF document creation.
+ * Written from scratch based on PDF Reference 13.
+ *
+ * @author hansonr Bob Hanson hansonr@stolaf.edu 10/28/2013
+ *
+ */
+class PDFObject extends SB {
+ private Map<String, Object> dictionary;
+ private byte[] stream;
+ private int index;
+ String type;
+ int len;
+ int pt;
+
+ PDFObject(int index) {
+ this.index = index;
+ }
+
+ String getRef() {
+ return index + " 0 R";
+ }
+
+ String getID() {
+ return type.substring(0, 1) + index;
+ }
+
+ boolean isFont() {
+ return "Font".equals(type);
+ }
+
+ void setStream(byte[] stream) {
+ this.stream = stream;
+ }
+
+ Object getDef(String key) {
+ return dictionary.get(key);
+ }
+
+ void addDef(String key, Object value) {
+ if (dictionary == null)
+ dictionary = new Hashtable<String, Object>();
+ dictionary.put(key, value);
+ if (key.equals("Type"))
+ type = ((String) value).substring(1);
+ }
+
+ void setAsStream() {
+ stream = toBytes(0, -1);
+ setLength(0);
+ }
+
+ int output(OutputStream os) throws IOException {
+ if (index > 0) {
+ String s = index + " 0 obj\n";
+ write(os, s.getBytes(), 0);
+ }
+ int streamLen = 0;
+ if (dictionary != null) {
+ if (dictionary.containsKey("Length")) {
+ if (stream == null)
+ setAsStream();
+ streamLen = stream.length;
+ boolean doDeflate = (streamLen > 1000);
+ if (doDeflate) {
+ Deflater deflater = new Deflater(9);
+ ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024);
+ DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes,
+ deflater);
+ compBytes.write(stream, 0, streamLen);
+ compBytes.finish();
+ stream = outBytes.toByteArray();
+ dictionary.put("Filter", "/FlateDecode");
+ streamLen = stream.length;
+ }
+ dictionary.put("Length", "" + streamLen);
+ }
+ write(os, getDictionaryText(dictionary, "\n").getBytes(), 0);
+ }
+ if (length() > 0)
+ write(os, this.toString().getBytes(), 0);
+ if (stream != null) {
+ write(os, "stream\r\n".getBytes(), 0);
+ write(os, stream, streamLen);
+ write(os, "\r\nendstream\r\n".getBytes(), 0);
+ }
+ if (index > 0)
+ write(os, "endobj\n".getBytes(), 0);
+ return len;
+ }
+
+ private void write(OutputStream os, byte[] bytes, int nBytes) throws IOException {
+ if (nBytes == 0)
+ nBytes = bytes.length;
+ len += nBytes;
+ os.write(bytes, 0, nBytes);
+ }
+
+ @SuppressWarnings("unchecked")
+ private String getDictionaryText(Map<String, Object> d, String nl) {
+ SB sb = new SB();
+ sb.append("<<");
+ if (d.containsKey("Type"))
+ sb.append("/Type").appendO(d.get("Type"));
+ for (Entry<String, Object> e : d.entrySet()) {
+ String s = e.getKey();
+ if (s.equals("Type") || s.startsWith("!"))
+ continue;
+ sb.append("/" + s);
+ Object o = e.getValue();
+ if (o instanceof Map<?, ?>) {
+ sb.append((getDictionaryText((Map<String, Object>) o, "")));
+ continue;
+ }
+ s = (String) e.getValue();
+ if (!s.startsWith("/"))
+ sb.append(" ");
+ sb.appendO(s);
+ }
+ return (sb.length() > 3 ? sb.append(">>").append(nl).toString() : "");
+ }
+
+ @SuppressWarnings("unchecked")
+ private Map<String, Object> createSubdict(Map<String, Object> d0, String dict) {
+ Map<String, Object> d = (Map<String, Object>) d0.get(dict);
+ if (d == null)
+ d0.put(dict, d = new Hashtable<String, Object>());
+ return d;
+ }
+
+ void addResource(String type, String key, String value) {
+ Map<String, Object> r = createSubdict(dictionary, "Resources");
+ if (type != null)
+ r = createSubdict(r, type);
+ r.put(key, value);
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: nicove $
+ * $Date: 2007-03-30 12:26:16 -0500 (Fri, 30 Mar 2007) $
+ * $Revision: 7275 $
+ *
+ * Copyright (C) 2002-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.img;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+
+import javajs.util.Rdr;
+
+/**
+ * src: http://www.javaworld.com/article/2077542/learn-java/java-tip-43--how-to-
+ * read-8--and-24-bit-microsoft-windows-bitmaps-in-java-applications.html
+ *
+ * see also: http://en.wikipedia.org/wiki/BMP_file_format
+ *
+ * Modified by Bob Hanson hansonr@stolaf.edu
+ *
+ * @author Bob Hanson (hansonr@stolaf.edu)
+ *
+ */
+public class BMPDecoder {
+
+ public BMPDecoder() {
+ // for reflection
+ }
+
+ private BufferedInputStream bis;
+
+ /**
+ * original comment:
+ *
+ * loadbitmap() method converted from Windows C code. Reads only uncompressed
+ * 24- and 8-bit images. Tested with images saved using Microsoft Paint in
+ * Windows 95. If the image is not a 24- or 8-bit image, the program refuses
+ * to even try. I guess one could include 4-bit images by masking the byte by
+ * first 1100 and then 0011. I am not really interested in such images. If a
+ * compressed image is attempted, the routine will probably fail by generating
+ * an IOException. Look for variable ncompression to be different from 0 to
+ * indicate compression is present.
+ *
+ * @param bytes
+ * @return [image byte array, width, height]
+ */
+ public Object[] decodeWindowsBMP(byte[] bytes) {
+ try {
+ bis = Rdr.getBIS(bytes);
+ temp = new byte[4];
+ // read BITMAPFILEHEADER
+ if (readByte() != 'B' || readByte() != 'M')
+ return null;
+ readInt(); // file size; ignored
+ readShort(); // reserved
+ readShort(); // reserved
+ readInt(); // ptr to pixel array; ignored
+ int imageWidth, imageHeight, bitsPerPixel, nColors = 0, imageSize = 0;
+ // read BITMAP header
+ int headerSize = readInt();
+ switch (headerSize) {
+ case 12:
+ // BITMAPCOREHEADER
+ imageWidth = readShort();
+ imageHeight = readShort();
+ readShort(); // planes
+ bitsPerPixel = readShort();
+ break;
+ case 40:
+ // BITMAPINFOHEADER
+ imageWidth = readInt();
+ imageHeight = readInt();
+ readShort(); // planes
+ bitsPerPixel = readShort();
+ int ncompression = readInt();
+ if (ncompression != 0) {
+ System.out.println("BMP Compression is :" + ncompression
+ + " -- aborting");
+ return null;
+ }
+ imageSize = readInt();
+ readInt(); // hres
+ readInt(); // vres
+ nColors = readInt();
+ readInt(); // colors used
+ break;
+ default:
+ System.out.println("BMP Header unrecognized, length=" + headerSize
+ + " -- aborting");
+ return null;
+ }
+ boolean isYReversed = (imageHeight < 0);
+ if (isYReversed)
+ imageHeight = -imageHeight;
+ int nPixels = imageHeight * imageWidth;
+ int bytesPerPixel = bitsPerPixel / 8;
+ nColors = (nColors > 0 ? nColors : 1 << bitsPerPixel);
+ int npad = (bytesPerPixel == 4 ? 0
+ : imageSize == 0 ? 4 - (imageWidth % 4) : (imageSize / imageHeight)
+ - imageWidth * bytesPerPixel) % 4;
+ int[] palette;
+ int[] buf = new int[nPixels];
+ int dpt = (isYReversed ? imageWidth : -imageWidth);
+ int pt0 = (isYReversed ? 0 : nPixels + dpt);
+ int pt1 = (isYReversed ? nPixels : dpt);
+ switch (bitsPerPixel) {
+ case 32:
+ case 24:
+ for (int pt = pt0; pt != pt1; pt += dpt, pad(npad))
+ for (int i = 0; i < imageWidth; i++)
+ buf[pt + i] = readColor(bytesPerPixel);
+ break;
+ case 8:
+ palette = new int[nColors];
+ for (int i = 0; i < nColors; i++)
+ palette[i] = readColor(4);
+ for (int pt = pt0; pt != pt1; pt += dpt, pad(npad))
+ for (int i = 0; i < imageWidth; i++)
+ buf[pt + i] = palette[readByte()];
+ break;
+ case 4:
+ npad = (4 - (((imageWidth + 1) / 2) % 4)) % 4;
+ palette = new int[nColors];
+ for (int i = 0; i < nColors; i++)
+ palette[i] = readColor(4);
+ int b4 = 0;
+ for (int pt = pt0; pt != pt1; pt += dpt, pad(npad))
+ for (int i = 0, shift = 4; i < imageWidth; i++, shift = 4 - shift)
+ buf[pt + i] = palette[((shift == 4 ? (b4 = readByte()) : b4) >> shift) & 0xF];
+ break;
+ case 1:
+ int color1 = readColor(3);
+ int color2 = readColor(3);
+ npad = (4 - (((imageWidth + 7) / 8) % 4)) % 4;
+ int b = 0;
+ for (int pt = pt0; pt != pt1; pt += dpt, pad(npad))
+ for (int i = 0, bpt = -1; i < imageWidth; i++, bpt--) {
+ if (bpt < 0) {
+ b = readByte();
+ bpt = 7;
+ }
+ buf[pt + i] = ((b & (1 << bpt)) == 0 ? color1 : color2);
+ }
+ break;
+ case 64:
+ case 2:
+ default:
+ System.out
+ .println("Not a 32-, 24-, 8-, 4-, or 1-bit Windows Bitmap, aborting...");
+ return null;
+ }
+ return new Object[] { buf, Integer.valueOf(imageWidth),
+ Integer.valueOf(imageHeight) };
+ } catch (Exception e) {
+ System.out.println("Caught exception in loadbitmap!");
+ }
+ return null;
+ }
+
+ private boolean pad(int npad) throws IOException {
+ for (int i = 0; i < npad; i++)
+ readByte();
+ return true;
+ }
+
+ private byte[] temp;
+
+ private int readColor(int n) throws IOException {
+ bis.read(temp, 0, n);
+ return 0xff << 24 | ((temp[2] & 0xff) << 16)
+ | ((temp[1] & 0xff) << 8) | temp[0] & 0xff;
+ }
+
+ private int readInt() throws IOException {
+ bis.read(temp, 0, 4);
+ return ((temp[3] & 0xff) << 24) | ((temp[2] & 0xff) << 16)
+ | ((temp[1] & 0xff) << 8) | temp[0] & 0xff;
+ }
+
+ private int readShort() throws IOException {
+ bis.read(temp, 0, 2);
+ return ((temp[1] & 0xff) << 8) | temp[0] & 0xff;
+ }
+
+ private int readByte() throws IOException {
+ bis.read(temp, 0, 1);
+ return temp[0] & 0xff;
+ }
+
+}
--- /dev/null
+package javajs.img;
+
+import java.util.zip.CRC32;
+
+
+import javajs.util.AU;
+
+abstract class CRCEncoder extends ImageEncoder {
+
+ protected int startPos, bytePos;
+
+ private CRC32 crc;
+ protected byte[] pngBytes;
+ protected int dataLen;
+ private byte[] int2 = new byte[2];
+ private byte[] int4 = new byte[4];
+
+ CRCEncoder() {
+ pngBytes = new byte[250];
+ crc = new CRC32();
+ }
+
+ protected void setData(byte[] b, int pt) {
+ pngBytes = b;
+ dataLen = b.length;
+ startPos = bytePos = pt;
+ }
+
+ protected byte[] getBytes() {
+ return (dataLen == pngBytes.length ? pngBytes : AU.arrayCopyByte(
+ pngBytes, dataLen));
+ }
+
+ protected void writeCRC() {
+ crc.reset();
+ crc.update(pngBytes, startPos, bytePos - startPos);
+ writeInt4((int) crc.getValue());
+ }
+
+ /**
+ * Write a two-byte integer into the pngBytes array at a given position.
+ *
+ * @param n The integer to be written into pngBytes.
+ */
+ protected void writeInt2(int n) {
+ int2[0] = (byte) ((n >> 8) & 0xff);
+ int2[1] = (byte) (n & 0xff);
+ writeBytes(int2);
+ }
+
+ /**
+ * Write a four-byte integer into the pngBytes array at a given position.
+ *
+ * @param n The integer to be written into pngBytes.
+ */
+ protected void writeInt4(int n) {
+ getInt4(n, int4);
+ writeBytes(int4);
+ }
+
+ protected static void getInt4(int n, byte[] int4) {
+ int4[0] = (byte) ((n >> 24) & 0xff);
+ int4[1] = (byte) ((n >> 16) & 0xff);
+ int4[2] = (byte) ((n >> 8) & 0xff);
+ int4[3] = (byte) (n & 0xff);
+ }
+
+ /**
+ * Write a single byte into the pngBytes array at a given position.
+ *
+ * @param b The byte to be written into pngBytes.
+ */
+ protected void writeByte(int b) {
+ byte[] temp = {
+ (byte) b
+ };
+ writeBytes(temp);
+ }
+
+ /**
+ * Write a string into the pngBytes array at a given position.
+ * This uses the getBytes method, so the encoding used will
+ * be its default.
+ *
+ * @param s The string to be written into pngBytes.
+ * @see java.lang.String#getBytes()
+ */
+ protected void writeString(String s) {
+ writeBytes(s.getBytes());
+ }
+
+ /**
+ * Write an array of bytes into the pngBytes array.
+ * Both dataLen and bytePos are updated. If we don't have
+ * enough room, this is certainly in image data writing,
+ * so we add just enough for CRC END CRC
+ *
+ * @param data
+ * The data to be written into pngBytes.
+ */
+ protected void writeBytes(byte[] data) {
+ int newPos = bytePos + data.length;
+ dataLen = Math.max(dataLen, newPos);
+ if (newPos > pngBytes.length)
+ pngBytes = AU.arrayCopyByte(pngBytes, newPos + 16);
+ System.arraycopy(data, 0, pngBytes, bytePos, data.length);
+ bytePos = newPos;
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2007-06-02 12:14:13 -0500 (Sat, 02 Jun 2007) $
+ * $Revision: 7831 $
+ *
+ * Copyright (C) 2000-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// Final encoding code from http://acme.com/resources/classes/Acme/JPM/Encoders/GifEncoder.java
+//
+// GifEncoder - write out an image as a GIF
+//
+//
+// Transparency handling and variable bit size courtesy of Jack Palevich.
+//
+// Copyright (C)1996,1998 by Jef Poskanzer <jef@mail.acme.com>. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+// Visit the ACME Labs Java page for up-to-date versions of this and other
+// fine Java utilities: http://www.acme.com/java/
+//
+/// Write out an image as a GIF.
+// <P>
+// <A HREF="/resources/classes/Acme/JPM/Encoders/GifEncoder.java">Fetch the software.</A><BR>
+// <A HREF="/resources/classes/Acme.tar.gz">Fetch the entire Acme package.</A>
+// <P>
+// @see ToGif
+
+package javajs.img;
+
+import javajs.util.CU;
+import javajs.util.Lst;
+import javajs.util.M3;
+import javajs.util.P3;
+
+import java.util.Hashtable;
+import java.util.Map;
+import java.io.IOException;
+
+/**
+ *
+ * GifEncoder extensively adapted for Jmol by Bob Hanson
+ *
+ * Color quantization roughly follows the GIMP method
+ * "dither Floyd-Steinberg (normal)" but with some twists. (For example, we
+ * exclude the background color.)
+ *
+ * Note that although GIMP code annotation refers to "median-cut", it is really
+ * using MEAN-cut. That is what I use here as well.
+ *
+ * -- commented code allows visualization of the color space using Jmol. Very
+ * enlightening!
+ *
+ * -- much simplified interface with ImageEncoder
+ *
+ * -- uses simple Hashtable with Integer() to catalog colors
+ *
+ * -- allows progressive production of animated GIF via Jmol CAPTURE command
+ *
+ * -- uses general purpose javajs.util.OutputChannel for byte-handling options
+ * such as posting to a server, writing to disk, and retrieving bytes.
+ *
+ * -- allows JavaScript port
+ *
+ * -- Bob Hanson, first try: 24 Sep 2013; final coding: 9 Nov 2014
+ *
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+
+public class GifEncoder extends ImageEncoder {
+
+ private Map<String, Object> params;
+ private P3[] palette;
+ private int backgroundColor;
+
+ private boolean interlaced;
+ private boolean addHeader = true;
+ private boolean addImage = true;
+ private boolean addTrailer = true;
+ private boolean isTransparent;
+ private boolean floydSteinberg = true;
+ private boolean capturing;
+ private boolean looping;
+
+ private int delayTime100ths = -1;
+ private int bitsPerPixel = 1;
+
+ private int byteCount;
+
+ /**
+ * we allow for animated GIF by being able to re-enter the code with different
+ * parameters held in params
+ *
+ *
+ */
+ @Override
+ protected void setParams(Map<String, Object> params) {
+ this.params = params;
+ Integer ic = (Integer) params.get("transparentColor");
+ if (ic == null) {
+ ic = (Integer) params.get("backgroundColor");
+ if (ic != null)
+ backgroundColor = ic.intValue();
+ } else {
+ backgroundColor = ic.intValue();
+ isTransparent = true;
+ }
+
+ interlaced = (Boolean.TRUE == params.get("interlaced"));
+ if (params.containsKey("captureRootExt") // file0000.gif
+ || !params.containsKey("captureMode")) // animated gif
+ return;
+ interlaced = false;
+ capturing = true;
+ try {
+ byteCount = ((Integer) params.get("captureByteCount")).intValue();
+ } catch (Exception e) {
+ // ignore
+ }
+ switch ("maec"
+ .indexOf(((String) params.get("captureMode")).substring(0, 1))) {
+ case 0: //"movie"
+ params.put("captureMode", "add");
+ addImage = false;
+ addTrailer = false;
+ break;
+ case 1: // add
+ addHeader = false;
+ addTrailer = false;
+ int fps = Math.abs(((Integer) params.get("captureFps")).intValue());
+ delayTime100ths = (fps == 0 ? 0 : 100 / fps);
+ looping = (Boolean.FALSE != params.get("captureLooping"));
+ break;
+ case 2: // end
+ addHeader = false;
+ addImage = false;
+ break;
+ case 3: // cancel
+ addHeader = false;
+ addImage = false;
+ out.cancel();
+ break;
+ }
+ }
+
+ @Override
+ protected void generate() throws IOException {
+ if (addHeader)
+ writeHeader();
+ addHeader = false; // only one header
+ if (addImage) {
+ createPalette();
+ writeGraphicControlExtension();
+ if (delayTime100ths >= 0 && looping)
+ writeNetscapeLoopExtension();
+ writeImage();
+ }
+ }
+
+ @Override
+ protected void close() {
+ if (addTrailer) {
+ writeTrailer();
+ } else {
+ doClose = false;
+ }
+ if (capturing)
+ params.put("captureByteCount", Integer.valueOf(byteCount));
+ }
+
+ ////////////// 256-color quantization //////////////
+
+ /**
+ * a color point in normalized L*a*b space with a flag indicating whether it
+ * is the background color
+ */
+ private class ColorItem extends P3 {
+ protected boolean isBackground;
+
+ ColorItem(int rgb, boolean isBackground) {
+ this.isBackground = isBackground;
+ setT(toLABnorm(rgb));
+ }
+ }
+
+ /**
+ * A list of normalized L*a*b points with an index and a center and volume
+ *
+ */
+ private class ColorCell extends Lst<P3> {
+
+ protected int index;
+ protected P3 center;
+
+ private float volume;
+
+ ColorCell(int index) {
+ this.index = index;
+ }
+
+ /**
+ * @param doVisualize
+ * debugging only
+ * @return volume in normalized L*a*b space
+ */
+ public float getVolume(boolean doVisualize) {
+ if (volume != 0)
+ return volume;
+ if (size() < 2)
+ return -1;
+ //if (true)
+ //return lst.size();
+ //float d;
+ float maxx = -Integer.MAX_VALUE;
+ float minx = Integer.MAX_VALUE;
+ float maxy = -Integer.MAX_VALUE;
+ float miny = Integer.MAX_VALUE;
+ float maxz = -Integer.MAX_VALUE;
+ float minz = Integer.MAX_VALUE;
+ int n = size();
+ for (int i = n; --i >= 0;) {
+ P3 xyz = get(i);
+ if (xyz.x < minx)
+ minx = xyz.x;
+ if (xyz.y < miny)
+ miny = xyz.y;
+ if (xyz.z < minz)
+ minz = xyz.z;
+ if (xyz.x > maxx)
+ maxx = xyz.x;
+ if (xyz.y > maxy)
+ maxy = xyz.y;
+ if (xyz.z > maxz)
+ maxz = xyz.z;
+ }
+ float dx = (maxx - minx);
+ float dy = (maxy - miny);
+ float dz = (maxz - minz);
+ // Jmol visualization only
+ // if (doVisualize) {
+ // P3 ptRGB = toRGB(center);
+ // drawPt(index, -size(), ptRGB);
+ // //for (int i = n; --i >= 0;)
+ // //drawPt(index, i, toRGB(get(i)));
+ // P3 pt0 = toRGB(P3.new3(Math.max(minx, 0), Math.max(miny, 0),
+ // Math.max(minz, 0)));
+ // P3 pt1 = toRGB(P3.new3(Math.min(maxx, 100), Math.min(maxy, 100),
+ // Math.min(maxz, 100)));
+ // rgbToXyz(pt0, pt0);
+ // xyzToLab(pt0, pt0);
+ // rgbToXyz(pt1, pt1);
+ // xyzToLab(pt1, pt1);
+ // System.out.println("boundbox corners " + pt0 + " " + pt1);
+ // System.out.println("draw d" + index + " boundbox color " + ptRGB
+ // + " mesh nofill");
+ // }
+ return volume = dx * dx + dy * dy + dz * dz;
+ }
+
+ // // Jmol visualization only
+ // private void drawPt(int index, int i, P3 rgb) {
+ // boolean isMain = (i < 0);
+ // P3 lab = rgbToXyz(rgb, null);
+ // xyzToLab(lab, lab);
+ // System.out.println("draw d" + index + (isMain ? "_" : "_" + i) + " width "
+ // + (isMain ? 1.0 : 0.2) + " " + lab
+ // + " color " + rgb + (isMain ? " '" + -i + "'" : ""));
+ // }
+
+ /**
+ * Set the average normalized L*a*b value for this cell and return its RGB point
+ *
+ * @return RGB point
+ *
+ */
+ protected P3 setColor() {
+ int count = size();
+ center = new P3();
+ for (int i = count; --i >= 0;)
+ center.add(get(i));
+ center.scale(1f / count);
+ // Jmol visualization only
+ //volume = 0;
+ //getVolume(true);
+ return toRGB(center);
+ }
+
+ /**
+ * use median_cut algorithm to split the cell, creating a doubly linked
+ * list.
+ *
+ * Paul Heckbert, MIT thesis COLOR IMAGE QUANTIZATION FOR FRAME BUFFER
+ * DISPLAY https://www.cs.cmu.edu/~ph/ciq_thesis
+ *
+ * except, as in GIMP, we use center (not median) here.
+ *
+ * @param cells
+ * @return true if split
+ */
+ protected boolean splitCell(Lst<ColorCell> cells) {
+ int n = size();
+ if (n < 2)
+ return false;
+ int newIndex = cells.size();
+ ColorCell newCell = new ColorCell(newIndex);
+ cells.addLast(newCell);
+ float[][] ranges = new float[3][3];
+ for (int ic = 0; ic < 3; ic++) {
+ float low = Float.MAX_VALUE;
+ float high = -Float.MAX_VALUE;
+ for (int i = n; --i >= 0;) {
+ P3 lab = get(i);
+ float v = (ic == 0 ? lab.x : ic == 1 ? lab.y : lab.z);
+ if (low > v)
+ low = v;
+ if (high < v)
+ high = v;
+ }
+ ranges[0][ic] = low;
+ ranges[1][ic] = high;
+ ranges[2][ic] = high - low;
+ }
+ float[] r = ranges[2];
+ int mode = (r[0] >= r[1] ? (r[0] >= r[2] ? 0 : 2) : r[1] >= r[2] ? 1 : 2);
+ float val = ranges[0][mode] + ranges[2][mode] / 2;
+ volume = 0; // recalculate volume if needed
+ switch (mode) {
+ case 0:
+ for (int i = n; --i >= 0;)
+ if (get(i).x >= val)
+ newCell.addLast(remove(i));
+ break;
+ case 1:
+ for (int i = n; --i >= 0;)
+ if (get(i).y >= val)
+ newCell.addLast(remove(i));
+ break;
+ case 2:
+ for (int i = size(); --i >= 0;)
+ if (get(i).z >= val)
+ newCell.addLast(remove(i));
+ break;
+ }
+ return true;
+ }
+ }
+
+ /**
+ * Quantize all colors and create the final palette;
+ * replace pixels[] with an array of color indices.
+ *
+ */
+ private void createPalette() {
+
+ // catalog all pixel colors
+
+ Lst<ColorItem> tempColors = new Lst<ColorItem>();
+ Map<Integer, ColorItem> ciHash = new Hashtable<Integer, ColorItem>();
+ for (int i = 0, n = pixels.length; i < n; i++) {
+ int rgb = pixels[i];
+ Integer key = Integer.valueOf(rgb);
+ ColorItem item = ciHash.get(key);
+ if (item == null) {
+ item = new ColorItem(rgb, rgb == backgroundColor);
+ ciHash.put(key, item);
+ tempColors.addLast(item);
+ }
+ }
+ int nColors = tempColors.size();
+ System.out.println("GIF total image colors: " + nColors);
+ ciHash = null;
+
+ // create a set of <= 256 color cells
+
+ Lst<ColorCell> cells = quantizeColors(tempColors);
+ nColors = cells.size();
+ System.out.println("GIF final color count: " + nColors);
+
+ // generate the palette and map each cell's rgb color to itself
+
+ Map<Integer, ColorCell> colorMap = new Hashtable<Integer, ColorCell>();
+ bitsPerPixel = (nColors <= 2 ? 1 : nColors <= 4 ? 2 : nColors <= 16 ? 4 : 8);
+ palette = new P3[1 << bitsPerPixel];
+ for (int i = 0; i < nColors; i++) {
+ ColorCell c = cells.get(i);
+ colorMap.put(
+ Integer.valueOf(CU.colorPtToFFRGB(palette[i] = c.setColor())), c);
+ }
+
+ // index all pixels to a pallete color
+
+ pixels = indexPixels(cells, colorMap);
+ }
+
+ /**
+ * Quantize colors by generating a set of cells in normalized L*a*b space
+ * containing all colors. Start with just two cells -- fixed background color
+ * and all others. Keep splitting cells while there are fewer than 256 and
+ * some with multiple colors in them.
+ *
+ * It is possible that we will end up with fewer than 256 colors.
+ *
+ * @param tempColors
+ * @return final list of colors
+ */
+ private Lst<ColorCell> quantizeColors(Lst<ColorItem> tempColors) {
+ int n = tempColors.size();
+ Lst<ColorCell> cells = new Lst<ColorCell>();
+ ColorCell cc = new ColorCell(0);
+ cc.addLast(new ColorItem(backgroundColor, true));
+ cells.addLast(cc);
+ cc = new ColorCell(1);
+ if (n > 256)
+ cells.addLast(cc);
+ for (int i = 0; i < n; i++) {
+ ColorItem c = tempColors.get(i);
+ if (c.isBackground)
+ continue;
+ cc.addLast(c);
+ if (n <= 256) {
+ cells.addLast(cc);
+ cc = new ColorCell(cells.size());
+ }
+ }
+ tempColors.clear();
+ if (n > 256)
+ while ((n = cells.size()) < 256) {
+ float maxVol = 0;
+ ColorCell maxCell = null;
+ for (int i = n; --i >= 1;) {
+ ColorCell c = cells.get(i);
+ float v = c.getVolume(false);
+ if (v > maxVol) {
+ maxVol = v;
+ maxCell = c;
+ }
+ }
+ if (maxCell == null || !maxCell.splitCell(cells))
+ break;
+ }
+ return cells;
+ }
+
+ /**
+ *
+ * Assign all colors to their closest approximation and return an array of
+ * color indexes.
+ *
+ * Uses Floyd-Steinberg dithering, finding the closest known color and then
+ * spreading out the error over four leading pixels. Limits error to +/- 75
+ * percent in normalized L*a*b space.
+ *
+ * @param cells
+ * quantized color cells
+ * @param colorMap
+ * map of quantized rgb to its cell
+ * @return array of color indexes, one for each pixel
+ *
+ */
+ private int[] indexPixels(Lst<ColorCell> cells,
+ Map<Integer, ColorCell> colorMap) {
+ // We need a strip only width+2 wide to process all the errors.
+ // Errors are added to the next pixel and the next row's pixels
+ // only through p + width + 1:
+ // p +1
+ // +w-1 +w +w+1
+ // so including p as well, we need a total of width + 2 errors.
+ //
+ // as p moves through the pixels, we just use mod to cycle through
+ // this strip.
+ //
+ int w2 = width + 2;
+ P3[] errors = new P3[w2];
+ // We should replace, not overwrite, pixels
+ // as this may be the raw canvas.buf32.
+ int[] newPixels = new int[pixels.length];
+ P3 err = new P3();
+ P3 lab;
+ int rgb;
+ Map<Integer, ColorCell> nearestCell = new Hashtable<Integer, ColorCell>();
+ for (int i = 0, p = 0; i < height; ++i) {
+ boolean notLastRow = (i != height - 1);
+ for (int j = 0; j < width; ++j, p++) {
+ if (pixels[p] == backgroundColor) {
+ // leave as 0
+ continue;
+ }
+ P3 pe = errors[p % w2];
+ if (pe == null || pe.x == Float.MAX_VALUE) {
+ lab = null;
+ rgb = pixels[p];
+ } else {
+ lab = toLABnorm(pixels[p]);
+ err = pe;
+ // important not to round the clamp here -- full floating precision
+ err.x = clamp(err.x, -75, 75);
+ err.y = clamp(err.y, -75, 75);
+ err.z = clamp(err.z, -75, 75);
+ lab.add(err);
+ rgb = CU.colorPtToFFRGB(toRGB(lab));
+ }
+ Integer key = Integer.valueOf(rgb);
+ ColorCell cell = colorMap.get(key);
+ if (cell == null) {
+ // critical to generate normalized L*a*b from RGB here for nearestCell mapping.
+ // otherwise future RGB keys may match the wrong cell
+ lab = toLABnorm(rgb);
+ cell = nearestCell.get(key);
+ if (cell == null) {
+ // find nearest cell
+ float maxerr = Float.MAX_VALUE;
+ // skip 0 0 0
+ for (int ib = cells.size(); --ib >= 1;) {
+ ColorCell c = cells.get(ib);
+ err.sub2(lab, c.center);
+ float d = err.lengthSquared();
+ if (d < maxerr) {
+ maxerr = d;
+ cell = c;
+ }
+ }
+ nearestCell.put(key, cell);
+ }
+ if (floydSteinberg) {
+ // dither
+ err.sub2(lab, cell.center);
+ boolean notLastCol = (j < width - 1);
+ if (notLastCol)
+ addError(err, 7, errors, p + 1, w2);
+ if (notLastRow) {
+ if (j > 0)
+ addError(err, 3, errors, p + width - 1, w2);
+ addError(err, 5, errors, p + width, w2);
+ if (notLastCol)
+ addError(err, 1, errors, p + width + 1, w2);
+ }
+ }
+ err.x = Float.MAX_VALUE; // used; flag for resetting to 0
+ }
+ newPixels[p] = cell.index;
+ }
+ }
+ return newPixels;
+ }
+
+ private void addError(P3 err, int f, P3[] errors, int p, int w2) {
+ // GIMP will allow changing the background color.
+ if (pixels[p] == backgroundColor)
+ return;
+ p %= w2;
+ P3 errp = errors[p];
+ if (errp == null)
+ errp = errors[p] = new P3();
+ else if (errp.x == Float.MAX_VALUE) // reuse
+ errp.set(0, 0, 0);
+ errp.scaleAdd2(f / 16f, err, errp);
+ }
+
+ ///////////////////////// CIE L*a*b / XYZ / sRGB conversion methods /////////
+
+ // these could be static, but that just makes for more JavaScript code
+
+ protected P3 toLABnorm(int rgb) {
+ P3 lab = CU.colorPtFromInt(rgb, null);
+ rgbToXyz(lab, lab);
+ xyzToLab(lab, lab);
+ // normalize to 0-100
+ lab.y = (lab.y + 86.185f) / (98.254f + 86.185f) * 100f;
+ lab.z = (lab.z + 107.863f) / (94.482f + 107.863f) * 100f;
+ return lab;
+ }
+
+ protected P3 toRGB(P3 lab) {
+ P3 xyz = P3.newP(lab);
+ // normalized to 0-100
+ xyz.y = xyz.y / 100f * (98.254f + 86.185f) - 86.185f;
+ xyz.z = xyz.z / 100f * (94.482f + 107.863f) - 107.863f;
+ labToXyz(xyz, xyz);
+ return xyzToRgb(xyz, xyz);
+ }
+
+ private static M3 xyz2rgb;
+ private static M3 rgb2xyz;
+
+ static {
+ rgb2xyz = M3.newA9(new float[] { 0.4124f, 0.3576f, 0.1805f, 0.2126f,
+ 0.7152f, 0.0722f, 0.0193f, 0.1192f, 0.9505f });
+
+ xyz2rgb = M3.newA9(new float[] { 3.2406f, -1.5372f, -0.4986f, -0.9689f,
+ 1.8758f, 0.0415f, 0.0557f, -0.2040f, 1.0570f });
+ }
+
+ public P3 rgbToXyz(P3 rgb, P3 xyz) {
+ // http://en.wikipedia.org/wiki/CIE_1931_color_space
+ // http://rsb.info.nih.gov/ij/plugins/download/Color_Space_Converter.java
+ if (xyz == null)
+ xyz = new P3();
+ xyz.x = sxyz(rgb.x);
+ xyz.y = sxyz(rgb.y);
+ xyz.z = sxyz(rgb.z);
+ rgb2xyz.rotate(xyz);
+ return xyz;
+ }
+
+ private float sxyz(float x) {
+ x /= 255;
+ return (float) (x <= 0.04045 ? x / 12.92 : Math.pow(((x + 0.055) / 1.055),
+ 2.4)) * 100;
+ }
+
+ public P3 xyzToRgb(P3 xyz, P3 rgb) {
+ // http://en.wikipedia.org/wiki/CIE_1931_color_space
+ // http://rsb.info.nih.gov/ij/plugins/download/Color_Space_Converter.java
+ if (rgb == null)
+ rgb = new P3();
+ rgb.setT(xyz);
+ rgb.scale(0.01f);
+ xyz2rgb.rotate(rgb);
+ rgb.x = clamp(srgb(rgb.x), 0, 255);
+ rgb.y = clamp(srgb(rgb.y), 0, 255);
+ rgb.z = clamp(srgb(rgb.z), 0, 255);
+ return rgb;
+ }
+
+ private float srgb(float x) {
+ return (float) (x > 0.0031308f ? (1.055 * Math.pow(x, 1.0 / 2.4)) - 0.055
+ : x * 12.92) * 255;
+ }
+
+ public P3 xyzToLab(P3 xyz, P3 lab) {
+ // http://en.wikipedia.org/wiki/Lab_color_space
+ // http://rsb.info.nih.gov/ij/plugins/download/Color_Space_Converter.java
+ // Lab([0..100], [-86.185..98.254], [-107.863..94.482])
+ // XYZn = D65 = {95.0429, 100.0, 108.8900};
+ if (lab == null)
+ lab = new P3();
+ float x = flab(xyz.x / 95.0429f);
+ float y = flab(xyz.y / 100);
+ float z = flab(xyz.z / 108.89f);
+ lab.x = (116 * y) - 16;
+ lab.y = 500 * (x - y);
+ lab.z = 200 * (y - z);
+ return lab;
+ }
+
+ private float flab(float t) {
+ return (float) (t > 8.85645168E-3 /* (24/116)^3 */? Math.pow(t,
+ 0.333333333) : 7.78703704 /* 1/3*116/24*116/24 */* t + 0.137931034 /* 16/116 */
+ );
+ }
+
+ public P3 labToXyz(P3 lab, P3 xyz) {
+ // http://en.wikipedia.org/wiki/Lab_color_space
+ // http://rsb.info.nih.gov/ij/plugins/download/Color_Space_Converter.java
+ // XYZn = D65 = {95.0429, 100.0, 108.8900};
+ if (xyz == null)
+ xyz = new P3();
+
+ xyz.setT(lab);
+ float y = (xyz.x + 16) / 116;
+ float x = xyz.y / 500 + y;
+ float z = y - xyz.z / 200;
+ xyz.x = fxyz(x) * 95.0429f;
+ xyz.y = fxyz(y) * 100;
+ xyz.z = fxyz(z) * 108.89f;
+
+ return xyz;
+ }
+
+ private float fxyz(float t) {
+ return (float) (t > 0.206896552 /* (24/116) */? t * t * t
+ : 0.128418549 /* 3*24/116*24/116 */* (t - 0.137931034 /* 16/116 */));
+ }
+
+ private float clamp(float c, float min, float max) {
+ c = (c < min ? min : c > max ? max : c);
+ return (min == 0 ? Math.round(c) : c);
+ }
+
+ ///////////////////////// GifEncoder writing methods ////////////////////////
+
+ /**
+ * includes logical screen descriptor
+ *
+ * @throws IOException
+ */
+ private void writeHeader() throws IOException {
+ putString("GIF89a");
+ putWord(width);
+ putWord(height);
+ putByte(0); // no global color table -- using local instead
+ putByte(0); // no background
+ putByte(0); // no pixel aspect ratio given
+ }
+
+ private void writeGraphicControlExtension() {
+ if (isTransparent || delayTime100ths >= 0) {
+ putByte(0x21); // graphic control extension
+ putByte(0xf9); // graphic control label
+ putByte(4); // block size
+ putByte((isTransparent ? 9 : 0) | (delayTime100ths > 0 ? 2 : 0)); // packed bytes
+ putWord(delayTime100ths > 0 ? delayTime100ths : 0);
+ putByte(0); // transparent index
+ putByte(0); // end-of-block
+ }
+ }
+
+ // see http://www.vurdalakov.net/misc/gif/netscape-looping-application-extension
+ // +---------------+
+ // 0 | 0x21 | Extension Label
+ // +---------------+
+ // 1 | 0xFF | Application Extension Label
+ // +---------------+
+ // 2 | 0x0B | Block Size
+ // +---------------+
+ // 3 | |
+ // +- -+
+ // 4 | |
+ // +- -+
+ // 5 | |
+ // +- -+
+ // 6 | |
+ // +- NETSCAPE -+ Application Identifier (8 bytes)
+ // 7 | |
+ // +- -+
+ // 8 | |
+ // +- -+
+ // 9 | |
+ // +- -+
+ // 10 | |
+ // +---------------+
+ // 11 | |
+ // +- -+
+ // 12 | 2.0 | Application Authentication Code (3 bytes)
+ // +- -+
+ // 13 | |
+ // +===============+ --+
+ // 14 | 0x03 | Sub-block Data Size |
+ // +---------------+ |
+ // 15 | 0x01 | Sub-block ID |
+ // +---------------+ | Application Data Sub-block
+ // 16 | | |
+ // +- -+ Loop Count (2 bytes) |
+ // 17 | | |
+ // +===============+ --+
+ // 18 | 0x00 | Block Terminator
+ // +---------------+
+
+ private void writeNetscapeLoopExtension() {
+ putByte(0x21); // graphic control extension
+ putByte(0xff); // netscape loop extension
+ putByte(0x0B); // block size
+ putString("NETSCAPE2.0");
+ putByte(3);
+ putByte(1);
+ putWord(0); // loop indefinitely
+ putByte(0); // end-of-block
+
+ }
+
+ private int initCodeSize;
+ private int curpt;
+
+ private void writeImage() {
+ putByte(0x2C);
+ putWord(0); //left
+ putWord(0); //top
+ putWord(width);
+ putWord(height);
+
+ // <Packed Fields> = LISx xZZZ
+
+ // L Local Color Table Flag
+ // I Interlace Flag
+ // S Sort Flag
+ // x Reserved
+ // ZZZ Size of Local Color Table
+
+ int packedFields = 0x80 | (interlaced ? 0x40 : 0) | (bitsPerPixel - 1);
+ putByte(packedFields);
+ int colorMapSize = 1 << bitsPerPixel;
+ P3 p = new P3();
+ for (int i = 0; i < colorMapSize; i++) {
+ if (palette[i] != null)
+ p = palette[i];
+ putByte((int) p.x);
+ putByte((int) p.y);
+ putByte((int) p.z);
+ }
+ putByte(initCodeSize = (bitsPerPixel <= 1 ? 2 : bitsPerPixel));
+ compress();
+ putByte(0);
+ }
+
+ private void writeTrailer() {
+ // Write the GIF file terminator
+ putByte(0x3B);
+ }
+
+ ///// compression routines /////
+
+ private static final int EOF = -1;
+
+ // Return the next pixel from the image
+ private int nextPixel() {
+ if (countDown-- == 0)
+ return EOF;
+ int colorIndex = pixels[curpt];
+ // Bump the current X position
+ ++curx;
+ if (curx == width) {
+ // If we are at the end of a scan line, set curx back to the beginning
+ // If we are interlaced, bump the cury to the appropriate spot,
+ // otherwise, just increment it.
+ curx = 0;
+ if (interlaced)
+ updateY(INTERLACE_PARAMS[pass], INTERLACE_PARAMS[pass + 4]);
+ else
+ ++cury;
+ }
+ curpt = cury * width + curx;
+ return colorIndex & 0xff;
+ }
+
+ private static final int[] INTERLACE_PARAMS = { 8, 8, 4, 2, 4, 2, 1, 0 };
+
+ /**
+ *
+ * Group 1 : Every 8th. row, starting with row 0. (Pass 1)
+ *
+ * Group 2 : Every 8th. row, starting with row 4. (Pass 2)
+ *
+ * Group 3 : Every 4th. row, starting with row 2. (Pass 3)
+ *
+ * Group 4 : Every 2nd. row, starting with row 1. (Pass 4)
+ *
+ * @param yNext
+ * @param yNew
+ */
+ private void updateY(int yNext, int yNew) {
+ cury += yNext;
+ if (yNew >= 0 && cury >= height) {
+ cury = yNew;
+ ++pass;
+ }
+ }
+
+ // Write out a word to the GIF file
+ private void putWord(int w) {
+ putByte(w);
+ putByte(w >> 8);
+ }
+
+ // GIFCOMPR.C - GIF Image compression routines
+ //
+ // Lempel-Ziv compression based on 'compress'. GIF modifications by
+ // David Rowley (mgardi@watdcsu.waterloo.edu)
+
+ // General DEFINEs
+
+ private static final int BITS = 12;
+
+ private static final int HSIZE = 5003; // 80% occupancy
+
+ // GIF Image compression - modified 'compress'
+ //
+ // Based on: compress.c - File compression ala IEEE Computer, June 1984.
+ //
+ // By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
+ // Jim McKie (decvax!mcvax!jim)
+ // Steve Davies (decvax!vax135!petsd!peora!srd)
+ // Ken Turkowski (decvax!decwrl!turtlevax!ken)
+ // James A. Woods (decvax!ihnp4!ames!jaw)
+ // Joe Orost (decvax!vax135!petsd!joe)
+
+ private int nBits; // number of bits/code
+ private int maxbits = BITS; // user settable max # bits/code
+ private int maxcode; // maximum code, given n_bits
+ private int maxmaxcode = 1 << BITS; // should NEVER generate this code
+
+ private final static int MAXCODE(int nBits) {
+ return (1 << nBits) - 1;
+ }
+
+ private int[] htab = new int[HSIZE];
+ private int[] codetab = new int[HSIZE];
+
+ private int hsize = HSIZE; // for dynamic table sizing
+
+ private int freeEnt = 0; // first unused entry
+
+ // block compression parameters -- after all codes are used up,
+ // and compression rate changes, start over.
+ private boolean clearFlag = false;
+
+ // Algorithm: use open addressing double hashing (no chaining) on the
+ // prefix code / next character combination. We do a variant of Knuth's
+ // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
+ // secondary probe. Here, the modular division first probe is gives way
+ // to a faster exclusive-or manipulation. Also do block compression with
+ // an adaptive reset, whereby the code table is cleared when the compression
+ // ratio decreases, but after the table fills. The variable-length output
+ // codes are re-sized at this point, and a special CLEAR code is generated
+ // for the decompressor. Late addition: construct the table according to
+ // file size for noticeable speed improvement on small files. Please direct
+ // questions about this implementation to ames!jaw.
+
+ private int clearCode;
+ private int EOFCode;
+
+ private int countDown;
+ private int pass = 0;
+ private int curx, cury;
+
+ private void compress() {
+
+ // Calculate number of bits we are expecting
+ countDown = width * height;
+
+ // Indicate which pass we are on (if interlace)
+ pass = 0;
+ // Set up the current x and y position
+ curx = 0;
+ cury = 0;
+
+ // Set up the necessary values
+ clearFlag = false;
+ nBits = initCodeSize + 1;
+ maxcode = MAXCODE(nBits);
+
+ clearCode = 1 << initCodeSize;
+ EOFCode = clearCode + 1;
+ freeEnt = clearCode + 2;
+
+ // Set up the 'byte output' routine
+ bufPt = 0;
+
+ int ent = nextPixel();
+
+ int hshift = 0;
+ int fcode;
+ for (fcode = hsize; fcode < 65536; fcode *= 2)
+ ++hshift;
+ hshift = 8 - hshift; // set hash code range bound
+
+ int hsizeReg = hsize;
+ clearHash(hsizeReg); // clear hash table
+
+ output(clearCode);
+
+ int c;
+ outer_loop: while ((c = nextPixel()) != EOF) {
+ fcode = (c << maxbits) + ent;
+ int i = (c << hshift) ^ ent; // xor hashing
+
+ if (htab[i] == fcode) {
+ ent = codetab[i];
+ continue;
+ } else if (htab[i] >= 0) // non-empty slot
+ {
+ int disp = hsizeReg - i; // secondary hash (after G. Knott)
+ if (i == 0)
+ disp = 1;
+ do {
+ if ((i -= disp) < 0)
+ i += hsizeReg;
+
+ if (htab[i] == fcode) {
+ ent = codetab[i];
+ continue outer_loop;
+ }
+ } while (htab[i] >= 0);
+ }
+ output(ent);
+ ent = c;
+ if (freeEnt < maxmaxcode) {
+ codetab[i] = freeEnt++; // code -> hashtable
+ htab[i] = fcode;
+ } else {
+ clearBlock();
+ }
+ }
+ // Put out the final code.
+ output(ent);
+ output(EOFCode);
+ }
+
+ // output
+ //
+ // Output the given code.
+ // Inputs:
+ // code: A n_bits-bit integer. If == -1, then EOF. This assumes
+ // that n_bits =< wordsize - 1.
+ // Outputs:
+ // Outputs code to the file.
+ // Assumptions:
+ // Chars are 8 bits long.
+ // Algorithm:
+ // Maintain a BITS character long buffer (so that 8 codes will
+ // fit in it exactly). Use the VAX insv instruction to insert each
+ // code in turn. When the buffer fills up empty it and start over.
+
+ private int curAccum = 0;
+ private int curBits = 0;
+
+ private int masks[] = { 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,
+ 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF,
+ 0x7FFF, 0xFFFF };
+
+ private void output(int code) {
+ curAccum &= masks[curBits];
+
+ if (curBits > 0)
+ curAccum |= (code << curBits);
+ else
+ curAccum = code;
+
+ curBits += nBits;
+
+ while (curBits >= 8) {
+ byteOut((byte) (curAccum & 0xff));
+ curAccum >>= 8;
+ curBits -= 8;
+ }
+
+ // If the next entry is going to be too big for the code size,
+ // then increase it, if possible.
+ if (freeEnt > maxcode || clearFlag) {
+ if (clearFlag) {
+ maxcode = MAXCODE(nBits = initCodeSize + 1);
+ clearFlag = false;
+ } else {
+ ++nBits;
+ if (nBits == maxbits)
+ maxcode = maxmaxcode;
+ else
+ maxcode = MAXCODE(nBits);
+ }
+ }
+
+ if (code == EOFCode) {
+ // At EOF, write the rest of the buffer.
+ while (curBits > 0) {
+ byteOut((byte) (curAccum & 0xff));
+ curAccum >>= 8;
+ curBits -= 8;
+ }
+ flushBytes();
+ }
+ }
+
+ // Clear out the hash table
+
+ // table clear for block compress
+ private void clearBlock() {
+ clearHash(hsize);
+ freeEnt = clearCode + 2;
+ clearFlag = true;
+
+ output(clearCode);
+ }
+
+ // reset code table
+ private void clearHash(int hsize) {
+ for (int i = 0; i < hsize; ++i)
+ htab[i] = -1;
+ }
+
+ // GIF-specific routines (byte array buffer)
+
+ // Number of bytes so far in this 'packet'
+ private int bufPt;
+
+ // Define the storage for the packet accumulator
+ final private byte[] buf = new byte[256];
+
+ // Add a byte to the end of the current packet, and if it is 254
+ // byte, flush the packet to disk.
+ private void byteOut(byte c) {
+ buf[bufPt++] = c;
+ if (bufPt >= 254)
+ flushBytes();
+ }
+
+ // Flush the packet to disk, and reset the accumulator
+ protected void flushBytes() {
+ if (bufPt > 0) {
+ putByte(bufPt);
+ out.write(buf, 0, bufPt);
+ byteCount += bufPt;
+ bufPt = 0;
+ }
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2007-06-02 12:14:13 -0500 (Sat, 02 Jun 2007) $
+ * $Revision: 7831 $
+ *
+ * Copyright (C) 2000-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// ImageEncoder - abstract class for writing out an image
+//
+// Copyright (C) 1996 by Jef Poskanzer <jef@mail.acme.com>. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+// Visit the ACME Labs Java page for up-to-date versions of this and other
+// fine Java utilities: http://www.acme.com/java/
+
+package javajs.img;
+
+import java.util.Map;
+
+import javajs.api.GenericImageEncoder;
+import javajs.util.OC;
+
+
+
+/**
+ * Generic abstract image creator:
+ *
+ * (1) set parameters
+ *
+ * (2) encode the image bytes, if necessary
+ *
+ * (3) generate the image
+ * @author Bob Hanson hansonr@stolaf.edu
+ */
+
+public abstract class ImageEncoder implements GenericImageEncoder {
+
+ protected OC out;
+
+ protected int width = -1;
+ protected int height = -1;
+ protected int quality = -1;
+ protected String date;
+ protected boolean logging;
+ protected boolean doClose = true;
+
+ /**
+ * @param type
+ * @param out
+ * @param params
+ */
+ @Override
+ public boolean createImage(String type, OC out, Map<String, Object> params)
+ throws Exception {
+ this.out = out;
+ logging = (Boolean.TRUE == params.get("logging"));
+ width = ((Integer) params.get("imageWidth")).intValue();
+ height = ((Integer) params.get("imageHeight")).intValue();
+ pixels = (int[]) params.get("imagePixels");
+ date = (String) params.get("date");
+ Integer q = (Integer) params.get("quality");
+ quality = (q == null ? -1 : q.intValue());
+ setParams(params);
+ generate();
+ close(); // GIF will override this and not close
+ return doClose;
+ }
+
+ abstract protected void setParams(Map<String, Object> params);
+ abstract protected void generate() throws Exception;
+
+ protected int[] pixels;
+
+ protected void putString(String s) {
+ byte[] b = s.getBytes();
+ out.write(b, 0, b.length);
+ }
+
+ protected void putByte(int b) {
+ out.writeByteAsInt(b);
+ }
+
+ protected void close() {
+ // your responsibility to close the output channel
+ }
+
+}
--- /dev/null
+// Version 1.0a
+// Copyright (C) 1998, James R. Weeks and BioElectroMech.
+// Visit BioElectroMech at www.obrador.com. Email James@obrador.com.
+
+// See license.txt for details about the allowed used of this software.
+// This software is based in part on the work of the Independent JPEG Group.
+// See IJGreadme.txt for details about the Independent JPEG Group's license.
+
+// This encoder is inspired by the Java Jpeg encoder by Florian Raemy,
+// studwww.eurecom.fr/~raemy.
+// It borrows a great deal of code and structure from the Independent
+// Jpeg Group's Jpeg 6a library, Copyright Thomas G. Lane.
+// See license.txt for details
+
+/*
+ * JpegEncoder and its associated classes are Copyright (c) 1998, James R. Weeks and BioElectroMech
+ * see(Jmol/src/com/obrador/license.txt)
+ *
+ * javajs.img.JpegEncoder.java was adapted by Bob Hanson
+ * for Jmol in the following ways:
+ *
+ * 1) minor coding efficiencies were made in some for() loops.
+ * 2) methods not used by Jmol were commented out
+ * 3) method and variable signatures were modified to provide
+ * more appropriate method privacy.
+ * 4) additions for Java2Script compatibility
+ *
+ * Original files are maintained in the Jmol.src.com.obrador package, but
+ * these original files are not distributed with Jmol.
+ *
+*/
+
+package javajs.img;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javajs.util.Base64;
+import javajs.util.OC;
+
+
+public class Jpg64Encoder extends JpgEncoder {
+
+ private OC outTemp;
+
+ @Override
+ protected void setParams(Map<String, Object> params) {
+ defaultQuality = 75;
+ outTemp = (OC) params.remove("outputChannelTemp");
+ super.setParams(params);
+ }
+
+ @Override
+ protected void generate() throws IOException {
+ OC out0 = out;
+ out = outTemp;
+ super.generate();
+ byte[] bytes = Base64.getBytes64(out.toByteArray());
+ outTemp = null;
+ out = out0;
+ out.write(bytes, 0, bytes.length);
+ }
+
+}
--- /dev/null
+// Version 1.0a
+// Copyright (C) 1998, James R. Weeks and BioElectroMech.
+// Visit BioElectroMech at www.obrador.com. Email James@obrador.com.
+
+// See license.txt for details about the allowed used of this software.
+// This software is based in part on the work of the Independent JPEG Group.
+// See IJGreadme.txt for details about the Independent JPEG Group's license.
+
+// This encoder is inspired by the Java Jpeg encoder by Florian Raemy,
+// studwww.eurecom.fr/~raemy.
+// It borrows a great deal of code and structure from the Independent
+// Jpeg Group's Jpeg 6a library, Copyright Thomas G. Lane.
+// See license.txt for details
+
+/*
+ * JpegEncoder and its associated classes are Copyright (c) 1998, James R. Weeks and BioElectroMech
+ * see(Jmol/src/com/obrador/license.txt)
+ *
+ * javjs.img.JpegEncoder.java was adapted by Bob Hanson
+ *
+ * for Jmol in the following ways:
+ *
+ * 1) minor coding efficiencies were made in some for() loops.
+ * 2) methods not used by Jmol were commented out
+ * 3) method and variable signatures were modified to provide
+ * more appropriate method privacy.
+ * 4) additions for Java2Script compatibility
+ *
+ * Original files are maintained in the Jmol.src.com.obrador package, but
+ * these original files are not distributed with Jmol.
+ *
+*/
+
+package javajs.img;
+
+import java.io.IOException;
+import java.util.Map;
+
+import javajs.img.ImageEncoder;
+import javajs.util.AU;
+import javajs.util.OC;
+
+/**
+ * JpegEncoder - The JPEG main program which performs a jpeg compression of an
+ * image.
+ *
+ * A system to allow the full Jmol state -- regardless of length --
+ * to be encoded in a set of APP1 (FFE1) tags.
+ * But we have to be careful about line ends for backward compatibility.
+ * This solution is not 100% effective, because some data lines may in principle be
+ * Very large and may not contain new lines for more than 65500 characters,
+ * But that would be very unusual. Perhaps a huge data set loaded from a
+ * string. Introduced in Jmol 12.1.36. Bob Hanson
+ *
+ * See org.com.obrador.license.txt
+ *
+ */
+
+public class JpgEncoder extends ImageEncoder {
+
+ // this string will GENERALLY appear at the end of lines and be escaped
+ private static final int CONTINUE_MAX = 65500; // some room to spare here.
+ private static final int CONTINUE_MAX_BUFFER = CONTINUE_MAX + 10; // never break up last 10 bytes
+
+ private JpegObj jpegObj;
+ private Huffman huf;
+ private DCT dct;
+ protected int defaultQuality = 100;
+ private String applicationTag;
+
+ public JpgEncoder() {
+
+ }
+
+ @Override
+ protected void setParams(Map<String, Object> params) {
+ if (quality <= 0)
+ quality = (params.containsKey("qualityJPG") ? ((Integer) params.get("qualityJPG")).intValue() : defaultQuality);
+ jpegObj = new JpegObj();
+ jpegObj.comment = (String) params.get("comment");
+ applicationTag = (String) params.get("jpgAppTag");
+ }
+
+ @Override
+ protected void generate() throws IOException {
+ jpegObj.imageWidth = width;
+ jpegObj.imageHeight = height;
+ dct = new DCT(quality);
+ huf = new Huffman(width, height);
+ if (jpegObj == null)
+ return;
+ jpegObj.getYCCArray(pixels);
+ String longState = writeHeaders(jpegObj, dct);
+ writeCompressedData(jpegObj, dct, huf);
+ writeMarker(eoi);
+ if (longState != null) {
+ byte[] b = longState.getBytes();
+ out.write(b, 0, b.length);
+ }
+ }
+
+ private void writeCompressedData(JpegObj jpegObj, DCT dct, Huffman huf) {
+ int i, j, r, c, a, b;
+ int comp, xpos, ypos, xblockoffset, yblockoffset;
+ float inputArray[][];
+ float dctArray1[][] = new float[8][8];
+ double dctArray2[][] = new double[8][8];
+ int dctArray3[] = new int[8 * 8];
+
+ /*
+ * This method controls the compression of the image.
+ * Starting at the upper left of the image, it compresses 8x8 blocks
+ * of data until the entire image has been compressed.
+ */
+
+ int lastDCvalue[] = new int[jpegObj.numberOfComponents];
+ //int zeroArray[] = new int[64]; // initialized to hold all zeros
+ //int Width = 0, Height = 0;
+ //int nothing = 0, not;
+ int minBlockWidth, minBlockHeight;
+ // This initial setting of MinBlockWidth and MinBlockHeight is done to
+ // ensure they start with values larger than will actually be the case.
+ minBlockWidth = ((huf.imageWidth % 8 != 0) ? (int) (Math
+ .floor(huf.imageWidth / 8.0) + 1) * 8 : huf.imageWidth);
+ minBlockHeight = ((huf.imageHeight % 8 != 0) ? (int) (Math
+ .floor(huf.imageHeight / 8.0) + 1) * 8 : huf.imageHeight);
+ for (comp = 0; comp < jpegObj.numberOfComponents; comp++) {
+ minBlockWidth = Math.min(minBlockWidth, jpegObj.blockWidth[comp]);
+ minBlockHeight = Math.min(minBlockHeight, jpegObj.blockHeight[comp]);
+ }
+ xpos = 0;
+ for (r = 0; r < minBlockHeight; r++) {
+ for (c = 0; c < minBlockWidth; c++) {
+ xpos = c * 8;
+ ypos = r * 8;
+ for (comp = 0; comp < jpegObj.numberOfComponents; comp++) {
+ //Width = JpegObj.BlockWidth[comp];
+ //Height = JpegObj.BlockHeight[comp];
+ inputArray = jpegObj.components[comp];
+ int vsampF = jpegObj.vsampFactor[comp];
+ int hsampF = jpegObj.hsampFactor[comp];
+ int qNumber = jpegObj.qtableNumber[comp];
+ int dcNumber = jpegObj.dctableNumber[comp];
+ int acNumber = jpegObj.actableNumber[comp];
+
+ for (i = 0; i < vsampF; i++) {
+ for (j = 0; j < hsampF; j++) {
+ xblockoffset = j * 8;
+ yblockoffset = i * 8;
+ for (a = 0; a < 8; a++) {
+ for (b = 0; b < 8; b++) {
+
+ // I believe this is where the dirty line at the bottom of
+ // the image is coming from.
+ // I need to do a check here to make sure I'm not reading past
+ // image data.
+ // This seems to not be a big issue right now. (04/04/98)
+
+ dctArray1[a][b] = inputArray[ypos + yblockoffset + a][xpos
+ + xblockoffset + b];
+ }
+ }
+ // The following code commented out because on some images this technique
+ // results in poor right and bottom borders.
+ // if ((!JpegObj.lastColumnIsDummy[comp] || c < Width - 1) &&
+ // (!JpegObj.lastRowIsDummy[comp] || r < Height - 1)) {
+ dctArray2 = DCT.forwardDCT(dctArray1);
+ dctArray3 = DCT.quantizeBlock(dctArray2, dct.divisors[qNumber]);
+ // }
+ // else {
+ // zeroArray[0] = dctArray3[0];
+ // zeroArray[0] = lastDCvalue[comp];
+ // dctArray3 = zeroArray;
+ // }
+ huf.HuffmanBlockEncoder(out, dctArray3, lastDCvalue[comp],
+ dcNumber, acNumber);
+ lastDCvalue[comp] = dctArray3[0];
+ }
+ }
+ }
+ }
+ }
+ huf.flushBuffer(out);
+ }
+
+ private static byte[] eoi = { (byte) 0xFF, (byte) 0xD9 };
+
+ private static byte[] jfif = new byte[] {
+ /* JFIF[0] =*/(byte) 0xff,
+ /* JFIF[1] =*/(byte) 0xe0,
+ /* JFIF[2] =*/0,
+ /* JFIF[3] =*/16,
+ /* JFIF[4] =*/(byte) 0x4a, //'J'
+ /* JFIF[5] =*/(byte) 0x46, //'F'
+ /* JFIF[6] =*/(byte) 0x49, //'I'
+ /* JFIF[7] =*/(byte) 0x46, //'F'
+ /* JFIF[8] =*/0,
+ /* JFIF[9] =*/1,
+ /* JFIF[10] =*/0,
+ /* JFIF[11] =*/0,
+ /* JFIF[12] =*/0,
+ /* JFIF[13] =*/1,
+ /* JFIF[14] =*/0,
+ /* JFIF[15] =*/1,
+ /* JFIF[16] =*/0,
+ /* JFIF[17] =*/0 };
+
+ private static byte[] soi = { (byte) 0xFF, (byte) 0xD8 };
+
+ private String writeHeaders(JpegObj jpegObj, DCT dct) {
+ int i, j, index, offset;
+ int tempArray[];
+
+ // the SOI marker
+ writeMarker(soi);
+
+ // The order of the following headers is quite inconsequential.
+ // the JFIF header
+ writeArray(jfif);
+
+ // Comment Header
+ String comment = null;
+ if (jpegObj.comment.length() > 0)
+ writeString(jpegObj.comment, (byte) 0xE1); // App data 1
+ writeString(
+ "JPEG Encoder Copyright 1998, James R. Weeks and BioElectroMech.\n\n",
+ (byte) 0xFE);
+
+ // The DQT header
+ // 0 is the luminance index and 1 is the chrominance index
+ byte dqt[] = new byte[134];
+ dqt[0] = (byte) 0xFF;
+ dqt[1] = (byte) 0xDB;
+ dqt[2] = 0;
+ dqt[3] = (byte) 132;
+ offset = 4;
+ for (i = 0; i < 2; i++) {
+ dqt[offset++] = (byte) ((0 << 4) + i);
+ tempArray = dct.quantum[i];
+ for (j = 0; j < 64; j++) {
+ dqt[offset++] = (byte) tempArray[Huffman.jpegNaturalOrder[j]];
+ }
+ }
+ writeArray(dqt);
+
+ // Start of Frame Header
+ byte sof[] = new byte[19];
+ sof[0] = (byte) 0xFF;
+ sof[1] = (byte) 0xC0;
+ sof[2] = 0;
+ sof[3] = 17;
+ sof[4] = (byte) jpegObj.precision;
+ sof[5] = (byte) ((jpegObj.imageHeight >> 8) & 0xFF);
+ sof[6] = (byte) ((jpegObj.imageHeight) & 0xFF);
+ sof[7] = (byte) ((jpegObj.imageWidth >> 8) & 0xFF);
+ sof[8] = (byte) ((jpegObj.imageWidth) & 0xFF);
+ sof[9] = (byte) jpegObj.numberOfComponents;
+ index = 10;
+ for (i = 0; i < sof[9]; i++) {
+ sof[index++] = (byte) jpegObj.compID[i];
+ sof[index++] = (byte) ((jpegObj.hsampFactor[i] << 4) + jpegObj.vsampFactor[i]);
+ sof[index++] = (byte) jpegObj.qtableNumber[i];
+ }
+ writeArray(sof);
+
+ WriteDHTHeader(Huffman.bitsDCluminance, Huffman.valDCluminance);
+ WriteDHTHeader(Huffman.bitsACluminance, Huffman.valACluminance);
+ WriteDHTHeader(Huffman.bitsDCchrominance, Huffman.valDCchrominance);
+ WriteDHTHeader(Huffman.bitsACchrominance, Huffman.valACchrominance);
+
+ // Start of Scan Header
+ byte sos[] = new byte[14];
+ sos[0] = (byte) 0xFF;
+ sos[1] = (byte) 0xDA;
+ sos[2] = 0;
+ sos[3] = 12;
+ sos[4] = (byte) jpegObj.numberOfComponents;
+ index = 5;
+ for (i = 0; i < sos[4]; i++) {
+ sos[index++] = (byte) jpegObj.compID[i];
+ sos[index++] = (byte) ((jpegObj.dctableNumber[i] << 4) + jpegObj.actableNumber[i]);
+ }
+ sos[index++] = (byte) jpegObj.ss;
+ sos[index++] = (byte) jpegObj.se;
+ sos[index++] = (byte) ((jpegObj.ah << 4) + jpegObj.al);
+ writeArray(sos);
+ return comment;
+ }
+
+ private void writeString(String s, byte id) {
+ int len = s.length();
+ int i0 = 0;
+ String suffix = applicationTag;
+ while (i0 < len) {
+ int nBytes = len - i0;
+ if (nBytes > CONTINUE_MAX_BUFFER) {
+ nBytes = CONTINUE_MAX;
+ // but break only at line breaks
+ int pt = s.lastIndexOf('\n', i0 + nBytes);
+ if (pt > i0 + 1)
+ nBytes = pt - i0;
+ }
+ if (i0 + nBytes == len)
+ suffix = "";
+ writeTag(nBytes + suffix.length(), id);
+ writeArray(s.substring(i0, i0 + nBytes).getBytes());
+ if (suffix.length() > 0)
+ writeArray(suffix.getBytes());
+ i0 += nBytes;
+ }
+ }
+
+ private void writeTag(int length, byte id) {
+ length += 2;
+ byte com[] = new byte[4];
+ com[0] = (byte) 0xFF;
+ com[1] = id;
+ com[2] = (byte) ((length >> 8) & 0xFF);
+ com[3] = (byte) (length & 0xFF);
+ writeArray(com);
+ }
+
+ void WriteDHTHeader(int[] bits, int[] val) {
+ // hansonr@stolaf.edu: simplified code.
+ byte[] dht;
+ int bytes = 0;
+ for (int j = 1; j < 17; j++)
+ bytes += bits[j];
+ dht = new byte[21 + bytes];
+ dht[0] = (byte) 0xFF;
+ dht[1] = (byte) 0xC4;
+ int index = 4;
+ for (int j = 0; j < 17; j++)
+ dht[index++] = (byte) bits[j];
+ for (int j = 0; j < bytes; j++)
+ dht[index++] = (byte) val[j];
+ dht[2] = (byte) (((index - 2) >> 8) & 0xFF);
+ dht[3] = (byte) ((index - 2) & 0xFF);
+ writeArray(dht);
+ }
+
+ void writeMarker(byte[] data) {
+ out.write(data, 0, 2);
+ }
+
+ void writeArray(byte[] data) {
+ out.write(data, 0, data.length);
+ }
+
+}
+
+// This class incorporates quality scaling as implemented in the JPEG-6a
+// library.
+
+/*
+ * DCT - A Java implementation of the Discreet Cosine Transform
+ */
+
+class DCT {
+
+ /**
+ * DCT Block Size - default 8
+ */
+ private final static int N = 8;
+ private final static int NN = N * N;
+
+ /**
+ * Image Quality (0-100) - default 80 (good image / good compression)
+ */
+ //public int QUALITY = 80;
+
+ int[][] quantum = AU.newInt2(2);
+ double[][] divisors = AU.newDouble2(2);
+
+ /**
+ * Quantitization Matrix for luminace.
+ */
+ private int quantum_luminance[] = new int[NN];
+ private double DivisorsLuminance[] = new double[NN];
+
+ /**
+ * Quantitization Matrix for chrominance.
+ */
+ private int quantum_chrominance[] = new int[NN];
+ private double DivisorsChrominance[] = new double[NN];
+
+ /**
+ * Constructs a new DCT object. Initializes the cosine transform matrix these
+ * are used when computing the DCT and it's inverse. This also initializes the
+ * run length counters and the ZigZag sequence. Note that the image quality
+ * can be worse than 25 however the image will be extemely pixelated, usually
+ * to a block size of N.
+ *
+ * @param quality
+ * The quality of the image (0 worst - 100 best)
+ *
+ */
+ DCT(int quality) {
+ initMatrix(quality);
+ }
+
+ /*
+ * This method sets up the quantization matrix for luminance and
+ * chrominance using the Quality parameter.
+ */
+ private void initMatrix(int quality) {
+ // converting quality setting to that specified in the jpeg_quality_scaling
+ // method in the IJG Jpeg-6a C libraries
+
+ quality = (quality < 1 ? 1 : quality > 100 ? 100 : quality);
+ quality = (quality < 50 ? 5000 / quality : 200 - quality * 2);
+
+ // Creating the luminance matrix
+
+ quantum_luminance[0] = 16;
+ quantum_luminance[1] = 11;
+ quantum_luminance[2] = 10;
+ quantum_luminance[3] = 16;
+ quantum_luminance[4] = 24;
+ quantum_luminance[5] = 40;
+ quantum_luminance[6] = 51;
+ quantum_luminance[7] = 61;
+ quantum_luminance[8] = 12;
+ quantum_luminance[9] = 12;
+ quantum_luminance[10] = 14;
+ quantum_luminance[11] = 19;
+ quantum_luminance[12] = 26;
+ quantum_luminance[13] = 58;
+ quantum_luminance[14] = 60;
+ quantum_luminance[15] = 55;
+ quantum_luminance[16] = 14;
+ quantum_luminance[17] = 13;
+ quantum_luminance[18] = 16;
+ quantum_luminance[19] = 24;
+ quantum_luminance[20] = 40;
+ quantum_luminance[21] = 57;
+ quantum_luminance[22] = 69;
+ quantum_luminance[23] = 56;
+ quantum_luminance[24] = 14;
+ quantum_luminance[25] = 17;
+ quantum_luminance[26] = 22;
+ quantum_luminance[27] = 29;
+ quantum_luminance[28] = 51;
+ quantum_luminance[29] = 87;
+ quantum_luminance[30] = 80;
+ quantum_luminance[31] = 62;
+ quantum_luminance[32] = 18;
+ quantum_luminance[33] = 22;
+ quantum_luminance[34] = 37;
+ quantum_luminance[35] = 56;
+ quantum_luminance[36] = 68;
+ quantum_luminance[37] = 109;
+ quantum_luminance[38] = 103;
+ quantum_luminance[39] = 77;
+ quantum_luminance[40] = 24;
+ quantum_luminance[41] = 35;
+ quantum_luminance[42] = 55;
+ quantum_luminance[43] = 64;
+ quantum_luminance[44] = 81;
+ quantum_luminance[45] = 104;
+ quantum_luminance[46] = 113;
+ quantum_luminance[47] = 92;
+ quantum_luminance[48] = 49;
+ quantum_luminance[49] = 64;
+ quantum_luminance[50] = 78;
+ quantum_luminance[51] = 87;
+ quantum_luminance[52] = 103;
+ quantum_luminance[53] = 121;
+ quantum_luminance[54] = 120;
+ quantum_luminance[55] = 101;
+ quantum_luminance[56] = 72;
+ quantum_luminance[57] = 92;
+ quantum_luminance[58] = 95;
+ quantum_luminance[59] = 98;
+ quantum_luminance[60] = 112;
+ quantum_luminance[61] = 100;
+ quantum_luminance[62] = 103;
+ quantum_luminance[63] = 99;
+
+ AANscale(DivisorsLuminance, quantum_luminance, quality);
+
+ // Creating the chrominance matrix
+
+ for (int i = 4; i < 64; i++)
+ quantum_chrominance[i] = 99;
+
+ quantum_chrominance[0] = 17;
+ quantum_chrominance[1] = 18;
+ quantum_chrominance[2] = 24;
+ quantum_chrominance[3] = 47;
+
+ quantum_chrominance[8] = 18;
+ quantum_chrominance[9] = 21;
+ quantum_chrominance[10] = 26;
+ quantum_chrominance[11] = 66;
+
+ quantum_chrominance[16] = 24;
+ quantum_chrominance[17] = 26;
+ quantum_chrominance[18] = 56;
+
+ quantum_chrominance[24] = 47;
+ quantum_chrominance[25] = 66;
+
+ AANscale(DivisorsChrominance, quantum_chrominance, quality);
+
+ // quantum and Divisors are objects used to hold the appropriate matices
+
+ quantum[0] = quantum_luminance;
+ quantum[1] = quantum_chrominance;
+
+ divisors[0] = DivisorsLuminance;
+ divisors[1] = DivisorsChrominance;
+
+ }
+
+ private final static double[] AANscaleFactor = { 1.0, 1.387039845,
+ 1.306562965, 1.175875602, 1.0, 0.785694958, 0.541196100, 0.275899379 };
+
+ static private void AANscale(double[] divisors, int[] values, int quality) {
+
+ for (int j = 0; j < 64; j++) {
+ int temp = (values[j] * quality + 50) / 100;
+ values[j] = (temp < 1 ? 1 : temp > 255 ? 255 : temp);
+ }
+
+ for (int i = 0, index = 0; i < 8; i++)
+ for (int j = 0; j < 8; j++, index++)
+ // The divisors for the LL&M method (the slow integer method used in
+ // jpeg 6a library). This method is currently (04/04/98) incompletely
+ // implemented.
+ // DivisorsLuminance[index] = ((double) quantum_luminance[index]) << 3;
+ // The divisors for the AAN method (the float method used in jpeg 6a library.
+ divisors[index] = (0.125 / (values[index] * AANscaleFactor[i] * AANscaleFactor[j]));
+ }
+
+ /*
+ * This method preforms forward DCT on a block of image data using
+ * the literal method specified for a 2-D Discrete Cosine Transform.
+ * It is included as a curiosity and can give you an idea of the
+ * difference in the compression result (the resulting image quality)
+ * by comparing its output to the output of the AAN method below.
+ * It is ridiculously inefficient.
+ */
+
+ // For now the final output is unusable. The associated quantization step
+ // needs some tweaking. If you get this part working, please let me know.
+ /*
+ public double[][] forwardDCTExtreme(float input[][])
+ {
+ double output[][] = new double[N][N];
+ int v, u, x, y;
+ for (v = 0; v < 8; v++) {
+ for (u = 0; u < 8; u++) {
+ for (x = 0; x < 8; x++) {
+ for (y = 0; y < 8; y++) {
+ output[v][u] += input[x][y] *
+ Math.cos(((double)(2*x + 1)*(double)u*Math.PI)/16)*
+ Math.cos(((double)(2*y + 1)*(double)v*Math.PI)/16);
+ }
+ }
+ output[v][u] *= (0.25)*((u == 0) ? (1.0/Math.sqrt(2)) : (double) 1.0)*((v == 0) ? (1.0/Math.sqrt(2)) : (double) 1.0);
+ }
+ }
+ return output;
+ }
+
+ */
+ /*
+ * This method preforms a DCT on a block of image data using the AAN
+ * method as implemented in the IJG Jpeg-6a library.
+ */
+ static double[][] forwardDCT(float input[][]) {
+ double output[][] = new double[N][N];
+ double tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
+ double tmp10, tmp11, tmp12, tmp13;
+ double z1, z2, z3, z4, z5, z11, z13;
+ // Subtracts 128 from the input values
+ for (int i = 0; i < 8; i++)
+ for (int j = 0; j < 8; j++)
+ output[i][j] = (input[i][j] - 128.0);
+ // input[i][j] -= 128;
+
+ for (int i = 0; i < 8; i++) {
+ tmp0 = output[i][0] + output[i][7];
+ tmp7 = output[i][0] - output[i][7];
+ tmp1 = output[i][1] + output[i][6];
+ tmp6 = output[i][1] - output[i][6];
+ tmp2 = output[i][2] + output[i][5];
+ tmp5 = output[i][2] - output[i][5];
+ tmp3 = output[i][3] + output[i][4];
+ tmp4 = output[i][3] - output[i][4];
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ output[i][0] = tmp10 + tmp11;
+ output[i][4] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * 0.707106781;
+ output[i][2] = tmp13 + z1;
+ output[i][6] = tmp13 - z1;
+
+ tmp10 = tmp4 + tmp5;
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ z5 = (tmp10 - tmp12) * 0.382683433;
+ z2 = 0.541196100 * tmp10 + z5;
+ z4 = 1.306562965 * tmp12 + z5;
+ z3 = tmp11 * 0.707106781;
+
+ z11 = tmp7 + z3;
+ z13 = tmp7 - z3;
+
+ output[i][5] = z13 + z2;
+ output[i][3] = z13 - z2;
+ output[i][1] = z11 + z4;
+ output[i][7] = z11 - z4;
+ }
+
+ for (int i = 0; i < 8; i++) {
+ tmp0 = output[0][i] + output[7][i];
+ tmp7 = output[0][i] - output[7][i];
+ tmp1 = output[1][i] + output[6][i];
+ tmp6 = output[1][i] - output[6][i];
+ tmp2 = output[2][i] + output[5][i];
+ tmp5 = output[2][i] - output[5][i];
+ tmp3 = output[3][i] + output[4][i];
+ tmp4 = output[3][i] - output[4][i];
+
+ tmp10 = tmp0 + tmp3;
+ tmp13 = tmp0 - tmp3;
+ tmp11 = tmp1 + tmp2;
+ tmp12 = tmp1 - tmp2;
+
+ output[0][i] = tmp10 + tmp11;
+ output[4][i] = tmp10 - tmp11;
+
+ z1 = (tmp12 + tmp13) * 0.707106781;
+ output[2][i] = tmp13 + z1;
+ output[6][i] = tmp13 - z1;
+
+ tmp10 = tmp4 + tmp5;
+ tmp11 = tmp5 + tmp6;
+ tmp12 = tmp6 + tmp7;
+
+ z5 = (tmp10 - tmp12) * 0.382683433;
+ z2 = 0.541196100 * tmp10 + z5;
+ z4 = 1.306562965 * tmp12 + z5;
+ z3 = tmp11 * 0.707106781;
+
+ z11 = tmp7 + z3;
+ z13 = tmp7 - z3;
+
+ output[5][i] = z13 + z2;
+ output[3][i] = z13 - z2;
+ output[1][i] = z11 + z4;
+ output[7][i] = z11 - z4;
+ }
+
+ return output;
+ }
+
+ /*
+ * This method quantitizes data and rounds it to the nearest integer.
+ */
+ static int[] quantizeBlock(double inputData[][], double[] divisorsCode) {
+ int outputData[] = new int[NN];
+ for (int i = 0, index = 0; i < 8; i++)
+ for (int j = 0; j < 8; j++, index++)
+ // The second line results in significantly better compression.
+ outputData[index] = (int) (Math.round(inputData[i][j]
+ * divisorsCode[index]));
+ // outputData[index] = (int)(((inputData[i][j] * (((double[]) (Divisors[code]))[index])) + 16384.5) -16384);
+ return outputData;
+ }
+
+ /*
+ * This is the method for quantizing a block DCT'ed with forwardDCTExtreme
+ * This method quantitizes data and rounds it to the nearest integer.
+ */
+
+ /*
+
+ public double[][] forwardDCTExtreme(float input[][])
+ {
+ double output[][] = new double[N][N];
+ int v, u, x, y;
+ for (v = 0; v < 8; v++) {
+ for (u = 0; u < 8; u++) {
+ for (x = 0; x < 8; x++) {
+ for (y = 0; y < 8; y++) {
+ output[v][u] += input[x][y] *
+ Math.cos(((double)(2*x + 1)*(double)u*Math.PI)/16)*
+ Math.cos(((double)(2*y + 1)*(double)v*Math.PI)/16);
+ }
+ }
+ output[v][u] *= (0.25)*((u == 0) ? (1.0/Math.sqrt(2)) : (double) 1.0)*((v == 0) ? (1.0/Math.sqrt(2)) : (double) 1.0);
+ }
+ }
+ return output;
+ }
+
+ */
+ /*
+ public int[] quantizeBlockExtreme(double inputData[][], int code)
+ {
+ int outputData[] = new int[NN];
+ int i, j;
+ int index;
+ index = 0;
+ for (i = 0; i < 8; i++) {
+ for (j = 0; j < 8; j++) {
+ outputData[index] = (int)(Math.round(inputData[i][j] / (((int[]) (quantum[code]))[index])));
+ index++;
+ }
+ }
+
+ return outputData;
+ }
+ */
+}
+
+// This class was modified by James R. Weeks on 3/27/98.
+// It now incorporates Huffman table derivation as in the C jpeg library
+// from the IJG, Jpeg-6a.
+
+class Huffman {
+ private int bufferPutBits, bufferPutBuffer;
+ int imageHeight;
+ int imageWidth;
+ private int dc_matrix0[][];
+ private int ac_matrix0[][];
+ private int dc_matrix1[][];
+ private int ac_matrix1[][];
+ private int[][][] dc_matrix;
+ private int[][][] ac_matrix;
+ //private int code;
+ int numOfDCTables;
+ int numOfACTables;
+ final static int[] bitsDCluminance = { 0x00, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0,
+ 0, 0, 0, 0, 0 };
+ final static int[] valDCluminance = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+ final static int[] bitsDCchrominance = { 0x01, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 0, 0, 0, 0, 0 };
+ final static int[] valDCchrominance = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
+ final static int[] bitsACluminance = { 0x10, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4,
+ 4, 0, 0, 1, 0x7d };
+ final static int[] valACluminance = { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
+ 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71,
+ 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52,
+ 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53,
+ 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
+ 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
+ 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9,
+ 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
+ 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
+ 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8,
+ 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa };
+ final static int[] bitsACchrominance = { 0x11, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5,
+ 4, 4, 0, 1, 2, 0x77 };
+ final static int[] valACchrominance = { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
+ 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
+ 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33,
+ 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25,
+ 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36,
+ 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a,
+ 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66,
+ 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
+ 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94,
+ 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
+ 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
+ 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa };
+
+ /*
+ * jpegNaturalOrder[i] is the natural-order position of the i'th element
+ * of zigzag order.
+ */
+ final static int[] jpegNaturalOrder = { 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32,
+ 25, 18, 11, 4, 5, 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14,
+ 21, 28, 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
+ 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, };
+
+ Huffman(int width, int height) {
+ initHuf();
+ imageWidth = width;
+ imageHeight = height;
+
+ }
+
+ /**
+ * HuffmanBlockEncoder run length encodes and Huffman encodes the quantized
+ * data.
+ *
+ * @param out
+ * @param zigzag
+ * @param prec
+ * @param dcCode
+ * @param acCode
+ **/
+
+ void HuffmanBlockEncoder(OC out, int zigzag[], int prec,
+ int dcCode, int acCode) {
+ int temp, temp2, nbits, k, r, i;
+
+ numOfDCTables = 2;
+ numOfACTables = 2;
+
+ int[][] matrixDC = dc_matrix[dcCode];
+ int[][] matrixAC = ac_matrix[acCode];
+
+ // The DC portion
+
+ temp = temp2 = zigzag[0] - prec;
+ if (temp < 0) {
+ temp = -temp;
+ temp2--;
+ }
+ nbits = 0;
+ while (temp != 0) {
+ nbits++;
+ temp >>= 1;
+ }
+ // if (nbits > 11) nbits = 11;
+ bufferIt(out, matrixDC[nbits][0], matrixDC[nbits][1]);
+ // The arguments in bufferIt are code and size.
+ if (nbits != 0) {
+ bufferIt(out, temp2, nbits);
+ }
+
+ // The AC portion
+
+ r = 0;
+
+ for (k = 1; k < 64; k++) {
+ if ((temp = zigzag[jpegNaturalOrder[k]]) == 0) {
+ r++;
+ } else {
+ while (r > 15) {
+ bufferIt(out, matrixAC[0xF0][0], matrixAC[0xF0][1]);
+ r -= 16;
+ }
+ temp2 = temp;
+ if (temp < 0) {
+ temp = -temp;
+ temp2--;
+ }
+ nbits = 1;
+ while ((temp >>= 1) != 0) {
+ nbits++;
+ }
+ i = (r << 4) + nbits;
+ bufferIt(out, matrixAC[i][0], matrixAC[i][1]);
+ bufferIt(out, temp2, nbits);
+
+ r = 0;
+ }
+ }
+
+ if (r > 0) {
+ bufferIt(out, matrixAC[0][0], matrixAC[0][1]);
+ }
+
+ }
+
+ // Uses an integer long (32 bits) buffer to store the Huffman encoded bits
+ // and sends them to out by the byte.
+
+ void bufferIt(OC out, int code, int size) {
+ int putBuffer = code;
+ int putBits = bufferPutBits;
+
+ putBuffer &= (1 << size) - 1;
+ putBits += size;
+ putBuffer <<= 24 - putBits;
+ putBuffer |= bufferPutBuffer;
+
+ while (putBits >= 8) {
+ int c = ((putBuffer >> 16) & 0xFF);
+ out.writeByteAsInt(c);
+ if (c == 0xFF) {
+ out.writeByteAsInt(0);
+ }
+ putBuffer <<= 8;
+ putBits -= 8;
+ }
+ bufferPutBuffer = putBuffer;
+ bufferPutBits = putBits;
+
+ }
+
+ void flushBuffer(OC out) {
+ int putBuffer = bufferPutBuffer;
+ int putBits = bufferPutBits;
+ while (putBits >= 8) {
+ int c = ((putBuffer >> 16) & 0xFF);
+ out.writeByteAsInt(c);
+ if (c == 0xFF) {
+ out.writeByteAsInt(0);
+ }
+ putBuffer <<= 8;
+ putBits -= 8;
+ }
+ if (putBits > 0) {
+ int c = ((putBuffer >> 16) & 0xFF);
+ out.writeByteAsInt(c);
+ }
+ }
+
+ /*
+ * Initialisation of the Huffman codes for Luminance and Chrominance.
+ * This code results in the same tables created in the IJG Jpeg-6a
+ * library.
+ */
+
+ private void initHuf() {
+ dc_matrix0 = new int[12][2];
+ dc_matrix1 = new int[12][2];
+ ac_matrix0 = new int[255][2];
+ ac_matrix1 = new int[255][2];
+ dc_matrix = AU.newInt3(2, -1);
+ ac_matrix = AU.newInt3(2, -1);
+ int p, l, i, lastp, si, code;
+ int[] huffsize = new int[257];
+ int[] huffcode = new int[257];
+
+ /*
+ * init of the DC values for the chrominance
+ * [][0] is the code [][1] is the number of bit
+ */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ // for (i = 1; i <= bitsDCchrominance[l]; i++)
+ for (i = bitsDCchrominance[l]; --i >= 0;) {
+ huffsize[p++] = l; //that's an "el", not a "one"
+ }
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p] != 0) {
+ while (huffsize[p] == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ for (p = 0; p < lastp; p++) {
+ dc_matrix1[valDCchrominance[p]][0] = huffcode[p];
+ dc_matrix1[valDCchrominance[p]][1] = huffsize[p];
+ }
+
+ /*
+ * Init of the AC huffman code for the chrominance
+ * matrix [][][0] is the code & matrix[][][1] is the number of bit needed
+ */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ for (i = bitsACchrominance[l]; --i >= 0;)
+ // for (i = 1; i <= bitsACchrominance[l]; i++)
+ {
+ huffsize[p++] = l;
+ }
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p] != 0) {
+ while (huffsize[p] == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ for (p = 0; p < lastp; p++) {
+ ac_matrix1[valACchrominance[p]][0] = huffcode[p];
+ ac_matrix1[valACchrominance[p]][1] = huffsize[p];
+ }
+
+ /*
+ * init of the DC values for the luminance
+ * [][0] is the code [][1] is the number of bit
+ */
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ // for (i = 1; i <= bitsDCluminance[l]; i++)
+ for (i = bitsDCluminance[l]; --i >= 0;) {
+ huffsize[p++] = l;
+ }
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p] != 0) {
+ while (huffsize[p] == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+
+ for (p = 0; p < lastp; p++) {
+ dc_matrix0[valDCluminance[p]][0] = huffcode[p];
+ dc_matrix0[valDCluminance[p]][1] = huffsize[p];
+ }
+
+ /*
+ * Init of the AC huffman code for luminance
+ * matrix [][][0] is the code & matrix[][][1] is the number of bit
+ */
+
+ p = 0;
+ for (l = 1; l <= 16; l++) {
+ // for (i = 1; i <= bitsACluminance[l]; i++)
+ for (i = bitsACluminance[l]; --i >= 0;) {
+ huffsize[p++] = l;
+ }
+ }
+ huffsize[p] = 0;
+ lastp = p;
+
+ code = 0;
+ si = huffsize[0];
+ p = 0;
+ while (huffsize[p] != 0) {
+ while (huffsize[p] == si) {
+ huffcode[p++] = code;
+ code++;
+ }
+ code <<= 1;
+ si++;
+ }
+ for (int q = 0; q < lastp; q++) {
+ ac_matrix0[valACluminance[q]][0] = huffcode[q];
+ ac_matrix0[valACluminance[q]][1] = huffsize[q];
+ }
+
+ dc_matrix[0] = dc_matrix0;
+ dc_matrix[1] = dc_matrix1;
+ ac_matrix[0] = ac_matrix0;
+ ac_matrix[1] = ac_matrix1;
+ }
+
+}
+
+/*
+ * JpegInfo - Given an image, sets default information about it and divides
+ * it into its constituant components, downsizing those that need to be.
+ */
+
+class JpegObj {
+ String comment;
+ int imageHeight;
+ int imageWidth;
+ int blockWidth[];
+ int blockHeight[];
+
+ int precision = 8;
+ int numberOfComponents = 3;
+ float[][][] components;
+ int[] compID = { 1, 2, 3 };
+ int[] hsampFactor = { 1, 1, 1 };
+ int[] vsampFactor = { 1, 1, 1 };
+ int[] qtableNumber = { 0, 1, 1 };
+ int[] dctableNumber = { 0, 1, 1 };
+ int[] actableNumber = { 0, 1, 1 };
+ private boolean[] lastColumnIsDummy = { false, false, false };
+ private boolean[] lastRowIsDummy = { false, false, false };
+ int ss = 0;
+ int se = 63;
+ int ah = 0;
+ int al = 0;
+ private int compWidth[];
+ private int compHeight[];
+ private int maxHsampFactor;
+ private int maxVsampFactor;
+
+ public JpegObj() {
+ components = AU.newFloat3(numberOfComponents, -1);
+ compWidth = new int[numberOfComponents];
+ compHeight = new int[numberOfComponents];
+ blockWidth = new int[numberOfComponents];
+ blockHeight = new int[numberOfComponents];
+ }
+
+ /*
+ * This method creates and fills three arrays, Y, Cb, and Cr using the
+ * input image.
+ */
+
+ void getYCCArray(int[] pixels) {
+ // In order to minimize the chance that grabPixels will throw an exception
+ // it may be necessary to grab some pixels every few scanlines and process
+ // those before going for more. The time expense may be prohibitive.
+ // However, for a situation where memory overhead is a concern, this may be
+ // the only choice.
+ maxHsampFactor = 1;
+ maxVsampFactor = 1;
+ for (int y = 0; y < numberOfComponents; y++) {
+ maxHsampFactor = Math.max(maxHsampFactor, hsampFactor[y]);
+ maxVsampFactor = Math.max(maxVsampFactor, vsampFactor[y]);
+ }
+ for (int y = 0; y < numberOfComponents; y++) {
+ compWidth[y] = (((imageWidth % 8 != 0) ? ((int) Math
+ .ceil(imageWidth / 8.0)) * 8 : imageWidth) / maxHsampFactor)
+ * hsampFactor[y];
+ if (compWidth[y] != ((imageWidth / maxHsampFactor) * hsampFactor[y])) {
+ lastColumnIsDummy[y] = true;
+ }
+ // results in a multiple of 8 for compWidth
+ // this will make the rest of the program fail for the unlikely
+ // event that someone tries to compress an 16 x 16 pixel image
+ // which would of course be worse than pointless
+ blockWidth[y] = (int) Math.ceil(compWidth[y] / 8.0);
+ compHeight[y] = (((imageHeight % 8 != 0) ? ((int) Math
+ .ceil(imageHeight / 8.0)) * 8 : imageHeight) / maxVsampFactor)
+ * vsampFactor[y];
+ if (compHeight[y] != ((imageHeight / maxVsampFactor) * vsampFactor[y])) {
+ lastRowIsDummy[y] = true;
+ }
+ blockHeight[y] = (int) Math.ceil(compHeight[y] / 8.0);
+ }
+ float Y[][] = new float[compHeight[0]][compWidth[0]];
+ float Cr1[][] = new float[compHeight[0]][compWidth[0]];
+ float Cb1[][] = new float[compHeight[0]][compWidth[0]];
+ //float Cb2[][] = new float[compHeight[1]][compWidth[1]];
+ //float Cr2[][] = new float[compHeight[2]][compWidth[2]];
+ for (int pt = 0, y = 0; y < imageHeight; ++y) {
+ for (int x = 0; x < imageWidth; ++x, pt++) {
+ int p = pixels[pt];
+ int r = ((p >> 16) & 0xff);
+ int g = ((p >> 8) & 0xff);
+ int b = (p & 0xff);
+ // The following three lines are a more correct color conversion but
+ // the current conversion technique is sufficient and results in a higher
+ // compression rate.
+ // Y[y][x] = 16 + (float)(0.8588*(0.299 * (float)r + 0.587 * (float)g + 0.114 * (float)b ));
+ // Cb1[y][x] = 128 + (float)(0.8784*(-0.16874 * (float)r - 0.33126 * (float)g + 0.5 * (float)b));
+ // Cr1[y][x] = 128 + (float)(0.8784*(0.5 * (float)r - 0.41869 * (float)g - 0.08131 * (float)b));
+ Y[y][x] = (float) ((0.299 * r + 0.587 * g + 0.114 * b));
+ Cb1[y][x] = 128 + (float) ((-0.16874 * r - 0.33126 * g + 0.5 * b));
+ Cr1[y][x] = 128 + (float) ((0.5 * r - 0.41869 * g - 0.08131 * b));
+ }
+ }
+
+ // Need a way to set the H and V sample factors before allowing downsampling.
+ // For now (04/04/98) downsampling must be hard coded.
+ // Until a better downsampler is implemented, this will not be done.
+ // Downsampling is currently supported. The downsampling method here
+ // is a simple box filter.
+
+ components[0] = Y;
+ // Cb2 = DownSample(Cb1, 1);
+ components[1] = Cb1;
+ // Cr2 = DownSample(Cr1, 2);
+ components[2] = Cr1;
+ }
+ /*
+ float[][] DownSample(float[][] C, int comp)
+ {
+ int inrow, incol;
+ int outrow, outcol;
+ float output[][];
+ int bias;
+ inrow = 0;
+ incol = 0;
+ int cHeight = compHeight[comp];
+ int cWidth = compWidth[comp];
+ output = new float[cHeight][cWidth];
+
+ for (outrow = 0; outrow < cHeight; outrow++) {
+ bias = 1;
+ for (outcol = 0; outcol < cWidth; outcol++) {
+ output[outrow][outcol] = (C[inrow][incol++] + C[inrow++][incol--]
+ + C[inrow][incol++] + C[inrow--][incol++] + bias)/(float)4.0;
+ bias ^= 3;
+ }
+ inrow += 2;
+ incol = 0;
+ }
+ return output;
+ }
+ */
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2009-06-30 18:58:33 -0500 (Tue, 30 Jun 2009) $
+ * $Revision: 11158 $
+ *
+ * Copyright (C) 2002-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.img;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import javajs.export.PDFCreator;
+
+/**
+ * A relatively primitive PDF generator that just makes a document with an image
+ * in it.
+ *
+ */
+public class PdfEncoder extends ImageEncoder {
+
+ private boolean isLandscape;
+ private PDFCreator pdf;
+ private String comment;
+
+ public PdfEncoder() {
+ // for Class.forName
+ }
+
+ @Override
+ protected void setParams(Map<String, Object> params) {
+ isLandscape = (quality > 1);
+ comment = "Jmol " + (String) params.get("comment");
+ }
+
+ @Override
+ protected void generate() throws Exception {
+ pdf = new PDFCreator();
+ int pageWidth = 8 * 72;
+ int pageHeight = 11 * 72;
+ pdf.setOutputStream(out);
+ pdf.newDocument(pageWidth, pageHeight, isLandscape); // A4 or Letter
+ addMyImage(pageWidth, pageHeight);
+ Map<String, String> ht = new Hashtable<String, String>();
+ if (comment != null)
+ ht.put("Producer", comment);
+ ht.put("Author", "JMol");
+ ht.put("CreationDate", date);
+ pdf.addInfo(ht);
+ pdf.closeDocument();
+ }
+
+
+ /**
+ * centered on the page
+ *
+ * @param pageWidth
+ * @param pageHeight
+ */
+ private void addMyImage(int pageWidth, int pageHeight) {
+ pdf.addImageResource("img1", width, height, pixels, true);
+ int w = (isLandscape ? pageHeight : pageWidth);
+ int h = (isLandscape ? pageWidth : pageHeight);
+ int iw = width;
+ int ih = height;
+ if (iw > 0.9 * w) {
+ ih = (int) (ih * 0.9 * w / iw);
+ iw = (int) (w * 0.9);
+ }
+ if (ih > 0.9 * h) {
+ iw = (int) (iw * 0.9 * h / ih);
+ ih = (int) (h * 0.9);
+ }
+ int x = 0;
+ int y = 0;
+ int x1 = iw;
+ int y1 = ih;
+ if (w > iw) {
+ x = (w - iw) / 2;
+ x1 = iw + x;
+ }
+ if (h > ih) {
+ y = (h - ih) / 2;
+ y1 = ih + y;
+ }
+ pdf.drawImage("img1", x, y, x1, y1, 0, 0, width, height);
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: nicove $
+ * $Date: 2007-03-30 12:26:16 -0500 (Fri, 30 Mar 2007) $
+ * $Revision: 7275 $
+ *
+ * Copyright (C) 2002-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.img;
+
+import java.util.Map;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+
+
+/**
+ *
+ * Modified by Bob Hanson hansonr@stolaf.edu to be a subclass of ImageEncoder
+ * and to use javajs.util.OutputChannel instead of just returning bytes. Also includes:
+ *
+ * -- JavaScript-compatible image processing
+ *
+ * -- transparent background option
+ *
+ * -- more efficient calculation of needs for pngBytes
+ *
+ * -- option to use pre-created PNGJ image data (3/19/14; Jmol 14.1.12)
+ *
+ * -- PNGJ format:
+ *
+ * // IHDR chunk
+ *
+ * // tEXt chunk "Jmol type - <PNG0|PNGJ><0000000pt>+<000000len>"
+ *
+ * // tEXt chunk "Software - Jmol <version>"
+ *
+ * // tEXt chunk "Creation Time - <date>"
+ *
+ * // tRNS chunk transparent color, if desired
+ *
+ * // IDAT chunk (image data)
+ *
+ * // IEND chunk
+ *
+ * // [JMOL ZIP FILE APPENDIX]
+ *
+ * Original Comment:
+ *
+ * PngEncoder takes a Java Image object and creates a byte string which can be
+ * saved as a PNG file. The Image is presumed to use the DirectColorModel.
+ *
+ * Thanks to Jay Denny at KeyPoint Software http://www.keypoint.com/ who let me
+ * develop this code on company time.
+ *
+ * You may contact me with (probably very-much-needed) improvements, comments,
+ * and bug fixes at:
+ *
+ * david@catcode.com
+ *
+ * @author J. David Eisenberg
+ * @author http://catcode.com/pngencoder/
+ * @author Christian Ribeaud (christian.ribeaud@genedata.com)
+ * @author Bob Hanson (hansonr@stolaf.edu)
+ *
+ * @version 1.4, 31 March 2000
+ */
+public class PngEncoder extends CRCEncoder {
+
+ /** Constants for filters */
+ public static final int FILTER_NONE = 0;
+ public static final int FILTER_SUB = 1;
+ public static final int FILTER_UP = 2;
+ public static final int FILTER_LAST = 2;
+
+ private static final int PT_FIRST_TAG = 37;
+
+ private boolean encodeAlpha;
+ private int filter = FILTER_NONE;
+ private int bytesPerPixel;
+ private int compressionLevel;
+ private String type;
+ private Integer transparentColor;
+
+ private byte[] appData;
+ private String appPrefix;
+ private String comment;
+ private byte[] bytes;
+
+
+ public PngEncoder() {
+ super();
+ }
+
+ @Override
+ protected void setParams(Map<String, Object> params) {
+ if (quality < 0)
+ quality = (params.containsKey("qualityPNG") ? ((Integer) params
+ .get("qualityPNG")).intValue() : 2);
+ if (quality > 9)
+ quality = 9;
+ encodeAlpha = false;
+ filter = FILTER_NONE;
+ compressionLevel = quality;
+ transparentColor = (Integer) params.get("transparentColor");
+ comment = (String) params.get("comment");
+ type = (params.get("type") + "0000").substring(0, 4);
+ bytes = (byte[]) params.get("pngImgData");
+ appData = (byte[]) params.get("pngAppData");
+ appPrefix = (String) params.get("pngAppPrefix");
+ }
+
+
+
+ @Override
+ protected void generate() throws IOException {
+ if (bytes == null) {
+ if (!pngEncode()) {
+ out.cancel();
+ return;
+ }
+ bytes = getBytes();
+ } else {
+ dataLen = bytes.length;
+ }
+ int len = dataLen;
+ if (appData != null) {
+ setJmolTypeText(appPrefix, bytes, len, appData.length,
+ type);
+ out.write(bytes, 0, len);
+ len = (bytes = appData).length;
+ }
+ out.write(bytes, 0, len);
+ }
+
+
+ /**
+ * Creates an array of bytes that is the PNG equivalent of the current image,
+ * specifying whether to encode alpha or not.
+ *
+ * @return true if successful
+ *
+ */
+ private boolean pngEncode() {
+
+ byte[] pngIdBytes = { -119, 80, 78, 71, 13, 10, 26, 10 };
+
+ writeBytes(pngIdBytes);
+ //hdrPos = bytePos;
+ writeHeader();
+ writeText(getApplicationText(appPrefix, type, 0, 0));
+
+ writeText("Software\0Jmol " + comment);
+ writeText("Creation Time\0" + date);
+
+ if (!encodeAlpha && transparentColor != null)
+ writeTransparentColor(transparentColor.intValue());
+ //dataPos = bytePos;
+ return writeImageData();
+ }
+
+ /**
+ * Fill in the Jmol type text area with number of bytes of PNG data and number
+ * of bytes of Jmol state data and fix checksum.
+ *
+ * If we do not do this, then the checksum will be wrong, and Jmol and some
+ * other programs may not be able to read the PNG image.
+ *
+ * This was corrected for Jmol 12.3.30. Between 12.3.7 and 12.3.29, PNG files
+ * created by Jmol have incorrect checksums.
+ *
+ * @param prefix
+ *
+ * @param b
+ * @param nPNG
+ * @param nState
+ * @param type
+ */
+ private static void setJmolTypeText(String prefix, byte[] b, int nPNG, int nState, String type) {
+ String s = "tEXt" + getApplicationText(prefix, type, nPNG, nState);
+ CRCEncoder encoder = new PngEncoder();
+ byte[] test = s.substring(0, 4 + prefix.length()).getBytes();
+ for (int i = test.length; -- i >= 0;)
+ if (b[i + PT_FIRST_TAG] != test[i]) {
+ System.out.println("image is not of the right form; appending data, but not adding tEXt tag.");
+ return;
+ }
+ encoder.setData(b, PT_FIRST_TAG);
+ encoder.writeString(s);
+ encoder.writeCRC();
+ }
+
+ private static String getApplicationText(String prefix, String type, int nPNG, int nState) {
+ String sPNG = "000000000" + nPNG;
+ sPNG = sPNG.substring(sPNG.length() - 9);
+ String sState = "000000000" + nState;
+ sState = sState.substring(sState.length() - 9);
+ return prefix + "\0" + type + (type.equals("PNG") ? "0" : "") + sPNG + "+"
+ + sState;
+ }
+
+ // /**
+ // * Set the filter to use
+ // *
+ // * @param whichFilter from constant list
+ // */
+ // public void setFilter(int whichFilter) {
+ // this.filter = (whichFilter <= FILTER_LAST ? whichFilter : FILTER_NONE);
+ // }
+
+ // /**
+ // * Retrieve filtering scheme
+ // *
+ // * @return int (see constant list)
+ // */
+ // public int getFilter() {
+ // return filter;
+ // }
+
+ // /**
+ // * Set the compression level to use
+ // *
+ // * @param level 0 through 9
+ // */
+ // public void setCompressionLevel(int level) {
+ // if ((level >= 0) && (level <= 9)) {
+ // this.compressionLevel = level;
+ // }
+ // }
+
+ // /**
+ // * Retrieve compression level
+ // *
+ // * @return int in range 0-9
+ // */
+ // public int getCompressionLevel() {
+ // return compressionLevel;
+ // }
+
+ /**
+ * Write a PNG "IHDR" chunk into the pngBytes array.
+ */
+ private void writeHeader() {
+
+ writeInt4(13);
+ startPos = bytePos;
+ writeString("IHDR");
+ writeInt4(width);
+ writeInt4(height);
+ writeByte(8); // bit depth
+ writeByte(encodeAlpha ? 6 : 2); // color type or direct model
+ writeByte(0); // compression method
+ writeByte(0); // filter method
+ writeByte(0); // no interlace
+ writeCRC();
+ }
+
+ private void writeText(String msg) {
+ writeInt4(msg.length());
+ startPos = bytePos;
+ writeString("tEXt" + msg);
+ writeCRC();
+ }
+
+ /**
+ * Write a PNG "tRNS" chunk into the pngBytes array.
+ *
+ * @param icolor
+ */
+ private void writeTransparentColor(int icolor) {
+
+ writeInt4(6);
+ startPos = bytePos;
+ writeString("tRNS");
+ writeInt2((icolor >> 16) & 0xFF);
+ writeInt2((icolor >> 8) & 0xFF);
+ writeInt2(icolor & 0xFF);
+ writeCRC();
+ }
+
+ private byte[] scanLines; // the scan lines to be compressed
+ private int byteWidth; // width * bytesPerPixel
+
+ //private int hdrPos, dataPos, endPos;
+ //private byte[] priorRow;
+ //private byte[] leftBytes;
+
+
+ /**
+ * Write the image data into the pngBytes array. This will write one or more
+ * PNG "IDAT" chunks. In order to conserve memory, this method grabs as many
+ * rows as will fit into 32K bytes, or the whole image; whichever is less.
+ *
+ *
+ * @return true if no errors; false if error grabbing pixels
+ */
+ private boolean writeImageData() {
+
+ bytesPerPixel = (encodeAlpha ? 4 : 3);
+ byteWidth = width * bytesPerPixel;
+
+ int scanWidth = byteWidth + 1; // the added 1 is for the filter byte
+
+ //boolean doFilter = (filter != FILTER_NONE);
+
+ int rowsLeft = height; // number of rows remaining to write
+ //int startRow = 0; // starting row to process this time through
+ int nRows; // how many rows to grab at a time
+
+ int scanPos; // where we are in the scan lines
+
+ Deflater deflater = new Deflater(compressionLevel);
+ ByteArrayOutputStream outBytes = new ByteArrayOutputStream(1024);
+
+ DeflaterOutputStream compBytes = new DeflaterOutputStream(outBytes,
+ deflater);
+
+ int pt = 0; // overall image byte pointer
+
+ // Jmol note: The entire image has been stored in pixels[] already
+
+ try {
+ while (rowsLeft > 0) {
+ nRows = Math.max(1, Math.min(32767 / scanWidth, rowsLeft));
+ scanLines = new byte[scanWidth * nRows];
+ // if (doFilter)
+ // switch (filter) {
+ // case FILTER_SUB:
+ // leftBytes = new byte[16];
+ // break;
+ // case FILTER_UP:
+ // priorRow = new byte[scanWidth - 1];
+ // break;
+ // }
+ int nPixels = width * nRows;
+ scanPos = 0;
+ //startPos = 1;
+ for (int i = 0; i < nPixels; i++, pt++) {
+ if (i % width == 0) {
+ scanLines[scanPos++] = (byte) filter;
+ //startPos = scanPos;
+ }
+ scanLines[scanPos++] = (byte) ((pixels[pt] >> 16) & 0xff);
+ scanLines[scanPos++] = (byte) ((pixels[pt] >> 8) & 0xff);
+ scanLines[scanPos++] = (byte) ((pixels[pt]) & 0xff);
+ if (encodeAlpha) {
+ scanLines[scanPos++] = (byte) ((pixels[pt] >> 24) & 0xff);
+ }
+ // if (doFilter && i % width == width - 1) {
+ // switch (filter) {
+ // case FILTER_SUB:
+ // filterSub();
+ // break;
+ // case FILTER_UP:
+ // filterUp();
+ // break;
+ // }
+ // }
+ }
+
+ /*
+ * Write these lines to the output area
+ */
+ compBytes.write(scanLines, 0, scanPos);
+
+ //startRow += nRows;
+ rowsLeft -= nRows;
+ }
+ compBytes.close();
+
+ /*
+ * Write the compressed bytes
+ */
+ byte[] compressedLines = outBytes.toByteArray();
+ writeInt4(compressedLines.length);
+ startPos = bytePos;
+ writeString("IDAT");
+ writeBytes(compressedLines);
+ writeCRC();
+ writeEnd();
+ deflater.finish();
+ return true;
+ } catch (IOException e) {
+ System.err.println(e.toString());
+ return false;
+ }
+ }
+
+ /**
+ * Write a PNG "IEND" chunk into the pngBytes array.
+ */
+ private void writeEnd() {
+ writeInt4(0);
+ startPos = bytePos;
+ writeString("IEND");
+ writeCRC();
+ }
+
+ ///**
+ //* Perform "sub" filtering on the given row.
+ //* Uses temporary array leftBytes to store the original values
+ //* of the previous pixels. The array is 16 bytes long, which
+ //* will easily hold two-byte samples plus two-byte alpha.
+ //*
+ //*/
+ //private void filterSub() {
+ // int offset = bytesPerPixel;
+ // int actualStart = startPos + offset;
+ // int leftInsert = offset;
+ // int leftExtract = 0;
+ // //byte current_byte;
+ //
+ // for (int i = actualStart; i < startPos + byteWidth; i++) {
+ // leftBytes[leftInsert] = scanLines[i];
+ // scanLines[i] = (byte) ((scanLines[i] - leftBytes[leftExtract]) % 256);
+ // leftInsert = (leftInsert + 1) % 0x0f;
+ // leftExtract = (leftExtract + 1) % 0x0f;
+ // }
+ //}
+ //
+ ///**
+ //* Perform "up" filtering on the given row. Side effect: refills the prior row
+ //* with current row
+ //*
+ //*/
+ //private void filterUp() {
+ // int nBytes = width * bytesPerPixel;
+ // for (int i = 0; i < nBytes; i++) {
+ // int pt = startPos + i;
+ // byte b = scanLines[pt];
+ // scanLines[pt] = (byte) ((scanLines[pt] - priorRow[i]) % 256);
+ // priorRow[i] = b;
+ // }
+ //}
+
+}
--- /dev/null
+// PpmEncoder - write out an image as a PPM
+//
+// Copyright (C)1996,1998 by Jef Poskanzer <jef@mail.acme.com>. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE.
+//
+// Visit the ACME Labs Java page for up-to-date versions of this and other
+// fine Java utilities: http://www.acme.com/java/
+
+package javajs.img;
+
+import java.util.Map;
+
+
+/**
+ * see http://netpbm.sourceforge.net/doc/ppm.html
+ */
+public class PpmEncoder extends ImageEncoder {
+
+ @Override
+ protected void setParams(Map<String, Object> params) {
+ // no params
+ }
+
+ @Override
+ protected void generate() {
+ putString("P6\n");
+ putString(width + " " + height + "\n");
+ putString("255\n");
+ byte[] ppmPixels = new byte[width * 3];
+ for (int pt = 0, row = 0; row < height; ++row) {
+ for (int col = 0, j = 0; col < width; ++col, pt++) {
+ int p = pixels[pt];
+ ppmPixels[j++] = (byte) ((p >> 16) & 0xff);
+ ppmPixels[j++] = (byte) ((p >> 8) & 0xff);
+ ppmPixels[j++] = (byte) (p & 0xff);
+ }
+ out.write(ppmPixels, 0, ppmPixels.length);
+ }
+ }
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.Component;
+
+import javajs.api.SC;
+
+public abstract class AbstractButton extends JComponent implements SC {
+
+ Object itemListener;
+ Object applet;
+ String htmlName;
+ boolean selected;
+
+ private SC popupMenu;
+
+ private String icon;
+
+ protected AbstractButton(String type) {
+ super(type);
+ enabled = true;
+ }
+
+ @Override
+ public void setSelected(boolean selected) {
+ this.selected = selected;
+ /**
+ * @j2sNative
+ *
+ * SwingController.setSelected(this);
+ *
+ */
+ {
+ }
+ }
+
+ @Override
+ public boolean isSelected() {
+ return selected;
+ }
+
+ @Override
+ public void addItemListener(Object listener) {
+ itemListener = listener;
+ }
+
+ @Override
+ public Object getIcon() {
+ return icon;
+ }
+
+ @Override
+ public void setIcon(Object icon) {
+ this.icon = (String) icon;
+ }
+
+ @Override
+ public void init(String text, Object icon, String actionCommand, SC popupMenu) {
+ this.text = text;
+ this.icon = (String) icon;
+ this.actionCommand = actionCommand;
+ this.popupMenu = popupMenu;
+ /**
+ * @j2sNative
+ *
+ * SwingController.initMenuItem(this);
+ *
+ */
+ {
+ }
+ }
+
+ public SC getTopPopupMenu() {
+ // note that JMenu.getPopupMenu refers to ITSELF, not the main one)
+ return popupMenu;
+ }
+
+ @Override
+ public void add(SC item) {
+ addComponent((Component) item);
+ }
+
+ @Override
+ public void insert(SC subMenu, int index) {
+ // JMenu, JPopupMenu only, but implemented here as well
+ // for simplicity
+ insertComponent((Component) subMenu, index);
+ }
+
+ @Override
+ public Object getPopupMenu() {
+ // JMenu only
+ return null;
+ }
+
+ protected String getMenuHTML() {
+ String label = (this.icon != null ? this.icon
+ : this.text != null ? this.text
+ : null);
+ String s = (label == null ? "" : "<li><a>" + label + "</a>"
+ + htmlMenuOpener("ul"));
+ int n = getComponentCount();
+ if (n > 0)
+ for(int i = 0; i < n; i++)
+ s += getComponent(i).toHTML();
+ if (label != null)
+ s += "</ul></li>";
+ return s;
+ }
+
+ protected String htmlMenuOpener(String type) {
+ return "<" + type + " id=\"" + this.id + "\"" + (this.enabled ? "" : getHtmlDisabled()) + ">";
+ }
+
+ protected String getHtmlDisabled() {
+ return " disabled=\"disabled\"";
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.util.BS;
+import javajs.util.SB;
+
+
+abstract public interface AbstractTableModel extends TableColumn {
+
+ TableColumn getColumn(int i);
+
+ void toHTML(SB sb, String id, BS bsSelectedRows);
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.api.SC;
+import javajs.awt.Component;
+
+public class ButtonGroup {
+
+ private String id;
+
+ public ButtonGroup() {
+ id = Component.newID("bg");
+ }
+
+ public void add(SC item) {
+ ((AbstractButton) item).htmlName = this.id;
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+public class Cell {
+
+ private JComponent component;
+ private int colspan;
+ private int rowspan;
+ int textAlign;
+ private GridBagConstraints c;
+
+ public Cell(JComponent btn, GridBagConstraints c) {
+ this.component = btn;
+ colspan = c.gridwidth;
+ rowspan = c.gridheight; // ignoring for now
+ this.c = c;
+ }
+
+ public String toHTML(String id) {
+ String style = c.getStyle(false);
+ return "<td id='" + id +"' " + (colspan < 2 ? "" : "colspan='" + colspan + "' ")
+ + style + "><span " + c.getStyle(true) + ">" + component.toHTML() + "</span></td>";
+ }
+
+
+}
--- /dev/null
+package javajs.swing;
+
+public interface ColumnSelectionModel {
+
+ ListSelectionModel getSelectionModel();
+
+ TableColumn getColumn(int i);
+
+}
--- /dev/null
+package javajs.swing;
+
+public interface Document {
+
+ void insertString(int i, String text, Object object);
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.LayoutManager;
+
+public class FlowLayout extends LayoutManager {
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.util.AU;
+import javajs.util.SB;
+
+
+public class Grid {
+
+ private int nrows;
+ private int ncols;
+
+ private Cell[][] grid;
+ private String renderer;
+
+
+ Grid(int rows, int cols) {
+ grid = new Cell[0][0];
+ }
+
+ public void add(JComponent btn, GridBagConstraints c) {
+ if (c.gridx >= ncols) {
+ ncols = c.gridx + 1;
+ for (int i = 0; i < nrows; i++) {
+ grid[i] = (Cell[]) AU.ensureLength(grid[i], ncols * 2);
+ }
+ }
+ if (c.gridy >= nrows) {
+ Cell[][] g = new Cell[c.gridy * 2 + 1][];
+ for (int i = 0; i < nrows; i++)
+ g[i] = grid[i];
+ for (int i = g.length; --i >= nrows;)
+ g[i] = new Cell[ncols * 2 + 1];
+ grid = g;
+ nrows = c.gridy + 1;
+ }
+ grid[c.gridy][c.gridx] = new Cell(btn, c);
+ }
+
+ public String toHTML(String id) {
+ SB sb = new SB();
+ id += "_grid";
+ sb.append("\n<table id='" + id + "' class='Grid' style='width:100%;height:100%'><tr><td style='height:20%;width:20%'></td></tr>");
+ for (int i = 0; i < nrows; i++) {
+ String rowid = id + "_" + i;
+ sb.append("\n<tr id='" + rowid + "'><td></td>");
+ for (int j = 0; j < ncols; j++)
+ if (grid[i][j] != null)
+ sb.append(grid[i][j].toHTML(rowid + "_" + j));
+ sb.append("</tr>");
+ }
+ sb.append("\n<tr><td style='height:20%;width:20%'></td></tr></table>\n");
+ return sb.toString();
+ }
+}
--- /dev/null
+package javajs.swing;
+
+public class GridBagConstraints {
+
+ public static final int NONE = 0;
+ public static final int CENTER = 10;
+ public static final int WEST = 17;
+ public static final int EAST = 13;
+
+ public int gridx;
+ public int gridy;
+ public int gridwidth;
+ public int gridheight;
+ double weightx;
+ double weighty;
+ public int anchor;
+ public int fill;
+ Insets insets;
+ public int ipadx;
+ public int ipady;
+
+ public GridBagConstraints(int gridx, int gridy, int gridwidth,
+ int gridheight, double weightx, double weighty, int anchor, int fill,
+ Insets insets, int ipadx, int ipady) {
+ this.gridx = gridx;
+ this.gridy = gridy;
+ this.gridwidth = gridwidth;
+ this.gridheight = gridheight;
+ this.weightx = weightx;
+ this.weighty = weighty;
+ this.anchor = anchor;
+ this.fill = fill;
+ if (insets == null)
+ insets = new Insets(0, 0, 0, 0);
+ this.insets = insets;
+ this.ipadx = ipadx;
+ this.ipady = ipady;
+ }
+
+ String getStyle(boolean margins) {
+ return "style='" + (margins ?
+ "margin:" + insets.top + "px " + (ipady + insets.right) + "px "
+ + insets.bottom + "px " + (ipadx + insets.left) + "px;"
+ : "text-align:" + (anchor == EAST ? "right" : anchor == WEST? "left" : "center")) + "'";
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.LayoutManager;
+
+public class GridBagLayout extends LayoutManager {
+
+}
--- /dev/null
+package javajs.swing;
+
+public class Insets {
+
+ int top, left, bottom, right;
+
+ public Insets(int top, int left, int bottom, int right) {
+ this.top = top;
+ this.left = left;
+ this.bottom = bottom;
+ this.right = right;
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.util.SB;
+
+public class JButton extends AbstractButton {
+
+ public JButton() {
+ super("btnJB");
+ }
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("<input type=button id='" + id + "' class='JButton' style='" + getCSSstyle(80, 0) + "' onclick='SwingController.click(this)' value='"+ text + "'/>");
+ return sb.toString();
+ }
+}
--- /dev/null
+package javajs.swing;
+
+public class JCheckBox extends AbstractButton {
+
+ public JCheckBox() {
+ super("chkJCB");
+ }
+
+ @Override
+ public String toHTML() {
+ String s = "<label><input type=checkbox id='" + id
+ + "' class='JCheckBox' style='" + getCSSstyle(0, 0) + "' "
+ + (selected ? "checked='checked' " : "")
+ + "onclick='SwingController.click(this)'>" + text + "</label>";
+ return s;
+ }
+
+
+}
--- /dev/null
+package javajs.swing;
+
+public class JCheckBoxMenuItem extends JMenuItem {
+
+
+ public JCheckBoxMenuItem() {
+ super("chk", TYPE_CHECKBOX);
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.util.SB;
+
+public class JComboBox<T> extends AbstractButton {
+
+ private String[] info;
+ private int selectedIndex;
+
+ public JComboBox(String[] info){
+ super("cmbJCB");
+ this.info = info;
+ }
+
+ public void setSelectedIndex(int i) {
+ selectedIndex = i;
+ /**
+ * @j2sNative
+ *
+ * SwingController.setSelectedIndex(this);
+ *
+ */
+ {
+ }
+ }
+
+ public int getSelectedIndex() {
+ return selectedIndex;
+ }
+
+ public Object getSelectedItem() {
+ return (selectedIndex < 0 ? null : info[selectedIndex]);
+ }
+
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("\n<select id='" + id + "' class='JComboBox' onchange='SwingController.click(this)'>\n");
+ for (int i = 0; i < info.length; i++)
+ sb.append("\n<option class='JComboBox_option'" + (i == selectedIndex ? "selected":"") + ">" + info[i] + "</option>");
+ sb.append("\n</select>\n");
+ return sb.toString();
+ }
+
+
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.Container;
+
+public abstract class JComponent extends Container {
+
+ protected boolean autoScrolls;
+ protected String actionCommand;
+ protected Object actionListener;
+
+ protected JComponent(String type) {
+ super(type);
+ }
+
+ public void setAutoscrolls(boolean b) {
+ autoScrolls = b;
+ }
+
+ /**
+ * Note that it will be the job of the JavaScript on the
+ * page to do with actionListener what is desired.
+ *
+ * In javax.swing, these methods are in AbstractButton, but
+ * this is better for javajs.swing, reducing the duplication
+ * of JTextField's actionListener business.
+ *
+ * @param listener
+ *
+ */
+ public void addActionListener(Object listener) {
+ actionListener = listener;
+ }
+
+ public String getActionCommand() {
+ return actionCommand;
+ }
+
+ public void setActionCommand(String actionCommand) {
+ this.actionCommand = actionCommand;
+ }
+
+
+
+
+}
--- /dev/null
+package javajs.swing;
+
+/**
+ * implementation of a JComponent
+ *
+ */
+class JComponentImp extends JComponent {
+
+ protected JComponentImp(String type) {
+ super(type);
+ }
+
+ @Override
+ public String toHTML() {
+ return null;
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.util.SB;
+
+public class JContentPane extends JComponent {
+
+ public JContentPane() {
+ super("JCP");
+ }
+
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("\n<div id='" + id + "' class='JContentPane' style='"
+ + getCSSstyle(100, 100) + "'>\n");
+ if (list != null)
+ for (int i = 0; i < list.size(); i++)
+ sb.append(list.get(i).toHTML());
+ sb.append("\n</div>\n");
+ return sb.toString();
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.Color;
+import javajs.awt.Container;
+import javajs.util.SB;
+
+
+/**
+ * There is really no need here for awt.Dialog.
+ * We would not use FileDialog in an HTML5 context anyway.
+ *
+ */
+public class JDialog extends Container {
+
+ private static final int headerHeight = 25;
+ private int defaultWidth = 600;
+ private int defaultHeight = 300;
+
+ private JContentPane contentPane;
+ private String title;
+ private String html;
+ private int zIndex = 9000;
+
+ public void setZIndex(int zIndex) {
+ this.zIndex = zIndex;
+ }
+
+ int[] loc;
+
+ public JDialog() {
+ super("JD");
+ add(contentPane = new JContentPane());
+ setBackground(Color.get3(210, 210, 240));
+ contentPane.setBackground(Color.get3(230, 230, 230));
+ }
+
+ public void setLocation(int[] loc) {
+ this.loc = loc;
+ }
+
+ public JContentPane getContentPane() {
+ return contentPane;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public void pack() {
+ html = null;
+ }
+
+ public void validate() {
+ html = null;
+ }
+
+ @Override
+ public void setVisible(boolean tf) {
+ if (tf && html == null)
+ setDialog();
+ super.setVisible(tf);
+ }
+
+ public void dispose() {
+ {
+
+ /**
+ * @j2sNative
+ *
+ * SwingController.dispose(this);
+ *
+ */
+ {
+ }
+
+ }
+ }
+
+ @Override
+ public void repaint() {
+ setDialog();
+ }
+
+ /**
+ * Set it into DOM, but don't show it yet.
+ * this.loc, this.manager, this.id, etc.
+ *
+ */
+ private void setDialog() {
+ html = toHTML();
+ /**
+ * @j2sNative
+ *
+ * SwingController.setDialog(this);
+ *
+ *
+ */
+ {
+ System.out.println(html);
+ }
+ }
+
+ @Override
+ public String toHTML() {
+ renderWidth = getSubcomponentWidth();
+ if (renderWidth == 0)
+ renderWidth = defaultWidth;
+ renderHeight = contentPane.getSubcomponentHeight();
+ if (renderHeight == 0)
+ renderHeight = defaultHeight;
+ int h = renderHeight - headerHeight;
+ SB sb = new SB();
+ sb.append("\n<div id='" + id + "' class='JDialog' style='" + getCSSstyle(0, 0) + "z-index:" + zIndex + ";position:relative;top:0px;left:0px;reize:both;'>\n");
+ sb.append("\n<div id='" + id + "_title' class='JDialogTitle' style='width:100%;height:25px;padding:5px 5px 5px 5px;height:"+headerHeight+"px'>"
+ +"<span style='text-align:center;'>" + title + "</span><span style='position:absolute;text-align:right;right:1px;'>"
+ + "<input type=button id='" + id + "_closer' onclick='SwingController.windowClosing(this)' value='x' /></span></div>\n");
+ sb.append("\n<div id='" + id + "_body' class='JDialogBody' style='width:100%;height:"+h+"px;"
+ +"position: relative;left:0px;top:0px'>\n");
+ sb.append(contentPane.toHTML());
+ sb.append("\n</div></div>\n");
+ return sb.toString();
+ }
+
+
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.util.SB;
+
+/**
+ * A simple implementation of a Swing JTextPane.
+ * Operates as its own Document; no attributes
+ *
+ * @author hansonr
+ *
+ */
+public class JEditorPane extends JComponent {
+
+ public JEditorPane() {
+ super("txtJEP");
+ text = "";
+ }
+
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("<textarea type=text id='" + id + "' class='JEditorPane' style='" + getCSSstyle(98, 98) + "'>"+ text + "</textarea>");
+ return sb.toString();
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.util.SB;
+
+public class JLabel extends JComponent {
+
+ public JLabel(String text) {
+ super("lblJL");
+ this.text = text;
+ }
+
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("<span id='" + id + "' class='JLabel' style='" + getCSSstyle(0, 0) + "'>");
+ sb.append(text);
+ sb.append("</span>");
+ return sb.toString();
+ }
+
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.Component;
+
+public class JMenu extends JMenuItem {
+
+ public JMenu() {
+ super("mnu",TYPE_MENU);
+ }
+
+ public int getItemCount() {
+ return getComponentCount();
+ }
+
+ public Component getItem(int i) {
+ return getComponent(i);
+ }
+
+ @Override
+ public Object getPopupMenu() {
+ return this;
+ }
+
+ @Override
+ public String toHTML() {
+ return getMenuHTML();
+ }
+}
--- /dev/null
+package javajs.swing;
+
+public class JMenuItem extends AbstractButton {
+
+ public final int btnType;
+
+ public static final int TYPE_SEPARATOR = 0;
+ public static final int TYPE_BUTTON = 1;
+ public static final int TYPE_CHECKBOX = 2;
+ public static final int TYPE_RADIO = 3;
+ public static final int TYPE_MENU = 4;
+
+
+ public JMenuItem(String text) {
+ super("btn");
+ setText(text);
+ btnType = (text == null ? 0 : 1);
+ }
+
+ public JMenuItem(String type, int i) {
+ super(type);
+ btnType = i;
+ }
+
+ @Override
+ public String toHTML() {
+ return htmlMenuOpener("li")
+ + (text == null ? "" : "<a>" + htmlLabel() + "</a>") + "</li>";
+ }
+
+ @Override
+ protected String getHtmlDisabled() {
+ return " class=\"ui-state-disabled\"";
+ }
+
+ private String htmlLabel() {
+ return (btnType == TYPE_BUTTON ? text
+ : "<label><input id=\"" + id + "-" + (btnType == TYPE_RADIO ? "r" : "c")
+ + "b\" type=\""
+ + (btnType == TYPE_RADIO ? "radio\" name=\"" + htmlName : "checkbox")
+ + "\" " + (selected ? "checked" : "") + " />"
+ + text + "</label>");
+ }
+
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.BorderLayout;
+import javajs.awt.LayoutManager;
+import javajs.util.SB;
+
+public class JPanel extends JComponent {
+
+ //private LayoutManager layoutManager;
+
+ private Grid grid;
+
+ private int nElements;
+ private JComponent last;
+
+
+ /**
+ * @param manager ignored. we just use the layout designations with a grid
+ */
+ public JPanel(LayoutManager manager) {
+ super("JP");
+ //this.layoutManager = manager;
+ grid = new Grid(10,10);
+ }
+
+ public void add(JComponent btn, Object c) {
+ last = (++nElements == 1 ? btn : null);
+ if (c instanceof String) {
+ if (c.equals(BorderLayout.NORTH))
+ c = new GridBagConstraints(0, 0, 3, 1, 0, 0, GridBagConstraints.CENTER,
+ 0, null, 0, 0);
+ else if (c.equals(BorderLayout.SOUTH))
+ c = new GridBagConstraints(0, 2, 3, 1, 0, 0, GridBagConstraints.CENTER,
+ 0, null, 0, 0);
+ else if (c.equals(BorderLayout.EAST))
+ c = new GridBagConstraints(2, 1, 1, 1, 0, 0, GridBagConstraints.EAST,
+ 0, null, 0, 0);
+ else if (c.equals(BorderLayout.WEST))
+ c = new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.WEST,
+ 0, null, 0, 0);
+ else
+ c = new GridBagConstraints(1, 1, 1, 1, 0, 0, GridBagConstraints.CENTER,
+ 0, null, 0, 0);
+ }
+ grid.add(btn, (GridBagConstraints) c);
+ }
+
+ @Override
+ public String toHTML() {
+ if (last != null) {
+ // only one element
+ grid = new Grid(1, 1);
+ grid.add(last, new GridBagConstraints(0, 0, 1, 1, 0, 0,
+ GridBagConstraints.CENTER, 0, null, 0, 0));
+ last = null;
+ }
+ SB sb = new SB();
+ sb.append("\n<div id='" + id + "' class='JPanel' style='"
+ + getCSSstyle(100, 100) + "'>\n");
+ sb.append("\n<span id='" + id + "_minimizer' style='width:" + minWidth
+ + "px;height:" + minHeight + "px;'>");
+ sb.append(grid.toHTML(id));
+ sb.append("</span>");
+ sb.append("\n</div>\n");
+ return sb.toString();
+ }
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.Component;
+
+public class JPopupMenu extends AbstractButton {
+
+ // note that in Java Swing JPopupMenu extends
+ // JComponent, but here we extend AbstractButton
+ // so that it shares the SwingComponent interface
+
+ boolean tainted = true;
+
+ static {
+ /**
+ * @j2sNative
+ *
+ * SwingController.setDraggable(javajs.swing.JPopupMenu);
+ */
+ {
+ }
+ }
+
+ public JPopupMenu(String name) {
+ super("mnu");
+ this.name = name;
+ }
+
+ public void setInvoker(Object applet) {
+ this.applet = applet;
+ /**
+ * @j2sNative
+ *
+ * SwingController.setMenu(this);
+ *
+ */
+ {}
+ }
+
+ /**
+ * @param applet
+ * @param x
+ * @param y
+ */
+ public void show(Component applet, int x, int y) {
+ /**
+ * @j2sNative
+ *
+ * if (applet != null)
+ * this.tainted = true;
+ * SwingController.showMenu(this, x, y);
+ *
+ */
+ {}
+ }
+
+ public void disposeMenu() {
+ /**
+ * @j2sNative
+ *
+ * SwingController.disposeMenu(this);
+ */
+ {}
+ }
+
+ @Override
+ public String toHTML() {
+ return getMenuHTML();
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+public class JRadioButtonMenuItem extends JMenuItem {
+
+ protected boolean isRadio = true;
+
+ public JRadioButtonMenuItem() {
+ super("rad",TYPE_RADIO);
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.Component;
+import javajs.awt.Dimension;
+import javajs.util.SB;
+
+public class JScrollPane extends JComponent {
+
+ public JScrollPane(JComponent component) {
+ super("JScP");
+ add(component);
+ }
+
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("\n<div id='" + id + "' class='JScrollPane' style='" + getCSSstyle(98, 98) + "overflow:auto'>\n");
+ if (list != null) {
+ Component c = list.get(0);
+ sb.append(c.toHTML());
+ }
+ sb.append("\n</div>\n");
+ return sb.toString();
+ }
+
+ @Override
+ public void setMinimumSize(Dimension dimension) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.Container;
+import javajs.util.SB;
+
+public class JSplitPane extends JComponent {
+
+ public static final int HORIZONTAL_SPLIT = 1;
+ boolean isH = true;
+ private int split = 1;
+ private Container right;
+ private Container left;
+
+ public JSplitPane(int split) {
+ super("JSpP");
+ this.split = split;
+ isH = (split == HORIZONTAL_SPLIT);
+ }
+
+ public void setRightComponent(JComponent r) {
+ right = new JComponentImp(null);
+ right.add(r);
+ }
+
+ public void setLeftComponent(JComponent l) {
+ left = new JComponentImp(null);
+ left.add(l);
+ }
+
+ @Override
+ public int getSubcomponentWidth() {
+ int w = this.width;
+ if (w == 0) {
+ int wleft = left.getSubcomponentWidth();
+ int wright = right.getSubcomponentWidth();
+ if (wleft > 0 && wright > 0) {
+ if (isH)
+ w = wleft + wright;
+ else
+ w = Math.max(wleft, wright);
+ }
+ }
+ return w;
+ }
+
+ @Override
+ public int getSubcomponentHeight() {
+ int h = this.height;
+ if (h == 0) {
+ int hleft = left.getSubcomponentHeight();
+ int hright = right.getSubcomponentHeight();
+ if (hleft > 0 && hright > 0) {
+ if (isH)
+ h = Math.max(hleft, hright);
+ else
+ h = hleft + hright;
+ }
+ }
+ return h;
+ }
+
+ @Override
+ public String toHTML() {
+ if (left == null || right == null)
+ return "";
+ boolean isH = (split == HORIZONTAL_SPLIT);
+ if (width == 0)
+ width = getSubcomponentWidth();
+ if (height == 0)
+ height = getSubcomponentHeight();
+ SB sb = new SB();
+ sb.append("<div id='" + id + "' class='JSplitPane' style='" + getCSSstyle(100, 100) + "'>");
+ if (isH)
+ sb.append("<div id='" + id + "_left' style='width:50%;height:100%;position:absolute;top:0%;left:0%'>");
+ else
+ sb.append("<div id='" + id + "_top' style='width:100%;height:50%;position:absolute;top:0%;left:0%'>");
+ sb.append(left.getComponents()[0].toHTML());
+ if (isH)
+ sb.append("</div><div id='" + id + "_right' style='width:50%;height:100%;position:absolute;top:0%;left:50%'>");
+ else
+ sb.append("</div><div id='" + id + "_bottom' style='width:100%;height:50%;position:absolute;top:50%;left:0%'>");
+ sb.append(right.getComponents()[0].toHTML());
+ sb.append("</div></div>\n");
+ return sb.toString();
+ }
+
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.awt.Dimension;
+import javajs.util.BS;
+import javajs.util.SB;
+
+
+public class JTable extends JComponent implements ListSelectionModel, ColumnSelectionModel {
+
+ private AbstractTableModel tableModel;
+ private BS bsSelectedCells;
+ private BS bsSelectedRows;
+
+ boolean rowSelectionAllowed;
+ boolean cellSelectionEnabled;
+ Object selectionListener;
+
+ public JTable(AbstractTableModel tableModel) {
+ super("JT");
+ this.tableModel = tableModel;
+ this.bsSelectedCells = new BS();
+ this.bsSelectedRows = new BS();
+ }
+
+ @Override
+ public ListSelectionModel getSelectionModel() {
+ return this;
+ }
+
+ public ColumnSelectionModel getColumnModel() {
+ return this;
+ }
+
+ public void setPreferredScrollableViewportSize(Dimension dimension) {
+ this.width = dimension.width;
+ this.height = dimension.height;
+ }
+
+ public void clearSelection() {
+ bsSelectedCells.clearAll();
+ bsSelectedRows.clearAll();
+ }
+
+ public void setRowSelectionAllowed(boolean b) {
+ rowSelectionAllowed = b;
+ }
+
+ public void setRowSelectionInterval(int i, int j) {
+ bsSelectedRows.clearAll();
+ bsSelectedRows.setBits(i, j);
+ bsSelectedCells.clearAll();
+ }
+
+ public void setCellSelectionEnabled(boolean enabled) {
+ cellSelectionEnabled = enabled;
+ }
+
+ /**
+ * It will be the function of the JavaScript on the
+ * page to do with selectionListener what is desired.
+ *
+ * @param listener
+ *
+ */
+ @Override
+ public void addListSelectionListener(Object listener) {
+ selectionListener = listener;
+ }
+
+ @Override
+ public TableColumn getColumn(int i) {
+ return tableModel.getColumn(i);
+ }
+
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("\n<table id='" + id + "_table' class='JTable' >");
+ tableModel.toHTML(sb, id, bsSelectedRows);
+ sb.append("\n</table>\n");
+ return sb.toString();
+ }
+}
--- /dev/null
+
+package javajs.swing;
+
+import javajs.util.SB;
+
+public class JTextField extends JComponent {
+
+ public JTextField(String value) {
+ super("txtJT");
+ text = value;
+ }
+
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("<input type=text id='" + id + "' class='JTextField' style='" + getCSSstyle(0, 0) + "' value='"+ text + "' onkeyup =SwingController.click(this,event) >");
+ return sb.toString();
+ }
+
+
+}
--- /dev/null
+package javajs.swing;
+
+import javajs.util.SB;
+
+/**
+ * A simple implementation of a Swing JTextPane.
+ * Operates as its own Document; no attributes
+ *
+ * @author hansonr
+ *
+ */
+public class JTextPane extends JComponent implements Document {
+
+ public JTextPane() {
+ super("txtJTP");
+ text = "";
+ }
+
+ public Document getDocument() {
+ return this;
+ }
+
+ @Override
+ public void insertString(int i, String s, Object object) {
+ i = Math.min(i, text.length());
+ text = text.substring(0, i) + s + text.substring(i);
+ }
+
+ @Override
+ public String toHTML() {
+ SB sb = new SB();
+ sb.append("<textarea type=text id='" + id + "' class='JTextPane' style='" + getCSSstyle(98, 98) + "'>"+ text + "</textarea>");
+ return sb.toString();
+ }
+
+}
--- /dev/null
+package javajs.swing;
+
+public interface ListSelectionModel {
+
+ void addListSelectionListener(Object listener);
+
+}
--- /dev/null
+package javajs.swing;
+
+public class SwingConstants {
+
+ public static final int LEFT = 2;
+ public static final int CENTER = 0;
+ public static final int RIGHT = 4;
+
+}
--- /dev/null
+package javajs.swing;
+
+public interface TableCellRenderer {
+
+ String getCellStyle(int iRow, int iCol, GridBagConstraints c);
+
+}
--- /dev/null
+package javajs.swing;
+
+public interface TableColumn {
+
+ void setPreferredWidth(int n);
+
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+import java.io.Serializable;
+
+import javajs.api.JSONEncodable;
+import javajs.util.T3;
+
+
+
+/**
+ * A 4 element axis angle represented by single precision floating point
+ * x,y,z,angle components. An axis angle is a rotation of angle (radians) about
+ * the vector (x,y,z).
+ *
+ * @version specification 1.1, implementation $Revision: 1.9 $, $Date:
+ * 2006/07/28 17:01:32 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
+ * for unique constructor and method names
+ * for the optimization of compiled JavaScript using Java2Script
+ */
+public class A4 implements JSONEncodable, Serializable {
+
+ /*
+ * I assumed that the length of the axis vector is not significant.
+ */
+
+ /**
+ * The x coordinate.
+ */
+ public float x;
+
+ /**
+ * The y coordinate.
+ */
+ public float y;
+
+ /**
+ * The z coordinate.
+ */
+ public float z;
+
+ /**
+ * The angle.
+ */
+ public float angle;
+
+ /**
+ * Constructs and initializes a AxisAngle4f to (0,0,1,0).
+ */
+ public A4() {
+ z = 1.0f;
+ }
+
+ /**
+ * Constructs and initializes an AxisAngle4f from the specified x, y, z, and
+ * angle.
+ *
+ * @param x
+ * the x coordinate
+ * @param y
+ * the y coordinate
+ * @param z
+ * the z coordinate
+ * @param angle
+ * the angle.
+ * @return a
+ */
+ public static A4 new4(float x, float y, float z, float angle) {
+ A4 a = new A4();
+ a.set4(x, y, z, angle);
+ return a;
+ }
+
+ /**
+ * Constructs and initializes a AxisAngle4f from the specified AxisAngle4f.
+ *
+ * @param a1
+ * the AxisAngle4f containing the initialization x y z angle data
+ * @return a
+ */
+ public static A4 newAA(A4 a1) {
+ A4 a = new A4();
+ a.set4(a1.x, a1.y, a1.z, a1.angle);
+ return a;
+ }
+
+ /**
+ * Constructs and initializes an AxisAngle4f from the specified axis and
+ * angle.
+ *
+ * @param axis
+ * the axis
+ * @param angle
+ * the angle
+ * @return a
+ */
+ public static A4 newVA(V3 axis, float angle) {
+ A4 a = new A4();
+ a.setVA(axis, angle);
+ return a;
+ }
+
+ /**
+ * Sets the value of this AxisAngle4f to the specified axis and angle.
+ *
+ * @param axis
+ * the axis
+ * @param angle
+ * the angle
+ * @since Java 3D 1.2
+ */
+ public final void setVA(V3 axis, float angle) {
+ x = axis.x;
+ y = axis.y;
+ z = axis.z;
+ this.angle = angle;
+ }
+
+ /**
+ * Sets the value of this axis angle to the specified x,y,z,angle.
+ *
+ * @param x
+ * the x coordinate
+ * @param y
+ * the y coordinate
+ * @param z
+ * the z coordinate
+ * @param angle
+ * the angle
+ */
+ public final void set4(float x, float y, float z, float angle) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.angle = angle;
+ }
+
+ /**
+ * Sets the value of this axis angle to the value of axis angle t1.
+ *
+ * @param a
+ * the axis angle to be copied
+ */
+ public final void setAA(A4 a) {
+ x = a.x;
+ y = a.y;
+ z = a.z;
+ angle = a.angle;
+ }
+
+
+ /**
+ * Sets the value of this axis-angle to the rotational component of the passed
+ * matrix.
+ *
+ * @param m1
+ * the matrix3f
+ */
+ public final void setM(M3 m1) {
+ setFromMat(m1.m00, m1.m01, m1.m02, m1.m10, m1.m11, m1.m12, m1.m20, m1.m21,
+ m1.m22);
+ }
+
+ // helper method
+ private void setFromMat(double m00, double m01, double m02, double m10,
+ double m11, double m12, double m20, double m21,
+ double m22) {
+ // assuming M is normalized.
+
+ double cos = (m00 + m11 + m22 - 1.0) * 0.5;
+ x = (float) (m21 - m12);
+ y = (float) (m02 - m20);
+ z = (float) (m10 - m01);
+ double sin = 0.5 * Math.sqrt(x * x + y * y + z * z);
+ if (sin == 0 && cos == 1) {
+ x = y = 0;
+ z = 1;
+ angle = 0;
+ } else {
+ angle = (float) Math.atan2(sin, cos);
+ }
+
+ // no need to normalize
+ // x /= n;
+ // y /= n;
+ // z /= n;
+ }
+
+ /**
+ * Returns a hash number based on the data values in this object. Two
+ * different AxisAngle4f objects with identical data values (ie, returns true
+ * for equals(AxisAngle4f) ) will return the same hash number. Two vectors
+ * with different data members may return the same hash value, although this
+ * is not likely.
+ */
+ @Override
+ public int hashCode() {
+ return T3.floatToIntBits0(x) ^ T3.floatToIntBits0(y)
+ ^ T3.floatToIntBits0(z) ^ T3.floatToIntBits0(angle);
+ }
+
+ /**
+ * Returns true if the Object o is of type AxisAngle4f and all of the data
+ * members of o1 are equal to the corresponding data members in this
+ * AxisAngle4f.
+ *
+ * @param o
+ * the object with which the comparison is made.
+ * @return T/F
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof A4))
+ return false;
+ A4 a1 = (A4) o;
+ return x == a1.x && y == a1.y && z == a1.z && angle == a1.angle;
+ }
+
+ /**
+ * Returns a string that contains the values of this AxisAngle4f. The form is
+ * (x,y,z,angle).
+ *
+ * @return the String representation
+ */
+ @Override
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ", " + angle + ")";
+ }
+
+ @Override
+ public String toJSON() {
+ return "[" + x + "," + y + "," + z + "," + (float) (angle * 180.0 / Math.PI) + "]";
+ }
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: egonw $
+ * $Date: 2005-11-10 09:52:44 -0600 (Thu, 10 Nov 2005) $
+ * $Revision: 4255 $
+ *
+ * Copyright (C) 2003-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.util;
+
+// 4/23/15 BH getComponentType fix
+
+import java.lang.reflect.Array;
+
+import java.util.Arrays;
+import java.util.Hashtable;
+import java.util.Map;
+
+
+final public class AU {
+
+ /**
+ * Very important that this not be used with Int32Array or Float32Array,
+ * because it is not initialized to all zeros in MSIE 9.
+ *
+ * @param array
+ * @param minimumLength
+ * @return array
+ */
+ public static Object ensureLength(Object array, int minimumLength) {
+ if (array != null && getLength(array) >= minimumLength)
+ return array;
+ return arrayCopyObject(array, minimumLength);
+ }
+
+ public static String[] ensureLengthS(String[] array, int minimumLength) {
+ if (array != null && array.length >= minimumLength)
+ return array;
+ return arrayCopyS(array, minimumLength);
+ }
+
+ public static float[] ensureLengthA(float[] array, int minimumLength) {
+ if (array != null && array.length >= minimumLength)
+ return array;
+ return arrayCopyF(array, minimumLength);
+ }
+
+ public static int[] ensureLengthI(int[] array, int minimumLength) {
+ if (array != null && array.length >= minimumLength)
+ return array;
+ return arrayCopyI(array, minimumLength);
+ }
+
+ public static short[] ensureLengthShort(short[] array, int minimumLength) {
+ if (array != null && array.length >= minimumLength)
+ return array;
+ return arrayCopyShort(array, minimumLength);
+ }
+
+ public static byte[] ensureLengthByte(byte[] array, int minimumLength) {
+ if (array != null && array.length >= minimumLength)
+ return array;
+ return arrayCopyByte(array, minimumLength);
+ }
+
+ /**
+ * Very important that this not be used with Int32Array or Float32Array,
+ * because it is not initialized to all zeros in MSIE 9.
+ *
+ * @param array
+ * @return array
+ */
+ public static Object doubleLength(Object array) {
+ return arrayCopyObject(array, (array == null ? 16 : 2 * getLength(array)));
+ }
+
+ public static String[] doubleLengthS(String[] array) {
+ return arrayCopyS(array, (array == null ? 16 : 2 * array.length));
+ }
+
+ public static float[] doubleLengthF(float[] array) {
+ return arrayCopyF(array, (array == null ? 16 : 2 * array.length));
+ }
+
+ public static int[] doubleLengthI(int[] array) {
+ return arrayCopyI(array, (array == null ? 16 : 2 * array.length));
+ }
+
+ public static short[] doubleLengthShort(short[] array) {
+ return arrayCopyShort(array, (array == null ? 16 : 2 * array.length));
+ }
+
+ public static byte[] doubleLengthByte(byte[] array) {
+ return arrayCopyByte(array, (array == null ? 16 : 2 * array.length));
+ }
+
+ public static boolean[] doubleLengthBool(boolean[] array) {
+ return arrayCopyBool(array, (array == null ? 16 : 2 * array.length));
+ }
+
+ public static Object deleteElements(Object array, int firstElement,
+ int nElements) {
+ if (nElements == 0 || array == null)
+ return array;
+ int oldLength = getLength(array);
+ if (firstElement >= oldLength)
+ return array;
+ int n = oldLength - (firstElement + nElements);
+ if (n < 0)
+ n = 0;
+ Object t = newInstanceO(array, firstElement + n);
+ if (firstElement > 0)
+ System.arraycopy(array, 0, t, 0, firstElement);
+ if (n > 0)
+ System.arraycopy(array, firstElement + nElements, t, firstElement, n);
+ return t;
+ }
+
+ /**
+ * note -- cannot copy if array is null!
+ *
+ * @param array
+ * @param newLength
+ * @return array
+ */
+ public static Object arrayCopyObject(Object array, int newLength) {
+ //System.out.println("ArrayUtil.copy " + newLength + " " + array + " ");
+ if (array == null) {
+ return null; // We can't allocate since we don't know the type of array
+ }
+ int oldLength = getLength(array);
+ if (newLength == oldLength)
+ return array;
+ Object t = newInstanceO(array, newLength);
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ return t;
+
+ }
+
+ /**
+ * Very important that this not be used with Int32Array or Float32Array,
+ * because those need to be initialized to all zeros in MSIE 9, and
+ * MSIE 9 cannot distinguish Int32Array or Float32Array from Array.
+ *
+ * @param array
+ * @param n
+ * @return array
+ */
+ private static Object newInstanceO(Object array, int n) {
+ /**
+ * @j2sNative
+ *
+ * if (!array.getClass().getComponentType)
+ * return new Array(n);
+ *
+ */
+ {
+ return Array.newInstance(array.getClass().getComponentType(), n);
+ }
+ }
+
+ public static int getLength(Object array) {
+ /**
+ * @j2sNative
+ *
+ * return array.length
+ *
+ */
+ {
+ return Array.getLength(array);
+ }
+ }
+
+ public static String[] arrayCopyS(String[] array, int newLength) {
+ if (newLength < 0)
+ newLength = array.length;
+ String[] t = new String[newLength];
+ if (array != null) {
+ int oldLength = array.length;
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ }
+ return t;
+ }
+
+ public static int[][] arrayCopyII(int[][] array, int newLength) {
+ int[][] t = newInt2(newLength);
+ if (array != null) {
+ int oldLength = array.length;
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ }
+ return t;
+ }
+
+ public static T3[] arrayCopyPt(T3[] array, int newLength) {
+ if (newLength < 0)
+ newLength = array.length;
+ T3[] t = new T3[newLength];
+ if (array != null) {
+ int oldLength = array.length;
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ }
+ return t;
+ }
+
+ public static float[] arrayCopyF(float[] array, int newLength) {
+ if (newLength < 0)
+ newLength = array.length;
+ float[] t = new float[newLength];
+ if (array != null) {
+ int oldLength = array.length;
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ }
+ return t;
+ }
+
+ public static int[] arrayCopyI(int[] array, int newLength) {
+ if (newLength < 0)
+ newLength = array.length;
+ int[] t = new int[newLength];
+ if (array != null) {
+ int oldLength = array.length;
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ }
+ return t;
+ }
+
+ /**
+ * a specialized method that allows copying from a starting point either
+ * to the end or to the middle (color schemes, especially)
+ * @param array
+ * @param i0
+ * @param n
+ * @return array or null
+ */
+ public static int[] arrayCopyRangeI(int[] array, int i0, int n) {
+ if (array == null)
+ return null;
+ int oldLength = array.length;
+ if (n == -1) n = oldLength;
+ if (n == -2) n = oldLength / 2;
+ n = n - i0;
+ int[] t = new int[n];
+ System.arraycopy(array, i0, t, 0, n);
+ return t;
+ }
+
+ public static int[] arrayCopyRangeRevI(int[] array, int i0, int n) {
+ if (array == null)
+ return null;
+ int[] t = arrayCopyRangeI(array, i0, n);
+ if (n < 0)
+ n = array.length;
+ for (int i = n / 2; --i >= 0;)
+ swapInt(t, i, n - 1 - i);
+ return t;
+ }
+
+ public static short[] arrayCopyShort(short[] array, int newLength) {
+ if (newLength < 0)
+ newLength = array.length;
+ short[] t = new short[newLength];
+ if (array != null) {
+ int oldLength = array.length;
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ }
+ return t;
+ }
+
+ public static byte[] arrayCopyByte(byte[] array, int newLength) {
+ if (newLength < 0)
+ newLength = array.length;
+ byte[] t = new byte[newLength];
+ if (array != null) {
+ int oldLength = array.length;
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ }
+ return t;
+ }
+
+ public static boolean[] arrayCopyBool(boolean[] array, int newLength) {
+ if (newLength < 0)
+ newLength = array.length;
+ boolean[] t = new boolean[newLength];
+ if (array != null) {
+ int oldLength = array.length;
+ System.arraycopy(array, 0, t, 0, oldLength < newLength ? oldLength
+ : newLength);
+ }
+ return t;
+ }
+
+ public static void swapInt(int[] array, int indexA, int indexB) {
+ int t = array[indexA];
+ array[indexA] = array[indexB];
+ array[indexB] = t;
+ }
+
+ /*
+ public static void swap(short[] array, int indexA, int indexB) {
+ short t = array[indexA];
+ array[indexA] = array[indexB];
+ array[indexB] = t;
+ }
+
+ public static void swap(float[] array, int indexA, int indexB) {
+ float t = array[indexA];
+ array[indexA] = array[indexB];
+ array[indexB] = t;
+ }
+ */
+
+ public static String dumpArray(String msg, float[][] A, int x1, int x2, int y1, int y2) {
+ String s = "dumpArray: " + msg + "\n";
+ for (int x = x1; x <= x2; x++)
+ s += "\t*" + x + "*";
+ for (int y = y2; y >= y1; y--) {
+ s += "\n*" + y + "*";
+ for (int x = x1; x <= x2; x++)
+ s += "\t" + (x < A.length && y < A[x].length ? A[x][y] : Float.NaN);
+ }
+ return s;
+ }
+
+ public static String dumpIntArray(int[] A, int n) {
+ String str = "";
+ for (int i = 0; i < n; i++)
+ str += " " + A[i];
+ return str;
+ }
+
+ public static String sortedItem(Lst<String> v, int n) {
+ if (v.size() == 0)
+ return null;
+ if (v.size() == 1)
+ return v.get(0);
+ String[] keys = v.toArray(new String[v.size()]);
+ Arrays.sort(keys);
+ return keys[n % keys.length];
+ }
+
+ /**
+ * Helper method for creating a List<Tx>[] without warnings.
+ *
+ * @param <type> Type of objects in the list.
+ * @param size Array size.
+ * @return Array of List<type>
+ */
+ @SuppressWarnings("unchecked")
+ public static <type> Lst<type>[] createArrayOfArrayList(int size) {
+ return new Lst[size];
+ }
+
+ /**
+ * Helper method for creating a Map<K, V>[] without warnings.
+ *
+ * @param <K> Type of object for the keys in the map.
+ * @param <V> Type of object for the values in the map.
+ * @param size Array size.
+ * @return Array of Map<K, V>
+ */
+ @SuppressWarnings("unchecked")
+ public static <K, V> Map<K, V>[] createArrayOfHashtable(int size) {
+ return new Hashtable[size];
+ }
+
+ public static void swap(Object[] o, int i, int j) {
+ Object oi = o[i];
+ o[i] = o[j];
+ o[j] = oi;
+ }
+
+ public static float[][] newFloat2(int n) {
+ /**
+ * @j2sNative
+ *
+ * return Clazz.newArray(n, null);
+ *
+ */
+ {
+ return new float[n][];
+ }
+ }
+
+ public static int[][] newInt2(int n) {
+ /**
+ * @j2sNative
+ *
+ * return Clazz.newArray(n, null);
+ *
+ */
+ {
+ return new int[n][];
+ }
+ }
+
+ public static int[][][] newInt3(int nx, int ny) {
+ /**
+ * @j2sNative
+ *
+ * return Clazz.newArray(nx, null);
+ *
+ */
+ {
+ return (ny < 0 ? new int[nx][][] : new int[nx][ny][]);
+ }
+ }
+
+ public static float[][][] newFloat3(int nx, int ny) {
+ /**
+ * @j2sNative
+ *
+ * return Clazz.newArray(nx, null);
+ *
+ */
+ {
+ return (ny < 0 ? new float[nx][][] : new float[nx][ny][]);
+ }
+ }
+
+ public static int[][][][] newInt4(int n) {
+ /**
+ * @j2sNative
+ *
+ * return Clazz.newArray(n, null);
+ *
+ */
+ {
+ return new int[n][][][];
+ }
+ }
+
+ public static short[][] newShort2(int n) {
+ /**
+ * @j2sNative
+ *
+ * return Clazz.newArray(n, null);
+ *
+ */
+ {
+ return new short[n][];
+ }
+ }
+
+ public static byte[][] newByte2(int n) {
+ /**
+ * @j2sNative
+ *
+ * return Clazz.newArray(n, null);
+ *
+ */
+ {
+ return new byte[n][];
+ }
+ }
+
+ public static double[][] newDouble2(int n) {
+ /**
+ * @j2sNative
+ *
+ * return Clazz.newArray(n, null);
+ *
+ */
+ {
+ return new double[n][];
+ }
+ }
+
+ /**
+ * remove all keys from a map that start with given root
+ * @param map
+ * @param root
+ * @return number removed
+ */
+ public static int removeMapKeys(Map<String, ?> map, String root) {
+ Lst<String> list = new Lst<String>();
+ for (String key: map.keySet())
+ if (key.startsWith(root))
+ list.addLast(key);
+ for (int i = list.size(); --i >= 0;)
+ map.remove(list.get(i));
+ return list.size();
+ }
+
+ public static boolean isAS(Object x) {
+ /**
+ *
+ * look also for array with first null element
+ * so untypable -- just call it a String[]
+ * (group3Lists, created in ModelLoader)
+ *
+ * @j2sNative
+ * return Clazz.isAS(x);
+ */
+ {
+ return x instanceof String[];
+ }
+ }
+
+ public static boolean isASS(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isASS(x);
+ */
+ {
+ return x instanceof String[][];
+ }
+ }
+
+ public static boolean isAP(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAP(x);
+ */
+ {
+ return x instanceof T3[];
+ }
+ }
+
+ public static boolean isAF(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAF(x);
+ */
+ {
+ return x instanceof float[];
+ }
+ }
+
+ public static boolean isAFloat(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAFloat(x);
+ */
+ {
+ return x instanceof Float[];
+ }
+ }
+
+ public static boolean isAD(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAF(x);
+ */
+ {
+ return x instanceof double[];
+ }
+ }
+
+ public static boolean isADD(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAFF(x);
+ */
+ {
+ return x instanceof double[][];
+ }
+ }
+
+ public static boolean isAB(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAI(x);
+ */
+ {
+ return x instanceof byte[];
+ }
+ }
+
+ public static boolean isAI(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAI(x);
+ */
+ {
+ return x instanceof int[];
+ }
+ }
+
+ public static boolean isAII(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAII(x);
+ */
+ {
+ return (x instanceof int[][]);
+ }
+ }
+
+ public static boolean isAFF(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAFF(x);
+ */
+ {
+ return x instanceof float[][];
+ }
+ }
+
+ public static boolean isAFFF(Object x) {
+ /**
+ * @j2sNative
+ * return Clazz.isAFFF(x);
+ */
+ {
+ return x instanceof float[][][];
+ }
+ }
+
+ /**
+ * Ensure that we have signed and not unsigned bytes
+ * coming out of any process, but particularly out of
+ * file reading.
+ *
+ * @param b
+ */
+ public static void ensureSignedBytes(byte[] b) {
+ /**
+ * @j2sNative
+ *
+ * for (var i = b.length; --i >= 0;) {
+ * var j = b[i] & 0xFF;
+ * if (j >= 0x80) j -= 0x100;
+ * b[i] = j;
+ * }
+ *
+ */
+ {
+ }
+ }
+
+
+}
--- /dev/null
+package javajs.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+
+import javajs.api.JmolObjectInterface;
+
+/**
+ *
+ * A method to allow a JavaScript Ajax
+ *
+ */
+public class AjaxURLConnection extends URLConnection {
+
+ protected AjaxURLConnection(URL url) {
+ super(url);
+ }
+
+ byte[] bytesOut;
+ String postOut = "";
+
+ /**
+ *
+ * doAjax() is where the synchronous call to AJAX is to happen. or at least
+ * where we wait for the asynchronous call to return. This method should fill
+ * the dataIn field with either a string or byte array, or null if you want to
+ * throw an error.
+ *
+ * url, bytesOut, and postOut are all available for use
+ *
+ * the method is "private", but in JavaScript that can still be overloaded.
+ * Just set something to org.jmol.awtjs.JmolURLConnection.prototype.doAjax
+ *
+ * @return file data as a javajs.util.SB or byte[] depending upon the file
+ * type.
+ *
+ *
+ */
+ @SuppressWarnings("null")
+ private Object doAjax() {
+ JmolObjectInterface jmol = null;
+ /**
+ * @j2sNative
+ *
+ * jmol = Jmol;
+ *
+ */
+ {
+ }
+ return jmol._doAjax(url, postOut, bytesOut);
+ }
+
+ @Override
+ public void connect() throws IOException {
+ // not expected to be used.
+ }
+
+ public void outputBytes(byte[] bytes) {
+ // type = "application/octet-stream;";
+ bytesOut = bytes;
+ }
+
+ public void outputString(String post) {
+ postOut = post;
+ // type = "application/x-www-form-urlencoded";
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ InputStream is = null;
+ Object o = doAjax();
+ if (AU.isAB(o))
+ is = Rdr.getBIS((byte[]) o);
+ else if (o instanceof SB)
+ is = Rdr.getBIS(Rdr.getBytesFromSB((SB)o));
+ else if (o instanceof String)
+ is = Rdr.getBIS(((String) o).getBytes());
+ return is;
+ }
+ /**
+ * @return javajs.util.SB or byte[], depending upon the file type
+ */
+ public Object getContents() {
+ return doAjax();
+ }
+
+}
--- /dev/null
+package javajs.util;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+
+
+/**
+ *
+ * A method to allow a JavaScript AJAX adapter to
+ * deliver web content to JSmol. This handler is just a formality.
+ *
+ */
+public class AjaxURLStreamHandler extends URLStreamHandler {
+
+ String protocol;
+
+ public AjaxURLStreamHandler(String protocol) {
+ this.protocol = protocol;
+ }
+
+ @Override
+ protected URLConnection openConnection(URL url) throws IOException {
+ return new AjaxURLConnection(url);
+ }
+
+
+ @Override
+ protected String toExternalForm(URL u) {
+ SB result = new SB();
+ result.append(u.getProtocol());
+ result.append(":");
+ if (u.getAuthority() != null && u.getAuthority().length() > 0) {
+ result.append("//");
+ result.append(u.getAuthority());
+ }
+ if (u.getPath() != null) {
+ result.append(u.getPath());
+ }
+ if (u.getQuery() != null) {
+ result.append("?");
+ result.append(u.getQuery());
+ }
+ if (u.getRef() != null) {
+ result.append("#");
+ result.append(u.getRef());
+ }
+ return result.toString();
+ }
+
+}
--- /dev/null
+package javajs.util;
+
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.util.Hashtable;
+import java.util.Map;
+
+
+/**
+ *
+ * For handling URL file IO via AJAX in JavaScript version
+ *
+ */
+
+public class AjaxURLStreamHandlerFactory implements URLStreamHandlerFactory {
+
+ Map<String, AjaxURLStreamHandler> htFactories = new Hashtable<String, AjaxURLStreamHandler>();
+
+ @Override
+ public URLStreamHandler createURLStreamHandler(String protocol) {
+ AjaxURLStreamHandler fac = htFactories.get(protocol);
+ if (fac == null)
+ htFactories.put(protocol, fac = new AjaxURLStreamHandler(protocol));
+ return (fac.protocol == null ? null : fac);
+ }
+
+}
--- /dev/null
+package javajs.util;
+
+import java.io.IOException;
+
+
+
+
+
+
+/**
+ *
+ * ArrayDataReader subclasses BufferedReader and overrides its
+ * read, readLine, mark, and reset methods so that JmolAdapter
+ * works with String[] arrays without any further adaptation.
+ *
+ */
+
+public class ArrayDataReader extends DataReader {
+ private String[] data;
+ private int pt;
+ private int len;
+
+ public ArrayDataReader() {
+ super();
+ }
+
+ @Override
+ public DataReader setData(Object data) {
+ this.data = (String[]) data;
+ len = this.data.length;
+ return this;
+ }
+
+ @Override
+ public int read(char[] buf, int off, int len) throws IOException {
+ return readBuf(buf, off, len);
+ }
+
+ @Override
+ public String readLine() {
+ return (pt < len ? data[pt++] : null);
+ }
+
+ /**
+ *
+ * @param ptr
+ */
+ public void mark(long ptr) {
+ //ignore ptr.
+ ptMark = pt;
+ }
+
+ @Override
+ public void reset() {
+ pt = ptMark;
+ }
+}
\ No newline at end of file
--- /dev/null
+package javajs.util;
+
+public class BArray {
+ public byte[] data;
+
+ public BArray(byte[] data) {
+ this.data = data;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (o instanceof BArray) {
+ byte[] d = ((BArray) o).data;
+ if (d.length == data.length){
+ for (int i = 0; i < d.length; i++)
+ if (d[i] != data[i])
+ return false;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return data.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return new String(data);
+ }
+}
--- /dev/null
+package javajs.util;
+
+public class BC {
+
+ public BC() {
+ // unnecessary to instantialize unless subclassed
+ }
+
+ public static float bytesToFloat(byte[] bytes, int j, boolean isBigEndian) throws Exception {
+ return intToFloat(bytesToInt(bytes, j, isBigEndian));
+ }
+
+ public static int bytesToInt(byte[] bytes, int j, boolean isBigEndian) {
+ int n = (isBigEndian ? (bytes[j + 3] & 0xff) | (bytes[j + 2] & 0xff) << 8
+ | (bytes[j + 1] & 0xff) << 16 | (bytes[j] & 0xff) << 24
+ : (bytes[j++] & 0xff) | (bytes[j++] & 0xff) << 8
+ | (bytes[j++] & 0xff) << 16 | (bytes[j++] & 0xff) << 24);
+ /**
+ * @j2sNative
+ *
+ * return (n > 0x7FFFFFFF ? n - 0x100000000 : n);
+ *
+ */
+ {
+ return n;
+ }
+ }
+
+ public static float intToFloat(int x) throws Exception {
+ /**
+ * see http://en.wikipedia.org/wiki/Binary32
+ *
+ * [sign] [8 bits power] [23 bits fraction]
+ * 0x80000000 0x7F800000 0x7FFFFF
+ *
+ * (untested)
+ *
+ * @j2sNative
+ *
+ * if (x == 0) return 0;
+ * var o = javajs.util.BC;
+ * if (o.fracIEEE == null)
+ * o.setFracIEEE();
+ * var m = ((x & 0x7F800000) >> 23);
+ * return ((x & 0x80000000) == 0 ? 1 : -1) * o.shiftIEEE((x & 0x7FFFFF) | 0x800000, m - 149);
+ *
+ */
+ {
+ return Float.intBitsToFloat(x);
+ }
+ }
+
+ /**
+ * see http://en.wikipedia.org/wiki/Binary64
+ *
+ * not concerning ourselves with very small or very large numbers and getting
+ * this exactly right. Just need a float here.
+ *
+ * @param bytes
+ * @param j
+ * @param isBigEndian
+ * @return float
+ */
+ public static float bytesToDoubleToFloat(byte[] bytes, int j, boolean isBigEndian) {
+ {
+ // IEEE754: sign (1 bit), exponent (11 bits), fraction (52 bits).
+ // seeeeeee eeeeffff ffffffff ffffffff ffffffff xxxxxxxx xxxxxxxx xxxxxxxx
+ // b1 b2 b3 b4 b5 ---------float ignores----
+
+ if (fracIEEE == null)
+ setFracIEEE();
+
+ /**
+ * @j2sNative
+ * var o = javajs.util.BC;
+ * var b1, b2, b3, b4, b5;
+ *
+ * if (isBigEndian) {
+ * b1 = bytes[j] & 0xFF;
+ * b2 = bytes[j + 1] & 0xFF;
+ * b3 = bytes[j + 2] & 0xFF;
+ * b4 = bytes[j + 3] & 0xFF;
+ * b5 = bytes[j + 4] & 0xFF;
+ * } else {
+ * b1 = bytes[j + 7] & 0xFF;
+ * b2 = bytes[j + 6] & 0xFF;
+ * b3 = bytes[j + 5] & 0xFF;
+ * b4 = bytes[j + 4] & 0xFF;
+ * b5 = bytes[j + 3] & 0xFF;
+ * }
+ * var s = ((b1 & 0x80) == 0 ? 1 : -1);
+ * var e = (((b1 & 0x7F) << 4) | (b2 >> 4)) - 1026;
+ * b2 = (b2 & 0xF) | 0x10;
+ * return s * (o.shiftIEEE(b2, e) + o.shiftIEEE(b3, e - 8) + o.shiftIEEE(b4, e - 16)
+ * + o.shiftIEEE(b5, e - 24));
+ */
+ {
+ double d;
+
+ if (isBigEndian)
+ d = Double.longBitsToDouble((((long) bytes[j]) & 0xff) << 56
+ | (((long) bytes[j + 1]) & 0xff) << 48
+ | (((long) bytes[j + 2]) & 0xff) << 40
+ | (((long) bytes[j + 3]) & 0xff) << 32
+ | (((long) bytes[j + 4]) & 0xff) << 24
+ | (((long) bytes[j + 5]) & 0xff) << 16
+ | (((long) bytes[j + 6]) & 0xff) << 8
+ | (((long) bytes[7]) & 0xff));
+ else
+ d = Double.longBitsToDouble((((long) bytes[j + 7]) & 0xff) << 56
+ | (((long) bytes[j + 6]) & 0xff) << 48
+ | (((long) bytes[j + 5]) & 0xff) << 40
+ | (((long) bytes[j + 4]) & 0xff) << 32
+ | (((long) bytes[j + 3]) & 0xff) << 24
+ | (((long) bytes[j + 2]) & 0xff) << 16
+ | (((long) bytes[j + 1]) & 0xff) << 8
+ | (((long) bytes[j]) & 0xff));
+ return (float) d;
+ }
+
+ }
+ }
+
+ private static float[] fracIEEE;
+
+ private static void setFracIEEE() {
+ fracIEEE = new float[270];
+ for (int i = 0; i < 270; i++)
+ fracIEEE[i] = (float) Math.pow(2, i - 141);
+ // System.out.println(fracIEEE[0] + " " + Parser.FLOAT_MIN_SAFE);
+ // System.out.println(fracIEEE[269] + " " + Float.MAX_VALUE);
+ }
+
+ /**
+ * only concerned about reasonable float values here -- private but not designated; called by JavaScript
+ *
+ * @param f
+ * @param i
+ * @return f * 2^i
+ */
+ static double shiftIEEE(double f, int i) {
+ if (f == 0 || i < -140)
+ return 0;
+ if (i > 128)
+ return Float.MAX_VALUE;
+ return f * fracIEEE[i + 140];
+ }
+
+// static {
+// setFracIEEE();
+// for (int i = -50; i < 50; i++) {
+// float f = i * (float) (Math.random() * Math.pow(2, Math.random() * 100 - 50));
+// int x = Float.floatToIntBits(f);
+// int m = ((x & 0x7F800000) >> 23);
+// float f1 = (float) (f == 0 ? 0 : ((x & 0x80000000) == 0 ? 1 : -1) * shiftIEEE((x & 0x7FFFFF) | 0x800000, m - 149));
+// System.out.println(f + " " + f1);
+// }
+// System.out.println("binarydo");
+// }
+
+
+
+}
--- /dev/null
+/*
+ * Copyright 1995-2007 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package javajs.util;
+
+import javajs.api.JSONEncodable;
+
+
+
+/**
+ *
+ * a fast 32-bit BitSet optimized for Java2Script -- about 25 times faster than
+ * java.util.BitSet
+ *
+ * @author Bob Hanson hansonr@stolaf.edu
+ *
+ * Additions by Bob Hanson to allow for JavaScript mix of int/long Note
+ * that Firefox (Sept 2012) does not really treat "Int32Array" as such,
+ * because any element can be pushed into being a 64-bit number, which
+ * really isn't because the last 8 bits are not usable.
+ *
+ * This class implements a vector of bits that grows as needed. Each
+ * component of the bit set has a {@code boolean} value. The bits of a
+ * {@code BitSet} are indexed by nonnegative integers. Individual
+ * indexed bits can be examined, set, or cleared. One {@code BitSet} may
+ * be used to modify the contents of another {@code BitSet} through
+ * logical AND, logical inclusive OR, and logical exclusive OR
+ * operations.
+ *
+ * <p>
+ * By default, all bits in the set initially have the value {@code
+ * false}.
+ *
+ * <p>
+ * Every bit set has a current size, which is the number of bits of
+ * space currently in use by the bit set. Note that the size is related
+ * to the implementation of a bit set, so it may change with
+ * implementation. The length of a bit set relates to logical length of
+ * a bit set and is defined independently of implementation.
+ *
+ * <p>
+ * Unless otherwise noted, passing a null parameter to any of the
+ * methods in a {@code BitSet} will result in a {@code
+ * NullPointerException}.
+ *
+ * <p>
+ * A {@code BitSet} is not safe for multithreaded use without external
+ * synchronization.
+ *
+ * @author Arthur van Hoff
+ * @author Michael McCloskey
+ * @author Martin Buchholz
+ * @since JDK1.0
+ */
+public class BS implements Cloneable, JSONEncodable {
+ /*
+ * BitSets are packed into arrays of "words."
+ *
+ * An int, which consists of 32 bits, requiring 5 address bits, is used for
+ * the JavaScript port.
+ */
+ private final static int ADDRESS_BITS_PER_WORD = 5;
+ private final static int BITS_PER_WORD = 1 << ADDRESS_BITS_PER_WORD;
+
+ /* Used to shift left or right for a partial word mask */
+ private static final int WORD_MASK = 0xffffffff;
+
+
+ /**
+ * The internal field corresponding to the serialField "bits".
+ */
+ private int[] words;
+
+ /**
+ * The number of words in the logical size of this BitSet.
+ */
+ private transient int wordsInUse = 0;
+
+ /**
+ * Whether the size of "words" is user-specified. If so, we assume the user
+ * knows what he's doing and try harder to preserve it.
+ */
+ private transient boolean sizeIsSticky = false;
+
+ /* use serialVersionUID from JDK 1.0.2 for interoperability */
+ //private static final long serialVersionUID = 7997698588986878753L;
+
+ /**
+ * Given a bit index, return word index containing it.
+ * @param bitIndex
+ * @return b
+ */
+ private static int wordIndex(int bitIndex) {
+ return bitIndex >> ADDRESS_BITS_PER_WORD;
+ }
+
+ /**
+ * Sets the field wordsInUse to the logical size in words of the bit set.
+ * WARNING:This method assumes that the number of words actually in use is
+ * less than or equal to the current value of wordsInUse!
+ */
+ private void recalculateWordsInUse() {
+ // Traverse the bitset until a used word is found
+ int i;
+ for (i = wordsInUse - 1; i >= 0; i--)
+ if (words[i] != 0)
+ break;
+
+ wordsInUse = i + 1; // The new logical size
+ }
+
+ /**
+ * Creates a new bit set. All bits are initially {@code false}.
+ */
+ public BS() {
+ initWords(BITS_PER_WORD);
+ sizeIsSticky = false;
+ }
+
+ /**
+ * Creates a bit set whose initial size is large enough to explicitly
+ * represent bits with indices in the range {@code 0} through {@code nbits-1}.
+ * All bits are initially {@code false}.
+ *
+ * @param nbits
+ * the initial size of the bit set
+ * @return bs
+ * @throws NegativeArraySizeException
+ * if the specified initial size is negative
+ */
+ public static BS newN(int nbits) {
+ BS bs = new BS();
+ bs.init(nbits);
+ return bs;
+ }
+
+ private void init(int nbits) {
+ // nbits can't be negative; size 0 is OK
+ if (nbits < 0)
+ throw new NegativeArraySizeException("nbits < 0: " + nbits);
+ initWords(nbits);
+ sizeIsSticky = true;
+ }
+
+ private void initWords(int nbits) {
+ words = new int[wordIndex(nbits - 1) + 1];
+ }
+
+ /**
+ * Ensures that the BitSet can hold enough words.
+ *
+ * @param wordsRequired
+ * the minimum acceptable number of words.
+ */
+ private void ensureCapacity(int wordsRequired) {
+ if (words.length < wordsRequired) {
+ // Allocate larger of doubled size or required size
+ int request = Math.max(2 * words.length, wordsRequired);
+ setLength(request);
+ sizeIsSticky = false;
+ }
+ }
+
+ /**
+ * Ensures that the BitSet can accommodate a given wordIndex, temporarily
+ * violating the invariants. The caller must restore the invariants before
+ * returning to the user, possibly using recalculateWordsInUse().
+ *
+ * @param wordIndex
+ * the index to be accommodated.
+ */
+ private void expandTo(int wordIndex) {
+ int wordsRequired = wordIndex + 1;
+ if (wordsInUse < wordsRequired) {
+ ensureCapacity(wordsRequired);
+ wordsInUse = wordsRequired;
+ }
+ }
+
+
+ /**
+ * Sets the bit at the specified index to {@code true}.
+ *
+ * @param bitIndex
+ * a bit index
+ * @throws IndexOutOfBoundsException
+ * if the specified index is negative
+ * @since JDK1.0
+ */
+ public void set(int bitIndex) {
+ if (bitIndex < 0)
+ throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
+
+ int wordIndex = wordIndex(bitIndex);
+ expandTo(wordIndex);
+
+ words[wordIndex] |= (1 << bitIndex); // Restores invariants
+
+ }
+
+ /**
+ * Sets the bit at the specified index to the specified value.
+ *
+ * @param bitIndex
+ * a bit index
+ * @param value
+ * a boolean value to set
+ * @throws IndexOutOfBoundsException
+ * if the specified index is negative
+ * @since 1.4
+ */
+ public void setBitTo(int bitIndex, boolean value) {
+ if (value)
+ set(bitIndex);
+ else
+ clear(bitIndex);
+ }
+
+ /**
+ * Sets the bits from the specified {@code fromIndex} (inclusive) to the
+ * specified {@code toIndex} (exclusive) to {@code true}.
+ *
+ * @param fromIndex
+ * index of the first bit to be set
+ * @param toIndex
+ * index after the last bit to be set
+ * @throws IndexOutOfBoundsException
+ * if {@code fromIndex} is negative, or {@code toIndex} is negative,
+ * or {@code fromIndex} is larger than {@code toIndex}
+ * @since 1.4
+ */
+ public void setBits(int fromIndex, int toIndex) {
+
+ if (fromIndex == toIndex)
+ return;
+
+ // Increase capacity if necessary
+ int startWordIndex = wordIndex(fromIndex);
+ int endWordIndex = wordIndex(toIndex - 1);
+ expandTo(endWordIndex);
+
+ int firstWordMask = WORD_MASK << fromIndex;
+ int lastWordMask = WORD_MASK >>> -toIndex;
+ if (startWordIndex == endWordIndex) {
+ // Case 1: One word
+ words[startWordIndex] |= (firstWordMask & lastWordMask);
+ } else {
+ // Case 2: Multiple words
+ // Handle first word
+ words[startWordIndex] |= firstWordMask;
+
+ // Handle intermediate words, if any
+ for (int i = startWordIndex + 1; i < endWordIndex; i++)
+ words[i] = WORD_MASK;
+
+ // Handle last word (restores invariants)
+ words[endWordIndex] |= lastWordMask;
+ }
+ }
+
+ /**
+ * Sets the bit specified by the index to {@code false}.
+ *
+ * @param bitIndex
+ * the index of the bit to be cleared
+ * @throws IndexOutOfBoundsException
+ * if the specified index is negative
+ * @since JDK1.0
+ */
+ public void clear(int bitIndex) {
+ if (bitIndex < 0)
+ throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
+
+ int wordIndex = wordIndex(bitIndex);
+ if (wordIndex >= wordsInUse)
+ return;
+
+ words[wordIndex] &= ~(1 << bitIndex);
+
+ recalculateWordsInUse();
+ }
+
+ /**
+ * Sets the bits from the specified {@code fromIndex} (inclusive) to the
+ * specified {@code toIndex} (exclusive) to {@code false}.
+ *
+ * @param fromIndex
+ * index of the first bit to be cleared
+ * @param toIndex
+ * index after the last bit to be cleared
+ * @throws IndexOutOfBoundsException
+ * if {@code fromIndex} is negative, or {@code toIndex} is negative,
+ * or {@code fromIndex} is larger than {@code toIndex}
+ * @since 1.4
+ */
+ public void clearBits(int fromIndex, int toIndex) {
+ if (fromIndex == toIndex)
+ return;
+
+ int startWordIndex = wordIndex(fromIndex);
+ if (startWordIndex >= wordsInUse)
+ return;
+
+ int endWordIndex = wordIndex(toIndex - 1);
+ if (endWordIndex >= wordsInUse) {
+ toIndex = length();
+ endWordIndex = wordsInUse - 1;
+ }
+
+ int firstWordMask = WORD_MASK << fromIndex;
+ int lastWordMask = WORD_MASK >>> -toIndex;
+ if (startWordIndex == endWordIndex) {
+ // Case 1: One word
+ words[startWordIndex] &= ~(firstWordMask & lastWordMask);
+ } else {
+ // Case 2: Multiple words
+ // Handle first word
+ words[startWordIndex] &= ~firstWordMask;
+
+ // Handle intermediate words, if any
+ for (int i = startWordIndex + 1; i < endWordIndex; i++)
+ words[i] = 0;
+
+ // Handle last word
+ words[endWordIndex] &= ~lastWordMask;
+ }
+
+ recalculateWordsInUse();
+ }
+
+ /**
+ * Sets all of the bits in this BitSet to {@code false}.
+ *
+ * @since 1.4
+ */
+ public void clearAll() {
+ while (wordsInUse > 0)
+ words[--wordsInUse] = 0;
+ }
+
+ /**
+ * Returns the value of the bit with the specified index. The value is {@code
+ * true} if the bit with the index {@code bitIndex} is currently set in this
+ * {@code BitSet}; otherwise, the result is {@code false}.
+ *
+ * @param bitIndex
+ * the bit index
+ * @return the value of the bit with the specified index
+ * @throws IndexOutOfBoundsException
+ * if the specified index is negative
+ */
+ public boolean get(int bitIndex) {
+ if (bitIndex < 0)
+ throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);
+
+ int wordIndex = wordIndex(bitIndex);
+ return (wordIndex < wordsInUse)
+ && ((words[wordIndex] & (1 << bitIndex)) != 0);
+ }
+
+ /**
+ * Returns the index of the first bit that is set to {@code true} that occurs
+ * on or after the specified starting index. If no such bit exists then
+ * {@code -1} is returned.
+ *
+ * <p>
+ * To iterate over the {@code true} bits in a {@code BitSet}, use the
+ * following loop:
+ *
+ * <pre>
+ * @code
+ * for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
+ * // operate on index i here
+ * }}
+ * </pre>
+ *
+ * @param fromIndex
+ * the index to start checking from (inclusive)
+ * @return the index of the next set bit, or {@code -1} if there is no such
+ * bit
+ * @throws IndexOutOfBoundsException
+ * if the specified index is negative
+ * @since 1.4
+ */
+ public int nextSetBit(int fromIndex) {
+ if (fromIndex < 0)
+ throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
+
+ int u = wordIndex(fromIndex);
+ if (u >= wordsInUse)
+ return -1;
+
+ int word = words[u] & (WORD_MASK << fromIndex);
+
+ while (true) {
+ if (word != 0)
+ return (u * BITS_PER_WORD) + Integer.numberOfTrailingZeros(word);
+ if (++u == wordsInUse)
+ return -1;
+ word = words[u];
+ }
+ }
+
+ /**
+ * Returns the index of the first bit that is set to {@code false} that occurs
+ * on or after the specified starting index.
+ *
+ * @param fromIndex
+ * the index to start checking from (inclusive)
+ * @return the index of the next clear bit
+ * @throws IndexOutOfBoundsException
+ * if the specified index is negative
+ * @since 1.4
+ */
+ public int nextClearBit(int fromIndex) {
+ // Neither spec nor implementation handle bitsets of maximal length.
+ // See 4816253.
+ if (fromIndex < 0)
+ throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);
+
+ int u = wordIndex(fromIndex);
+ if (u >= wordsInUse)
+ return fromIndex;
+
+ int word = ~words[u] & (WORD_MASK << fromIndex);
+
+ while (true) {
+ if (word != 0)
+ return (u * BITS_PER_WORD) + Integer.numberOfTrailingZeros(word);
+ if (++u == wordsInUse)
+ return wordsInUse * BITS_PER_WORD;
+ word = ~words[u];
+ }
+ }
+
+ /**
+ * Returns the "logical size" of this {@code BitSet}: the index of the highest
+ * set bit in the {@code BitSet} plus one. Returns zero if the {@code BitSet}
+ * contains no set bits.
+ *
+ * @return the logical size of this {@code BitSet}
+ * @since 1.2
+ */
+ public int length() {
+ if (wordsInUse == 0)
+ return 0;
+
+ return BITS_PER_WORD * (wordsInUse - 1)
+ + (BITS_PER_WORD - Integer.numberOfLeadingZeros(words[wordsInUse - 1]));
+ }
+
+ /**
+ * Returns true if this {@code BitSet} contains no bits that are set to
+ * {@code true}.
+ *
+ * @return boolean indicating whether this {@code BitSet} is empty
+ * @since 1.4
+ */
+ public boolean isEmpty() {
+ return wordsInUse == 0;
+ }
+
+ /**
+ * Returns true if the specified {@code BitSet} has any bits set to {@code
+ * true} that are also set to {@code true} in this {@code BitSet}.
+ *
+ * @param set
+ * {@code BitSet} to intersect with
+ * @return boolean indicating whether this {@code BitSet} intersects the
+ * specified {@code BitSet}
+ * @since 1.4
+ */
+ public boolean intersects(BS set) {
+ for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)
+ if ((words[i] & set.words[i]) != 0)
+ return true;
+ return false;
+ }
+
+ /**
+ * Returns the number of bits set to {@code true} in this {@code BitSet}.
+ *
+ * @return the number of bits set to {@code true} in this {@code BitSet}
+ * @since 1.4
+ */
+ public int cardinality() {
+ int sum = 0;
+ for (int i = 0; i < wordsInUse; i++)
+ sum += Integer.bitCount(words[i]);
+ return sum;
+ }
+
+ /**
+ * Performs a logical <b>AND</b> of this target bit set with the argument bit
+ * set. This bit set is modified so that each bit in it has the value {@code
+ * true} if and only if it both initially had the value {@code true} and the
+ * corresponding bit in the bit set argument also had the value {@code true}.
+ *
+ * @param set
+ * a bit set
+ */
+ public void and(BS set) {
+ if (this == set)
+ return;
+
+ while (wordsInUse > set.wordsInUse)
+ words[--wordsInUse] = 0;
+
+ // Perform logical AND on words in common
+ for (int i = 0; i < wordsInUse; i++)
+ words[i] &= set.words[i];
+
+ recalculateWordsInUse();
+ }
+
+ /**
+ * Performs a logical <b>OR</b> of this bit set with the bit set argument.
+ * This bit set is modified so that a bit in it has the value {@code true} if
+ * and only if it either already had the value {@code true} or the
+ * corresponding bit in the bit set argument has the value {@code true}.
+ *
+ * @param set
+ * a bit set
+ */
+ public void or(BS set) {
+ if (this == set)
+ return;
+
+ int wordsInCommon = Math.min(wordsInUse, set.wordsInUse);
+
+ if (wordsInUse < set.wordsInUse) {
+ ensureCapacity(set.wordsInUse);
+ wordsInUse = set.wordsInUse;
+ }
+
+ // Perform logical OR on words in common
+ for (int i = 0; i < wordsInCommon; i++)
+ words[i] |= set.words[i];
+
+ // Copy any remaining words
+ if (wordsInCommon < set.wordsInUse)
+ System.arraycopy(set.words, wordsInCommon, words, wordsInCommon,
+ wordsInUse - wordsInCommon);
+
+ }
+
+ /**
+ * Performs a logical <b>XOR</b> of this bit set with the bit set argument.
+ * This bit set is modified so that a bit in it has the value {@code true} if
+ * and only if one of the following statements holds:
+ * <ul>
+ * <li>The bit initially has the value {@code true}, and the corresponding bit
+ * in the argument has the value {@code false}.
+ * <li>The bit initially has the value {@code false}, and the corresponding
+ * bit in the argument has the value {@code true}.
+ * </ul>
+ *
+ * @param set
+ * a bit set
+ */
+ public void xor(BS set) {
+ int wordsInCommon = Math.min(wordsInUse, set.wordsInUse);
+
+ if (wordsInUse < set.wordsInUse) {
+ ensureCapacity(set.wordsInUse);
+ wordsInUse = set.wordsInUse;
+ }
+
+ // Perform logical XOR on words in common
+ for (int i = 0; i < wordsInCommon; i++)
+ words[i] ^= set.words[i];
+
+ // Copy any remaining words
+ if (wordsInCommon < set.wordsInUse)
+ System.arraycopy(set.words, wordsInCommon, words, wordsInCommon,
+ set.wordsInUse - wordsInCommon);
+
+ recalculateWordsInUse();
+ }
+
+ /**
+ * Clears all of the bits in this {@code BitSet} whose corresponding bit is
+ * set in the specified {@code BitSet}.
+ *
+ * @param set
+ * the {@code BitSet} with which to mask this {@code BitSet}
+ * @since 1.2
+ */
+ public void andNot(BS set) {
+ // Perform logical (a & !b) on words in common
+ for (int i = Math.min(wordsInUse, set.wordsInUse) - 1; i >= 0; i--)
+ words[i] &= ~set.words[i];
+
+ recalculateWordsInUse();
+ }
+
+ /**
+ * Returns a hash code value for this bit set. The hash code depends only on
+ * which bits have been set within this <code>BitSet</code>. The algorithm
+ * used to compute it may be described as follows.
+ * <p>
+ * Suppose the bits in the <code>BitSet</code> were to be stored in an array
+ * of <code>long</code> integers called, say, <code>words</code>, in such a
+ * manner that bit <code>k</code> is set in the <code>BitSet</code> (for
+ * nonnegative values of <code>k</code>) if and only if the expression
+ *
+ * <pre>
+ * ((k >> 6) < words.length) && ((words[k >> 6] & (1 << (bit & 0x3F))) != 0)
+ * </pre>
+ *
+ * is true. Then the following definition of the <code>hashCode</code> method
+ * would be a correct implementation of the actual algorithm:
+ *
+ * <pre>
+ * public int hashCode() {
+ * long h = 1234;
+ * for (int i = words.length; --i >= 0;) {
+ * h ˆ= words[i] * (i + 1);
+ * }
+ * return (int) ((h >> 32) ˆ h);
+ * }
+ * </pre>
+ *
+ * Note that the hash code values change if the set of bits is altered.
+ * <p>
+ * Overrides the <code>hashCode</code> method of <code>Object</code>.
+ *
+ * @return a hash code value for this bit set.
+ */
+ @Override
+ public int hashCode() {
+ long h = 1234;
+ for (int i = wordsInUse; --i >= 0;)
+ h ^= words[i] * (i + 1);
+
+ return (int) ((h >> 32) ^ h);
+ }
+
+ /**
+ * Returns the number of bits of space actually in use by this {@code BitSet}
+ * to represent bit values. The maximum element in the set is the size - 1st
+ * element.
+ *
+ * @return the number of bits currently in this bit set
+ */
+ public int size() {
+ return words.length * BITS_PER_WORD;
+ }
+
+ /**
+ * Compares this object against the specified object. The result is {@code
+ * true} if and only if the argument is not {@code null} and is a {@code
+ * Bitset} object that has exactly the same set of bits set to {@code true} as
+ * this bit set. That is, for every nonnegative {@code int} index {@code k},
+ *
+ * <pre>
+ * ((BitSet) obj).get(k) == this.get(k)
+ * </pre>
+ *
+ * must be true. The current sizes of the two bit sets are not compared.
+ *
+ * @param obj
+ * the object to compare with
+ * @return {@code true} if the objects are the same; {@code false} otherwise
+ * @see #size()
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof BS))
+ return false;
+ if (this == obj)
+ return true;
+
+ BS set = (BS) obj;
+
+ if (wordsInUse != set.wordsInUse)
+ return false;
+
+ // Check words in use by both BitSets
+ for (int i = 0; i < wordsInUse; i++)
+ if (words[i] != set.words[i])
+ return false;
+
+ return true;
+ }
+
+ /**
+ * Cloning this {@code BitSet} produces a new {@code BitSet} that is equal to
+ * it. The clone of the bit set is another bit set that has exactly the same
+ * bits set to {@code true} as this bit set.
+ *
+ * @return a clone of this bit set
+ * @see #size()
+ */
+ @Override
+ public Object clone() {
+ if (!sizeIsSticky && wordsInUse != words.length)
+ setLength(wordsInUse);
+ return copy(this);
+ }
+
+ /**
+ * Attempts to reduce internal storage used for the bits in this bit set.
+ * Calling this method may, but is not required to, affect the value returned
+ * by a subsequent call to the {@link #size()} method.
+ * @param n
+ */
+ private void setLength(int n) {
+ int[] a = new int[n];
+ System.arraycopy(words, 0, a, 0, Math.min(wordsInUse, n));
+ words = a;
+ }
+
+ /**
+ * Returns a string representation of this bit set. For every index for which
+ * this {@code BitSet} contains a bit in the set state, the decimal
+ * representation of that index is included in the result. Such indices are
+ * listed in order from lowest to highest, separated by ", " (a comma and
+ * a space) and surrounded by braces, resulting in the usual mathematical
+ * notation for a set of integers.
+ *
+ * <p>
+ * Example:
+ *
+ * <pre>
+ * BitSet drPepper = new BitSet();
+ * </pre>
+ *
+ * Now {@code drPepper.toString()} returns "{}".
+ * <p>
+ *
+ * <pre>
+ * drPepper.set(2);
+ * </pre>
+ *
+ * Now {@code drPepper.toString()} returns "{2}".
+ * <p>
+ *
+ * <pre>
+ * drPepper.set(4);
+ * drPepper.set(10);
+ * </pre>
+ *
+ * Now {@code drPepper.toString()} returns "{2, 4, 10}".
+ *
+ * @return a string representation of this bit set
+ */
+ @Override
+ public String toString() {
+ return escape(this, '{', '}');
+ }
+
+ private final static int[] emptyBitmap = new int[0];
+
+ /**
+ * fast copy
+ *
+ * @param bitsetToCopy
+ * @return bs
+ */
+ public static BS copy(BS bitsetToCopy) {
+ BS bs;
+ /**
+ * Clazz.clone will copy wordsInUse and sizeIsSticky,
+ * but just a pointer to the words array.
+ *
+ * @j2sNative
+ *
+ * bs = Clazz.clone(bitsetToCopy);
+ *
+ */
+ {
+ bs = new BS();
+ }
+ int wordCount = bitsetToCopy.wordsInUse;
+ if (wordCount == 0) {
+ bs.words = emptyBitmap;
+ } else {
+ bs.words = new int[bs.wordsInUse = wordCount];
+ System.arraycopy(bitsetToCopy.words, 0, bs.words, 0, wordCount);
+ }
+ return bs;
+ }
+
+ /**
+ *
+ * @param max
+ * @return n bits below max
+ */
+ public int cardinalityN(int max) {
+ int n = cardinality();
+ for (int i = length(); --i >= max;)
+ if (get(i))
+ n--;
+ return n;
+ }
+
+ @Override
+ public String toJSON() {
+
+ int numBits = (wordsInUse > 128) ? cardinality() : wordsInUse
+ * BITS_PER_WORD;
+ SB b = SB.newN(6 * numBits + 2);
+ b.appendC('[');
+
+ int i = nextSetBit(0);
+ if (i != -1) {
+ b.appendI(i);
+ for (i = nextSetBit(i + 1); i >= 0; i = nextSetBit(i + 1)) {
+ int endOfRun = nextClearBit(i);
+ do {
+ b.append(", ").appendI(i);
+ } while (++i < endOfRun);
+ }
+ }
+
+ b.appendC(']');
+ return b.toString();
+ }
+
+ public static String escape(BS bs, char chOpen, char chClose) {
+ if (bs == null)
+ return chOpen + "{}" + chClose;
+ SB s = new SB();
+ s.append(chOpen + "{");
+ int imax = bs.length();
+ int iLast = -1;
+ int iFirst = -2;
+ int i = -1;
+ while (++i <= imax) {
+ boolean isSet = bs.get(i);
+ if (i == imax || iLast >= 0 && !isSet) {
+ if (iLast >= 0 && iFirst != iLast)
+ s.append((iFirst == iLast - 1 ? " " : ":") + iLast);
+ if (i == imax)
+ break;
+ iLast = -1;
+ }
+ if (bs.get(i)) {
+ if (iLast < 0) {
+ s.append((iFirst == -2 ? "" : " ") + i);
+ iFirst = i;
+ }
+ iLast = i;
+ }
+ }
+ s.append("}").appendC(chClose);
+ return s.toString();
+ }
+
+ public static BS unescape(String str) {
+ char ch;
+ int len;
+ if (str == null || (len = (str = str.trim()).length()) < 4
+ || str.equalsIgnoreCase("({null})")
+ || (ch = str.charAt(0)) != '(' && ch != '['
+ || str.charAt(len - 1) != (ch == '(' ? ')' : ']')
+ || str.charAt(1) != '{' || str.indexOf('}') != len - 2)
+ return null;
+ len -= 2;
+ for (int i = len; --i >= 2;)
+ if (!PT.isDigit(ch = str.charAt(i)) && ch != ' ' && ch != '\t'
+ && ch != ':')
+ return null;
+ int lastN = len;
+ while (PT.isDigit(str.charAt(--lastN))) {
+ // loop
+ }
+ if (++lastN == len)
+ lastN = 0;
+ else
+ try {
+ lastN = Integer.parseInt(str.substring(lastN, len));
+ } catch (NumberFormatException e) {
+ return null;
+ }
+ BS bs = BS.newN(lastN);
+ lastN = -1;
+ int iPrev = -1;
+ int iThis = -2;
+ for (int i = 2; i <= len; i++) {
+ switch (ch = str.charAt(i)) {
+ case '\t':
+ case ' ':
+ case '}':
+ if (iThis < 0)
+ break;
+ if (iThis < lastN)
+ return null;
+ lastN = iThis;
+ if (iPrev < 0)
+ iPrev = iThis;
+ bs.setBits(iPrev, iThis + 1);
+ iPrev = -1;
+ iThis = -2;
+ break;
+ case ':':
+ iPrev = lastN = iThis;
+ iThis = -2;
+ break;
+ default:
+ if (PT.isDigit(ch)) {
+ if (iThis < 0)
+ iThis = 0;
+ iThis = (iThis * 10) + (ch - 48);
+ }
+ }
+ }
+ return (iPrev >= 0 ? null : bs);
+ }
+
+}
--- /dev/null
+// Version 1.0a
+// Copyright (C) 1998, James R. Weeks and BioElectroMech.
+// Visit BioElectroMech at www.obrador.com. Email James@obrador.com.
+
+// See license.txt for details about the allowed used of this software.
+// This software is based in part on the work of the Independent JPEG Group.
+// See IJGreadme.txt for details about the Independent JPEG Group's license.
+
+// This encoder is inspired by the Java Jpeg encoder by Florian Raemy,
+// studwww.eurecom.fr/~raemy.
+// It borrows a great deal of code and structure from the Independent
+// Jpeg Group's Jpeg 6a library, Copyright Thomas G. Lane.
+// See license.txt for details.
+
+package javajs.util;
+
+
+public class Base64 {
+
+ // 0 1 2 3 4 5 6
+ // 0123456789012345678901234567890123456789012345678901234567890123
+ private static String base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+ // 41----------------------5A
+ // 61----------------------7A
+ // 30------39
+ // 2B
+ // 2F
+ // alternative "URL-SAFE" 2D and 5F -_
+
+ private static int[] decode64 = new int[] {
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, //0x00-0x0F
+ 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, //0x10-0x1F
+ 0,0,0,0, 0,0,0,0, 0,0,0,62, 0,62,0,63, //0x20-0x2F
+ 52,53,54,55, 56,57,58,59, 60,61,0,0, 0,0,0,0, //0x30-0x3F
+ 0,0,1,2, 3,4,5,6, 7,8,9,10, 11,12,13,14, //0x40-0x4F
+ 15,16,17,18, 19,20,21,22, 23,24,25,0, 0,0,0,63, //0x50-0x5F
+ 0,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, //0x60-0x6F
+ 41,42,43,44, 45,46,47,48, 49,50,51,0, 0,0,0,0, //0x70-0x7F
+ };
+
+// public static void write(byte[] bytes, OutputChannel out) {
+// SB sb = getBase64(bytes);
+// int len = sb.length();
+// byte[] b = new byte[1];
+// for (int i = 0; i < len; i++) {
+// b[0] = (byte) sb.charAt(i);
+// out.write(b, 0, 1);
+// }
+// }
+
+ public static byte[] getBytes64(byte[] bytes) {
+ return getBase64(bytes).toBytes(0, -1);
+ }
+
+ /**
+ *
+ * @param bytes
+ * @return BASE64-encoded string, without ";base64,"
+ */
+ public static SB getBase64(byte[] bytes) {
+ long nBytes = bytes.length;
+ SB sout = new SB();
+ if (nBytes == 0)
+ return sout;
+ for (int i = 0, nPad = 0; i < nBytes && nPad == 0;) {
+ if (i % 75 == 0 && i != 0)
+ sout.append("\r\n");
+ nPad = (i + 2 == nBytes ? 1 : i + 1 == nBytes ? 2 : 0);
+ int outbytes = ((bytes[i++] << 16) & 0xFF0000)
+ | ((nPad == 2 ? 0 : bytes[i++] << 8) & 0x00FF00)
+ | ((nPad >= 1 ? 0 : (int) bytes[i++]) & 0x0000FF);
+ //System.out.println(Integer.toHexString(outbytes));
+ sout.appendC(base64.charAt((outbytes >> 18) & 0x3F));
+ sout.appendC(base64.charAt((outbytes >> 12) & 0x3F));
+ sout.appendC(nPad == 2 ? '=' : base64.charAt((outbytes >> 6) & 0x3F));
+ sout.appendC(nPad >= 1 ? '=' : base64.charAt(outbytes & 0x3F));
+ }
+ return sout;
+ }
+
+ //Note: Just a simple decoder here. Nothing fancy at all
+ // Because of the 0s in decode64, this is not a VERIFIER
+ // Rather, it may decode even bad Base64-encoded data
+ //
+ // Bob Hanson 4/2007
+
+ public static byte[] decodeBase64(String strBase64) {
+ int nBytes = 0;
+ int ch;
+ int pt0 = strBase64.indexOf(";base64,") + 1;
+ if (pt0 > 0)
+ pt0 += 7;
+ char[] chars64 = strBase64.toCharArray();
+ int len64 = chars64.length;
+ if (len64 == 0)
+ return new byte[0];
+ for (int i = len64; --i >= pt0;)
+ nBytes += ((ch = chars64[i] & 0x7F) == 'A' || decode64[ch] > 0 ? 3 : 0);
+ nBytes = nBytes >> 2;
+ byte[] bytes = new byte[nBytes];
+ int offset = 18;
+ for (int i = pt0, pt = 0, b = 0; i < len64; i++) {
+ if (decode64[ch = chars64[i] & 0x7F] > 0 || ch == 'A' || ch == '=') {
+ b |= decode64[ch] << offset;
+ //System.out.println(chars64[i] + " " + decode64[ch] + " " + offset + " " + Integer.toHexString(b));
+ offset -= 6;
+ if (offset < 0) {
+ bytes[pt++] = (byte) ((b & 0xFF0000) >> 16);
+ if (pt < nBytes)
+ bytes[pt++] = (byte) ((b & 0xFF00) >> 8);
+ if (pt < nBytes)
+ bytes[pt++] = (byte) (b & 0xFF);
+ offset = 18;
+ b = 0;
+ }
+ }
+ }
+ return bytes;
+ }
+}
\ No newline at end of file
--- /dev/null
+/* $RCSfile$
+ * $Author: egonw $
+ * $Date: 2006-03-18 15:59:33 -0600 (Sat, 18 Mar 2006) $
+ * $Revision: 4652 $
+ *
+ * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: hansonr@stolaf.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.util;
+
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.util.Map;
+
+
+import javajs.api.GenericBinaryDocument;
+import javajs.api.GenericZipTools;
+
+
+//import java.io.RandomAccessFile;
+
+/* a basic binary file reader (extended by CompoundDocument).
+ *
+ * random access file info:
+ * http://java.sun.com/docs/books/tutorial/essential/io/rafs.html
+ *
+ * SHOOT! random access is only for applications, not applets!
+ *
+ * Note that YOU are responsible for determining whether a file
+ * is bigEndian or littleEndian; the default is bigEndian.
+ *
+ * JavaScript note: readShort() malfunctioned because (short) (xx << 8)
+ * isn't the same as (int) (xx << 8); same problem in java.io.DataStream
+ *
+ *
+ */
+
+public class BinaryDocument extends BC implements GenericBinaryDocument {
+
+ /**
+ * @j2sIgnore
+ */
+ public BinaryDocument() {
+ }
+
+
+ // called by reflection
+
+ protected DataInputStream stream;
+ protected boolean isRandom = false;
+ public boolean isBigEndian = true;
+ protected GenericZipTools jzt;
+
+ @Override
+ public void close() {
+ if (stream != null)
+ try {
+ stream.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ if (out != null)
+ out.closeChannel();
+ }
+
+ @Override
+ public void setStream(GenericZipTools jzt, BufferedInputStream bis, boolean isBigEndian) {
+ if (jzt != null)
+ this.jzt = jzt;
+ if (bis != null)
+ stream = new DataInputStream(bis);
+ this.isBigEndian = isBigEndian;
+ }
+
+ @Override
+ public void setStreamData(DataInputStream stream, boolean isBigEndian) {
+ if (stream != null)
+ this.stream = stream;
+ this.isBigEndian = isBigEndian;
+ }
+
+ public void setRandom(boolean TF) {
+ isRandom = TF;
+ //CANNOT be random for web
+ }
+
+ @Override
+ public byte readByte() throws Exception {
+ nBytes++;
+ return ioReadByte();
+ }
+
+ private byte ioReadByte() throws Exception {
+ byte b = stream.readByte();
+ if (out != null)
+ out.writeByteAsInt(b);
+ return b;
+ }
+
+ @Override
+ public int readByteArray(byte[] b, int off, int len) throws Exception {
+ int n = ioRead(b, off, len);
+ nBytes += n;
+ return n;
+ }
+
+ private int ioRead(byte[] b, int off, int len) throws Exception {
+ int m = 0;
+ while (len > 0) {
+ int n = stream.read(b, off, len);
+ m += n;
+ if (n > 0 && out != null)
+ writeBytes(b, off, n);
+ if (n >= len)
+ break;
+ off += n;
+ len -= n;
+ }
+ return m;
+ }
+
+ public void writeBytes(byte[] b, int off, int n) throws Exception {
+ out.write(b, off, n);
+ }
+
+ @Override
+ public String readString(int nChar) throws Exception {
+ byte[] temp = new byte[nChar];
+ int n = readByteArray(temp, 0, nChar);
+ return new String(temp, 0, n, "UTF-8");
+ }
+
+ @Override
+ public short readShort() throws Exception {
+ nBytes += 2;
+ short n = (isBigEndian ? ioReadShort()
+ : (short) ((ioReadByte() & 0xff)
+ | (ioReadByte() & 0xff) << 8));
+ /**
+ * @j2sNative
+ *
+ * return (n > 0x7FFF ? n - 0x10000 : n);
+ */
+ {
+ return n;
+ }
+ }
+
+ private short ioReadShort() throws Exception {
+ short b = stream.readShort();
+ if (out != null)
+ writeShort(b);
+ return b;
+ }
+
+
+ public void writeShort(short i) throws Exception {
+ out.writeByteAsInt(i >> 8);
+ out.writeByteAsInt(i);
+ }
+
+ @Override
+ public int readIntLE() throws Exception {
+ nBytes += 4;
+ return readLEInt();
+ }
+
+ @Override
+ public int readInt() throws Exception {
+ nBytes += 4;
+ return (isBigEndian ? ioReadInt() : readLEInt());
+ }
+
+ private int ioReadInt() throws Exception {
+ int i = stream.readInt();
+ if (out != null)
+ writeInt(i);
+ return i;
+ }
+
+ public void writeInt(int i) throws Exception {
+ out.writeByteAsInt(i >> 24);
+ out.writeByteAsInt(i >> 16);
+ out.writeByteAsInt(i >> 8);
+ out.writeByteAsInt(i);
+ }
+
+ @Override
+ public int swapBytesI(int n) {
+ return (((n >> 24) & 0xff)
+ | ((n >> 16) & 0xff) << 8
+ | ((n >> 8) & 0xff) << 16
+ | (n & 0xff) << 24);
+ }
+
+ @Override
+ public short swapBytesS(short n) {
+ return (short) ((((n >> 8) & 0xff)
+ | (n & 0xff) << 8));
+ }
+
+
+ @Override
+ public int readUnsignedShort() throws Exception {
+ nBytes += 2;
+ int a = (ioReadByte() & 0xff);
+ int b = (ioReadByte() & 0xff);
+ return (isBigEndian ? (a << 8) + b : (b << 8) + a);
+ }
+
+ @Override
+ public long readLong() throws Exception {
+ nBytes += 8;
+ return (isBigEndian ? ioReadLong()
+ : ((((long) ioReadByte()) & 0xff)
+ | (((long) ioReadByte()) & 0xff) << 8
+ | (((long) ioReadByte()) & 0xff) << 16
+ | (((long) ioReadByte()) & 0xff) << 24
+ | (((long) ioReadByte()) & 0xff) << 32
+ | (((long) ioReadByte()) & 0xff) << 40
+ | (((long) ioReadByte()) & 0xff) << 48
+ | (((long) ioReadByte()) & 0xff) << 54));
+ }
+
+ private long ioReadLong() throws Exception {
+ long b = stream.readLong();
+ if (out != null)
+ writeLong(b);
+ return b;
+ }
+
+ public void writeLong(long b) throws Exception {
+ writeInt((int)((b >> 32) & 0xFFFFFFFFl));
+ writeInt((int)(b & 0xFFFFFFFFl));
+ }
+
+ private int readLEInt() throws Exception {
+ ioRead(t8, 0, 4);
+ return bytesToInt(t8, 0, false);
+ }
+
+ byte[] t8 = new byte[8];
+
+ @Override
+ public float readFloat() throws Exception {
+ return intToFloat(readInt());
+ }
+
+ @Override
+ public double readDouble() throws Exception {
+ /**
+ *
+ * reading the float equivalent here in JavaScript
+ *
+ * @j2sNative
+ *
+ * this.readByteArray(this.t8, 0, 8);
+ * return this.bytesToDoubleToFloat(this.t8, 0, this.isBigEndian);
+ *
+ */
+ {
+ nBytes += 8;
+ return (isBigEndian ? ioReadDouble() : Double.longBitsToDouble(readLELong()));
+ }
+ }
+
+ private double ioReadDouble() throws Exception {
+ double d = stream.readDouble();
+ if (out != null)
+ writeLong(Double.doubleToRawLongBits(d));
+ return d;
+ }
+
+ private long readLELong() throws Exception {
+ return ((((long) ioReadByte()) & 0xff)
+ | (((long) ioReadByte()) & 0xff) << 8
+ | (((long) ioReadByte()) & 0xff) << 16
+ | (((long) ioReadByte()) & 0xff) << 24
+ | (((long) ioReadByte()) & 0xff) << 32
+ | (((long) ioReadByte()) & 0xff) << 40
+ | (((long) ioReadByte()) & 0xff) << 48
+ | (((long) ioReadByte()) & 0xff) << 56);
+ }
+
+ @Override
+ public void seek(long offset) {
+ // slower, but all that is available using the applet
+ try {
+ if (offset == nBytes)
+ return;
+ if (offset < nBytes) {
+ stream.reset();
+ if (out != null && nBytes != 0)
+ out.reset();
+ nBytes = 0;
+ } else {
+ offset -= nBytes;
+ }
+ if (out == null) {
+ stream.skipBytes((int)offset);
+ } else {
+ readByteArray(new byte[(int)offset], 0, (int) offset);
+ }
+ nBytes += offset;
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+
+ long nBytes;
+
+ @Override
+ public long getPosition() {
+ return nBytes;
+ }
+
+ OC out;
+ @Override
+ public void setOutputChannel(OC out) {
+ this.out = out;
+ }
+
+ @Override
+ public SB getAllDataFiles(String binaryFileList, String firstFile) {
+ return null;
+ }
+
+ @Override
+ public void getAllDataMapped(String replace, String string,
+ Map<String, String> fileData) {
+ }
+
+
+/* random access -- application only:
+ *
+ void seekFile(long offset) {
+ try {
+ file.seek(offset);
+ } catch (Exception e) {
+ System.out.println(e.getMessage());
+ }
+ }
+*/
+}
--- /dev/null
+package javajs.util;
+
+import java.util.Hashtable;
+import java.util.Map;
+
+import javajs.api.GenericColor;
+
+/**
+ * ColorUtility
+ *
+ */
+
+public class CU {
+
+ public static String toRGBHexString(GenericColor c) {
+ int rgb = c.getRGB();
+ if (rgb == 0)
+ return "000000";
+ String r = "00" + Integer.toHexString((rgb >> 16) & 0xFF);
+ r = r.substring(r.length() - 2);
+ String g = "00" + Integer.toHexString((rgb >> 8) & 0xFF);
+ g = g.substring(g.length() - 2);
+ String b = "00" + Integer.toHexString(rgb & 0xFF);
+ b = b.substring(b.length() - 2);
+ return r + g + b;
+ }
+
+ public static String toCSSString(GenericColor c) {
+ int opacity = c.getOpacity255();
+ if (opacity == 255)
+ return "#" + toRGBHexString(c);
+ int rgb = c.getRGB();
+ return "rgba(" + ((rgb>>16)&0xFF) + "," + ((rgb>>8)&0xff) + "," + (rgb&0xff) + "," + opacity/255f + ")";
+ }
+
+ private final static String[] colorNames = {
+ "black", // 000000
+ "pewhite", // ffffff
+ "pecyan", // 00ffff
+ "pepurple", // d020ff
+ "pegreen", // 00ff00
+ "peblue", // 6060ff
+ "peviolet", // ff80c0
+ "pebrown", // a42028
+ "pepink", // ffd8d8
+ "peyellow", // ffff00
+ "pedarkgreen", // 00c000
+ "peorange", // ffb000
+ "pelightblue", // b0b0ff
+ "pedarkcyan", // 00a0a0
+ "pedarkgray", // 606060
+
+ "aliceblue", // F0F8FF
+ "antiquewhite", // FAEBD7
+ "aqua", // 00FFFF
+ "aquamarine", // 7FFFD4
+ "azure", // F0FFFF
+ "beige", // F5F5DC
+ "bisque", // FFE4C4
+ "blanchedalmond", // FFEBCD
+ "blue", // 0000FF
+ "blueviolet", // 8A2BE2
+ "brown", // A52A2A
+ "burlywood", // DEB887
+ "cadetblue", // 5F9EA0
+ "chartreuse", // 7FFF00
+ "chocolate", // D2691E
+ "coral", // FF7F50
+ "cornflowerblue", // 6495ED
+ "cornsilk", // FFF8DC
+ "crimson", // DC143C
+ "cyan", // 00FFFF
+ "darkblue", // 00008B
+ "darkcyan", // 008B8B
+ "darkgoldenrod", // B8860B
+ "darkgray", // A9A9A9
+ "darkgreen", // 006400
+ "darkkhaki", // BDB76B
+ "darkmagenta", // 8B008B
+ "darkolivegreen", // 556B2F
+ "darkorange", // FF8C00
+ "darkorchid", // 9932CC
+ "darkred", // 8B0000
+ "darksalmon", // E9967A
+ "darkseagreen", // 8FBC8F
+ "darkslateblue", // 483D8B
+ "darkslategray", // 2F4F4F
+ "darkturquoise", // 00CED1
+ "darkviolet", // 9400D3
+ "deeppink", // FF1493
+ "deepskyblue", // 00BFFF
+ "dimgray", // 696969
+ "dodgerblue", // 1E90FF
+ "firebrick", // B22222
+ "floralwhite", // FFFAF0 16775920
+ "forestgreen", // 228B22
+ "fuchsia", // FF00FF
+ "gainsboro", // DCDCDC
+ "ghostwhite", // F8F8FF
+ "gold", // FFD700
+ "goldenrod", // DAA520
+ "gray", // 808080
+ "green", // 008000
+ "greenyellow", // ADFF2F
+ "honeydew", // F0FFF0
+ "hotpink", // FF69B4
+ "indianred", // CD5C5C
+ "indigo", // 4B0082
+ "ivory", // FFFFF0
+ "khaki", // F0E68C
+ "lavender", // E6E6FA
+ "lavenderblush", // FFF0F5
+ "lawngreen", // 7CFC00
+ "lemonchiffon", // FFFACD
+ "lightblue", // ADD8E6
+ "lightcoral", // F08080
+ "lightcyan", // E0FFFF
+ "lightgoldenrodyellow", // FAFAD2
+ "lightgreen", // 90EE90
+ "lightgrey", // D3D3D3
+ "lightpink", // FFB6C1
+ "lightsalmon", // FFA07A
+ "lightseagreen", // 20B2AA
+ "lightskyblue", // 87CEFA
+ "lightslategray", // 778899
+ "lightsteelblue", // B0C4DE
+ "lightyellow", // FFFFE0
+ "lime", // 00FF00
+ "limegreen", // 32CD32
+ "linen", // FAF0E6
+ "magenta", // FF00FF
+ "maroon", // 800000
+ "mediumaquamarine", // 66CDAA
+ "mediumblue", // 0000CD
+ "mediumorchid", // BA55D3
+ "mediumpurple", // 9370DB
+ "mediumseagreen", // 3CB371
+ "mediumslateblue", // 7B68EE
+ "mediumspringgreen", // 00FA9A
+ "mediumturquoise", // 48D1CC
+ "mediumvioletred", // C71585
+ "midnightblue", // 191970
+ "mintcream", // F5FFFA
+ "mistyrose", // FFE4E1
+ "moccasin", // FFE4B5
+ "navajowhite", // FFDEAD
+ "navy", // 000080
+ "oldlace", // FDF5E6
+ "olive", // 808000
+ "olivedrab", // 6B8E23
+ "orange", // FFA500
+ "orangered", // FF4500
+ "orchid", // DA70D6
+ "palegoldenrod", // EEE8AA
+ "palegreen", // 98FB98
+ "paleturquoise", // AFEEEE
+ "palevioletred", // DB7093
+ "papayawhip", // FFEFD5
+ "peachpuff", // FFDAB9
+ "peru", // CD853F
+ "pink", // FFC0CB
+ "plum", // DDA0DD
+ "powderblue", // B0E0E6
+ "purple", // 800080
+ "red", // FF0000
+ "rosybrown", // BC8F8F
+ "royalblue", // 4169E1
+ "saddlebrown", // 8B4513
+ "salmon", // FA8072
+ "sandybrown", // F4A460
+ "seagreen", // 2E8B57
+ "seashell", // FFF5EE
+ "sienna", // A0522D
+ "silver", // C0C0C0
+ "skyblue", // 87CEEB
+ "slateblue", // 6A5ACD
+ "slategray", // 708090
+ "snow", // FFFAFA 16775930
+ "springgreen", // 00FF7F
+ "steelblue", // 4682B4
+ "tan", // D2B48C
+ "teal", // 008080
+ "thistle", // D8BFD8
+ "tomato", // FF6347
+ "turquoise", // 40E0D0
+ "violet", // EE82EE
+ "wheat", // F5DEB3
+ "white", // FFFFFF 16777215
+ "whitesmoke", // F5F5F5
+ "yellow", // FFFF00
+ "yellowgreen", // 9ACD32
+ // plus a few rasmol names/values
+ "bluetint", // AFD7FF
+ "greenblue", // 2E8B57
+ "greentint", // 98FFB3
+ "grey", // 808080
+ "pinktint", // FFABBB
+ "redorange", // FF4500
+ "yellowtint", // F6F675
+ };
+
+ private final static int[] colorArgbs = {
+ //#FFFFC3 hover
+ 0xFF000000, // black
+ // plus the PE chain colors
+ 0xFFffffff, // pewhite
+ 0xFF00ffff, // pecyan
+ 0xFFd020ff, // pepurple
+ 0xFF00ff00, // pegreen
+ 0xFF6060ff, // peblue
+ 0xFFff80c0, // peviolet
+ 0xFFa42028, // pebrown
+ 0xFFffd8d8, // pepink
+ 0xFFffff00, // peyellow
+ 0xFF00c000, // pedarkgreen
+ 0xFFffb000, // peorange
+ 0xFFb0b0ff, // pelightblue
+ 0xFF00a0a0, // pedarkcyan
+ 0xFF606060, // pedarkgray
+ // standard JavaScript
+ 0xFFF0F8FF, // aliceblue
+ 0xFFFAEBD7, // antiquewhite
+ 0xFF00FFFF, // aqua
+ 0xFF7FFFD4, // aquamarine
+ 0xFFF0FFFF, // azure
+ 0xFFF5F5DC, // beige
+ 0xFFFFE4C4, // bisque
+ 0xFFFFEBCD, // blanchedalmond
+ 0xFF0000FF, // blue
+ 0xFF8A2BE2, // blueviolet
+ 0xFFA52A2A, // brown
+ 0xFFDEB887, // burlywood
+ 0xFF5F9EA0, // cadetblue
+ 0xFF7FFF00, // chartreuse
+ 0xFFD2691E, // chocolate
+ 0xFFFF7F50, // coral
+ 0xFF6495ED, // cornflowerblue
+ 0xFFFFF8DC, // cornsilk
+ 0xFFDC143C, // crimson
+ 0xFF00FFFF, // cyan
+ 0xFF00008B, // darkblue
+ 0xFF008B8B, // darkcyan
+ 0xFFB8860B, // darkgoldenrod
+ 0xFFA9A9A9, // darkgray
+ 0xFF006400, // darkgreen
+
+ 0xFFBDB76B, // darkkhaki
+ 0xFF8B008B, // darkmagenta
+ 0xFF556B2F, // darkolivegreen
+ 0xFFFF8C00, // darkorange
+ 0xFF9932CC, // darkorchid
+ 0xFF8B0000, // darkred
+ 0xFFE9967A, // darksalmon
+ 0xFF8FBC8F, // darkseagreen
+ 0xFF483D8B, // darkslateblue
+ 0xFF2F4F4F, // darkslategray
+ 0xFF00CED1, // darkturquoise
+ 0xFF9400D3, // darkviolet
+ 0xFFFF1493, // deeppink
+ 0xFF00BFFF, // deepskyblue
+ 0xFF696969, // dimgray
+ 0xFF1E90FF, // dodgerblue
+ 0xFFB22222, // firebrick
+ 0xFFFFFAF0, // floralwhite
+ 0xFF228B22, // forestgreen
+ 0xFFFF00FF, // fuchsia
+ 0xFFDCDCDC, // gainsboro
+ 0xFFF8F8FF, // ghostwhite
+ 0xFFFFD700, // gold
+ 0xFFDAA520, // goldenrod
+ 0xFF808080, // gray
+ 0xFF008000, // green
+ 0xFFADFF2F, // greenyellow
+ 0xFFF0FFF0, // honeydew
+ 0xFFFF69B4, // hotpink
+ 0xFFCD5C5C, // indianred
+ 0xFF4B0082, // indigo
+ 0xFFFFFFF0, // ivory
+ 0xFFF0E68C, // khaki
+ 0xFFE6E6FA, // lavender
+ 0xFFFFF0F5, // lavenderblush
+ 0xFF7CFC00, // lawngreen
+ 0xFFFFFACD, // lemonchiffon
+ 0xFFADD8E6, // lightblue
+ 0xFFF08080, // lightcoral
+ 0xFFE0FFFF, // lightcyan
+ 0xFFFAFAD2, // lightgoldenrodyellow
+ 0xFF90EE90, // lightgreen
+ 0xFFD3D3D3, // lightgrey
+ 0xFFFFB6C1, // lightpink
+ 0xFFFFA07A, // lightsalmon
+ 0xFF20B2AA, // lightseagreen
+ 0xFF87CEFA, // lightskyblue
+ 0xFF778899, // lightslategray
+ 0xFFB0C4DE, // lightsteelblue
+ 0xFFFFFFE0, // lightyellow
+ 0xFF00FF00, // lime
+ 0xFF32CD32, // limegreen
+ 0xFFFAF0E6, // linen
+ 0xFFFF00FF, // magenta
+ 0xFF800000, // maroon
+ 0xFF66CDAA, // mediumaquamarine
+ 0xFF0000CD, // mediumblue
+ 0xFFBA55D3, // mediumorchid
+ 0xFF9370DB, // mediumpurple
+ 0xFF3CB371, // mediumseagreen
+ 0xFF7B68EE, // mediumslateblue
+ 0xFF00FA9A, // mediumspringgreen
+ 0xFF48D1CC, // mediumturquoise
+ 0xFFC71585, // mediumvioletred
+ 0xFF191970, // midnightblue
+ 0xFFF5FFFA, // mintcream
+ 0xFFFFE4E1, // mistyrose
+ 0xFFFFE4B5, // moccasin
+ 0xFFFFDEAD, // navajowhite
+ 0xFF000080, // navy
+ 0xFFFDF5E6, // oldlace
+ 0xFF808000, // olive
+ 0xFF6B8E23, // olivedrab
+ 0xFFFFA500, // orange
+ 0xFFFF4500, // orangered
+ 0xFFDA70D6, // orchid
+ 0xFFEEE8AA, // palegoldenrod
+ 0xFF98FB98, // palegreen
+ 0xFFAFEEEE, // paleturquoise
+ 0xFFDB7093, // palevioletred
+ 0xFFFFEFD5, // papayawhip
+ 0xFFFFDAB9, // peachpuff
+ 0xFFCD853F, // peru
+ 0xFFFFC0CB, // pink
+ 0xFFDDA0DD, // plum
+ 0xFFB0E0E6, // powderblue
+ 0xFF800080, // purple
+ 0xFFFF0000, // red
+ 0xFFBC8F8F, // rosybrown
+ 0xFF4169E1, // royalblue
+ 0xFF8B4513, // saddlebrown
+ 0xFFFA8072, // salmon
+ 0xFFF4A460, // sandybrown
+ 0xFF2E8B57, // seagreen
+ 0xFFFFF5EE, // seashell
+ 0xFFA0522D, // sienna
+ 0xFFC0C0C0, // silver
+ 0xFF87CEEB, // skyblue
+ 0xFF6A5ACD, // slateblue
+ 0xFF708090, // slategray
+ 0xFFFFFAFA, // snow
+ 0xFF00FF7F, // springgreen
+ 0xFF4682B4, // steelblue
+ 0xFFD2B48C, // tan
+ 0xFF008080, // teal
+ 0xFFD8BFD8, // thistle
+ 0xFFFF6347, // tomato
+ 0xFF40E0D0, // turquoise
+ 0xFFEE82EE, // violet
+ 0xFFF5DEB3, // wheat
+ 0xFFFFFFFF, // white
+ 0xFFF5F5F5, // whitesmoke
+ 0xFFFFFF00, // yellow
+ 0xFF9ACD32, // yellowgreen
+ // plus a few rasmol names/values
+ 0xFFAFD7FF, // bluetint
+ 0xFF2E8B57, // greenblue
+ 0xFF98FFB3, // greentint
+ 0xFF808080, // grey
+ 0xFFFFABBB, // pinktint
+ 0xFFFF4500, // redorange
+ 0xFFF6F675, // yellowtint
+ };
+
+ private static final Map<String, Integer> mapJavaScriptColors = new Hashtable<String, Integer>();
+
+ static {
+ for (int i = colorNames.length; --i >= 0; )
+ mapJavaScriptColors.put(colorNames[i], Integer.valueOf(colorArgbs[i]));
+ }
+
+ /**
+ * accepts [xRRGGBB] or [0xRRGGBB] or [0xFFRRGGBB] or #RRGGBB or
+ * [red,green,blue] or a valid JavaScript color
+ *
+ * @param strColor
+ * @return 0 if invalid or integer color
+ */
+ public static int getArgbFromString(String strColor) {
+ int len = 0;
+ if (strColor == null || (len = strColor.length()) == 0)
+ return 0;
+ if (strColor.charAt(0) == '[' && strColor.charAt(len - 1) == ']') {
+ String check;
+ if (strColor.indexOf(",") >= 0) {
+ String[] tokens = PT.split(strColor.substring(1, strColor
+ .length() - 1), ",");
+ if (tokens.length != 3)
+ return 0;
+ float red = PT.parseFloat(tokens[0]);
+ float grn = PT.parseFloat(tokens[1]);
+ float blu = PT.parseFloat(tokens[2]);
+ return colorTriadToFFRGB(red, grn, blu);
+ }
+ switch (len) {
+ case 9:
+ check = "x";
+ break;
+ case 10:
+ check = "0x";
+ break;
+ default:
+ return 0;
+ }
+ if (strColor.indexOf(check) != 1)
+ return 0;
+ strColor = "#" + strColor.substring(len - 7, len - 1);
+ len = 7;
+ }
+ if (len == 7 && strColor.charAt(0) == '#') {
+ try {
+ return PT.parseIntRadix(strColor.substring(1, 7), 16) | 0xFF000000;
+ } catch (Exception e) {
+ return 0;
+ }
+ }
+ Integer boxedArgb = mapJavaScriptColors.get(strColor.toLowerCase());
+ return (boxedArgb == null ? 0 : boxedArgb.intValue());
+ }
+
+ public static int colorTriadToFFRGB(float x, float y, float z) {
+ if (x <= 1 && y <= 1 && z <= 1) {
+ if (x > 0)
+ x = x * 256 - 1;
+ if (y > 0)
+ y = y * 256 - 1;
+ if (z > 0)
+ z = z * 256 - 1;
+ }
+ return rgb((int) x, (int) y, (int) z);
+ }
+
+ public static int rgb(int red, int grn, int blu) {
+ return 0xFF000000 | (red << 16) | (grn << 8) | blu;
+ }
+
+ public final static P3 colorPtFromString(String colorName) {
+ return colorPtFromInt(getArgbFromString(colorName), null);
+ }
+
+ public final static P3 colorPtFromInt(int color, P3 pt) {
+ if (pt == null)
+ pt = new P3();
+ pt.set((color >> 16) & 0xFF, (color >> 8) & 0xFF, color & 0xFF);
+ return pt;
+ }
+
+ public static int colorPtToFFRGB(T3 pt) {
+ return colorTriadToFFRGB(pt.x, pt.y, pt.z);
+ }
+
+ public static void toRGB3f(int c, float[] f) {
+ f[0] = ((c >> 16) & 0xFF) / 255f; // red
+ f[1] = ((c >> 8) & 0xFF) / 255f;
+ f[2] = (c & 0xFF) / 255f;
+ }
+
+ /**
+ * Return a greyscale rgb value 0-FF using NTSC color lightness algorithm
+ *<p>
+ * the alpha component is set to 0xFF. If you want a value in the
+ * range 0-255 then & the result with 0xFF;
+ *
+ * @param rgb the rgb value
+ * @return a grayscale value in the range 0 - 255 decimal
+ */
+ public static int toFFGGGfromRGB(int rgb) {
+ int grey = (((2989 * ((rgb >> 16) & 0xFF)) +
+ (5870 * ((rgb >> 8) & 0xFF)) +
+ (1140 * (rgb & 0xFF)) + 5000) / 10000) & 0xFFFFFF;
+ return rgb(grey, grey, grey);
+ }
+
+
+ /**
+ * Convert RGB values to HSL (hue/saturation/lightness)
+ *
+ * @param rgb
+ * range 255 255 255
+ * @param doRound
+ * set to false when just using this for
+ * for RGB -- HSL -- HSL' -- RGB' conversion
+ *
+ * @return the HSL as P3 range 360 100 100
+ * @author hansonr
+ */
+
+ public static P3 rgbToHSL(P3 rgb, boolean doRound) {
+ // adapted from http://tips4java.wordpress.com/2009/07/05/hsl-color/
+ // see http://en.wikipedia.org/wiki/HSL_color_space
+ float r = rgb.x / 255;
+ float g = rgb.y / 255;
+ float b = rgb.z / 255;
+ float min = Math.min(r, Math.min(g, b));
+ float max = Math.max(r, Math.max(g, b));
+
+ // lightness is just p * 50
+
+ float p = (max + min);
+ float q = (max - min);
+
+ float h = (60 * ((q == 0 ? 0 : max == r ? ((g - b) / q + 6)
+ : max == g ? (b - r) / q + 2 : (r - g) / q + 4))) % 360;
+
+ float s = q / (q == 0 ? 1 : p <= 1 ? p : 2 - p);
+
+ // we round to tenths for HSL so that we can return enough
+ // precision to get back 1-255 in RGB
+ return (doRound ? P3.new3(Math.round(h*10)/10f, Math.round(s * 1000)/10f,
+ Math.round(p * 500)/10f) : P3.new3(h, s * 100, p * 50));
+ }
+
+ /**
+ * Convert HSL (hue/saturation/luninance) values to RGB
+ *
+ * @param hsl in the range 360, 100, 100
+ * @return the RGB as P3 range 0 to 255
+ * @author hansonr
+ */
+ public static P3 hslToRGB(P3 hsl) {
+ // adapted from http://tips4java.wordpress.com/2009/07/05/hsl-color/
+ // see http://en.wikipedia.org/wiki/HSL_color_space
+
+ // highly condensed
+
+ float h = Math.max(0, Math.min(360, hsl.x)) / 60;
+ float s = Math.max(0, Math.min(100, hsl.y)) / 100;
+ float l = Math.max(0, Math.min(100, hsl.z)) / 100;
+
+ float p = l - (l < 0.5 ? l : 1 - l) * s;
+ float q = 2 * (l - p);
+
+ float r = toRGB(p, q, h + 2);
+ float g = toRGB(p, q, h);
+ float b = toRGB(p, q, h - 2);
+ return P3.new3(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255));
+ }
+
+ private static float toRGB(float p, float q, float h) {
+ return ((h = (h + (h < 0 ? 6 : h > 6 ? -6 : 0))) < 1 ? p + q * h
+ : h < 3 ? p + q : h < 4 ? p + q * (4 - h) : p);
+ }
+
+}
--- /dev/null
+package javajs.util;
+
+import java.io.BufferedReader;
+
+import java.util.Hashtable;
+
+import java.util.Map;
+
+import javajs.api.GenericCifDataParser;
+import javajs.api.GenericLineReader;
+
+
+
+public class CifDataParser implements GenericCifDataParser {
+ /**
+ *
+ * A special tokenizer class for dealing with quoted strings in CIF files.
+ *
+ * Greek letters implemented in Jmol 13.3.9 and only for
+ * titles and space groups. All other mark ups ignored.
+ *
+ *<p>
+ * regarding the treatment of single quotes vs. primes in
+ * cif file, PMR wrote:
+ *</p>
+ *<p>
+ * * There is a formal grammar for CIF
+ * (see http://www.iucr.org/iucr-top/cif/index.html)
+ * which confirms this. The textual explanation is
+ *<p />
+ *<p>
+ * 14. Matching single or double quote characters (' or ") may
+ * be used to bound a string representing a non-simple data value
+ * provided the string does not extend over more than one line.
+ *<p />
+ *<p>
+ * 15. Because data values are invariably separated from other
+ * tokens in the file by white space, such a quote-delimited
+ * character string may contain instances of the character used
+ * to delimit the string provided they are not followed by white
+ * space. For example, the data item
+ *<code>
+ * _example 'a dog's life'
+ *</code>
+ * is legal; the data value is a dog's life.
+ *</p>
+ *<p>
+ * [PMR - the terminating character(s) are quote+whitespace.
+ * That would mean that:
+ *<code>
+ * _example 'Jones' life'
+ *</code>
+ * would be an error
+ *</p>
+ *<p>
+ * The CIF format was developed in that late 1980's under the aegis of the
+ * International Union of Crystallography (I am a consultant to the COMCIFs
+ * committee). It was ratified by the Union and there have been several
+ * workshops. mmCIF is an extension of CIF which includes a relational
+ * structure. The formal publications are:
+ *</p>
+ *<p>
+ * Hall, S. R. (1991). "The STAR File: A New Format for Electronic Data
+ * Transfer and Archiving", J. Chem. Inform. Comp. Sci., 31, 326-333.
+ * Hall, S. R., Allen, F. H. and Brown, I. D. (1991). "The Crystallographic
+ * Information File (CIF): A New Standard Archive File for Crystallography",
+ * Acta Cryst., A47, 655-685.
+ * Hall, S.R. & Spadaccini, N. (1994). "The STAR File: Detailed
+ * Specifications," J. Chem. Info. Comp. Sci., 34, 505-508.
+ *</p>
+ */
+ private GenericLineReader reader;
+ private BufferedReader br;
+
+ private String line;
+ private String str;
+ private int ich;
+ private int cch;
+ private boolean wasUnQuoted;
+ private String strPeeked;
+ private int ichPeeked;
+ private int fieldCount;
+ private String[] loopData;
+ private SB fileHeader = new SB();
+ private boolean isHeader = true;
+ private String nullString = "\0";
+
+ /**
+ * Set the string value of what is returned for "." and "?"
+ *
+ * @param nullString null here returns "." and "?"; default is "\0"
+ *
+ */
+ public void setNullValue(String nullString) {
+ this.nullString = nullString;
+ }
+
+ /**
+ * A global, static map that contains field information. The assumption is that
+ * if we read a set of fields for, say, atom_site, once in a lifetime, then
+ * that should be good forever. Those are static lists. Or should be....
+ */
+ private static Map<String, Integer> htFields = new Hashtable<String, Integer>();
+
+ ////////////////////////////////////////////////////////////////
+ // special tokenizer class
+ ////////////////////////////////////////////////////////////////
+
+ public CifDataParser() {
+ // for reflection
+ }
+
+ private String[] fields;
+
+ @Override
+ public String getLoopData(int i) {
+ return loopData[i];
+ }
+
+ @Override
+ public int getFieldCount() {
+ return fieldCount;
+ }
+
+ @Override
+ public String getField(int i) {
+ return fields[i];
+ }
+
+ /**
+ * A Chemical Information File data parser.
+ *
+ * Should be called immediately upon construction.
+ *
+ * Two options; one of reader or br should be null, or reader will be
+ * ignored. Just simpler this way...
+ *
+ * @param reader Anything that can deliver a line of text or null
+ * @param br A standard BufferedReader.
+ *
+ */
+ @Override
+ public CifDataParser set(GenericLineReader reader, BufferedReader br) {
+ this.reader = reader;
+ this.br = br;
+ return this;
+ }
+
+ /**
+ *
+ * @return commented-out section at the start of a CIF file.
+ *
+ */
+ @Override
+ public String getFileHeader() {
+ return fileHeader.toString();
+ }
+
+
+ /**
+ * Parses all CIF data for a reader defined in the constructor
+ * into a standard Map structure and close the BufferedReader if
+ * it exists.
+ *
+ * @return Hashtable of models Vector of Hashtable data
+ */
+ @Override
+ public Map<String, Object> getAllCifData() {
+ line = "";
+ String key;
+ Map<String, Object> data = null;
+ Map<String, Object> allData = new Hashtable<String, Object>();
+ Lst<Map<String, Object>> models = new Lst<Map<String,Object>>();
+ allData.put("models", models);
+ try {
+ while ((key = getNextToken()) != null) {
+ if (key.startsWith("global_") || key.startsWith("data_")) {
+ models.addLast(data = new Hashtable<String, Object>());
+ data.put("name", key);
+ continue;
+ }
+ if (key.startsWith("loop_")) {
+ getAllCifLoopData(data);
+ continue;
+ }
+ if (key.charAt(0) != '_') {
+ System.out.println("CIF ERROR ? should be an underscore: " + key);
+ } else {
+ String value = getNextToken();
+ if (value == null) {
+ System.out.println("CIF ERROR ? end of file; data missing: " + key);
+ } else {
+ data.put(fixKey(key), value);
+ }
+ }
+ }
+ } catch (Exception e) {
+ // ?
+ }
+ try {
+ if (br != null)
+ br.close();
+ } catch (Exception e) {
+ // ?
+ }
+ return allData;
+ }
+
+ /**
+ * create our own list of keywords and for each one create a list
+ * of data associated with that keyword. For example, a list of all
+ * x coordinates, then a list of all y coordinates, etc.
+ *
+ * @param data
+ * @throws Exception
+ */
+ @SuppressWarnings("unchecked")
+ private void getAllCifLoopData(Map<String, Object> data) throws Exception {
+ String key;
+ Lst<String> keyWords = new Lst<String>();
+ while ((key = peekToken()) != null && key.charAt(0) == '_') {
+ key = fixKey(getTokenPeeked());
+ keyWords.addLast(key);
+ data.put(key, new Lst<String>());
+ }
+ fieldCount = keyWords.size();
+ if (fieldCount == 0)
+ return;
+ loopData = new String[fieldCount];
+ while (getData())
+ for (int i = 0; i < fieldCount; i++)
+ ((Lst<String>)data.get(keyWords.get(i))).addLast(loopData[i]);
+ }
+
+ @Override
+ public String readLine() {
+ try {
+ line = (reader == null ? br.readLine() : reader.readNextLine());
+ if (line == null)
+ return null;
+ if (isHeader) {
+ if (line.startsWith("#"))
+ fileHeader.append(line).appendC('\n');
+ else
+ isHeader = false;
+ }
+ return line;
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ /**
+ * The work horse; a general reader for loop data.
+ * Fills loopData with fieldCount fields.
+ *
+ * @return false if EOF
+ * @throws Exception
+ */
+ @Override
+ public boolean getData() throws Exception {
+ // line is already present, and we leave with the next line to parse
+ for (int i = 0; i < fieldCount; ++i)
+ if ((loopData[i] = getNextDataToken()) == null)
+ return false;
+ return (fieldCount > 0);
+ }
+
+ /**
+ *
+ * Skips all associated loop data. (Skips to next control word.)
+ *
+ * @throws Exception
+ */
+ @Override
+ public String skipLoop(boolean doReport) throws Exception {
+ String str;
+ SB ret = (doReport ? new SB() : null);
+ int n = 0;
+ while ((str = peekToken()) != null && str.charAt(0) == '_') {
+ if (ret != null)
+ ret.append(str).append("\n");
+ getTokenPeeked();
+ n++;
+ }
+ int m = 0;
+ while ((str = getNextDataToken()) != null) {
+ if (ret == null)
+ continue;
+ ret.append(str).append(" ");
+ if ((++m % n) == 0)
+ ret.append("\n");
+ }
+ return (ret == null ? null : ret.toString());
+ }
+
+ /**
+ *
+ * @return the next token of any kind, or null
+ * @throws Exception
+ */
+ @Override
+ public String getNextToken() throws Exception {
+ while (!strHasMoreTokens())
+ if (setStringNextLine() == null)
+ return null;
+ return nextStrToken();
+ }
+
+ /**
+ *
+ * first checks to see if the next token is an unquoted
+ * control code, and if so, returns null
+ *
+ * @return next data token or null
+ * @throws Exception
+ */
+ @Override
+ public String getNextDataToken() throws Exception {
+ String str = peekToken();
+ if (str == null)
+ return null;
+ if (wasUnQuoted)
+ if (str.charAt(0) == '_' || str.startsWith("loop_")
+ || str.startsWith("data_")
+ || str.startsWith("stop_")
+ || str.startsWith("global_"))
+ return null;
+ return getTokenPeeked();
+ }
+
+ /**
+ * Just look at the next token. Saves it for retrieval
+ * using getTokenPeeked()
+ *
+ * @return next token or null if EOF
+ * @throws Exception
+ */
+ @Override
+ public String peekToken() throws Exception {
+ while (!strHasMoreTokens())
+ if (setStringNextLine() == null)
+ return null;
+ int ich = this.ich;
+ strPeeked = nextStrToken();
+ ichPeeked= this.ich;
+ this.ich = ich;
+ return strPeeked;
+ }
+
+ /**
+ *
+ * @return the token last acquired; may be null
+ */
+ @Override
+ public String getTokenPeeked() {
+ ich = ichPeeked;
+ return strPeeked;
+ }
+
+ /**
+ * Used especially for data that might be multi-line data that
+ * might have unwanted white space at start or end.
+ *
+ * @param str
+ * @return str without any leading/trailing white space, and no '\n'
+ */
+ @Override
+ public String fullTrim(String str) {
+ int pt0 = -1;
+ int pt1 = str.length();
+ while (++pt0 < pt1 && PT.isWhitespace(str.charAt(pt0))) {
+ }
+ while (--pt1 > pt0 && PT.isWhitespace(str.charAt(pt1))) {
+ }
+ return str.substring(pt0, pt1 + 1);
+ }
+
+ private final static String grABC =
+ "ABX\u0394E\u03A6\u0393H" // ABCDEFGH
+ + "I_K\u039BMNO\u03A0" // I_KLMNOP
+ + "\u0398P\u03A3TY_\u03A9\u039E\u03A5Z"; // QRSTU_WXYZ
+ private final static String grabc =
+ "\u03B1\u03B2\u03C7\u03A4\u03A5\u03C6\u03B3\u03B7" // abcdefgh
+ + "\u03B9_\u03BA\u03BB\u03BC\u03BD\u03BF\u03C0" // i_klmnop
+ + "\u03B8\u03C1\u03C3\u03C4\u03C5_\u03C9\u03BE\u03C5\u03B6"; // qrstu_wxyz
+
+ /**
+ * Only translating the basic Greek set here, not all the other stuff. See
+ * http://www.iucr.org/resources/cif/spec/version1.1/semantics#markup
+ *
+ * @param data
+ * @return cleaned string
+ */
+ @Override
+ public String toUnicode(String data) {
+ int pt;
+ try {
+ while ((pt = data.indexOf('\\')) >= 0) {
+ int c = data.charAt(pt + 1);
+ String ch = (c >= 65 && c <= 90 ? grABC.substring(c - 65, c - 64)
+ : c >= 97 && c <= 122 ? grabc.substring(c - 97, c - 96) : "_");
+ data = data.substring(0, pt) + ch + data.substring(pt + 2);
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+
+ return data;
+ }
+
+ /**
+ * Passing an array of field names, this method fills two arrays.
+ * The first, fieldOf, identifies
+ * It does this by first creating a map of names to their indices in fields[].
+ *
+ * Alternatively, if fields is null, then a private array is filled, in order,
+ * with key data. This is used in cases such as matrices for which there are simply
+ * too many possibilities to list, and the key name itself contains the x-y
+ * information that we need.
+ *
+ */
+ @Override
+ public int parseLoopParameters(String[] fields, int[] fieldOf, int[] propertyOf) throws Exception {
+ int propertyCount = 0;
+ if (fields == null) {
+ // for reading full list of keys, as for matrices
+ this.fields = new String[100];
+ } else {
+ if (!htFields.containsKey(fields[0]))
+ for (int i = fields.length; --i >= 0;)
+ htFields.put(fields[i], Integer.valueOf(i));
+ for (int i = fields.length; --i >= 0;)
+ fieldOf[i] = NONE;
+ propertyCount = fields.length;
+ }
+ fieldCount = 0;
+ while (true) {
+ String str = peekToken();
+ if (str == null) {
+ // we are PREMATURELY done; reset
+ fieldCount = 0;
+ break;
+ }
+ // end of the loop is a new token starting with underscore
+ if (str.charAt(0) != '_')
+ break;
+
+ int pt = fieldCount++;
+ str = fixKey(getTokenPeeked());
+ if (fields == null) {
+ // just make a linear model, saving the list
+ this.fields[propertyOf[pt] = fieldOf[pt] = pt] = str;
+ continue;
+ }
+ Integer iField = htFields.get(str);
+ int i = (iField == null ? NONE : iField.intValue());
+ if ((propertyOf[pt] = i) != NONE)
+ fieldOf[i] = pt;
+ }
+ if (fieldCount > 0)
+ loopData = new String[fieldCount];
+ return propertyCount;
+ }
+
+ @Override
+ public String fixKey(String key) {
+ // PRELIMINARY -- BilBao _magnetic
+ // PRELIMINARY -- Jana2006
+ return (PT.rep(
+ key.startsWith("_magnetic") ? key.substring(9)
+ : key.startsWith("_jana") ? key.substring(5)
+ : key, ".", "_").toLowerCase());
+ }
+
+ //////////////////// private methods ////////////////////
+
+
+ /**
+ * sets a string to be parsed from the beginning
+ *
+ * @param str
+ */
+ private void setString(String str) {
+ this.str = line = str;
+ cch = (str == null ? 0 : str.length());
+ ich = 0;
+ }
+
+ /*
+ * http://www.iucr.org/resources/cif/spec/version1.1/cifsyntax
+ *
+ * 17. The special sequence of end-of-line followed
+ * immediately by a semicolon in column one (denoted "<eol>;")
+ * may also be used as a delimiter at the beginning and end
+ * of a character string comprising a data value. The complete
+ * bounded string is called a text field, and may be used to
+ * convey multi-line values. The end-of-line associated with
+ * the closing semicolon does not form part of the data value.
+ * Within a multi-line text field, leading white space within
+ * text lines must be retained as part of the data value; trailing
+ * white space on a line may however be elided.
+ *
+ * 18. A text field delimited by the <eol>; digraph may not
+ * include a semicolon at the start of a line of text as
+ * part of its value.
+ *
+ * 20. For example, the data value foo may be expressed
+ * equivalently as an unquoted string foo, as a quoted
+ * string 'foo' or as a text field
+ *
+ *;foo
+ *;
+ *
+ * By contrast the value of the text field
+ *
+ *; foo
+ * bar
+ *;
+ *
+ * is foo<eol> bar (where <eol> represents an end-of-line);
+ * the embedded space characters are significant.
+ *
+ *
+ * I (BH) note, however, that we sometimes have:
+ *
+ * _some_name
+ * ;
+ * the name here
+ * ;
+ *
+ * so this should actually be
+ *
+ * ;the name here
+ * ;
+ *
+ * for this, we use fullTrim();
+ *
+ */
+
+ /**
+ *
+ * sets the string for parsing to be from the next line
+ * when the token buffer is empty, and if ';' is at the
+ * beginning of that line, extends the string to include
+ * that full multiline string. Uses \1 to indicate that
+ * this is a special quotation.
+ *
+ * @return the next line or null if EOF
+ * @throws Exception
+ */
+ private String setStringNextLine() throws Exception {
+ setString(readLine());
+ if (line == null || line.length() == 0)
+ return line;
+ if (line.charAt(0) != ';') {
+ if (str.startsWith("###non-st#"))
+ ich = 10;
+ return line;
+ }
+ ich = 1;
+ String str = '\1' + line.substring(1) + '\n';
+ while (readLine() != null) {
+ if (line.startsWith(";")) {
+ // remove trailing <eol> only, and attach rest of next line
+ str = str.substring(0, str.length() - 1)
+ + '\1' + line.substring(1);
+ break;
+ }
+ str += line + '\n';
+ }
+ setString(str);
+ return str;
+ }
+
+ /**
+ * @return TRUE if there are more tokens in the line buffer
+ *
+ */
+ private boolean strHasMoreTokens() {
+ if (str == null)
+ return false;
+ char ch = '#';
+ while (ich < cch && ((ch = str.charAt(ich)) == ' ' || ch == '\t'))
+ ++ich;
+ return (ich < cch && ch != '#');
+ }
+
+ /**
+ * assume that hasMoreTokens() has been called and that
+ * ich is pointing at a non-white character. Also sets
+ * boolean wasUnQuoted, because we need to know if we should
+ * be checking for a control keyword. 'loop_' is different from just
+ * loop_ without the quotes.
+ *
+ * @return null if no more tokens, "\0" if '.' or '?', or next token
+ */
+ private String nextStrToken() {
+ if (ich == cch)
+ return null;
+ int ichStart = ich;
+ char ch = str.charAt(ichStart);
+ if (ch != '\'' && ch != '"' && ch != '\1') {
+ wasUnQuoted = true;
+ while (ich < cch && (ch = str.charAt(ich)) != ' ' && ch != '\t')
+ ++ich;
+ if (ich == ichStart + 1)
+ if (nullString != null && (str.charAt(ichStart) == '.' || str.charAt(ichStart) == '?'))
+ return nullString;
+ String s = str.substring(ichStart, ich);
+ return s;
+ }
+ wasUnQuoted = false;
+ char chOpeningQuote = ch;
+ boolean previousCharacterWasQuote = false;
+ while (++ich < cch) {
+ ch = str.charAt(ich);
+ if (previousCharacterWasQuote && (ch == ' ' || ch == '\t'))
+ break;
+ previousCharacterWasQuote = (ch == chOpeningQuote);
+ }
+ if (ich == cch) {
+ if (previousCharacterWasQuote) // close quote was last char of string
+ return str.substring(ichStart + 1, ich - 1);
+ // reached the end of the string without finding closing '
+ return str.substring(ichStart, ich);
+ }
+ ++ich; // throw away the last white character
+ return str.substring(ichStart + 1, ich - 2);
+ }
+
+
+}
\ No newline at end of file
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Copyright (C) 2011 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package javajs.util;
+
+
+class CompoundDocDirEntry {
+
+ private final CompoundDocument cd;
+
+ /**
+ * @param compoundDocument
+ */
+ CompoundDocDirEntry(CompoundDocument compoundDocument) {
+ cd = compoundDocument;
+ }
+
+ // 128 bytes
+ //offset 0:
+ byte[] unicodeName64 = new byte[64];
+ short nBytesUnicodeName; // twice the ascii length, including terminating 0
+ byte entryType; // 0 empty; 1 storage; 2 stream; 5 root storage
+ //byte entryColor; // 0 red or 1 black
+ //int DIDchildLeft;
+ //int DIDchildRight;
+ //int DIDstorageRoot;
+ byte[] uniqueID16 = new byte[16];
+ byte[] userflags4 = new byte[4];
+ //long timeStamp1;
+ //long timeStamp2;
+ //offset 116:
+ int SIDfirstSector; // either SAT or SSAT
+ int lenStream;
+ byte[] unused = new byte[8];
+
+ // derived:
+
+ String entryName;
+ boolean isStandard;
+ boolean isEmpty;
+
+ final boolean readData() {
+ try {
+ cd.readByteArray(unicodeName64, 0, 64);
+ nBytesUnicodeName = cd.readShort();
+ entryType = cd.readByte();
+ /*entryColor = */cd.readByte();
+ /*DIDchildLeft = */cd.readInt();
+ /*DIDchildRight = */cd.readInt();
+ /*DIDstorageRoot = */cd.readInt();
+ cd.readByteArray(uniqueID16, 0, 16);
+ cd.readByteArray(userflags4, 0, 4);
+ /*timeStamp1 = */ cd.readByteArray(unused, 0, 8);//cd.readLong();
+ /*timeStamp2 = */ cd.readByteArray(unused, 0, 8);//cd.readLong();
+ //offset 116:
+ SIDfirstSector = cd.readInt();
+ lenStream = cd.readInt();
+ cd.readByteArray(unused, 0, 4);
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ return false;
+ }
+ entryName = "";
+ for (int i = 0; i < nBytesUnicodeName - 2; i += 2)
+ entryName += (char) unicodeName64[i];
+ isStandard = (entryType == 5 || lenStream >= cd.header.minBytesStandardStream);
+ isEmpty = (entryType == 0 || lenStream <= 0);
+ //System.out.println(entryName + " type " + entryType);
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Copyright (C) 2011 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package javajs.util;
+
+
+class CompoundDocHeader {
+
+ /**
+ *
+ */
+ private final CompoundDocument cd;
+
+ /**
+ * @param compoundDocument
+ */
+ CompoundDocHeader(CompoundDocument compoundDocument) {
+ cd = compoundDocument;
+ }
+
+ //512 bytes
+ //offset 0:
+ byte[] magicNumbers = new byte[8]; // D0CF11E0A1B11AE1
+ byte[] uniqueID16 = new byte[16];
+ byte revNumber; // 3E = 62
+ //byte unusedb1;
+ byte verNumber; // 3
+ //byte unusedb2;
+ //short byteOrder; // -2 littleEndian
+ short sectorPower; // 2^sectorPower = sector size; 512 = 2^9
+ short shortSectorPower; // 2^shortSectorPower = short sector size; 64 = 2^6
+ byte[] unused = new byte[10];
+ int nSATsectors; // number of sectors for sector allocation table
+ int SID_DIR_start; // sector identifier of start of directory sector
+ //offset 56:
+ int minBytesStandardStream; // less than this (and not DIR) will be "short"
+ int SID_SSAT_start; // start of short sector allocation table (SSAT)
+ int nSSATsectors; // number of sectors allocated to SSAT
+ int SID_MSAT_next; // pointer to next master sector allocation table sector
+ int nAdditionalMATsectors; // number of sectors allocated to more MSAT sectors
+ //offset 76; 436 bytes:
+ int[] MSAT0 = new int[109]; // beginning of master allocation table
+
+ /*
+ * Sector 0 is first sector AFTER this header
+ *
+ * If sectorPower = 9, then this allows for 109 PAGES
+ * of sector allocation tables, with 127 pointers per
+ * page (plus 1 pointer to the next SAT page), each
+ * pointing to a sector of 512 bytes. Thus, with no additional
+ * MSAT pages, the header allows for 109*128*512 = 7.1 Mb file
+ *
+ */
+
+ final boolean readData() {
+ try {
+ cd.readByteArray(magicNumbers, 0, 8);
+ if (magicNumbers[0] != (byte) 0xD0 || magicNumbers[1] != (byte) 0xCF
+ || magicNumbers[2] != (byte) 0x11 || magicNumbers[3] != (byte) 0xE0
+ || magicNumbers[4] != (byte) 0xA1 || magicNumbers[5] != (byte) 0xB1
+ || magicNumbers[6] != (byte) 0x1A || magicNumbers[7] != (byte) 0xE1)
+ return false;
+ cd.readByteArray(uniqueID16, 0, 16);
+ revNumber = cd.readByte();
+ cd.readByte();
+ verNumber = cd.readByte();
+ cd.readByte();
+ byte b1 = cd.readByte();
+ byte b2 = cd.readByte();
+ cd.isBigEndian = (b1 == -1 && b2 == -2);
+ sectorPower = cd.readShort();
+ shortSectorPower = cd.readShort();
+ cd.readByteArray(unused, 0, 10);
+ nSATsectors = cd.readInt();
+ SID_DIR_start = cd.readInt();
+ cd.readByteArray(unused, 0, 4);
+ minBytesStandardStream = cd.readInt();
+ SID_SSAT_start = cd.readInt();
+ nSSATsectors = cd.readInt();
+ SID_MSAT_next = cd.readInt();
+ nAdditionalMATsectors = cd.readInt();
+ for (int i = 0; i < 109; i++)
+ MSAT0[i] = cd.readInt();
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ return false;
+ }
+ return true;
+ }
+}
\ No newline at end of file
--- /dev/null
+/* $RCSfile$
+ * $Author: egonw $
+ * $Date: 2006-03-18 15:59:33 -0600 (Sat, 18 Mar 2006) $
+ * $Revision: 4652 $
+ *
+ * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: hansonr@stolaf.edu
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.util;
+
+
+import java.io.DataInputStream;
+import java.io.BufferedInputStream;
+
+
+import java.util.Map;
+
+import javajs.api.GenericZipTools;
+
+
+
+/* a simple compound document reader.
+ * See http://sc.openoffice.org/compdocfileformat.pdf
+ *
+ * random access file info:
+ * http://java.sun.com/docs/books/tutorial/essential/io/rafs.html
+ *
+ * SHOOT! random access is only for applications, not applets!
+ *
+ * With a bit more work, this could be set up to deliver binary files, but
+ * right now I've only implemented it for string-based data. All Jmol is using
+ * is getAllData().
+ *
+ */
+
+public class CompoundDocument extends BinaryDocument{
+
+// RandomAccessFile file;
+ CompoundDocHeader header = new CompoundDocHeader(this);
+ Lst<CompoundDocDirEntry> directory = new Lst<CompoundDocDirEntry>();
+ CompoundDocDirEntry rootEntry;
+
+ int[] SAT;
+ int[] SSAT;
+ int sectorSize;
+ int shortSectorSize;
+ int nShortSectorsPerStandardSector;
+ int nIntPerSector;
+ int nDirEntriesperSector;
+
+ // called by reflection
+
+ public CompoundDocument(){
+ super();
+ this.isBigEndian = true;
+ }
+
+ @Override
+ public void setStream(GenericZipTools jzt, BufferedInputStream bis, boolean isBigEndian) {
+ // isBigEndian is ignored here; it must be true
+ /* try {
+ file = new RandomAccessFile(fileName, "r");
+ isRandom = true;
+ } catch (Exception e) {
+ // probably an applet
+ }
+ */
+ this.jzt = jzt;
+ if (!isRandom) {
+ stream = new DataInputStream(bis);
+ }
+ stream.mark(Integer.MAX_VALUE);
+ if (!readHeader())
+ return;
+ getSectorAllocationTable();
+ getShortSectorAllocationTable();
+ getDirectoryTable();
+ }
+
+ public Lst<CompoundDocDirEntry> getDirectory() {
+ return directory;
+ }
+
+ public String getDirectoryListing(String separator) {
+ String str = "";
+ for (int i = 0; i < directory.size(); i++) {
+ CompoundDocDirEntry thisEntry = directory.get(i);
+ if (!thisEntry.isEmpty)
+ str += separator
+ + thisEntry.entryName
+ + "\tlen="
+ + thisEntry.lenStream
+ + "\tSID="
+ + thisEntry.SIDfirstSector
+ + (thisEntry.isStandard ? "\tfileOffset="
+ + getOffset(thisEntry.SIDfirstSector) : "");
+ }
+ return str;
+ }
+
+ SB data;
+
+ public SB getAllData() {
+ return getAllDataFiles(null, null);
+ }
+
+ /**
+ * reads a compound document directory and saves all data in a Hashtable
+ * so that the files may be organized later in a different order. Also adds
+ * a #Directory_Listing entry.
+ *
+ * Files are bracketed by BEGIN Directory Entry and END Directory Entry lines,
+ * similar to ZipUtil.getAllData.
+ *
+ * @param prefix
+ * @param binaryFileList |-separated list of files that should be saved
+ * as xx xx xx hex byte strings. The directory listing
+ * is appended with ":asBinaryString"
+ * @param fileData
+ */
+ @Override
+ public void getAllDataMapped(String prefix,
+ String binaryFileList, Map<String, String> fileData) {
+ fileData.put("#Directory_Listing", getDirectoryListing("|"));
+ binaryFileList = "|" + binaryFileList + "|";
+ for (int i = 0; i < directory.size(); i++) {
+ CompoundDocDirEntry thisEntry = directory.get(i);
+ if (!thisEntry.isEmpty && thisEntry.entryType != 5) {
+ String name = thisEntry.entryName;
+ System.out.println("CompoundDocument file " + name);
+ boolean isBinary = (binaryFileList.indexOf("|" + name + "|") >= 0);
+ if (isBinary)
+ name += ":asBinaryString";
+ SB data = new SB();
+ data.append("BEGIN Directory Entry ").append(name).append("\n");
+ data.appendSB(getEntryAsString(thisEntry, isBinary));
+ data.append("\nEND Directory Entry ").append(name).append("\n");
+ fileData.put(prefix + "/" + name, data.toString());
+ }
+ }
+ close();
+ }
+
+ @Override
+ public SB getAllDataFiles(String binaryFileList, String firstFile) {
+ if (firstFile != null) {
+ for (int i = 0; i < directory.size(); i++) {
+ CompoundDocDirEntry thisEntry = directory.get(i);
+ if (thisEntry.entryName.equals(firstFile)) {
+ directory.remove(i);
+ directory.add(1, thisEntry); // after ROOT_ENTRY
+ break;
+ }
+ }
+ }
+ data = new SB();
+ data.append("Compound Document File Directory: ");
+ data.append(getDirectoryListing("|"));
+ data.append("\n");
+ binaryFileList = "|" + binaryFileList + "|";
+ for (int i = 0; i < directory.size(); i++) {
+ CompoundDocDirEntry thisEntry = directory.get(i);
+ //System.out.println("CompoundDocument reading " + thisEntry.entryName);
+ if (!thisEntry.isEmpty && thisEntry.entryType != 5) {
+ String name = thisEntry.entryName;
+ if (name.endsWith(".gz"))
+ name = name.substring(0, name.length() - 3);
+ data.append("BEGIN Directory Entry ").append(name).append("\n");
+ data.appendSB(getEntryAsString(thisEntry, binaryFileList.indexOf("|" + thisEntry.entryName + "|") >= 0));
+ data.append("\n");
+ data.append("END Directory Entry ").append(thisEntry.entryName).append("\n");
+ }
+ }
+ close();
+ return data;
+ }
+
+ public SB getFileAsString(String entryName) {
+ for (int i = 0; i < directory.size(); i++) {
+ CompoundDocDirEntry thisEntry = directory.get(i);
+ if (thisEntry.entryName.equals(entryName))
+ return getEntryAsString(thisEntry, false);
+ }
+ return new SB();
+ }
+
+ private long getOffset(int SID) {
+ return (SID + 1) * sectorSize;
+ }
+
+ private void gotoSector(int SID) {
+ seek(getOffset(SID));
+ }
+
+ private boolean readHeader() {
+ if (!header.readData())
+ return false;
+ sectorSize = 1 << header.sectorPower;
+ shortSectorSize = 1 << header.shortSectorPower;
+ nShortSectorsPerStandardSector = sectorSize / shortSectorSize; // e.g. 512 / 64 = 8
+ nIntPerSector = sectorSize / 4; // e.g. 512 / 4 = 128
+ nDirEntriesperSector = sectorSize / 128; // e.g. 512 / 128 = 4
+// System.out.println(
+// "compound document: revNum=" + header.revNumber +
+// " verNum=" + header.verNumber + " isBigEndian=" + isBigEndian +
+// " bytes per standard/short sector=" + sectorSize + "/" + shortSectorSize);
+ return true;
+ }
+
+ private void getSectorAllocationTable() {
+ int nSID = 0;
+ int thisSID;
+ SAT = new int[header.nSATsectors * nIntPerSector + 109];
+
+ try {
+ for (int i = 0; i < 109; i++) {
+ thisSID = header.MSAT0[i];
+ if (thisSID < 0)
+ break;
+ gotoSector(thisSID);
+ for (int j = 0; j < nIntPerSector; j++) {
+ SAT[nSID++] = readInt();
+ //Logger.debug(thisSID+"."+j + "/" + (nSID - 1) + " : " + SAT[nSID - 1]);
+ }
+ }
+ int nMaster = header.nAdditionalMATsectors;
+ thisSID = header.SID_MSAT_next;
+ int[] MSAT = new int[nIntPerSector];
+ out: while (nMaster-- > 0 && thisSID >= 0) {
+ // read a page of sector identifiers pointing to SAT sectors
+ gotoSector(thisSID);
+ for (int i = 0; i < nIntPerSector; i++)
+ MSAT[i] = readInt();
+ // read each page of SAT sector identifiers
+ // last entry is pointer to next master sector allocation table page
+ for (int i = 0; i < nIntPerSector - 1; i++) {
+ thisSID = MSAT[i];
+ if (thisSID < 0)
+ break out;
+ gotoSector(thisSID);
+ for (int j = nIntPerSector; --j >= 0;)
+ SAT[nSID++] = readInt();
+ }
+ thisSID = MSAT[nIntPerSector - 1];
+ }
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+
+ private void getShortSectorAllocationTable() {
+ int nSSID = 0;
+ int thisSID = header.SID_SSAT_start;
+ int nMax = header.nSSATsectors * nIntPerSector;
+ SSAT = new int[nMax];
+ try {
+ while (thisSID > 0 && nSSID < nMax) {
+ gotoSector(thisSID);
+ for (int j = 0; j < nIntPerSector; j++) {
+ SSAT[nSSID++] = readInt();
+ //System.out.println("short: " + thisSID+"."+j+" SSID=" +(nSSID-1)+" "+SSAT[nSSID-1]);
+ }
+ thisSID = SAT[thisSID];
+ }
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ }
+
+ private void getDirectoryTable() {
+ int thisSID = header.SID_DIR_start;
+ CompoundDocDirEntry thisEntry;
+ rootEntry = null;
+ try {
+ while (thisSID > 0) {
+ gotoSector(thisSID);
+ for (int j = nDirEntriesperSector; --j >= 0;) {
+ thisEntry = new CompoundDocDirEntry(this);
+ thisEntry.readData();
+ if (thisEntry.lenStream > 0) {
+ directory.addLast(thisEntry);
+ //System.out.println(thisEntry.entryName);
+ }
+ if (thisEntry.entryType == 5)
+ rootEntry = thisEntry;
+ }
+ thisSID = SAT[thisSID];
+ }
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+// System.out.println("CompoundDocument directory entry: \n"
+// + getDirectoryListing("\n"));
+ }
+
+ private SB getEntryAsString(CompoundDocDirEntry thisEntry, boolean asBinaryString) {
+ if(thisEntry.isEmpty)
+ return new SB();
+ //System.out.println(thisEntry.entryName + " " + thisEntry.entryType + " " + thisEntry.lenStream + " " + thisEntry.isStandard + " " + thisEntry.SIDfirstSector);
+ return (thisEntry.isStandard ? getStandardStringData(
+ thisEntry.SIDfirstSector, thisEntry.lenStream, asBinaryString)
+ : getShortStringData(thisEntry.SIDfirstSector, thisEntry.lenStream, asBinaryString));
+ }
+ private SB getStandardStringData(int thisSID, int nBytes,
+ boolean asBinaryString) {
+ SB data = new SB();
+ byte[] byteBuf = new byte[sectorSize];
+ ZipData gzipData = new ZipData(nBytes);
+ try {
+ while (thisSID > 0 && nBytes > 0) {
+ gotoSector(thisSID);
+ nBytes = getSectorData(data, byteBuf, sectorSize, nBytes, asBinaryString, gzipData);
+ thisSID = SAT[thisSID];
+ }
+ if (nBytes == -9999)
+ return new SB();
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ if (gzipData.isEnabled)
+ gzipData.addTo(jzt, data);
+ return data;
+ }
+
+ private int getSectorData(SB data, byte[] byteBuf,
+ int nSectorBytes, int nBytes,
+ boolean asBinaryString, ZipData gzipData)
+ throws Exception {
+ readByteArray(byteBuf, 0, byteBuf.length);
+ int n = gzipData.addBytes(byteBuf, nSectorBytes, nBytes);
+ if (n >= 0)
+ return n;
+ if (asBinaryString) {
+ for (int i = 0; i < nSectorBytes; i++) {
+ data.append(Integer.toHexString(byteBuf[i] & 0xFF)).appendC(' ');
+ if (--nBytes < 1)
+ break;
+ }
+ } else {
+ for (int i = 0; i < nSectorBytes; i++) {
+ if (byteBuf[i] == 0)
+ return -9999; // don't allow binary data
+ data.appendC((char) byteBuf[i]);
+ if (--nBytes < 1)
+ break;
+ }
+ }
+ return nBytes;
+ }
+
+ private SB getShortStringData(int shortSID, int nBytes, boolean asBinaryString) {
+ SB data = new SB();
+ if (rootEntry == null)
+ return data;
+ int thisSID = rootEntry.SIDfirstSector;
+ int ptShort = 0;
+ byte[] byteBuf = new byte[shortSectorSize];
+ ZipData gzipData = new ZipData(nBytes);
+ try {
+ //System.out.println("CD shortSID=" + shortSID);
+ // point to correct short data sector, 512/64 = 4 per page
+ while (thisSID >= 0 && shortSID >= 0 && nBytes > 0) {
+ while (shortSID - ptShort >= nShortSectorsPerStandardSector) {
+ ptShort += nShortSectorsPerStandardSector;
+ thisSID = SAT[thisSID];
+ }
+ seek(getOffset(thisSID) + (shortSID - ptShort) * shortSectorSize);
+ nBytes = getSectorData(data, byteBuf, shortSectorSize, nBytes, asBinaryString, gzipData);
+ shortSID = SSAT[shortSID];
+ //System.out.println("CD shortSID=" + shortSID);
+ }
+ } catch (Exception e) {
+ System.out.println(data.toString());
+ System.out.println("reader error in CompoundDocument " + e.toString());
+ }
+ if (gzipData.isEnabled)
+ gzipData.addTo(jzt, data);
+ return data;
+ }
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2007-04-26 16:57:51 -0500 (Thu, 26 Apr 2007) $
+ * $Revision: 7502 $
+ *
+ * Copyright (C) 2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package javajs.util;
+
+/**
+ * created to remove ambiguities and make a simpler DecimalFormat
+ */
+public class DF {
+
+ private final static String[] formattingStrings = { "0", "0.0", "0.00",
+ "0.000", "0.0000", "0.00000", "0.000000", "0.0000000", "0.00000000",
+ "0.000000000" };
+ private final static String zeros = "0000000000000000000000000000000000000000";
+
+ private final static float[] formatAdds = { 0.5f, 0.05f, 0.005f, 0.0005f,
+ 0.00005f, 0.000005f, 0.0000005f, 0.00000005f, 0.000000005f, 0.0000000005f };
+
+ private final static Boolean[] useNumberLocalization = new Boolean[] { Boolean.TRUE };
+
+ public static void setUseNumberLocalization(boolean TF) {
+ useNumberLocalization[0] = (TF ? Boolean.TRUE : Boolean.FALSE);
+ }
+
+ public static String formatDecimalDbl(double value, int decimalDigits) {
+ if (decimalDigits == Integer.MAX_VALUE
+ || value == Double.NEGATIVE_INFINITY
+ || value == Double.POSITIVE_INFINITY
+ || Double.isNaN(value))
+ return "" + value;
+ return DF.formatDecimal((float) value, decimalDigits);
+ }
+
+ /**
+ * a simple alternative to DecimalFormat (which Java2Script does not have
+ * and which is quite too complex for our use here.)
+ *
+ * @param value
+ * @param decimalDigits
+ * @return formatted decimal
+ */
+ public static String formatDecimal(float value, int decimalDigits) {
+ if (decimalDigits == Integer.MAX_VALUE
+ || value == Float.NEGATIVE_INFINITY || value == Float.POSITIVE_INFINITY || Float.isNaN(value))
+ return "" + value;
+ int n;
+ if (decimalDigits < 0) {
+ decimalDigits = -decimalDigits;
+ if (decimalDigits > formattingStrings.length)
+ decimalDigits = formattingStrings.length;
+ if (value == 0)
+ return formattingStrings[decimalDigits] + "E+0";
+ //scientific notation
+ n = 0;
+ double d;
+ if (Math.abs(value) < 1) {
+ n = 10;
+ d = value * 1e-10;
+ } else {
+ n = -10;
+ d = value * 1e10;
+ }
+ String s = ("" + d).toUpperCase();
+ int i = s.indexOf("E");
+ n = PT.parseInt(s.substring(i + 1)) + n;
+ return (i < 0 ? "" + value : formatDecimal(PT.parseFloat(s.substring(
+ 0, i)), decimalDigits - 1)
+ + "E" + (n >= 0 ? "+" : "") + n);
+ }
+
+ if (decimalDigits >= formattingStrings.length)
+ decimalDigits = formattingStrings.length - 1;
+ String s1 = ("" + value).toUpperCase();
+ int pt = s1.indexOf(".");
+ if (pt < 0) // specifically JavaScript "-2" not "-2.0"
+ return s1 + formattingStrings[decimalDigits].substring(1);
+ boolean isNeg = s1.startsWith("-");
+ if (isNeg) {
+ s1 = s1.substring(1);
+ pt--;
+ }
+ int pt1 = s1.indexOf("E-");
+ if (pt1 > 0) {
+ n = PT.parseInt(s1.substring(pt1 + 1));
+ // 3.567E-2
+ // 0.03567
+ s1 = "0." + zeros.substring(0, -n - 1) + s1.substring(0, 1) + s1.substring(2, pt1);
+ pt = 1;
+ }
+
+ pt1 = s1.indexOf("E");
+ // 3.5678E+3
+ // 3567.800000000
+ // 1.234E10 %3.8f -> 12340000000.00000000
+ if (pt1 > 0) {
+ n = PT.parseInt(s1.substring(pt1 + 1));
+ s1 = s1.substring(0, 1) + s1.substring(2, pt1) + zeros;
+ s1 = s1.substring(0, n + 1) + "." + s1.substring(n + 1);
+ pt = s1.indexOf(".");
+ }
+ // "234.345667 len == 10; pt = 3
+ // " 0.0 " decimalDigits = 1
+
+ int len = s1.length();
+ int pt2 = decimalDigits + pt + 1;
+ if (pt2 < len && s1.charAt(pt2) >= '5') {
+ return formatDecimal(
+ value + (isNeg ? -1 : 1) * formatAdds[decimalDigits], decimalDigits);
+ }
+
+ SB sb = SB.newS(s1.substring(0, (decimalDigits == 0 ? pt
+ : ++pt)));
+ for (int i = 0; i < decimalDigits; i++, pt++) {
+ if (pt < len)
+ sb.appendC(s1.charAt(pt));
+ else
+ sb.appendC('0');
+ }
+ s1 = (isNeg ? "-" : "") + sb;
+ return (Boolean.TRUE.equals(useNumberLocalization[0]) ? s1 : s1.replace(',',
+ '.'));
+ }
+
+ /**
+ * an alternative to DecimalFormat "0.#"
+ *
+ * @param x
+ * @param precision
+ * @return formatted number
+ */
+ public static String formatDecimalTrimmed(double x, int precision) {
+ String str = formatDecimalDbl(x, precision);
+ int m = str.length() - 1;
+ char zero = '0';
+ while (m >= 0 && str.charAt(m) == zero)
+ m--;
+ return str.substring(0, m + 1); // 0.##...
+ }
+
+}
--- /dev/null
+package javajs.util;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+
+/**
+ * Just a simple abstract class to join a String reader and a String[]
+ * reader under the same BufferedReader umbrella.
+ *
+ * Subclassed as StringDataReader, ArrayDataReader, and ListDataReader
+ *
+ */
+
+public abstract class DataReader extends BufferedReader {
+
+ public abstract DataReader setData(Object data);
+
+ protected int ptMark;
+
+ public DataReader() {
+ super(new StringReader(""));
+ }
+
+ protected DataReader(Reader in) {
+ super(in);
+ }
+
+ public BufferedReader getBufferedReader() {
+ return this;
+ }
+
+ protected int readBuf(char[] buf, int off, int len) throws IOException {
+ // not used by StringDataReader
+ int nRead = 0;
+ String line = readLine();
+ if (line == null)
+ return 0;
+ int linept = 0;
+ int linelen = line.length();
+ for (int i = off; i < len && linelen >= 0; i++) {
+ if (linept >= linelen) {
+ linept = 0;
+ buf[i] = '\n';
+ line = readLine();
+ linelen = (line == null ? -1 : line.length());
+ } else {
+ buf[i] = line.charAt(linept++);
+ }
+ nRead++;
+ }
+ return nRead;
+ }
+
+}
\ No newline at end of file
--- /dev/null
+/* $RCSfile$
+ * $Author: egonw $
+ * $Date: 2005-11-10 09:52:44f -0600 (Thu, 10 Nov 2005) $
+ * $Revision: 4255 $
+ *
+ * Copyright (C) 2003-2005 Miguel, Jmol Development, www.jmol.org
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package javajs.util;
+
+import javajs.api.EigenInterface;
+
+
+/**
+ * Eigenvalues and eigenvectors of a real matrix.
+ * See javajs.api.EigenInterface() as well.
+ *
+ * adapted by Bob Hanson from http://math.nist.gov/javanumerics/jama/ (public
+ * domain); adding quaternion superimposition capability; removing
+ * nonsymmetric reduction to Hessenberg form, which we do not need in Jmol.
+ *
+ * Output is as a set of double[n] columns, but for the EigenInterface
+ * we return them as V3[3] and float[3] (or double[3]) values.
+ *
+ * Eigenvalues and eigenvectors are sorted from smallest to largest eigenvalue.
+ *
+ * <P>
+ * If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is diagonal
+ * and the eigenvector matrix V is orthogonal. I.e. A =
+ * V.times(D.times(V.transpose())) and V.times(V.transpose()) equals the
+ * identity matrix.
+ * <P>
+ * If A is not symmetric, then the eigenvalue matrix D is block diagonal with
+ * the real eigenvalues in 1-by-1 blocks and any complex eigenvalues, lambda +
+ * i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda]. The columns of V represent
+ * the eigenvectors in the sense that A*V = V*D, i.e. A.times(V) equals
+ * V.times(D). The matrix V may be badly conditioned, or even singular, so the
+ * validity of the equation A = V*D*inverse(V) depends upon V.cond().
+ **/
+
+public class Eigen implements EigenInterface {
+
+ /* ------------------------
+ Public Methods
+ * ------------------------ */
+
+ public Eigen() {}
+
+ public Eigen set(int n) {
+ this.n = n;
+ V = new double[n][n];
+ d = new double[n];
+ e = new double[n];
+ return this;
+ }
+
+ @Override
+ public Eigen setM(double[][] m) {
+ set(m.length);
+ calc(m);
+ return this;
+ }
+
+ /**
+ * return values sorted from smallest to largest value.
+ */
+ @Override
+ public double[] getEigenvalues() {
+ return d;
+ }
+
+ /**
+ * Specifically for 3x3 systems, returns eigenVectors as V3[3]
+ * and values as float[3]; sorted from smallest to largest value.
+ *
+ * @param eigenVectors returned vectors
+ * @param eigenValues returned values
+ *
+ */
+ @Override
+ public void fillFloatArrays(V3[] eigenVectors, float[] eigenValues) {
+ for (int i = 0; i < 3; i++) {
+ if (eigenVectors != null) {
+ if (eigenVectors[i] == null)
+ eigenVectors[i] = new V3();
+ eigenVectors[i].set((float) V[0][i], (float) V[1][i], (float) V[2][i]);
+ }
+ if (eigenValues != null)
+ eigenValues[i] = (float) d[i];
+ }
+ }
+
+ /**
+ * Transpose V and turn into floats; sorted from smallest to largest value.
+ *
+ * @return ROWS of eigenvectors f[0], f[1], f[2], etc.
+ */
+ @Override
+ public float[][] getEigenvectorsFloatTransposed() {
+ float[][] f = new float[n][n];
+ for (int i = n; --i >= 0;)
+ for (int j = n; --j >= 0;)
+ f[j][i] = (float) V[i][j];
+ return f;
+ }
+
+
+ /**
+ * Check for symmetry, then construct the eigenvalue decomposition
+ *
+ * @param A
+ * Square matrix
+ */
+
+ public void calc(double[][] A) {
+
+ /* Jmol only has need of symmetric solutions
+ *
+ issymmetric = true;
+
+ for (int j = 0; (j < n) & issymmetric; j++) {
+ for (int i = 0; (i < n) & issymmetric; i++) {
+ issymmetric = (A[i][j] == A[j][i]);
+ }
+ }
+
+ if (issymmetric) {
+ */
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ V[i][j] = A[i][j];
+ }
+ }
+
+ // Tridiagonalize.
+ tred2();
+
+ // Diagonalize.
+ tql2();
+ /*
+ } else {
+ H = new double[n][n];
+ ort = new double[n];
+
+ for (int j = 0; j < n; j++) {
+ for (int i = 0; i < n; i++) {
+ H[i][j] = A[i][j];
+ }
+ }
+
+ // Reduce to Hessenberg form.
+ orthes();
+
+ // Reduce Hessenberg to real Schur form.
+ hqr2();
+ }
+ */
+
+ }
+
+ /**
+ * Return the real parts of the eigenvalues
+ *
+ * @return real(diag(D))
+ */
+
+ public double[] getRealEigenvalues() {
+ return d;
+ }
+
+ /**
+ * Return the imaginary parts of the eigenvalues
+ *
+ * @return imag(diag(D))
+ */
+
+ public double[] getImagEigenvalues() {
+ return e;
+ }
+
+ /* ------------------------
+ Class variables
+ * ------------------------ */
+
+ /**
+ * Row and column dimension (square matrix).
+ *
+ * @serial matrix dimension.
+ */
+ private int n = 3;
+
+ /**
+ * Symmetry flag.
+ *
+ * @serial internal symmetry flag.
+ */
+ //private boolean issymmetric = true;
+
+ /**
+ * Arrays for internal storage of eigenvalues.
+ *
+ * @serial internal storage of eigenvalues.
+ */
+ private double[] d, e;
+
+ /**
+ * Array for internal storage of eigenvectors.
+ *
+ * @serial internal storage of eigenvectors.
+ */
+ private double[][] V;
+
+ /**
+ * Array for internal storage of nonsymmetric Hessenberg form.
+ *
+ * @serial internal storage of nonsymmetric Hessenberg form.
+ */
+ //private double[][] H;
+
+ /**
+ * Working storage for nonsymmetric algorithm.
+ *
+ * @serial working storage for nonsymmetric algorithm.
+ */
+ //private double[] ort;
+
+ /* ------------------------
+ Private Methods
+ * ------------------------ */
+
+ // Symmetric Householder reduction to tridiagonal form.
+
+ private void tred2() {
+
+ // This is derived from the Algol procedures tred2 by
+ // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+ // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutine in EISPACK.
+
+ for (int j = 0; j < n; j++) {
+ d[j] = V[n - 1][j];
+ }
+
+ // Householder reduction to tridiagonal form.
+
+ for (int i = n - 1; i > 0; i--) {
+
+ // Scale to avoid under/overflow.
+
+ double scale = 0.0;
+ double h = 0.0;
+ for (int k = 0; k < i; k++) {
+ scale = scale + Math.abs(d[k]);
+ }
+ if (scale == 0.0) {
+ e[i] = d[i - 1];
+ for (int j = 0; j < i; j++) {
+ d[j] = V[i - 1][j];
+ V[i][j] = 0.0;
+ V[j][i] = 0.0;
+ }
+ } else {
+
+ // Generate Householder vector.
+
+ for (int k = 0; k < i; k++) {
+ d[k] /= scale;
+ h += d[k] * d[k];
+ }
+ double f = d[i - 1];
+ double g = Math.sqrt(h);
+ if (f > 0) {
+ g = -g;
+ }
+ e[i] = scale * g;
+ h = h - f * g;
+ d[i - 1] = f - g;
+ for (int j = 0; j < i; j++) {
+ e[j] = 0.0;
+ }
+
+ // Apply similarity transformation to remaining columns.
+
+ for (int j = 0; j < i; j++) {
+ f = d[j];
+ V[j][i] = f;
+ g = e[j] + V[j][j] * f;
+ for (int k = j + 1; k <= i - 1; k++) {
+ g += V[k][j] * d[k];
+ e[k] += V[k][j] * f;
+ }
+ e[j] = g;
+ }
+ f = 0.0;
+ for (int j = 0; j < i; j++) {
+ e[j] /= h;
+ f += e[j] * d[j];
+ }
+ double hh = f / (h + h);
+ for (int j = 0; j < i; j++) {
+ e[j] -= hh * d[j];
+ }
+ for (int j = 0; j < i; j++) {
+ f = d[j];
+ g = e[j];
+ for (int k = j; k <= i - 1; k++) {
+ V[k][j] -= (f * e[k] + g * d[k]);
+ }
+ d[j] = V[i - 1][j];
+ V[i][j] = 0.0;
+ }
+ }
+ d[i] = h;
+ }
+
+ // Accumulate transformations.
+
+ for (int i = 0; i < n - 1; i++) {
+ V[n - 1][i] = V[i][i];
+ V[i][i] = 1.0;
+ double h = d[i + 1];
+ if (h != 0.0) {
+ for (int k = 0; k <= i; k++) {
+ d[k] = V[k][i + 1] / h;
+ }
+ for (int j = 0; j <= i; j++) {
+ double g = 0.0;
+ for (int k = 0; k <= i; k++) {
+ g += V[k][i + 1] * V[k][j];
+ }
+ for (int k = 0; k <= i; k++) {
+ V[k][j] -= g * d[k];
+ }
+ }
+ }
+ for (int k = 0; k <= i; k++) {
+ V[k][i + 1] = 0.0;
+ }
+ }
+ for (int j = 0; j < n; j++) {
+ d[j] = V[n - 1][j];
+ V[n - 1][j] = 0.0;
+ }
+ V[n - 1][n - 1] = 1.0;
+ e[0] = 0.0;
+ }
+
+ // Symmetric tridiagonal QL algorithm.
+
+ private void tql2() {
+
+ // This is derived from the Algol procedures tql2, by
+ // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+ // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutine in EISPACK.
+
+ for (int i = 1; i < n; i++) {
+ e[i - 1] = e[i];
+ }
+ e[n - 1] = 0.0;
+
+ double f = 0.0;
+ double tst1 = 0.0;
+ double eps = Math.pow(2.0, -52.0);
+ for (int l = 0; l < n; l++) {
+
+ // Find small subdiagonal element
+
+ tst1 = Math.max(tst1, Math.abs(d[l]) + Math.abs(e[l]));
+ int m = l;
+ while (m < n) {
+ if (Math.abs(e[m]) <= eps * tst1) {
+ break;
+ }
+ m++;
+ }
+
+ // If m == l, d[l] is an eigenvalue,
+ // otherwise, iterate.
+
+ if (m > l) {
+ int iter = 0;
+ do {
+ iter = iter + 1; // (Could check iteration count here.)
+
+ // Compute implicit shift
+
+ double g = d[l];
+ double p = (d[l + 1] - g) / (2.0 * e[l]);
+ double r = hypot(p, 1.0);
+ if (p < 0) {
+ r = -r;
+ }
+ d[l] = e[l] / (p + r);
+ d[l + 1] = e[l] * (p + r);
+ double dl1 = d[l + 1];
+ double h = g - d[l];
+ for (int i = l + 2; i < n; i++) {
+ d[i] -= h;
+ }
+ f = f + h;
+
+ // Implicit QL transformation.
+
+ p = d[m];
+ double c = 1.0;
+ double c2 = c;
+ double c3 = c;
+ double el1 = e[l + 1];
+ double s = 0.0;
+ double s2 = 0.0;
+ for (int i = m - 1; i >= l; i--) {
+ c3 = c2;
+ c2 = c;
+ s2 = s;
+ g = c * e[i];
+ h = c * p;
+ r = hypot(p, e[i]);
+ e[i + 1] = s * r;
+ s = e[i] / r;
+ c = p / r;
+ p = c * d[i] - s * g;
+ d[i + 1] = h + s * (c * g + s * d[i]);
+
+ // Accumulate transformation.
+
+ for (int k = 0; k < n; k++) {
+ h = V[k][i + 1];
+ V[k][i + 1] = s * V[k][i] + c * h;
+ V[k][i] = c * V[k][i] - s * h;
+ }
+ }
+ p = -s * s2 * c3 * el1 * e[l] / dl1;
+ e[l] = s * p;
+ d[l] = c * p;
+
+ // Check for convergence.
+
+ } while (Math.abs(e[l]) > eps * tst1);
+ }
+ d[l] = d[l] + f;
+ e[l] = 0.0;
+ }
+
+ // Sort eigenvalues and corresponding vectors.
+
+ for (int i = 0; i < n - 1; i++) {
+ int k = i;
+ double p = d[i];
+ for (int j = i + 1; j < n; j++) {
+ if (d[j] < p) {
+ k = j;
+ p = d[j];
+ }
+ }
+ if (k != i) {
+ d[k] = d[i];
+ d[i] = p;
+ for (int j = 0; j < n; j++) {
+ p = V[j][i];
+ V[j][i] = V[j][k];
+ V[j][k] = p;
+ }
+ }
+ }
+ }
+
+ private static double hypot(double a, double b) {
+
+ // sqrt(a^2 + b^2) without under/overflow.
+
+ double r;
+ if (Math.abs(a) > Math.abs(b)) {
+ r = b / a;
+ r = Math.abs(a) * Math.sqrt(1 + r * r);
+ } else if (b != 0) {
+ r = a / b;
+ r = Math.abs(b) * Math.sqrt(1 + r * r);
+ } else {
+ r = 0.0;
+ }
+ return r;
+ }
+
+ // Nonsymmetric reduction to Hessenberg form.
+
+ /*
+ private void orthes() {
+
+ // This is derived from the Algol procedures orthes and ortran,
+ // by Martin and Wilkinson, Handbook for Auto. Comp.,
+ // Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutines in EISPACK.
+
+ int low = 0;
+ int high = n - 1;
+
+ for (int m = low + 1; m <= high - 1; m++) {
+
+ // Scale column.
+
+ double scale = 0.0;
+ for (int i = m; i <= high; i++) {
+ scale = scale + Math.abs(H[i][m - 1]);
+ }
+ if (scale != 0.0) {
+
+ // Compute Householder transformation.
+
+ double h = 0.0;
+ for (int i = high; i >= m; i--) {
+ ort[i] = H[i][m - 1] / scale;
+ h += ort[i] * ort[i];
+ }
+ double g = Math.sqrt(h);
+ if (ort[m] > 0) {
+ g = -g;
+ }
+ h = h - ort[m] * g;
+ ort[m] = ort[m] - g;
+
+ // Apply Householder similarity transformation
+ // H = (I-u*u'/h)*H*(I-u*u')/h)
+
+ for (int j = m; j < n; j++) {
+ double f = 0.0;
+ for (int i = high; i >= m; i--) {
+ f += ort[i] * H[i][j];
+ }
+ f = f / h;
+ for (int i = m; i <= high; i++) {
+ H[i][j] -= f * ort[i];
+ }
+ }
+
+ for (int i = 0; i <= high; i++) {
+ double f = 0.0;
+ for (int j = high; j >= m; j--) {
+ f += ort[j] * H[i][j];
+ }
+ f = f / h;
+ for (int j = m; j <= high; j++) {
+ H[i][j] -= f * ort[j];
+ }
+ }
+ ort[m] = scale * ort[m];
+ H[m][m - 1] = scale * g;
+ }
+ }
+
+ // Accumulate transformations (Algol's ortran).
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ V[i][j] = (i == j ? 1.0 : 0.0);
+ }
+ }
+
+ for (int m = high - 1; m >= low + 1; m--) {
+ if (H[m][m - 1] != 0.0) {
+ for (int i = m + 1; i <= high; i++) {
+ ort[i] = H[i][m - 1];
+ }
+ for (int j = m; j <= high; j++) {
+ double g = 0.0;
+ for (int i = m; i <= high; i++) {
+ g += ort[i] * V[i][j];
+ }
+ // Double division avoids possible underflow
+ g = (g / ort[m]) / H[m][m - 1];
+ for (int i = m; i <= high; i++) {
+ V[i][j] += g * ort[i];
+ }
+ }
+ }
+ }
+ }
+
+ // Complex scalar division.
+
+ private transient double cdivr, cdivi;
+
+ private void cdiv(double xr, double xi, double yr, double yi) {
+ double r, d;
+ if (Math.abs(yr) > Math.abs(yi)) {
+ r = yi / yr;
+ d = yr + r * yi;
+ cdivr = (xr + r * xi) / d;
+ cdivi = (xi - r * xr) / d;
+ } else {
+ r = yr / yi;
+ d = yi + r * yr;
+ cdivr = (r * xr + xi) / d;
+ cdivi = (r * xi - xr) / d;
+ }
+ }
+
+ // Nonsymmetric reduction from Hessenberg to real Schur form.
+
+ private void hqr2() {
+
+ // This is derived from the Algol procedure hqr2,
+ // by Martin and Wilkinson, Handbook for Auto. Comp.,
+ // Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutine in EISPACK.
+
+ // Initialize
+
+ int nn = this.n;
+ int n = nn - 1;
+ int low = 0;
+ int high = nn - 1;
+ double eps = Math.pow(2.0, -52.0);
+ double exshift = 0.0;
+ double p = 0, q = 0, r = 0, s = 0, z = 0, t, w, x, y;
+
+ // Store roots isolated by balanc and compute matrix norm
+
+ double norm = 0.0;
+ for (int i = 0; i < nn; i++) {
+ if (i < low || i > high) {
+ d[i] = H[i][i];
+ e[i] = 0.0;
+ }
+ for (int j = Math.max(i - 1, 0); j < nn; j++) {
+ norm = norm + Math.abs(H[i][j]);
+ }
+ }
+
+ // Outer loop over eigenvalue index
+
+ int iter = 0;
+ while (n >= low) {
+
+ // Look for single small sub-diagonal element
+
+ int l = n;
+ while (l > low) {
+ s = Math.abs(H[l - 1][l - 1]) + Math.abs(H[l][l]);
+ if (s == 0.0) {
+ s = norm;
+ }
+ if (Math.abs(H[l][l - 1]) < eps * s) {
+ break;
+ }
+ l--;
+ }
+
+ // Check for convergence
+ // One root found
+
+ if (l == n) {
+ H[n][n] = H[n][n] + exshift;
+ d[n] = H[n][n];
+ e[n] = 0.0;
+ n--;
+ iter = 0;
+
+ // Two roots found
+
+ } else if (l == n - 1) {
+ w = H[n][n - 1] * H[n - 1][n];
+ p = (H[n - 1][n - 1] - H[n][n]) / 2.0;
+ q = p * p + w;
+ z = Math.sqrt(Math.abs(q));
+ H[n][n] = H[n][n] + exshift;
+ H[n - 1][n - 1] = H[n - 1][n - 1] + exshift;
+ x = H[n][n];
+
+ // Real pair
+
+ if (q >= 0) {
+ if (p >= 0) {
+ z = p + z;
+ } else {
+ z = p - z;
+ }
+ d[n - 1] = x + z;
+ d[n] = d[n - 1];
+ if (z != 0.0) {
+ d[n] = x - w / z;
+ }
+ e[n - 1] = 0.0;
+ e[n] = 0.0;
+ x = H[n][n - 1];
+ s = Math.abs(x) + Math.abs(z);
+ p = x / s;
+ q = z / s;
+ r = Math.sqrt(p * p + q * q);
+ p = p / r;
+ q = q / r;
+
+ // Row modification
+
+ for (int j = n - 1; j < nn; j++) {
+ z = H[n - 1][j];
+ H[n - 1][j] = q * z + p * H[n][j];
+ H[n][j] = q * H[n][j] - p * z;
+ }
+
+ // Column modification
+
+ for (int i = 0; i <= n; i++) {
+ z = H[i][n - 1];
+ H[i][n - 1] = q * z + p * H[i][n];
+ H[i][n] = q * H[i][n] - p * z;
+ }
+
+ // Accumulate transformations
+
+ for (int i = low; i <= high; i++) {
+ z = V[i][n - 1];
+ V[i][n - 1] = q * z + p * V[i][n];
+ V[i][n] = q * V[i][n] - p * z;
+ }
+
+ // Complex pair
+
+ } else {
+ d[n - 1] = x + p;
+ d[n] = x + p;
+ e[n - 1] = z;
+ e[n] = -z;
+ }
+ n = n - 2;
+ iter = 0;
+
+ // No convergence yet
+
+ } else {
+
+ // Form shift
+
+ x = H[n][n];
+ y = 0.0;
+ w = 0.0;
+ if (l < n) {
+ y = H[n - 1][n - 1];
+ w = H[n][n - 1] * H[n - 1][n];
+ }
+
+ // Wilkinson's original ad hoc shift
+
+ if (iter == 10) {
+ exshift += x;
+ for (int i = low; i <= n; i++) {
+ H[i][i] -= x;
+ }
+ s = Math.abs(H[n][n - 1]) + Math.abs(H[n - 1][n - 2]);
+ x = y = 0.75 * s;
+ w = -0.4375 * s * s;
+ }
+
+ // MATLAB's new ad hoc shift
+
+ if (iter == 30) {
+ s = (y - x) / 2.0;
+ s = s * s + w;
+ if (s > 0) {
+ s = Math.sqrt(s);
+ if (y < x) {
+ s = -s;
+ }
+ s = x - w / ((y - x) / 2.0 + s);
+ for (int i = low; i <= n; i++) {
+ H[i][i] -= s;
+ }
+ exshift += s;
+ x = y = w = 0.964;
+ }
+ }
+
+ iter = iter + 1; // (Could check iteration count here.)
+
+ // Look for two consecutive small sub-diagonal elements
+
+ int m = n - 2;
+ while (m >= l) {
+ z = H[m][m];
+ r = x - z;
+ s = y - z;
+ p = (r * s - w) / H[m + 1][m] + H[m][m + 1];
+ q = H[m + 1][m + 1] - z - r - s;
+ r = H[m + 2][m + 1];
+ s = Math.abs(p) + Math.abs(q) + Math.abs(r);
+ p = p / s;
+ q = q / s;
+ r = r / s;
+ if (m == l) {
+ break;
+ }
+ if (Math.abs(H[m][m - 1]) * (Math.abs(q) + Math.abs(r)) < eps
+ * (Math.abs(p) * (Math.abs(H[m - 1][m - 1]) + Math.abs(z) + Math
+ .abs(H[m + 1][m + 1])))) {
+ break;
+ }
+ m--;
+ }
+
+ for (int i = m + 2; i <= n; i++) {
+ H[i][i - 2] = 0.0;
+ if (i > m + 2) {
+ H[i][i - 3] = 0.0;
+ }
+ }
+
+ // Double QR step involving rows l:n and columns m:n
+
+ for (int k = m; k <= n - 1; k++) {
+ boolean notlast = (k != n - 1);
+ if (k != m) {
+ p = H[k][k - 1];
+ q = H[k + 1][k - 1];
+ r = (notlast ? H[k + 2][k - 1] : 0.0);
+ x = Math.abs(p) + Math.abs(q) + Math.abs(r);
+ if (x != 0.0) {
+ p = p / x;
+ q = q / x;
+ r = r / x;
+ }
+ }
+ if (x == 0.0) {
+ break;
+ }
+ s = Math.sqrt(p * p + q * q + r * r);
+ if (p < 0) {
+ s = -s;
+ }
+ if (s != 0) {
+ if (k != m) {
+ H[k][k - 1] = -s * x;
+ } else if (l != m) {
+ H[k][k - 1] = -H[k][k - 1];
+ }
+ p = p + s;
+ x = p / s;
+ y = q / s;
+ z = r / s;
+ q = q / p;
+ r = r / p;
+
+ // Row modification
+
+ for (int j = k; j < nn; j++) {
+ p = H[k][j] + q * H[k + 1][j];
+ if (notlast) {
+ p = p + r * H[k + 2][j];
+ H[k + 2][j] = H[k + 2][j] - p * z;
+ }
+ H[k][j] = H[k][j] - p * x;
+ H[k + 1][j] = H[k + 1][j] - p * y;
+ }
+
+ // Column modification
+
+ for (int i = 0; i <= Math.min(n, k + 3); i++) {
+ p = x * H[i][k] + y * H[i][k + 1];
+ if (notlast) {
+ p = p + z * H[i][k + 2];
+ H[i][k + 2] = H[i][k + 2] - p * r;
+ }
+ H[i][k] = H[i][k] - p;
+ H[i][k + 1] = H[i][k + 1] - p * q;
+ }
+
+ // Accumulate transformations
+
+ for (int i = low; i <= high; i++) {
+ p = x * V[i][k] + y * V[i][k + 1];
+ if (notlast) {
+ p = p + z * V[i][k + 2];
+ V[i][k + 2] = V[i][k + 2] - p * r;
+ }
+ V[i][k] = V[i][k] - p;
+ V[i][k + 1] = V[i][k + 1] - p * q;
+ }
+ } // (s != 0)
+ } // k loop
+ } // check convergence
+ } // while (n >= low)
+
+ // Backsubstitute to find vectors of upper triangular form
+
+ if (norm == 0.0) {
+ return;
+ }
+
+ for (n = nn - 1; n >= 0; n--) {
+ p = d[n];
+ q = e[n];
+
+ // Real vector
+
+ if (q == 0) {
+ int l = n;
+ H[n][n] = 1.0;
+ for (int i = n - 1; i >= 0; i--) {
+ w = H[i][i] - p;
+ r = 0.0;
+ for (int j = l; j <= n; j++) {
+ r = r + H[i][j] * H[j][n];
+ }
+ if (e[i] < 0.0) {
+ z = w;
+ s = r;
+ } else {
+ l = i;
+ if (e[i] == 0.0) {
+ if (w != 0.0) {
+ H[i][n] = -r / w;
+ } else {
+ H[i][n] = -r / (eps * norm);
+ }
+
+ // Solve real equations
+
+ } else {
+ x = H[i][i + 1];
+ y = H[i + 1][i];
+ q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
+ t = (x * s - z * r) / q;
+ H[i][n] = t;
+ if (Math.abs(x) > Math.abs(z)) {
+ H[i + 1][n] = (-r - w * t) / x;
+ } else {
+ H[i + 1][n] = (-s - y * t) / z;
+ }
+ }
+
+ // Overflow control
+
+ t = Math.abs(H[i][n]);
+ if ((eps * t) * t > 1) {
+ for (int j = i; j <= n; j++) {
+ H[j][n] = H[j][n] / t;
+ }
+ }
+ }
+ }
+
+ // Complex vector
+
+ } else if (q < 0) {
+ int l = n - 1;
+
+ // Last vector component imaginary so matrix is triangular
+
+ if (Math.abs(H[n][n - 1]) > Math.abs(H[n - 1][n])) {
+ H[n - 1][n - 1] = q / H[n][n - 1];
+ H[n - 1][n] = -(H[n][n] - p) / H[n][n - 1];
+ } else {
+ cdiv(0.0, -H[n - 1][n], H[n - 1][n - 1] - p, q);
+ H[n - 1][n - 1] = cdivr;
+ H[n - 1][n] = cdivi;
+ }
+ H[n][n - 1] = 0.0;
+ H[n][n] = 1.0;
+ for (int i = n - 2; i >= 0; i--) {
+ double ra, sa, vr, vi;
+ ra = 0.0;
+ sa = 0.0;
+ for (int j = l; j <= n; j++) {
+ ra = ra + H[i][j] * H[j][n - 1];
+ sa = sa + H[i][j] * H[j][n];
+ }
+ w = H[i][i] - p;
+
+ if (e[i] < 0.0) {
+ z = w;
+ r = ra;
+ s = sa;
+ } else {
+ l = i;
+ if (e[i] == 0) {
+ cdiv(-ra, -sa, w, q);
+ H[i][n - 1] = cdivr;
+ H[i][n] = cdivi;
+ } else {
+
+ // Solve complex equations
+
+ x = H[i][i + 1];
+ y = H[i + 1][i];
+ vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
+ vi = (d[i] - p) * 2.0 * q;
+ if (vr == 0.0 & vi == 0.0) {
+ vr = eps
+ * norm
+ * (Math.abs(w) + Math.abs(q) + Math.abs(x) + Math.abs(y) + Math
+ .abs(z));
+ }
+ cdiv(x * r - z * ra + q * sa, x * s - z * sa - q * ra, vr, vi);
+ H[i][n - 1] = cdivr;
+ H[i][n] = cdivi;
+ if (Math.abs(x) > (Math.abs(z) + Math.abs(q))) {
+ H[i + 1][n - 1] = (-ra - w * H[i][n - 1] + q * H[i][n]) / x;
+ H[i + 1][n] = (-sa - w * H[i][n] - q * H[i][n - 1]) / x;
+ } else {
+ cdiv(-r - y * H[i][n - 1], -s - y * H[i][n], z, q);
+ H[i + 1][n - 1] = cdivr;
+ H[i + 1][n] = cdivi;
+ }
+ }
+
+ // Overflow control
+
+ t = Math.max(Math.abs(H[i][n - 1]), Math.abs(H[i][n]));
+ if ((eps * t) * t > 1) {
+ for (int j = i; j <= n; j++) {
+ H[j][n - 1] = H[j][n - 1] / t;
+ H[j][n] = H[j][n] / t;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Vectors of isolated roots
+
+ for (int i = 0; i < nn; i++) {
+ if (i < low || i > high) {
+ for (int j = i; j < nn; j++) {
+ V[i][j] = H[i][j];
+ }
+ }
+ }
+
+ // Back transformation to get eigenvectors of original matrix
+
+ for (int j = nn - 1; j >= low; j--) {
+ for (int i = low; i <= high; i++) {
+ z = 0.0;
+ for (int k = low; k <= Math.min(j, high); k++) {
+ z = z + V[i][k] * H[k][j];
+ }
+ V[i][j] = z;
+ }
+ }
+ }
+ */
+
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Copyright (C) 2011 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package javajs.util;
+
+public enum Encoding {
+ NONE, UTF8, UTF_16BE, UTF_16LE, UTF_32BE, UTF_32LE
+}
\ No newline at end of file
--- /dev/null
+package javajs.util;
+
+import java.io.BufferedReader;
+
+/**
+ * A simple class to read a designated number of bytes from a
+ * file and then return them line by line, skipping lines that
+ * start with #, and including the \n or \r characters at line ends.
+ *
+ * Generally useful for determining what sort of data a file contains.
+ *
+ */
+public class LimitedLineReader {
+ private char[] buf;
+ private int cchBuf;
+ private int ichCurrent;
+
+ public LimitedLineReader(BufferedReader bufferedReader, int readLimit)
+ throws Exception {
+ bufferedReader.mark(readLimit + 1);
+ buf = new char[readLimit];
+ cchBuf = Math.max(bufferedReader.read(buf, 0, readLimit), 0);
+ ichCurrent = 0;
+ bufferedReader.reset();
+ }
+
+ public String getHeader(int n) {
+ return (n == 0 ? new String(buf) : new String(buf, 0, Math.min(cchBuf, n)));
+ }
+
+ public String readLineWithNewline() {
+ while (ichCurrent < cchBuf) {
+ int ichBeginningOfLine = ichCurrent;
+ char ch = 0;
+ while (ichCurrent < cchBuf &&
+ (ch = buf[ichCurrent++]) != '\r' && ch != '\n') {
+ }
+ if (ch == '\r' && ichCurrent < cchBuf && buf[ichCurrent] == '\n')
+ ++ichCurrent;
+ int cchLine = ichCurrent - ichBeginningOfLine;
+ if (buf[ichBeginningOfLine] == '#')
+ continue; // flush comment lines;
+ return new String(buf, ichBeginningOfLine, cchLine);
+ }
+ return "";
+ }
+}
+
--- /dev/null
+package javajs.util;
+
+import java.io.IOException;
+
+
+
+
+
+/**
+ *
+ * VectorDataReader subclasses BufferedReader and overrides its
+ * read, readLine, mark, and reset methods so that JmolAdapter
+ * works with Vector<String> arrays without any further adaptation.
+ *
+ */
+
+public class ListDataReader extends DataReader {
+ private Lst<String> data;
+ private int pt;
+ private int len;
+
+ public ListDataReader() {
+ super();
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public DataReader setData(Object data) {
+ this.data = (Lst<String>) data;
+ len = this.data.size();
+ return this;
+ }
+
+ @Override
+ public int read(char[] buf, int off, int len) throws IOException {
+ return readBuf(buf, off, len);
+ }
+
+ @Override
+ public String readLine() {
+ return (pt < len ? data.get(pt++) : null);
+ }
+
+ /**
+ *
+ * @param ptr
+ */
+ public void mark(long ptr) {
+ //ignore ptr.
+ ptMark = pt;
+ }
+
+ @Override
+ public void reset() {
+ pt = ptMark;
+ }
+}
\ No newline at end of file
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2007-04-26 16:57:51 -0500 (Thu, 26 Apr 2007) $
+ * $Revision: 7502 $
+ *
+ * Copyright (C) 2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package javajs.util;
+
+import java.util.ArrayList;
+
+/**
+ * created to remove ambiguities in add and remove
+ *
+ * @param <V>
+ */
+public class Lst<V> extends ArrayList<V> {
+
+ public Lst() {
+ super();
+ }
+
+ /**
+ * @j2sIgnore
+ *
+ */
+ @Override
+ @Deprecated
+ public boolean add(V v) {
+ throw new NullPointerException("use addLast(value), not add(value) in List for JavaScript compatibility");
+ }
+
+ public boolean addLast(V v) {
+ /**
+ * no overloading of add(Object) in JavaScript
+ *
+ * @j2sNative
+ *
+ * return this.add1(v);
+ *
+ */
+ {
+ return super.add(v);
+ }
+ }
+
+ /**
+ * @j2sIgnore
+ *
+ */
+ @Override
+ @Deprecated
+ public boolean remove(Object v) {
+ throw new NullPointerException("use removeObj(obj), not remove(obj) in List for JavaScript compatibility");
+ }
+
+ public boolean removeObj(Object v) {
+ /**
+ * no overloading of remove(Object) in JavaScript
+ *
+ * @j2sNative
+ *
+ * return this.removeObject(v);
+ *
+ */
+ {
+ return super.remove(v);
+ }
+ }
+
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+import java.io.Serializable;
+
+
+
+/**
+ * A single precision floating point 3 by 3 matrix.
+ *
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
+ * constructor and method names for the optimization of compiled
+ * JavaScript using Java2Script
+ *
+ *
+ */
+public class M3 extends M34 implements Serializable {
+
+ /**
+ * Constructs and initializes a Matrix3f to all zeros.
+ * @j2sIgnore
+ */
+ public M3() {
+ }
+
+ /**
+ * Constructs and initializes a Matrix3f from the specified 9 element array.
+ * this.m00 =v[0], this.m01=v[1], etc.
+ *
+ * @param v
+ * the array of length 9 containing in order
+ * @return m
+ */
+ public static M3 newA9(float[] v) {
+ M3 m = new M3();
+ m.setA(v);
+ return m;
+ }
+
+ /**
+ * Constructs a new matrix with the same values as the Matrix3f parameter.
+ *
+ * @param m1
+ * The source matrix.
+ * @return m
+ */
+ public static M3 newM3(M3 m1) {
+ M3 m = new M3();
+ if (m1 == null) {
+ m.setScale(1);
+ return m;
+ }
+ m.m00 = m1.m00;
+ m.m01 = m1.m01;
+ m.m02 = m1.m02;
+
+ m.m10 = m1.m10;
+ m.m11 = m1.m11;
+ m.m12 = m1.m12;
+
+ m.m20 = m1.m20;
+ m.m21 = m1.m21;
+ m.m22 = m1.m22;
+ return m;
+ }
+
+ /**
+ * Sets this Matrix3f to a scalar * Identity.
+ * @param scale
+ */
+ public void setScale(float scale) {
+ clear33();
+ m00 = m11 = m22 = scale;
+ }
+
+ /**
+ * Sets the value of this matrix to the double value of the Matrix3f argument.
+ *
+ * @param m1
+ * the matrix3f
+ */
+ public void setM3(M34 m1) {
+ setM33(m1);
+ }
+ /**
+ * Sets the values in this Matrix3f equal to the row-major array parameter
+ * (ie, the first four elements of the array will be copied into the first row
+ * of this matrix, etc.).
+ *
+ * @param m
+ */
+ public void setA(float m[]) {
+ m00 = m[0];
+ m01 = m[1];
+ m02 = m[2];
+ m10 = m[3];
+ m11 = m[4];
+ m12 = m[5];
+ m20 = m[6];
+ m21 = m[7];
+ m22 = m[8];
+ }
+
+ /**
+ * Sets the specified element of this matrix3d to the value provided.
+ *
+ * @param row
+ * the row number to be modified (zero indexed)
+ * @param col
+ * the column number to be modified (zero indexed)
+ * @param v
+ * the new value
+ */
+ public void setElement(int row, int col, float v) {
+ set33(row, col, v);
+ }
+
+ /**
+ * Retrieves the value at the specified row and column of this matrix.
+ *
+ * @param row
+ * the row number to be retrieved (zero indexed)
+ * @param col
+ * the column number to be retrieved (zero indexed)
+ * @return the value at the indexed element
+ */
+ public float getElement(int row, int col) {
+ return get33(row, col);
+ }
+
+ /**
+ * Sets the specified row of this matrix3d to the three values provided.
+ *
+ * @param row
+ * the row number to be modified (zero indexed)
+ * @param x
+ * the first column element
+ * @param y
+ * the second column element
+ * @param z
+ * the third column element
+ */
+ public void setRow(int row, float x, float y, float z) {
+ switch (row) {
+ case 0:
+ m00 = x;
+ m01 = y;
+ m02 = z;
+ return;
+ case 1:
+ m10 = x;
+ m11 = y;
+ m12 = z;
+ return;
+ case 2:
+ m20 = x;
+ m21 = y;
+ m22 = z;
+ return;
+ default:
+ err();
+ }
+ }
+
+ /**
+ * Sets the specified row of this matrix3d to the Vector provided.
+ *
+ * @param row
+ * the row number to be modified (zero indexed)
+ * @param v
+ * the replacement row
+ */
+ public void setRowV(int row, T3 v) {
+ switch (row) {
+ case 0:
+ m00 = v.x;
+ m01 = v.y;
+ m02 = v.z;
+ return;
+ case 1:
+ m10 = v.x;
+ m11 = v.y;
+ m12 = v.z;
+ return;
+ case 2:
+ m20 = v.x;
+ m21 = v.y;
+ m22 = v.z;
+ return;
+ default:
+ err();
+ }
+ }
+
+ /**
+ * Sets the specified row of this matrix3d to the four values provided.
+ *
+ * @param row
+ * the row number to be modified (zero indexed)
+ * @param v
+ * the replacement row
+ */
+ public void setRowA(int row, float v[]) {
+ setRow33(row, v);
+ }
+
+ /**
+ * Copies the matrix values in the specified row into the array parameter.
+ *
+ * @param row
+ * the matrix row
+ * @param v
+ * The array into which the matrix row values will be copied
+ */
+ @Override
+ public void getRow(int row, float v[]) {
+ getRow33(row, v);
+ }
+
+ /**
+ * Sets the specified column of this matrix3d to the three values provided.
+ *
+ * @param column
+ * the column number to be modified (zero indexed)
+ * @param x
+ * the first row element
+ * @param y
+ * the second row element
+ * @param z
+ * the third row element
+ */
+ public void setColumn3(int column, float x, float y, float z) {
+ switch (column) {
+ case 0:
+ m00 = x;
+ m10 = y;
+ m20 = z;
+ break;
+ case 1:
+ m01 = x;
+ m11 = y;
+ m21 = z;
+ break;
+ case 2:
+ m02 = x;
+ m12 = y;
+ m22 = z;
+ break;
+ default:
+ err();
+ }
+ }
+
+ /**
+ * Sets the specified column of this matrix3d to the vector provided.
+ *
+ * @param column
+ * the column number to be modified (zero indexed)
+ * @param v
+ * the replacement column
+ */
+ public void setColumnV(int column, T3 v) {
+ switch (column) {
+ case 0:
+ m00 = v.x;
+ m10 = v.y;
+ m20 = v.z;
+ break;
+ case 1:
+ m01 = v.x;
+ m11 = v.y;
+ m21 = v.z;
+ break;
+ case 2:
+ m02 = v.x;
+ m12 = v.y;
+ m22 = v.z;
+ break;
+ default:
+ err();
+ }
+ }
+
+ /**
+ * Copies the matrix values in the specified column into the vector parameter.
+ *
+ * @param column
+ * the matrix column
+ * @param v
+ * The vector into which the matrix row values will be copied
+ */
+ public void getColumnV(int column, T3 v) {
+ switch (column) {
+ case 0:
+ v.x = m00;
+ v.y = m10;
+ v.z = m20;
+ break;
+ case 1:
+ v.x = m01;
+ v.y = m11;
+ v.z = m21;
+ break;
+ case 2:
+ v.x = m02;
+ v.y = m12;
+ v.z = m22;
+ break;
+ default:
+ err();
+ }
+ }
+
+ /**
+ * Sets the specified column of this matrix3d to the four values provided.
+ *
+ * @param column
+ * the column number to be modified (zero indexed)
+ * @param v
+ * the replacement column
+ */
+ public void setColumnA(int column, float v[]) {
+ setColumn33(column, v);
+ }
+
+ /**
+ * Copies the matrix values in the specified column into the array parameter.
+ *
+ * @param column
+ * the matrix column
+ * @param v
+ * The array into which the matrix row values will be copied
+ */
+ public void getColumn(int column, float v[]) {
+ getColumn33(column, v);
+ }
+
+ /**
+ * Sets the value of this matrix to sum of itself and matrix m1.
+ *
+ * @param m1
+ * the other matrix
+ */
+ public void add(M3 m1) {
+ add33(m1);
+ }
+
+ /**
+ * Sets the value of this matrix to the matrix difference of itself and matrix
+ * m1 (this = this - m1).
+ *
+ * @param m1
+ * the other matrix
+ */
+ public void sub(M3 m1) {
+ sub33(m1);
+ }
+
+ /**
+ * Sets the value of this matrix to its transpose.
+ */
+ public void transpose() {
+ transpose33();
+ }
+
+ /**
+ * Sets the value of this matrix to the transpose of the argument matrix
+ *
+ * @param m1
+ * the matrix to be transposed
+ */
+ public void transposeM(M3 m1) {
+ // alias-safe
+ setM33(m1);
+ transpose33();
+ }
+
+ /**
+ * Sets the value of this matrix to the matrix inverse of the passed matrix
+ * m1.
+ *
+ * @param m1
+ * the matrix to be inverted
+ */
+ public void invertM(M3 m1) {
+ setM33(m1);
+ invert();
+ }
+
+ /**
+ * Sets the value of this matrix to its inverse.
+ */
+ public void invert() {
+ double s = determinant3();
+ if (s == 0.0)
+ return;
+ s = 1 / s;
+ // alias-safe way.
+ set9(m11 * m22 - m12 * m21, m02 * m21 - m01 * m22, m01 * m12 - m02 * m11,
+ m12 * m20 - m10 * m22, m00 * m22 - m02 * m20, m02 * m10 - m00 * m12,
+ m10 * m21 - m11 * m20, m01 * m20 - m00 * m21, m00 * m11 - m01 * m10);
+ scale((float) s);
+ }
+
+ /**
+ * Sets the value of this matrix to a rotation matrix about the x axis by the
+ * passed angle.
+ *
+ * @param angle
+ * the angle to rotate about the X axis in radians
+ * @return this
+ */
+ public M3 setAsXRotation(float angle) {
+ setXRot(angle);
+ return this;
+ }
+
+ /**
+ * Sets the value of this matrix to a rotation matrix about the y axis by the
+ * passed angle.
+ *
+ * @param angle
+ * the angle to rotate about the Y axis in radians
+ * @return this
+ */
+ public M3 setAsYRotation(float angle) {
+ setYRot(angle);
+ return this;
+ }
+
+ /**
+ * Sets the value of this matrix to a rotation matrix about the z axis by the
+ * passed angle.
+ *
+ * @param angle
+ * the angle to rotate about the Z axis in radians
+ * @return this
+ */
+ public M3 setAsZRotation(float angle) {
+ setZRot(angle);
+ return this;
+ }
+
+ /**
+ * Multiplies each element of this matrix by a scalar.
+ *
+ * @param scalar
+ * The scalar multiplier.
+ */
+ public void scale(float scalar) {
+ mul33(scalar);
+ }
+
+ /**
+ * Sets the value of this matrix to the result of multiplying itself with
+ * matrix m1.
+ *
+ * @param m1
+ * the other matrix
+ */
+ public void mul(M3 m1) {
+ mul2(this, m1);
+ }
+
+ /**
+ * Sets the value of this matrix to the result of multiplying the two argument
+ * matrices together.
+ *
+ * @param m1
+ * the first matrix
+ * @param m2
+ * the second matrix
+ */
+ public void mul2(M3 m1, M3 m2) {
+ // alias-safe way.
+ set9(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20, m1.m00 * m2.m01
+ + m1.m01 * m2.m11 + m1.m02 * m2.m21, m1.m00 * m2.m02 + m1.m01 * m2.m12
+ + m1.m02 * m2.m22,
+
+ m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20, m1.m10 * m2.m01
+ + m1.m11 * m2.m11 + m1.m12 * m2.m21, m1.m10 * m2.m02 + m1.m11 * m2.m12
+ + m1.m12 * m2.m22,
+
+ m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20, m1.m20 * m2.m01
+ + m1.m21 * m2.m11 + m1.m22 * m2.m21, m1.m20 * m2.m02 + m1.m21 * m2.m12
+ + m1.m22 * m2.m22);
+ }
+
+ /**
+ * Returns true if the Object o is of type Matrix3f and all of the data
+ * members of t1 are equal to the corresponding data members in this Matrix3f.
+ *
+ * @param o
+ * the object with which the comparison is made.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof M3))
+ return false;
+ M3 m = (M3) o;
+ return m00 == m.m00 && m01 == m.m01 && m02 == m.m02 && m10 == m.m10
+ && m11 == m.m11 && m12 == m.m12 && m20 == m.m20 && m21 == m.m21
+ && m22 == m.m22;
+ }
+
+ /**
+ * Returns a hash number based on the data values in this object. Two
+ * different Matrix3f objects with identical data values (ie, returns true for
+ * equals(Matrix3f) ) will return the same hash number. Two objects with
+ * different data members may return the same hash value, although this is not
+ * likely.
+ *
+ * @return the integer hash value
+ */
+ @Override
+ public int hashCode() {
+ return T3.floatToIntBits0(m00) ^ T3.floatToIntBits0(m01)
+ ^ T3.floatToIntBits0(m02) ^ T3.floatToIntBits0(m10)
+ ^ T3.floatToIntBits0(m11) ^ T3.floatToIntBits0(m12)
+ ^ T3.floatToIntBits0(m20) ^ T3.floatToIntBits0(m21)
+ ^ T3.floatToIntBits0(m22);
+ }
+
+ /**
+ * Sets this matrix to all zeros.
+ */
+ public void setZero() {
+ clear33();
+ }
+
+ /**
+ * Sets 9 values
+ *
+ * @param m00
+ * @param m01
+ * @param m02
+ * @param m10
+ * @param m11
+ * @param m12
+ * @param m20
+ * @param m21
+ * @param m22
+ */
+ private void set9(float m00, float m01, float m02, float m10, float m11,
+ float m12, float m20, float m21, float m22) {
+ this.m00 = m00;
+ this.m01 = m01;
+ this.m02 = m02;
+ this.m10 = m10;
+ this.m11 = m11;
+ this.m12 = m12;
+ this.m20 = m20;
+ this.m21 = m21;
+ this.m22 = m22;
+ }
+
+ /**
+ * Returns a string that contains the values of this Matrix3f.
+ *
+ * @return the String representation
+ */
+ @Override
+ public String toString() {
+ return "[\n [" + m00 + "\t" + m01 + "\t" + m02 + "]" + "\n [" + m10
+ + "\t" + m11 + "\t" + m12 + "]" + "\n [" + m20 + "\t" + m21 + "\t"
+ + m22 + "] ]";
+ }
+
+ /**
+ * Sets the value of this matrix to the matrix conversion of the single
+ * precision axis and angle argument.
+ *
+ * @param a
+ * the axis and angle to be converted
+ * @return this
+ */
+ public M3 setAA(A4 a) {
+ setAA33(a);
+ return this;
+ }
+
+ /**
+ * 3D ball rotation from dx dy in-plane mouse motion
+ * adapted from Andrew Hanson
+ * Computer Graphics beyond the Third Dimension:
+ * Geometry, Orientation Control, and Rendering for
+ * Graphics in Dimensions Greater than Three
+ * Course Notes for SIGGRAPH ’98
+ * http://www.cse.ohio-state.edu/~hwshen/888_su02/hanson_note.pdf
+ *
+ * @param responseFactor Jmol uses 0.02 here
+ * @param dx
+ * @param dy
+ * @return true if successful; false if not;
+ */
+ public boolean setAsBallRotation(float responseFactor, float dx, float dy) {
+ float r = (float) Math.sqrt(dx * dx + dy * dy);
+ float th = r * responseFactor;
+ if (th == 0) {
+ setScale(1);
+ return false;
+ }
+ float c = (float) Math.cos(th);
+ float s = (float) Math.sin(th);
+ float nx = -dy / r;
+ float ny = dx / r;
+ float c1 = c - 1;
+ m00 = 1 + c1 * nx * nx;
+ m01 = m10 = c1 * nx * ny;
+ m20 = -(m02 = s * nx);
+ m11 = 1 + c1 * ny * ny;
+ m21 = -(m12 = s * ny);
+ m22 = c;
+ return true;
+ }
+
+ public boolean isRotation() {
+ return (Math.abs(determinant3() - 1) < 0.001f);
+ }
+
+}
--- /dev/null
+package javajs.util;
+
+/**
+ * A base class for both M3 and M4 to conserve code size.
+ *
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
+ * constructor and method names for the optimization of compiled
+ * JavaScript using Java2Script and for subclassing to M3 and M4
+ *
+ */
+public abstract class M34 {
+
+ /**
+ * The first element of the first row
+ */
+ public float m00;
+
+ /**
+ * The second element of the first row.
+ */
+ public float m01;
+
+ /**
+ * third element of the first row.
+ */
+ public float m02;
+
+ /**
+ * The first element of the second row.
+ */
+ public float m10;
+
+ /**
+ * The second element of the second row.
+ */
+ public float m11;
+
+ /**
+ * The third element of the second row.
+ */
+ public float m12;
+
+ /**
+ * The first element of the third row.
+ */
+ public float m20;
+
+ /**
+ * The second element of the third row.
+ */
+ public float m21;
+
+ /**
+ * The third element of the third row.
+ */
+ public float m22;
+
+ protected void setAA33(A4 a) {
+ double x = a.x;
+ double y = a.y;
+ double z = a.z;
+ double angle = a.angle;
+ // Taken from Rick's which is taken from Wertz. pg. 412
+ // Bug Fixed and changed into right-handed by hiranabe
+ double n = Math.sqrt(x * x + y * y + z * z);
+ // zero-div may occur
+ n = 1 / n;
+ x *= n;
+ y *= n;
+ z *= n;
+ double c = Math.cos(angle);
+ double s = Math.sin(angle);
+ double omc = 1.0 - c;
+ m00 = (float) (c + x * x * omc);
+ m11 = (float) (c + y * y * omc);
+ m22 = (float) (c + z * z * omc);
+
+ double tmp1 = x * y * omc;
+ double tmp2 = z * s;
+ m01 = (float) (tmp1 - tmp2);
+ m10 = (float) (tmp1 + tmp2);
+
+ tmp1 = x * z * omc;
+ tmp2 = y * s;
+ m02 = (float) (tmp1 + tmp2);
+ m20 = (float) (tmp1 - tmp2);
+
+ tmp1 = y * z * omc;
+ tmp2 = x * s;
+ m12 = (float) (tmp1 - tmp2);
+ m21 = (float) (tmp1 + tmp2);
+ }
+
+ public void rotate(T3 t) {
+ // alias-safe
+ rotate2(t, t);
+ }
+
+ /**
+ * Transform the vector vec using this Matrix3f and place the result into
+ * vecOut.
+ *
+ * @param t
+ * the single precision vector to be transformed
+ * @param result
+ * the vector into which the transformed values are placed
+ */
+ public void rotate2(T3 t, T3 result) {
+ // alias-safe
+ result.set(m00 * t.x + m01 * t.y + m02 * t.z, m10 * t.x + m11 * t.y + m12
+ * t.z, m20 * t.x + m21 * t.y + m22 * t.z);
+ }
+
+
+ /**
+ * Sets the value of this matrix to the double value of the Matrix3f argument.
+ *
+ * @param m1
+ * the matrix3f
+ */
+ protected void setM33(M34 m1) {
+ m00 = m1.m00;
+ m01 = m1.m01;
+ m02 = m1.m02;
+ m10 = m1.m10;
+ m11 = m1.m11;
+ m12 = m1.m12;
+ m20 = m1.m20;
+ m21 = m1.m21;
+ m22 = m1.m22;
+ }
+
+ protected void clear33() {
+ m00 = m01 = m02 = m10 = m11 = m12 = m20 = m21 = m22 = 0.0f;
+ }
+
+ protected void set33(int row, int col, float v) {
+ switch (row) {
+ case 0:
+ switch (col) {
+ case 0:
+ m00 = v;
+ return;
+ case 1:
+ m01 = v;
+ return;
+ case 2:
+ m02 = v;
+ return;
+ }
+ break;
+ case 1:
+ switch (col) {
+ case 0:
+ m10 = v;
+ return;
+ case 1:
+ m11 = v;
+ return;
+ case 2:
+ m12 = v;
+ return;
+ }
+ break;
+ case 2:
+ switch (col) {
+ case 0:
+ m20 = v;
+ return;
+ case 1:
+ m21 = v;
+ return;
+ case 2:
+ m22 = v;
+ return;
+ }
+ break;
+ }
+ err();
+ }
+
+ protected float get33(int row, int col) {
+ switch (row) {
+ case 0:
+ switch (col) {
+ case 0:
+ return m00;
+ case 1:
+ return m01;
+ case 2:
+ return m02;
+ }
+ break;
+ case 1:
+ switch (col) {
+ case 0:
+ return m10;
+ case 1:
+ return m11;
+ case 2:
+ return m12;
+ }
+ break;
+ case 2:
+ switch (col) {
+ case 0:
+ return m20;
+ case 1:
+ return m21;
+ case 2:
+ return m22;
+ }
+ break;
+ }
+ err();
+ return 0;
+ }
+
+ protected void setRow33(int row, float v[]) {
+ switch (row) {
+ case 0:
+ m00 = v[0];
+ m01 = v[1];
+ m02 = v[2];
+ return;
+ case 1:
+ m10 = v[0];
+ m11 = v[1];
+ m12 = v[2];
+ return;
+ case 2:
+ m20 = v[0];
+ m21 = v[1];
+ m22 = v[2];
+ return;
+ default:
+ err();
+ }
+ }
+
+ public abstract void getRow(int row, float v[]);
+
+ protected void getRow33(int row, float v[]) {
+ switch (row) {
+ case 0:
+ v[0] = m00;
+ v[1] = m01;
+ v[2] = m02;
+ return;
+ case 1:
+ v[0] = m10;
+ v[1] = m11;
+ v[2] = m12;
+ return;
+ case 2:
+ v[0] = m20;
+ v[1] = m21;
+ v[2] = m22;
+ return;
+ }
+ err();
+ }
+
+ protected void setColumn33(int column, float v[]) {
+ switch(column) {
+ case 0:
+ m00 = v[0];
+ m10 = v[1];
+ m20 = v[2];
+ break;
+ case 1:
+ m01 = v[0];
+ m11 = v[1];
+ m21 = v[2];
+ break;
+ case 2:
+ m02 = v[0];
+ m12 = v[1];
+ m22 = v[2];
+ break;
+ default:
+ err();
+ }
+ }
+
+ protected void getColumn33(int column, float v[]) {
+ switch(column) {
+ case 0:
+ v[0] = m00;
+ v[1] = m10;
+ v[2] = m20;
+ break;
+ case 1:
+ v[0] = m01;
+ v[1] = m11;
+ v[2] = m21;
+ break;
+ case 2:
+ v[0] = m02;
+ v[1] = m12;
+ v[2] = m22;
+ break;
+ default:
+ err();
+ }
+ }
+
+ protected void add33(M34 m1) {
+ m00 += m1.m00;
+ m01 += m1.m01;
+ m02 += m1.m02;
+ m10 += m1.m10;
+ m11 += m1.m11;
+ m12 += m1.m12;
+ m20 += m1.m20;
+ m21 += m1.m21;
+ m22 += m1.m22;
+ }
+
+ protected void sub33(M34 m1) {
+ m00 -= m1.m00;
+ m01 -= m1.m01;
+ m02 -= m1.m02;
+ m10 -= m1.m10;
+ m11 -= m1.m11;
+ m12 -= m1.m12;
+ m20 -= m1.m20;
+ m21 -= m1.m21;
+ m22 -= m1.m22;
+ }
+
+ protected void mul33(float x) {
+ m00 *= x;
+ m01 *= x;
+ m02 *= x;
+ m10 *= x;
+ m11 *= x;
+ m12 *= x;
+ m20 *= x;
+ m21 *= x;
+ m22 *= x;
+ }
+
+ protected void transpose33() {
+ float tmp = m01;
+ m01 = m10;
+ m10 = tmp;
+
+ tmp = m02;
+ m02 = m20;
+ m20 = tmp;
+
+ tmp = m12;
+ m12 = m21;
+ m21 = tmp;
+ }
+
+ protected void setXRot(float angle) {
+ double c = Math.cos(angle);
+ double s = Math.sin(angle);
+ m00 = 1.0f;
+ m01 = 0.0f;
+ m02 = 0.0f;
+ m10 = 0.0f;
+ m11 = (float) c;
+ m12 = (float) -s;
+ m20 = 0.0f;
+ m21 = (float) s;
+ m22 = (float) c;
+ }
+
+ protected void setYRot(float angle) {
+ double c = Math.cos(angle);
+ double s = Math.sin(angle);
+ m00 = (float) c;
+ m01 = 0.0f;
+ m02 = (float) s;
+ m10 = 0.0f;
+ m11 = 1.0f;
+ m12 = 0.0f;
+ m20 = (float) -s;
+ m21 = 0.0f;
+ m22 = (float) c;
+ }
+
+ protected void setZRot(float angle) {
+ double c = Math.cos(angle);
+ double s = Math.sin(angle);
+ m00 = (float) c;
+ m01 = (float) -s;
+ m02 = 0.0f;
+ m10 = (float) s;
+ m11 = (float) c;
+ m12 = 0.0f;
+ m20 = 0.0f;
+ m21 = 0.0f;
+ m22 = 1.0f;
+ }
+
+ /**
+ * @return 3x3 determinant
+ */
+ public float determinant3() {
+ return m00 * (m11 * m22 - m21 * m12) - m01 * (m10 * m22 - m20 * m12) + m02
+ * (m10 * m21 - m20 * m11);
+ }
+
+ protected void err() {
+ throw new ArrayIndexOutOfBoundsException(
+ "matrix column/row out of bounds");
+ }
+
+
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+/**
+ * A single precision floating point 4 by 4 matrix.
+ *
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
+ * constructor and method names for the optimization of compiled
+ * JavaScript using Java2Script
+ */
+public class M4 extends M34 {
+
+ /**
+ * The fourth element of the first row.
+ */
+ public float m03;
+
+ /**
+ * The fourth element of the second row.
+ */
+ public float m13;
+
+ /**
+ * The fourth element of the third row.
+ */
+ public float m23;
+
+ /**
+ * The first element of the fourth row.
+ */
+ public float m30;
+
+ /**
+ * The second element of the fourth row.
+ */
+ public float m31;
+
+ /**
+ * The third element of the fourth row.
+ */
+ public float m32;
+
+ /**
+ * The fourth element of the fourth row.
+ */
+ public float m33 = 0;
+
+ /**
+ * all zeros
+ * @j2sIgnore
+ */
+ public M4() {
+ }
+ /**
+ * Constructs and initializes a Matrix4f from the specified 16 element array.
+ * this.m00 =v[0], this.m01=v[1], etc.
+ *
+ * @param v
+ * the array of length 16 containing in order
+ * @return m
+ */
+ public static M4 newA16(float[] v) {
+ M4 m = new M4();
+ m.m00 = v[0];
+ m.m01 = v[1];
+ m.m02 = v[2];
+ m.m03 = v[3];
+
+ m.m10 = v[4];
+ m.m11 = v[5];
+ m.m12 = v[6];
+ m.m13 = v[7];
+
+ m.m20 = v[8];
+ m.m21 = v[9];
+ m.m22 = v[10];
+ m.m23 = v[11];
+
+ m.m30 = v[12];
+ m.m31 = v[13];
+ m.m32 = v[14];
+ m.m33 = v[15];
+
+ return m;
+ }
+
+ /**
+ * Constructs a new matrix with the same values as the Matrix4f parameter.
+ *
+ * @param m1
+ * the source matrix
+ * @return m
+ */
+ public static M4 newM4(M4 m1) {
+ M4 m = new M4();
+ if (m1 == null) {
+ m.setIdentity();
+ return m;
+ }
+ m.setToM3(m1);
+ m.m03 = m1.m03;
+ m.m13 = m1.m13;
+ m.m23 = m1.m23;
+ m.m30 = m1.m30;
+ m.m31 = m1.m31;
+ m.m32 = m1.m32;
+ m.m33 = m1.m33;
+ return m;
+ }
+
+ /**
+ * Constructs and initializes a Matrix4f from the rotation matrix and
+ * translation.
+ *
+ * @param m1
+ * The rotation matrix representing the rotational components
+ * @param t
+ * The translational components of the matrix
+ * @return m
+ */
+ public static M4 newMV(M3 m1, T3 t) {
+ M4 m = new M4();
+ m.setMV(m1, t);
+ return m;
+ }
+
+ /**
+ * Sets this matrix to all zeros.
+ */
+ public void setZero() {
+ clear33();
+ m03 = m13 = m23 = m30 = m31 = m32 = m33 = 0.0f;
+ }
+
+ /**
+ * Sets this Matrix4f to identity.
+ */
+ public void setIdentity() {
+ setZero();
+ m00 = m11 = m22 = m33 = 1.0f;
+ }
+
+ /**
+ * Sets the value of this matrix to a copy of the passed matrix m1.
+ *
+ * @param m1
+ * the matrix to be copied
+ * @return this
+ */
+ public M4 setM4(M4 m1) {
+ setM33(m1);
+ m03 = m1.m03;
+ m13 = m1.m13;
+ m23 = m1.m23;
+ m30 = m1.m30;
+ m31 = m1.m31;
+ m32 = m1.m32;
+ m33 = m1.m33;
+ return this;
+ }
+
+ /**
+ * Initializes a Matrix4f from the rotation matrix and translation.
+ *
+ * @param m1
+ * The rotation matrix representing the rotational components
+ * @param t
+ * The translational components of the matrix
+ */
+ public void setMV(M3 m1, T3 t) {
+ setM33(m1);
+ setTranslation(t);
+ m33 = 1;
+ }
+
+ /**
+ * Sets the rotational component (upper 3x3) of this matrix to the matrix
+ * values in the single precision Matrix3f argument; the other elements of
+ * this matrix are initialized as if this were an identity matrix (ie, affine
+ * matrix with no translational component).
+ *
+ * @param m1
+ * the 3x3 matrix
+ */
+ public void setToM3(M34 m1) {
+ setM33(m1);
+ m03 = m13 = m23 = m30 = m31 = m32 = 0.0f;
+ m33 = 1.0f;
+ }
+
+ /**
+ * Sets the rotational component (upper 3x3) of this matrix
+ * to a rotation given by an axis angle
+ *
+ * @param a
+ * the axis and angle to be converted
+ */
+ public void setToAA(A4 a) {
+ setIdentity();
+ setAA33(a);
+ }
+
+ /**
+ * Sets the values in this Matrix4f equal to the row-major array parameter
+ * (ie, the first four elements of the array will be copied into the first row
+ * of this matrix, etc.).
+ *
+ * @param m
+ */
+ public void setA(float m[]) {
+ m00 = m[0];
+ m01 = m[1];
+ m02 = m[2];
+ m03 = m[3];
+ m10 = m[4];
+ m11 = m[5];
+ m12 = m[6];
+ m13 = m[7];
+ m20 = m[8];
+ m21 = m[9];
+ m22 = m[10];
+ m23 = m[11];
+ m30 = m[12];
+ m31 = m[13];
+ m32 = m[14];
+ m33 = m[15];
+ }
+
+ /**
+ * Modifies the translational components of this matrix to the values of the
+ * Vector3f argument; the other values of this matrix are not modified.
+ *
+ * @param trans
+ * the translational component
+ */
+ public void setTranslation(T3 trans) {
+ m03 = trans.x;
+ m13 = trans.y;
+ m23 = trans.z;
+ }
+
+ /**
+ * Sets the specified element of this matrix4f to the value provided.
+ *
+ * @param row
+ * the row number to be modified (zero indexed)
+ * @param col
+ * the column number to be modified (zero indexed)
+ * @param v
+ * the new value
+ */
+ public void setElement(int row, int col, float v) {
+ if (row < 3 && col < 3) {
+ set33(row, col, v);
+ return;
+ }
+ if (row > 3 || col > 3)
+ err();
+ switch (row) {
+ case 0:
+ m03 = v;
+ return;
+ case 1:
+ m13 = v;
+ return;
+ case 2:
+ m23 = v;
+ return;
+ }
+ switch (col) {
+ case 0:
+ m30 = v;
+ return;
+ case 1:
+ m31 = v;
+ return;
+ case 2:
+ m32 = v;
+ return;
+ case 3:
+ m33 = v;
+ return;
+ }
+ }
+
+ /**
+ * Retrieves the value at the specified row and column of this matrix.
+ *
+ * @param row
+ * the row number to be retrieved (zero indexed)
+ * @param col
+ * the column number to be retrieved (zero indexed)
+ * @return the value at the indexed element
+ */
+ public float getElement(int row, int col) {
+ if (row < 3 && col < 3)
+ return get33(row, col);
+ if (row > 3 || col > 3) {
+ err();
+ return 0;
+ }
+ switch (row) {
+ case 0:
+ return m03;
+ case 1:
+ return m13;
+ case 2:
+ return m23;
+ default:
+ switch (col) {
+ case 0:
+ return m30;
+ case 1:
+ return m31;
+ case 2:
+ return m32;
+ default:
+ return m33;
+ }
+ }
+ }
+
+ /**
+ * Retrieves the translational components of this matrix.
+ *
+ * @param trans
+ * the vector that will receive the translational component
+ */
+ public void getTranslation(T3 trans) {
+ trans.x = m03;
+ trans.y = m13;
+ trans.z = m23;
+ }
+
+ /**
+ * Gets the upper 3x3 values of this matrix and places them into the matrix
+ * m1.
+ *
+ * @param m1
+ * The matrix that will hold the values
+ */
+ public void getRotationScale(M3 m1) {
+ m1.m00 = m00;
+ m1.m01 = m01;
+ m1.m02 = m02;
+ m1.m10 = m10;
+ m1.m11 = m11;
+ m1.m12 = m12;
+ m1.m20 = m20;
+ m1.m21 = m21;
+ m1.m22 = m22;
+ }
+
+ /**
+ * Replaces the upper 3x3 matrix values of this matrix with the values in the
+ * matrix m1.
+ *
+ * @param m1
+ * The matrix that will be the new upper 3x3
+ */
+ public void setRotationScale(M3 m1) {
+ m00 = m1.m00;
+ m01 = m1.m01;
+ m02 = m1.m02;
+ m10 = m1.m10;
+ m11 = m1.m11;
+ m12 = m1.m12;
+ m20 = m1.m20;
+ m21 = m1.m21;
+ m22 = m1.m22;
+ }
+
+ /**
+ * Sets the specified row of this matrix4f to the four values provided.
+ *
+ * @param row
+ * the row number to be modified (zero indexed)
+ * @param v
+ * the replacement row
+ */
+ public void setRowA(int row, float v[]) {
+ if (row < 3)
+ setRow33(row, v);
+ switch (row) {
+ case 0:
+ m03 = v[3];
+ return;
+ case 1:
+ m13 = v[3];
+ return;
+ case 2:
+ m23 = v[3];
+ return;
+ case 3:
+ m30 = v[0];
+ m31 = v[1];
+ m32 = v[2];
+ m33 = v[3];
+ return;
+ }
+ err();
+ }
+
+ /**
+ * Copies the matrix values in the specified row into the array parameter.
+ *
+ * @param row
+ * the matrix row
+ * @param v
+ * The array into which the matrix row values will be copied
+ */
+ @Override
+ public void getRow(int row, float v[]) {
+ if (row < 3)
+ getRow33(row, v);
+ switch (row) {
+ case 0:
+ v[3] = m03;
+ return;
+ case 1:
+ v[3] = m13;
+ return;
+ case 2:
+ v[3] = m23;
+ return;
+ case 3:
+ v[0] = m30;
+ v[1] = m31;
+ v[2] = m32;
+ v[3] = m33;
+ return;
+ }
+ err();
+ }
+
+ /**
+ * Sets the specified column of this matrix4f to the four values provided.
+ *
+ * @param column
+ * the column number to be modified (zero indexed)
+ * @param x
+ * the first row element
+ * @param y
+ * the second row element
+ * @param z
+ * the third row element
+ * @param w
+ * the fourth row element
+ */
+ public void setColumn4(int column, float x, float y, float z, float w) {
+ if (column == 0) {
+ m00 = x;
+ m10 = y;
+ m20 = z;
+ m30 = w;
+ } else if (column == 1) {
+ m01 = x;
+ m11 = y;
+ m21 = z;
+ m31 = w;
+ } else if (column == 2) {
+ m02 = x;
+ m12 = y;
+ m22 = z;
+ m32 = w;
+ } else if (column == 3) {
+ m03 = x;
+ m13 = y;
+ m23 = z;
+ m33 = w;
+ } else {
+ err();
+ }
+ }
+
+ /**
+ * Sets the specified column of this matrix4f to the four values provided.
+ *
+ * @param column
+ * the column number to be modified (zero indexed)
+ * @param v
+ * the replacement column
+ */
+ public void setColumnA(int column, float v[]) {
+ if (column < 3)
+ setColumn33(column, v);
+ switch (column) {
+ case 0:
+ m30 = v[3];
+ return;
+ case 1:
+ m31 = v[3];
+ return;
+ case 2:
+ m32 = v[3];
+ return;
+ case 3:
+ m03 = v[0];
+ m13 = v[1];
+ m23 = v[2];
+ m33 = v[3];
+ return;
+ default:
+ err();
+ }
+ }
+
+ /**
+ * Copies the matrix values in the specified column into the array parameter.
+ *
+ * @param column
+ * the matrix column
+ * @param v
+ * The array into which the matrix column values will be copied
+ */
+ public void getColumn(int column, float v[]) {
+ if (column < 3)
+ getColumn33(column, v);
+ switch (column) {
+ case 0:
+ v[3] = m30;
+ return;
+ case 1:
+ v[3] = m31;
+ return;
+ case 2:
+ v[3] = m32;
+ return;
+ case 3:
+ v[0] = m03;
+ v[1] = m13;
+ v[2] = m23;
+ v[3] = m33;
+ return;
+ default:
+ err();
+ }
+ }
+
+ /**
+ * Sets the value of this matrix to the matrix difference of itself and matrix
+ * m1 (this = this - m1).
+ *
+ * @param m1
+ * the other matrix
+ */
+ public void sub(M4 m1) {
+ sub33(m1);
+ m03 -= m1.m03;
+ m13 -= m1.m13;
+ m23 -= m1.m23;
+ m30 -= m1.m30;
+ m31 -= m1.m31;
+ m32 -= m1.m32;
+ m33 -= m1.m33;
+ }
+
+ /**
+ * Sets the value of this matrix to its transpose.
+ */
+ public void transpose() {
+ transpose33();
+ float tmp = m03;
+ m03 = m30;
+ m30 = tmp;
+
+ tmp = m13;
+ m13 = m31;
+ m31 = tmp;
+
+ tmp = m23;
+ m23 = m32;
+ m32 = tmp;
+ }
+
+ /**
+ * Sets the value of this matrix to its inverse.
+ * @return this
+ */
+ public M4 invert() {
+ float s = determinant4();
+ if (s == 0.0)
+ return this;
+ s = 1 / s;
+ // alias-safe way.
+ // less *,+,- calculation than expanded expression.
+ set(m11 * (m22 * m33 - m23 * m32) + m12 * (m23 * m31 - m21 * m33) + m13
+ * (m21 * m32 - m22 * m31), m21 * (m02 * m33 - m03 * m32) + m22
+ * (m03 * m31 - m01 * m33) + m23 * (m01 * m32 - m02 * m31), m31
+ * (m02 * m13 - m03 * m12) + m32 * (m03 * m11 - m01 * m13) + m33
+ * (m01 * m12 - m02 * m11), m01 * (m13 * m22 - m12 * m23) + m02
+ * (m11 * m23 - m13 * m21) + m03 * (m12 * m21 - m11 * m22),
+
+ m12 * (m20 * m33 - m23 * m30) + m13 * (m22 * m30 - m20 * m32) + m10
+ * (m23 * m32 - m22 * m33), m22 * (m00 * m33 - m03 * m30) + m23
+ * (m02 * m30 - m00 * m32) + m20 * (m03 * m32 - m02 * m33), m32
+ * (m00 * m13 - m03 * m10) + m33 * (m02 * m10 - m00 * m12) + m30
+ * (m03 * m12 - m02 * m13), m02 * (m13 * m20 - m10 * m23) + m03
+ * (m10 * m22 - m12 * m20) + m00 * (m12 * m23 - m13 * m22),
+
+ m13 * (m20 * m31 - m21 * m30) + m10 * (m21 * m33 - m23 * m31) + m11
+ * (m23 * m30 - m20 * m33), m23 * (m00 * m31 - m01 * m30) + m20
+ * (m01 * m33 - m03 * m31) + m21 * (m03 * m30 - m00 * m33), m33
+ * (m00 * m11 - m01 * m10) + m30 * (m01 * m13 - m03 * m11) + m31
+ * (m03 * m10 - m00 * m13), m03 * (m11 * m20 - m10 * m21) + m00
+ * (m13 * m21 - m11 * m23) + m01 * (m10 * m23 - m13 * m20),
+
+ m10 * (m22 * m31 - m21 * m32) + m11 * (m20 * m32 - m22 * m30) + m12
+ * (m21 * m30 - m20 * m31), m20 * (m02 * m31 - m01 * m32) + m21
+ * (m00 * m32 - m02 * m30) + m22 * (m01 * m30 - m00 * m31), m30
+ * (m02 * m11 - m01 * m12) + m31 * (m00 * m12 - m02 * m10) + m32
+ * (m01 * m10 - m00 * m11), m00 * (m11 * m22 - m12 * m21) + m01
+ * (m12 * m20 - m10 * m22) + m02 * (m10 * m21 - m11 * m20));
+ scale(s);
+ return this;
+ }
+
+ /**
+ * Sets 16 values
+ *
+ * @param m00
+ * @param m01
+ * @param m02
+ * @param m03
+ * @param m10
+ * @param m11
+ * @param m12
+ * @param m13
+ * @param m20
+ * @param m21
+ * @param m22
+ * @param m23
+ * @param m30
+ * @param m31
+ * @param m32
+ * @param m33
+ */
+ private void set(float m00, float m01, float m02, float m03, float m10,
+ float m11, float m12, float m13, float m20, float m21,
+ float m22, float m23, float m30, float m31, float m32,
+ float m33) {
+ this.m00 = m00;
+ this.m01 = m01;
+ this.m02 = m02;
+ this.m03 = m03;
+ this.m10 = m10;
+ this.m11 = m11;
+ this.m12 = m12;
+ this.m13 = m13;
+ this.m20 = m20;
+ this.m21 = m21;
+ this.m22 = m22;
+ this.m23 = m23;
+ this.m30 = m30;
+ this.m31 = m31;
+ this.m32 = m32;
+ this.m33 = m33;
+ }
+ /**
+ * Computes the determinant of this matrix.
+ *
+ * @return the determinant of the matrix
+ */
+ public float determinant4() {
+ // less *,+,- calculation than expanded expression.
+ return (m00 * m11 - m01 * m10) * (m22 * m33 - m23 * m32)
+ - (m00 * m12 - m02 * m10) * (m21 * m33 - m23 * m31)
+ + (m00 * m13 - m03 * m10) * (m21 * m32 - m22 * m31)
+ + (m01 * m12 - m02 * m11) * (m20 * m33 - m23 * m30)
+ - (m01 * m13 - m03 * m11) * (m20 * m32 - m22 * m30)
+ + (m02 * m13 - m03 * m12) * (m20 * m31 - m21 * m30);
+
+ }
+
+ /**
+ * Multiplies each element of this matrix by a scalar.
+ *
+ * @param scalar
+ * The scalar multiplier.
+ */
+ private void scale(float scalar) {
+ mul33(scalar);
+ m03 *= scalar;
+ m13 *= scalar;
+ m23 *= scalar;
+ m30 *= scalar;
+ m31 *= scalar;
+ m32 *= scalar;
+ m33 *= scalar;
+ }
+
+ /**
+ * Sets the value of this matrix to the result of multiplying itself with
+ * matrix m1.
+ *
+ * @param m1
+ * the other matrix
+ */
+ public void mul(M4 m1) {
+ mul2(this, m1);
+ }
+
+ /**
+ * Sets the value of this matrix to the result of multiplying the two argument
+ * matrices together.
+ *
+ * @param m1
+ * the first matrix
+ * @param m2
+ * the second matrix
+ */
+ public void mul2(M4 m1, M4 m2) {
+ // alias-safe way.
+ set(m1.m00 * m2.m00 + m1.m01 * m2.m10 + m1.m02 * m2.m20 + m1.m03 * m2.m30,
+ m1.m00 * m2.m01 + m1.m01 * m2.m11 + m1.m02 * m2.m21 + m1.m03 * m2.m31,
+ m1.m00 * m2.m02 + m1.m01 * m2.m12 + m1.m02 * m2.m22 + m1.m03 * m2.m32,
+ m1.m00 * m2.m03 + m1.m01 * m2.m13 + m1.m02 * m2.m23 + m1.m03 * m2.m33,
+
+ m1.m10 * m2.m00 + m1.m11 * m2.m10 + m1.m12 * m2.m20 + m1.m13 * m2.m30,
+ m1.m10 * m2.m01 + m1.m11 * m2.m11 + m1.m12 * m2.m21 + m1.m13 * m2.m31,
+ m1.m10 * m2.m02 + m1.m11 * m2.m12 + m1.m12 * m2.m22 + m1.m13 * m2.m32,
+ m1.m10 * m2.m03 + m1.m11 * m2.m13 + m1.m12 * m2.m23 + m1.m13 * m2.m33,
+
+ m1.m20 * m2.m00 + m1.m21 * m2.m10 + m1.m22 * m2.m20 + m1.m23 * m2.m30,
+ m1.m20 * m2.m01 + m1.m21 * m2.m11 + m1.m22 * m2.m21 + m1.m23 * m2.m31,
+ m1.m20 * m2.m02 + m1.m21 * m2.m12 + m1.m22 * m2.m22 + m1.m23 * m2.m32,
+ m1.m20 * m2.m03 + m1.m21 * m2.m13 + m1.m22 * m2.m23 + m1.m23 * m2.m33,
+
+ m1.m30 * m2.m00 + m1.m31 * m2.m10 + m1.m32 * m2.m20 + m1.m33 * m2.m30,
+ m1.m30 * m2.m01 + m1.m31 * m2.m11 + m1.m32 * m2.m21 + m1.m33 * m2.m31,
+ m1.m30 * m2.m02 + m1.m31 * m2.m12 + m1.m32 * m2.m22 + m1.m33 * m2.m32,
+ m1.m30 * m2.m03 + m1.m31 * m2.m13 + m1.m32 * m2.m23 + m1.m33 * m2.m33);
+ }
+
+ /**
+ * Transform the vector vec using this Matrix4f and place the result back into
+ * vec.
+ *
+ * @param vec
+ * the single precision vector to be transformed
+ */
+ public void transform(T4 vec) {
+ transform2(vec, vec);
+ }
+
+ /**
+ * Transform the vector vec using this Matrix4f and place the result into
+ * vecOut.
+ *
+ * @param vec
+ * the single precision vector to be transformed
+ * @param vecOut
+ * the vector into which the transformed values are placed
+ */
+ public void transform2(T4 vec, T4 vecOut) {
+ // alias-safe
+ vecOut.set4(m00 * vec.x + m01 * vec.y + m02 * vec.z + m03 * vec.w, m10
+ * vec.x + m11 * vec.y + m12 * vec.z + m13 * vec.w, m20 * vec.x + m21
+ * vec.y + m22 * vec.z + m23 * vec.w, m30 * vec.x + m31 * vec.y + m32
+ * vec.z + m33 * vec.w);
+ }
+
+ /**
+ * Transforms the point parameter with this Matrix4f and places the result
+ * back into point. The fourth element of the point input parameter is assumed
+ * to be one.
+ *
+ * @param point
+ * the input point to be transformed.
+ */
+ public void rotTrans(T3 point) {
+ rotTrans2(point, point);
+ }
+
+ /**
+ * Transforms the point parameter with this Matrix4f and places the result
+ * into pointOut. The fourth element of the point input parameter is assumed to
+ * be one. point may be pointOut
+ *
+ * @param point
+ * the input point to be transformed.
+ * @param pointOut
+ * the transformed point
+ * @return pointOut
+ */
+ public T3 rotTrans2(T3 point, T3 pointOut) {
+ pointOut.set(
+ m00 * point.x + m01 * point.y + m02 * point.z + m03,
+ m10 * point.x + m11 * point.y + m12 * point.z + m13,
+ m20 * point.x + m21 * point.y + m22 * point.z + m23);
+ return pointOut;
+ }
+
+ /**
+ * Sets the value of this matrix to a rotation matrix about the w axis by the
+ * passed angle.
+ *
+ * @param angle
+ * the angle to rotate about the W axis in radians
+ * @return this
+ */
+ public M4 setAsXYRotation(float angle) {
+ setIdentity();
+ double c = Math.cos(angle);
+ double s = Math.sin(angle);
+ m22 = (float) c;
+ m23 = (float) -s;
+ m32 = (float) s;
+ m33 = (float) c;
+ return this;
+ }
+
+ /**
+ * Sets the value of this matrix to a rotation matrix about the w axis by the
+ * passed angle.
+ *
+ * @param angle
+ * the angle to rotate about the W axis in radians
+ * @return this
+ */
+ public M4 setAsYZRotation(float angle) {
+ setIdentity();
+ double c = Math.cos(angle);
+ double s = Math.sin(angle);
+ m00 = (float) c;
+ m03 = (float) -s;
+ m30 = (float) s;
+ m33 = (float) c;
+ return this;
+ }
+
+ /**
+ * Sets the value of this matrix to a rotation matrix about the w axis by the
+ * passed angle.
+ *
+ * @param angle
+ * the angle to rotate about the W axis in radians
+ * @return this
+ */
+ public M4 setAsXZRotation(float angle) {
+ setIdentity();
+ double c = Math.cos(angle);
+ double s = Math.sin(angle);
+ m11 = (float) c;
+ m13 = (float) -s;
+ m31 = (float) s;
+ m33 = (float) c;
+ return this;
+ }
+
+ /**
+ * Returns true if the Object o is of type Matrix4f and all of the data
+ * members of t1 are equal to the corresponding data members in this Matrix4f.
+ *
+ * @param o
+ * the object with which the comparison is made.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof M4))
+ return false;
+ M4 m = (M4) o;
+ return (this.m00 == m.m00 && this.m01 == m.m01 && this.m02 == m.m02
+ && this.m03 == m.m03 && this.m10 == m.m10 && this.m11 == m.m11
+ && this.m12 == m.m12 && this.m13 == m.m13 && this.m20 == m.m20
+ && this.m21 == m.m21 && this.m22 == m.m22 && this.m23 == m.m23
+ && this.m30 == m.m30 && this.m31 == m.m31 && this.m32 == m.m32 && this.m33 == m.m33);
+ }
+
+ /**
+ * Returns a hash number based on the data values in this object. Two
+ * different Matrix4f objects with identical data values (ie, returns true for
+ * equals(Matrix4f) ) will return the same hash number. Two objects with
+ * different data members may return the same hash value, although this is not
+ * likely.
+ *
+ * @return the integer hash value
+ */
+ @Override
+ public int hashCode() {
+ return T3.floatToIntBits0(m00) ^ T3.floatToIntBits0(m01)
+ ^ T3.floatToIntBits0(m02) ^ T3.floatToIntBits0(m03)
+ ^ T3.floatToIntBits0(m10) ^ T3.floatToIntBits0(m11)
+ ^ T3.floatToIntBits0(m12) ^ T3.floatToIntBits0(m13)
+ ^ T3.floatToIntBits0(m20) ^ T3.floatToIntBits0(m21)
+ ^ T3.floatToIntBits0(m22) ^ T3.floatToIntBits0(m23)
+ ^ T3.floatToIntBits0(m30) ^ T3.floatToIntBits0(m31)
+ ^ T3.floatToIntBits0(m32) ^ T3.floatToIntBits0(m33);
+ }
+
+ /**
+ * Returns a string that contains the values of this Matrix4f.
+ *
+ * @return the String representation
+ */
+ @Override
+ public String toString() {
+ return "[\n [" + m00 + "\t" + m01 + "\t" + m02 + "\t" + m03 + "]"
+ + "\n [" + m10 + "\t" + m11 + "\t" + m12 + "\t" + m13 + "]" + "\n ["
+ + m20 + "\t" + m21 + "\t" + m22 + "\t" + m23 + "]" + "\n [" + m30
+ + "\t" + m31 + "\t" + m32 + "\t" + m33 + "] ]";
+ }
+ public M4 round(float f) {
+ m00 = rnd(m00, f);
+ m01 = rnd(m01, f);
+ m02 = rnd(m02, f);
+ m03 = rnd(m03, f);
+ m10 = rnd(m10, f);
+ m11 = rnd(m11, f);
+ m12 = rnd(m12, f);
+ m13 = rnd(m13, f);
+ m20 = rnd(m20, f);
+ m21 = rnd(m21, f);
+ m22 = rnd(m22, f);
+ m23 = rnd(m23, f);
+ m30 = rnd(m30, f);
+ m31 = rnd(m31, f);
+ m32 = rnd(m32, f);
+ m33 = rnd(m33, f);
+ return this;
+ }
+
+ private float rnd(float n, float f) {
+ return (Math.abs(n) < f ? 0 : n);
+ }
+}
--- /dev/null
+package javajs.util;
+
+/**
+ *
+ * streamlined and refined for Jmol by Bob Hanson
+ *
+ * from http://math.nist.gov/javanumerics/jama/
+ *
+ * Jama = Java Matrix class.
+ *
+ * @author The MathWorks, Inc. and the National Institute of Standards and
+ * Technology.
+ * @version 5 August 1998
+ */
+
+public class Matrix implements Cloneable {
+
+ public double[][] a;
+ protected int m, n;
+
+ /**
+ * Construct a matrix quickly without checking arguments.
+ *
+ * @param a
+ * Two-dimensional array of doubles or null
+ * @param m
+ * Number of rows.
+ * @param n
+ * Number of colums.
+ */
+
+ public Matrix(double[][] a, int m, int n) {
+ this.a = (a == null ? new double[m][n] : a);
+ this.m = m;
+ this.n = n;
+ }
+
+ /**
+ * Get row dimension.
+ *
+ * @return m, the number of rows.
+ */
+
+ public int getRowDimension() {
+ return m;
+ }
+
+ /**
+ * Get column dimension.
+ *
+ * @return n, the number of columns.
+ */
+
+ public int getColumnDimension() {
+ return n;
+ }
+
+ /**
+ * Access the internal two-dimensional array.
+ *
+ * @return Pointer to the two-dimensional array of matrix elements.
+ */
+
+ public double[][] getArray() {
+ return a;
+ }
+
+ /**
+ * Copy the internal two-dimensional array.
+ *
+ * @return Two-dimensional array copy of matrix elements.
+ */
+
+ public double[][] getArrayCopy() {
+ double[][] x = new double[m][n];
+ for (int i = m; --i >= 0;)
+ for (int j = n; --j >= 0;)
+ x[i][j] = a[i][j];
+ return x;
+ }
+
+ /**
+ * Make a deep copy of a matrix
+ *
+ * @return copy
+ */
+
+ public Matrix copy() {
+ Matrix x = new Matrix(null, m, n);
+ double[][] c = x.a;
+ for (int i = m; --i >= 0;)
+ for (int j = n; --j >= 0;)
+ c[i][j] = a[i][j];
+ return x;
+ }
+
+ /**
+ * Clone the Matrix object.
+ */
+
+ @Override
+ public Object clone() {
+ return copy();
+ }
+
+ /**
+ * Get a submatrix.
+ *
+ * @param i0
+ * Initial row index
+ * @param j0
+ * Initial column index
+ * @param nrows
+ * Number of rows
+ * @param ncols
+ * Number of columns
+ * @return submatrix
+ *
+ */
+
+ public Matrix getSubmatrix(int i0, int j0, int nrows, int ncols) {
+ Matrix x = new Matrix(null, nrows, ncols);
+ double[][] xa = x.a;
+ for (int i = nrows; --i >= 0;)
+ for (int j = ncols; --j >= 0;)
+ xa[i][j] = a[i0 + i][j0 + j];
+ return x;
+ }
+
+ /**
+ * Get a submatrix for a give number of columns and selected row set.
+ *
+ * @param r
+ * Array of row indices.
+ * @param n
+ * number of rows
+ * @return submatrix
+ */
+
+ public Matrix getMatrixSelected(int[] r, int n) {
+ Matrix x = new Matrix(null, r.length, n);
+ double[][] xa = x.a;
+ for (int i = r.length; --i >= 0;) {
+ double[] b = a[r[i]];
+ for (int j = n; --j >= 0;)
+ xa[i][j] = b[j];
+ }
+ return x;
+ }
+
+ /**
+ * Matrix transpose.
+ *
+ * @return A'
+ */
+
+ public Matrix transpose() {
+ Matrix x = new Matrix(null, n, m);
+ double[][] c = x.a;
+ for (int i = m; --i >= 0;)
+ for (int j = n; --j >= 0;)
+ c[j][i] = a[i][j];
+ return x;
+ }
+
+ /**
+ * add two matrices
+ * @param b
+ * @return new Matrix this + b
+ */
+ public Matrix add(Matrix b) {
+ return scaleAdd(b, 1);
+ }
+
+ /**
+ * subtract two matrices
+ * @param b
+ * @return new Matrix this - b
+ */
+ public Matrix sub(Matrix b) {
+ return scaleAdd(b, -1);
+ }
+
+ /**
+ * X = A + B*scale
+ * @param b
+ * @param scale
+ * @return X
+ *
+ */
+ public Matrix scaleAdd(Matrix b, double scale) {
+ Matrix x = new Matrix(null, m, n);
+ double[][] xa = x.a;
+ double[][] ba = b.a;
+ for (int i = m; --i >= 0;)
+ for (int j = n; --j >= 0;)
+ xa[i][j] = ba[i][j] * scale + a[i][j];
+ return x;
+ }
+
+ /**
+ * Linear algebraic matrix multiplication, A * B
+ *
+ * @param b
+ * another matrix
+ * @return Matrix product, A * B or null for wrong dimension
+ */
+
+ public Matrix mul(Matrix b) {
+ if (b.m != n)
+ return null;
+ Matrix x = new Matrix(null, m, b.n);
+ double[][] xa = x.a;
+ double[][] ba = b.a;
+ for (int j = b.n; --j >= 0;)
+ for (int i = m; --i >= 0;) {
+ double[] arowi = a[i];
+ double s = 0;
+ for (int k = n; --k >= 0;)
+ s += arowi[k] * ba[k][j];
+ xa[i][j] = s;
+ }
+ return x;
+ }
+
+ /**
+ * Matrix inverse or pseudoinverse
+ *
+ * @return inverse (m == n) or pseudoinverse (m != n)
+ */
+
+ public Matrix inverse() {
+ return new LUDecomp(m, n).solve(identity(m, m), n);
+ }
+
+ /**
+ * Matrix trace.
+ *
+ * @return sum of the diagonal elements.
+ */
+
+ public double trace() {
+ double t = 0;
+ for (int i = Math.min(m, n); --i >= 0;)
+ t += a[i][i];
+ return t;
+ }
+
+ /**
+ * Generate identity matrix
+ *
+ * @param m
+ * Number of rows.
+ * @param n
+ * Number of columns.
+ * @return An m-by-n matrix with ones on the diagonal and zeros elsewhere.
+ */
+
+ public static Matrix identity(int m, int n) {
+ Matrix x = new Matrix(null, m, n);
+ double[][] xa = x.a;
+ for (int i = Math.min(m, n); --i >= 0;)
+ xa[i][i] = 1;
+ return x;
+ }
+
+ /**
+ * similarly to M3/M4 standard rotation/translation matrix
+ * we set a rotationTranslation matrix to be:
+ *
+ * [ nxn rot nx1 trans
+ *
+ * 1xn 0 1x1 1 ]
+ *
+ *
+ * @return rotation matrix
+ */
+ public Matrix getRotation() {
+ return getSubmatrix(0, 0, m - 1, n - 1);
+ }
+
+ public Matrix getTranslation() {
+ return getSubmatrix(0, n - 1, m - 1, 1);
+ }
+
+ public static Matrix newT(T3 r, boolean asColumn) {
+ return (asColumn ? new Matrix(new double[][] { new double[] { r.x },
+ new double[] { r.y }, new double[] { r.z } }, 3, 1) : new Matrix(
+ new double[][] { new double[] { r.x, r.y, r.z } }, 1, 3));
+ }
+
+ @Override
+ public String toString() {
+ String s = "[\n";
+ for (int i = 0; i < m; i++) {
+ s += " [";
+ for (int j = 0; j < n; j++)
+ s += " " + a[i][j];
+ s += "]\n";
+ }
+ s += "]";
+ return s;
+ }
+
+ /**
+ *
+ * Edited down by Bob Hanson for minimum needed by Jmol -- just constructor
+ * and solve
+ *
+ * LU Decomposition.
+ * <P>
+ * For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n unit
+ * lower triangular matrix L, an n-by-n upper triangular matrix U, and a
+ * permutation vector piv of length m so that A(piv,:) = L*U. If m < n, then L
+ * is m-by-m and U is m-by-n.
+ * <P>
+ * The LU decompostion with pivoting always exists, even if the matrix is
+ * singular, so the constructor will never fail. The primary use of the LU
+ * decomposition is in the solution of square systems of simultaneous linear
+ * equations. This will fail if isNonsingular() returns false.
+ */
+
+ private class LUDecomp {
+
+ /* ------------------------
+ Class variables
+ * ------------------------ */
+
+ /**
+ * Array for internal storage of decomposition.
+ *
+ */
+ private double[][] LU;
+
+ /**
+ * Internal storage of pivot vector.
+ *
+ */
+ private int[] piv;
+
+ private int pivsign;
+
+ /* ------------------------
+ Constructor
+ * ------------------------ */
+
+ /**
+ * LU Decomposition Structure to access L, U and piv.
+ * @param m
+ * @param n
+ *
+ */
+
+ protected LUDecomp(int m, int n) {
+
+ // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
+
+ LU = getArrayCopy();
+ piv = new int[m];
+ for (int i = m; --i >= 0;)
+ piv[i] = i;
+ pivsign = 1;
+ double[] LUrowi;
+ double[] LUcolj = new double[m];
+
+ // Outer loop.
+
+ for (int j = 0; j < n; j++) {
+
+ // Make a copy of the j-th column to localize references.
+
+ for (int i = m; --i >= 0;)
+ LUcolj[i] = LU[i][j];
+
+ // Apply previous transformations.
+
+ for (int i = m; --i >= 0;) {
+ LUrowi = LU[i];
+
+ // Most of the time is spent in the following dot product.
+
+ int kmax = Math.min(i, j);
+ double s = 0.0;
+ for (int k = kmax; --k >= 0;)
+ s += LUrowi[k] * LUcolj[k];
+
+ LUrowi[j] = LUcolj[i] -= s;
+ }
+
+ // Find pivot and exchange if necessary.
+
+ int p = j;
+ for (int i = m; --i > j;)
+ if (Math.abs(LUcolj[i]) > Math.abs(LUcolj[p]))
+ p = i;
+ if (p != j) {
+ for (int k = n; --k >= 0;) {
+ double t = LU[p][k];
+ LU[p][k] = LU[j][k];
+ LU[j][k] = t;
+ }
+ int k = piv[p];
+ piv[p] = piv[j];
+ piv[j] = k;
+ pivsign = -pivsign;
+ }
+
+ // Compute multipliers.
+
+ if (j < m & LU[j][j] != 0.0)
+ for (int i = m; --i > j;)
+ LU[i][j] /= LU[j][j];
+ }
+ }
+
+ /* ------------------------
+ default Methods
+ * ------------------------ */
+
+ /**
+ * Solve A*X = B
+ *
+ * @param b
+ * A Matrix with as many rows as A and any number of columns.
+ * @param n
+ * @return X so that L*U*X = B(piv,:) or null for wrong size or singular matrix
+ */
+
+ protected Matrix solve(Matrix b, int n) {
+ for (int j = 0; j < n; j++)
+ if (LU[j][j] == 0)
+ return null; // matrix is singular
+
+ // Copy right hand side with pivoting
+ int nx = b.n;
+ Matrix x = b.getMatrixSelected(piv, nx);
+ double[][] a = x.a;
+
+ // Solve L*Y = B(piv,:)
+ for (int k = 0; k < n; k++)
+ for (int i = k + 1; i < n; i++)
+ for (int j = 0; j < nx; j++)
+ a[i][j] -= a[k][j] * LU[i][k];
+
+ // Solve U*X = Y;
+ for (int k = n; --k >= 0;) {
+ for (int j = nx; --j >= 0;)
+ a[k][j] /= LU[k][k];
+ for (int i = k; --i >= 0;)
+ for (int j = nx; --j >= 0;)
+ a[i][j] -= a[k][j] * LU[i][k];
+ }
+ return x;
+ }
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: egonw $
+ * $Date: 2005-11-10 09:52:44 -0600 (Thu, 10 Nov 2005) $
+ * $Revision: 4255 $
+ *
+ * Copyright (C) 2003-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.util;
+
+import javajs.api.EigenInterface;
+
+import javajs.api.Interface;
+
+
+
+
+//import org.jmol.script.T;
+
+final public class Measure {
+
+ public final static float radiansPerDegree = (float) (2 * Math.PI / 360);
+
+ public static float computeAngle(T3 pointA, T3 pointB, T3 pointC, V3 vectorBA, V3 vectorBC, boolean asDegrees) {
+ vectorBA.sub2(pointA, pointB);
+ vectorBC.sub2(pointC, pointB);
+ float angle = vectorBA.angle(vectorBC);
+ return (asDegrees ? angle / radiansPerDegree : angle);
+ }
+
+ public static float computeAngleABC(T3 pointA, T3 pointB, T3 pointC, boolean asDegrees) {
+ V3 vectorBA = new V3();
+ V3 vectorBC = new V3();
+ return computeAngle(pointA, pointB, pointC, vectorBA, vectorBC, asDegrees);
+ }
+
+ public static float computeTorsion(T3 p1, T3 p2, T3 p3, T3 p4, boolean asDegrees) {
+
+ float ijx = p1.x - p2.x;
+ float ijy = p1.y - p2.y;
+ float ijz = p1.z - p2.z;
+
+ float kjx = p3.x - p2.x;
+ float kjy = p3.y - p2.y;
+ float kjz = p3.z - p2.z;
+
+ float klx = p3.x - p4.x;
+ float kly = p3.y - p4.y;
+ float klz = p3.z - p4.z;
+
+ float ax = ijy * kjz - ijz * kjy;
+ float ay = ijz * kjx - ijx * kjz;
+ float az = ijx * kjy - ijy * kjx;
+ float cx = kjy * klz - kjz * kly;
+ float cy = kjz * klx - kjx * klz;
+ float cz = kjx * kly - kjy * klx;
+
+ float ai2 = 1f / (ax * ax + ay * ay + az * az);
+ float ci2 = 1f / (cx * cx + cy * cy + cz * cz);
+
+ float ai = (float) Math.sqrt(ai2);
+ float ci = (float) Math.sqrt(ci2);
+ float denom = ai * ci;
+ float cross = ax * cx + ay * cy + az * cz;
+ float cosang = cross * denom;
+ if (cosang > 1) {
+ cosang = 1;
+ }
+ if (cosang < -1) {
+ cosang = -1;
+ }
+
+ float torsion = (float) Math.acos(cosang);
+ float dot = ijx * cx + ijy * cy + ijz * cz;
+ float absDot = Math.abs(dot);
+ torsion = (dot / absDot > 0) ? torsion : -torsion;
+ return (asDegrees ? torsion / radiansPerDegree : torsion);
+ }
+
+ /**
+ * This method calculates measures relating to two points in space
+ * with related quaternion frame difference. It is used in Jmol for
+ * calculating straightness and many other helical quantities.
+ *
+ * @param a
+ * @param b
+ * @param dq
+ * @return new T3[] { pt_a_prime, n, r, P3.new3(theta, pitch, residuesPerTurn), pt_b_prime };
+ */
+ public static T3[] computeHelicalAxis(P3 a, P3 b, Quat dq) {
+
+ // b
+ // | /|
+ // | / |
+ // | / |
+ // |/ c
+ // b'+ / \
+ // | / \ Vcb = Vab . n
+ // n | / \d Vda = (Vcb - Vab) / 2
+ // |/theta \
+ // a'+---------a
+ // r
+
+ V3 vab = new V3();
+ vab.sub2(b, a);
+ /*
+ * testing here to see if directing the normal makes any difference -- oddly
+ * enough, it does not. When n = -n and theta = -theta vab.n is reversed,
+ * and that magnitude is multiplied by n in generating the A'-B' vector.
+ *
+ * a negative angle implies a left-handed axis (sheets)
+ */
+ float theta = dq.getTheta();
+ V3 n = dq.getNormal();
+ float v_dot_n = vab.dot(n);
+ if (Math.abs(v_dot_n) < 0.0001f)
+ v_dot_n = 0;
+ V3 va_prime_d = new V3();
+ va_prime_d.cross(vab, n);
+ if (va_prime_d.dot(va_prime_d) != 0)
+ va_prime_d.normalize();
+ V3 vda = new V3();
+ V3 vcb = V3.newV(n);
+ if (v_dot_n == 0)
+ v_dot_n = PT.FLOAT_MIN_SAFE; // allow for perpendicular axis to vab
+ vcb.scale(v_dot_n);
+ vda.sub2(vcb, vab);
+ vda.scale(0.5f);
+ va_prime_d.scale(theta == 0 ? 0 : (float) (vda.length() / Math.tan(theta
+ / 2 / 180 * Math.PI)));
+ V3 r = V3.newV(va_prime_d);
+ if (theta != 0)
+ r.add(vda);
+ P3 pt_a_prime = P3.newP(a);
+ pt_a_prime.sub(r);
+ // already done this. ??
+ if (v_dot_n != PT.FLOAT_MIN_SAFE)
+ n.scale(v_dot_n);
+ // must calculate directed angle:
+ P3 pt_b_prime = P3.newP(pt_a_prime);
+ pt_b_prime.add(n);
+ theta = computeTorsion(a, pt_a_prime, pt_b_prime, b, true);
+ if (Float.isNaN(theta) || r.length() < 0.0001f)
+ theta = dq.getThetaDirectedV(n); // allow for r = 0
+ // anything else is an array
+ float residuesPerTurn = Math.abs(theta == 0 ? 0 : 360f / theta);
+ float pitch = Math.abs(v_dot_n == PT.FLOAT_MIN_SAFE ? 0 : n.length()
+ * (theta == 0 ? 1 : 360f / theta));
+ return new T3[] { pt_a_prime, n, r, P3.new3(theta, pitch, residuesPerTurn), pt_b_prime };
+ }
+
+ public static P4 getPlaneThroughPoints(T3 pointA,
+ T3 pointB,
+ T3 pointC, V3 vNorm,
+ V3 vAB, P4 plane) {
+ float w = getNormalThroughPoints(pointA, pointB, pointC, vNorm, vAB);
+ plane.set4(vNorm.x, vNorm.y, vNorm.z, w);
+ return plane;
+ }
+
+ public static void getPlaneThroughPoint(T3 pt, V3 normal, P4 plane) {
+ plane.set4(normal.x, normal.y, normal.z, -normal.dot(pt));
+ }
+
+ public static float distanceToPlane(P4 plane, T3 pt) {
+ return (plane == null ? Float.NaN
+ : (plane.dot(pt) + plane.w) / (float) Math.sqrt(plane.dot(plane)));
+ }
+
+ public static float directedDistanceToPlane(P3 pt, P4 plane, P3 ptref) {
+ float f = plane.dot(pt) + plane.w;
+ float f1 = plane.dot(ptref) + plane.w;
+ return Math.signum(f1) * f / (float) Math.sqrt(plane.dot(plane));
+ }
+
+ public static float distanceToPlaneD(P4 plane, float d, P3 pt) {
+ return (plane == null ? Float.NaN : (plane.dot(pt) + plane.w) / d);
+ }
+
+ public static float distanceToPlaneV(V3 norm, float w, P3 pt) {
+ return (norm == null ? Float.NaN
+ : (norm.dot(pt) + w) / (float) Math.sqrt(norm.dot(norm)));
+ }
+
+ /**
+ * note that if vAB or vAC is dispensible, vNormNorm can be one of them
+ * @param pointA
+ * @param pointB
+ * @param pointC
+ * @param vNormNorm
+ * @param vAB
+ */
+ public static void calcNormalizedNormal(T3 pointA, T3 pointB,
+ T3 pointC, V3 vNormNorm, V3 vAB) {
+ vAB.sub2(pointB, pointA);
+ vNormNorm.sub2(pointC, pointA);
+ vNormNorm.cross(vAB, vNormNorm);
+ vNormNorm.normalize();
+ }
+
+ public static float getDirectedNormalThroughPoints(T3 pointA,
+ T3 pointB, T3 pointC, T3 ptRef, V3 vNorm,
+ V3 vAB) {
+ // for x = plane({atomno=1}, {atomno=2}, {atomno=3}, {atomno=4})
+ float nd = getNormalThroughPoints(pointA, pointB, pointC, vNorm, vAB);
+ if (ptRef != null) {
+ P3 pt0 = P3.newP(pointA);
+ pt0.add(vNorm);
+ float d = pt0.distance(ptRef);
+ pt0.sub2(pointA, vNorm);
+ if (d > pt0.distance(ptRef)) {
+ vNorm.scale(-1);
+ nd = -nd;
+ }
+ }
+ return nd;
+ }
+
+ /**
+ * if vAC is dispensible vNorm can be vAC
+ * @param pointA
+ * @param pointB
+ * @param pointC
+ * @param vNorm
+ * @param vTemp
+ * @return w
+ */
+ public static float getNormalThroughPoints(T3 pointA, T3 pointB,
+ T3 pointC, V3 vNorm, V3 vTemp) {
+ // for Polyhedra
+ calcNormalizedNormal(pointA, pointB, pointC, vNorm, vTemp);
+ // ax + by + cz + d = 0
+ // so if a point is in the plane, then N dot X = -d
+ vTemp.setT(pointA);
+ return -vTemp.dot(vNorm);
+ }
+
+ public static void getPlaneProjection(P3 pt, P4 plane, P3 ptProj, V3 vNorm) {
+ float dist = distanceToPlane(plane, pt);
+ vNorm.set(plane.x, plane.y, plane.z);
+ vNorm.normalize();
+ vNorm.scale(-dist);
+ ptProj.add2(pt, vNorm);
+ }
+
+ public final static V3 axisY = V3.new3(0, 1, 0);
+
+ public static void getNormalToLine(P3 pointA, P3 pointB,
+ V3 vNormNorm) {
+ // vector in xy plane perpendicular to a line between two points RMH
+ vNormNorm.sub2(pointA, pointB);
+ vNormNorm.cross(vNormNorm, axisY);
+ vNormNorm.normalize();
+ if (Float.isNaN(vNormNorm.x))
+ vNormNorm.set(1, 0, 0);
+ }
+
+ public static void getBisectingPlane(P3 pointA, V3 vAB,
+ T3 ptTemp, V3 vTemp, P4 plane) {
+ ptTemp.scaleAdd2(0.5f, vAB, pointA);
+ vTemp.setT(vAB);
+ vTemp.normalize();
+ getPlaneThroughPoint(ptTemp, vTemp, plane);
+ }
+
+ public static void projectOntoAxis(P3 point, P3 axisA,
+ V3 axisUnitVector,
+ V3 vectorProjection) {
+ vectorProjection.sub2(point, axisA);
+ float projectedLength = vectorProjection.dot(axisUnitVector);
+ point.scaleAdd2(projectedLength, axisUnitVector, axisA);
+ vectorProjection.sub2(point, axisA);
+ }
+
+ public static void calcBestAxisThroughPoints(P3[] points, P3 axisA,
+ V3 axisUnitVector,
+ V3 vectorProjection,
+ int nTriesMax) {
+ // just a crude starting point.
+
+ int nPoints = points.length;
+ axisA.setT(points[0]);
+ axisUnitVector.sub2(points[nPoints - 1], axisA);
+ axisUnitVector.normalize();
+
+ /*
+ * We now calculate the least-squares 3D axis
+ * through the helix alpha carbons starting with Vo
+ * as a first approximation.
+ *
+ * This uses the simple 0-centered least squares fit:
+ *
+ * Y = M cross Xi
+ *
+ * minimizing R^2 = SUM(|Y - Yi|^2)
+ *
+ * where Yi is the vector PERPENDICULAR of the point onto axis Vo
+ * and Xi is the vector PROJECTION of the point onto axis Vo
+ * and M is a vector adjustment
+ *
+ * M = SUM_(Xi cross Yi) / sum(|Xi|^2)
+ *
+ * from which we arrive at:
+ *
+ * V = Vo + (M cross Vo)
+ *
+ * Basically, this is just a 3D version of a
+ * standard 2D least squares fit to a line, where we would say:
+ *
+ * y = m xi + b
+ *
+ * D = n (sum xi^2) - (sum xi)^2
+ *
+ * m = [(n sum xiyi) - (sum xi)(sum yi)] / D
+ * b = [(sum yi) (sum xi^2) - (sum xi)(sum xiyi)] / D
+ *
+ * but here we demand that the line go through the center, so we
+ * require (sum xi) = (sum yi) = 0, so b = 0 and
+ *
+ * m = (sum xiyi) / (sum xi^2)
+ *
+ * In 3D we do the same but
+ * instead of x we have Vo,
+ * instead of multiplication we use cross products
+ *
+ * A bit of iteration is necessary.
+ *
+ * Bob Hanson 11/2006
+ *
+ */
+
+ calcAveragePointN(points, nPoints, axisA);
+
+ int nTries = 0;
+ while (nTries++ < nTriesMax
+ && findAxis(points, nPoints, axisA, axisUnitVector, vectorProjection) > 0.001) {
+ }
+
+ /*
+ * Iteration here gets the job done.
+ * We now find the projections of the endpoints onto the axis
+ *
+ */
+
+ P3 tempA = P3.newP(points[0]);
+ projectOntoAxis(tempA, axisA, axisUnitVector, vectorProjection);
+ axisA.setT(tempA);
+ }
+
+ public static float findAxis(P3[] points, int nPoints, P3 axisA,
+ V3 axisUnitVector, V3 vectorProjection) {
+ V3 sumXiYi = new V3();
+ V3 vTemp = new V3();
+ P3 pt = new P3();
+ P3 ptProj = new P3();
+ V3 a = V3.newV(axisUnitVector);
+
+ float sum_Xi2 = 0;
+ for (int i = nPoints; --i >= 0;) {
+ pt.setT(points[i]);
+ ptProj.setT(pt);
+ projectOntoAxis(ptProj, axisA, axisUnitVector,
+ vectorProjection);
+ vTemp.sub2(pt, ptProj);
+ //sum_Yi2 += vTemp.lengthSquared();
+ vTemp.cross(vectorProjection, vTemp);
+ sumXiYi.add(vTemp);
+ sum_Xi2 += vectorProjection.lengthSquared();
+ }
+ V3 m = V3.newV(sumXiYi);
+ m.scale(1 / sum_Xi2);
+ vTemp.cross(m, axisUnitVector);
+ axisUnitVector.add(vTemp);
+ axisUnitVector.normalize();
+ //check for change in direction by measuring vector difference length
+ vTemp.sub2(axisUnitVector, a);
+ return vTemp.length();
+ }
+
+
+ public static void calcAveragePoint(P3 pointA, P3 pointB,
+ P3 pointC) {
+ pointC.set((pointA.x + pointB.x) / 2, (pointA.y + pointB.y) / 2,
+ (pointA.z + pointB.z) / 2);
+ }
+
+ public static void calcAveragePointN(P3[] points, int nPoints,
+ P3 averagePoint) {
+ averagePoint.setT(points[0]);
+ for (int i = 1; i < nPoints; i++)
+ averagePoint.add(points[i]);
+ averagePoint.scale(1f / nPoints);
+ }
+
+ public static Lst<P3> transformPoints(Lst<P3> vPts, M4 m4, P3 center) {
+ Lst<P3> v = new Lst<P3>();
+ for (int i = 0; i < vPts.size(); i++) {
+ P3 pt = P3.newP(vPts.get(i));
+ pt.sub(center);
+ m4.rotTrans(pt);
+ pt.add(center);
+ v.addLast(pt);
+ }
+ return v;
+ }
+
+ public static boolean isInTetrahedron(P3 pt, P3 ptA, P3 ptB,
+ P3 ptC, P3 ptD,
+ P4 plane, V3 vTemp,
+ V3 vTemp2, boolean fullyEnclosed) {
+ boolean b = (distanceToPlane(getPlaneThroughPoints(ptC, ptD, ptA, vTemp, vTemp2, plane), pt) >= 0);
+ if (b != (distanceToPlane(getPlaneThroughPoints(ptA, ptD, ptB, vTemp, vTemp2, plane), pt) >= 0))
+ return false;
+ if (b != (distanceToPlane(getPlaneThroughPoints(ptB, ptD, ptC, vTemp, vTemp2, plane), pt) >= 0))
+ return false;
+ float d = distanceToPlane(getPlaneThroughPoints(ptA, ptB, ptC, vTemp, vTemp2, plane), pt);
+ if (fullyEnclosed)
+ return (b == (d >= 0));
+ float d1 = distanceToPlane(plane, ptD);
+ return d1 * d <= 0 || Math.abs(d1) > Math.abs(d);
+ }
+
+
+ /**
+ *
+ * @param plane1
+ * @param plane2
+ * @return [ point, vector ] or []
+ */
+ public static Lst<Object> getIntersectionPP(P4 plane1, P4 plane2) {
+ float a1 = plane1.x;
+ float b1 = plane1.y;
+ float c1 = plane1.z;
+ float d1 = plane1.w;
+ float a2 = plane2.x;
+ float b2 = plane2.y;
+ float c2 = plane2.z;
+ float d2 = plane2.w;
+ V3 norm1 = V3.new3(a1, b1, c1);
+ V3 norm2 = V3.new3(a2, b2, c2);
+ V3 nxn = new V3();
+ nxn.cross(norm1, norm2);
+ float ax = Math.abs(nxn.x);
+ float ay = Math.abs(nxn.y);
+ float az = Math.abs(nxn.z);
+ float x, y, z, diff;
+ int type = (ax > ay ? (ax > az ? 1 : 3) : ay > az ? 2 : 3);
+ switch(type) {
+ case 1:
+ x = 0;
+ diff = (b1 * c2 - b2 * c1);
+ if (Math.abs(diff) < 0.01) return null;
+ y = (c1 * d2 - c2 * d1) / diff;
+ z = (b2 * d1 - d2 * b1) / diff;
+ break;
+ case 2:
+ diff = (a1 * c2 - a2 * c1);
+ if (Math.abs(diff) < 0.01) return null;
+ x = (c1 * d2 - c2 * d1) / diff;
+ y = 0;
+ z = (a2 * d1 - d2 * a1) / diff;
+ break;
+ case 3:
+ default:
+ diff = (a1 * b2 - a2 * b1);
+ if (Math.abs(diff) < 0.01) return null;
+ x = (b1 * d2 - b2 * d1) / diff;
+ y = (a2 * d1 - d2 * a1) / diff;
+ z = 0;
+ }
+ Lst<Object>list = new Lst<Object>();
+ list.addLast(P3.new3(x, y, z));
+ nxn.normalize();
+ list.addLast(nxn);
+ return list;
+ }
+
+ /**
+ *
+ * @param pt1 point on line
+ * @param v unit vector of line
+ * @param plane
+ * @param ptRet point of intersection of line with plane
+ * @param tempNorm
+ * @param vTemp
+ * @return ptRtet
+ */
+ public static P3 getIntersection(P3 pt1, V3 v,
+ P4 plane, P3 ptRet, V3 tempNorm, V3 vTemp) {
+ getPlaneProjection(pt1, plane, ptRet, tempNorm);
+ tempNorm.set(plane.x, plane.y, plane.z);
+ tempNorm.normalize();
+ if (v == null)
+ v = V3.newV(tempNorm);
+ float l_dot_n = v.dot(tempNorm);
+ if (Math.abs(l_dot_n) < 0.01) return null;
+ vTemp.sub2(ptRet, pt1);
+ ptRet.scaleAdd2(vTemp.dot(tempNorm) / l_dot_n, v, pt1);
+ return ptRet;
+ }
+
+ /*
+ public static Point3f getTriangleIntersection(Point3f a1, Point3f a2,
+ Point3f a3, Point4f plane,
+ Point3f b1,
+ Point3f b2, Point3f b3,
+ Vector3f vNorm, Vector3f vTemp,
+ Point3f ptRet, Point3f ptTemp, Vector3f vTemp2, Point4f pTemp, Vector3f vTemp3) {
+
+ if (getTriangleIntersection(b1, b2, a1, a2, a3, vTemp, plane, vNorm, vTemp2, vTemp3, ptRet, ptTemp))
+ return ptRet;
+ if (getTriangleIntersection(b2, b3, a1, a2, a3, vTemp, plane, vNorm, vTemp2, vTemp3, ptRet, ptTemp))
+ return ptRet;
+ if (getTriangleIntersection(b3, b1, a1, a2, a3, vTemp, plane, vNorm, vTemp2, vTemp3, ptRet, ptTemp))
+ return ptRet;
+ return null;
+ }
+ */
+ /*
+ public static boolean getTriangleIntersection(Point3f b1, Point3f b2,
+ Point3f a1, Point3f a2,
+ Point3f a3, Vector3f vTemp,
+ Point4f plane, Vector3f vNorm,
+ Vector3f vTemp2, Vector3f vTemp3,
+ Point3f ptRet,
+ Point3f ptTemp) {
+ if (distanceToPlane(plane, b1) * distanceToPlane(plane, b2) >= 0)
+ return false;
+ vTemp.sub(b2, b1);
+ vTemp.normalize();
+ if (getIntersection(b1, vTemp, plane, ptRet, vNorm, vTemp2) != null) {
+ if (isInTriangle(ptRet, a1, a2, a3, vTemp, vTemp2, vTemp3))
+ return true;
+ }
+ return false;
+ }
+ private static boolean isInTriangle(Point3f p, Point3f a, Point3f b,
+ Point3f c, Vector3f v0, Vector3f v1,
+ Vector3f v2) {
+ // from http://www.blackpawn.com/texts/pointinpoly/default.html
+ // Compute barycentric coordinates
+ v0.sub(c, a);
+ v1.sub(b, a);
+ v2.sub(p, a);
+ float dot00 = v0.dot(v0);
+ float dot01 = v0.dot(v1);
+ float dot02 = v0.dot(v2);
+ float dot11 = v1.dot(v1);
+ float dot12 = v1.dot(v2);
+ float invDenom = 1 / (dot00 * dot11 - dot01 * dot01);
+ float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
+ float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
+ return (u > 0 && v > 0 && u + v < 1);
+ }
+ */
+
+ /**
+ * Closed-form solution of absolute orientation requiring 1:1 mapping of
+ * positions.
+ *
+ * @param centerAndPoints
+ * @param retStddev
+ * @return unit quaternion representation rotation
+ *
+ * @author hansonr Bob Hanson
+ *
+ */
+ public static Quat calculateQuaternionRotation(P3[][] centerAndPoints,
+ float[] retStddev) {
+
+ retStddev[1] = Float.NaN;
+ Quat q = new Quat();
+ if (centerAndPoints[0].length == 1
+ || centerAndPoints[0].length != centerAndPoints[1].length)
+ return q;
+
+ /*
+ * see Berthold K. P. Horn,
+ * "Closed-form solution of absolute orientation using unit quaternions" J.
+ * Opt. Soc. Amer. A, 1987, Vol. 4, pp. 629-642
+ * http://www.opticsinfobase.org/viewmedia.cfm?uri=josaa-4-4-629&seq=0
+ *
+ *
+ * A similar treatment was developed independently (and later!)
+ * by G. Kramer, in G. R. Kramer,
+ * "Superposition of Molecular Structures Using Quaternions"
+ * Molecular Simulation, 1991, Vol. 7, pp. 113-119.
+ *
+ * In that treatment there is a lot of unnecessary calculation
+ * along the trace of matrix M (eqn 20).
+ * I'm not sure why the extra x^2 + y^2 + z^2 + x'^2 + y'^2 + z'^2
+ * is in there, but they are unnecessary and only contribute to larger
+ * numerical averaging errors and additional processing time, as far as
+ * I can tell. Adding aI, where a is a scalar and I is the 4x4 identity
+ * just offsets the eigenvalues but doesn't change the eigenvectors.
+ *
+ * and Lydia E. Kavraki, "Molecular Distance Measures"
+ * http://cnx.org/content/m11608/latest/
+ *
+ */
+
+ int n = centerAndPoints[0].length - 1;
+ if (n < 2)
+ return q;
+
+ double Sxx = 0, Sxy = 0, Sxz = 0, Syx = 0, Syy = 0, Syz = 0, Szx = 0, Szy = 0, Szz = 0;
+ P3 ptA = new P3();
+ P3 ptB = new P3();
+ for (int i = n + 1; --i >= 1;) {
+ P3 aij = centerAndPoints[0][i];
+ P3 bij = centerAndPoints[1][i];
+ ptA.sub2(aij, centerAndPoints[0][0]);
+ ptB.sub2(bij, centerAndPoints[0][1]);
+ Sxx += (double) ptA.x * (double) ptB.x;
+ Sxy += (double) ptA.x * (double) ptB.y;
+ Sxz += (double) ptA.x * (double) ptB.z;
+ Syx += (double) ptA.y * (double) ptB.x;
+ Syy += (double) ptA.y * (double) ptB.y;
+ Syz += (double) ptA.y * (double) ptB.z;
+ Szx += (double) ptA.z * (double) ptB.x;
+ Szy += (double) ptA.z * (double) ptB.y;
+ Szz += (double) ptA.z * (double) ptB.z;
+ }
+ retStddev[0] = getRmsd(centerAndPoints, q);
+ double[][] N = new double[4][4];
+ N[0][0] = Sxx + Syy + Szz;
+ N[0][1] = N[1][0] = Syz - Szy;
+ N[0][2] = N[2][0] = Szx - Sxz;
+ N[0][3] = N[3][0] = Sxy - Syx;
+
+ N[1][1] = Sxx - Syy - Szz;
+ N[1][2] = N[2][1] = Sxy + Syx;
+ N[1][3] = N[3][1] = Szx + Sxz;
+
+ N[2][2] = -Sxx + Syy - Szz;
+ N[2][3] = N[3][2] = Syz + Szy;
+
+ N[3][3] = -Sxx - Syy + Szz;
+
+ //this construction prevents JavaScript from requiring preloading of Eigen
+
+ float[] v = ((EigenInterface) Interface.getInterface("javajs.util.Eigen"))
+ .setM(N).getEigenvectorsFloatTransposed()[3];
+ q = Quat.newP4(P4.new4(v[1], v[2], v[3], v[0]));
+ retStddev[1] = getRmsd(centerAndPoints, q);
+ return q;
+ }
+
+ /**
+ * Fills a 4x4 matrix with rotation-translation of mapped points A to B.
+ * If centerA is null, this is a standard 4x4 rotation-translation matrix;
+ * otherwise, this 4x4 matrix is a rotation around a vector through the center of ptsA,
+ * and centerA is filled with that center;
+ * Prior to Jmol 14.3.12_2014.02.14, when used from the JmolScript compare() function,
+ * this method returned the second of these options instead of the first.
+ *
+ * @param ptsA
+ * @param ptsB
+ * @param m 4x4 matrix to be returned
+ * @param centerA return center of rotation; if null, then standard 4x4 matrix is returned
+ * @return stdDev
+ */
+ public static float getTransformMatrix4(Lst<P3> ptsA, Lst<P3> ptsB, M4 m,
+ P3 centerA) {
+ P3[] cptsA = getCenterAndPoints(ptsA);
+ P3[] cptsB = getCenterAndPoints(ptsB);
+ float[] retStddev = new float[2];
+ Quat q = calculateQuaternionRotation(new P3[][] { cptsA, cptsB },
+ retStddev);
+ M3 r = q.getMatrix();
+ if (centerA == null)
+ r.rotate(cptsA[0]);
+ else
+ centerA.setT(cptsA[0]);
+ V3 t = V3.newVsub(cptsB[0], cptsA[0]);
+ m.setMV(r, t);
+ return retStddev[1];
+ }
+
+ /**
+ * from a list of points, create an array that includes the center
+ * point as the first point. This array is used as a starting point for
+ * a quaternion analysis of superposition.
+ *
+ * @param vPts
+ * @return array of points with first point center
+ */
+ public static P3[] getCenterAndPoints(Lst<P3> vPts) {
+ int n = vPts.size();
+ P3[] pts = new P3[n + 1];
+ pts[0] = new P3();
+ if (n > 0) {
+ for (int i = 0; i < n; i++) {
+ pts[0].add(pts[i + 1] = vPts.get(i));
+ }
+ pts[0].scale(1f / n);
+ }
+ return pts;
+ }
+
+ public static float getRmsd(P3[][] centerAndPoints, Quat q) {
+ double sum2 = 0;
+ P3[] ptsA = centerAndPoints[0];
+ P3[] ptsB = centerAndPoints[1];
+ P3 cA = ptsA[0];
+ P3 cB = ptsB[0];
+ int n = ptsA.length - 1;
+ P3 ptAnew = new P3();
+
+ for (int i = n + 1; --i >= 1;) {
+ ptAnew.sub2(ptsA[i], cA);
+ q.transform2(ptAnew, ptAnew).add(cB);
+ sum2 += ptAnew.distanceSquared(ptsB[i]);
+ }
+ return (float) Math.sqrt(sum2 / n);
+ }
+
+}
--- /dev/null
+package javajs.util;
+
+import java.io.BufferedWriter;
+import java.io.ByteArrayOutputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+
+
+
+import javajs.J2SIgnoreImport;
+import javajs.api.BytePoster;
+import javajs.api.JmolObjectInterface;
+
+/**
+ *
+ * A generic output method. JmolOutputChannel can be used to:
+ *
+ * add characters to a StringBuffer
+ * using fileName==null, append() and toString()
+ *
+ * add bytes utilizing ByteArrayOutputStream
+ * using writeBytes(), writeByteAsInt(), append()*, and bytesAsArray()
+ * *append() can be used as long as os==ByteArrayOutputStream
+ * or it is not used before one of the writeByte methods.
+ *
+ * output characters to a FileOutputStream
+ * using os==FileOutputStream, asWriter==true, append(), and closeChannel()
+ *
+ * output bytes to a FileOutputStream
+ * using os==FileOutputStream, writeBytes(), writeByteAsInt(), append(), and closeChannel()
+ *
+ * post characters or bytes to a remote server
+ * using fileName=="http://..." or "https://...",
+ * writeBytes(), writeByteAsInt(), append(), and closeChannel()
+ *
+ * send characters or bytes to a JavaScript function
+ * when JavaScript and (typeof fileName == "function")
+ *
+ * if fileName equals ";base64,", then the data are base64-encoded
+ * prior to writing, and closeChannel() returns the data.
+ *
+ * @author hansonr Bob Hanson hansonr@stolaf.edu 9/2013
+ *
+ *
+ */
+
+@J2SIgnoreImport({ java.io.FileOutputStream.class })
+public class OC extends OutputStream {
+
+ private BytePoster bytePoster; // only necessary for writing to http:// or https://
+ private String fileName;
+ private BufferedWriter bw;
+ private boolean isLocalFile;
+ private int byteCount;
+ private boolean isCanceled;
+ private boolean closed;
+ private OutputStream os;
+ private SB sb;
+ private String type;
+ private boolean isBase64;
+ private OutputStream os0;
+ private byte[] bytes; // preset bytes; output only
+
+ public OC setParams(BytePoster bytePoster, String fileName,
+ boolean asWriter, OutputStream os) {
+ this.bytePoster = bytePoster;
+ this.fileName = fileName;
+ isBase64 = ";base64,".equals(fileName);
+ if (isBase64) {
+ fileName = null;
+ os0 = os;
+ os = null;
+ }
+ this.os = os;
+ isLocalFile = (fileName != null && !isRemote(fileName));
+ if (asWriter && !isBase64 && os != null)
+ bw = new BufferedWriter(new OutputStreamWriter(os));
+ return this;
+ }
+
+ public OC setBytes(byte[] b) {
+ bytes = b;
+ return this;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public String getName() {
+ return (fileName == null ? null : fileName.substring(fileName.lastIndexOf("/") + 1));
+ }
+
+ public int getByteCount() {
+ return byteCount;
+ }
+
+ /**
+ *
+ * @param type user-identified type (PNG, JPG, etc)
+ */
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ /**
+ * will go to string buffer if bw == null and os == null
+ *
+ * @param s
+ * @return this, for chaining like a standard StringBuffer
+ *
+ */
+ public OC append(String s) {
+ try {
+ if (bw != null) {
+ bw.write(s);
+ } else if (os == null) {
+ if (sb == null)
+ sb = new SB();
+ sb.append(s);
+ } else {
+ byte[] b = s.getBytes();
+ os.write(b, 0, b.length);
+ byteCount += b.length;
+ return this;
+ }
+ } catch (IOException e) {
+ // ignore
+ }
+ byteCount += s.length(); // not necessarily exactly correct if unicode
+ return this;
+ }
+
+ public void reset() {
+ sb = null;
+ initOS();
+ }
+
+
+ private void initOS() {
+ if (sb != null) {
+ String s = sb.toString();
+ reset();
+ append(s);
+ return;
+ }
+ try {
+ /**
+ * @j2sNative
+ *
+ * this.os = null;
+ */
+ {
+ if (os instanceof FileOutputStream) {
+ os.close();
+ os = new FileOutputStream(fileName);
+ } else {
+ os = null;
+ }
+ }
+ if (os == null)
+ os = new ByteArrayOutputStream();
+ if (bw != null) {
+ bw.close();
+ bw = new BufferedWriter(new OutputStreamWriter(os));
+ }
+ } catch (Exception e) {
+ // not perfect here.
+ System.out.println(e.toString());
+ }
+ byteCount = 0;
+ }
+
+ /**
+ * @j2sOverride
+ */
+ @Override
+ public void write(byte[] buf, int i, int len) {
+ if (os == null)
+ initOS();
+ try {
+ os.write(buf, i, len);
+ } catch (IOException e) {
+ }
+ byteCount += len;
+ }
+
+ /**
+ * @param b
+ */
+ public void writeByteAsInt(int b) {
+ if (os == null)
+ initOS();
+ /**
+ * @j2sNative
+ *
+ * this.os.writeByteAsInt(b);
+ *
+ */
+ {
+ try {
+ os.write(b);
+ } catch (IOException e) {
+ }
+ }
+ byteCount++;
+ }
+
+ /**
+ * Will break JavaScript if used.
+ *
+ * @j2sIgnore
+ *
+ * @param b
+ */
+ @Override
+ @Deprecated
+ public void write(int b) {
+ // required by standard ZipOutputStream -- do not use, as it will break JavaScript methods
+ if (os == null)
+ initOS();
+ try {
+ os.write(b);
+ } catch (IOException e) {
+ }
+ byteCount++;
+ }
+
+// /**
+// * Will break if used; no equivalent in JavaScript.
+// *
+// * @j2sIgnore
+// *
+// * @param b
+// */
+// @Override
+// @Deprecated
+// public void write(byte[] b) {
+// // not used in JavaScript due to overloading problem there
+// write(b, 0, b.length);
+// }
+
+ public void cancel() {
+ isCanceled = true;
+ closeChannel();
+ }
+
+ @SuppressWarnings({ "null", "unused" })
+ public String closeChannel() {
+ if (closed)
+ return null;
+ // can't cancel file writers
+ try {
+ if (bw != null) {
+ bw.flush();
+ bw.close();
+ } else if (os != null) {
+ os.flush();
+ os.close();
+ }
+ if (os0 != null && isCanceled) {
+ os0.flush();
+ os0.close();
+ }
+ } catch (Exception e) {
+ // ignore closing issues
+ }
+ if (isCanceled) {
+ closed = true;
+ return null;
+ }
+ if (fileName == null) {
+ if (isBase64) {
+ String s = getBase64();
+ if (os0 != null) {
+ os = os0;
+ append(s);
+ }
+ sb = new SB();
+ sb.append(s);
+ isBase64 = false;
+ return closeChannel();
+ }
+ return (sb == null ? null : sb.toString());
+ }
+ closed = true;
+ JmolObjectInterface jmol = null;
+ Object _function = null;
+ /**
+ * @j2sNative
+ *
+ * jmol = Jmol; _function = (typeof this.fileName == "function" ?
+ * this.fileName : null);
+ *
+ */
+ {
+ if (!isLocalFile) {
+ String ret = postByteArray(); // unsigned applet could do this
+ if (ret.startsWith("java.net"))
+ byteCount = -1;
+ return ret;
+ }
+ }
+ if (jmol != null) {
+ Object data = (sb == null ? toByteArray() : sb.toString());
+ if (_function == null)
+ jmol._doAjax(fileName, null, data);
+ else
+ jmol._apply(fileName, data);
+ }
+ return null;
+ }
+
+ public boolean isBase64() {
+ return isBase64;
+ }
+
+ public String getBase64() {
+ return Base64.getBase64(toByteArray()).toString();
+ }
+
+ public byte[] toByteArray() {
+ return (bytes != null ? bytes : os instanceof ByteArrayOutputStream ? ((ByteArrayOutputStream)os).toByteArray() : null);
+ }
+
+ @Override
+ @Deprecated
+ public void close() {
+ closeChannel();
+ }
+
+ @Override
+ public String toString() {
+ if (bw != null)
+ try {
+ bw.flush();
+ } catch (IOException e) {
+ // TODO
+ }
+ if (sb != null)
+ return closeChannel();
+ return byteCount + " bytes";
+ }
+
+ private String postByteArray() {
+ byte[] bytes = (sb == null ? toByteArray() : sb.toString().getBytes());
+ return bytePoster.postByteArray(fileName, bytes);
+ }
+
+ public final static String[] urlPrefixes = { "http:", "https:", "sftp:", "ftp:",
+ "file:" };
+ // note that SFTP is not supported
+ public final static int URL_LOCAL = 4;
+
+ public static boolean isRemote(String fileName) {
+ if (fileName == null)
+ return false;
+ int itype = urlTypeIndex(fileName);
+ return (itype >= 0 && itype != URL_LOCAL);
+ }
+
+ public static boolean isLocal(String fileName) {
+ if (fileName == null)
+ return false;
+ int itype = urlTypeIndex(fileName);
+ return (itype < 0 || itype == URL_LOCAL);
+ }
+
+ public static int urlTypeIndex(String name) {
+ if (name == null)
+ return -2; // local unsigned applet
+ for (int i = 0; i < urlPrefixes.length; ++i) {
+ if (name.startsWith(urlPrefixes[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+
+
+/**
+ * A 3 element point that is represented by single precision floating point
+ * x,y,z coordinates.
+ *
+ * @version specification 1.1, implementation $Revision: 1.10 $, $Date:
+ * 2006/09/08 20:20:20 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
+ * for unique constructor and method names
+ * for the optimization of compiled JavaScript using Java2Script
+ *
+ */
+public class P3 extends T3 {
+
+ /**
+ * @j2sIgnore
+ */
+ public P3() {
+ // ignore T3
+ }
+
+ public static P3 newP(T3 t) {
+ P3 p = new P3();
+ p.x = t.x;
+ p.y = t.y;
+ p.z = t.z;
+ return p;
+ }
+
+ private static P3 unlikely;
+
+ public static P3 getUnlikely() {
+ return (unlikely == null ? unlikely = new3((float) Math.PI, (float) Math.E, (float) (Math.PI * Math.E)) : unlikely);
+ }
+
+ public static P3 new3(float x, float y, float z) {
+ P3 p = new P3();
+ p.x = x;
+ p.y = y;
+ p.z = z;
+ return p;
+ }
+
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+
+
+/**
+ * A 3 element point that is represented by signed integer x,y,z coordinates.
+ *
+ * @since Java 3D 1.2
+ * @version specification 1.2, implementation $Revision: 1.9 $, $Date:
+ * 2006/07/28 17:01:33 $
+ * @author Kenji hiranabe
+ *
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
+ * constructor and method names for the optimization of compiled
+ * JavaScript using Java2Script
+ */
+public class P3i extends T3i {
+
+ public static P3i new3(int x, int y, int z) {
+ P3i pt = new P3i();
+ pt.x = x;
+ pt.y = y;
+ pt.z = z;
+ return pt;
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+
+
+/**
+ * A 4 element point that is represented by single precision floating point
+ * x,y,z,w coordinates.
+ *
+ * @version specification 1.1, implementation $Revision: 1.9 $, $Date:
+ * 2006/07/28 17:01:32 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
+ * for unique constructor and method names
+ * for the optimization of compiled JavaScript using Java2Script
+ */
+public class P4 extends T4 {
+
+ /**
+ *
+ * @j2sIgnore *
+ */
+ public P4() {
+ // skip T4() constructor
+ }
+
+ public static P4 new4(float x, float y, float z, float w) {
+ P4 pt = new P4();
+ pt.set4(x, y, z, w);
+ return pt;
+ }
+
+ public static P4 newPt(P4 value) {
+ P4 pt = new P4();
+ pt.set4(value.x, value.y, value.z, value.w);
+ return pt;
+ }
+
+ /**
+ * Returns the distance between this point and point p1.
+ *
+ * @param p1
+ * the other point
+ * @return the distance between these two points
+ */
+ public final float distance4(P4 p1) {
+ double dx = x - p1.x;
+ double dy = y - p1.y;
+ double dz = z - p1.z;
+ double dw = w - p1.w;
+ return (float) Math.sqrt(dx * dx + dy * dy + dz * dz + dw * dw);
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2007-04-26 16:57:51 -0500 (Thu, 26 Apr 2007) $
+ * $Revision: 7502 $
+ *
+ * Copyright (C) 2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+package javajs.util;
+
+import java.lang.reflect.Array;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import javajs.J2SIgnoreImport;
+import javajs.api.JSONEncodable;
+
+/**
+ * a combination of Parsing and Text-related utility classes
+ *
+ * @author hansonr
+ *
+ */
+
+@J2SIgnoreImport(value = { java.lang.reflect.Array.class })
+public class PT {
+
+ public static int parseInt(String str) {
+ return parseIntNext(str, new int[] {0});
+ }
+
+ public static int parseIntNext(String str, int[] next) {
+ int cch = str.length();
+ if (next[0] < 0 || next[0] >= cch)
+ return Integer.MIN_VALUE;
+ return parseIntChecked(str, cch, next);
+ }
+
+ public static int parseIntChecked(String str, int ichMax, int[] next) {
+ boolean digitSeen = false;
+ int value = 0;
+ int ich = next[0];
+ if (ich < 0)
+ return Integer.MIN_VALUE;
+ int ch;
+ while (ich < ichMax && isWhiteSpace(str, ich))
+ ++ich;
+ boolean negative = false;
+ if (ich < ichMax && str.charAt(ich) == 45) { //"-"
+ negative = true;
+ ++ich;
+ }
+ while (ich < ichMax && (ch = str.charAt(ich)) >= 48 && ch <= 57) {
+ value = value * 10 + (ch - 48);
+ digitSeen = true;
+ ++ich;
+ }
+ if (!digitSeen)// || !checkTrailingText(str, ich, ichMax))
+ value = Integer.MIN_VALUE;
+ else if (negative)
+ value = -value;
+ next[0] = ich;
+ return value;
+ }
+
+ public static boolean isWhiteSpace(String str, int ich) {
+ char ch;
+ return (ich >= 0 && ((ch = str.charAt(ich)) == ' ' || ch == '\t' || ch == '\n'));
+ }
+
+ /**
+ * A float parser that is 30% faster than Float.parseFloat(x) and also accepts
+ * x.yD+-n
+ *
+ * @param str
+ * @param ichMax
+ * @param next
+ * pointer; incremented
+ * @param isStrict
+ * @return value or Float.NaN
+ */
+ public static float parseFloatChecked(String str, int ichMax, int[] next,
+ boolean isStrict) {
+ boolean digitSeen = false;
+ int ich = next[0];
+ if (isStrict && str.indexOf('\n') != str.lastIndexOf('\n'))
+ return Float.NaN;
+ while (ich < ichMax && isWhiteSpace(str, ich))
+ ++ich;
+ boolean negative = false;
+ if (ich < ichMax && str.charAt(ich) == '-') {
+ ++ich;
+ negative = true;
+ }
+ // looks crazy, but if we don't do this, Google Closure Compiler will
+ // write code that Safari will misinterpret in a VERY nasty way --
+ // getting totally confused as to long integers and double values
+
+ // This is Safari figuring out the values of the numbers on the line (x, y, then z):
+
+ // ATOM 1241 CD1 LEU A 64 -2.206 36.532 31.576 1.00 60.60 C
+ // e=1408749273
+ // -e =-1408749273
+ // ATOM 1241 CD1 LEU A 64 -2.206 36.532 31.576 1.00 60.60 C
+ // e=-1821066134
+ // e=36.532
+ // ATOM 1241 CD1 LEU A 64 -2.206 36.532 31.576 1.00 60.60 C
+ // e=-1133871366
+ // e=31.576
+ //
+ // "e" values are just before and after the "value = -value" statement.
+
+ int ch = 0;
+ float ival = 0f;
+ float ival2 = 0f;
+ while (ich < ichMax && (ch = str.charAt(ich)) >= 48 && ch <= 57) {
+ ival = (ival * 10f) + (ch - 48)*1f;
+ ++ich;
+ digitSeen = true;
+ }
+ boolean isDecimal = false;
+ int iscale = 0;
+ int nzero = (ival == 0 ? -1 : 0);
+ if (ch == '.') {
+ isDecimal = true;
+ while (++ich < ichMax && (ch = str.charAt(ich)) >= 48 && ch <= 57) {
+ digitSeen = true;
+ if (nzero < 0) {
+ if (ch == 48) {
+ nzero--;
+ continue;
+ }
+ nzero = -nzero;
+ }
+ if (iscale < decimalScale.length) {
+ ival2 = (ival2 * 10f) + (ch - 48)*1f;
+ iscale++;
+ }
+ }
+ }
+ float value;
+
+ // Safari breaks here intermittently converting integers to floats
+
+ if (!digitSeen) {
+ value = Float.NaN;
+ } else if (ival2 > 0) {
+ value = ival2 * decimalScale[iscale - 1];
+ if (nzero > 1) {
+ if (nzero - 2 < decimalScale.length) {
+ value *= decimalScale[nzero - 2];
+ } else {
+ value *= Math.pow(10, 1 - nzero);
+ }
+ } else {
+ value += ival;
+ }
+ } else {
+ value = ival;
+ }
+ boolean isExponent = false;
+ if (ich < ichMax && (ch == 69 || ch == 101 || ch == 68)) { // E e D
+ isExponent = true;
+ if (++ich >= ichMax)
+ return Float.NaN;
+ ch = str.charAt(ich);
+ if ((ch == '+') && (++ich >= ichMax))
+ return Float.NaN;
+ next[0] = ich;
+ int exponent = parseIntChecked(str, ichMax, next);
+ if (exponent == Integer.MIN_VALUE)
+ return Float.NaN;
+ if (exponent > 0 && exponent <= tensScale.length)
+ value *= tensScale[exponent - 1];
+ else if (exponent < 0 && -exponent <= decimalScale.length)
+ value *= decimalScale[-exponent - 1];
+ else if (exponent != 0)
+ value *= Math.pow(10, exponent);
+ } else {
+ next[0] = ich; // the exponent code finds its own ichNextParse
+ }
+ // believe it or not, Safari reports the long-equivalent of the
+ // float value here, then later the float value, after no operation!
+ if (negative)
+ value = -value;
+ if (value == Float.POSITIVE_INFINITY)
+ value = Float.MAX_VALUE;
+ return (!isStrict || (!isExponent || isDecimal)
+ && checkTrailingText(str, next[0], ichMax) ? value : Float.NaN);
+ }
+
+ public final static float[] tensScale = { 10f, 100f, 1000f, 10000f, 100000f, 1000000f };
+ public final static float[] decimalScale = {
+ 0.1f,
+ 0.01f,
+ 0.001f,
+ 0.0001f,
+ 0.00001f,
+ 0.000001f,
+ 0.0000001f,
+ 0.00000001f,
+ 0.000000001f
+ };
+ public static boolean checkTrailingText(String str, int ich, int ichMax) {
+ //number must be pure -- no additional characters other than white space or ;
+ char ch;
+ while (ich < ichMax && (isWhitespace(ch = str.charAt(ich)) || ch == ';'))
+ ++ich;
+ return (ich == ichMax);
+ }
+
+ public static float[] parseFloatArray(String str) {
+ return parseFloatArrayNext(str, new int[1], null, null, null);
+ }
+
+ public static int parseFloatArrayInfested(String[] tokens, float[] data) {
+ int len = data.length;
+ int nTokens = tokens.length;
+ int n = 0;
+ int max = 0;
+ for (int i = 0; i >= 0 && i < len && n < nTokens; i++) {
+ float f;
+ while (Float.isNaN(f = parseFloat(tokens[n++]))
+ && n < nTokens) {
+ }
+ if (!Float.isNaN(f))
+ data[(max = i)] = f;
+ if (n == nTokens)
+ break;
+ }
+ return max + 1;
+ }
+
+ /**
+ * @param str
+ * @param next
+ * @param f
+ * @param strStart or null
+ * @param strEnd or null
+ * @return array of float values
+ *
+ */
+ public static float[] parseFloatArrayNext(String str, int[] next, float[] f,
+ String strStart, String strEnd) {
+ int n = 0;
+ int pt = next[0];
+ if (pt >= 0) {
+ if (strStart != null) {
+ int p = str.indexOf(strStart, pt);
+ if (p >= 0)
+ next[0] = p + strStart.length();
+ }
+ str = str.substring(next[0]);
+ pt = (strEnd == null ? -1 : str.indexOf(strEnd));
+ if (pt < 0)
+ pt = str.length();
+ else
+ str = str.substring(0, pt);
+ next[0] += pt + 1;
+ String[] tokens = getTokens(str);
+ if (f == null)
+ f = new float[tokens.length];
+ n = parseFloatArrayInfested(tokens, f);
+ }
+ if (f == null)
+ return new float[0];
+ for (int i = n; i < f.length; i++)
+ f[i] = Float.NaN;
+ return f;
+ }
+
+ public static float parseFloatRange(String str, int ichMax, int[] next) {
+ int cch = str.length();
+ if (ichMax > cch)
+ ichMax = cch;
+ if (next[0] < 0 || next[0] >= ichMax)
+ return Float.NaN;
+ return parseFloatChecked(str, ichMax, next, false);
+ }
+
+ public static float parseFloatNext(String str, int[] next) {
+ int cch = (str == null ? -1 : str.length());
+ return (next[0] < 0 || next[0] >= cch ? Float.NaN : parseFloatChecked(str, cch, next, false));
+ }
+
+ public static float parseFloatStrict(String str) {
+ // checks trailing characters and does not allow "1E35" to be float
+ int cch = str.length();
+ if (cch == 0)
+ return Float.NaN;
+ return parseFloatChecked(str, cch, new int[] {0}, true);
+ }
+
+ public static float parseFloat(String str) {
+ return parseFloatNext(str, new int[] {0});
+ }
+
+ public static int parseIntRadix(String s, int i) throws NumberFormatException {
+ /**
+ *
+ * JavaScript uses parseIntRadix
+ *
+ * @j2sNative
+ *
+ * return Integer.parseIntRadix(s, i);
+ *
+ */
+ {
+ return Integer.parseInt(s, i);
+ }
+ }
+
+ public static String[] getTokens(String line) {
+ return getTokensAt(line, 0);
+ }
+
+ public static String parseToken(String str) {
+ return parseTokenNext(str, new int[] {0});
+ }
+
+ public static String parseTrimmed(String str) {
+ return parseTrimmedRange(str, 0, str.length());
+ }
+
+ public static String parseTrimmedAt(String str, int ichStart) {
+ return parseTrimmedRange(str, ichStart, str.length());
+ }
+
+ public static String parseTrimmedRange(String str, int ichStart, int ichMax) {
+ int cch = str.length();
+ if (ichMax < cch)
+ cch = ichMax;
+ if (cch < ichStart)
+ return "";
+ return parseTrimmedChecked(str, ichStart, cch);
+ }
+
+ public static String[] getTokensAt(String line, int ich) {
+ if (line == null)
+ return null;
+ int cchLine = line.length();
+ if (ich < 0 || ich > cchLine)
+ return null;
+ int tokenCount = countTokens(line, ich);
+ String[] tokens = new String[tokenCount];
+ int[] next = new int[1];
+ next[0] = ich;
+ for (int i = 0; i < tokenCount; ++i)
+ tokens[i] = parseTokenChecked(line, cchLine, next);
+ return tokens;
+ }
+
+ public static int countChar(String line, char c) {
+ int tokenCount = 0;
+ int pt = -1;
+ while ((pt = line.indexOf(c, pt + 1)) >= 0)
+ tokenCount++;
+ return tokenCount;
+ }
+
+ public static int countTokens(String line, int ich) {
+ int tokenCount = 0;
+ if (line != null) {
+ int ichMax = line.length();
+ while (true) {
+ while (ich < ichMax && isWhiteSpace(line, ich))
+ ++ich;
+ if (ich == ichMax)
+ break;
+ ++tokenCount;
+ do {
+ ++ich;
+ } while (ich < ichMax && !isWhiteSpace(line, ich));
+ }
+ }
+ return tokenCount;
+ }
+
+ public static String parseTokenNext(String str, int[] next) {
+ int cch = str.length();
+ return (next[0] < 0 || next[0] >= cch ? null : parseTokenChecked(str, cch, next));
+ }
+
+ public static String parseTokenRange(String str, int ichMax, int[] next) {
+ int cch = str.length();
+ if (ichMax > cch)
+ ichMax = cch;
+ return (next[0] < 0 || next[0] >= ichMax ? null : parseTokenChecked(str, ichMax, next));
+ }
+
+ public static String parseTokenChecked(String str, int ichMax, int[] next) {
+ int ich = next[0];
+ while (ich < ichMax && isWhiteSpace(str, ich))
+ ++ich;
+ int ichNonWhite = ich;
+ while (ich < ichMax && !isWhiteSpace(str, ich))
+ ++ich;
+ next[0] = ich;
+ return (ichNonWhite == ich ? null : str.substring(ichNonWhite, ich));
+ }
+
+ public static String parseTrimmedChecked(String str, int ich, int ichMax) {
+ while (ich < ichMax && isWhiteSpace(str, ich))
+ ++ich;
+ int ichLast = ichMax - 1;
+ while (ichLast >= ich && isWhiteSpace(str, ichLast))
+ --ichLast;
+ return (ichLast < ich ? "" : str.substring(ich, ichLast + 1));
+ }
+
+ public static double dVal(String s) throws NumberFormatException {
+ /**
+ * @j2sNative
+ *
+ * if(s==null)
+ * throw new NumberFormatException("null");
+ * var d=parseFloat(s);
+ * if(isNaN(d))
+ * throw new NumberFormatException("Not a Number : "+s);
+ * return d
+ *
+ */
+ {
+ return Double.valueOf(s).doubleValue();
+ }
+ }
+
+ public static float fVal(String s) throws NumberFormatException {
+ /**
+ * @j2sNative
+ *
+ * return this.dVal(s);
+ */
+ {
+ return Float.parseFloat(s);
+ }
+ }
+
+ public static int parseIntRange(String str, int ichMax, int[] next) {
+ int cch = str.length();
+ if (ichMax > cch)
+ ichMax = cch;
+ return (next[0] < 0 || next[0] >= ichMax ? Integer.MIN_VALUE : parseIntChecked(str, ichMax, next));
+ }
+
+ /**
+ * parses a string array for floats. Returns NaN for nonfloats.
+ *
+ * @param tokens the strings to parse
+ * @param data the array to fill
+ */
+ public static void parseFloatArrayData(String[] tokens, float[] data) {
+ parseFloatArrayDataN(tokens, data, data.length);
+ }
+
+ /**
+ * parses a string array for floats. Returns NaN for nonfloats or missing data.
+ *
+ * @param tokens the strings to parse
+ * @param data the array to fill
+ * @param nData the number of elements
+ */
+ public static void parseFloatArrayDataN(String[] tokens, float[] data, int nData) {
+ for (int i = nData; --i >= 0;)
+ data[i] = (i >= tokens.length ? Float.NaN : parseFloat(tokens[i]));
+ }
+
+ /**
+ *
+ * proper splitting, even for Java 1.3 -- if the text ends in the run,
+ * no new line is appended.
+ *
+ * @param text
+ * @param run
+ * @return String array
+ */
+ public static String[] split(String text, String run) {
+ if (text.length() == 0)
+ return new String[0];
+ int n = 1;
+ int i = text.indexOf(run);
+ String[] lines;
+ int runLen = run.length();
+ if (i < 0 || runLen == 0) {
+ lines = new String[1];
+ lines[0] = text;
+ return lines;
+ }
+ int len = text.length() - runLen;
+ for (; i >= 0 && i < len; n++)
+ i = text.indexOf(run, i + runLen);
+ lines = new String[n];
+ i = 0;
+ int ipt = 0;
+ int pt = 0;
+ for (; (ipt = text.indexOf(run, i)) >= 0 && pt + 1 < n;) {
+ lines[pt++] = text.substring(i, ipt);
+ i = ipt + runLen;
+ }
+ if (text.indexOf(run, len) != len)
+ len += runLen;
+ lines[pt] = text.substring(i, len);
+ return lines;
+ }
+
+ public final static float FLOAT_MIN_SAFE = 2E-45f;
+ // Float.MIN_VALUE (1.45E-45) is not reliable with JavaScript because of the float/double difference there
+
+ /// general static string-parsing class ///
+
+ // next[0] tracks the pointer within the string so these can all be static.
+ // but the methods parseFloat, parseInt, parseToken, parseTrimmed, and getTokens do not require this.
+
+// public static String concatTokens(String[] tokens, int iFirst, int iEnd) {
+// String str = "";
+// String sep = "";
+// for (int i = iFirst; i < iEnd; i++) {
+// if (i < tokens.length) {
+// str += sep + tokens[i];
+// sep = " ";
+// }
+// }
+// return str;
+// }
+
+ public static String getQuotedStringAt(String line, int ipt0) {
+ int[] next = new int[] { ipt0 };
+ return getQuotedStringNext(line, next);
+ }
+
+ /**
+ *
+ * @param line
+ * @param next passes [current pointer]
+ * @return quoted string -- does NOT unescape characters
+ */
+ public static String getQuotedStringNext(String line, int[] next) {
+ int i = next[0];
+ if (i < 0 || (i = line.indexOf("\"", i)) < 0)
+ return "";
+ int pt = i + 1;
+ int len = line.length();
+ while (++i < len && line.charAt(i) != '"')
+ if (line.charAt(i) == '\\')
+ i++;
+ next[0] = i + 1;
+ return line.substring(pt, i);
+ }
+
+ /**
+ * CSV format -- escaped quote is "" WITHIN "..."
+ *
+ *
+ * @param line
+ * @param next int[2] filled with [ptrQuote1, ptrAfterQuote2]
+ * next[1] will be -1 if unmatched quotes are found (continuation on next line)
+ * @return unescaped string or null
+ */
+ public static String getCSVString(String line, int[] next) {
+ int i = next[1];
+ if (i < 0 || (i = line.indexOf("\"", i)) < 0)
+ return null;
+ int pt = next[0] = i;
+ int len = line.length();
+ boolean escaped = false;
+ boolean haveEscape = false;
+ while (++i < len
+ && (line.charAt(i) != '"' || (escaped = (i + 1 < len && line.charAt(i + 1) == '"'))))
+ if (escaped) {
+ escaped = false;
+ haveEscape = true;
+ i++;
+ }
+ if (i >= len) {
+ next[1] = -1;
+ return null; // unmatched
+ }
+ next[1] = i + 1;
+ String s = line.substring(pt + 1, i);
+ return (haveEscape ? rep(rep(s, "\"\"", "\0"), "\0","\"") : s);
+ }
+
+ public static boolean isOneOf(String key, String semiList) {
+ if (semiList.length() == 0)
+ return false;
+ if (semiList.charAt(0) != ';')
+ semiList = ";" + semiList + ";";
+ return key.indexOf(";") < 0 && semiList.indexOf(';' + key + ';') >= 0;
+ }
+
+ public static String getQuotedAttribute(String info, String name) {
+ int i = info.indexOf(name + "=");
+ return (i < 0 ? null : getQuotedStringAt(info, i));
+ }
+
+ public static float approx(float f, float n) {
+ return Math.round (f * n) / n;
+ }
+
+ /**
+ * Does a clean ITERATIVE replace of strFrom in str with strTo.
+ * Thus, rep("Testttt", "tt","t") becomes "Test".
+ *
+ * @param str
+ * @param strFrom
+ * @param strTo
+ * @return replaced string
+ */
+ public static String rep(String str, String strFrom, String strTo) {
+ if (str == null || strFrom.length() == 0 || str.indexOf(strFrom) < 0)
+ return str;
+ boolean isOnce = (strTo.indexOf(strFrom) >= 0);
+ do {
+ str = str.replace(strFrom, strTo);
+ } while (!isOnce && str.indexOf(strFrom) >= 0);
+ return str;
+ }
+
+ public static String formatF(float value, int width, int precision,
+ boolean alignLeft, boolean zeroPad) {
+ return formatS(DF.formatDecimal(value, precision), width, 0, alignLeft, zeroPad);
+ }
+
+ /**
+ *
+ * @param value
+ * @param width
+ * @param precision
+ * @param alignLeft
+ * @param zeroPad
+ * @param allowOverflow IGNORED
+ * @return formatted string
+ */
+ public static String formatD(double value, int width, int precision,
+ boolean alignLeft, boolean zeroPad, boolean allowOverflow) {
+ return formatS(DF.formatDecimal((float)value, -1 - precision), width, 0, alignLeft, zeroPad);
+ }
+
+ /**
+ *
+ * @param value
+ * @param width number of columns
+ * @param precision precision > 0 ==> precision = number of characters max from left
+ * precision < 0 ==> -1 - precision = number of char. max from right
+ * @param alignLeft
+ * @param zeroPad generally for numbers turned strings
+ * @return formatted string
+ */
+ public static String formatS(String value, int width, int precision,
+ boolean alignLeft, boolean zeroPad) {
+ if (value == null)
+ return "";
+ int len = value.length();
+ if (precision != Integer.MAX_VALUE && precision > 0
+ && precision < len)
+ value = value.substring(0, precision);
+ else if (precision < 0 && len + precision >= 0)
+ value = value.substring(len + precision + 1);
+
+ int padLength = width - value.length();
+ if (padLength <= 0)
+ return value;
+ boolean isNeg = (zeroPad && !alignLeft && value.charAt(0) == '-');
+ char padChar = (zeroPad ? '0' : ' ');
+ char padChar0 = (isNeg ? '-' : padChar);
+
+ SB sb = new SB();
+ if (alignLeft)
+ sb.append(value);
+ sb.appendC(padChar0);
+ for (int i = padLength; --i > 0;)
+ // this is correct, not >= 0
+ sb.appendC(padChar);
+ if (!alignLeft)
+ sb.append(isNeg ? padChar + value.substring(1) : value);
+ return sb.toString();
+ }
+
+ /**
+ * Does a clean replace of any of the characters in str with chrTo
+ * If strTo contains strFrom, then only a single pass is done.
+ * Otherwise, multiple passes are made until no more replacements can be made.
+ *
+ * @param str
+ * @param strFrom
+ * @param chTo
+ * @return replaced string
+ */
+ public static String replaceWithCharacter(String str, String strFrom,
+ char chTo) {
+ if (str == null)
+ return null;
+ for (int i = strFrom.length(); --i >= 0;)
+ str = str.replace(strFrom.charAt(i), chTo);
+ return str;
+ }
+
+ /**
+ * Does a clean replace of any of the characters in str with strTo
+ * If strTo contains strFrom, then only a single pass is done.
+ * Otherwise, multiple passes are made until no more replacements can be made.
+ *
+ * @param str
+ * @param strFrom
+ * @param strTo
+ * @return replaced string
+ */
+ public static String replaceAllCharacters(String str, String strFrom,
+ String strTo) {
+ for (int i = strFrom.length(); --i >= 0;) {
+ String chFrom = strFrom.substring(i, i + 1);
+ str = rep(str, chFrom, strTo);
+ }
+ return str;
+ }
+
+ public static String trim(String str, String chars) {
+ if (str == null || str.length() == 0)
+ return str;
+ if (chars.length() == 0)
+ return str.trim();
+ int len = str.length();
+ int k = 0;
+ while (k < len && chars.indexOf(str.charAt(k)) >= 0)
+ k++;
+ int m = str.length() - 1;
+ while (m > k && chars.indexOf(str.charAt(m)) >= 0)
+ m--;
+ return str.substring(k, m + 1);
+ }
+
+ public static String trimQuotes(String value) {
+ return (value != null && value.length() > 1 && value.startsWith("\"")
+ && value.endsWith("\"") ? value.substring(1, value.length() - 1)
+ : value);
+ }
+
+ public static boolean isNonStringPrimitive(Object info) {
+ // note that we don't use Double, Float, or Integer here
+ // because in JavaScript those would be false for unwrapped primitives
+ // coming from equivalent of Array.get()
+ // Strings will need their own escaped processing
+
+ return info instanceof Number || info instanceof Boolean;
+ }
+
+ private static Object arrayGet(Object info, int i) {
+ /**
+ *
+ * Note that info will be a primitive in JavaScript
+ * but a wrapped primitive in Java.
+ *
+ * @j2sNative
+ *
+ * return info[i];
+ */
+ {
+ return Array.get(info, i);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public static String toJSON(String infoType, Object info) {
+ if (info == null)
+ return packageJSON(infoType, null);
+ if (isNonStringPrimitive(info))
+ return packageJSON(infoType, info.toString());
+ String s = null;
+ SB sb = null;
+ while (true) {
+ if (info instanceof String) {
+ s = (String) info;
+ /**
+ * @j2sNative
+ *
+ * if (typeof s == "undefined") s = "null"
+ *
+ */
+ {}
+ if (s.indexOf("{\"") != 0) {
+ //don't doubly fix JSON strings when retrieving status
+ s = rep(s, "\"", "\\\"");
+ s = rep(s, "\n", "\\n");
+ s = "\"" + s + "\"";
+ }
+ break;
+ }
+ if (info instanceof JSONEncodable) {
+ // includes javajs.util.BS, org.jmol.script.SV
+ if ((s = ((JSONEncodable) info).toJSON()) == null)
+ s = "null"; // perhaps a list has a null value (group3List, for example)
+ break;
+ }
+ sb = new SB();
+ if (info instanceof Map) {
+ sb.append("{ ");
+ String sep = "";
+ for (String key : ((Map<String, ?>) info).keySet()) {
+ sb.append(sep).append(
+ packageJSON(key, toJSON(null, ((Map<?, ?>) info).get(key))));
+ sep = ",";
+ }
+ sb.append(" }");
+ break;
+ }
+ if (info instanceof Lst) {
+ sb.append("[ ");
+ int n = ((Lst<?>) info).size();
+ for (int i = 0; i < n; i++) {
+ if (i > 0)
+ sb.appendC(',');
+ sb.append(toJSON(null, ((Lst<?>) info).get(i)));
+ }
+ sb.append(" ]");
+ break;
+ }
+ if (info instanceof M34) {
+ // M4 extends M3
+ int len = (info instanceof M4 ? 4 : 3);
+ float[] x = new float[len];
+ M34 m = (M34) info;
+ sb.appendC('[');
+ for (int i = 0; i < len; i++) {
+ if (i > 0)
+ sb.appendC(',');
+ m.getRow(i, x);
+ sb.append(toJSON(null, x));
+ }
+ sb.appendC(']');
+ break;
+ }
+ s = nonArrayString(info);
+ if (s == null) {
+ sb.append("[");
+ int n = AU.getLength(info);
+ for (int i = 0; i < n; i++) {
+ if (i > 0)
+ sb.appendC(',');
+ sb.append(toJSON(null, arrayGet(info, i)));
+ }
+ sb.append("]");
+ break;
+ }
+ info = info.toString();
+ }
+ return packageJSON(infoType, (s == null ? sb.toString() : s));
+ }
+
+ /**
+ * Checks to see if an object is an array, and if it is, returns null;
+ * otherwise it returns the string equivalent of that object.
+ *
+ * @param x
+ * @return String or null
+ */
+ public static String nonArrayString(Object x) {
+ /**
+ * @j2sNative
+ *
+ * var s = x.toString(); return (s.startsWith("[object") &&
+ * s.endsWith("Array]") ? null : s);
+ *
+ */
+ {
+ try {
+ Array.getLength(x);
+ return null;
+ } catch (Exception e) {
+ return x.toString();
+ }
+ }
+ }
+
+ public static String byteArrayToJSON(byte[] data) {
+ SB sb = new SB();
+ sb.append("[");
+ int n = data.length;
+ for (int i = 0; i < n; i++) {
+ if (i > 0)
+ sb.appendC(',');
+ sb.appendI(data[i] & 0xFF);
+ }
+ sb.append("]");
+ return sb.toString();
+ }
+
+ public static String packageJSON(String infoType, String info) {
+ return (infoType == null ? info : "\"" + infoType + "\": " + info);
+ }
+
+ public static String escapeUrl(String url) {
+ url = rep(url, "\n", "");
+ url = rep(url, "%", "%25");
+ url = rep(url, "#", "%23");
+ url = rep(url, "[", "%5B");
+ url = rep(url, "]", "%5D");
+ url = rep(url, " ", "%20");
+ return url;
+ }
+
+ private final static String escapable = "\\\\\tt\rr\nn\"\"";
+
+ public static String esc(String str) {
+ if (str == null || str.length() == 0)
+ return "\"\"";
+ boolean haveEscape = false;
+ int i = 0;
+ for (; i < escapable.length(); i += 2)
+ if (str.indexOf(escapable.charAt(i)) >= 0) {
+ haveEscape = true;
+ break;
+ }
+ if (haveEscape)
+ while (i < escapable.length()) {
+ int pt = -1;
+ char ch = escapable.charAt(i++);
+ char ch2 = escapable.charAt(i++);
+ SB sb = new SB();
+ int pt0 = 0;
+ while ((pt = str.indexOf(ch, pt + 1)) >= 0) {
+ sb.append(str.substring(pt0, pt)).appendC('\\').appendC(ch2);
+ pt0 = pt + 1;
+ }
+ sb.append(str.substring(pt0, str.length()));
+ str = sb.toString();
+ }
+ return "\"" + escUnicode(str) + "\"";
+ }
+
+ public static String escUnicode(String str) {
+ for (int i = str.length(); --i >= 0;)
+ if (str.charAt(i) > 0x7F) {
+ String s = "0000" + Integer.toHexString(str.charAt(i));
+ str = str.substring(0, i) + "\\u" + s.substring(s.length() - 4)
+ + str.substring(i + 1);
+ }
+ return str;
+ }
+
+ /**
+ * ensures that a float turned to string has a decimal point
+ *
+ * @param f
+ * @return string version of float
+ */
+ public static String escF(float f) {
+ String sf = "" + f;
+ /**
+ * @j2sNative
+ *
+ * if (sf.indexOf(".") < 0 && sf.indexOf("e") < 0)
+ * sf += ".0";
+ */
+ {
+ }
+ return sf;
+ }
+ public static String join(String[] s, char c, int i0) {
+ if (s.length < i0)
+ return null;
+ SB sb = new SB();
+ sb.append(s[i0++]);
+ for (int i = i0; i < s.length; i++)
+ sb.appendC(c).append(s[i]);
+ return sb.toString();
+ }
+
+ /**
+ * a LIKE "x" a is a string and equals x
+ *
+ * a LIKE "*x" a is a string and ends with x
+ *
+ * a LIKE "x*" a is a string and starts with x
+ *
+ * a LIKE "*x*" a is a string and contains x
+ *
+ * @param a
+ * @param b
+ * @return a LIKE b
+ */
+ public static boolean isLike(String a, String b) {
+ boolean areEqual = a.equals(b);
+ if (areEqual)
+ return true;
+ boolean isStart = b.startsWith("*");
+ boolean isEnd = b.endsWith("*");
+ return (!isStart && !isEnd) ? areEqual
+ : isStart && isEnd ? b.length() == 1 || a.contains(b.substring(1, b.length() - 1))
+ : isStart ? a.endsWith(b.substring(1))
+ : a.startsWith(b.substring(0, b.length() - 1));
+ }
+
+ public static Object getMapValueNoCase(Map<String, ?> h, String key) {
+ if ("this".equals(key))
+ return h;
+ Object val = h.get(key);
+ if (val == null)
+ for (Entry<String, ?> e : h.entrySet())
+ if (e.getKey().equalsIgnoreCase(key))
+ return e.getValue();
+ return val;
+ }
+
+ public static String clean(String s) {
+ return rep(replaceAllCharacters(s, " \t\n\r", " "), " ", " ").trim();
+ }
+
+ /**
+ *
+ * fdup duplicates p or q formats for formatCheck
+ * and the format() function.
+ *
+ * @param f
+ * @param pt
+ * @param n
+ * @return %3.5q%3.5q%3.5q%3.5q or %3.5p%3.5p%3.5p
+ */
+ public static String fdup(String f, int pt, int n) {
+ char ch;
+ int count = 0;
+ for (int i = pt; --i >= 1; ) {
+ if (isDigit(ch = f.charAt(i)))
+ continue;
+ switch (ch) {
+ case '.':
+ if (count++ != 0)
+ return f;
+ continue;
+ case '-':
+ if (i != 1 && f.charAt(i - 1) != '.')
+ return f;
+ continue;
+ default:
+ return f;
+ }
+ }
+ String s = f.substring(0, pt + 1);
+ SB sb = new SB();
+ for (int i = 0; i < n; i++)
+ sb.append(s);
+ sb.append(f.substring(pt + 1));
+ return sb.toString();
+ }
+
+ /**
+ * generic string formatter based on formatLabel in Atom
+ *
+ *
+ * @param strFormat .... %width.precisionKEY....
+ * @param key any string to match
+ * @param strT replacement string or null
+ * @param floatT replacement float or Float.NaN
+ * @param doubleT replacement double or Double.NaN -- for exponential
+ * @param doOne mimic sprintf
+ * @return formatted string
+ */
+
+ public static String formatString(String strFormat, String key, String strT,
+ float floatT, double doubleT, boolean doOne) {
+ if (strFormat == null)
+ return null;
+ if ("".equals(strFormat))
+ return "";
+ int len = key.length();
+ if (strFormat.indexOf("%") < 0 || len == 0 || strFormat.indexOf(key) < 0)
+ return strFormat;
+
+ String strLabel = "";
+ int ich, ichPercent, ichKey;
+ for (ich = 0; (ichPercent = strFormat.indexOf('%', ich)) >= 0
+ && (ichKey = strFormat.indexOf(key, ichPercent + 1)) >= 0;) {
+ if (ich != ichPercent)
+ strLabel += strFormat.substring(ich, ichPercent);
+ ich = ichPercent + 1;
+ if (ichKey > ichPercent + 6) {
+ strLabel += '%';
+ continue;//%12.10x
+ }
+ try {
+ boolean alignLeft = false;
+ if (strFormat.charAt(ich) == '-') {
+ alignLeft = true;
+ ++ich;
+ }
+ boolean zeroPad = false;
+ if (strFormat.charAt(ich) == '0') {
+ zeroPad = true;
+ ++ich;
+ }
+ char ch;
+ int width = 0;
+ while ((ch = strFormat.charAt(ich)) >= '0' && (ch <= '9')) {
+ width = (10 * width) + (ch - '0');
+ ++ich;
+ }
+ int precision = Integer.MAX_VALUE;
+ boolean isExponential = false;
+ if (strFormat.charAt(ich) == '.') {
+ ++ich;
+ if ((ch = strFormat.charAt(ich)) == '-') {
+ isExponential = true;
+ ++ich;
+ }
+ if ((ch = strFormat.charAt(ich)) >= '0' && ch <= '9') {
+ precision = ch - '0';
+ ++ich;
+ }
+ if (isExponential)
+ precision = -precision - (strT == null ? 1 : 0);
+ }
+ String st = strFormat.substring(ich, ich + len);
+ if (!st.equals(key)) {
+ ich = ichPercent + 1;
+ strLabel += '%';
+ continue;
+ }
+ ich += len;
+ if (!Float.isNaN(floatT))
+ strLabel += formatF(floatT, width, precision, alignLeft,
+ zeroPad);
+ else if (strT != null)
+ strLabel += formatS(strT, width, precision, alignLeft,
+ zeroPad);
+ else if (!Double.isNaN(doubleT))
+ strLabel += formatD(doubleT, width, precision, alignLeft,
+ zeroPad, true);
+ if (doOne)
+ break;
+ } catch (IndexOutOfBoundsException ioobe) {
+ ich = ichPercent;
+ break;
+ }
+ }
+ strLabel += strFormat.substring(ich);
+ //if (strLabel.length() == 0)
+ //return null;
+ return strLabel;
+ }
+
+ public static String formatStringS(String strFormat, String key, String strT) {
+ return formatString(strFormat, key, strT, Float.NaN, Double.NaN, false);
+ }
+
+ public static String formatStringF(String strFormat, String key, float floatT) {
+ return formatString(strFormat, key, null, floatT, Double.NaN, false);
+ }
+
+ public static String formatStringI(String strFormat, String key, int intT) {
+ return formatString(strFormat, key, "" + intT, Float.NaN, Double.NaN, false);
+ }
+
+ /**
+ * sprintf emulation uses (almost) c++ standard string formats
+ *
+ * 's' string 'i' or 'd' integer, 'e' double, 'f' float, 'p' point3f 'q'
+ * quaternion/plane/axisangle with added "i" (equal to the insipid "d" --
+ * digits?)
+ *
+ * @param strFormat
+ * @param list
+ * a listing of what sort of data will be found in Object[] values, in
+ * order: s string, f float, i integer, d double, p point3f, q
+ * quaternion/point4f, S String[], F float[], I int[], and D double[]
+ * @param values
+ * Object[] containing above types
+ * @return formatted string
+ */
+ public static String sprintf(String strFormat, String list, Object[] values) {
+ if (values == null)
+ return strFormat;
+ int n = list.length();
+ if (n == values.length)
+ try {
+ for (int o = 0; o < n; o++) {
+ if (values[o] == null)
+ continue;
+ switch (list.charAt(o)) {
+ case 's':
+ strFormat = formatString(strFormat, "s", (String) values[o],
+ Float.NaN, Double.NaN, true);
+ break;
+ case 'f':
+ strFormat = formatString(strFormat, "f", null, ((Float) values[o])
+ .floatValue(), Double.NaN, true);
+ break;
+ case 'i':
+ strFormat = formatString(strFormat, "d", "" + values[o], Float.NaN,
+ Double.NaN, true);
+ strFormat = formatString(strFormat, "i", "" + values[o], Float.NaN,
+ Double.NaN, true);
+ break;
+ case 'd':
+ strFormat = formatString(strFormat, "e", null, Float.NaN,
+ ((Double) values[o]).doubleValue(), true);
+ break;
+ case 'p':
+ T3 pVal = (T3) values[o];
+ strFormat = formatString(strFormat, "p", null, pVal.x, Double.NaN,
+ true);
+ strFormat = formatString(strFormat, "p", null, pVal.y, Double.NaN,
+ true);
+ strFormat = formatString(strFormat, "p", null, pVal.z, Double.NaN,
+ true);
+ break;
+ case 'q':
+ T4 qVal = (T4) values[o];
+ strFormat = formatString(strFormat, "q", null, qVal.x, Double.NaN,
+ true);
+ strFormat = formatString(strFormat, "q", null, qVal.y, Double.NaN,
+ true);
+ strFormat = formatString(strFormat, "q", null, qVal.z, Double.NaN,
+ true);
+ strFormat = formatString(strFormat, "q", null, qVal.w, Double.NaN,
+ true);
+ break;
+ case 'S':
+ String[] sVal = (String[]) values[o];
+ for (int i = 0; i < sVal.length; i++)
+ strFormat = formatString(strFormat, "s", sVal[i], Float.NaN,
+ Double.NaN, true);
+ break;
+ case 'F':
+ float[] fVal = (float[]) values[o];
+ for (int i = 0; i < fVal.length; i++)
+ strFormat = formatString(strFormat, "f", null, fVal[i],
+ Double.NaN, true);
+ break;
+ case 'I':
+ int[] iVal = (int[]) values[o];
+ for (int i = 0; i < iVal.length; i++)
+ strFormat = formatString(strFormat, "d", "" + iVal[i], Float.NaN,
+ Double.NaN, true);
+ for (int i = 0; i < iVal.length; i++)
+ strFormat = formatString(strFormat, "i", "" + iVal[i], Float.NaN,
+ Double.NaN, true);
+ break;
+ case 'D':
+ double[] dVal = (double[]) values[o];
+ for (int i = 0; i < dVal.length; i++)
+ strFormat = formatString(strFormat, "e", null, Float.NaN,
+ dVal[i], true);
+ }
+
+ }
+ return rep(strFormat, "%%", "%");
+ } catch (Exception e) {
+ //
+ }
+ System.out.println("TextFormat.sprintf error " + list + " " + strFormat);
+ return rep(strFormat, "%", "?");
+ }
+
+ /**
+ *
+ * formatCheck checks p and q formats and duplicates if necessary
+ * "%10.5p xxxx" ==> "%10.5p%10.5p%10.5p xxxx"
+ *
+ * @param strFormat
+ * @return f or dupicated format
+ */
+ public static String formatCheck(String strFormat) {
+ if (strFormat == null || strFormat.indexOf('p') < 0 && strFormat.indexOf('q') < 0)
+ return strFormat;
+ strFormat = rep(strFormat, "%%", "\1");
+ strFormat = rep(strFormat, "%p", "%6.2p");
+ strFormat = rep(strFormat, "%q", "%6.2q");
+ String[] format = split(strFormat, "%");
+ SB sb = new SB();
+ sb.append(format[0]);
+ for (int i = 1; i < format.length; i++) {
+ String f = "%" + format[i];
+ int pt;
+ if (f.length() >= 3) {
+ if ((pt = f.indexOf('p')) >= 0)
+ f = fdup(f, pt, 3);
+ if ((pt = f.indexOf('q')) >= 0)
+ f = fdup(f, pt, 4);
+ }
+ sb.append(f);
+ }
+ return sb.toString().replace('\1', '%');
+ }
+
+ public static void leftJustify(SB s, String s1, String s2) {
+ s.append(s2);
+ int n = s1.length() - s2.length();
+ if (n > 0)
+ s.append(s1.substring(0, n));
+ }
+
+ public static void rightJustify(SB s, String s1, String s2) {
+ int n = s1.length() - s2.length();
+ if (n > 0)
+ s.append(s1.substring(0, n));
+ s.append(s2);
+ }
+
+ public static String safeTruncate(float f, int n) {
+ if (f > -0.001 && f < 0.001)
+ f = 0;
+ return (f + " ").substring(0,n);
+ }
+
+ public static boolean isWild(String s) {
+ return s != null && (s.indexOf("*") >= 0 || s.indexOf("?") >= 0);
+ }
+
+ /**
+ * A general non-regex (for performance) text matcher that utilizes ? and *.
+ *
+ * ??? means "at most three" characters if at beginning or end;
+ * "exactly three" otherwise
+ * \1 in search is a stand-in for actual ?
+ *
+ * @param search
+ * the string to search
+ * @param match
+ * the match string
+ * @param checkStar
+ * @param allowInitialStar
+ * @return true if found
+ */
+ public static boolean isMatch(String search, String match, boolean checkStar,
+ boolean allowInitialStar) {
+ // search == match --> true
+ if (search.equals(match))
+ return true;
+ int mLen = match.length();
+ // match == "" --> false
+ if (mLen == 0)
+ return false;
+ boolean isStar0 = (checkStar && allowInitialStar ? match.charAt(0) == '*'
+ : false);
+ // match == "*" --> true
+ if (mLen == 1 && isStar0)
+ return true;
+ boolean isStar1 = (checkStar && match.endsWith("*"));
+ boolean haveQ = (match.indexOf('?') >= 0);
+ // match == "**" --> true
+ // match == "*xxx*" --> search contains "xxx"
+ // match == "*xxx" --> search ends with "xxx"
+ // match == "xxx*" --> search starts with "xxx"
+ if (!haveQ) {
+ if (isStar0)
+ return (isStar1 ? (mLen < 3 || search.indexOf(match.substring(1,
+ mLen - 1)) >= 0) : search.endsWith(match.substring(1)));
+ else if (isStar1)
+ return search.startsWith(match.substring(0, mLen - 1));
+ }
+ int sLen = search.length();
+ // pad match with "?" -- same as *
+ String qqqq = "????";
+ int nq = 4;
+ while (nq < sLen) {
+ qqqq += qqqq;
+ nq += 4;
+ }
+ if (checkStar) {
+ if (isStar0) {
+ match = qqqq + match.substring(1);
+ mLen += nq - 1;
+ }
+ if (isStar1) {
+ match = match.substring(0, mLen - 1) + qqqq;
+ mLen += nq - 1;
+ }
+ }
+ // length of match < length of search --> false
+ if (mLen < sLen)
+ return false;
+
+ // -- each ? matches ONE character if not at end
+ // -- extra ? at end ignored
+
+ // (allowInitialStar == true)
+ // -- extra ? at beginning reduced to match length
+
+ int ich = 0;
+ while (mLen > sLen) {
+ if (allowInitialStar && match.charAt(ich) == '?') {
+ ++ich;
+ } else if (match.charAt(ich + mLen - 1) != '?') {
+ return false;
+ }
+ --mLen;
+ }
+
+ // both are effectively same length now.
+ // \1 is stand-in for "?"
+
+ for (int i = sLen; --i >= 0;) {
+ char chm = match.charAt(ich + i);
+ if (chm == '?')
+ continue;
+ char chs = search.charAt(i);
+ if (chm != chs && (chm != '\1' || chs != '?'))
+ return false;
+ }
+ return true;
+ }
+
+ public static String replaceQuotedStrings(String s, Lst<String> list,
+ Lst<String> newList) {
+ int n = list.size();
+ for (int i = 0; i < n; i++) {
+ String name = list.get(i);
+ String newName = newList.get(i);
+ if (!newName.equals(name))
+ s = rep(s, "\"" + name + "\"", "\"" + newName
+ + "\"");
+ }
+ return s;
+ }
+
+ public static String replaceStrings(String s, Lst<String> list,
+ Lst<String> newList) {
+ int n = list.size();
+ for (int i = 0; i < n; i++) {
+ String name = list.get(i);
+ String newName = newList.get(i);
+ if (!newName.equals(name))
+ s = rep(s, name, newName);
+ }
+ return s;
+ }
+
+ public static boolean isDigit(char ch) {
+ // just way simpler code than Character.isDigit(ch);
+ int c = ch;
+ return (48 <= c && c <= 57);
+ }
+
+ public static boolean isUpperCase(char ch) {
+ int c = ch;
+ return (65 <= c && c <= 90);
+ }
+
+ public static boolean isLowerCase(char ch) {
+ int c = ch;
+ return (97 <= c && c <= 122);
+ }
+
+ public static boolean isLetter(char ch) {
+ // just way simpler code than Character.isLetter(ch);
+ int c = ch;
+ return (65 <= c && c <= 90 || 97 <= c && c <= 122);
+ }
+
+ public static boolean isLetterOrDigit(char ch) {
+ // just way simpler code than Character.isLetterOrDigit(ch);
+ int c = ch;
+ return (65 <= c && c <= 90 || 97 <= c && c <= 122 || 48 <= c && c <= 57);
+ }
+
+ public static boolean isWhitespace(char ch) {
+ int c = ch;
+ return (c >= 0x1c && c <= 0x20 || c >= 0x9 && c <= 0xd);
+ }
+
+ public static final float FRACTIONAL_PRECISION = 100000f;
+ public static final float CARTESIAN_PRECISION = 10000f;
+
+ public static void fixPtFloats(T3 pt, float f) {
+ //this will equate float and double as long as -256 <= x <= 256
+ pt.x = Math.round(pt.x * f) / f;
+ pt.y = Math.round(pt.y * f) / f;
+ pt.z = Math.round(pt.z * f) / f;
+ }
+
+ public static double fixDouble(double d, double f) {
+ return Math.round(d * f) / f;
+ }
+
+ /**
+ * parse a float or "float/float"
+ * @param s
+ * @return a/b
+ */
+ public static float parseFloatFraction(String s) {
+ int pt = s.indexOf("/");
+ return (pt < 0 ? parseFloat(s) : parseFloat(s.substring(0, pt))
+ / parseFloat(s.substring(pt + 1)));
+ }
+
+//static {
+//
+// double d = 790.8999998888;
+// float x = 790.8999998888f;
+// for (int i = 0; i < 50; i++) {
+// System.out.println(x + " " + d);
+// System.out.println(Math.round(x * 100000) / 100000f);
+// System.out.println(Math.round(d * 100000) / 100000.);
+// System.out.println(Math.round(x * 10000) / 10000f);
+// System.out.println(Math.round(d * 10000) / 10000.);
+// x+=1;
+// d+=1;
+// }
+// System.out.println(100.123456789f);
+//}
+
+// static {
+// long t;
+// char c = '0';
+// t = System.currentTimeMillis();
+// for (int i = 0; i < 10000000; i++) {
+// boolean b = PT.isUpperCase(c);
+// }
+// System.out.println(System.currentTimeMillis() - t);
+//
+// t = System.currentTimeMillis();
+// for (int i = 0; i < 10000000; i++) {
+// boolean b = Character.isUpperCase(c);
+// }
+// System.out.println(System.currentTimeMillis() - t);
+//
+// t = System.currentTimeMillis();
+// for (int i = 0; i < 10000000; i++) {
+// boolean b = PT.isUpperCase(c);
+// }
+// System.out.println(System.currentTimeMillis() - t);
+//
+// System.out.println("PT test");
+// }
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2007-04-05 09:07:28 -0500 (Thu, 05 Apr 2007) $
+ * $Revision: 7326 $
+ *
+ * Copyright (C) 2003-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.util;
+
+/*
+ * Standard UNIT quaternion math -- for rotation.
+ *
+ * All rotations can be represented as two identical quaternions.
+ * This is because any rotation can be considered from either end of the
+ * rotational axis -- either as a + rotation or a - rotation. This code
+ * is designed to always maintain the quaternion with a rotation in the
+ * [0, PI) range.
+ *
+ * This ensures that the reported theta is always positive, and the normal
+ * reported is always associated with a positive theta.
+ *
+ * @author Bob Hanson, hansonr@stolaf.edu 6/2008
+ *
+ */
+
+public class Quat {
+ public float q0, q1, q2, q3;
+ private M3 mat;
+
+ private final static P4 qZero = new P4();
+ private static final double RAD_PER_DEG = Math.PI / 180;
+
+ public Quat() {
+ q0 = 1;
+ }
+
+ public static Quat newQ(Quat q) {
+ Quat q1 = new Quat();
+ q1.set(q);
+ return q1;
+ }
+
+ public static Quat newVA(T3 v, float theta) {
+ Quat q = new Quat();
+ q.setTA(v, theta);
+ return q;
+ }
+
+ public static Quat newM(M3 mat) {
+ Quat q = new Quat();
+ q.setM(M3.newM3(mat));
+ return q;
+ }
+
+ public static Quat newAA(A4 a) {
+ Quat q = new Quat();
+ q.setAA(a);
+ return q;
+ }
+
+ public static Quat newP4(P4 pt) {
+ Quat q = new Quat();
+ q.setP4(pt);
+ return q;
+ }
+
+ /**
+ * Note that q0 is the last parameter here
+ *
+ * @param q1
+ * @param q2
+ * @param q3
+ * @param q0
+ * @return {q1 q2 q3 q0}
+ */
+ public static Quat new4(float q1, float q2, float q3, float q0) {
+ Quat q = new Quat();
+ if (q0 < -1) {
+ q.q0 = -1;
+ return q;
+ }
+ if (q0 > 1) {
+ q.q0 = 1;
+ return q;
+ }
+ q.q0 = q0;
+ q.q1 = q1;
+ q.q2 = q2;
+ q.q3 = q3;
+ return q;
+ }
+
+ public void set(Quat q) {
+ q0 = q.q0;
+ q1 = q.q1;
+ q2 = q.q2;
+ q3 = q.q3;
+ }
+
+ /**
+ * {x y z w} --> {q1 q2 q3 q0} and factored
+ *
+ * @param pt
+ */
+ private void setP4(P4 pt) {
+ float factor = (pt == null ? 0 : pt.distance4(qZero));
+ if (factor == 0) {
+ q0 = 1;
+ return;
+ }
+ q0 = pt.w / factor;
+ q1 = pt.x / factor;
+ q2 = pt.y / factor;
+ q3 = pt.z / factor;
+ }
+
+ /**
+ * q = (cos(theta/2), sin(theta/2) * n)
+ *
+ * @param pt
+ * @param theta
+ */
+ public void setTA(T3 pt, float theta) {
+ if (pt.x == 0 && pt.y == 0 && pt.z == 0) {
+ q0 = 1;
+ return;
+ }
+ double fact = (Math.sin(theta / 2 * RAD_PER_DEG) / Math.sqrt(pt.x
+ * pt.x + pt.y * pt.y + pt.z * pt.z));
+ q0 = (float) (Math.cos(theta / 2 * RAD_PER_DEG));
+ q1 = (float) (pt.x * fact);
+ q2 = (float) (pt.y * fact);
+ q3 = (float) (pt.z * fact);
+ }
+
+ public void setAA(A4 a) {
+ A4 aa = A4.newAA(a);
+ if (aa.angle == 0)
+ aa.y = 1;
+ setM(new M3().setAA(aa));
+ }
+
+ private void setM(M3 mat) {
+
+ /*
+ * Changed 7/16/2008 to double precision for 11.5.48.
+ *
+ * <quote>
+ *
+ * RayTrace Software Package, release 3.0. May 3, 2006.
+ *
+ * Mathematics Subpackage (VrMath)
+ *
+ * Author: Samuel R. Buss
+ *
+ * Software is "as-is" and carries no warranty. It may be used without
+ * restriction, but if you modify it, please change the filenames to
+ * prevent confusion between different versions. Please acknowledge
+ * all use of the software in any publications or products based on it.
+ *
+ * Bug reports: Sam Buss, sbuss@ucsd.edu.
+ * Web page: http://math.ucsd.edu/~sbuss/MathCG
+
+ // Use Shepperd's algorithm, which is stable, does not lose
+ // significant precision and uses only one sqrt.
+ // J. Guidance and Control, 1 (1978) 223-224.
+
+ * </quote>
+ *
+ * Except, that code has errors.
+ *
+ * CORRECTIONS (as noted below) of Quaternion.cpp. I have reported the bug.
+ *
+ * -- Bob Hanson
+ *
+ * theory:
+ * cos(theta/2)^2 = (cos(theta) + 1)/2
+ * and
+ * trace = (1-x^2)ct + (1-y^2)ct + (1-z^2)ct + 1 = 2cos(theta) + 1
+ * or
+ * cos(theta) = (trace - 1)/2
+ *
+ * so in general,
+ *
+ * w = cos(theta/2)
+ * = sqrt((cos(theta)+1)/2)
+ * = sqrt((trace-1)/4+1/2)
+ * = sqrt((trace+1)/4)
+ * = sqrt(trace+1)/2
+ *
+ * but there are precision issues, so we allow for other situations.
+ * note -- trace >= 0.5 when cos(theta) >= -0.25 (-104.48 <= theta <= 104.48).
+ * this code cleverly matches the precision in all four options.
+ *
+ */
+
+ this.mat = mat;
+
+ double trace = mat.m00 + mat.m11 + mat.m22;
+ double temp;
+ double w, x, y, z;
+ if (trace >= 0.5) {
+ w = Math.sqrt(1.0 + trace);
+ x = (mat.m21 - mat.m12) / w;
+ y = (mat.m02 - mat.m20) / w;
+ z = (mat.m10 - mat.m01) / w;
+ } else if ((temp = mat.m00 + mat.m00 - trace) >= 0.5) {
+ x = Math.sqrt(1.0 + temp);
+ w = (mat.m21 - mat.m12) / x;
+ y = (mat.m10 + mat.m01) / x;
+ z = (mat.m20 + mat.m02) / x;
+ } else if ((temp = mat.m11 + mat.m11 - trace) >= 0.5
+ || mat.m11 > mat.m22) {
+ y = Math.sqrt(1.0 + temp);
+ w = (mat.m02 - mat.m20) / y;
+ x = (mat.m10 + mat.m01) / y;
+ z = (mat.m21 + mat.m12) / y;
+ } else {
+ z = Math.sqrt(1.0 + mat.m22 + mat.m22 - trace);
+ w = (mat.m10 - mat.m01) / z;
+ x = (mat.m20 + mat.m02) / z; // was -
+ y = (mat.m21 + mat.m12) / z; // was -
+ }
+
+ q0 = (float) (w * 0.5);
+ q1 = (float) (x * 0.5);
+ q2 = (float) (y * 0.5);
+ q3 = (float) (z * 0.5);
+
+ /*
+ * Originally from http://www.gamedev.net/community/forums/topic.asp?topic_id=448380
+ * later algorithm was adapted from Visualizing Quaternions, by Andrew J. Hanson
+ * (Morgan Kaufmann, 2006), page 446
+ *
+ * HOWEVER, checking with AxisAngle4f and Quat4f equivalents, it was found that
+ * BOTH of these sources produce inverted quaternions. So here we do an inversion.
+ *
+ * This correction was made in 11.5.42 6/19/2008 -- Bob Hanson
+ *
+ * former algorithm used:
+ * /
+
+ double tr = mat.m00 + mat.m11 + mat.m22; //Matrix trace
+ double s;
+ double[] q = new double[4];
+ if (tr > 0) {
+ s = Math.sqrt(tr + 1);
+ q0 = (float) (0.5 * s);
+ s = 0.5 / s; // = 1/q0
+ q1 = (float) ((mat.m21 - mat.m12) * s);
+ q2 = (float) ((mat.m02 - mat.m20) * s);
+ q3 = (float) ((mat.m10 - mat.m01) * s);
+ } else {
+ float[][] m = new float[][] { new float[3], new float[3], new float[3] };
+ mat.getRow(0, m[0]);
+ mat.getRow(1, m[1]);
+ mat.getRow(2, m[2]);
+
+ //Find out the biggest element along the diagonal
+ float max = Math.max(mat.m11, mat.m00);
+ int i = (mat.m22 > max ? 2 : max == mat.m11 ? 1 : 0);
+ int j = (i + 1) % 3;
+ int k = (j + 1) % 3;
+ s = -Math.sqrt(1 + m[i][i] - m[j][j] - m[k][k]);
+ // 0 = 1 + (1-x^2)ct + x^2 -(1-y^2)ct - y^2 - (1-z^2)ct - z^2
+ // 0 = 1 - ct + (x^2 - y^2 - z^2) - (x^2 - y^2 - z^2)ct
+ // 0 = 1 - ct + 2x^2 - 1 - (2x^2)ct + ct
+ // 0 = 2x^2(1 - ct)
+ // theta = 0 (but then trace = 1 + 1 + 1 = 3)
+ // or x = 0.
+ q[i] = s * 0.5;
+ if (s != 0)
+ s = 0.5 / s; // = 1/q[i]
+ q[j] = (m[i][j] + m[j][i]) * s;
+ q[k] = (m[i][k] + m[k][i]) * s;
+ q0 = (float) ((m[k][j] - m[j][k]) * s);
+ q1 = (float) q[0]; // x
+ q2 = (float) q[1]; // y
+ q3 = (float) q[2]; // z
+ }
+
+ */
+ }
+
+ /*
+ * if qref is null, "fix" this quaternion
+ * otherwise, return a quaternion that is CLOSEST to the given quaternion
+ * that is, one that gives a positive dot product
+ *
+ */
+ public void setRef(Quat qref) {
+ if (qref == null) {
+ mul(getFixFactor());
+ return;
+ }
+ if (dot(qref) >= 0)
+ return;
+ q0 *= -1;
+ q1 *= -1;
+ q2 *= -1;
+ q3 *= -1;
+ }
+
+ /**
+ * returns a quaternion frame based on three points (center, x, and any point in xy plane)
+ * or two vectors (vA, vB).
+ *
+ * @param center (null for vA/vB option)
+ * @param x
+ * @param xy
+ * @return quaternion for frame
+ */
+ public static final Quat getQuaternionFrame(P3 center, T3 x,
+ T3 xy) {
+ V3 vA = V3.newV(x);
+ V3 vB = V3.newV(xy);
+ if (center != null) {
+ vA.sub(center);
+ vB.sub(center);
+ }
+ return getQuaternionFrameV(vA, vB, null, false);
+ }
+
+ /**
+ * Create a quaternion based on a frame
+ * @param vA
+ * @param vB
+ * @param vC
+ * @param yBased
+ * @return quaternion
+ */
+ public static final Quat getQuaternionFrameV(V3 vA, V3 vB,
+ V3 vC, boolean yBased) {
+ if (vC == null) {
+ vC = new V3();
+ vC.cross(vA, vB);
+ if (yBased)
+ vA.cross(vB, vC);
+ }
+ V3 vBprime = new V3();
+ vBprime.cross(vC, vA);
+ vA.normalize();
+ vBprime.normalize();
+ vC.normalize();
+ M3 mat = new M3();
+ mat.setColumnV(0, vA);
+ mat.setColumnV(1, vBprime);
+ mat.setColumnV(2, vC);
+
+ /*
+ *
+ * Verification tests using Quat4f and AngleAxis4f:
+ *
+ System.out.println("quaternion frame matrix: " + mat);
+
+ Point3f pt2 = new Point3f();
+ mat.transform(Point3f.new3(1, 0, 0), pt2);
+ System.out.println("vA=" + vA + " M(100)=" + pt2);
+ mat.transform(Point3f.new3(0, 1, 0), pt2);
+ System.out.println("vB'=" + vBprime + " M(010)=" + pt2);
+ mat.transform(Point3f.new3(0, 0, 1), pt2);
+ System.out.println("vC=" + vC + " M(001)=" + pt2);
+ Quat4f q4 = new Quat4f();
+ q4.set(mat);
+ System.out.println("----");
+ System.out.println("Quat4f: {" + q4.w + " " + q4.x + " " + q4.y + " " + q4.z + "}");
+ System.out.println("Quat4f: 2xy + 2wz = m10: " + (2 * q4.x * q4.y + 2 * q4.w * q4.z) + " = " + mat.m10);
+
+ */
+
+ Quat q = newM(mat);
+
+ /*
+ System.out.println("Quaternion mat from q \n" + q.getMatrix());
+ System.out.println("Quaternion: " + q.getNormal() + " " + q.getTheta());
+ AxisAngle4f a = new AxisAngle4f();
+ a.set(mat);
+ Vector3f v = Vector3f.new3(a.x, a.y, a.z);
+ v.normalize();
+ System.out.println("angleAxis: " + v + " "+(a.angle/Math.PI * 180));
+ */
+
+ return q;
+ }
+
+ public M3 getMatrix() {
+ if (mat == null)
+ setMatrix();
+ return mat;
+ }
+
+ private void setMatrix() {
+ mat = new M3();
+ // q0 = w, q1 = x, q2 = y, q3 = z
+ mat.m00 = q0 * q0 + q1 * q1 - q2 * q2 - q3 * q3;
+ mat.m01 = 2 * q1 * q2 - 2 * q0 * q3;
+ mat.m02 = 2 * q1 * q3 + 2 * q0 * q2;
+ mat.m10 = 2 * q1 * q2 + 2 * q0 * q3;
+ mat.m11 = q0 * q0 - q1 * q1 + q2 * q2 - q3 * q3;
+ mat.m12 = 2 * q2 * q3 - 2 * q0 * q1;
+ mat.m20 = 2 * q1 * q3 - 2 * q0 * q2;
+ mat.m21 = 2 * q2 * q3 + 2 * q0 * q1;
+ mat.m22 = q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3;
+ }
+
+ public Quat add(float x) {
+ // scalar theta addition (degrees)
+ return newVA(getNormal(), getTheta() + x);
+ }
+
+ public Quat mul(float x) {
+ // scalar theta multiplication
+ return (x == 1 ? new4(q1, q2, q3, q0) :
+ newVA(getNormal(), getTheta() * x));
+ }
+
+ public Quat mulQ(Quat p) {
+ return new4(
+ q0 * p.q1 + q1 * p.q0 + q2 * p.q3 - q3 * p.q2,
+ q0 * p.q2 + q2 * p.q0 + q3 * p.q1 - q1 * p.q3,
+ q0 * p.q3 + q3 * p.q0 + q1 * p.q2 - q2 * p.q1,
+ q0 * p.q0 - q1 * p.q1 - q2 * p.q2 - q3 * p.q3);
+ }
+
+ public Quat div(Quat p) {
+ // unit quaternions assumed -- otherwise would scale by 1/p.dot(p)
+ return mulQ(p.inv());
+ }
+
+ public Quat divLeft(Quat p) {
+ // unit quaternions assumed -- otherwise would scale by 1/p.dot(p)
+ return this.inv().mulQ(p);
+ }
+
+ public float dot(Quat q) {
+ return this.q0 * q.q0 + this.q1 * q.q1 + this.q2 * q.q2 + this.q3 * q.q3;
+ }
+
+ public Quat inv() {
+ return new4(-q1, -q2, -q3, q0);
+ }
+
+ public Quat negate() {
+ return new4(-q1, -q2, -q3, -q0);
+ }
+
+ /**
+ * ensures
+ *
+ * 1) q0 > 0
+ * or
+ * 2) q0 = 0 and q1 > 0
+ * or
+ * 3) q0 = 0 and q1 = 0 and q2 > 0
+ * or
+ * 4) q0 = 0 and q1 = 0 and q2 = 0 and q3 > 0
+ *
+ * @return 1 or -1
+ *
+ */
+
+ private float getFixFactor() {
+ return (q0 < 0 ||
+ q0 == 0 && (q1 < 0 || q1 == 0 && (q2 < 0 || q2 == 0 && q3 < 0)) ? -1 : 1);
+ }
+
+ public V3 getVector(int i) {
+ return getVectorScaled(i, 1f);
+ }
+
+ public V3 getVectorScaled(int i, float scale) {
+ if (i == -1) {
+ scale *= getFixFactor();
+ return V3.new3(q1 * scale, q2 * scale, q3 * scale);
+ }
+ if (mat == null)
+ setMatrix();
+ V3 v = new V3();
+ mat.getColumnV(i, v);
+ if (scale != 1f)
+ v.scale(scale);
+ return v;
+ }
+
+ /**
+ *
+ * @return vector such that 0 <= angle <= 180
+ */
+ public V3 getNormal() {
+ V3 v = getRawNormal(this);
+ v.scale(getFixFactor());
+ return v;
+ }
+
+ private static V3 getRawNormal(Quat q) {
+ V3 v = V3.new3(q.q1, q.q2, q.q3);
+ if (v.length() == 0)
+ return V3.new3(0, 0, 1);
+ v.normalize();
+ return v;
+ }
+
+ /**
+ *
+ * @return 0 <= angle <= 180 in degrees
+ */
+ public float getTheta() {
+ return (float) (Math.acos(Math.abs(q0)) * 2 * 180 / Math.PI);
+ }
+
+ public float getThetaRadians() {
+ return (float) (Math.acos(Math.abs(q0)) * 2);
+ }
+
+ /**
+ *
+ * @param v0
+ * @return vector option closest to v0
+ *
+ */
+ public V3 getNormalDirected(V3 v0) {
+ V3 v = getNormal();
+ if (v.x * v0.x + v.y * v0.y + v.z * v0.z < 0) {
+ v.scale(-1);
+ }
+ return v;
+ }
+
+ public V3 get3dProjection(V3 v3d) {
+ v3d.set(q1, q2, q3);
+ return v3d;
+ }
+
+ /**
+ *
+ * @param axisAngle
+ * @return fill in theta of axisAngle such that
+ */
+ public P4 getThetaDirected(P4 axisAngle) {
+ //fills in .w;
+ float theta = getTheta();
+ V3 v = getNormal();
+ if (axisAngle.x * q1 + axisAngle.y * q2 + axisAngle.z * q3 < 0) {
+ v.scale(-1);
+ theta = -theta;
+ }
+ axisAngle.set4(v.x, v.y, v.z, theta);
+ return axisAngle;
+ }
+
+ /**
+ *
+ * @param vector a vector, same as for getNormalDirected
+ * @return return theta
+ */
+ public float getThetaDirectedV(V3 vector) {
+ //fills in .w;
+ float theta = getTheta();
+ V3 v = getNormal();
+ if (vector.x * q1 + vector.y * q2 + vector.z * q3 < 0) {
+ v.scale(-1);
+ theta = -theta;
+ }
+ return theta;
+ }
+
+ /**
+ * Quaternions are saved as {q1, q2, q3, q0}
+ *
+ * While this may seem odd, it is so that for any point4 --
+ * planes, axisangles, and quaternions -- we can use the
+ * first three coordinates to determine the relavent axis
+ * the fourth then gives us offset to {0,0,0} (plane),
+ * rotation angle (axisangle), and cos(theta/2) (quaternion).
+ * @return {x y z w} (unnormalized)
+ */
+ public P4 toPoint4f() {
+ return P4.new4(q1, q2, q3, q0); // x,y,z,w
+ }
+
+ public A4 toAxisAngle4f() {
+ double theta = 2 * Math.acos(Math.abs(q0));
+ double sinTheta2 = Math.sin(theta/2);
+ V3 v = getNormal();
+ if (sinTheta2 < 0) {
+ v.scale(-1);
+ theta = Math.PI - theta;
+ }
+ return A4.newVA(v, (float) theta);
+ }
+
+ public T3 transform2(T3 pt, T3 ptNew) {
+ if (mat == null)
+ setMatrix();
+ mat.rotate2(pt, ptNew);
+ return ptNew;
+ }
+
+ public Quat leftDifference(Quat q2) {
+ //dq = q.leftDifference(qnext);//q.inv().mul(qnext);
+ Quat q2adjusted = (this.dot(q2) < 0 ? q2.negate() : q2);
+ return inv().mulQ(q2adjusted);
+ }
+
+ public Quat rightDifference(Quat q2) {
+ //dq = qnext.rightDifference(q);//qnext.mul(q.inv());
+ Quat q2adjusted = (this.dot(q2) < 0 ? q2.negate() : q2);
+ return mulQ(q2adjusted.inv());
+ }
+
+ /**
+ *
+ * Java axisAngle / plane / Point4f format
+ * all have the format {x y z w}
+ * so we go with that here as well
+ *
+ * @return "{q1 q2 q3 q0}"
+ */
+ @Override
+ public String toString() {
+ return "{" + q1 + " " + q2 + " " + q3 + " " + q0 + "}";
+ }
+
+ /**
+ *
+ * @param data1
+ * @param data2
+ * @param nMax > 0 --> limit to this number
+ * @param isRelative
+ *
+ * @return pairwise array of data1 / data2 or data1 \ data2
+ */
+ public static Quat[] div(Quat[] data1, Quat[] data2, int nMax, boolean isRelative) {
+ int n;
+ if (data1 == null || data2 == null || (n = Math.min(data1.length, data2.length)) == 0)
+ return null;
+ if (nMax > 0 && n > nMax)
+ n = nMax;
+ Quat[] dqs = new Quat[n];
+ for (int i = 0; i < n; i++) {
+ if (data1[i] == null || data2[i] == null)
+ return null;
+ dqs[i] = (isRelative ? data1[i].divLeft(data2[i]) : data1[i].div(data2[i]));
+ }
+ return dqs;
+ }
+
+ public static Quat sphereMean(Quat[] data, float[] retStddev, float criterion) {
+ // Samuel R. Buss, Jay P. Fillmore:
+ // Spherical averages and applications to spherical splines and interpolation.
+ // ACM Trans. Graph. 20(2): 95-126 (2001)
+ if (data == null || data.length == 0)
+ return new Quat();
+ if (retStddev == null)
+ retStddev = new float[1];
+ if (data.length == 1) {
+ retStddev[0] = 0;
+ return newQ(data[0]);
+ }
+ float diff = Float.MAX_VALUE;
+ float lastStddev = Float.MAX_VALUE;
+ Quat qMean = simpleAverage(data);
+ int maxIter = 100; // typically goes about 5 iterations
+ int iter = 0;
+ while (diff > criterion && lastStddev != 0 && iter < maxIter) {
+ qMean = newMean(data, qMean);
+ retStddev[0] = stdDev(data, qMean);
+ diff = Math.abs(retStddev[0] - lastStddev);
+ lastStddev = retStddev[0];
+ //Logger.info(++iter + " sphereMean " + qMean + " stddev=" + lastStddev + " diff=" + diff);
+ }
+ return qMean;
+ }
+
+ /**
+ * Just a starting point.
+ * get average normal vector
+ * scale normal by average projection of vectors onto it
+ * create quaternion from this 3D projection
+ *
+ * @param ndata
+ * @return approximate average
+ */
+ private static Quat simpleAverage(Quat[] ndata) {
+ V3 mean = V3.new3(0, 0, 1);
+ // using the directed normal ensures that the mean is
+ // continually added to and never subtracted from
+ V3 v = ndata[0].getNormal();
+ mean.add(v);
+ for (int i = ndata.length; --i >= 0;)
+ mean.add(ndata[i].getNormalDirected(mean));
+ mean.sub(v);
+ mean.normalize();
+ float f = 0;
+ // the 3D projection of the quaternion is [sin(theta/2)]*n
+ // so dotted with the normalized mean gets us an approximate average for sin(theta/2)
+ for (int i = ndata.length; --i >= 0;)
+ f += Math.abs(ndata[i].get3dProjection(v).dot(mean));
+ if (f != 0)
+ mean.scale(f / ndata.length);
+ // now convert f to the corresponding cosine instead of sine
+ f = (float) Math.sqrt(1 - mean.lengthSquared());
+ if (Float.isNaN(f))
+ f = 0;
+ return newP4(P4.new4(mean.x, mean.y, mean.z, f));
+ }
+
+ private static Quat newMean(Quat[] data, Quat mean) {
+ /* quaternion derivatives nicely take care of producing the necessary
+ * metric. Since dq gives us the normal with the smallest POSITIVE angle,
+ * we just scale by that -- using degrees.
+ * No special normalization is required.
+ *
+ * The key is that the mean has been set up already, and dq.getTheta()
+ * will always return a value between 0 and 180. True, for groupings
+ * where dq swings wildly -- 178, 182, 178, for example -- there will
+ * be problems, but the presumption here is that there is a REASONABLE
+ * set of data. Clearly there are spherical data sets that simply cannot
+ * be assigned a mean. (For example, where the three projected points
+ * are equally distant on the sphere. We just can't worry about those
+ * cases here. Rather, if there is any significance to the data,
+ * there will be clusters of projected points, and the analysis will
+ * be meaningful.
+ *
+ * Note that the hemisphere problem drops out because dq.getNormal() and
+ * dq.getTheta() will never return (n, 182 degrees) but will
+ * instead return (-n, 2 degrees). That's just what we want in that case.
+ *
+ * Note that the projection in this case is to 3D -- a set of vectors
+ * in space with lengths proportional to theta (not the sin(theta/2)
+ * that is associated with a quaternion map).
+ *
+ * This is officially an "exponential" or "hyperbolic" projection.
+ *
+ */
+ V3 sum = new V3();
+ V3 v;
+ Quat q, dq;
+ //System.out.println("newMean mean " + mean);
+ for (int i = data.length; --i >= 0;) {
+ q = data[i];
+ dq = q.div(mean);
+ v = dq.getNormal();
+ v.scale(dq.getTheta());
+ sum.add(v);
+ }
+ sum.scale(1f/data.length);
+ Quat dqMean = newVA(sum, sum.length());
+ //System.out.println("newMean dqMean " + dqMean + " " + dqMean.getNormal() + " " + dqMean.getTheta());
+ return dqMean.mulQ(mean);
+ }
+
+ /**
+ * @param data
+ * @param mean
+ * @return standard deviation in units of degrees
+ */
+ private static float stdDev(Quat[] data, Quat mean) {
+ // the quaternion dot product gives q0 for dq (i.e. q / mean)
+ // that is, cos(theta/2) for theta between them
+ double sum2 = 0;
+ int n = data.length;
+ for (int i = n; --i >= 0;) {
+ float theta = data[i].div(mean).getTheta();
+ sum2 += theta * theta;
+ }
+ return (float) Math.sqrt(sum2 / n);
+ }
+
+ public float[] getEulerZYZ() {
+ // http://www.swarthmore.edu/NatSci/mzucker1/e27/diebel2006attitude.pdf
+ double rA, rB, rG;
+ if (q1 == 0 && q2 == 0) {
+ float theta = getTheta();
+ // pure Z rotation - ambiguous
+ return new float[] { q3 < 0 ? -theta : theta , 0, 0 };
+ }
+ rA = Math.atan2(2 * (q2 * q3 + q0 * q1), 2 * (-q1 * q3 + q0 * q2 ));
+ rB = Math.acos(q3 * q3 - q2 * q2 - q1 * q1 + q0 * q0);
+ rG = Math.atan2( 2 * (q2 * q3 - q0 * q1), 2 * (q0 * q2 + q1 * q3));
+ return new float[] {(float) (rA / RAD_PER_DEG), (float) (rB / RAD_PER_DEG), (float) (rG / RAD_PER_DEG)};
+ }
+
+ public float[] getEulerZXZ() {
+ // NOT http://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles
+ // http://www.swarthmore.edu/NatSci/mzucker1/e27/diebel2006attitude.pdf
+ double rA, rB, rG;
+ if (q1 == 0 && q2 == 0) {
+ float theta = getTheta();
+ // pure Z rotation - ambiguous
+ return new float[] { q3 < 0 ? -theta : theta , 0, 0 };
+ }
+ rA = Math.atan2(2 * (q1 * q3 - q0 * q2), 2 * (q0 * q1 + q2 * q3 ));
+ rB = Math.acos(q3 * q3 - q2 * q2 - q1 * q1 + q0 * q0);
+ rG = Math.atan2( 2 * (q1 * q3 + q0 * q2), 2 * (-q2 * q3 + q0 * q1));
+ return new float[] {(float) (rA / RAD_PER_DEG), (float) (rB / RAD_PER_DEG), (float) (rG / RAD_PER_DEG)};
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author: hansonr $
+ * $Date: 2007-04-05 09:07:28 -0500 (Thu, 05 Apr 2007) $
+ * $Revision: 7326 $
+ *
+ * Copyright (C) 2003-2005 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+package javajs.util;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.StringReader;
+import java.io.UnsupportedEncodingException;
+
+import java.util.Map;
+
+
+import javajs.api.GenericCifDataParser;
+import javajs.api.GenericLineReader;
+import javajs.api.GenericZipTools;
+
+/**
+ * A general helper class for a variety of stream and reader functionality
+ * including:
+ *
+ * stream and byte magic-number decoding for PNG, PNGJ, ZIP, and GZIP streams
+ *
+ * various stream/reader methods, including UTF-encoded stream reading
+ *
+ * reflection-protected access to a CIF parser and ZIP tools
+ *
+ *
+ *
+ *
+ */
+public class Rdr implements GenericLineReader {
+
+ BufferedReader reader;
+
+ public Rdr(BufferedReader reader) {
+ this.reader = reader;
+ }
+
+ @Override
+ public String readNextLine() throws Exception {
+ return reader.readLine();
+ }
+
+ public static Map<String, Object> readCifData(GenericCifDataParser parser, BufferedReader br) {
+ return parser.set(null, br).getAllCifData();
+ }
+
+
+ ///////////
+
+ public static String fixUTF(byte[] bytes) {
+ Encoding encoding = getUTFEncoding(bytes);
+ if (encoding != Encoding.NONE)
+ try {
+ String s = new String(bytes, encoding.name().replace('_', '-'));
+ switch (encoding) {
+ case UTF8:
+ case UTF_16BE:
+ case UTF_16LE:
+ // extra byte at beginning removed
+ s = s.substring(1);
+ break;
+ default:
+ break;
+ }
+ return s;
+ } catch (UnsupportedEncodingException e) {
+ System.out.println(e);
+ }
+ return new String(bytes);
+ }
+
+ private static Encoding getUTFEncoding(byte[] bytes) {
+ if (bytes.length >= 3 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF)
+ return Encoding.UTF8;
+ if (bytes.length >= 4 && bytes[0] == (byte) 0 && bytes[1] == (byte) 0
+ && bytes[2] == (byte) 0xFE && bytes[3] == (byte) 0xFF)
+ return Encoding.UTF_32BE;
+ if (bytes.length >= 4 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE
+ && bytes[2] == (byte) 0 && bytes[3] == (byte) 0)
+ return Encoding.UTF_32LE;
+ if (bytes.length >= 2 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE)
+ return Encoding.UTF_16LE;
+ if (bytes.length >= 2 && bytes[0] == (byte) 0xFE && bytes[1] == (byte) 0xFF)
+ return Encoding.UTF_16BE;
+ return Encoding.NONE;
+
+ }
+
+ ////////// stream type checking //////////
+
+
+ private static Encoding getUTFEncodingForStream(BufferedInputStream is) throws IOException {
+ /**
+ * @j2sNative
+ *
+ * is.resetStream();
+ *
+ */
+ {
+ }
+ byte[] abMagic = new byte[4];
+ abMagic[3] = 1;
+ try{
+ is.mark(5);
+ } catch (Exception e) {
+ return Encoding.NONE;
+ }
+ is.read(abMagic, 0, 4);
+ is.reset();
+ return getUTFEncoding(abMagic);
+ }
+
+ public static boolean isBase64(SB sb) {
+ return (sb.indexOf(";base64,") == 0);
+ }
+
+ public static boolean isCompoundDocumentS(InputStream is) {
+ return isCompoundDocumentB(getMagic(is, 8));
+ }
+
+ public static boolean isCompoundDocumentB(byte[] bytes) {
+ return (bytes.length >= 8 && bytes[0] == (byte) 0xD0
+ && bytes[1] == (byte) 0xCF && bytes[2] == (byte) 0x11
+ && bytes[3] == (byte) 0xE0 && bytes[4] == (byte) 0xA1
+ && bytes[5] == (byte) 0xB1 && bytes[6] == (byte) 0x1A
+ && bytes[7] == (byte) 0xE1);
+ }
+
+ public static boolean isGzipS(InputStream is) {
+ return isGzipB(getMagic(is, 2));
+ }
+
+ public static boolean isGzipB(byte[] bytes) {
+ return (bytes != null && bytes.length >= 2
+ && bytes[0] == (byte) 0x1F && bytes[1] == (byte) 0x8B);
+ }
+
+ public static boolean isPickleS(InputStream is) {
+ return Rdr.isPickleB(getMagic(is, 2));
+ }
+
+ public static boolean isPickleB(byte[] bytes) {
+ return (bytes != null && bytes.length >= 2
+ && bytes[0] == (byte) 0x7D && bytes[1] == (byte) 0x71);
+ }
+
+ public static boolean isPngZipStream(InputStream is) {
+ return isPngZipB(getMagic(is, 55));
+ }
+
+ public static boolean isPngZipB(byte[] bytes) {
+ // \0PNGJ starting at byte 50
+ return (bytes[50] == 0 && bytes[51] == 0x50 && bytes[52] == 0x4E && bytes[53] == 0x47 && bytes[54] == 0x4A);
+ }
+
+ public static boolean isZipS(InputStream is) {
+ return isZipB(getMagic(is, 4));
+ }
+
+ public static boolean isZipB(byte[] bytes) {
+ return (bytes.length >= 4
+ && bytes[0] == 0x50 //PK<03><04>
+ && bytes[1] == 0x4B
+ && bytes[2] == 0x03
+ && bytes[3] == 0x04);
+ }
+
+ private static byte[] getMagic(InputStream is, int n) {
+ byte[] abMagic = new byte[n];
+ /**
+ * @j2sNative
+ *
+ * is.resetStream();
+ *
+ */
+ {
+ }
+ try {
+ is.mark(n + 1);
+ is.read(abMagic, 0, n);
+ } catch (IOException e) {
+ }
+ try {
+ is.reset();
+ } catch (IOException e) {
+ }
+ return abMagic;
+ }
+
+ public static String guessMimeTypeForBytes(byte[] bytes) {
+ // only options here are JPEG, PNG, GIF, and BMP
+ switch (bytes.length < 2 ? -1 : bytes[1]) {
+ case 0:
+ return "image/jpg"; // 0xFF 0x00 ...
+ case 0x49:
+ return "image/gif"; // GIF89a...
+ case 0x4D:
+ return "image/BMP"; // BM...
+ case 0x50:
+ return "image/png";
+ default:
+ return "image/unknown";
+ }
+ }
+
+
+ ////////// stream/byte methods ///////////
+
+ public static BufferedInputStream getBIS(byte[] bytes) {
+ return new BufferedInputStream(new ByteArrayInputStream(bytes));
+ }
+
+ public static BufferedReader getBR(String string) {
+ return new BufferedReader(new StringReader(string));
+ }
+
+ /**
+ * Drill down into a GZIP stack until no more layers.
+ * @param jzt
+ *
+ * @param bis
+ * @return non-gzipped buffered input stream.
+ *
+ * @throws IOException
+ */
+ public static BufferedInputStream getUnzippedInputStream(GenericZipTools jzt, BufferedInputStream bis) throws IOException {
+ while (isGzipS(bis))
+ bis = new BufferedInputStream(jzt.newGZIPInputStream(bis));
+ return bis;
+ }
+
+ /**
+ * Allow for base64-encoding check.
+ *
+ * @param sb
+ * @return byte array
+ */
+ public static byte[] getBytesFromSB(SB sb) {
+ return (isBase64(sb) ? Base64.decodeBase64(sb.substring(8)) : sb.toBytes(0, -1));
+ }
+
+ /**
+ * Read a an entire BufferedInputStream for its bytes, and
+ * either return them or leave them in the designated output channel.
+ *
+ * @param bis
+ * @param out a destination output channel, or null
+ * @return byte[] (if out is null) or a message indicating length (if not)
+ *
+ * @throws IOException
+ */
+ public static Object getStreamAsBytes(BufferedInputStream bis,
+ OC out) throws IOException {
+ byte[] buf = new byte[1024];
+ byte[] bytes = (out == null ? new byte[4096] : null);
+ int len = 0;
+ int totalLen = 0;
+ while ((len = bis.read(buf, 0, 1024)) > 0) {
+ totalLen += len;
+ if (out == null) {
+ if (totalLen >= bytes.length)
+ bytes = AU.ensureLengthByte(bytes, totalLen * 2);
+ System.arraycopy(buf, 0, bytes, totalLen - len, len);
+ } else {
+ out.write(buf, 0, len);
+ }
+ }
+ bis.close();
+ if (out == null) {
+ return AU.arrayCopyByte(bytes, totalLen);
+ }
+ return totalLen + " bytes";
+ }
+
+ /**
+ * Read an input stream fully, saving a byte array, then
+ * return a buffered reader to those bytes converted to string form.
+ *
+ * @param bis
+ * @param charSet
+ * @return Reader
+ * @throws IOException
+ */
+ public static BufferedReader getBufferedReader(BufferedInputStream bis, String charSet)
+ throws IOException {
+ // could also just make sure we have a buffered input stream here.
+ if (getUTFEncodingForStream(bis) == Encoding.NONE)
+ return new BufferedReader(new InputStreamReader(bis, (charSet == null ? "UTF-8" : charSet)));
+ byte[] bytes = getLimitedStreamBytes(bis, -1);
+ bis.close();
+ return getBR(charSet == null ? fixUTF(bytes) : new String(bytes, charSet));
+ }
+
+ /**
+ * Read a possibly limited number of bytes (when n > 0) from a stream,
+ * leaving the stream open.
+ *
+ * @param is an input stream, not necessarily buffered.
+ * @param n the maximum number of bytes to read, or -1 for all
+ * @return the bytes read
+ *
+ * @throws IOException
+ */
+ public static byte[] getLimitedStreamBytes(InputStream is, long n)
+ throws IOException {
+
+ //Note: You cannot use InputStream.available() to reliably read
+ // zip data from the web.
+
+ int buflen = (n > 0 && n < 1024 ? (int) n : 1024);
+ byte[] buf = new byte[buflen];
+ byte[] bytes = new byte[n < 0 ? 4096 : (int) n];
+ int len = 0;
+ int totalLen = 0;
+ if (n < 0)
+ n = Integer.MAX_VALUE;
+ while (totalLen < n && (len = is.read(buf, 0, buflen)) > 0) {
+ totalLen += len;
+ if (totalLen > bytes.length)
+ bytes = AU.ensureLengthByte(bytes, totalLen * 2);
+ System.arraycopy(buf, 0, bytes, totalLen - len, len);
+ if (n != Integer.MAX_VALUE && totalLen + buflen > bytes.length)
+ buflen = bytes.length - totalLen;
+
+ }
+ if (totalLen == bytes.length)
+ return bytes;
+ buf = new byte[totalLen];
+ System.arraycopy(bytes, 0, buf, 0, totalLen);
+ return buf;
+ }
+
+ /**
+ *
+ * Read a UTF-8 stream fully, converting it to a String.
+ * Called by Jmol's XMLReaders
+ *
+ * @param bis
+ * @return a UTF-8 string
+ */
+ public static String StreamToUTF8String(BufferedInputStream bis) {
+ String[] data = new String[1];
+ try {
+ readAllAsString(getBufferedReader(bis, "UTF-8"), -1, true, data, 0);
+ } catch (IOException e) {
+ }
+ return data[0];
+ }
+
+ /**
+ * This method fills data[i] with string data from a file that may or may not
+ * be binary even though it is being read by a reader. It is meant to be used
+ * simple text-based files only.
+ *
+ * @param br
+ * @param nBytesMax
+ * @param allowBinary
+ * @param data
+ * @param i
+ * @return true if data[i] holds the data; false if data[i] holds an error message.
+ */
+ public static boolean readAllAsString(BufferedReader br, int nBytesMax, boolean allowBinary, String[] data, int i) {
+ try {
+ SB sb = SB.newN(8192);
+ String line;
+ if (nBytesMax < 0) {
+ line = br.readLine();
+ if (allowBinary || line != null && line.indexOf('\0') < 0
+ && (line.length() != 4 || line.charAt(0) != 65533
+ || line.indexOf("PNG") != 1)) {
+ sb.append(line).appendC('\n');
+ while ((line = br.readLine()) != null)
+ sb.append(line).appendC('\n');
+ }
+ } else {
+ int n = 0;
+ int len;
+ while (n < nBytesMax && (line = br.readLine()) != null) {
+ if (nBytesMax - n < (len = line.length()) + 1)
+ line = line.substring(0, nBytesMax - n - 1);
+ sb.append(line).appendC('\n');
+ n += len + 1;
+ }
+ }
+ br.close();
+ data[i] = sb.toString();
+ return true;
+ } catch (Exception ioe) {
+ data[i] = ioe.toString();
+ return false;
+ }
+ }
+
+
+ /////////// PNGJ support /////////////
+
+
+ /**
+ * Look at byte 50 for "\0PNGJxxxxxxxxx+yyyyyyyyy" where xxxxxxxxx is a byte
+ * offset to the JMOL data and yyyyyyyyy is the length of the data.
+ *
+ * @param bis
+ * @return same stream or byte stream
+ */
+
+ /**
+ * Retrieve the two numbers in a PNG iTXt tag indicating the
+ * file pointer for the start of the ZIP data as well as its length.
+ *
+ * @param bis
+ * @param pt_count
+ */
+ static void getPngZipPointAndCount(BufferedInputStream bis, int[] pt_count) {
+ bis.mark(75);
+ try {
+ byte[] data = getLimitedStreamBytes(bis, 74);
+ bis.reset();
+ int pt = 0;
+ for (int i = 64, f = 1; --i > 54; f *= 10)
+ pt += (data[i] - '0') * f;
+ int n = 0;
+ for (int i = 74, f = 1; --i > 64; f *= 10)
+ n += (data[i] - '0') * f;
+ pt_count[0] = pt;
+ pt_count[1] = n;
+ } catch (Throwable e) {
+ pt_count[1] = 0;
+ }
+ }
+
+ /**
+ * Either advance a PNGJ stream to its zip file data or pull out the ZIP data
+ * bytes and create a new stream for them from which a ZIP utility can start
+ * extracting files.
+ *
+ * @param bis
+ * @param asNewStream
+ * @return new buffered ByteArrayInputStream, possibly with no data if there is an error
+ */
+ public static BufferedInputStream getPngZipStream(BufferedInputStream bis, boolean asNewStream) {
+ if (!isPngZipStream(bis))
+ return bis;
+ byte[] data = new byte[0];
+ bis.mark(75);
+ try {
+ int pt_count[] = new int[2];
+ getPngZipPointAndCount(bis, pt_count);
+ if (pt_count[1] != 0) {
+ int pt = pt_count[0];
+ while (pt > 0)
+ pt -= bis.skip(pt);
+ if (!asNewStream)
+ return bis;
+ data = getLimitedStreamBytes(bis, pt_count[1]);
+ }
+ } catch (Throwable e) {
+ } finally {
+ try {
+ if (asNewStream)
+ bis.close();
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ return getBIS(data);
+ }
+
+ /** We define a request for zip file extraction by vertical bar:
+ * zipName|interiorFileName. These may be nested if there is a
+ * zip file contained in a zip file.
+ *
+ * @param fileName
+ * @return filename trimmed of interior fileName
+ *
+ */
+ public static String getZipRoot(String fileName) {
+ int pt = fileName.indexOf("|");
+ return (pt < 0 ? fileName : fileName.substring(0, pt));
+ }
+
+
+}
+
--- /dev/null
+
+package javajs.util;
+
+import javajs.J2SIgnoreImport;
+
+/**
+ * Interesting thing here is that JavaScript is 3x faster than Java in handling strings.
+ *
+ * Java StringBuilder is final, unfortunately. I guess they weren't thinking about Java2Script!
+ *
+ * The reason we have to do this that several overloaded append methods is WAY too expensive
+ *
+ */
+
+@J2SIgnoreImport({java.lang.StringBuilder.class})
+public class SB {
+
+ private java.lang.StringBuilder sb;
+ String s; // used by JavaScript only; no Java references
+
+ //TODO: JS experiment with using array and .push() here
+
+ public SB() {
+ /**
+ * @j2sNative
+ *
+ * this.s = "";
+ *
+ */
+ {
+ sb = new java.lang.StringBuilder();
+ }
+ }
+
+ public static SB newN(int n) {
+ /**
+ * @j2sNative
+ * return new javajs.util.SB();
+ */
+ {
+ // not perfect, because it requires defining sb twice.
+ // We can do better...
+ SB sb = new SB();
+ sb.sb = new java.lang.StringBuilder(n);
+ return sb;
+ }
+ }
+
+ public static SB newS(String s) {
+ /**
+ * @j2sNative
+ *
+ * var sb = new javajs.util.SB();
+ * sb.s = s;
+ * return sb;
+ *
+ */
+ {
+ SB sb = new SB();
+ sb.sb = new java.lang.StringBuilder(s);
+ return sb;
+ }
+ }
+
+ public SB append(String s) {
+ /**
+ * @j2sNative
+ *
+ * this.s += s
+ *
+ */
+ {
+ sb.append(s);
+ }
+ return this;
+ }
+
+ public SB appendC(char c) {
+ /**
+ * @j2sNative
+ *
+ * this.s += c;
+ */
+ {
+ sb.append(c);
+ }
+ return this;
+
+ }
+
+ public SB appendI(int i) {
+ /**
+ * @j2sNative
+ *
+ * this.s += i
+ *
+ */
+ {
+ sb.append(i);
+ }
+ return this;
+ }
+
+ public SB appendB(boolean b) {
+ /**
+ * @j2sNative
+ *
+ * this.s += b
+ *
+ */
+ {
+ sb.append(b);
+ }
+ return this;
+ }
+
+ /**
+ * note that JavaScript could drop off the ".0" in "1.0"
+ * @param f
+ * @return this
+ */
+ public SB appendF(float f) {
+ /**
+ * @j2sNative
+ *
+ * var sf = "" + f;
+ * if (sf.indexOf(".") < 0 && sf.indexOf("e") < 0)
+ * sf += ".0" ;
+ * this.s += sf;
+ *
+ */
+ {
+ sb.append(f);
+ }
+ return this;
+ }
+
+ public SB appendD(double d) {
+ /**
+ * @j2sNative
+ *
+ * var sf = "" + d;
+ * if (sf.indexOf(".") < 0 && sf.indexOf("e") < 0)
+ * sf += ".0" ;
+ * this.s += sf;
+ *
+ */
+ {
+ sb.append(d);
+ }
+ return this;
+ }
+
+ public SB appendSB(SB buf) {
+ /**
+ * @j2sNative
+ *
+ * this.s += buf.s;
+ *
+ */
+ {
+ sb.append(buf.sb);
+ }
+ return this;
+ }
+
+ public SB appendO(Object data) {
+ if (data != null) {
+ /**
+ * @j2sNative
+ *
+ * this.s += data.toString();
+ *
+ */
+ {
+ sb.append(data);
+ }
+ }
+ return this;
+ }
+
+ public void appendCB(char[] cb, int off, int len) {
+ /**
+ * @j2sNative
+ *
+ * for (var i = len,j=off; --i >= 0;)
+ * this.s += cb[j++];
+ *
+ */
+ {
+ sb.append(cb, off, len);
+ }
+ }
+
+ @Override
+ public String toString() {
+ /**
+ * @j2sNative
+ *
+ * return this.s;
+ *
+ */
+ {
+ return sb.toString();
+ }
+ }
+
+ public int length() {
+ /**
+ * @j2sNative
+ *
+ * return this.s.length;
+ *
+ */
+ {
+ return sb.length();
+ }
+ }
+
+ public int indexOf(String s) {
+ /**
+ * @j2sNative
+ *
+ * return this.s.indexOf(s);
+ *
+ */
+ {
+ return sb.indexOf(s);
+ }
+ }
+
+ public char charAt(int i) {
+ /**
+ * @j2sNative
+ *
+ * return this.s.charAt(i);
+ *
+ */
+ {
+ return sb.charAt(i);
+ }
+ }
+
+ public int charCodeAt(int i) {
+ /**
+ * @j2sNative
+ *
+ * return this.s.charCodeAt(i);
+ *
+ */
+ {
+ return sb.codePointAt(i);
+ }
+ }
+
+ public void setLength(int n) {
+ /**
+ * @j2sNative
+ *
+ * this.s = this.s.substring(0, n);
+ */
+ {
+ sb.setLength(n);
+ }
+ }
+
+ public int lastIndexOf(String s) {
+ /**
+ * @j2sNative
+ *
+ * return this.s.lastIndexOf(s);
+ */
+ {
+ return sb.lastIndexOf(s);
+ }
+ }
+
+ public int indexOf2(String s, int i) {
+ /**
+ * @j2sNative
+ *
+ * return this.s.indexOf(s, i);
+ */
+ {
+ return sb.indexOf(s, i);
+ }
+ }
+
+ public String substring(int i) {
+ /**
+ * @j2sNative
+ *
+ * return this.s.substring(i);
+ */
+ {
+ return sb.substring(i);
+ }
+ }
+
+ public String substring2(int i, int j) {
+ /**
+ * @j2sNative
+ *
+ * return this.s.substring(i, j);
+ */
+ {
+ return sb.substring(i, j);
+ }
+ }
+
+ /**
+ * simple byte conversion not allowing for unicode.
+ * Used for base64 conversion and allows for offset
+ * @param off
+ * @param len or -1 for full length (then off must = 0)
+ * @return byte[]
+ */
+ public byte[] toBytes(int off, int len) {
+ if (len < 0)
+ len = length() - off;
+ byte[] b = new byte[len];
+ for (int i = off + len, j = i - off; --i >= off;)
+ b[--j] = (byte) charAt(i);
+ return b;
+ }
+
+ public void replace(int start, int end, String str) {
+ /**
+ * @j2sNative
+ *
+ * this.s = this.s.substring(0, start) + str + this.s.substring(end);
+ */
+ {
+ sb.replace(start, end, str);
+ }
+ }
+
+ public void insert(int offset, String str) {
+ replace(offset, offset, str);
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Copyright (C) 2011 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package javajs.util;
+
+import java.io.StringReader;
+
+
+
+
+
+public class StringDataReader extends DataReader {
+
+ public StringDataReader() {
+ super();
+ }
+
+ public StringDataReader(String data) {
+ super(new StringReader(data));
+ }
+
+ @Override
+ public DataReader setData(Object data) {
+ return new StringDataReader((String) data);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+import java.io.Serializable;
+
+import javajs.api.JSONEncodable;
+
+/**
+ * A generic 3 element tuple that is represented by single precision floating
+ * point x,y and z coordinates.
+ *
+ * @version specification 1.1, implementation $Revision: 1.10 $, $Date:
+ * 2006/09/08 20:20:20 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
+ * for unique constructor and method names
+ * for the optimization of compiled JavaScript using Java2Script
+ */
+public abstract class T3 implements JSONEncodable, Serializable {
+
+ public float x, y, z;
+
+ /**
+ * @j2sIgnore
+ *
+ */
+ public T3() {
+ }
+
+ /**
+ * Sets the value of this tuple to the specified xyz coordinates.
+ *
+ * @param x
+ * the x coordinate
+ * @param y
+ * the y coordinate
+ * @param z
+ * the z coordinate
+ */
+ public final void set(float x, float y, float z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ /**
+ * Sets the value of this tuple from the 3 values specified in the array.
+ *
+ * @param t
+ * the array of length 3 containing xyz in order
+ */
+ public final void setA(float t[]) {
+ // ArrayIndexOutOfBounds is thrown if t.length < 3
+ x = t[0];
+ y = t[1];
+ z = t[2];
+ }
+
+ /**
+ * Sets the value of this tuple to the value of the Tuple3f argument.
+ *
+ * @param t1
+ * the tuple to be copied
+ */
+ public final void setT(T3 t1) {
+ x = t1.x;
+ y = t1.y;
+ z = t1.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the vector sum of tuples t1 and t2.
+ *
+ * @param t1
+ * the first tuple
+ * @param t2
+ * the second tuple
+ */
+ public final void add2(T3 t1, T3 t2) {
+ x = t1.x + t2.x;
+ y = t1.y + t2.y;
+ z = t1.z + t2.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the vector sum of itself and tuple t1.
+ *
+ * @param t1
+ * the other tuple
+ */
+ public final void add(T3 t1) {
+ x += t1.x;
+ y += t1.y;
+ z += t1.z;
+ }
+
+ /**
+ * Computes the square of the distance between this point and point p1.
+ *
+ * @param p1
+ * the other point
+ * @return the square of distance between these two points as a float
+ */
+ public final float distanceSquared(T3 p1) {
+ double dx = x - p1.x;
+ double dy = y - p1.y;
+ double dz = z - p1.z;
+ return (float) (dx * dx + dy * dy + dz * dz);
+ }
+
+ /**
+ * Returns the distance between this point and point p1.
+ *
+ * @param p1
+ * the other point
+ * @return the distance between these two points
+ */
+ public final float distance(T3 p1) {
+ return (float) Math.sqrt(distanceSquared(p1));
+ }
+
+ /**
+ * Sets the value of this tuple to the vector difference of tuple t1 and t2
+ * (this = t1 - t2).
+ *
+ * @param t1
+ * the first tuple
+ * @param t2
+ * the second tuple
+ */
+ public final void sub2(T3 t1, T3 t2) {
+ x = t1.x - t2.x;
+ y = t1.y - t2.y;
+ z = t1.z - t2.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the vector difference of itself and tuple
+ * t1 (this = this - t1).
+ *
+ * @param t1
+ * the other tuple
+ */
+ public final void sub(T3 t1) {
+ x -= t1.x;
+ y -= t1.y;
+ z -= t1.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the scalar multiplication of itself.
+ *
+ * @param s
+ * the scalar value
+ */
+ public final void scale(float s) {
+ x *= s;
+ y *= s;
+ z *= s;
+ }
+
+ /**
+ * Add {a b c}
+ *
+ * @param a
+ * @param b
+ * @param c
+ */
+ public final void add3(float a, float b, float c) {
+ x += a;
+ y += b;
+ z += c;
+ }
+
+
+ /**
+ * {x*p.x, y*p.y, z*p.z) used for three-way scaling
+ *
+ * @param p
+ */
+ public final void scaleT(T3 p) {
+ x *= p.x;
+ y *= p.y;
+ z *= p.z;
+ }
+
+
+ /**
+ * Sets the value of this tuple to the scalar multiplication of tuple t1 and
+ * then adds tuple t2 (this = s*t1 + t2).
+ *
+ * @param s
+ * the scalar value
+ * @param t1
+ * the tuple to be multipled
+ * @param t2
+ * the tuple to be added
+ */
+ public final void scaleAdd2(float s, T3 t1, T3 t2) {
+ x = s * t1.x + t2.x;
+ y = s * t1.y + t2.y;
+ z = s * t1.z + t2.z;
+ }
+
+
+ /**
+ * average of two tuples
+ *
+ * @param a
+ * @param b
+ */
+ public void ave(T3 a, T3 b) {
+ x = (a.x + b.x) / 2f;
+ y = (a.y + b.y) / 2f;
+ z = (a.z + b.z) / 2f;
+ }
+
+ /**
+ * Vector dot product. Was in Vector3f; more useful here, though.
+ *
+ * @param v
+ * the other vector
+ * @return this.dot.v
+ */
+ public final float dot(T3 v) {
+ return x * v.x + y * v.y + z * v.z;
+ }
+
+ /**
+ * Returns the squared length of this vector.
+ * Was in Vector3f; more useful here, though.
+ *
+ * @return the squared length of this vector
+ */
+ public final float lengthSquared() {
+ return x * x + y * y + z * z;
+ }
+
+ /**
+ * Returns the length of this vector.
+ * Was in Vector3f; more useful here, though.
+ *
+ * @return the length of this vector
+ */
+ public final float length() {
+ return (float) Math.sqrt(lengthSquared());
+ }
+
+ /**
+ * Normalizes this vector in place.
+ * Was in Vector3f; more useful here, though.
+ */
+ public final void normalize() {
+ double d = length();
+
+ // zero-div may occur.
+ x /= d;
+ y /= d;
+ z /= d;
+ }
+
+ /**
+ * Sets this tuple to be the vector cross product of vectors v1 and v2.
+ *
+ * @param v1
+ * the first vector
+ * @param v2
+ * the second vector
+ */
+ public final void cross(T3 v1, T3 v2) {
+ set(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y
+ - v1.y * v2.x);
+ }
+
+ /**
+ * Returns a hash number based on the data values in this object. Two
+ * different Tuple3f objects with identical data values (ie, returns true for
+ * equals(Tuple3f) ) will return the same hash number. Two vectors with
+ * different data members may return the same hash value, although this is not
+ * likely.
+ */
+ @Override
+ public int hashCode() {
+ long bits = 1L;
+ bits = 31L * bits + floatToIntBits0(x);
+ bits = 31L * bits + floatToIntBits0(y);
+ bits = 31L * bits + floatToIntBits0(z);
+ return (int) (bits ^ (bits >> 32));
+ }
+
+ public static int floatToIntBits0(float f) {
+ return (f == 0 ? 0 : Float.floatToIntBits(f));
+ }
+
+ /**
+ * Returns true if all of the data members of Tuple3f t1 are equal to the
+ * corresponding data members in this
+ *
+ * @param t1
+ * the vector with which the comparison is made.
+ */
+ @Override
+ public boolean equals(Object t1) {
+ if (!(t1 instanceof T3))
+ return false;
+ T3 t2 = (T3) t1;
+ return (x == t2.x && y == t2.y && z == t2.z);
+ }
+
+ /**
+ * Returns a string that contains the values of this Tuple3f. The form is
+ * (x,y,z).
+ *
+ * @return the String representation
+ */
+ @Override
+ public String toString() {
+ return "{" + x + ", " + y + ", " + z + "}";
+ }
+
+ @Override
+ public String toJSON() {
+ return "[" + x + "," + y + "," + z + "]";
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+import java.io.Serializable;
+
+/**
+ * A generic 3 element tuple that is represented by double precision floating
+ * point x,y and z coordinates.
+ *
+ * @version specification 1.1, implementation $Revision: 1.9 $, $Date:
+ * 2006/07/28 17:01:32 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
+ * for unique constructor and method names
+ * for the optimization of compiled JavaScript using Java2Script
+ */
+public abstract class T3d implements Serializable {
+ /**
+ * The x coordinate.
+ */
+ public double x;
+
+ /**
+ * The y coordinate.
+ */
+ public double y;
+
+ /**
+ * The z coordinate.
+ */
+ public double z;
+
+ /**
+ * Constructs and initializes a Tuple3d to (0,0,0).
+ */
+ public T3d() {
+ }
+
+ /**
+ * Sets the value of this tuple to the specified xyz coordinates.
+ *
+ * @param x
+ * the x coordinate
+ * @param y
+ * the y coordinate
+ * @param z
+ * the z coordinate
+ */
+ public final void set(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ /**
+ * Sets the value of this tuple from the 3 values specified in the array.
+ *
+ * @param t
+ * the array of length 3 containing xyz in order
+ */
+ public final void setA(double t[]) {
+ // ArrayIndexOutOfBounds is thrown if t.length < 3
+ x = t[0];
+ y = t[1];
+ z = t[2];
+ }
+
+ /**
+ * Sets the value of this tuple to the value of the Tuple3d argument.
+ *
+ * @param t1
+ * the tuple to be copied
+ */
+ public final void setT(T3d t1) {
+ x = t1.x;
+ y = t1.y;
+ z = t1.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the vector sum of tuples t1 and t2.
+ *
+ * @param t1
+ * the first tuple
+ * @param t2
+ * the second tuple
+ */
+ public final void add2(T3d t1, T3d t2) {
+ x = t1.x + t2.x;
+ y = t1.y + t2.y;
+ z = t1.z + t2.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the vector sum of itself and tuple t1.
+ *
+ * @param t1
+ * the other tuple
+ */
+ public final void add(T3d t1) {
+ x += t1.x;
+ y += t1.y;
+ z += t1.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the vector difference of tuple t1 and t2
+ * (this = t1 - t2).
+ *
+ * @param t1
+ * the first tuple
+ * @param t2
+ * the second tuple
+ */
+ public final void sub2(T3d t1, T3d t2) {
+ x = t1.x - t2.x;
+ y = t1.y - t2.y;
+ z = t1.z - t2.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the vector difference of itself and tuple
+ * t1 (this = this - t1).
+ *
+ * @param t1
+ * the other tuple
+ */
+ public final void sub(T3d t1) {
+ x -= t1.x;
+ y -= t1.y;
+ z -= t1.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the scalar multiplication of itself.
+ *
+ * @param s
+ * the scalar value
+ */
+ public final void scale(double s) {
+ x *= s;
+ y *= s;
+ z *= s;
+ }
+
+ /**
+ * Sets the value of this tuple to the scalar multiplication of tuple t1 and
+ * then adds tuple t2 (this = s*t1 + t2).
+ *
+ * @param s
+ * the scalar value
+ * @param t1
+ * the tuple to be multipled
+ * @param t2
+ * the tuple to be added
+ */
+ public final void scaleAdd(double s, T3d t1, T3d t2) {
+ x = s * t1.x + t2.x;
+ y = s * t1.y + t2.y;
+ z = s * t1.z + t2.z;
+ }
+
+ /**
+ * Returns a hash number based on the data values in this object. Two
+ * different Tuple3d objects with identical data values (ie, returns true for
+ * equals(Tuple3d) ) will return the same hash number. Two vectors with
+ * different data members may return the same hash value, although this is not
+ * likely.
+ */
+ @Override
+ public int hashCode() {
+ long xbits = doubleToLongBits0(x);
+ long ybits = doubleToLongBits0(y);
+ long zbits = doubleToLongBits0(z);
+ return (int) (xbits ^ (xbits >> 32) ^ ybits ^ (ybits >> 32) ^ zbits ^ (zbits >> 32));
+ }
+
+ static long doubleToLongBits0(double d) {
+ // Check for +0 or -0
+ return (d == 0 ? 0 : Double.doubleToLongBits(d));
+ }
+
+ /**
+ * Returns true if all of the data members of Tuple3d t1 are equal to the
+ * corresponding data members in this
+ *
+ * @param t1
+ * the vector with which the comparison is made.
+ */
+ @Override
+ public boolean equals(Object t1) {
+ if (!(t1 instanceof T3d))
+ return false;
+ T3d t2 = (T3d) t1;
+ return (this.x == t2.x && this.y == t2.y && this.z == t2.z);
+ }
+
+ /**
+ * Returns a string that contains the values of this Tuple3d. The form is
+ * (x,y,z).
+ *
+ * @return the String representation
+ */
+ @Override
+ public String toString() {
+ return "{" + x + ", " + y + ", " + z + "}";
+ }
+
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+import java.io.Serializable;
+
+/**
+ * A 3-element tuple represented by signed integer x,y,z coordinates.
+ *
+ * @since Java 3D 1.2
+ * @version specification 1.2, implementation $Revision: 1.9 $, $Date:
+ * 2006/07/28 17:01:32 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012 for unique
+ * constructor and method names for the optimization of compiled
+ * JavaScript using Java2Script
+ */
+public abstract class T3i implements Serializable {
+
+ /**
+ * The x coordinate.
+ */
+ public int x;
+
+ /**
+ * The y coordinate.
+ */
+ public int y;
+
+ /**
+ * The z coordinate.
+ */
+ public int z;
+
+ /**
+ * Constructs and initializes a Tuple3i to (0,0,0).
+ */
+ public T3i() {
+ }
+
+ /**
+ * Sets the value of this tuple to to the specified x, y, and z coordinates.
+ *
+ * @param x
+ * the x coordinate.
+ * @param y
+ * the y coordinate.
+ * @param z
+ * the z coordinate.
+ */
+ public final void set(int x, int y, int z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ /**
+ * Sets the value of this tuple to the value of tuple t1.
+ *
+ * @param t1
+ * the tuple to be copied.
+ */
+ public final void setT(T3i t1) {
+ x = t1.x;
+ y = t1.y;
+ z = t1.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the sum of itself and t1.
+ *
+ * @param t
+ * is the other tuple
+ */
+ public final void add(T3i t) {
+ x += t.x;
+ y += t.y;
+ z += t.z;
+ }
+
+ /**
+ * Sets the value of this tuple to the scalar multiplication of tuple t1 plus
+ * tuple t2 (this = s*t1 + t2).
+ *
+ * @param s
+ * the scalar value
+ * @param t1
+ * the tuple to be multipled
+ * @param t2
+ * the tuple to be added
+ */
+ public final void scaleAdd(int s, T3i t1, T3i t2) {
+ x = s * t1.x + t2.x;
+ y = s * t1.y + t2.y;
+ z = s * t1.z + t2.z;
+ }
+
+ /**
+ * Returns a hash number based on the data values in this object. Two
+ * different Tuple3i objects with identical data values (ie, returns true for
+ * equals(Tuple3i) ) will return the same hash number. Two vectors with
+ * different data members may return the same hash value, although this is not
+ * likely.
+ */
+ @Override
+ public int hashCode() {
+ return x ^ y ^ z;
+ }
+
+ /**
+ * Returns true if the Object o is of type Tuple3i and all of the data members
+ * of t are equal to the corresponding data members in this Tuple3i.
+ *
+ * @param o
+ * the object with which the comparison is made.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof T3i))
+ return false;
+ T3i t = (T3i) o;
+ return (this.x == t.x && this.y == t.y && this.z == t.z);
+ }
+
+ /**
+ * Returns a string that contains the values of this Tuple3i. The form is
+ * (x,y,z).
+ *
+ * @return the String representation
+ */
+ @Override
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ")";
+ }
+
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+/**
+ * A generic 4 element tuple that is represented by single precision floating
+ * point x,y,z and w coordinates.
+ *
+ * @version specification 1.1, implementation $Revision: 1.9 $, $Date:
+ * 2006/07/28 17:01:32 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
+ * for unique constructor and method names
+ * for the optimization of compiled JavaScript using Java2Script
+ */
+public abstract class T4 extends T3 {
+
+ /**
+ * The w coordinate.
+ */
+ public float w;
+
+ /**
+ * Constructs and initializes a Tuple4f to (0,0,0,0).
+ *
+ * @j2sIgnore *
+ */
+ public T4() {
+ }
+
+ /**
+ * Sets the value of this tuple to the specified xyzw coordinates.
+ *
+ * @param x
+ * the x coordinate
+ * @param y
+ * the y coordinate
+ * @param z
+ * the z coordinate
+ * @param w
+ * the w coordinate
+ */
+ public final void set4(float x, float y, float z, float w) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ this.w = w;
+ }
+
+ /**
+ * Sets the value of this tuple to the scalar multiplication of itself.
+ *
+ * @param s
+ * the scalar value
+ */
+ public final void scale4(float s) {
+ scale(s);
+ w *= s;
+ }
+
+ /**
+ * Returns a hash number based on the data values in this object. Two
+ * different Tuple4f objects with identical data values (ie, returns true for
+ * equals(Tuple4f) ) will return the same hash number. Two vectors with
+ * different data members may return the same hash value, although this is not
+ * likely.
+ */
+ @Override
+ public int hashCode() {
+ return floatToIntBits0(x) ^ floatToIntBits0(y)
+ ^ floatToIntBits0(z) ^ floatToIntBits0(w);
+ }
+
+ /**
+ * Returns true if all of the data members of Object are equal to the
+ * corresponding data members in this
+ *
+ * @param o
+ * the vector with which the comparison is made.
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (!(o instanceof T4))
+ return false;
+ T4 t = (T4) o;
+ return (this.x == t.x && this.y == t.y && this.z == t.z && this.w == t.w);
+ }
+
+ /**
+ * Returns a string that contains the values of this Tuple4f. The form is
+ * (x,y,z,w).
+ *
+ * @return the String representation
+ */
+ @Override
+ public String toString() {
+ return "(" + x + ", " + y + ", " + z + ", " + w + ")";
+ }
+
+ @Override
+ public String toJSON() {
+ return "[" + x + ", " + y + ", " + z + ", " + w + "]";
+ }
+
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+ */
+package javajs.util;
+
+
+/**
+ * A 3-element vector that is represented by single precision floating point
+ * x,y,z coordinates. If this value represents a normal, then it should be
+ * normalized.
+ *
+ * @version specification 1.1, implementation $Revision: 1.10 $, $Date:
+ * 2006/10/03 19:52:30 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
+ * for unique constructor and method names
+ * for the optimization of compiled JavaScript using Java2Script
+ */
+public class V3 extends T3 {
+
+ /**
+ * @j2sIgnoreSuperConstructor
+ */
+ public V3() {
+ // ignore T3
+ }
+ public static V3 newV(T3 t) {
+ return V3.new3(t.x, t.y, t.z);
+ }
+
+ public static V3 newVsub(T3 t1, T3 t2) {
+ return V3.new3(t1.x - t2.x, t1.y - t2.y,t1.z - t2.z);
+ }
+
+ public static V3 new3(float x, float y, float z) {
+ V3 v = new V3();
+ v.x = x;
+ v.y = y;
+ v.z = z;
+ return v;
+ }
+
+ /**
+ * Returns the angle in radians between this vector and the vector parameter;
+ * the return value is constrained to the range [0,PI].
+ *
+ * @param v1
+ * the other vector
+ * @return the angle in radians in the range [0,PI]
+ */
+ public final float angle(V3 v1) {
+ // return (double)Math.acos(dot(v1)/v1.length()/v.length());
+ // Numerically, near 0 and PI are very bad condition for acos.
+ // In 3-space, |atan2(sin,cos)| is much stable.
+
+ double xx = y * v1.z - z * v1.y;
+ double yy = z * v1.x - x * v1.z;
+ double zz = x * v1.y - y * v1.x;
+ double cross = Math.sqrt(xx * xx + yy * yy + zz * zz);
+
+ return (float) Math.abs(Math.atan2(cross, dot(v1)));
+ }
+}
--- /dev/null
+/*
+ Copyright (C) 1997,1998,1999
+ Kenji Hiranabe, Eiwa System Management, Inc.
+
+ This program is free software.
+ Implemented by Kenji Hiranabe(hiranabe@esm.co.jp),
+ conforming to the Java(TM) 3D API specification by Sun Microsystems.
+
+ Permission to use, copy, modify, distribute and sell this software
+ and its documentation for any purpose is hereby granted without fee,
+ provided that the above copyright notice appear in all copies and
+ that both that copyright notice and this permission notice appear
+ in supporting documentation. Kenji Hiranabe and Eiwa System Management,Inc.
+ makes no representations about the suitability of this software for any
+ purpose. It is provided "AS IS" with NO WARRANTY.
+*/
+package javajs.util;
+
+
+
+
+/**
+ * A 3 element vector that is represented by double precision floating point
+ * x,y,z coordinates. If this value represents a normal, then it should be
+ * normalized.
+ *
+ * @version specification 1.1, implementation $Revision: 1.9 $, $Date:
+ * 2006/07/28 17:01:32 $
+ * @author Kenji hiranabe
+ *
+ * additions by Bob Hanson hansonr@stolaf.edu 9/30/2012
+ * for unique constructor and method names
+ * for the optimization of compiled JavaScript using Java2Script
+ */
+public class V3d extends T3d {
+
+ /**
+ * Sets this vector to be the vector cross product of vectors v1 and v2.
+ *
+ * @param v1
+ * the first vector
+ * @param v2
+ * the second vector
+ */
+ public final void cross(V3d v1, V3d v2) {
+ // store on stack once for aliasing-safty
+ // i.e. safe when a.cross(a, b)
+ set(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y
+ - v1.y * v2.x);
+ }
+
+ /**
+ * Normalizes this vector in place.
+ */
+ public final void normalize() {
+ double d = length();
+
+ // zero-div may occur.
+ x /= d;
+ y /= d;
+ z /= d;
+ }
+
+ /**
+ * Computes the dot product of the this vector and vector v.
+ *
+ * @param v
+ * the other vector
+ * @return this.dot.v
+ */
+ public final double dot(V3d v) {
+ return x * v.x + y * v.y + z * v.z;
+ }
+
+ /**
+ * Returns the squared length of this vector.
+ *
+ * @return the squared length of this vector
+ */
+ public final double lengthSquared() {
+ return x * x + y * y + z * z;
+ }
+
+ /**
+ * Returns the length of this vector.
+ *
+ * @return the length of this vector
+ */
+ public final double length() {
+ return Math.sqrt(lengthSquared());
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Copyright (C) 2006 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package javajs.util;
+
+public class XmlUtil {
+
+ public XmlUtil() {
+ // Jmol's PropertyManager class uses reflection
+ }
+ // / simple Xml parser/generator ///
+
+ public static void openDocument(SB data) {
+ data.append("<?xml version=\"1.0\"?>\n");
+ }
+
+ public static void openTag(SB sb, String name) {
+ sb.append("<").append(name).append(">\n");
+ }
+
+ public static void openTagAttr(SB sb, String name, Object[] attributes) {
+ appendTagAll(sb, name, attributes, null, false, false);
+ sb.append("\n");
+ }
+
+ public static void closeTag(SB sb, String name) {
+ sb.append("</").append(name).append(">\n");
+ }
+
+ public static void appendTagAll(SB sb, String name,
+ Object[] attributes, Object data,
+ boolean isCdata, boolean doClose) {
+ String closer = ">";
+ if (name.endsWith("/")){
+ name = name.substring(0, name.length() - 1);
+ if (data == null) {
+ closer = "/>\n";
+ doClose = false;
+ }
+ }
+ sb.append("<").append(name);
+ if (attributes != null)
+ for (int i = 0; i < attributes.length; i++) {
+ Object o = attributes[i];
+ if (o == null)
+ continue;
+ if (o instanceof Object[])
+ for (int j = 0; j < ((Object[]) o).length; j+= 2)
+ appendAttrib(sb, ((Object[]) o)[j], ((Object[]) o)[j + 1]);
+ else
+ appendAttrib(sb, o, attributes[++i]);
+ }
+ sb.append(closer);
+ if (data != null) {
+ if (isCdata)
+ data = wrapCdata(data);
+ sb.appendO(data);
+ }
+ if (doClose)
+ closeTag(sb, name);
+ }
+
+ /**
+ * wrap the string as character data, with replacements for [ noted
+ * as a list starting with * after the CDATA termination
+ *
+ * @param data
+ * @return wrapped text
+ */
+ public static String wrapCdata(Object data) {
+ String s = "" + data;
+ return (s.indexOf("&") < 0 && s.indexOf("<") < 0 ? (s.startsWith("\n") ? "" : "\n") + s
+ : "<![CDATA[" + PT.rep(s, "]]>", "]]]]><![CDATA[>") + "]]>");
+ }
+
+ /**
+ * @param s
+ * @return unwrapped text
+ */
+ public static String unwrapCdata(String s) {
+ return (s.startsWith("<![CDATA[") && s.endsWith("]]>") ?
+ PT.rep(s.substring(9, s.length()-3),"]]]]><![CDATA[>", "]]>") : s);
+ }
+
+ /**
+ * standard <name attr="..." attr="...">data</name>"
+ *
+ * @param sb
+ * @param name
+ * @param attributes
+ * @param data
+ */
+ public static void appendTagObj(SB sb, String name,
+ Object[] attributes, Object data) {
+ appendTagAll(sb, name, attributes, data, false, true);
+ }
+
+ /**
+ * standard <name>data</name>"
+ * standard <name attr="..." attr="..."></name>"
+ *
+ * @param sb
+ * @param name
+ * @param data
+ */
+ public static void appendTag(SB sb, String name, Object data) {
+ if (data instanceof Object[])
+ appendTagAll(sb, name, (Object[]) data, null, false, true);
+ else
+ appendTagAll(sb, name, null, data, false, true);
+ }
+
+ /**
+ * <name><![CDATA[data]]></name>"
+ *
+ * will convert ]]> to ]] >
+ *
+ * @param sb
+ * @param name
+ * @param attributes
+ * @param data
+ */
+ public static void appendCdata(SB sb, String name,
+ Object[] attributes, String data) {
+ appendTagAll(sb, name, attributes, data, true, true);
+ }
+
+ /**
+ *
+ * @param sb
+ * @param name
+ * @param value
+ */
+ public static void appendAttrib(SB sb, Object name, Object value) {
+ if (value == null)
+ return;
+
+ // note: <&" are disallowed but not checked for here
+
+ sb.append(" ").appendO(name).append("=\"").appendO(value).append("\"");
+ }
+
+}
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Copyright (C) 2006 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package javajs.util;
+
+import java.io.BufferedInputStream;
+
+import javajs.api.GenericZipTools;
+
+
+
+
+public class ZipData {
+ boolean isEnabled = true;
+ byte[] buf;
+ int pt;
+ int nBytes;
+
+ public ZipData(int nBytes) {
+ this.nBytes = nBytes;
+ }
+
+ public int addBytes(byte[] byteBuf, int nSectorBytes, int nBytesRemaining) {
+ if (pt == 0) {
+ if (!Rdr.isGzipB(byteBuf)) {
+ isEnabled = false;
+ return -1;
+ }
+ buf = new byte[nBytesRemaining];
+ }
+ int nToAdd = Math.min(nSectorBytes, nBytesRemaining);
+ System.arraycopy(byteBuf, 0, buf, pt, nToAdd);
+ pt += nToAdd;
+ return nBytesRemaining - nToAdd;
+ }
+
+ public void addTo(GenericZipTools jzt, SB data) {
+ data.append(getGzippedBytesAsString(jzt, buf));
+ }
+
+ static String getGzippedBytesAsString(GenericZipTools jzt, byte[] bytes) {
+ try {
+ BufferedInputStream bis = jzt.getUnGzippedInputStream(bytes);
+ String s = ZipTools.getStreamAsString(bis);
+ bis.close();
+ return s;
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+
+}
+
--- /dev/null
+/* $RCSfile$
+ * $Author$
+ * $Date$
+ * $Revision$
+ *
+ * Copyright (C) 2006 The Jmol Development Team
+ *
+ * Contact: jmol-developers@lists.sf.net
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+package javajs.util;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javajs.J2SIgnoreImport;
+import javajs.api.GenericZipInputStream;
+import javajs.api.GenericZipTools;
+import javajs.api.ZInputStream;
+
+import java.util.Map;
+import java.util.zip.CRC32;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+import java.util.zip.ZipOutputStream;
+
+
+/**
+ * Note the JSmol/HTML5 must use its own version of java.util.zip.ZipOutputStream.
+ *
+ */
+@J2SIgnoreImport({ java.util.zip.ZipOutputStream.class })
+public class ZipTools implements GenericZipTools {
+
+ public ZipTools() {
+ // for reflection
+ }
+
+ @Override
+ public ZInputStream newZipInputStream(InputStream is) {
+ return newZIS(is);
+ }
+
+ @SuppressWarnings("resource")
+ private static ZInputStream newZIS(InputStream is) {
+ return (is instanceof ZInputStream ? (ZInputStream) is
+ : is instanceof BufferedInputStream ? new GenericZipInputStream(is)
+ : new GenericZipInputStream(new BufferedInputStream(is)));
+ }
+
+ /**
+ * reads a ZIP file and saves all data in a Hashtable so that the files may be
+ * organized later in a different order. Also adds a #Directory_Listing entry.
+ *
+ * Files are bracketed by BEGIN Directory Entry and END Directory Entry lines,
+ * similar to CompoundDocument.getAllData.
+ *
+ * @param is
+ * @param subfileList
+ * @param name0
+ * prefix for entry listing
+ * @param binaryFileList
+ * |-separated list of files that should be saved as xx xx xx hex byte
+ * strings. The directory listing is appended with ":asBinaryString"
+ * @param fileData
+ */
+ @Override
+ public void getAllZipData(InputStream is, String[] subfileList,
+ String name0, String binaryFileList,
+ Map<String, String> fileData) {
+ ZipInputStream zis = (ZipInputStream) newZIS(is);
+ ZipEntry ze;
+ SB listing = new SB();
+ binaryFileList = "|" + binaryFileList + "|";
+ String prefix = PT.join(subfileList, '/', 1);
+ String prefixd = null;
+ if (prefix != null) {
+ prefixd = prefix.substring(0, prefix.indexOf("/") + 1);
+ if (prefixd.length() == 0)
+ prefixd = null;
+ }
+ try {
+ while ((ze = zis.getNextEntry()) != null) {
+ String name = ze.getName();
+ if (prefix != null && prefixd != null
+ && !(name.equals(prefix) || name.startsWith(prefixd)))
+ continue;
+ //System.out.println("ziputil: " + name);
+ listing.append(name).appendC('\n');
+ String sname = "|" + name.substring(name.lastIndexOf("/") + 1) + "|";
+ boolean asBinaryString = (binaryFileList.indexOf(sname) >= 0);
+ byte[] bytes = Rdr.getLimitedStreamBytes(zis, ze.getSize());
+ String str;
+ if (asBinaryString) {
+ str = getBinaryStringForBytes(bytes);
+ name += ":asBinaryString";
+ } else {
+ str = Rdr.fixUTF(bytes);
+ }
+ str = "BEGIN Directory Entry " + name + "\n" + str
+ + "\nEND Directory Entry " + name + "\n";
+ fileData.put(name0 + "|" + name, str);
+ }
+ } catch (Exception e) {
+ }
+ fileData.put("#Directory_Listing", listing.toString());
+ }
+
+ private String getBinaryStringForBytes(byte[] bytes) {
+ SB ret = new SB();
+ for (int i = 0; i < bytes.length; i++)
+ ret.append(Integer.toHexString(bytes[i] & 0xFF)).appendC(' ');
+ return ret.toString();
+ }
+
+ /**
+ * iteratively drills into zip files of zip files to extract file content or
+ * zip file directory. Also works with JAR files.
+ *
+ * Does not return "__MACOS" paths
+ *
+ * @param bis
+ * @param list
+ * @param listPtr
+ * @param asBufferedInputStream
+ * for Pmesh
+ * @return directory listing or subfile contents
+ */
+ @Override
+ public Object getZipFileDirectory(BufferedInputStream bis, String[] list,
+ int listPtr, boolean asBufferedInputStream) {
+ SB ret;
+ if (list == null || listPtr >= list.length)
+ return getZipDirectoryAsStringAndClose(bis);
+ bis = Rdr.getPngZipStream(bis, true);
+ String fileName = list[listPtr];
+ ZipInputStream zis = new ZipInputStream(bis);
+ ZipEntry ze;
+ //System.out.println("fname=" + fileName);
+ try {
+ boolean isAll = (fileName.equals("."));
+ if (isAll || fileName.lastIndexOf("/") == fileName.length() - 1) {
+ ret = new SB();
+ while ((ze = zis.getNextEntry()) != null) {
+ String name = ze.getName();
+ if (isAll || name.startsWith(fileName))
+ ret.append(name).appendC('\n');
+ }
+ String str = ret.toString();
+ return (asBufferedInputStream ? Rdr.getBIS(str.getBytes()) : str);
+ }
+ int pt = fileName.indexOf(":asBinaryString");
+ boolean asBinaryString = (pt > 0);
+ if (asBinaryString)
+ fileName = fileName.substring(0, pt);
+ fileName = fileName.replace('\\', '/');
+ while ((ze = zis.getNextEntry()) != null
+ && !fileName.equals(ze.getName())) {
+ }
+ byte[] bytes = (ze == null ? null : Rdr.getLimitedStreamBytes(zis,
+ ze.getSize()));
+ ze = null;
+ zis.close();
+ if (bytes == null)
+ return "";
+ if (Rdr.isZipB(bytes) || Rdr.isPngZipB(bytes))
+ return getZipFileDirectory(Rdr.getBIS(bytes), list, ++listPtr,
+ asBufferedInputStream);
+ if (asBufferedInputStream)
+ return Rdr.getBIS(bytes);
+ if (asBinaryString) {
+ ret = new SB();
+ for (int i = 0; i < bytes.length; i++)
+ ret.append(Integer.toHexString(bytes[i] & 0xFF)).appendC(' ');
+ return ret.toString();
+ }
+ if (Rdr.isGzipB(bytes))
+ bytes = Rdr.getLimitedStreamBytes(getUnGzippedInputStream(bytes), -1);
+ return Rdr.fixUTF(bytes);
+ } catch (Exception e) {
+ return "";
+ }
+ }
+
+ @Override
+ public byte[] getZipFileContentsAsBytes(BufferedInputStream bis,
+ String[] list, int listPtr) {
+ byte[] ret = new byte[0];
+ String fileName = list[listPtr];
+ if (fileName.lastIndexOf("/") == fileName.length() - 1)
+ return ret;
+ try {
+ bis = Rdr.getPngZipStream(bis, true);
+ ZipInputStream zis = new ZipInputStream(bis);
+ ZipEntry ze;
+ while ((ze = zis.getNextEntry()) != null) {
+ if (!fileName.equals(ze.getName()))
+ continue;
+ byte[] bytes = Rdr.getLimitedStreamBytes(zis, ze.getSize());
+ return ((Rdr.isZipB(bytes) || Rdr.isPngZipB(bytes)) && ++listPtr < list.length ? getZipFileContentsAsBytes(
+ Rdr.getBIS(bytes), list, listPtr) : bytes);
+ }
+ } catch (Exception e) {
+ }
+ return ret;
+ }
+
+ @Override
+ public String getZipDirectoryAsStringAndClose(BufferedInputStream bis) {
+ SB sb = new SB();
+ String[] s = new String[0];
+ try {
+ s = getZipDirectoryOrErrorAndClose(bis, null);
+ bis.close();
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ for (int i = 0; i < s.length; i++)
+ sb.append(s[i]).appendC('\n');
+ return sb.toString();
+ }
+
+ @Override
+ public String[] getZipDirectoryAndClose(BufferedInputStream bis,
+ String manifestID) {
+ String[] s = new String[0];
+ try {
+ s = getZipDirectoryOrErrorAndClose(bis, manifestID);
+ bis.close();
+ } catch (Exception e) {
+ System.out.println(e.toString());
+ }
+ return s;
+ }
+
+ private String[] getZipDirectoryOrErrorAndClose(BufferedInputStream bis,
+ String manifestID)
+ throws IOException {
+ bis = Rdr.getPngZipStream(bis, true);
+ Lst<String> v = new Lst<String>();
+ ZipInputStream zis = new ZipInputStream(bis);
+ ZipEntry ze;
+ String manifest = null;
+ while ((ze = zis.getNextEntry()) != null) {
+ String fileName = ze.getName();
+ if (manifestID != null && fileName.startsWith(manifestID))
+ manifest = getStreamAsString(zis);
+ else if (!fileName.startsWith("__MACOS")) // resource fork not nec.
+ v.addLast(fileName);
+ }
+ zis.close();
+ if (manifestID != null)
+ v.add(0, manifest == null ? "" : manifest + "\n############\n");
+ return v.toArray(new String[v.size()]);
+ }
+
+ public static String getStreamAsString(InputStream is) throws IOException {
+ return Rdr.fixUTF(Rdr.getLimitedStreamBytes(is, -1));
+ }
+
+ @Override
+ public InputStream newGZIPInputStream(InputStream is) throws IOException {
+ return new BufferedInputStream(new GZIPInputStream(is, 512));
+ }
+
+ @Override
+ public BufferedInputStream getUnGzippedInputStream(byte[] bytes) {
+ try {
+ return Rdr.getUnzippedInputStream(this, Rdr.getBIS(bytes));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ public void addZipEntry(Object zos, String fileName) throws IOException {
+ ((ZipOutputStream) zos).putNextEntry(new ZipEntry(fileName));
+ }
+
+ @Override
+ public void closeZipEntry(Object zos) throws IOException {
+ ((ZipOutputStream) zos).closeEntry();
+ }
+
+ @Override
+ public Object getZipOutputStream(Object bos) {
+ /**
+ * @j2sNative
+ *
+ * return javajs.api.Interface.getInterface(
+ * "java.util.zip.ZipOutputStream").setZOS(bos);
+ *
+ */
+ {
+ return new ZipOutputStream((OutputStream) bos);
+ }
+ }
+
+ @Override
+ public int getCrcValue(byte[] bytes) {
+ CRC32 crc = new CRC32();
+ crc.update(bytes, 0, bytes.length);
+ return (int) crc.getValue();
+ }
+
+ @Override
+ public void readFileAsMap(BufferedInputStream bis, Map<String, Object> bdata, String name) {
+ int pt = (name == null ? -1 : name.indexOf("|"));
+ name = (pt >= 0 ? name.substring(pt + 1) : null);
+ try {
+ if (Rdr.isPngZipStream(bis)) {
+ boolean isImage = "_IMAGE_".equals(name);
+ if (name == null || isImage)
+ bdata.put((isImage ? "_DATA_" : "_IMAGE_"), new BArray(getPngImageBytes(bis)));
+ if (!isImage)
+ cacheZipContents(bis, name, bdata, true);
+ } else if (Rdr.isZipS(bis)) {
+ cacheZipContents(bis, name, bdata, true);
+ } else if (name == null){
+ bdata.put("_DATA_", new BArray(Rdr.getLimitedStreamBytes(bis, -1)));
+ } else {
+ throw new IOException("ZIP file " + name + " not found");
+ }
+ bdata.put("$_BINARY_$", Boolean.TRUE);
+ } catch (IOException e) {
+ bdata.clear();
+ bdata.put("_ERROR_", e.getMessage());
+ }
+ }
+
+ @Override
+ public String cacheZipContents(BufferedInputStream bis,
+ String fileName,
+ Map<String, Object> cache,
+ boolean asByteArray) {
+ ZipInputStream zis = (ZipInputStream) newZIS(bis);
+ ZipEntry ze;
+ SB listing = new SB();
+ long n = 0;
+ boolean oneFile = (asByteArray && fileName != null);
+ int pt = (oneFile ? fileName.indexOf("|") : -1);
+ String file0 = (pt >= 0 ? fileName : null);
+ if (pt >= 0)
+ fileName = fileName.substring(0, pt);
+ try {
+ while ((ze = zis.getNextEntry()) != null) {
+ String name = ze.getName();
+ if (fileName != null) {
+ if (oneFile) {
+ if (!name.equalsIgnoreCase(fileName))
+ continue;
+ } else {
+ listing.append(name).appendC('\n');
+ }
+ }
+ long nBytes = ze.getSize();
+ byte[] bytes = Rdr.getLimitedStreamBytes(zis, nBytes);
+ if (file0 != null) {
+ readFileAsMap(Rdr.getBIS(bytes), cache, file0);
+ return null;
+ }
+ n += bytes.length;
+ Object o = (asByteArray ? new BArray(bytes) : bytes);
+ cache.put((oneFile ? "_DATA_" : (fileName == null ? "" : fileName + "|") + name), o);
+ if (oneFile)
+ break;
+ }
+ zis.close();
+ } catch (Exception e) {
+ try {
+ zis.close();
+ } catch (IOException e1) {
+ }
+ return null;
+ }
+ if (n == 0 || fileName == null)
+ return null;
+ System.out.println("ZipTools cached " + n + " bytes from " + fileName);
+ return listing.toString();
+ }
+
+ private static byte[] getPngImageBytes(BufferedInputStream bis) {
+ try {
+ if (Rdr.isPngZipStream(bis)) {
+ int pt_count[] = new int[2];
+ Rdr.getPngZipPointAndCount(bis, pt_count);
+ if (pt_count[1] != 0)
+ return deActivatePngZipB(Rdr.getLimitedStreamBytes(bis, pt_count[0]));
+ }
+ return Rdr.getLimitedStreamBytes(bis, -1);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ /**
+ * Once a PNGJ image has been extracted, we want to red-line its
+ * iTXt "Jmol Type PNGJ" tag, since it is no longer associated with
+ * ZIP data.
+ *
+ * @param bytes
+ * @return disfigured bytes
+ *
+ */
+ private static byte[] deActivatePngZipB(byte[] bytes) {
+ // \0PNGJ starting at byte 50 changed to \0 NGJ
+ if (Rdr.isPngZipB(bytes))
+ bytes[51] = 32;
+ return bytes;
+ }
+
+
+
+}
--- /dev/null
+package netscape.javascript;
+
+public class JSException extends Exception {
+
+}
--- /dev/null
+package netscape.javascript;
+
+import jalview.bin.JalviewLite;
+
+public class JSObject {
+
+ public static JSObject getWindow(JalviewLite jvlite) {
+ /**
+ * @j2sNative
+ *
+ * return window;
+ *
+ */
+ {
+ return null;
+ }
+ }
+
+ public void call(String _listener, Object[] objects) {
+ /**
+ * @j2sNative
+ *
+ * alert("call " + _listener);
+ */
+ {}
+ }
+
+ public Object eval(String string) {
+ /**
+ * @j2sNative
+ *
+ * alert("evval " + string);
+ */
+ {
+
+
+ }
+ return eval(string);
+ }
+
+}
--- /dev/null
+package org.exolab.castor.mapping;
+
+import java.net.URL;
+
+public class Mapping {
+
+ public Mapping(ClassLoader classLoader) {
+ // TODO Auto-generated constructor stub
+ }
+
+ public void loadMapping(URL url) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
--- /dev/null
+package org.exolab.castor.xml;
+
+import java.io.PrintWriter;
+import java.io.Reader;
+
+import org.exolab.castor.mapping.Mapping;
+
+public class Unmarshaller {
+
+ public Unmarshaller(Object record) {
+ // TODO Auto-generated constructor stub
+ }
+
+ public void setIgnoreExtraElements(boolean b) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setIgnoreExtraAttributes(boolean b) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setMapping(Mapping map) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public void setLogWriter(PrintWriter printWriter) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public Object unmarshal(Reader file) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ public void setDebug(boolean debugEnabled) {
+ // TODO Auto-generated method stub
+
+ }
+
+}
--- /dev/null
+package org.jmol.viewer;
+
+public class Viewer {
+
+}
--- /dev/null
+package swingjs;
+
+import java.awt.event.InvocationEvent;
+
+/**
+ * a custom implementation of java.awt.event.InvocationEvent for JSThread
+ *
+ * @author Bob Hanson
+ *
+ */
+public class JSEvent extends InvocationEvent {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -8061376242084344200L;
+
+ JSEvent(JSThread t, Runnable r) {
+ super(t, r);
+ }
+
+}
--- /dev/null
+package swingjs;
+
+import java.awt.Toolkit;
+import java.awt.event.InvocationEvent;
+import swingjs.api.JSFunction;
+
+/**
+ * A class that takes care of simple threading. There are three states: INIT, LOOP, and DONE.
+ * These states are passed into run1
+ *
+ *
+ * @author Bob Hanson
+ *
+ */
+public abstract class JSThread extends Thread implements JSFunction {
+
+ public static final int INIT = 0;
+ public static final int LOOP = 1;
+ public static final int DONE = 2;
+
+ protected boolean isJS;
+ protected boolean doDispatch = true;
+ protected int msDelay;
+
+ public JSThread(ThreadGroup group, String name) {
+ super(group, name);
+ /**
+ * @j2sNative
+ *
+ * this.isJS = true;
+ */
+ {}
+ }
+
+ public void run() {
+ run1(INIT);
+ }
+
+ @Override
+ public synchronized void start() {
+
+ /**
+ * @j2sNative
+ *
+ * JSToolkit.setTimeout(this, 1, 0);
+ *
+ */
+ {
+ super.start();
+ }
+
+ }
+
+ /**
+ * set the delay time between run1 calls
+ *
+ * @param ms
+ */
+ public void setDelayMillis(int ms) {
+ msDelay = ms;
+ }
+
+ /**
+ * a generic method that loops until done, or in JavaScript, will reenter and
+ * continue at the appropriate spot. Example given here
+ *
+ * @param state
+ */
+ protected abstract void run1(int state);
+
+
+ // protected void run1(int state) {
+ // try {
+ // while (true)
+ // switch (state) {
+ // case INIT:
+ // // once-through stuff here
+ // state = LOOP;
+ // break;
+ // case LOOP:
+ // if (!doDispatch || isInterrupted()) {
+ // state = DONE;
+ // } else {
+ // // put the loop code here
+ // };
+ // dispatchAndReturn(state);
+ // if (isJS)
+ // return;
+ // }
+ // break;
+ // // add more cases as needed
+ // case DONE:
+ // // finish up here
+ // if (isInterrupted())
+ // return;
+ // // or here
+ // break;
+ // }
+ // } finally {
+ // // stuff here to be executed after each loop in JS or at the end in Java
+ // }
+ // }
+
+ /**
+ *
+ * @param r
+ * @param state
+ * @throws InterruptedException
+ */
+ protected void dispatchAndReturn(final int state)
+ throws InterruptedException {
+ final int delay = msDelay;
+ if (isJS) {
+ // in JavaScript, we need to do this through the system event queue,
+ // which in JSToolkit takes care of all the "thread" handling.
+
+ final JSThread me = this;
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ me.run1(state);
+ }
+ };
+ /**
+ * @j2sNative
+ *
+ * setTimeout(function() {
+ * java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue
+ * ().postEvent(new java.awt.event.InvocationEvent(me, r)),
+ * delay; }
+ *
+ */
+ {
+ // for reference only
+ Toolkit.getDefaultToolkit().getSystemEventQueue()
+ .postEvent(new InvocationEvent(me, r));
+ }
+ } else {
+ sleep(delay);
+ }
+ }
+
+}
--- /dev/null
+package swingjs.api;
+
+public interface JSFunction {
+
+}