diff --git a/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip b/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip index 871b9d25d..e738f20ae 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip and b/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/j2s.core.jar b/sources/net.sf.j2s.core/dist/swingjs/j2s.core.jar index e6f92de1b..805c52281 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/j2s.core.jar and b/sources/net.sf.j2s.core/dist/swingjs/j2s.core.jar differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/net.sf.j2s.core.jar b/sources/net.sf.j2s.core/dist/swingjs/net.sf.j2s.core.jar deleted file mode 100644 index dd10a4959..000000000 Binary files a/sources/net.sf.j2s.core/dist/swingjs/net.sf.j2s.core.jar and /dev/null differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/timestamp b/sources/net.sf.j2s.core/dist/swingjs/timestamp index b6ad9d051..d6484515e 100644 --- a/sources/net.sf.j2s.core/dist/swingjs/timestamp +++ b/sources/net.sf.j2s.core/dist/swingjs/timestamp @@ -1 +1 @@ -20240225103130 +20241217101652 diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/SwingJS-site.zip b/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/SwingJS-site.zip index 871b9d25d..e738f20ae 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/SwingJS-site.zip and b/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/j2s.core.jar b/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/j2s.core.jar index e6f92de1b..805c52281 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/j2s.core.jar and b/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/j2s.core.jar differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/timestamp b/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/timestamp index b6ad9d051..d6484515e 100644 --- a/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/timestamp +++ b/sources/net.sf.j2s.core/dist/swingjs/ver/5.0.1/timestamp @@ -1 +1 @@ -20240225103130 +20241217101652 diff --git a/sources/net.sf.j2s.core/src/j2s/CorePlugin.java b/sources/net.sf.j2s.core/src/j2s/CorePlugin.java index f48d40af6..c78c1cd61 100644 --- a/sources/net.sf.j2s.core/src/j2s/CorePlugin.java +++ b/sources/net.sf.j2s.core/src/j2s/CorePlugin.java @@ -26,11 +26,13 @@ public class CorePlugin extends Plugin { * the actual "x.y.z" version is specified in plugin.xml. * */ - public static String VERSION = "5.0.1-v2"; + public static String VERSION = "5.0.1-v4"; // if you change the x.x.x number, be sure to also indicate that in // j2sApplet.js and also (Bob only) update.bat, update-clean.bat + // BH 2024.07.14 -- 5.0.1-v4 fixes numerical array initializer using characters ['a','b',...] + // BH 2024.02.22 -- 5.0.1-v3 fixes long extension issue causing MutableBitInteger to miscalculate subtraction(no change in version #) // BH 2023.11.27 -- 5.0.1-v2 final refactoring and creatiton of J2SUtil // BH 2023.11.21 -- 5.0.1-v2 adds Java8 syntaxes for try and switch; removes dependency for instanceOf and exception checking // BH 2023.11.09 -- 5.0.1-v1 merges Jmol legacy (.j2sjmol) with Java8//11 (.j2s) diff --git a/sources/net.sf.j2s.core/src/j2s/jmol/J2SLegacyVisitor.java b/sources/net.sf.j2s.core/src/j2s/jmol/J2SLegacyVisitor.java index 36bc7c520..5cb8ee90b 100644 --- a/sources/net.sf.j2s.core/src/j2s/jmol/J2SLegacyVisitor.java +++ b/sources/net.sf.j2s.core/src/j2s/jmol/J2SLegacyVisitor.java @@ -2100,7 +2100,7 @@ public boolean visit(ArrayCreation node) { buffer.append(" Clazz.newBooleanArray("); boxList(dim, ", "); buffer.append(", false)"); - } else { + } else { if (dim != null && dim.size() > 1) { buffer.append(" Clazz.newArray("); boxList(dim, ", "); @@ -2140,6 +2140,8 @@ public boolean visit(ArrayInitializer node) { buffer.append("]"); return false; } + // note that this does NOT allow for new byte[] {'a', 'b', 'c'} + // only implemented that for SwingJS if (elementType.isPrimitive()) { String typeCode = elementType.getName(); if ("int".equals(typeCode) diff --git a/sources/net.sf.j2s.core/src/j2s/swingjs/Java2ScriptVisitor.java b/sources/net.sf.j2s.core/src/j2s/swingjs/Java2ScriptVisitor.java index 0874ed417..4f9119115 100644 --- a/sources/net.sf.j2s.core/src/j2s/swingjs/Java2ScriptVisitor.java +++ b/sources/net.sf.j2s.core/src/j2s/swingjs/Java2ScriptVisitor.java @@ -31,7 +31,11 @@ // TODO: superclass inheritance for JAXB XmlAccessorType // TODO: Transpiler bug allows static String name, but JavaScript function().name is read-only and will be "clazz" -//BH 2024.02.22 -- 3.3.1-v7 fixes long extension issue causing MutableBitInteger to miscalculate subtraction(no change in version #) +//BH 2024.07.14 -- 5.0.1-v4 fixes numerical array initializer using characters ['a','b',...], but not new int[] { "test".charAt(3) } +//BH 2024.02.22 -- 5.0.1-v3 fixes long extension issue causing MutableBitInteger to miscalculate subtraction(no change in version #) +//BH 2023.11.27 -- 5.0.1-v2 final refactoring and creatiton of J2SUtil +//BH 2023.11.21 -- 5.0.1-v2 adds Java8 syntaxes for try and switch; removes dependency for instanceOf and exception checking +//BH 2023.11.09 -- 5.0.1-v1 merges Jmol legacy (.j2sjmol) with Java8//11 (.j2s) //BH 2023.03.29 -- 3.3.1-v7 fixes outer static method call from within lambda expression. //BH 2023.02.09 -- 3.3.1.v6 fixes j2s.excluded.paths needing /src/xxxx //BH 2022.06.27 -- 3.3.1-v5 fixes missing method annotations @@ -3015,15 +3019,63 @@ private void addArrayConstructor(ITypeBinding binding, List dim) { public boolean visit(ArrayInitializer node) { // as in: public String[] d = {"1", "2"}; - buffer.append(clazzArray(node.resolveTypeBinding(), ARRAY_INITIALIZED)); + ITypeBinding type = node.resolveTypeBinding(); + buffer.append(clazzArray(type, ARRAY_INITIALIZED)); buffer.append(", ["); + int toChar = toCharType(type); @SuppressWarnings("unchecked") - List expressions = node.expressions(); - visitList(expressions, ", "); + List ex = node.expressions(); + if (toChar == 0) { + visitList(ex, ", "); + } else { + fixCharArrayInit(buffer, ex, toChar); + } buffer.append("])"); return false; } + private static int toCharType(ITypeBinding type) { + switch (type == null ? "" : type.getName()) { + case "char[]": + return 1; + case "byte[]": + case "short[]": + case "int[]": + case "long[]": + case "float[]": + case "double[]": + return -1; + default: + return 0; + } + } + + private void fixCharArrayInit(StringBuffer buffer, List list, int toChar) { + for (Iterator iter = list.iterator(); iter.hasNext();) { + int pt = buffer.length(); + appendBoxingNode(iter.next(), false, null, false, false); + if (toChar != 0) { + String s = buffer.substring(pt); + // only fix "x" and number + // not fixed: int[] a = new int[] {"test".charAt(0)} + try { + if (pt > 0 && (s.charAt(0) == '"') != (toChar == 1)) { + buffer.replace(pt, buffer.length(), + (toChar == 1 ? + "\"" + ((char) Integer.parseInt(s)) + "\"" + : s.length() == 3 ? "" + (byte) s.charAt(1) : s) + ); + } + } catch (@SuppressWarnings("unused") Exception e) { + // ignore + } + } + if (!iter.hasNext()) + return; + buffer.append(", "); + } + } + public boolean visit(Assignment node) { // note that this is not // var x = ..... -- that is a visit(VariableDeclaration) @@ -4431,8 +4483,6 @@ private void addNonCharacter(Expression exp) { switch (name) { case "char": case "Character": - addOperand(exp, false); - break; case "Byte": case "Short": case "Integer": diff --git a/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip b/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip index 871b9d25d..573368c76 100644 Binary files a/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip and b/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.java.core/dist/j2s.core.jar b/sources/net.sf.j2s.java.core/dist/j2s.core.jar deleted file mode 100644 index e6f92de1b..000000000 Binary files a/sources/net.sf.j2s.java.core/dist/j2s.core.jar and /dev/null differ diff --git a/sources/net.sf.j2s.java.core/dist_to_jsmol/Jmol-j2s-site.zip b/sources/net.sf.j2s.java.core/dist_to_jsmol/Jmol-j2s-site.zip index 1b3a6c9ce..d73aafd28 100644 Binary files a/sources/net.sf.j2s.java.core/dist_to_jsmol/Jmol-j2s-site.zip and b/sources/net.sf.j2s.java.core/dist_to_jsmol/Jmol-j2s-site.zip differ diff --git a/sources/net.sf.j2s.java.core/site-resources_4.2/jsmol/js/JSmolJavaExt.js b/sources/net.sf.j2s.java.core/site-resources_4.2/jsmol/js/JSmolJavaExt.js index 047b276a3..0a990521b 100644 --- a/sources/net.sf.j2s.java.core/site-resources_4.2/jsmol/js/JSmolJavaExt.js +++ b/sources/net.sf.j2s.java.core/site-resources_4.2/jsmol/js/JSmolJavaExt.js @@ -1002,6 +1002,8 @@ return buf.join(''); if(String.prototype.$replace==null){ java.lang.String=String; +Clazz._setDeclared("String", String); + if(Clazz._supportsNativeObject){ for(var i=0;i= 0); -} catch (e) { +} catch(e) { } var __debuggingBH = false; var _globals = ["j2s.clazzloaded", "j2s.object.native"]; @@ -83,15 +84,15 @@ Clazz._startProfiling = function(doProfile) { _profile = (doProfile && self.JSON ? {} : null); } -NullObject = function () {}; +NullObject = function(){}; /* protected */ Clazz._supportsNativeObject = window["j2s.object.native"]; if (Clazz._supportsNativeObject) { - Clazz._O = function () {}; + Clazz._O = function(){}; Clazz._O.__CLASS_NAME__ = "Object"; - Clazz._O["getClass"] = function () { return Clazz._O; }; + Clazz._O["getClass"] = function(){ return Clazz._O; }; } else { Clazz._O = Object; } @@ -105,30 +106,30 @@ var addProto = function(proto, name, func) { }; ;(function(proto) { - addProto(proto, "equals", function (obj) { + addProto(proto, "equals", function(obj) { return this == obj; }); - addProto(proto, "hashCode", function () { + addProto(proto, "hashCode", function(){ return this._$hashcode || (this._$hashcode = ++Clazz._hashCode) /* try { - return this.toString ().hashCode (); + return this.toString().hashCode(); } catch (e) { var str = ":"; for (var s in this) { str += s + ":" } - return str.hashCode (); + return str.hashCode(); } */ }); - addProto(proto, "getClass", function () { return Clazz.getClass (this); }); + addProto(proto, "getClass", function(){ return Clazz.getClass (this); }); - addProto(proto, "clone", function () { return Clazz.clone(this); }); + addProto(proto, "clone", function(){ return Clazz.clone(this); }); Clazz.clone = function(me) { // BH allows @j2sNative access without super constructor @@ -142,19 +143,21 @@ var addProto = function(proto, name, func) { /* * Methods for thread in Object */ - addProto(proto, "finalize", function () {}); - addProto(proto, "notify", function () {}); - addProto(proto, "notifyAll", function () {}); - addProto(proto, "wait", function () {}); + addProto(proto, "finalize", function(){}); + addProto(proto, "notify", function(){}); + addProto(proto, "notifyAll", function(){}); + addProto(proto, "wait", function(){}); addProto(proto, "to$tring", Object.prototype.toString); - addProto(proto, "toString", function () { return (this.__CLASS_NAME__ ? "[" + this.__CLASS_NAME__ + " object]" : this.to$tring.apply(this, arguments)); }); + addProto(proto, "toString", function(){ return (this.__CLASS_NAME__ ? "[" + this.__CLASS_NAME__ + " object]" : this.to$tring.apply(this, arguments)); }); Clazz._extendedObjectMethods = [ "equals", "hashCode", "getClass", "clone", "finalize", "notify", "notifyAll", "wait", "to$tring", "toString" ]; })(Clazz._O.prototype); Clazz.extendJO = function(c, name) { - if (name) + if (name) { c.__CLASS_NAME__ = c.prototype.__CLASS_NAME__ = name; + Clazz._setDeclared(name, c); + } if (Clazz._supportsNativeObject) { for (var i = 0; i < Clazz._extendedObjectMethods.length; i++) { var p = Clazz._extendedObjectMethods[i]; @@ -182,7 +185,7 @@ Clazz.extractClassName = function(clazzStr) { * @return class name */ /* public */ -Clazz.getClassName = function (obj) { +Clazz.getClassName = function(obj) { if (obj == null) return "NullObject"; if (obj instanceof Clazz.CastedNull) @@ -241,7 +244,7 @@ Clazz.getClassName = function (obj) { * @return class name */ /* public */ -Clazz.getClass = function (clazzHost) { +Clazz.getClass = function(clazzHost) { if (!clazzHost) return Clazz._O; // null/undefined is always treated as Object if (typeof clazzHost == "function") @@ -267,7 +270,7 @@ Clazz.getClass = function (clazzHost) { /* private */ -var checkInnerFunction = function (hostSuper, funName) { +var checkInnerFunction = function(hostSuper, funName) { for (var k = 0; k < Clazz.innerFunctionNames.length; k++) if (funName == Clazz.innerFunctionNames[k] && Clazz._innerFunctions[funName] === hostSuper[funName]) @@ -275,9 +278,9 @@ var checkInnerFunction = function (hostSuper, funName) { return false; }; -var args4InheritClass = function () {}; +var args4InheritClass = function(){}; -Clazz.inheritArgs = new args4InheritClass (); +Clazz.inheritArgs = new args4InheritClass(); /** * Inherit class with "extends" keyword and also copy those static members. @@ -289,12 +292,12 @@ Clazz.inheritArgs = new args4InheritClass (); * @param objSuper super class instance */ /* protected */ -Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) { +Clazz.inheritClass = function(clazzThis, clazzSuper, objSuper) { //var thisClassName = Clazz.getClassName (clazzThis); for (var o in clazzSuper) { if (o != "b$" && o != "prototype" && o != "superClazz" && o != "__CLASS_NAME__" && o != "implementz" - && !checkInnerFunction (clazzSuper, o)) { + && !checkInnerFunction(clazzSuper, o)) { clazzThis[o] = clazzSuper[o]; } } @@ -310,7 +313,7 @@ Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) { } else if (clazzSuper !== Number) { clazzThis.prototype = new clazzSuper (Clazz.inheritArgs); } else { // Number - clazzThis.prototype = new Number (); + clazzThis.prototype = new Number(); } clazzThis.superClazz = clazzSuper; /* @@ -331,7 +334,7 @@ Clazz.inheritClass = function (clazzThis, clazzSuper, objSuper) { * @param interfacez Array of interfaces */ /* public */ -Clazz.implementOf = function (clazzThis, interfacez) { +Clazz.implementOf = function(clazzThis, interfacez) { if (arguments.length >= 2) { if (!clazzThis.implementz) clazzThis.implementz = []; @@ -375,7 +378,7 @@ var copyProperties = function(clazzThis, clazzSuper) { Clazz.extendInterface = Clazz.implementOf; /* protected */ -Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) { +Clazz.equalsOrExtendsLevel = function(clazzThis, clazzAncestor) { if (clazzThis === clazzAncestor) return 0; if (clazzThis.implementz) { @@ -390,7 +393,7 @@ Clazz.equalsOrExtendsLevel = function (clazzThis, clazzAncestor) { }; /* protected */ -Clazz.getInheritedLevel = function (clazzTarget, clazzBase) { +Clazz.getInheritedLevel = function(clazzTarget, clazzBase) { if (clazzTarget === clazzBase) return 0; var isTgtStr = (typeof clazzTarget == "string"); @@ -449,36 +452,34 @@ Clazz.getInheritedLevel = function (clazzTarget, clazzBase) { Clazz.allClasses = {}; Clazz.isClassDefined = Clazz.isDefinedClass = function(clazzName) { - if (!clazzName) - return false; /* consider null or empty name as non-defined class */ - var pkg = Clazz._getDeclared(clazzName); - if (!pkg) { - var pkgFrags = clazzName.split (/\./); - pkg = null; - for (var i = 0; i < pkgFrags.length; i++) { - if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) { - return false; - } - } - Clazz._setDeclared(clazzName, pkg); - } - return pkg; + return (clazzName && Clazz._getDeclared(clazzName)); +// this next was only for String and Date, which are now registered properly +// if (!clazzName) +// return false; /* consider null or empty name as non-defined class */ +// var pkg = Clazz._getDeclared(clazzName); +// if (!pkg) { +// var pkgFrags = clazzName.split (/\./); +// pkg = null; +// for (var i = 0; i < pkgFrags.length; i++) { +// if (!(pkg = (pkg ? pkg[pkgFrags[i]] : Clazz.allPackage[pkgFrags[0]]))) { +// return false; +// } +// } +// Clazz._setDeclared(clazzName, pkg); +// } +// return pkg; }; Clazz._setDeclared = function(name, func) { - Clazz.allClasses[name] = func; - if (name.indexOf(".") < 0) - Clazz.allClasses["java.lang." + name] = func; + (name.indexOf(".") < 0) && (name = "java.lang." + name); + Clazz.allClasses[name] = func; } Clazz._getDeclared = function(name) { - var f = Clazz.allClasses[name]; - if (!f && name.indexOf(".") < 0) - f = Clazz.allClasses["java.lang." + name]; - return f + (name.indexOf(".") < 0) && (name = "java.lang." + name); + return Clazz.allClasses[name] } - /** * Implements Java's keyword "instanceof" in JavaScript's way. * As in JavaScript part of the object inheritance is implemented in only- @@ -489,11 +490,11 @@ Clazz._getDeclared = function(name) { * @return whether the object is an instance of the class */ /* public */ -Clazz.instanceOf = function (obj, clazz) { +Clazz.instanceOf = function(obj, clazz) { if (obj == null) return false; if (typeof clazz == "string") { - clazz = Clazz.isClassDefined(clazz); + clazz = Clazz._getDeclared(clazz); } if (!clazz) return false; @@ -504,10 +505,51 @@ Clazz.instanceOf = function (obj, clazz) { return (obj != null && clazz && (obj == clazz || obj instanceof clazz || Clazz.getInheritedLevel(Clazz.getClassName(obj), clazz) >= 0)); }; +/**sgurin + * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**. + * + * calls Clazz.instanceOf if e is a Java exception. If not, try to detect known native + * exceptions, like native NullPointerExceptions and wrap it into a Java exception and + * call Clazz.instanceOf again. if the native exception can't be wrapped, false is returned. + * + * @param obj the object to be tested + * @param clazz the class to be checked + * @return whether the object is an instance of the class + * @author: sgurin + */ +Clazz.exceptionOf = function(e, clazz) { + if(e.__CLASS_NAME__) { + if (typeof clazz == "string") { + var c = Clazz._getDeclared(clazz); + if (!c) return false; + clazz = c; + } + return Clazz.instanceOf(e, clazz); + } + if (!e.getMessage) { + // Firefox at least now has a nice stack report + e.getMessage = function() {return "" + e + (e.stack ? "\n" + e.stack : "")}; + } + if (!e.printStackTrace) { + e.printStackTrace = function(){System.err.println("" + e)}; + } + if(clazz == Error) { + if (("" + e).indexOf("Error") < 0) + return false; + System.out.println (Clazz.getStackTrace()); + return true; + } + // everything here is a Java Exception, not a Java Error + return (clazz == Exception || clazz == Throwable + || clazz == NullPointerException && _isNPEExceptionPredicate(e)); +}; + + + /** * Call super method of the class. * The same effect as Java's expression: - * super.* () + * super.*() * * @param objThis host object * @param clazzThis class of declaring method scope. It's hard to determine @@ -527,7 +569,7 @@ Clazz.instanceOf = function (obj, clazz) { * @param funParams Array of method parameters */ /* public */ -Clazz.superCall = function (objThis, clazzThis, funName, funParams) { +Clazz.superCall = function(objThis, clazzThis, funName, funParams) { var fx = null; var i = -1; var clazzFun = objThis[funName]; @@ -610,10 +652,10 @@ Clazz.superCall = function (objThis, clazzThis, funName, funParams) { /** * Call super constructor of the class. * The same effect as Java's expression: - * super () + * super() */ /* public */ -Clazz.superConstructor = function (objThis, clazzThis, funParams) { +Clazz.superConstructor = function(objThis, clazzThis, funParams) { Clazz.superCall (objThis, clazzThis, "construct", funParams); /* If there are members which are initialized out of the constructor */ if (clazzThis.con$truct) { @@ -628,7 +670,7 @@ Clazz.superConstructor = function (objThis, clazzThis, funParams) { * this.call ((String) null); */ /* public */ -Clazz.CastedNull = function (asClazz) { +Clazz.CastedNull = function(asClazz) { if (asClazz) { if (asClazz instanceof String) { this.clazzName = asClazz; @@ -640,10 +682,10 @@ Clazz.CastedNull = function (asClazz) { } else { this.clazzName = "Object"; } - this.toString = function () { + this.toString = function(){ return null; }; - this.valueOf = function () { + this.valueOf = function(){ return null; }; }; @@ -656,7 +698,7 @@ Clazz.CastedNull = function (asClazz) { * @return an instance of class Clazz.CastedNull */ /* public */ -Clazz.castNullAs = function (asClazz) { +Clazz.castNullAs = function(asClazz) { return new Clazz.CastedNull (asClazz); }; @@ -687,14 +729,14 @@ Clazz._callingStackTraces = []; * not found in the current clazz hierarchy. */ /* private */ -var MethodException = function () { - this.toString = function () { +var MethodException = function(){ + this.toString = function(){ return "J2S MethodException"; }; }; /* private */ -//var MethodNotFoundException = function () { -// this.toString = function () { +//var MethodNotFoundException = function(){ +// this.toString = function(){ // return "J2S MethodNotFoundException"; // }; //}; @@ -738,39 +780,6 @@ var MethodException = function () { }; })(); -/**sgurin - * Implements Java's keyword "instanceof" in JavaScript's way **for exception objects**. - * - * calls Clazz.instanceOf if e is a Java exception. If not, try to detect known native - * exceptions, like native NullPointerExceptions and wrap it into a Java exception and - * call Clazz.instanceOf again. if the native exception can't be wrapped, false is returned. - * - * @param obj the object to be tested - * @param clazz the class to be checked - * @return whether the object is an instance of the class - * @author: sgurin - */ -Clazz.exceptionOf = function(e, clazz) { - if(e.__CLASS_NAME__) - return Clazz.instanceOf(e, clazz); - if (!e.getMessage) { - // Firefox at least now has a nice stack report - e.getMessage = function() {return "" + e + (e.stack ? "\n" + e.stack : "")}; - } - if (!e.printStackTrace) { - e.printStackTrace = function(){System.err.println("" + e)}; - } - if(clazz == Error) { - if (("" + e).indexOf("Error") < 0) - return false; - System.out.println (Clazz.getStackTrace()); - return true; - } - // everything here is a Java Exception, not a Java Error - return (clazz == Exception || clazz == Throwable - || clazz == NullPointerException && _isNPEExceptionPredicate(e)); -}; - /** * BH need to limit this, as JavaScript call stack may be recursive */ @@ -817,7 +826,7 @@ Clazz.getStackTrace = function(n) { * @param funParams constructor parameters signature */ /* public */ -Clazz.makeConstructor = function (clazzThis, funBody, funParams) { +Clazz.makeConstructor = function(clazzThis, funBody, funParams) { Clazz.defineMethod (clazzThis, "construct", funBody, funParams); if (clazzThis.con$truct) { clazzThis.con$truct.index = clazzThis.con$truct.stacks.length; @@ -834,7 +843,7 @@ Clazz.makeConstructor = function (clazzThis, funBody, funParams) { * @param funParams constructor parameters signature */ /* public */ -Clazz.overrideConstructor = function (clazzThis, funBody, funParams) { +Clazz.overrideConstructor = function(clazzThis, funBody, funParams) { Clazz.overrideMethod (clazzThis, "construct", funBody, funParams); if (clazzThis.con$truct) { clazzThis.con$truct.index = clazzThis.con$truct.stacks.length; @@ -849,13 +858,13 @@ Clazz.overrideConstructor = function (clazzThis, funBody, funParams) { * * @param clazzThis host class in which the method to be defined * @param funName method name - * @param funBody function object, e.g function () { ... } + * @param funBody function object, e.g function(){ ... } * @param funParams paramether signature, e.g ["string", "number"] * @return method of the given name. The method may be funBody or a wrapper * of the given funBody. */ /* public */ -Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) { +Clazz.defineMethod = function(clazzThis, funName, funBody, funParams) { //if (Clazz.assureInnerClass) //Clazz.assureInnerClass(clazzThis, funBody); funBody.exName = funName; @@ -875,7 +884,7 @@ Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) { var oldFun = null; var oldStacks = f$.stacks; if (!oldStacks) { - /* method is not defined by Clazz.defineMethod () */ + /* method is not defined by Clazz.defineMethod() */ oldStacks = []; oldFun = f$; if (f$.claxxOwner) { @@ -895,7 +904,7 @@ Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) { //Generate a new delegating method for the class var id = ++SAEMid; //console.log("SAEM " + clazzThis.__CLASS_NAME__ + "." + funName); - var delegate = function () { + var delegate = function(){ return searchAndExecuteMethod(id, this, arguments.callee.claxxReference, arguments.callee.methodName, arguments); }; delegate.methodName = funName; @@ -918,7 +927,7 @@ Clazz.defineMethod = function (clazzThis, funName, funBody, funParams) { oldFun.funParams = null; // null ? safe ? // safe for != null } else if (!oldFun.claxxOwner) { /* - * The function is not defined Clazz.defineMethod (). + * The function is not defined Clazz.defineMethod(). * Try to fixup the method ... * As a matter of lost method information, I just suppose * the method to be fixed is with void parameter! @@ -989,9 +998,9 @@ var removeArrayItem = function(arr, item) { * to deal complicated situation. */ /* protected */ -var formatParameters = function (funParams) { +var formatParameters = function(funParams) { return (funParams ? funParams.replace (/~([NABSO])/g, - function ($0, $1) { + function($0, $1) { switch ($1) { case 'N': return "n"; @@ -1018,7 +1027,7 @@ var formatParameters = function (funParams) { * * @param clazzThis host class in which the method to be defined * @param funName method name - * @param funBody function object, e.g function () { ... } + * @param funBody function object, e.g function(){ ... } * @param funParams paramether signature, e.g ["string", "number"] */ /* public */ @@ -1075,7 +1084,7 @@ var addProfile = function(c, f, p, id) { * Called also by Throwable * /* public */ -Clazz.getParamsType = function (funParams) { +Clazz.getParamsType = function(funParams) { // bh: optimization here for very common cases var n = funParams.length; switch (n) { @@ -1159,7 +1168,7 @@ var SAEMid = 0; * @throws MethodNotFoundException if no matched method is found */ /* protected */ -var searchAndExecuteMethod = function (id, objThis, claxxRef, fxName, args, _saem) { +var searchAndExecuteMethod = function(id, objThis, claxxRef, fxName, args, _saem) { // var fx = SAEMarray[id]; // if (fx) { @@ -1383,7 +1392,7 @@ Clazz.lastPackage = null; Clazz.unloadedClasses = []; /* public */ -Clazz.declarePackage = function (pkgName) { +Clazz.declarePackage = function(pkgName) { if (Clazz.lastPackageName == pkgName) return Clazz.lastPackage; if (pkgName && pkgName.length) { @@ -1410,7 +1419,7 @@ Clazz.declarePackage = function (pkgName) { }; /* protected */ -Clazz.evalType = function (typeStr, isQualified) { +Clazz.evalType = function(typeStr, isQualified) { var idx = typeStr.lastIndexOf("."); if (idx != -1) { var pkgName = typeStr.substring (0, idx); @@ -1453,7 +1462,7 @@ Clazz.evalType = function (typeStr, isQualified) { * @return Ruturn the modified Clazz object */ /* public */ -Clazz.defineType = function (qClazzName, clazzFun, clazzParent, interfacez) { +Clazz.defineType = function(qClazzName, clazzFun, clazzParent, interfacez) { var cf = Clazz.unloadedClasses[qClazzName]; if (cf) { clazzFun = cf; @@ -1498,7 +1507,7 @@ if (isSafari) { } /* public */ -Clazz.instantialize = function (objThis, args) { +Clazz.instantialize = function(objThis, args) { if (args && args.length == 1 && args[0] @@ -1506,7 +1515,7 @@ Clazz.instantialize = function (objThis, args) { return; } if (objThis instanceof Number) { - objThis.valueOf = function () { + objThis.valueOf = function(){ return this; }; } @@ -1518,17 +1527,17 @@ Clazz.instantialize = function (objThis, args) { args = argsClone; } - var c = objThis.construct; + var c = objThis.construct; // the actual constructor Xxx() {...} if (c) { if (!objThis.con$truct) { // no need to init fields c.apply (objThis, args); - } else if (!objThis.getClass ().superClazz) { // the base class + } else if (!objThis.getClass().superClazz) { // the base class objThis.con$truct.apply (objThis, []); c.apply (objThis, args); } else if ((c.claxxOwner - && c.claxxOwner === objThis.getClass ()) + && c.claxxOwner === objThis.getClass()) || (c.stacks - && c.stacks[c.stacks.length - 1] == objThis.getClass ())) { + && c.stacks[c.stacks.length - 1] == objThis.getClass())) { /* * This #construct is defined by this class itself. * #construct will call Clazz.superConstructor, which will @@ -1577,28 +1586,28 @@ Clazz._innerFunctions = { return Clazz.instanceOf(c, this); }, - equals : function (aFun) { + equals : function(aFun) { return this === aFun; }, - hashCode : function () { - return this.getName ().hashCode (); + hashCode : function(){ + return this.getName().hashCode(); }, - toString : function () { - return "class " + this.getName (); + toString : function(){ + return "class " + this.getName(); }, /* * Similar to Class#getName */ - getName : function () { + getName : function(){ return Clazz.getClassName (this, true); }, - getCanonicalName : function () { + getCanonicalName : function(){ return this.__CLASS_NAME__; }, - getClassLoader : function () { + getClassLoader : function(){ var clazzName = this.__CLASS_NAME__; var baseFolder = Clazz._Loader.getClasspathFor(clazzName); var x = baseFolder.lastIndexOf (clazzName.replace (/\./g, "/")); @@ -1618,7 +1627,7 @@ Clazz._innerFunctions = { return (stream ? stream.url : null); }, - getResourceAsStream : function (name) { + getResourceAsStream : function(name) { if (!name) return null; name = name.replace (/\\/g, '/'); @@ -1728,14 +1737,14 @@ Clazz._innerFunctions = { /* * For JavaScript programmers */ - defineMethod : function (methodName, funBody, paramTypes) { + defineMethod : function(methodName, funBody, paramTypes) { Clazz.defineMethod (this, methodName, funBody, paramTypes); }, /* * For JavaScript programmers */ - defineStaticMethod : function (methodName, funBody, paramTypes) { + defineStaticMethod : function(methodName, funBody, paramTypes) { Clazz.defineMethod (this, methodName, funBody, paramTypes); this[methodName] = this.prototype[methodName]; }, @@ -1743,7 +1752,7 @@ Clazz._innerFunctions = { /* * For JavaScript programmers */ - makeConstructor : function (funBody, paramTypes) { + makeConstructor : function(funBody, paramTypes) { Clazz.makeConstructor (this, funBody, paramTypes); } /*# x<< #*/ @@ -1756,17 +1765,17 @@ var cStack = []; * BH: I would like to be able to remove "self.c$" here, but that is tricky. */ -Clazz.pu$h = function (c) { +Clazz.pu$h = function(c) { c || (c = self.c$); // old style c && cStack.push(c); }; -Clazz.p0p = function () { +Clazz.p0p = function(){ return cStack.pop(); }; /* protected */ -Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent, +Clazz.decorateAsClass = function(clazzFun, prefix, name, clazzParent, interfacez, parentClazzInstance, _decorateAsClass) { var prefixName = null; @@ -1803,7 +1812,7 @@ Clazz.decorateAsClass = function (clazzFun, prefix, name, clazzParent, }; /* private */ -var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) { +var decorateFunction = function(clazzFun, prefix, name, interfacez) { var qName; if (!prefix) { // e.g. Clazz.declareInterface (null, "ICorePlugin", org.eclipse.ui.IPlugin); @@ -1825,44 +1834,37 @@ var decorateFunction = function (clazzFun, prefix, name, _decorateFunction) { for (var i = 0; i < inF.length; i++) { clazzFun[inF[i]] = Clazz._innerFunctions[inF[i]]; } - - if (Clazz._Loader) - Clazz._Loader.updateNodeForFunctionDecoration(qName); + interfacez && Clazz.implementOf(clazzFun, interfacez); + Clazz._Loader && Clazz._Loader.updateNodeForFunctionDecoration(qName); + return clazzFun; }; /* protected */ -Clazz.declareInterface = function (prefix, name, interfacez, _declareInterface) { - var clazzFun = function () {}; - decorateFunction(clazzFun, prefix, name); - if (interfacez) { - Clazz.implementOf (clazzFun, interfacez); - } - return clazzFun; +Clazz.declareInterface = function(prefix, name, interfacez, _declareInterface) { + return decorateFunction(function(){}, prefix, name, interfacez); }; /* public */ -Clazz.declareType = function (prefix, name, clazzParent, interfacez, +Clazz.declareType = function(prefix, name, clazzParent, interfacez, parentClazzInstance, _declareType) { - var f = function () { + return Clazz.decorateAsClass (function(){ Clazz.instantialize (this, arguments); - }; - return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, + }, prefix, name, clazzParent, interfacez, parentClazzInstance); }; /* public */ -Clazz.declareAnonymous = function (prefix, name, clazzParent, interfacez, +Clazz.declareAnonymous = function(prefix, name, clazzParent, interfacez, parentClazzInstance, _declareAnonymous) { - var f = function () { + return Clazz.decorateAsClass (function(){ Clazz.prepareCallback(this, arguments); Clazz.instantialize (this, arguments); - }; - return Clazz.decorateAsClass (f, prefix, name, clazzParent, interfacez, + }, prefix, name, clazzParent, interfacez, parentClazzInstance); }; /* public */ -Clazz.decorateAsType = function (clazzFun, qClazzName, clazzParent, +Clazz.decorateAsType = function(clazzFun, qClazzName, clazzParent, interfacez, parentClazzInstance, inheritClazzFuns, _decorateAsType) { Clazz.extendJO(clazzFun, qClazzName); clazzFun.equals = Clazz._innerFunctions.equals; @@ -1878,9 +1880,7 @@ Clazz.decorateAsType = function (clazzFun, qClazzName, clazzParent, } else if (clazzParent) { Clazz.inheritClass (clazzFun, clazzParent); } - if (interfacez) { - Clazz.implementOf (clazzFun, interfacez); - } + interfacez && Clazz.implementOf(clazzFun, interfacez); return clazzFun; }; @@ -1952,7 +1952,7 @@ java.lang.ClassLoader = { */ /* protected */ // Override the Clazz.MethodNotFoundException in Class.js to give details -var newMethodNotFoundException = function (obj, clazz, method, params) { +var newMethodNotFoundException = function(obj, clazz, method, params) { var paramStr = ""; if (params) { paramStr = params.substring (1).replace (/\\/g, ","); @@ -1983,7 +1983,7 @@ var newMethodNotFoundException = function (obj, clazz, method, params) { * Attention: parameters should not be null! */ /* protected */ -Clazz.prepareCallback = function (innerObj, args) { +Clazz.prepareCallback = function(innerObj, args) { var outerObj = args[0]; var cbName = "b$"; // "callbacks"; if (innerObj && outerObj && outerObj !== window) { @@ -2029,7 +2029,7 @@ Clazz.prepareCallback = function (innerObj, args) { * @see Clazz#cloneFinals */ /* public */ -Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) { +Clazz.innerTypeInstance = function(clazzInner, innerObj, finalVars) { if (!clazzInner) clazzInner = arguments.callee.caller; var obj; @@ -2096,7 +2096,7 @@ Clazz.innerTypeInstance = function (clazzInner, innerObj, finalVars) { * @return Object with all final variables */ /* public */ -Clazz.cloneFinals = function () { +Clazz.cloneFinals = function(){ var o = {}; var len = arguments.length / 2; for (var i = len; --i >= 0;) @@ -2113,14 +2113,17 @@ Clazz.cloneFinals = function () { * @return return defined enum constant */ /* public */ -Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) { +Clazz.defineEnumConstant = function(clazzEnum, enumName, enumOrdinal, initialParams, clazzEnumExt) { var o = (clazzEnumExt ? new clazzEnumExt() : new clazzEnum()); // BH avoids unnecessary calls to SAEM - o.$name = enumName; - o.$ordinal = enumOrdinal; - //Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]); - if (initialParams && initialParams.length) - o.construct.apply (o, initialParams); + if (initialParams && initialParams.length) { + o.constructor.apply (o, initialParams); +// Clazz.superConstructor (o, clazzEnum, [enumName, enumOrdinal]); + } +//else { + o.$name = enumName; + o.$ordinal = enumOrdinal; +// } clazzEnum[enumName] = o; clazzEnum.prototype[enumName] = o; if (!clazzEnum["$ values"]) { // BH added @@ -2135,14 +2138,14 @@ Clazz.defineEnumConstant = function (clazzEnum, enumName, enumOrdinal, initialPa //////// (int) conversions ////////// -Clazz.floatToInt = function (x) { +Clazz.floatToInt = function(x) { return isNaN(x) ? 0 : x < 0 ? Math.ceil(x) : Math.floor(x); }; Clazz.floatToByte = Clazz.floatToShort = Clazz.floatToLong = Clazz.floatToInt; Clazz.doubleToByte = Clazz.doubleToShort = Clazz.doubleToLong = Clazz.doubleToInt = Clazz.floatToInt; -Clazz.floatToChar = function (x) { +Clazz.floatToChar = function(x) { return String.fromCharCode (x < 0 ? Math.ceil(x) : Math.floor(x)); }; @@ -2211,7 +2214,7 @@ Float64Array.prototype.clone = function() { return this.slice(); }; * @return the created Array object */ /* public */ -Clazz.newArray = function (a, b, c, d) { +Clazz.newArray = function(a, b, c, d) { if (a != -1 || arguments.length == 2) { // Clazz.newArray(36,null) // Clazz.newArray(3, 0) @@ -2273,15 +2276,15 @@ var newTypedArray = function(args, nBits) { } } -Clazz.newByteArray = function () { +Clazz.newByteArray = function(){ return newTypedArray(arguments, 8); } -Clazz.newIntArray = function () { +Clazz.newIntArray = function(){ return newTypedArray(arguments, 32); } -Clazz.newFloatArray = function () { +Clazz.newFloatArray = function(){ return newTypedArray(arguments, 64); } @@ -2338,7 +2341,7 @@ Clazz.isAP = function(a) { } /* public */ -Clazz.prepareFields = function (clazz, fieldsFun) { +Clazz.prepareFields = function(clazz, fieldsFun) { var stacks = []; if (clazz.con$truct) { var ss = clazz.con$truct.stacks; @@ -2347,7 +2350,7 @@ Clazz.prepareFields = function (clazz, fieldsFun) { stacks[i] = ss[i]; } } - addProto(clazz.prototype, "con$truct", clazz.con$truct = function () { + addProto(clazz.prototype, "con$truct", clazz.con$truct = function(){ var stacks = arguments.callee.stacks; if (stacks) { for (var i = 0; i < stacks.length; i++) { @@ -2359,7 +2362,7 @@ Clazz.prepareFields = function (clazz, fieldsFun) { clazz.con$truct.stacks = stacks; clazz.con$truct.index = 0; }; -Clazz.checkPrivateMethod = function () { +Clazz.checkPrivateMethod = function(){ // get both this one and the one calling it me = arguments.callee.caller; caller = arguments.callee.caller.caller; @@ -2384,9 +2387,9 @@ java.lang.Object = Clazz._O; Clazz._O.getName = Clazz._innerFunctions.getName; java.lang.System = System = { - props : null, //new java.util.Properties (), + props : null, //new java.util.Properties(), $props : {}, - arraycopy : function (src, srcPos, dest, destPos, length) { + arraycopy : function(src, srcPos, dest, destPos, length) { if (src !== dest || srcPos > destPos) { for (var i = length; --i >= 0;) dest[destPos++] = src[srcPos++]; @@ -2397,14 +2400,14 @@ java.lang.System = System = { src[--destPos] = src[--srcPos]; } }, - currentTimeMillis : function () { - return new Date ().getTime (); + currentTimeMillis : function(){ + return new Date().getTime(); }, gc : function() {}, // bh - getProperties : function () { + getProperties : function(){ return System.props; }, - getProperty : function (key, def) { + getProperty : function(key, def) { if (System.props) return System.props.getProperty (key, def); var v = System.$props[key]; @@ -2433,11 +2436,11 @@ java.lang.System = System = { return (arguments.length == 1 ? null : def == null ? key : def); // BH }, getSecurityManager : function() { return null }, // bh - setProperties : function (props) { + setProperties : function(props) { System.props = props; }, lineSeparator : function() { return '\n' }, // bh - setProperty : function (key, val) { + setProperty : function(key, val) { if (!System.props) return System.$props[key] = val; // BH System.props.setProperty (key, val); @@ -2451,27 +2454,27 @@ System.identityHashCode=function(obj){ return obj._$hashcode || (obj._$hashcode = ++Clazz._hashCode) } -System.out = new Clazz._O (); +System.out = new Clazz._O(); System.out.__CLASS_NAME__ = "java.io.PrintStream"; -System.out.print = function () {}; -System.out.printf = function () {}; -System.out.println = function () {}; -System.out.write = function () {}; +System.out.print = function(){}; +System.out.printf = function(){}; +System.out.println = function(){}; +System.out.write = function(){}; System.out.flush = function() {}; -System.err = new Clazz._O (); +System.err = new Clazz._O(); System.err.__CLASS_NAME__ = "java.io.PrintStream"; -System.err.print = function () {}; -System.err.printf = function () {}; -System.err.println = function () {}; -System.err.write = function () {}; +System.err.print = function(){}; +System.err.printf = function(){}; +System.err.println = function(){}; +System.err.write = function(){}; System.err.flush = function() {}; Clazz.popup = Clazz.assert = Clazz.log = Clazz.error = window.alert; -Thread = function () {}; -Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread (); -Thread.currentThread = Thread.prototype.currentThread = function () { +Thread = function(){}; +Thread.J2S_THREAD = Thread.prototype.J2S_THREAD = new Thread(); +Thread.currentThread = Thread.prototype.currentThread = function(){ return this.J2S_THREAD; }; @@ -2486,22 +2489,22 @@ Clazz.innerFunctionNames = Clazz.innerFunctionNames.concat ([ "getModifiers", /*"isArray",*/ "newInstance"]); /* public */ -Clazz._innerFunctions.getSuperclass = function () { +Clazz._innerFunctions.getSuperclass = function(){ return this.superClazz; }; /* public */ -Clazz._innerFunctions.isAssignableFrom = function (clazz) { +Clazz._innerFunctions.isAssignableFrom = function(clazz) { return Clazz.getInheritedLevel (clazz, this) >= 0; }; /* public */ -Clazz._innerFunctions.getConstructor = function () { +Clazz._innerFunctions.getConstructor = function(){ return new java.lang.reflect.Constructor (this, [], [], java.lang.reflect.Modifier.PUBLIC); }; /* public */ -Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function () { +Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = function(){ var ms = []; var p = this.prototype; for (var attr in p) { @@ -2522,7 +2525,7 @@ Clazz._innerFunctions.getDeclaredMethods = Clazz._innerFunctions.getMethods = fu return ms; }; /* public */ -Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = function (name, clazzes) { +Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = function(name, clazzes) { var p = this.prototype; for (var attr in p) { if (name == attr && typeof p[attr] == "function" @@ -2544,11 +2547,11 @@ Clazz._innerFunctions.getDeclaredMethod = Clazz._innerFunctions.getMethod = func return null; }; /* public */ -Clazz._innerFunctions.getModifiers = function () { +Clazz._innerFunctions.getModifiers = function(){ return java.lang.reflect.Modifier.PUBLIC; }; -Clazz._innerFunctions.newInstance = function (a) { +Clazz._innerFunctions.newInstance = function(a) { var clz = this; switch(a == null ? 0 : a.length) { case 0: @@ -2686,13 +2689,13 @@ Clazz._innerFunctions.newInstance = function (a) { /** * Static class loader class */ -Clazz._Loader = Clazz.ClazzLoader = function () {}; +Clazz._Loader = Clazz.ClazzLoader = function(){}; /** * Class dependency tree node */ /* private */ -var Node = function () { +var Node = function(){ this.parents = []; this.musts = []; this.optionals = []; @@ -2737,13 +2740,13 @@ Node.STATUS_LOAD_COMPLETE = 5; var loaders = []; /* public */ -_Loader.requireLoaderByBase = function (base) { +_Loader.requireLoaderByBase = function(base) { for (var i = 0; i < loaders.length; i++) { if (loaders[i].base == base) { return loaders[i]; } } - var loader = new _Loader (); + var loader = new _Loader(); loader.base = base; loaders.push(loader); return loader; @@ -2772,7 +2775,7 @@ var inLoadingThreads = 0; /* private */ var maxLoadingThreads = 6; -var userAgent = navigator.userAgent.toLowerCase (); +var userAgent = navigator.userAgent.toLowerCase(); var isOpera = (userAgent.indexOf ("opera") != -1); var isIE = (userAgent.indexOf ("msie") != -1) && !isOpera; var isGecko = (userAgent.indexOf ("gecko") != -1); @@ -2809,7 +2812,7 @@ if (self.Clazz && Clazz.isClassDefined) { isClassDefined = Clazz.isClassDefined; } else { definedClasses = {}; - isClassDefined = function (clazzName) { + isClassDefined = function(clazzName) { return definedClasses[clazzName] == true; }; } @@ -2826,7 +2829,7 @@ if (self.Clazz && Clazz.isClassDefined) { * the ignored classes list. */ /* private */ -var unwrapArray = function (arr) { +var unwrapArray = function(arr) { if (!arr || arr.length == 0) return []; var last = null; @@ -2864,7 +2867,7 @@ var classpathMap = {}; var pkgRefCount = 0; /* public */ -_Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) { +_Loader.loadPackageClasspath = function(pkg, base, isIndex, fSuccess, mode, pt) { var map = classpathMap; mode || (mode = 0); fSuccess || (fSuccess = null); @@ -2919,7 +2922,7 @@ _Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) pkgRefCount++; if (pkg == "java") pkg = "core" // JSmol -- moves java/package.js to core/package.js - _Loader.loadClass(pkg + ".package", function () { + _Loader.loadClass(pkg + ".package", function(){ if (--pkgRefCount == 0) runtimeLoaded(); //fSuccess && fSuccess(); @@ -2934,7 +2937,7 @@ _Loader.loadPackageClasspath = function (pkg, base, isIndex, fSuccess, mode, pt) * Closure Compiler has not been run on the class. * */ -Clazz.loadClass = function (name, onLoaded, async) { +Clazz.loadClass = function(name, onLoaded, async) { if (!self.Class) { Class = Clazz; Class.forName = Clazz._4Name; @@ -2948,7 +2951,7 @@ Clazz.loadClass = function (name, onLoaded, async) { * Load the given class ant its related classes. */ /* public */ -_Loader.loadClass = function (name, onLoaded, forced, async, mode) { +_Loader.loadClass = function(name, onLoaded, forced, async, mode) { //System.out.println("loadClass " + name) @@ -3009,7 +3012,7 @@ _Loader.loadClass = function (name, onLoaded, forced, async, mode) { if (!n.onLoaded) { n.onLoaded = onLoaded; } else if (onLoaded != n.onLoaded) { - n.onLoaded = (function (nF, oF) { return function () { nF(); oF() }; }) (n.onLoaded, onLoaded); + n.onLoaded = (function(nF, oF) { return function(){ nF(); oF() }; }) (n.onLoaded, onLoaded); } } } @@ -3079,7 +3082,7 @@ _Loader.loadPackage = function(pkg, fSuccess) { * for all those classes. */ /* public */ -_Loader.jarClasspath = function (jar, clazzes) { +_Loader.jarClasspath = function(jar, clazzes) { if (!(clazzes instanceof Array)) clazzes = [clazzes]; unwrapArray(clazzes); @@ -3095,8 +3098,8 @@ _Loader.jarClasspath = function (jar, clazzes) { * to the same classpath of given prefix package. */ /* public */ -_Loader.registerPackages = function (prefix, pkgs) { - //_Loader.checkInteractive (); +_Loader.registerPackages = function(prefix, pkgs) { + //_Loader.checkInteractive(); var base = _Loader.getClasspathFor (prefix + ".*", true); for (var i = 0; i < pkgs.length; i++) { if (window["Clazz"]) { @@ -3120,7 +3123,7 @@ _Loader.registerPackages = function (prefix, pkgs) { */ /* protected */ /* -_Loader.multipleSites = function (path) { +_Loader.multipleSites = function(path) { var deltas = window["j2s.update.delta"]; if (deltas && deltas instanceof Array && deltas.length >= 3) { var lastOldVersion = null; @@ -3171,7 +3174,7 @@ _Loader.multipleSites = function (path) { * extension. */ /* public */ -_Loader.getClasspathFor = function (clazz, forRoot, ext) { +_Loader.getClasspathFor = function(clazz, forRoot, ext) { var path = classpathMap["#" + clazz]; if (!path || forRoot || ext) { var base; @@ -3207,7 +3210,7 @@ _Loader.getClasspathFor = function (clazz, forRoot, ext) { * To ignore some classes. */ /* public */ -_Loader.ignore = function () { +_Loader.ignore = function(){ var clazzes = (arguments.length == 1 && arguments[0] instanceof Array ? clazzes = arguments[0] : null); var n = (clazzes ? clazzes.length : arguments.length); @@ -3228,26 +3231,26 @@ _Loader.ignore = function () { * TODO: There should be a Java interface with name like INativeLoaderStatus */ /* public */ -_Loader.onScriptLoading = function (file){}; +_Loader.onScriptLoading = function(file){}; /* public */ -_Loader.onScriptLoaded = function (file, isError){}; +_Loader.onScriptLoaded = function(file, isError){}; /* public */ -_Loader.onScriptInitialized = function (file){}; +_Loader.onScriptInitialized = function(file){}; /* public */ -_Loader.onScriptCompleted = function (file){}; +_Loader.onScriptCompleted = function(file){}; /* public */ -_Loader.onClassUnloaded = function (clazz){}; +_Loader.onClassUnloaded = function(clazz){}; /** * After all the classes are loaded, this method will be called. * Should be overriden to run *.main([]). */ /* public */ -_Loader.onGlobalLoaded = function () {}; +_Loader.onGlobalLoaded = function(){}; /* public */ _Loader.keepOnLoading = true; // never set false in this code @@ -3257,7 +3260,7 @@ _Loader.keepOnLoading = true; // never set false in this code var mapPath2ClassNode = {}; /* private */ -var isClassExcluded = function (clazz) { +var isClassExcluded = function(clazz) { return excludeClassMap["@" + clazz]; }; @@ -3288,8 +3291,8 @@ var evaluate = function(file, file0, js, isLoaded) { var failedHandles = {}; /* private */ -var generateRemovingFunction = function (node) { - return function () { +var generateRemovingFunction = function(node) { + return function(){ if (node.readyState != "interactive") { try { if (node.parentNode) @@ -3301,12 +3304,12 @@ var generateRemovingFunction = function (node) { }; /* private */ -var removeScriptNode = function (n) { +var removeScriptNode = function(n) { if (window["j2s.script.debugging"]) { return; } // lazily remove script nodes. - window.setTimeout (generateRemovingFunction (n), 1); + window.setTimeout (generateRemovingfunction(n), 1); }; /* public */ @@ -3335,7 +3338,7 @@ Clazz.currentPath= ""; * load the next class in dependency tree. */ /* private */ -var loadScript = function (node, file, why, ignoreOnload, fSuccess, _loadScript) { +var loadScript = function(node, file, why, ignoreOnload, fSuccess, _loadScript) { Clazz.currentPath = file; @@ -3404,9 +3407,9 @@ var loadScript = function (node, file, why, ignoreOnload, fSuccess, _loadScript) }; /* private */ -var W3CScriptOnCallback = function (path, forError, fSuccess) { +var W3CScriptOnCallback = function(path, forError, fSuccess) { var s = Clazz.getStackTrace(); - return function () { + return function(){ if (forError && __debuggingBH)Clazz.alert ("############ forError=" + forError + " path=" + path + " ####" + (forError ? "NOT" : "") + "LOADED###"); if (isGecko && this.timeoutHandle) window.clearTimeout(this.timeoutHandle), this.timeoutHandle = null; @@ -3441,7 +3444,7 @@ var besidesJavaPackage = false; * are classes in the dependency tree that need to be loaded. */ /* private */ -var tryToLoadNext = function (file, fSuccess) { +var tryToLoadNext = function(file, fSuccess) { var node = mapPath2ClassNode["@" + file]; if (!node) // maybe class tree root return; @@ -3640,7 +3643,7 @@ var tracks = []; * There are classes reference cycles. Try to detect and break those cycles. */ /* private */ -var checkCycle = function (node, file) { +var checkCycle = function(node, file) { var ts = tracks; var len = ts.length; // add this node to tracks @@ -3836,7 +3839,7 @@ updateNode = function(node, _updateNode) { } } } - // _Loader.updateParents = function (node, level, _updateParents) + // _Loader.updateParents = function(node, level, _updateParents) if (node.parents && node.parents.length) { for (var i = 0; i < node.parents.length; i++) { var p = node.parents[i]; @@ -3952,7 +3955,7 @@ var findNextMustNode = function(node, status) { }; /* private */ -var findNextRequiredNode = function (node, status) { +var findNextRequiredNode = function(node, status) { // search musts first // search optionals second // search itself last @@ -3963,7 +3966,7 @@ var findNextRequiredNode = function (node, status) { }; /* private */ -var searchClassArray = function (arr, status) { +var searchClassArray = function(arr, status) { if (arr) { var rnd = clazzTreeRoot.random; for (var i = 0; i < arr.length; i++) { @@ -3993,7 +3996,7 @@ var innerLoadedScripts = {}; * compiler. */ /* public */ -var load = function (musts, name, optionals, declaration) { +var load = function(musts, name, optionals, declaration) { // called as name.load in Jmol if (name instanceof Array) { unwrapArray(name); @@ -4076,7 +4079,7 @@ if (window["Clazz"]) { * @node Node object */ /* private */ -var mappingPathNameNode = function (path, name, node) { +var mappingPathNameNode = function(path, name, node) { var map = mapPath2ClassNode; var keyPath = "@" + path; var v = map[keyPath]; @@ -4101,7 +4104,7 @@ var mappingPathNameNode = function (path, name, node) { }; /* protected */ -var loadClassNode = function (node) { +var loadClassNode = function(node) { var name = node.name; if (!isClassDefined (name) && !isClassExcluded (name)) { @@ -4135,7 +4138,7 @@ var J2sLibBase; * Return J2SLib base path from existed SCRIPT src attribute. */ /* public */ -_Loader.getJ2SLibBase = function () { +_Loader.getJ2SLibBase = function(){ var o = window["j2s.lib"]; return (o ? o.base + (o.alias == "." ? "" : (o.alias ? o.alias : (o.version ? o.version : "1.0.0")) + "/") : null); }; @@ -4173,7 +4176,7 @@ _Loader.MODE_SYNC = 1; * Script 4; XHR 2; SYNC bit 1; */ /* public */ -_Loader.setLoadingMode = function (mode, timeLag) { +_Loader.setLoadingMode = function(mode, timeLag) { var async = true; var ajax = true; if (typeof mode == "string") { @@ -4196,7 +4199,7 @@ _Loader.setLoadingMode = function (mode, timeLag) { }; /* private */ -var runtimeLoaded = function () { +var runtimeLoaded = function(){ if (pkgRefCount || !isClassDefined(runtimeKeyClass)) return; var qbs = queueBe4KeyClazz; @@ -4210,7 +4213,7 @@ var runtimeLoaded = function () { * queued *.js. */ /* public */ -_Loader.loadZJar = function (zjarPath, keyClass) { +_Loader.loadZJar = function(zjarPath, keyClass) { // used only by package.js for core.z.js var f = null; var isArr = (keyClass instanceof Array); @@ -4230,7 +4233,7 @@ var _allNodes = []; * The method help constructing the multiple-binary class dependency tree. */ /* private */ -var addChildClassNode = function (parent, child, isMust) { +var addChildClassNode = function(parent, child, isMust) { var existed = false; var arr; if (isMust) { @@ -4286,7 +4289,7 @@ var addParentClassNode = function(child, parent) { } /* private */ -var destroyClassNode = function (node) { +var destroyClassNode = function(node) { var parents = node.parents; if (parents) for (var k = parents.length; --k >= 0;) @@ -4295,7 +4298,7 @@ var destroyClassNode = function (node) { /* / * public * / -_Loader.unloadClassExt = function (qClazzName) { +_Loader.unloadClassExt = function(qClazzName) { if (definedClasses) definedClasses[qClazzName] = false; if (classpathMap["#" + qClazzName]) { @@ -4315,7 +4318,7 @@ _Loader.unloadClassExt = function (qClazzName) { _Loader.onClassUnloaded(qClazzName); }; / * private * / -var assureInnerClass = function (clzz, fun) { +var assureInnerClass = function(clzz, fun) { clzz = clzz.__CLASS_NAME__; if (Clazz.unloadedClasses[clzz]) { if (clzz.indexOf("$") >= 0) @@ -4375,7 +4378,7 @@ var bindingParent = null; CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonitorOpacity : 55); /* public */ -/*CLPM.initialize = function (parent) { +/*CLPM.initialize = function(parent) { bindingParent = parent; if (parent && !attached) { attached = true; @@ -4386,14 +4389,14 @@ CLPM.DEFAULT_OPACITY = (Jmol && Jmol._j2sLoadMonitorOpacity ? Jmol._j2sLoadMonit */ /* public */ -CLPM.hideMonitor = function () { +CLPM.hideMonitor = function(){ monitorEl.style.display = "none"; } /* public */ -CLPM.showStatus = function (msg, fading) { +CLPM.showStatus = function(msg, fading) { if (!monitorEl) { - createHandle (); + createHandle(); if (!attached) { attached = true; //Clazz.addEvent (window, "unload", cleanup); @@ -4426,7 +4429,7 @@ CLPM.showStatus = function (msg, fading) { }; /* private static */ -var clearChildren = function (el) { +var clearChildren = function(el) { if (!el) return; for (var i = el.childNodes.length; --i >= 0;) { @@ -4441,7 +4444,7 @@ var clearChildren = function (el) { } }; /* private */ -var setAlpha = function (alpha) { +var setAlpha = function(alpha) { if (fadeOutTimer && alpha == CLPM.DEFAULT_OPACITY) { window.clearTimeout (fadeOutTimer); fadeOutTimer = null; @@ -4452,14 +4455,14 @@ var setAlpha = function (alpha) { monitorEl.style.opacity = alpha / 100.0; }; /* private */ -var hidingOnMouseOver = function () { +var hidingOnMouseOver = function(){ CLPM.hideMonitor(); }; /* private */ var attached = false; /* private */ -var cleanup = function () { +var cleanup = function(){ //if (monitorEl) { // monitorEl.onmouseover = null; //} @@ -4470,7 +4473,7 @@ var cleanup = function () { attached = false; }; /* private */ -var createHandle = function () { +var createHandle = function(){ var div = document.createElement ("DIV"); div.id = "_Loader-status"; div.style.cssText = "position:absolute;bottom:4px;left:4px;padding:2px 8px;" @@ -4487,16 +4490,16 @@ var createHandle = function () { }; /* private */ -var fadeOut = function () { +var fadeOut = function(){ if (monitorEl.style.display == "none") return; if (fadeAlpha == CLPM.DEFAULT_OPACITY) { - fadeOutTimer = window.setTimeout(function () { + fadeOutTimer = window.setTimeout(function(){ fadeOut(); }, 750); fadeAlpha -= 5; } else if (fadeAlpha - 10 >= 0) { setAlpha(fadeAlpha - 10); - fadeOutTimer = window.setTimeout(function () { + fadeOutTimer = window.setTimeout(function(){ fadeOut(); }, 40); } else { @@ -4504,7 +4507,7 @@ var fadeOut = function () { } }; /* private */ -var getFixedOffsetTop = function (){ +var getFixedOffsetTop = function(){ if (bindingParent) { var b = bindingParent; return b.scrollTop; @@ -4563,7 +4566,7 @@ if (window["ClazzLoader"]) { Con.maxTotalLines = 10000; /* protected */ -Con.setMaxTotalLines = function (lines) { +Con.setMaxTotalLines = function(lines) { Con.maxTotalLines = (lines > 0 ? lines : 999999); } @@ -4571,7 +4574,7 @@ Con.setMaxTotalLines = function (lines) { Con.maxLatency = 40; /* protected */ -Con.setMaxLatency = function (latency) { +Con.setMaxLatency = function(latency) { Con.maxLatency = (latency > 0 ? latency : 40); }; @@ -4579,7 +4582,7 @@ Con.setMaxLatency = function (latency) { Con.pinning = false; /* protected */ -Con.enablePinning = function (enabled) { +Con.enablePinning = function(enabled) { Con.pinning = enabled; }; @@ -4597,7 +4600,7 @@ Con.metLineBreak = false; * TODO: provide more template of binding console window to browser. */ /* protected */ -Con.createConsoleWindow = function (parentEl) { +Con.createConsoleWindow = function(parentEl) { var console = document.createElement ("DIV"); console.style.cssText = "font-family:monospace, Arial, sans-serif;"; document.body.appendChild (console); @@ -4608,7 +4611,7 @@ var c160 = String.fromCharCode(160); //nbsp; c160 += c160+c160+c160; /* protected */ -Con.consoleOutput = function (s, color) { +Con.consoleOutput = function(s, color) { var o = window["j2s.lib"]; var console = (o && o.console); if (console && typeof console == "string") @@ -4676,14 +4679,14 @@ Con.consoleOutput = function (s, color) { && cssClazzName.indexOf ("composite") != -1) { console.parentNode.scrollTop = console.parentNode.scrollHeight; } - Con.lastOutputTime = new Date ().getTime (); + Con.lastOutputTime = new Date().getTime(); }; /* * Clear all contents inside the console. */ /* public */ -Con.clear = function () { +Con.clear = function(){ try { Con.metLineBreak = true; var o = window["j2s.lib"]; @@ -4698,14 +4701,14 @@ Con.clear = function () { }; /* public */ -Clazz.alert = function (s) { +Clazz.alert = function(s) { Con.consoleOutput (s + "\r\n"); Jmol.clazzAlert(s); }; /* public */ -Sys.out.print = function (s) { +Sys.out.print = function(s) { Con.consoleOutput (s); }; /* public */ @@ -4713,7 +4716,7 @@ Sys.out.println = function(s) { Con.consoleOutput(typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n"); }; -Sys.out.write = function (buf, offset, len) { +Sys.out.write = function(buf, offset, len) { Sys.out.print(String.instantialize(buf).substring(offset, offset+len)); }; @@ -4721,16 +4724,16 @@ Sys.out.write = function (buf, offset, len) { Sys.err.__CLASS_NAME__ = "java.io.PrintStream"; /* public */ -Sys.err.print = function (s) { +Sys.err.print = function(s) { Con.consoleOutput (s, "red"); }; /* public */ -Sys.err.println = function (s) { +Sys.err.println = function(s) { Con.consoleOutput (typeof s == "undefined" ? "\r\n" : s == null ? s = "null\r\n" : s + "\r\n", "red"); }; -Sys.err.write = function (buf, offset, len) { +Sys.err.write = function(buf, offset, len) { Sys.err.print(String.instantialize(buf).substring(offset, offset+len)); }; diff --git a/sources/net.sf.j2s.java.core/src/java/applet/JSApplet.java b/sources/net.sf.j2s.java.core/src/java/applet/JSApplet.java index adb582368..54644924c 100644 --- a/sources/net.sf.j2s.java.core/src/java/applet/JSApplet.java +++ b/sources/net.sf.j2s.java.core/src/java/applet/JSApplet.java @@ -204,6 +204,9 @@ public boolean isActive() { * @see java.applet.Applet#getCodeBase() */ public URL getDocumentBase() { + if (stub == null) + throw new NullPointerException(); + return stub.getDocumentBase(); } @@ -244,6 +247,8 @@ public URL getCodeBase() { * or null if not set. */ public String getParameter(String name) { + if (stub == null) + throw new NullPointerException(); return stub.getParameter(name); } @@ -257,6 +262,8 @@ public String getParameter(String name) { * @return the applet's context. */ public AppletContext getAppletContext() { + if (stub == null) + throw new NullPointerException(); return stub.getAppletContext(); } diff --git a/sources/net.sf.j2s.java.core/src/java/awt/Font.java b/sources/net.sf.j2s.java.core/src/java/awt/Font.java index 27f105c5b..abe25d43f 100644 --- a/sources/net.sf.j2s.java.core/src/java/awt/Font.java +++ b/sources/net.sf.j2s.java.core/src/java/awt/Font.java @@ -70,8 +70,8 @@ import sun.font.AttributeValues; import sun.font.CoreMetrics; import sun.font.Font2DHandle; +import sun.font.FontDesignMetrics; import sun.font.FontLineMetrics; -import swingjs.JSFontMetrics; import swingjs.JSToolkit; /** @@ -235,18 +235,10 @@ public class Font { - FontMetrics fm; - - public FontMetrics getFontMetrics() { - if (fm == null) - ((JSFontMetrics) (fm = new JSFontMetrics())).setFont(this); - return fm; + public FontMetrics getFontMetrics() { + return FontDesignMetrics.getMetrics(this); } - public void setFontMetrics(FontMetrics fm) { - this.fm = fm; - } - // /** // * This is now only used during serialization. Typically // * it is null. @@ -422,16 +414,16 @@ public void setFontMetrics(FontMetrics fm) { */ private transient boolean nonIdentityTx; - /* - * A cached value used when a transform is required for internal - * use. This must not be exposed to callers since AffineTransform - * is mutable. - */ - private static AffineTransform identityTx; - - private static AffineTransform getIdentityTx() { - return (identityTx == null ? (identityTx = new AffineTransform()) : identityTx); - } +// /* +// * A cached value used when a transform is required for internal +// * use. This must not be exposed to callers since AffineTransform +// * is mutable. +// */ +// private static AffineTransform identityTx; +// +// private static AffineTransform getIdentityTx() { +// return (identityTx == null ? (identityTx = new AffineTransform()) : identityTx); +// } /* * JDK 1.1 serialVersionUID */ @@ -2212,11 +2204,7 @@ private FontLineMetrics defaultLineMetrics(FontRenderContext frc) { * just pass identity here */ float [] metrics = new float[8]; - ((JSFontMetrics)getFontMetrics()).//getFont2D(). - getMetrics(getIdentityTx(), - frc.getAntiAliasingHint(), - frc.getFractionalMetricsHint(), - metrics); + ((FontDesignMetrics) getFontMetrics()).秘fillMetrics(metrics); float ascent = metrics[0]; float descent = metrics[1]; float leading = metrics[2]; @@ -2367,7 +2355,7 @@ public LineMetrics getLineMetrics(CharacterIterator ci, * @since 1.2 */ public Rectangle2D getStringBounds( String str, FontRenderContext frc) { - return getStringBoundsStr(str, 0, -1); + return getStringBoundsStr(str, 0, str.length()); } /** @@ -2403,56 +2391,93 @@ public Rectangle2D getStringBounds( String str, return getStringBoundsStr(str, beginIndex, limit); } - /** - * Returns the logical bounds of the specified array of characters - * in the specified FontRenderContext. The logical - * bounds contains the origin, ascent, advance, and height, which - * includes the leading. The logical bounds does not always enclose - * all the text. For example, in some languages and in some fonts, - * accent marks can be positioned above the ascent or below the - * descent. To obtain a visual bounding box, which encloses all the - * text, use the {@link TextLayout#getBounds() getBounds} method of - * TextLayout. - *

Note: The returned bounds is in baseline-relative coordinates - * (see {@link java.awt.Font class notes}). - * @param chars an array of characters - * @param beginIndex the initial offset in the array of - * characters - * @param limit the end offset in the array of characters - * @param frc the specified FontRenderContext - * @return a Rectangle2D that is the bounding box of the - * specified array of characters in the specified - * FontRenderContext. - * @throws IndexOutOfBoundsException if beginIndex is - * less than zero, or limit is greater than the - * length of chars, or beginIndex - * is greater than limit. - * @see FontRenderContext - * @see Font#createGlyphVector - * @since 1.2 - */ - public Rectangle2D getStringBounds(char [] chars, - int beginIndex, int limit, - FontRenderContext frc) { - SB sb = new SB(); - sb.appendCB(chars, beginIndex, limit); - return getStringBoundsStr(sb.toString(), 0, -1); - } - - public Rectangle2D getStringBoundsStr(String s, int i, int j) { - if (j >= i) - s = s.substring(i, j); -// if (beginIndex < 0) { -// throw new IndexOutOfBoundsException("beginIndex: " + beginIndex); -// } -// if (limit > chars.length) { -// throw new IndexOutOfBoundsException("limit: " + limit); -// } -// if (beginIndex > limit) { -// throw new IndexOutOfBoundsException("range length: " + -// (limit - beginIndex)); -// } + /** + * Returns the logical bounds of the specified array of characters in the + * specified FontRenderContext. The logical bounds contains the + * origin, ascent, advance, and height, which includes the leading. The logical + * bounds does not always enclose all the text. For example, in some languages + * and in some fonts, accent marks can be positioned above the ascent or below + * the descent. To obtain a visual bounding box, which encloses all the text, + * use the {@link TextLayout#getBounds() getBounds} method of + * TextLayout. + *

+ * Note: The returned bounds is in baseline-relative coordinates (see + * {@link java.awt.Font class notes}). + * + * @param chars an array of characters + * @param beginIndex the initial offset in the array of characters + * @param limit the end offset in the array of characters + * @param frc the specified FontRenderContext + * @return a Rectangle2D that is the bounding box of the specified + * array of characters in the specified FontRenderContext. + * @throws IndexOutOfBoundsException if beginIndex is less than + * zero, or limit is greater than + * the length of chars, or + * beginIndex is greater than + * limit. + * @see FontRenderContext + * @see Font#createGlyphVector + * @since 1.2 + */ + @SuppressWarnings("unused") + public Rectangle2D getStringBounds(char[] chars, int beginIndex, int limit, FontRenderContext frc) { + if (beginIndex < 0) { + throw new IndexOutOfBoundsException("beginIndex: " + beginIndex); + } + if (limit > chars.length) { + throw new IndexOutOfBoundsException("limit: " + limit); + } + if (beginIndex > limit) { + throw new IndexOutOfBoundsException("range length: " + (limit - beginIndex)); + } + + // In JavaScript, we just let the browser figure this out. + SB sb = new SB(); + sb.appendCB(chars, beginIndex, limit); + return ((FontDesignMetrics) getFontMetrics()).秘getStringBounds(sb.toString()); + + +// boolean simple = values == null || (values.getKerning() == 0 && values.getLigatures() == 0 +// && values.getBaselineTransform() == null); +// if (simple) { +// simple = !FontUtilities.isComplexText(chars, beginIndex, limit); +// } +// // +// if (simple) { +// GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex, limit - beginIndex, frc); +// return gv.getLogicalBounds(); +// } else { +// // need char array constructor on textlayout +// String str = new String(chars, beginIndex, limit - beginIndex); +// TextLayout tl = new TextLayout(str, this, frc); +// return new Rectangle2D.Float(0, -tl.getAscent(), tl.getAdvance(), +// tl.getAscent() + tl.getDescent() + tl.getLeading()); +// } + + } + + /** + * Keep it simple in JavaScript. + * + * @param s + * @param beginIndex + * @param limit + * @return Rectangle2D.Float + */ + public Rectangle2D getStringBoundsStr(String s, int beginIndex, int limit) { + if (beginIndex < 0) { + throw new IndexOutOfBoundsException("beginIndex: " + beginIndex); + } + if (limit > s.length()) { + throw new IndexOutOfBoundsException("limit: " + limit); + } + if (beginIndex > limit) { + throw new IndexOutOfBoundsException("range length: " + + (limit - beginIndex)); + } + + s = s.substring(beginIndex, limit); // this code should be in textlayout // quick check for simple text, assume GV ok to use if simple @@ -2466,11 +2491,7 @@ public Rectangle2D getStringBoundsStr(String s, int i, int j) { // if (simple) { // GlyphVector gv = new StandardGlyphVector(this, chars, beginIndex, // limit - beginIndex, frc); - FontMetrics fm = getFontMetrics(); - int dec = fm.getDescent(); - int asc = fm.getAscent(); - int width = fm.stringWidth(s); - return new Rectangle2D.Float(0, -dec, width, asc + dec); + return ((FontDesignMetrics) getFontMetrics()).秘getStringBounds(s); // return null;//gv.getLogicalBounds(); // } else { // // need char array constructor on textlayout @@ -2551,9 +2572,7 @@ public Rectangle2D getStringBounds(CharacterIterator ci, */ public Rectangle2D getMaxCharBounds(FontRenderContext frc) { float [] metrics = new float[4]; - - ((JSFontMetrics) getFontMetrics()).getMetrics(frc, metrics); - + ((FontDesignMetrics) getFontMetrics()).秘fillMetrics(metrics); return new Rectangle2D.Float(0, -metrics[0], metrics[3], metrics[0] + metrics[1] + metrics[2]); diff --git a/sources/net.sf.j2s.java.core/src/java/awt/FontMetrics.java b/sources/net.sf.j2s.java.core/src/java/awt/FontMetrics.java index cb8601989..ab4d68ee2 100644 --- a/sources/net.sf.j2s.java.core/src/java/awt/FontMetrics.java +++ b/sources/net.sf.j2s.java.core/src/java/awt/FontMetrics.java @@ -29,7 +29,9 @@ package java.awt; import java.awt.font.FontRenderContext; +import java.awt.font.LineMetrics; import java.awt.geom.Rectangle2D; +import java.text.CharacterIterator; /** * The FontMetrics class defines a font metrics object, which @@ -435,88 +437,89 @@ public int bytesWidth(byte data[], int off, int len) { // return widths; // } -// /** -// * Checks to see if the Font has uniform line metrics. A -// * composite font may consist of several different fonts to cover -// * various character sets. In such cases, the -// * FontLineMetrics objects are not uniform. -// * Different fonts may have a different ascent, descent, metrics and -// * so on. This information is sometimes necessary for line -// * measuring and line breaking. -// * @return true if the font has uniform line metrics; -// * false otherwise. -// * @see java.awt.Font#hasUniformLineMetrics() -// */ -// public boolean hasUniformLineMetrics() { -// return font.hasUniformLineMetrics(); -// } -// -// /** -// * Returns the {@link LineMetrics} object for the specified -// * String in the specified {@link Graphics} context. -// * @param str the specified String -// * @param context the specified Graphics context -// * @return a LineMetrics object created with the -// * specified String and Graphics context. -// * @see java.awt.Font#getLineMetrics(String, FontRenderContext) -// */ -// public LineMetrics getLineMetrics( String str, Graphics context) { -// return font.getLineMetrics(str, myFRC(context)); -// } -// -// /** -// * Returns the {@link LineMetrics} object for the specified -// * String in the specified {@link Graphics} context. -// * @param str the specified String -// * @param beginIndex the initial offset of str -// * @param limit the end offset of str -// * @param context the specified Graphics context -// * @return a LineMetrics object created with the -// * specified String and Graphics context. -// * @see java.awt.Font#getLineMetrics(String, int, int, FontRenderContext) -// */ -// public LineMetrics getLineMetrics( String str, -// int beginIndex, int limit, -// Graphics context) { -// return font.getLineMetrics(str, beginIndex, limit, myFRC(context)); -// } -// -// /** -// * Returns the {@link LineMetrics} object for the specified -// * character array in the specified {@link Graphics} context. -// * @param chars the specified character array -// * @param beginIndex the initial offset of chars -// * @param limit the end offset of chars -// * @param context the specified Graphics context -// * @return a LineMetrics object created with the -// * specified character array and Graphics context. -// * @see java.awt.Font#getLineMetrics(char[], int, int, FontRenderContext) -// */ -// public LineMetrics getLineMetrics(char [] chars, -// int beginIndex, int limit, -// Graphics context) { -// return font.getLineMetrics( -// chars, beginIndex, limit, myFRC(context)); -// } -// -// /** -// * Returns the {@link LineMetrics} object for the specified -// * {@link CharacterIterator} in the specified {@link Graphics} -// * context. -// * @param ci the specified CharacterIterator -// * @param beginIndex the initial offset in ci -// * @param limit the end index of ci -// * @param context the specified Graphics context -// * @return a LineMetrics object created with the -// * specified arguments. -// * @see java.awt.Font#getLineMetrics(CharacterIterator, int, int, FontRenderContext) -// */ -// public LineMetrics getLineMetrics(CharacterIterator ci, -// int beginIndex, int limit, -// Graphics context) { -// return font.getLineMetrics(ci, beginIndex, limit, myFRC(context)); -// } -// + /** + * Checks to see if the Font has uniform line metrics. A + * composite font may consist of several different fonts to cover + * various character sets. In such cases, the + * FontLineMetrics objects are not uniform. + * Different fonts may have a different ascent, descent, metrics and + * so on. This information is sometimes necessary for line + * measuring and line breaking. + * @return true if the font has uniform line metrics; + * false otherwise. + * @see java.awt.Font#hasUniformLineMetrics() + */ + public boolean hasUniformLineMetrics() { + return font.hasUniformLineMetrics(); + } + + + /** + * Returns the {@link LineMetrics} object for the specified + * String in the specified {@link Graphics} context. + * @param str the specified String + * @param context the specified Graphics context + * @return a LineMetrics object created with the + * specified String and Graphics context. + * @see java.awt.Font#getLineMetrics(String, FontRenderContext) + */ + public LineMetrics getLineMetrics( String str, Graphics context) { + return font.getLineMetrics(str, myFRC(context)); + } + + /** + * Returns the {@link LineMetrics} object for the specified + * String in the specified {@link Graphics} context. + * @param str the specified String + * @param beginIndex the initial offset of str + * @param limit the end offset of str + * @param context the specified Graphics context + * @return a LineMetrics object created with the + * specified String and Graphics context. + * @see java.awt.Font#getLineMetrics(String, int, int, FontRenderContext) + */ + public LineMetrics getLineMetrics( String str, + int beginIndex, int limit, + Graphics context) { + return font.getLineMetrics(str, beginIndex, limit, myFRC(context)); + } + + /** + * Returns the {@link LineMetrics} object for the specified + * character array in the specified {@link Graphics} context. + * @param chars the specified character array + * @param beginIndex the initial offset of chars + * @param limit the end offset of chars + * @param context the specified Graphics context + * @return a LineMetrics object created with the + * specified character array and Graphics context. + * @see java.awt.Font#getLineMetrics(char[], int, int, FontRenderContext) + */ + public LineMetrics getLineMetrics(char [] chars, + int beginIndex, int limit, + Graphics context) { + return font.getLineMetrics( + chars, beginIndex, limit, myFRC(context)); + } + + /** + * Returns the {@link LineMetrics} object for the specified + * {@link CharacterIterator} in the specified {@link Graphics} + * context. + * @param ci the specified CharacterIterator + * @param beginIndex the initial offset in ci + * @param limit the end index of ci + * @param context the specified Graphics context + * @return a LineMetrics object created with the + * specified arguments. + * @see java.awt.Font#getLineMetrics(CharacterIterator, int, int, FontRenderContext) + */ + public LineMetrics getLineMetrics(CharacterIterator ci, + int beginIndex, int limit, + Graphics context) { + return font.getLineMetrics(ci, beginIndex, limit, myFRC(context)); + } + /** * Returns the bounds of the specified String in the * specified Graphics context. The bounds is used @@ -616,9 +619,9 @@ public Rectangle2D getStringBounds( char [] chars, // } // private FontRenderContext myFRC(Graphics context) { -// if (context instanceof Graphics2D) { -// return ((Graphics2D)context).getFontRenderContext(); -// } + if (context instanceof Graphics2D) { + return ((Graphics2D)context).getFontRenderContext(); + } return DEFAULT_FRC; } diff --git a/sources/net.sf.j2s.java.core/src/java/awt/JSComponent.java b/sources/net.sf.j2s.java.core/src/java/awt/JSComponent.java index a21443d23..7fd455158 100644 --- a/sources/net.sf.j2s.java.core/src/java/awt/JSComponent.java +++ b/sources/net.sf.j2s.java.core/src/java/awt/JSComponent.java @@ -249,7 +249,7 @@ public JSComponent() { */ @Override public Graphics getGraphics() { - if (width == 0 || height == 0 || !isVisible()) + if (!秘winOrApplet && (width == 0 || height == 0 || !isVisible())) return null; Graphics g; // this was 秘frameViewer != null, but that diff --git a/sources/net.sf.j2s.java.core/src/java/awt/Toolkit.java b/sources/net.sf.j2s.java.core/src/java/awt/Toolkit.java index 5eab07bda..270d2cb86 100644 --- a/sources/net.sf.j2s.java.core/src/java/awt/Toolkit.java +++ b/sources/net.sf.j2s.java.core/src/java/awt/Toolkit.java @@ -1748,7 +1748,12 @@ protected final void setDesktopProperty(String name, Object newValue) { * an opportunity to lazily evaluate desktop property values. */ protected Object lazilyLoadDesktopProperty(String name) { - return null; + // BH SwingJS -- we store these in Clazz.js System.getProperty$S. + // but they will be Objects. For example, + + // "awt.multiClickInterval" => Integer.valueOf(500); + + return System.getProperty("DeskTop_" + name); } /** @@ -1810,7 +1815,7 @@ public PropertyChangeListener[] getPropertyChangeListeners() { public PropertyChangeListener[] getPropertyChangeListeners(String propertyName) { return desktopPropsSupport.getPropertyChangeListeners(propertyName); } - + protected final Map desktopProperties = new HashMap(); protected final PropertyChangeSupport desktopPropsSupport = diff --git a/sources/net.sf.j2s.java.core/src/java/lang/Thread.java b/sources/net.sf.j2s.java.core/src/java/lang/Thread.java index d11657f9a..4ed749574 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/Thread.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/Thread.java @@ -379,7 +379,8 @@ private void init(ThreadGroup g, Runnable target, String name, * @param acc the AccessControlContext to inherit, or * AccessController.getContext() if null */ - private void init(ThreadGroup g, Runnable target, String name, + @SuppressWarnings("unlikely-arg-type") + private void init(ThreadGroup g, Runnable target, String name, long stackSize, Object acc) { // was access controller Thread parent = (秘thisThread == null ? null : 秘thisThread); // SecurityManager security = System.getSecurityManager(); diff --git a/sources/net.sf.j2s.java.core/src/java/math/BigInteger.java b/sources/net.sf.j2s.java.core/src/java/math/BigInteger.java index a2aadab44..1502368f3 100644 --- a/sources/net.sf.j2s.java.core/src/java/math/BigInteger.java +++ b/sources/net.sf.j2s.java.core/src/java/math/BigInteger.java @@ -2754,7 +2754,8 @@ private static int[] montReduce(int[] n, int[] mod, int mlen, int inv) { do { int nEnd = n[n.length-1-offset]; - int carry = mulAdd(n, mod, offset, mlen, inv * nEnd); + // BH JavaScript does not roll over int multiplication + int carry = mulAdd(n, mod, offset, mlen, (int)((long)inv * nEnd)); c += addOne(n, offset, mlen, carry); offset++; } while (--len > 0); diff --git a/sources/net.sf.j2s.java.core/src/java/util/zip/ZipInputStream.java b/sources/net.sf.j2s.java.core/src/java/util/zip/ZipInputStream.java index 8d89af06c..935c29c57 100644 --- a/sources/net.sf.j2s.java.core/src/java/util/zip/ZipInputStream.java +++ b/sources/net.sf.j2s.java.core/src/java/util/zip/ZipInputStream.java @@ -346,16 +346,29 @@ private ZipEntry readLOC() throws IOException { } e.method = get16(tmpbuf, LOCHOW); e.time = get32(tmpbuf, LOCTIM); - if ((flag & 8) == 8) { - /* "Data Descriptor" present */ - if (e.method != DEFLATED) { - throw new ZipException("only DEFLATED entries can have EXT descriptor"); - } - } else { - e.crc = get32(tmpbuf, LOCCRC); - e.csize = get32(tmpbuf, LOCSIZ); - e.size = get32(tmpbuf, LOCLEN); - } + boolean readSizes = ((flag & 8) != 8 || e.getMethod() != DEFLATED); + // flag 8 means size is unknown at compression time + // leave crc and sizes -1 + /* "Data Descriptor" present */ + // still read the 0 if (e.getMethod() == DEFLATED) + // DO NOT throw new ZipException + //System.out.println("ZipInputStream: only DEFLATED entries can have EXT descriptor?? - " + e.getName()); + if (readSizes) { + e.setCrc(get32(tmpbuf, LOCCRC)); + e.setCompressedSize(get32(tmpbuf, LOCSIZ)); + e.setSize(get32(tmpbuf, LOCLEN)); + } +// if ((flag & 8) == 8) { + // oops - don't set 0! +// /* "Data Descriptor" present */ +// if (e.method != DEFLATED) { +// throw new ZipException("only DEFLATED entries can have EXT descriptor"); +// } +// } else { +// e.crc = get32(tmpbuf, LOCCRC); +// e.csize = get32(tmpbuf, LOCSIZ); +// e.size = get32(tmpbuf, LOCLEN); +// } len = get16(tmpbuf, LOCEXT); byte[] bb = new byte[len + 4]; if (len > 0) { diff --git a/sources/net.sf.j2s.java.core/src/javajs/img/GifEncoder.java b/sources/net.sf.j2s.java.core/src/javajs/img/GifEncoder.java index a330595d9..ae48fe0ce 100644 --- a/sources/net.sf.j2s.java.core/src/javajs/img/GifEncoder.java +++ b/sources/net.sf.j2s.java.core/src/javajs/img/GifEncoder.java @@ -73,8 +73,8 @@ import javajs.util.CU; import javajs.util.Lst; -import javajs.util.M3; -import javajs.util.P3; +import javajs.util.M3d; +import javajs.util.P3d; /** * @@ -110,7 +110,7 @@ public class GifEncoder extends ImageEncoder { private Map params; - private P3[] palette; + private P3d[] palette; private int backgroundColor; private boolean interlaced; @@ -146,15 +146,22 @@ protected void setParams(Map params) { isTransparent = true; } + if (backgroundColor == 0xFF000000) { + // fix speckling of text Jmol 14.32.69 + // must return background to true color + for (int i = pixels.length; --i >= 0;) + pixels[i] = pixels[i] &~0x040404; + } + interlaced = (Boolean.TRUE == params.get("interlaced")); if (params.containsKey("captureRootExt") // file0000.gif || !params.containsKey("captureMode")) // animated gif return; interlaced = false; capturing = true; - Integer c = (Integer) params.get("captureByteCount"); - if (c != null) - byteCount = c.intValue(); + Integer c = (Integer) params.get("captureByteCount"); + if (c != null) + byteCount = c.intValue(); switch ("maec" .indexOf(((String) params.get("captureMode")).substring(0, 1))) { case 0: //"movie" @@ -212,8 +219,7 @@ protected void close() { * a color point in normalized L*a*b space with a flag indicating whether it * is the background color */ - @SuppressWarnings("serial") - private class ColorItem extends P3 { + private class ColorItem extends P3d { /** * */ @@ -229,16 +235,16 @@ private class ColorItem extends P3 { * A list of normalized L*a*b points with an index and a center and volume * */ - private class ColorCell extends Lst { + private class ColorCell extends Lst { /** * */ private static final long serialVersionUID = 1L; protected int index; - protected P3 center; + protected P3d center; - private float volume; + private double volume; ColorCell(int index) { this.index = index; @@ -249,23 +255,23 @@ private class ColorCell extends Lst { * debugging only * @return volume in normalized L*a*b space */ - public float getVolume(boolean doVisualize) { + public double 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; + //double d; + double maxx = -Integer.MAX_VALUE; + double minx = Integer.MAX_VALUE; + double maxy = -Integer.MAX_VALUE; + double miny = Integer.MAX_VALUE; + double maxz = -Integer.MAX_VALUE; + double minz = Integer.MAX_VALUE; int n = size(); for (int i = n; --i >= 0;) { - P3 xyz = get(i); + P3d xyz = get(i); if (xyz.x < minx) minx = xyz.x; if (xyz.y < miny) @@ -279,9 +285,9 @@ public float getVolume(boolean doVisualize) { if (xyz.z > maxz) maxz = xyz.z; } - float dx = (maxx - minx); - float dy = (maxy - miny); - float dz = (maxz - minz); + double dx = (maxx - minx); + double dy = (maxy - miny); + double dz = (maxz - minz); // Jmol visualization only // if (doVisualize) { // P3 ptRGB = toRGB(center); @@ -296,8 +302,8 @@ public float getVolume(boolean doVisualize) { // 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 + //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; @@ -308,7 +314,7 @@ public float getVolume(boolean doVisualize) { // boolean isMain = (i < 0); // P3 lab = rgbToXyz(rgb, null); // xyzToLab(lab, lab); - // System.out.println("draw d" + index + (isMain ? "_" : "_" + i) + " width " + //System.out.println("draw d" + index + (isMain ? "_" : "_" + i) + " width " // + (isMain ? 1.0 : 0.2) + " " + lab // + " color " + rgb + (isMain ? " '" + -i + "'" : "")); // } @@ -319,12 +325,12 @@ public float getVolume(boolean doVisualize) { * @return RGB point * */ - protected P3 setColor() { + protected P3d setColor() { int count = size(); - center = new P3(); + center = new P3d(); for (int i = count; --i >= 0;) center.add(get(i)); - center.scale(1f / count); + center.scale(1d / count); // Jmol visualization only //volume = 0; //getVolume(true); @@ -350,13 +356,13 @@ protected boolean splitCell(Lst cells) { int newIndex = cells.size(); ColorCell newCell = new ColorCell(newIndex); cells.addLast(newCell); - float[][] ranges = new float[3][3]; + double[][] ranges = new double[3][3]; for (int ic = 0; ic < 3; ic++) { - float low = Float.MAX_VALUE; - float high = -Float.MAX_VALUE; + double low = Double.MAX_VALUE; + double high = -Double.MAX_VALUE; for (int i = n; --i >= 0;) { - P3 lab = get(i); - float v = (ic == 0 ? lab.x : ic == 1 ? lab.y : lab.z); + P3d lab = get(i); + double v = (ic == 0 ? lab.x : ic == 1 ? lab.y : lab.z); if (low > v) low = v; if (high < v) @@ -366,9 +372,9 @@ protected boolean splitCell(Lst cells) { ranges[1][ic] = high; ranges[2][ic] = high - low; } - float[] r = ranges[2]; + double[] 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; + double val = ranges[0][mode] + ranges[2][mode] / 2; volume = 0; // recalculate volume if needed switch (mode) { case 0: @@ -426,7 +432,7 @@ private void createPalette() { Map colorMap = new Hashtable(); bitsPerPixel = (nColors <= 2 ? 1 : nColors <= 4 ? 2 : nColors <= 16 ? 4 : 8); - palette = new P3[1 << bitsPerPixel]; + palette = new P3d[1 << bitsPerPixel]; for (int i = 0; i < nColors; i++) { ColorCell c = cells.get(i); colorMap.put( @@ -471,11 +477,11 @@ private Lst quantizeColors(Lst tempColors) { tempColors.clear(); if (n > 256) while ((n = cells.size()) < 256) { - float maxVol = 0; + double maxVol = 0; ColorCell maxCell = null; for (int i = n; --i >= 1;) { ColorCell c = cells.get(i); - float v = c.getVolume(false); + double v = c.getVolume(false); if (v > maxVol) { maxVol = v; maxCell = c; @@ -516,12 +522,12 @@ private int[] indexPixels(Lst cells, // this strip. // int w2 = width + 2; - P3[] errors = new P3[w2]; + P3d[] errors = new P3d[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; + P3d err = new P3d(); + P3d lab; int rgb; Map nearestCell = new Hashtable(); for (int i = 0, p = 0; i < height; ++i) { @@ -531,8 +537,8 @@ private int[] indexPixels(Lst cells, // leave as 0 continue; } - P3 pe = errors[p % w2]; - if (pe == null || pe.x == Float.MAX_VALUE) { + P3d pe = errors[p % w2]; + if (pe == null || pe.x == Double.MAX_VALUE) { lab = null; rgb = pixels[p]; } else { @@ -554,12 +560,12 @@ private int[] indexPixels(Lst cells, cell = nearestCell.get(key); if (cell == null) { // find nearest cell - float maxerr = Float.MAX_VALUE; + double maxerr = Double.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(); + double d = err.lengthSquared(); if (d < maxerr) { maxerr = d; cell = c; @@ -581,7 +587,7 @@ private int[] indexPixels(Lst cells, addError(err, 1, errors, p + width + 1, w2); } } - err.x = Float.MAX_VALUE; // used; flag for resetting to 0 + err.x = Double.MAX_VALUE; // used; flag for resetting to 0 } newPixels[p] = cell.index; } @@ -589,15 +595,15 @@ private int[] indexPixels(Lst cells, return newPixels; } - private void addError(P3 err, int f, P3[] errors, int p, int w2) { + private void addError(P3d err, int f, P3d[] errors, int p, int w2) { // GIMP will allow changing the background color. if (pixels[p] == backgroundColor) return; p %= w2; - P3 errp = errors[p]; + P3d errp = errors[p]; if (errp == null) - errp = errors[p] = new P3(); - else if (errp.x == Float.MAX_VALUE) // reuse + errp = errors[p] = new P3d(); + else if (errp.x == Double.MAX_VALUE) // reuse errp.set(0, 0, 0); errp.scaleAdd2(f / 16f, err, errp); } @@ -606,8 +612,8 @@ else if (errp.x == Float.MAX_VALUE) // reuse // these could be static, but that just makes for more JavaScript code - protected P3 toLABnorm(int rgb) { - P3 lab = P3.new3((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, rgb & 0xFF); + protected P3d toLABnorm(int rgb) { + P3d lab = CU.colorPtFromInt(rgb, null); rgbToXyz(lab, lab); xyzToLab(lab, lab); // normalize to 0-100 @@ -616,8 +622,8 @@ protected P3 toLABnorm(int rgb) { return lab; } - protected P3 toRGB(P3 lab) { - P3 xyz = P3.newP(lab); + protected P3d toRGB(P3d lab) { + P3d xyz = P3d.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; @@ -625,22 +631,22 @@ protected P3 toRGB(P3 lab) { return xyzToRgb(xyz, xyz); } - private static M3 xyz2rgb; - private static M3 rgb2xyz; + private static M3d xyz2rgb; + private static M3d rgb2xyz; static { - rgb2xyz = M3.newA9(new float[] { 0.4124f, 0.3576f, 0.1805f, 0.2126f, + rgb2xyz = M3d.newA9(new double[] { 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, + xyz2rgb = M3d.newA9(new double[] { 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) { + public P3d rgbToXyz(P3d rgb, P3d 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 = new P3d(); xyz.x = sxyz(rgb.x); xyz.y = sxyz(rgb.y); xyz.z = sxyz(rgb.z); @@ -648,17 +654,17 @@ public P3 rgbToXyz(P3 rgb, P3 xyz) { return xyz; } - private float sxyz(float x) { + private double sxyz(double x) { x /= 255; - return (float) (x <= 0.04045 ? x / 12.92 : Math.pow(((x + 0.055) / 1.055), + return (x <= 0.04045 ? x / 12.92 : Math.pow(((x + 0.055) / 1.055), 2.4)) * 100; } - public P3 xyzToRgb(P3 xyz, P3 rgb) { + public P3d xyzToRgb(P3d xyz, P3d 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 = new P3d(); rgb.setT(xyz); rgb.scale(0.01f); xyz2rgb.rotate(rgb); @@ -668,44 +674,44 @@ public P3 xyzToRgb(P3 xyz, P3 rgb) { return rgb; } - private float srgb(float x) { - return (float) (x > 0.0031308f ? (1.055 * Math.pow(x, 1.0 / 2.4)) - 0.055 + private double srgb(double x) { + return (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) { + public P3d xyzToLab(P3d xyz, P3d 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 = new P3d(); + double x = flab(xyz.x / 95.0429f); + double y = flab(xyz.y / 100); + double 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, + private double flab(double t) { + return (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) { + public P3d labToXyz(P3d lab, P3d 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 = new P3d(); xyz.setT(lab); - float y = (xyz.x + 16) / 116; - float x = xyz.y / 500 + y; - float z = y - xyz.z / 200; + double y = (xyz.x + 16) / 116; + double x = xyz.y / 500 + y; + double z = y - xyz.z / 200; xyz.x = fxyz(x) * 95.0429f; xyz.y = fxyz(y) * 100; xyz.z = fxyz(z) * 108.89f; @@ -713,12 +719,12 @@ public P3 labToXyz(P3 lab, P3 xyz) { return xyz; } - private float fxyz(float t) { - return (float) (t > 0.206896552 /* (24/116) */? t * t * t + private double fxyz(double t) { + return (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) { + private double clamp(double c, double min, double max) { c = (c < min ? min : c > max ? max : c); return (min == 0 ? Math.round(c) : c); } @@ -825,7 +831,7 @@ private void writeImage() { int packedFields = 0x80 | (interlaced ? 0x40 : 0) | (bitsPerPixel - 1); putByte(packedFields); int colorMapSize = 1 << bitsPerPixel; - P3 p = new P3(); + P3d p = new P3d(); for (int i = 0; i < colorMapSize; i++) { if (palette[i] != null) p = palette[i]; diff --git a/sources/net.sf.j2s.java.core/src/javajs/util/AjaxURLConnection.java b/sources/net.sf.j2s.java.core/src/javajs/util/AjaxURLConnection.java index 2b2abeed9..80d09ecb6 100644 --- a/sources/net.sf.j2s.java.core/src/javajs/util/AjaxURLConnection.java +++ b/sources/net.sf.j2s.java.core/src/javajs/util/AjaxURLConnection.java @@ -139,7 +139,7 @@ public Map> getHeaderFields() { * */ @SuppressWarnings("null") - private Object doAjax(boolean isBinary, Function whenDone) { + private Object doAjax(boolean isBinary, boolean isScript, Function whenDone) { getBytesOut(); J2SObjectInterface J2S = /** @j2sNative self.J2S || */ null; @@ -238,7 +238,7 @@ private Object doAjax(boolean isBinary, Function whenDone) { } } result = J2S.doAjax(myURL, postOut, bytesOut, info); - if (whenDone != null) + if (whenDone != null || isScript) return null; setJQueryResponseCodeFromJQuery(result); return result; @@ -410,9 +410,6 @@ public InputStream getInputStream() throws IOException { return is; responseCode = -1; is = getInputStreamAndResponse(false); - switch (responseCode) { - - } if (responseCode == HTTP_BAD_REQUEST) { throw new java.net.UnknownHostException(url.toString()); } else if (responseCode > HTTP_BAD_REQUEST && responseCode != 404) { @@ -462,7 +459,7 @@ private void getInputStreamAndResponseAsync(Function whenDone whenDone.apply(is); return; } - doAjax(true, new Function() { + doAjax(true, false, new Function() { @Override public Void apply(Object response) { @@ -490,7 +487,12 @@ private BufferedInputStream getInputStreamAndResponse(boolean allowNWError) { if (is != null || doCache() && (is = getCachedStream(allowNWError)) != null) { return is; } - is = attachStreamData(url, doAjax(ajax == null, null)); + + boolean isScript = /** @j2sNative this.ajax && (this.ajax.dataType == "script")||*/false; + Object result = doAjax(ajax == null, isScript, null); + if (isScript) + return Rdr.getBIS(new byte[0]); + is = attachStreamData(url, result); if (doCache() && is != null) { isNetworkError(is); setCachedStream(); @@ -645,8 +647,9 @@ public static BufferedInputStream attachStreamData(URL url, Object o) { /** * @return javajs.util.SB or byte[], depending upon the file type */ + @Deprecated public Object getContents() { - return doAjax(false, null); + return doAjax(false, false, null); } @Override diff --git a/sources/net.sf.j2s.java.core/src/javajs/util/CU.java b/sources/net.sf.j2s.java.core/src/javajs/util/CU.java index 52b90728c..80b6787e6 100644 --- a/sources/net.sf.j2s.java.core/src/javajs/util/CU.java +++ b/sources/net.sf.j2s.java.core/src/javajs/util/CU.java @@ -34,6 +34,7 @@ public static String toCSSString(GenericColor c) { } private final static String[] colorNames = { + "contrast", // fedcba "black", // 000000 "pewhite", // ffffff "pecyan", // 00ffff @@ -203,6 +204,7 @@ public static String toCSSString(GenericColor c) { private final static int[] colorArgbs = { //#FFFFC3 hover + 0xFFfedcba, // CONTRAST (colix = 3) 0xFF000000, // black // plus the PE chain colors 0xFFffffff, // pewhite @@ -456,11 +458,11 @@ public final static P3d colorPtFromInt(int color, P3d pt) { return pt; } - public static int colorPtToFFRGB(T3 pt) { - return colorTriadToFFRGB(pt.x, pt.y, pt.z); - } + public static int colorPtToFFRGB(T3d pt) { + return colorTriadToFFRGB(pt.x, pt.y, pt.z); + } - public static void toRGB3f(int c, double[] f) { + public static void toRGB3(int c, double[] f) { f[0] = ((c >> 16) & 0xFF) / 255f; // red f[1] = ((c >> 8) & 0xFF) / 255f; f[2] = (c & 0xFF) / 255f; diff --git a/sources/net.sf.j2s.java.core/src/javajs/util/CifDataParser.java b/sources/net.sf.j2s.java.core/src/javajs/util/CifDataParser.java index 5d613f1bc..57f4a6113 100644 --- a/sources/net.sf.j2s.java.core/src/javajs/util/CifDataParser.java +++ b/sources/net.sf.j2s.java.core/src/javajs/util/CifDataParser.java @@ -424,7 +424,8 @@ public String skipLoop(boolean doReport) throws Exception { while ((str = (String) getNextDataToken()) != null) { if (ret == null) continue; - ret.append(str).append(" "); + if (str.charAt(0) != 0) + ret.append(str).append(" "); if ((++m % n) == 0) ret.append("\n"); } diff --git a/sources/net.sf.j2s.java.core/src/javajs/util/Lst.java b/sources/net.sf.j2s.java.core/src/javajs/util/Lst.java index e7fdda5c0..3273ef897 100644 --- a/sources/net.sf.j2s.java.core/src/javajs/util/Lst.java +++ b/sources/net.sf.j2s.java.core/src/javajs/util/Lst.java @@ -41,8 +41,8 @@ public Lst() { super(); } - public boolean addLast(V v) { - return super.add(v); + public void addLast(V v) { + super.add(v); } public V removeItemAt(int location) { diff --git a/sources/net.sf.j2s.java.core/src/javajs/util/M34d.java b/sources/net.sf.j2s.java.core/src/javajs/util/M34d.java index f66b789d3..9e92b57eb 100644 --- a/sources/net.sf.j2s.java.core/src/javajs/util/M34d.java +++ b/sources/net.sf.j2s.java.core/src/javajs/util/M34d.java @@ -350,7 +350,7 @@ protected void mul33(double x) { m22 *= x; } - protected void transpose33() { + public void transpose33() { double tmp = m01; m01 = m10; m10 = tmp; diff --git a/sources/net.sf.j2s.java.core/src/javajs/util/MeasureD.java b/sources/net.sf.j2s.java.core/src/javajs/util/MeasureD.java index 8a8983d2c..226b742e2 100644 --- a/sources/net.sf.j2s.java.core/src/javajs/util/MeasureD.java +++ b/sources/net.sf.j2s.java.core/src/javajs/util/MeasureD.java @@ -47,7 +47,8 @@ public static double computeAngleABC(T3d pointA, T3d pointB, T3d pointC, boolean } public static double computeTorsion(T3d p1, T3d p2, T3d p3, T3d p4, boolean asDegrees) { - + if (p1.distanceSquared(p2) < 1e-10) + return 0; double ijx = p1.x - p2.x; double ijy = p1.y - p2.y; double ijz = p1.z - p2.z; diff --git a/sources/net.sf.j2s.java.core/src/javajs/util/PT.java b/sources/net.sf.j2s.java.core/src/javajs/util/PT.java index 99e9422b6..e191df3d1 100644 --- a/sources/net.sf.j2s.java.core/src/javajs/util/PT.java +++ b/sources/net.sf.j2s.java.core/src/javajs/util/PT.java @@ -827,7 +827,7 @@ else if (isStar1) int nq = 4; while (nq < sLen) { qqqq += qqqq; - nq += 4; + nq *= 2; } if (checkStar) { if (isStar0) { diff --git a/sources/net.sf.j2s.java.core/src/javax/swing/JMenuBar.java b/sources/net.sf.j2s.java.core/src/javax/swing/JMenuBar.java index a381d1b51..8ca104178 100644 --- a/sources/net.sf.j2s.java.core/src/javax/swing/JMenuBar.java +++ b/sources/net.sf.j2s.java.core/src/javax/swing/JMenuBar.java @@ -30,6 +30,8 @@ import java.util.Vector; +import javax.swing.border.EmptyBorder; + import java.awt.Component; import java.awt.Graphics; import java.awt.Insets; @@ -95,6 +97,7 @@ public class JMenuBar extends JComponent implements MenuElement */ public JMenuBar() { super(); + setBorder(new EmptyBorder(4, 4, 2, 4)); //setFocusTraversalKeysEnabled(false); setSelectionModel(new DefaultSingleSelectionModel()); updateUI(); diff --git a/sources/net.sf.j2s.java.core/src/sun/font/FontDesignMetrics.java b/sources/net.sf.j2s.java.core/src/sun/font/FontDesignMetrics.java index 9d2cbea28..d4a8a864d 100644 --- a/sources/net.sf.j2s.java.core/src/sun/font/FontDesignMetrics.java +++ b/sources/net.sf.j2s.java.core/src/sun/font/FontDesignMetrics.java @@ -30,12 +30,14 @@ import java.awt.Font; import java.awt.FontMetrics; +import java.awt.geom.Rectangle2D; //import java.awt.font.FontRenderContext; //import java.awt.geom.AffineTransform; //import sun.java2d.Disposer; //import sun.java2d.DisposerRecord; import java.util.Hashtable; +import swingjs.JSFontMetrics; import swingjs.JSToolkit; /* @@ -404,10 +406,10 @@ private void initMatrixAndMetrics() { // return frc; // } // - @Override - public int charWidth(char ch) { - // default metrics for compatibility with legacy code - return stringWidth("" + ch); +// @Override +// public int charWidth(char ch) { +// // default metrics for compatibility with legacy code +// return stringWidth("" + ch); // float w; // if (ch < 0x100) { // w = getLatinCharWidth(ch); @@ -416,8 +418,8 @@ public int charWidth(char ch) { // w = handleCharWidth(ch); // } // return (int)(0.5 + w); - } - +// } +// // public int charWidth(int ch) { // if (!Character.isValidCodePoint(ch)) { // ch = 0xffff; @@ -429,7 +431,7 @@ public int charWidth(char ch) { // } @Override - public int stringWidth(String str) { + public int stringWidth(String str) { return (int) (0.5 + getWidth(str)); } @@ -481,31 +483,6 @@ public int charsWidth(char data[], int off, int len) { return (int) (0.5 + width); } - /** - * Gets the advance widths of the first 256 characters in the - * Font. The advance is the - * distance from the leftmost point to the rightmost point on the - * character's baseline. Note that the advance of a - * String is not necessarily the sum of the advances - * of its characters. - * @return an array storing the advance widths of the - * characters in the Font - * described by this FontMetrics object. - */ - // More efficient than base class implementation - reuses existing cache - @Override - public int[] getWidths() { - int[] widths = new int[256]; -// for (char ch = 0 ; ch < 256 ; ch++) { -// float w = advCache[ch]; -// if (w == UNKNOWN_WIDTH) { -// w = advCache[ch] = handleCharWidth(ch); -// } -// widths[ch] = (int) (0.5 + w); -// } - return widths; - } - /* * Returns the typographic ascent of the font. This is the maximum distance * glyphs in this font extend above the base line (measured in typographic @@ -527,12 +504,15 @@ public int getDescent() { return (int)(roundingUpValue + descent); } + //JSFontMetrics 秘fm; + private void _getMetrics() { if (ascent >= 0) return; - ascent = font.getFontMetrics().getAscent(); - descent = font.getFontMetrics().getDescent(); - leading = font.getFontMetrics().getLeading(); +// 秘fm = new JSFontMetrics(font); + ascent = JSFontMetrics.fontAscent(font); + descent = JSFontMetrics.fontDescent(font); + leading = JSFontMetrics.fontLeading(font); } @Override @@ -562,20 +542,120 @@ public int getHeight() { return height; } +// public JSFontMetrics 秘getJSMetrics() { +// _getMetrics(); +// return 秘fm; +// } + + /** + * The length of the metrics array must be >= 8. This method will store the + * following elements in that array before returning: metrics[0]: ascent + * metrics[1]: descent metrics[2]: leading metrics[3]: max advance metrics[4]: + * strikethrough offset metrics[5]: strikethrough thickness metrics[6]: + * underline offset metrics[7]: underline thickness + */ + public void 秘fillMetrics(float[] metrics) { + _getMetrics(); + metrics[0] = ascent; + metrics[1] = descent; + metrics[2] = leading; + metrics[3] = 0; + if (metrics.length >= 8) { + metrics[4] = font.getSize2D() / -4f; + metrics[5] = metrics[6] = metrics[7] = 1; + } + } + + public Rectangle2D 秘getStringBounds(String s) { + _getMetrics(); + return new Rectangle2D.Float(0, -ascent, stringWidth(s), ascent + descent + leading); + } + + /** + * The actual {@link Font} from which the font metrics are created. This cannot + * be null. + * + * @serial + * @see #getFont() + */ + private final Font font; + + private float[] fwidths; + private int[] iwidths; + private int FIRST_PRINTABLE = 32; + + @Override + public int charWidth(char pt) { + return (pt < 256 ? (int)(0.5 + getWidthsFloat()[pt]) : stringWidth("" + pt)); + } + @Override public int charWidth(int codePoint) { // from FontMetrics if (!Character.isValidCodePoint(codePoint)) { codePoint = 0xffff; // substitute missing glyph width } - if (codePoint < 256) { return getWidths()[codePoint]; - } else { - char[] buffer = new char[2]; - int len = Character.toChars(codePoint, buffer, 0); - return charsWidth(buffer, 0, len); } + String s = /** @j2sNative String.fromCharCode(codePoint) || */ + null; + return stringWidth(s); + } + +// public int charWidth(int pt) { +// /** +// * could be a character ?? really ? how? +// * +// * @j2sNative +// * +// * var spt; return ((pt + 0 == pt ? pt : (pt = (spt = +// * pt).charCodeAt(0))) < 256 ? (this.getWidthsFloat$()[pt] | 0) : +// * this.stringWidth$S(isChar ? spt : String.fromCharCode(pt))); +// */ +// } + + /** + * Gets the advance widths of the first 256 characters in the + * Font. The advance is the + * distance from the leftmost point to the rightmost point on the + * character's baseline. Note that the advance of a + * String is not necessarily the sum of the advances + * of its characters. + * @return an array storing the advance widths of the + * characters in the Font + * described by this FontMetrics object. + */ + // More efficient than base class implementation - reuses existing cache + @Override + public int[] getWidths() { + if (iwidths != null) + return iwidths; + iwidths = new int[256]; + getWidthsFloat(); + for (int ch = FIRST_PRINTABLE; ch < 256; ch++) { + iwidths[ch] = (int) fwidths[ch]; + } + return iwidths; } + public float[] getWidthsFloat() { + if (fwidths != null) + return fwidths; + fwidths = new float[256]; + for (int ch = FIRST_PRINTABLE; ch < 256; ch++) { + fwidths[ch] = JSToolkit.getStringWidth(null, font, "" + (char) ch); + } + return fwidths; + } + + public float getFloatWidth(int ch) { + String s = (/** @j2sNative 1 ? String.fromCharCode(ch) : */ + ""); + return JSToolkit.getStringWidth(null, font, s); + } + + + + } diff --git a/sources/net.sf.j2s.java.core/src/sun/font/FontManager.java b/sources/net.sf.j2s.java.core/src/sun/font/FontManager.java index 5c6953213..fa4ead62b 100644 --- a/sources/net.sf.j2s.java.core/src/sun/font/FontManager.java +++ b/sources/net.sf.j2s.java.core/src/sun/font/FontManager.java @@ -139,4 +139,9 @@ public interface FontManager { */ public void preferProportionalFonts(); + public static boolean isComplexText(char[] chars, int beginIndex, int limit) { + // TODO Auto-generated method stub + return false; + } + } diff --git a/sources/net.sf.j2s.java.core/src/sun/font/FontUtilities.java b/sources/net.sf.j2s.java.core/src/sun/font/FontUtilities.java index 7785bc297..bca075e07 100644 --- a/sources/net.sf.j2s.java.core/src/sun/font/FontUtilities.java +++ b/sources/net.sf.j2s.java.core/src/sun/font/FontUtilities.java @@ -174,53 +174,55 @@ public static Font2D getFont2D(Font font) { return FontAccess.getFontAccess().getFont2D(font); } -// /** -// * If there is anything in the text which triggers a case -// * where char->glyph does not map 1:1 in straightforward -// * left->right ordering, then this method returns true. -// * Scripts which might require it but are not treated as such -// * due to JDK implementations will not return true. -// * ie a 'true' return is an indication of the treatment by -// * the implementation. -// * Whether supplementary characters should be considered is dependent -// * on the needs of the caller. Since this method accepts the 'char' type -// * then such chars are always represented by a pair. From a rendering -// * perspective these will all (in the cases I know of) still be one -// * unicode character -> one glyph. But if a caller is using this to -// * discover any case where it cannot make naive assumptions about -// * the number of chars, and how to index through them, then it may -// * need the option to have a 'true' return in such a case. -// */ -// public static boolean isComplexText(char [] chs, int start, int limit) { -// -// for (int i = start; i < limit; i++) { -// if (chs[i] < MIN_LAYOUT_CHARCODE) { -// continue; -// } -// else if (isNonSimpleChar(chs[i])) { -// return true; -// } -// } -// return false; -// } -// -// /* This is almost the same as the method above, except it takes a -// * char which means it may include undecoded surrogate pairs. -// * The distinction is made so that code which needs to identify all -// * cases in which we do not have a simple mapping from -// * char->unicode character->glyph can be be identified. -// * For example measurement cannot simply sum advances of 'chars', -// * the caret in editable text cannot advance one 'char' at a time, etc. -// * These callers really are asking for more than whether 'layout' -// * needs to be run, they need to know if they can assume 1->1 -// * char->glyph mapping. -// */ -// public static boolean isNonSimpleChar(char ch) { -// return -// isComplexCharCode(ch) || -// (ch >= CharToGlyphMapper.HI_SURROGATE_START && -// ch <= CharToGlyphMapper.LO_SURROGATE_END); -// } + /** + * If there is anything in the text which triggers a case + * where char->glyph does not map 1:1 in straightforward + * left->right ordering, then this method returns true. + * Scripts which might require it but are not treated as such + * due to JDK implementations will not return true. + * ie a 'true' return is an indication of the treatment by + * the implementation. + * Whether supplementary characters should be considered is dependent + * on the needs of the caller. Since this method accepts the 'char' type + * then such chars are always represented by a pair. From a rendering + * perspective these will all (in the cases I know of) still be one + * unicode character -> one glyph. But if a caller is using this to + * discover any case where it cannot make naive assumptions about + * the number of chars, and how to index through them, then it may + * need the option to have a 'true' return in such a case. + * + * @j2sIgnore + */ + public static boolean isComplexText(char [] chs, int start, int limit) { + + for (int i = start; i < limit; i++) { + if (chs[i] < MIN_LAYOUT_CHARCODE) { + continue; + } + else if (isNonSimpleChar(chs[i])) { + return true; + } + } + return false; + } + + /* This is almost the same as the method above, except it takes a + * char which means it may include undecoded surrogate pairs. + * The distinction is made so that code which needs to identify all + * cases in which we do not have a simple mapping from + * char->unicode character->glyph can be be identified. + * For example measurement cannot simply sum advances of 'chars', + * the caret in editable text cannot advance one 'char' at a time, etc. + * These callers really are asking for more than whether 'layout' + * needs to be run, they need to know if they can assume 1->1 + * char->glyph mapping. + */ + public static boolean isNonSimpleChar(char ch) { + return + isComplexCharCode(ch) || + (ch >= CharToGlyphMapper.HI_SURROGATE_START && + ch <= CharToGlyphMapper.LO_SURROGATE_END); + } /* If the character code falls into any of a number of unicode ranges * where we know that simple left->right layout mapping chars to glyphs diff --git a/sources/net.sf.j2s.java.core/src/sun/font/StandardGlyphVector.java b/sources/net.sf.j2s.java.core/src/sun/font/StandardGlyphVector.java index ea02f93d4..d9d96ac44 100644 --- a/sources/net.sf.j2s.java.core/src/sun/font/StandardGlyphVector.java +++ b/sources/net.sf.j2s.java.core/src/sun/font/StandardGlyphVector.java @@ -44,8 +44,10 @@ import java.text.CharacterIterator; import sun.awt.SunHints; +import sun.font.GlyphLayout.GVData; import sun.java2d.loops.FontInfo; import swingjs.JSFontMetrics; +import swingjs.JSToolkit; import swingjs.JSUtil; /** @@ -1155,9 +1157,7 @@ private void init(Font font, char[] text, int start, int count, glyphs = new int[count]; // hmmm /* Glyphs obtained here are already validated by the font */ userGlyphs = glyphs; - - - //font2D.getMapper(). + JSFontMetrics.charsToGlyphs(count, text, glyphs); } @@ -1221,10 +1221,8 @@ private Shape getGlyphsOutline(int start, int count, float x, float y) { setFRCTX(); initPositions(); - double h0 = -font.getFontMetrics().getDescent(); - double h1 = font.getFontMetrics().getHeight() + h0; - - return new Rectangle2D.Double(x + positions[start * 2], y + positions[start * 2 + 1] + h0, positions[count * 2], positions[count * 2 + 1] + h1); + float h = JSFontMetrics.fontAscent(font); + return new Rectangle2D.Float(x + positions[start * 2], y + positions[start * 2 + 1] - h, positions[count * 2], positions[count * 2 + 1] + h); // GeneralPath result = new GeneralPath(GeneralPath.WIND_NON_ZERO); // for (int i = start, e = start + count, n = start * 2; i < e; ++i, n += 2) { // float px = x + positions[n]; @@ -1782,6 +1780,54 @@ static GlyphStrike create(StandardGlyphVector sgv, AffineTransform dtx, AffineTr // return new GlyphStrike(sgv, null, dx, dy); } + /** + * Only used by StandardGlyphVector. + * + * Takes the place of nativeLayout in SunLayoutEngine. + * + * @param font2d actually just Font in JavaScript; there is no Font2D + * @param mat + * @param gmask + * @param baseIndex + * @param tr + * @param typo_flags + * @param pt + * @param data + */ + public static void layout(Font2D font2d, float[] mat, int gmask, int baseIndex, TextRecord tr, int typo_flags, + Point2D.Float pt, GVData data) { + Font f = (Font) (Object) font2d; + FontDesignMetrics fm = (FontDesignMetrics) f.getFontMetrics(); + // TODO: scaling? rotation? + int g2 = 0; + float x = 0, y = 0, w; // I suspect all fonts are( laid out linearly in x. Maybe not? + for (int g = 0, p = tr.start; p < tr.limit; p++, g++) { + int ch = tr.text[p]; + if (Character.isHighSurrogate((char) ch) && p < tr.limit - 1 && Character.isLowSurrogate(tr.text[++p])) { + // rare case + ch = Character.toCodePoint((char) ch, tr.text[p]); // inc + w = fm.getFloatWidth(ch); + } else if (ch > 255) { + // unicode value + w = fm.getFloatWidth(ch); + } else { + w = fm.getWidthsFloat()[ch]; + + } + + data._indices[g] = p + baseIndex; + data._positions[g2++] = x; + data._positions[g2++] = y; + data._glyphs[g] = ch; + data._count++; + x += w; + } + data._positions[g2++] = x; + data._positions[g2++] = y; + + } + + private GlyphStrike(StandardGlyphVector sgv, FontStrike strike, float dx, float dy) { this.sgv = sgv; this.strike = strike; diff --git a/sources/net.sf.j2s.java.core/src/sun/font/SunLayoutEngine.java b/sources/net.sf.j2s.java.core/src/sun/font/SunLayoutEngine.java index 9ca4e01ca..b4a6f8bfe 100644 --- a/sources/net.sf.j2s.java.core/src/sun/font/SunLayoutEngine.java +++ b/sources/net.sf.j2s.java.core/src/sun/font/SunLayoutEngine.java @@ -32,6 +32,8 @@ import sun.font.GlyphLayout.*; import swingjs.JSFontMetrics; + +import java.awt.Font; import java.awt.geom.Point2D; import java.util.concurrent.ConcurrentHashMap; @@ -156,8 +158,10 @@ public void layout(FontStrikeDesc desc, float[] mat, int gmask, //SwingJS Note: This is the method in c++ that sets _count, along with _indices, _positions, and _glyphs - JSFontMetrics.layout(key.font(), mat, gmask, baseIndex, tr, typo_flags, pt, data); + layout(key.font(), mat, gmask, baseIndex, tr, typo_flags, pt, data); + + // Font2D font = key.font(); // FontStrike strike = font.getStrike(desc); // long layoutTables = 0; @@ -169,7 +173,57 @@ public void layout(FontStrikeDesc desc, float[] mat, int gmask, // key.script(), key.lang(), typo_flags, pt, data, // font.getUnitsPerEm(), layoutTables); } -// + + /** + * Only used by StandardGlyphVector. + * + * Takes the place of nativeLayout in SunLayoutEngine. + * + * @param font2d actually just Font in JavaScript; there is no Font2D + * @param mat + * @param gmask + * @param baseIndex + * @param tr + * @param typo_flags + * @param pt + * @param data + */ + static void layout(Font2D font2d, float[] mat, int gmask, int baseIndex, TextRecord tr, int typo_flags, + Point2D.Float pt, GVData data) { + Font f = (Font) (Object) font2d; + FontDesignMetrics fm = (FontDesignMetrics) f.getFontMetrics(); + // TODO: scaling? rotation? + int g2 = 0; + float x = 0, y = 0, w; // I suspect all fonts are( laid out linearly in x. Maybe not? + for (int g = 0, p = tr.start; p < tr.limit; p++, g++) { + int ch = tr.text[p]; + if (Character.isHighSurrogate((char) ch) && p < tr.limit - 1 && Character.isLowSurrogate(tr.text[++p])) { + // rare case + ch = Character.toCodePoint((char) ch, tr.text[p]); // inc + w = fm.getFloatWidth(ch); + } else if (ch > 255) { + // unicode value + w = fm.getFloatWidth(ch); + } else { + w = fm.getWidthsFloat()[ch]; + + } + + data._indices[g] = p + baseIndex; + data._positions[g2++] = x; + data._positions[g2++] = y; + data._glyphs[g] = ch; + data._count++; + x += w; + } + data._positions[g2++] = x; + data._positions[g2++] = y; + + } + + + + // // private static native void // nativeLayout(Font2D font, FontStrike strike, float[] mat, int gmask, // int baseIndex, char[] chars, int offset, int limit, diff --git a/sources/net.sf.j2s.java.core/src/sun/swing/SwingUtilities2.java b/sources/net.sf.j2s.java.core/src/sun/swing/SwingUtilities2.java index 46ebb1ddf..6fb9192ed 100644 --- a/sources/net.sf.j2s.java.core/src/sun/swing/SwingUtilities2.java +++ b/sources/net.sf.j2s.java.core/src/sun/swing/SwingUtilities2.java @@ -46,6 +46,7 @@ import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; import java.lang.ref.SoftReference; +import java.text.AttributedCharacterIterator; import java.text.AttributedString; import java.util.HashMap; import java.util.HashSet; @@ -88,6 +89,8 @@ import javax.swing.tree.TreeModel; import javax.swing.tree.TreePath; +import sun.font.FontDesignMetrics; + /** * A collection of utility methods for Swing. *

@@ -141,8 +144,8 @@ public class SwingUtilities2 { /* Presently this class assumes default fractional metrics. * This may need to change to emulate future platform L&Fs. */ - public static class AATextInfo { - +// public static class AATextInfo { +// // private static AATextInfo getAATextInfoFromMap(Map hints) { // // Object aaHint = hints.get(KEY_TEXT_ANTIALIASING); @@ -156,22 +159,22 @@ public static class AATextInfo { // return new AATextInfo(aaHint, 0);//(Integer)contHint); // } // } - - public static AATextInfo getAATextInfo(boolean lafCondition) { -// SunToolkit.setAAFontSettingsCondition(lafCondition); -// Toolkit tk = Toolkit.getDefaultToolkit(); -// Object map = tk.getDesktopProperty(SunToolkit.DESKTOPFONTHINTS); -// if (map instanceof Map) { -// return getAATextInfoFromMap((Map)map); -// } else { - return null; -// } - } - - Object aaHint; - Integer lcdContrastHint; - FontRenderContext frc; - +// +//// public static AATextInfo getAATextInfo(boolean lafCondition) { +//// SunToolkit.setAAFontSettingsCondition(lafCondition); +//// Toolkit tk = Toolkit.getDefaultToolkit(); +//// Object map = tk.getDesktopProperty(SunToolkit.DESKTOPFONTHINTS); +//// if (map instanceof Map) { +//// return getAATextInfoFromMap((Map)map); +//// } else { +//// return null; +//// } +//// } +//// +// Object aaHint; +// Integer lcdContrastHint; +// FontRenderContext frc; +// // /* These are rarely constructed objects, and only when a complete // * UI is being updated, so the cost of the tests here is minimal // * and saves tests elsewhere. @@ -190,7 +193,7 @@ public static AATextInfo getAATextInfo(boolean lafCondition) { // this.frc = new FontRenderContext(null, aaHint, // VALUE_FRACTIONALMETRICS_DEFAULT); // } - } +// } /** * Key used in client properties used to indicate that the @@ -246,13 +249,15 @@ public static final boolean isComplexLayout(char[] text, int start, int limit) { * specified component. */ public static AATextInfo drawTextAntialiased(JComponent c) { - if (c != null) { - /* a non-null property implies some form of AA requested */ - return (AATextInfo)c.getClientProperty(AA_TEXT_PROPERTY_KEY); - } +// if (c != null) { +// /* a non-null property implies some form of AA requested */ +// return (AATextInfo)c.getClientProperty(AA_TEXT_PROPERTY_KEY); +// } // No component, assume aa is off return null; } + + class AATextInfo {}; /** * Returns the left side bearing of the first character of string. The @@ -533,6 +538,9 @@ public static String clipString(JComponent c, FontMetrics fm, /** + * SwingJS -- no need for antialiasing text -- we always do that + * SwingJS -- no need for printing + * * Draws the string at the specified location. * * @param c JComponent that will display the string, may be null @@ -802,22 +810,23 @@ public static void adjustFocus(JComponent c) { } } -// /** -// * The following draw functions have the same semantic as the -// * Graphics methods with the same names. -// * -// * this is used for printing -// */ -// public static int drawChars(JComponent c, Graphics g, -// char[] data, -// int offset, -// int length, -// int x, -// int y) { -// if ( length <= 0 ) { //no need to paint empty strings -// return x; -// } -// int nextX = x + getFontMetrics(c, g).charsWidth(data, offset, length); + /** + * SwingJS - ignoring printing; all text already antialiased + * The following draw functions have the same semantic as the + * Graphics methods with the same names. + * + * this is used for printing + */ + public static int drawChars(JComponent c, Graphics g, + char[] data, + int offset, + int length, + int x, + int y) { + if ( length <= 0 ) { //no need to paint empty strings + return x; + } + int nextX = x + getFontMetrics(c, g).charsWidth(data, offset, length); // if (isPrinting(g)) { // Graphics2D g2d = getGraphics2D(g); // if (g2d != null) { @@ -883,39 +892,39 @@ public static void adjustFocus(JComponent c) { // } // } // else { -// g.drawChars(data, offset, length, x, y); + g.drawChars(data, offset, length, x, y); // } -// return nextX; -// } -// -// /* -// * see documentation for drawChars -// * returns the advance -// */ -// public static float drawString(JComponent c, Graphics g, -// AttributedCharacterIterator iterator, -// int x, -// int y) { -// -// float retVal; -// boolean isPrinting = isPrinting(g); -// Color col = g.getColor(); -// -// if (isPrinting) { -// /* Use alternate print color if specified */ -// if (col instanceof PrintColorUIResource) { -// g.setColor(((PrintColorUIResource)col).getPrintColor()); -// } -// } -// -// Graphics2D g2d = getGraphics2D(g); -// if (g2d == null) { -// g.drawString(iterator,x,y); //for the cases where advance -// //matters it should not happen -// retVal = x; -// -// } else { -// FontRenderContext frc; + return nextX; + } + + /* + * see documentation for drawChars + * returns the advance + */ + public static float drawString(JComponent c, Graphics g, + AttributedCharacterIterator iterator, + int x, + int y) { + + float retVal; + boolean isPrinting = isPrinting(g); + Color col = g.getColor(); + + if (isPrinting) { + /* Use alternate print color if specified */ + if (col instanceof PrintColorUIResource) { + g.setColor(((PrintColorUIResource)col).getPrintColor()); + } + } + + Graphics2D g2d = getGraphics2D(g); + if (g2d == null) { + g.drawString(iterator,x,y); //for the cases where advance + //matters it should not happen + retVal = x; + + } else { + FontRenderContext frc; // if (isPrinting) { // frc = getFontRenderContext(c); // if (frc.isAntiAliased() || frc.usesFractionalMetrics()) { @@ -924,73 +933,73 @@ public static void adjustFocus(JComponent c) { // } else if ((frc = getFRCProperty(c)) != null) { // /* frc = frc; ! */ // } else { -// frc = g2d.getFontRenderContext(); -// } -// TextLayout layout = new TextLayout(iterator, frc); -// if (isPrinting) { -// FontRenderContext deviceFRC = g2d.getFontRenderContext(); -// if (!isFontRenderContextPrintCompatible(frc, deviceFRC)) { -// float screenWidth = layout.getAdvance(); -// layout = new TextLayout(iterator, deviceFRC); -// layout = layout.getJustifiedLayout(screenWidth); -// } -// } -// layout.draw(g2d, x, y); -// retVal = layout.getAdvance(); -// } -// -// if (isPrinting) { -// g.setColor(col); -// } -// -// return retVal; -// } + frc = g2d.getFontRenderContext(); + // } + TextLayout layout = new TextLayout(iterator, frc); + if (isPrinting) { + FontRenderContext deviceFRC = g2d.getFontRenderContext(); + if (!isFontRenderContextPrintCompatible(frc, deviceFRC)) { + float screenWidth = layout.getAdvance(); + layout = new TextLayout(iterator, deviceFRC); + layout = layout.getJustifiedLayout(screenWidth); + } + } + layout.draw(g2d, x, y); + retVal = layout.getAdvance(); + } -// /* -// * Checks if two given FontRenderContexts are compatible for printing. -// * We can't just use equals as we want to exclude from the comparison : -// * + whether AA is set as irrelevant for printing and shouldn't affect -// * printed metrics anyway -// * + any translation component in the transform of either FRC, as it -// * does not affect metrics. -// * Compatible means no special handling needed for text painting -// */ -// private static boolean -// isFontRenderContextPrintCompatible(FontRenderContext frc1, -// FontRenderContext frc2) { -// -// if (frc1 == frc2) { -// return true; -// } -// -// if (frc1 == null || frc2 == null) { // not supposed to happen -// return false; -// } -// -// if (frc1.getFractionalMetricsHint() != -// frc2.getFractionalMetricsHint()) { -// return false; -// } -// -// /* If both are identity, return true */ -// if (!frc1.isTransformed() && !frc2.isTransformed()) { -// return true; -// } -// -// /* That's the end of the cheap tests, need to get and compare -// * the transform matrices. We don't care about the translation -// * components, so return true if they are otherwise identical. -// */ -// double[] mat1 = new double[4]; -// double[] mat2 = new double[4]; -// frc1.getTransform().getMatrix(mat1); -// frc2.getTransform().getMatrix(mat2); -// return -// mat1[0] == mat2[0] && -// mat1[1] == mat2[1] && -// mat1[2] == mat2[2] && -// mat1[3] == mat2[3]; -// } + if (isPrinting) { + g.setColor(col); + } + + return retVal; + } + + /* + * Checks if two given FontRenderContexts are compatible for printing. + * We can't just use equals as we want to exclude from the comparison : + * + whether AA is set as irrelevant for printing and shouldn't affect + * printed metrics anyway + * + any translation component in the transform of either FRC, as it + * does not affect metrics. + * Compatible means no special handling needed for text painting + */ + private static boolean + isFontRenderContextPrintCompatible(FontRenderContext frc1, + FontRenderContext frc2) { + + if (frc1 == frc2) { + return true; + } + + if (frc1 == null || frc2 == null) { // not supposed to happen + return false; + } + + if (frc1.getFractionalMetricsHint() != + frc2.getFractionalMetricsHint()) { + return false; + } + + /* If both are identity, return true */ + if (!frc1.isTransformed() && !frc2.isTransformed()) { + return true; + } + + /* That's the end of the cheap tests, need to get and compare + * the transform matrices. We don't care about the translation + * components, so return true if they are otherwise identical. + */ + double[] mat1 = new double[4]; + double[] mat2 = new double[4]; + frc1.getTransform().getMatrix(mat1); + frc2.getTransform().getMatrix(mat2); + return + mat1[0] == mat2[0] && + mat1[1] == mat2[1] && + mat1[2] == mat2[2] && + mat1[3] == mat2[3]; + } /* * Tries it best to get Graphics2D out of the given Graphics @@ -1034,21 +1043,21 @@ private static FontRenderContext getFontRenderContext(Component c, FontMetrics f : getFontRenderContext(c); } -// /* -// * This method is to be used only for JComponent.getFontMetrics. -// * In all other places to get FontMetrics we need to use -// * JComponent.getFontMetrics. -// * -// */ -// public static FontMetrics getFontMetrics(JComponent c, Font font) { -//// FontRenderContext frc = DEFAULT_FRC;//getFRCProperty(c); -//// if (frc == null) { -//// frc = DEFAULT_FRC; -//// } -// return FontDesignMetrics.getMetrics(font);//, frc); -// } + /* + * This method is to be used only for JComponent.getFontMetrics. + * In all other places to get FontMetrics we need to use + * JComponent.getFontMetrics. + * + */ + public static FontMetrics getFontMetrics(JComponent c, Font font) { +// FontRenderContext //frc = getFRCProperty(c); +// if (frc == null) { +// frc = DEFAULT_FRC; + // } + return FontDesignMetrics.getMetrics(font); // , frc + } + -// // /* Get any FontRenderContext associated with a JComponent // * - may return null // */ @@ -1062,7 +1071,7 @@ private static FontRenderContext getFontRenderContext(Component c, FontMetrics f // } // return null; // } - +// /* * returns true if the Graphics is print Graphics * false otherwise @@ -1113,7 +1122,7 @@ private static class BearingCacheEntry { private FontRenderContext frc; private Map cache; // Used for the creation of a GlyphVector - private static final char[] oneChar = new char[1]; +// private static final char[] oneChar = new char[1]; public BearingCacheEntry(FontMetrics fontMetrics) { this.fontMetrics = fontMetrics; @@ -1190,7 +1199,8 @@ private short calcBearing(char aChar) { } - public boolean equals(Object entry) { + @Override + public boolean equals(Object entry) { if (entry == this) { return true; } @@ -1202,7 +1212,8 @@ public boolean equals(Object entry) { frc.equals(oEntry.frc)); } - public int hashCode() { + @Override + public int hashCode() { int result = 17; if (font != null) { result = 37 * result + font.hashCode(); diff --git a/sources/net.sf.j2s.java.core/src/sun/util/calendar/AbstractCalendar.java b/sources/net.sf.j2s.java.core/src/sun/util/calendar/AbstractCalendar.java index b3affa4ff..2e2b42c8c 100644 --- a/sources/net.sf.j2s.java.core/src/sun/util/calendar/AbstractCalendar.java +++ b/sources/net.sf.j2s.java.core/src/sun/util/calendar/AbstractCalendar.java @@ -67,7 +67,7 @@ protected AbstractCalendar() { public Era getEra(String eraName) { if (eras != null) { for (int i = 0; i < eras.length; i++) { - if (eras[i].equals(eraName)) { + if (eras[i].getName().equals(eraName)) { return eras[i]; } } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSFontMetrics.java b/sources/net.sf.j2s.java.core/src/swingjs/JSFontMetrics.java index b691fbef5..0a23b92a1 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSFontMetrics.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSFontMetrics.java @@ -1,6 +1,5 @@ package swingjs; - import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; @@ -11,277 +10,80 @@ import java.text.CharacterIterator; import sun.font.Font2D; +import sun.font.FontDesignMetrics; import sun.font.GlyphLayout.GVData; import sun.font.TextRecord; -public class JSFontMetrics extends FontMetrics { - - private float[] fwidths; - private int[] iwidths; - private int FIRST_PRINTABLE = 32; - - public JSFontMetrics() { - super(null); - } - - public void setFont(Font f) { - font = f; - } - - /** - * Determines the standard leading of the Font described - * by this FontMetrics object. The standard leading, or interline - * spacing, is the logical amount of space to be reserved between the descent of - * one line of text and the ascent of the next line. The height metric is - * calculated to include this extra space. - * - * @return the standard leading of the Font. - * @see #getHeight() - * @see #getAscent() - * @see #getDescent() - */ - @Override - public int getLeading() { - return (int) fontLeading(font); - } - - private static float fontLeading(Font font) { - return font.getSize() / 20f + 1; - } - - /** - * Determines the font ascent of the Font described by - * this FontMetrics object. The font ascent is the distance from - * the font's baseline to the top of most alphanumeric characters. Some - * characters in the Font might extend above the font ascent line. - * - * @return the font ascent of the Font. - * @see #getMaxAscent() - */ - @Override - public int getAscent() { - return (int) fontAscent(font); - } - - private static float fontAscent(Font font) { - return font.getSize(); - } - +/** + * This class holds a set of static float methods that are accessed by sun.font.FontDesignMetrics, + * sun.font.StandardGlyphVector, and + * and + * + * + * @author hanso + * + */ +public class JSFontMetrics { + + private JSFontMetrics() {} + /** - * Determines the font descent of the Font described by - * this FontMetrics object. The font descent is the distance from - * the font's baseline to the bottom of most alphanumeric characters with - * descenders. Some characters in the Font might extend below the - * font descent line. + * Use simple linear relationship found using Java and a range of fonts. * - * @return the font descent of the Font. - * @see #getMaxDescent() + * @param font + * @return */ - @Override - public int getDescent() { - return (int) fontDescent(font); - } - - private static float fontDescent(Font font) { - return font.getSize() / 4f + 1; - } - - @Override - public int charWidth(char pt) { - return (pt < 256 ? (int) getWidthsFloat()[pt] : stringWidth("" + pt)); - } - - @Override - public int charWidth(int pt) { - /** - * could be a character - * - * @j2sNative - * - * var spt; return ((pt + 0 == pt ? pt : (pt = (spt = - * pt).charCodeAt(0))) < 256 ? (this.getWidthsFloat$()[pt] | 0) : - * this.stringWidth$S(isChar ? spt : String.fromCharCode(pt))); - */ - { - return (pt < 256 ? (int) getWidthsFloat()[pt] : stringWidth("" + (char) pt)); - } - } - - @Override - public int stringWidth(String s) { - return (int) JSToolkit.getStringWidth(null, font, s); - } - - @Override - public int[] getWidths() { - if (iwidths != null) - return iwidths; - iwidths = new int[256]; - getWidthsFloat(); - for (int ch = FIRST_PRINTABLE; ch < 256; ch++) { - iwidths[ch] = (int) fwidths[ch]; - } - return iwidths; - } - - public float[] getWidthsFloat() { - if (fwidths != null) - return fwidths; - fwidths = new float[256]; - for (int ch = FIRST_PRINTABLE; ch < 256; ch++) { - fwidths[ch] = JSToolkit.getStringWidth(null, font, "" + (char) ch); + public static float fontLeading(Font font) { + // leading + // is exact for sizes 6 to 50 + switch (font.getName()) { + default: + case "SansSerif": + case "Dialog": + return font.getSize2D() * 0.0327f; + case "Serif": + return font.getSize2D() * 0.0425f; + case "Monospaced": + return 0; } - return fwidths; - } - - public float getFloatWidth(int ch) { - String s = (/** @j2sNative 1 ? String.fromCharCode(ch) : */"" ); - return JSToolkit.getStringWidth(null, font, s); } /** - * Returns the {@link LineMetrics} object for the specified String - * in the specified {@link Graphics} context. + * Use simple linear relationship found using Java and a range of fonts. * - * @param str the specified String - * @param context the specified Graphics context - * @return a LineMetrics object created with the specified - * String and Graphics context. - * @see java.awt.Font#getLineMetrics(String, FontRenderContext) + * @param font + * @return */ - public LineMetrics getLineMetrics(String str, Graphics context) { - return font.getLineMetrics(str, getFontRenderContext()); + public static float fontAscent(Font font) { + // is exact for 6-50 + return font.getSize2D() * 1.005371f; } /** - * Returns the {@link LineMetrics} object for the specified String - * in the specified {@link Graphics} context. + * Use simple linear relationship found using Java and a range of fonts. * - * @param str the specified String - * @param beginIndex the initial offset of str - * @param limit the end offset of str - * @param context the specified Graphics context - * @return a LineMetrics object created with the specified - * String and Graphics context. - * @see java.awt.Font#getLineMetrics(String, int, int, FontRenderContext) + * @param font + * @return */ - public LineMetrics getLineMetrics(String str, int beginIndex, int limit, Graphics context) { - return font.getLineMetrics(str, beginIndex, limit, null); - } - - /** - * Returns the {@link LineMetrics} object for the specified character array in - * the specified {@link Graphics} context. - * - * @param chars the specified character array - * @param beginIndex the initial offset of chars - * @param limit the end offset of chars - * @param context the specified Graphics context - * @return a LineMetrics object created with the specified - * character array and Graphics context. - * @see java.awt.Font#getLineMetrics(char[], int, int, FontRenderContext) - */ - public LineMetrics getLineMetrics(char[] chars, int beginIndex, int limit, Graphics context) { - return font.getLineMetrics(chars, beginIndex, limit, null); + public static float fontDescent(Font font) { + switch (font.getName()) { + default: + return font.getSize2D() * 0.2197f; + case "Monospaced": + return font.getSize2D() * 0.3003f; + } } /** - * Returns the {@link LineMetrics} object for the specified - * {@link CharacterIterator} in the specified {@link Graphics} context. + * Just copy these over in JavaScript * - * @param ci the specified CharacterIterator - * @param beginIndex the initial offset in ci - * @param limit the end index of ci - * @param context the specified Graphics context - * @return a LineMetrics object created with the specified - * arguments. - * @see java.awt.Font#getLineMetrics(CharacterIterator, int, int, - * FontRenderContext) + * @param count + * @param text + * @param glyphs */ - public LineMetrics getLineMetrics(CharacterIterator ci, int beginIndex, int limit, Graphics context) { - return font.getLineMetrics(ci, beginIndex, limit, null); - } - - /** - * The length of the metrics array must be >= 8. This method will - * store the following elements in that array before returning: - * metrics[0]: ascent - * metrics[1]: descent - * metrics[2]: leading - * metrics[3]: max advance - * metrics[4]: strikethrough offset - * metrics[5]: strikethrough thickness - * metrics[6]: underline offset - * metrics[7]: underline thickness - */ - public void getMetrics(AffineTransform identityTx, Object anRtiAliasingHint, - Object fractionalMetricsHint, float[] metrics) { - metrics[0] = fontAscent(font); - metrics[1] = fontDescent(font); - metrics[2] = fontLeading(font); - metrics[3] = 0; - if (metrics.length >= 8) { - metrics[4] = font.getSize2D() / -4f; - metrics[5] = metrics[6] = metrics[7] = 1; - } - } - - public void getMetrics(FontRenderContext frc, float[] metrics) { - getMetrics(null, null, null, metrics); - - } - public static void charsToGlyphs(int count, char[] text, int[] glyphs) { for (int i = 0; i < count; i++) glyphs[i] = text[i]; } - /** - * Takes the place of nativeLayout in SunLayoutEngine - * - * @param font2d - * @param mat - * @param gmask - * @param baseIndex - * @param tr - * @param typo_flags - * @param pt - * @param data - */ - public static void layout(Font2D font2d, float[] mat, int gmask, int baseIndex, TextRecord tr, int typo_flags, - Point2D.Float pt, GVData data) { - Font f = (Font) (Object) font2d; - JSFontMetrics fm = (JSFontMetrics) f.getFontMetrics(); - // TODO: scaling? rotation? - int g2 = 0; - float x = 0, y = 0, w; // I suspect all fonts are laid out linearly in x. Maybe not? - for (int g = 0, p=tr.start; p < tr.limit; p++, g++) { - int ch = tr.text[p]; - if (Character.isHighSurrogate((char)ch) && - p < tr.limit - 1 && - Character.isLowSurrogate(tr.text[++p])) { - // rare case - ch = Character.toCodePoint((char)ch,tr.text[p]); // inc - w = fm.getFloatWidth(ch); - } else if (ch > 255){ - // unicode value - w = fm.getFloatWidth(ch); - } else { - w = fm.getWidthsFloat()[ch]; - - } - - data._indices[g] = p + baseIndex; - data._positions[g2++] = x; - data._positions[g2++] = y; - data._glyphs[g] = ch; - data._count++; - x += w; - } - data._positions[g2++] = x; - data._positions[g2++] = y; - - } - - } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSImage.java b/sources/net.sf.j2s.java.core/src/swingjs/JSImage.java index 11481306a..86f46987f 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSImage.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSImage.java @@ -6,6 +6,8 @@ import java.awt.image.MemoryImageSource; import java.io.File; import java.io.IOException; +import java.util.Map; +import java.util.function.Consumer; import javax.swing.ImageIcon; import javax.swing.JLabel; @@ -40,6 +42,8 @@ public class JSImage extends BufferedImage { public String src; + protected Map videoTrackInfo; + public Object 秘source; /** * Frome JSImageKit reading pixels from an image file or MemoryImageSource @@ -51,6 +55,7 @@ public class JSImage extends BufferedImage { */ public JSImage(int[] argb, int width, int height, String src, int type) { super(width, height, type); + @SuppressWarnings("unused") MemoryImageSource m; // just an Eclipse tag so we can find this reference; this.src = src; if (argb != null) @@ -139,8 +144,9 @@ public void run() { } } }; - if (b != null) + if (b != null) { src = JSImagekit.getDataBlob(b, "video/mp4"); + } // see https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image /** * @j2sNative img.crossOrigin = "Anonymous"; diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSImagekit.java b/sources/net.sf.j2s.java.core/src/swingjs/JSImagekit.java index f232aa735..e5e82af60 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSImagekit.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSImagekit.java @@ -1,6 +1,9 @@ package swingjs; import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; import javax.swing.Icon; import javax.swing.ImageIcon; @@ -22,6 +25,7 @@ import swingjs.api.Interface; import swingjs.api.js.DOMNode; import swingjs.api.js.HTML5Canvas; +import swingjs.json.JSON; /** * An image consumer for off-line images. @@ -325,5 +329,91 @@ public static Object getDataBlob(byte[] b, String type) { return (/** @j2sNative URL.createObjectURL(new Blob([b], {type:type})) || */null); } + static boolean mediaInfoLoaded = false; + static Object mediaInfoObject = null; + private static String mediaInfoURL = "https://unpkg.com/mediainfo.js@0.3.1/dist/umd/index.min.js"; + + + /** + * Load mediainfo.js and MediaInfoModule.wasm, then use them to generate a JSON array. + * + * @param data + * @param trackType + * @param success + * @param onError + * @param path + */ + public static void getMediaInfoAsync(byte[] data, String trackType, String path, Consumer> success, Consumer onError) { + + if (!mediaInfoLoaded) { + // load MediaInfo.js + JSUtil.loadScriptAsync(path == null ? mediaInfoURL : path.startsWith("http") ? path : JSUtil.newJSUtil().getJ2SPath() + path, () -> { + mediaInfoLoaded = true; + getMediaInfoAsync(data, null, trackType, success, onError); + }); + return; + } + Consumer f; + if (mediaInfoObject == null) { + f = new Consumer() { + + @Override + public void accept(Object mediainfo) { + mediaInfoObject = mediainfo; + getMediaInfoAsync(data, null, trackType, success, onError); + } + + }; + // load MediaInfo.wasm and create MediaInfo object + /** + * @j2sNative + * + * MediaInfo.mediaInfoFactory( { format: 'JSON' }, + * function(mediainfo){ f.accept$O(mediainfo) } + * ); + * + */ + return; + } + f = new Consumer() { + + @Override + public void accept(Object result) { + try { + Map info = null; + info = (Map) JSON.parse((String) result); + if (trackType != null) { + info = (Map) info.get("media"); + List tracks = (List) info.get("track"); + info = null; + for (int i = tracks.size(); --i >= 0;) { + info = (Map) tracks.get(i); + if (info.get("@type").equals(trackType)) + break; + } + } + success.accept(info); + } catch (Exception e) { + e.printStackTrace(); + onError.accept(e.getMessage()); + } + } + + }; + /** + * @j2sNative + * + * C$.mediaInfoObject.analyzeData(data.length, + * function(chunkSize, offset){ + * return new Uint8Array(data.slice(offset, offset + chunkSize)); + * } + * ).then( + * function(result){f.accept$O(result)}, + * function(error){onError ? onError.accept$O(error) : console.log(error)} + * ); + */ + + } + } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSMouse.java b/sources/net.sf.j2s.java.core/src/swingjs/JSMouse.java index d2e7b5bca..42b9c515a 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSMouse.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSMouse.java @@ -206,7 +206,7 @@ private void entry(long time, int x, int y, int id) { * @param modifiers * @param clickCount */ - private void clicked(long time, int x, int y, int modifiers, int clickCount) { + public void clicked(long time, int x, int y, int modifiers, int clickCount) { // clearKeyBuffer(); // clickedCount is not reliable on some platforms // so we will just deal with it ourselves @@ -404,10 +404,10 @@ private static void processMouseEvent(Object jqevent, Component source, int id, boolean popupTrigger = isPopupTrigger(id, modifiers, JSToolkit.isWin); MouseEvent e; if (id == MouseEvent.MOUSE_WHEEL) { - e = new MouseWheelEvent(source, id, time, modifiers, x, y, x, y, count, popupTrigger, + e = new MouseWheelEvent(source, id, time, modifiers, x, y, count, popupTrigger, MouseWheelEvent.WHEEL_UNIT_SCROLL, 1, dy); } else { - e = new MouseEvent(source, id, time, modifiers, x, y, x, y, count, popupTrigger, button); + e = new MouseEvent(source, id, time, modifiers, x, y, count, popupTrigger, button); } byte[] bdata = new byte[0]; e.setBData(bdata); diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSMouse2.java b/sources/net.sf.j2s.java.core/src/swingjs/JSMouse2.java index 69a809ec0..1c0f44ea5 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSMouse2.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSMouse2.java @@ -57,23 +57,29 @@ public JSMouse2 set(JSMouse mouse) { * */ public void processTwoPointGesture(float[][][] touches) { - - if (touches[0].length < 2) - return; float[][] t1 = touches[0]; float[][] t2 = touches[1]; + int nt = t1.length; + if (nt < 2) + return; + boolean isClick = (nt > t2.length); float[] t1first = t1[0]; - float[] t1last = t1[t2.length - 1]; float x1first = t1first[0]; - float x1last = t1last[0]; - float dx1 = x1last - x1first; float y1first = t1first[1]; + + if (isClick) { + mouse.clicked(System.currentTimeMillis(), (int) x1first, (int) y1first, 0, 2); + return; + } + float[] t1last = t1[nt - 1]; + float x1last = t1last[0]; float y1last = t1last[1]; + float dx1 = x1last - x1first; float dy1 = y1last - y1first; V3 v1 = V3.new3(dx1, dy1, 0); float d1 = v1.length(); float[] t2first = t2[0]; - float[] t2last = t2[t2.length - 1]; + float[] t2last = t2[nt - 1]; float x2first = t2first[0]; float x2last = t2last[0]; float dx2 = x2last - x2first; diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSToolkit.java b/sources/net.sf.j2s.java.core/src/swingjs/JSToolkit.java index 6a4733c56..71e02eea9 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSToolkit.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSToolkit.java @@ -223,7 +223,9 @@ public static Object getPropertyObject(Object t, String key, Object def) { * @return */ public static GraphicsConfiguration getGraphicsConfiguration() { - JSAppletViewer ap = JSToolkit.getAppletViewer(); + JSAppletViewer ap = getAppletViewer(); + if (ap == null) + ap = Thread.currentThread().getThreadGroup().秘getAppletViewer(); GraphicsConfiguration gc = (ap == null ? null : ap.graphicsConfig); return (gc == null ? (gc = ap.graphicsConfig = (GraphicsConfiguration) JSUtil.getInstance("swingjs.JSGraphicsConfiguration")) : gc); } @@ -254,6 +256,25 @@ public static float getStringWidth(HTML5CanvasContext2D context, Font font, return w; } + public static Object getTextMetrics(HTML5CanvasContext2D context, Font font, + String text) { + if (text == null || text.length() == 0) + return 0; + @SuppressWarnings("unused") + String fontInfo = getCanvasFont(font); + if (context == null) + context = getDefaultCanvasContext2d(); + Object tm = null; + /** + * @j2sNative + * context.font = fontInfo; + * tm = context.measureText(text); + */ + { + } + return tm; + } + /** * Used as a stratch pad for determining text string dimensions. * @@ -872,7 +893,8 @@ public static String getCanvasFont(Font font) { String family = getCSSFontFamilyName(font.getFamily()); // for whatever reason, Java font points are much larger than HTML5 canvas // points - return strStyle + font.getSize() + "px " + family; + font.getSize(); + return strStyle + font.getSize2D() + "px " + family; } public static String getCSSFontFamilyName(String family) { diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java b/sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java index fe0e17033..9c8968f24 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java @@ -456,7 +456,7 @@ static String processCSS(String css, String path) { return css; } - static String processJS(String js, String resourceName) { + public static String processJS(String js, String resourceName) { try { /** * @j2sNative @@ -753,6 +753,10 @@ public static String prompt(String msg, String defaultRet) { } } + /** + * Sets the url's ajax field to point to it. + * @param url + */ public static void setAjax(URL url) { JSON.setAjax(url); } @@ -1284,8 +1288,28 @@ public String getJ2SPath() { return (String) getAppletAttribute("_j2sFullPath"); } - - + public static void loadScriptAsync(String url, Runnable success) { + URL u; + try { + u = new URL(url); + JSFunction f = /** @j2sNative function(){success.run$()} || */ null; + setAjax("url", u, "url", url, "dataType", "script", "success", f); + u.getContent(); + } catch (Exception e) { + e.printStackTrace(); + } + } + /** + * Get + * @param data + * @param trackType + * @param success + * @param onError + */ + @Override + public void getMediaInfoAsync(byte[] data, String trackType, String path, Consumer> success, Consumer onError) { + JSImagekit.getMediaInfoAsync(data, trackType, path, success, onError); + } } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSUtil2.java b/sources/net.sf.j2s.java.core/src/swingjs/JSUtil2.java index 71c6479a3..c7a960567 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSUtil2.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSUtil2.java @@ -13,9 +13,9 @@ public class JSUtil2 { public static Promise importModule(String resource, Consumer resolve, Consumer reject) { return /** - * @j2sNative import(resource) .then(function(value) { resolve && - * resolve.accept$O(value) }, function(reason) {reject && - * reject.accept$O(reason)}) || + * @j2sNative import(resource).then( + * function(value) { resolve && resolve.accept$O(value) }, + * function(reason) {reject && reject.accept$O(reason)}) || */null; } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/api/JSUtilI.java b/sources/net.sf.j2s.java.core/src/swingjs/api/JSUtilI.java index 5eed766d6..247a52cd1 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/api/JSUtilI.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/api/JSUtilI.java @@ -386,4 +386,16 @@ public interface JSUtilI { */ String getJ2SPath(); + /** + * Asyncronously fires either success or onError after running mediainfo.analyzeData + * + * This information is always created in JSImagekit for the JSImage. + * + * @param videoData byte array data of video + * @param trackType the &type for the media track to return, or null to return the full MediaInfo result JSON map + * @param success function to handle the returned map, if everything works out + * @param onError function to handle the error message, if an error occurs + */ + void getMediaInfoAsync(byte[] videoData, String trackType, String path, Consumer> success, Consumer onError); + } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/api/js/HTML5Video.java b/sources/net.sf.j2s.java.core/src/swingjs/api/js/HTML5Video.java index 3b6ef3b85..9879587c1 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/api/js/HTML5Video.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/api/js/HTML5Video.java @@ -10,6 +10,7 @@ import java.net.URL; import java.nio.file.Files; import java.util.ArrayList; +import java.util.function.Consumer; import java.util.function.Function; import javax.swing.BoxLayout; @@ -62,8 +63,10 @@ public interface HTML5Video extends DOMNode { // already been loaded (or partially loaded), and the load() method is called to // reload it. "ended", // Playback has stopped because the end of the media was reached. + "error", // An error occurred while fetching the media data, or the type of the resource is not a supported media format. "loadeddata", // The first frame of the media has finished loading. "loadedmetadata", // The metadata has been loaded. + "loadstart", // Fired when the browser has started to load the resource. "pause", // Playback has been paused. "play", // Playback has begun. "playing", // Playback is ready to start after having been paused or delayed due to lack of @@ -99,6 +102,8 @@ public interface HTML5Video extends DOMNode { public void mozGetMetadata() throws Throwable; public void pause() throws Throwable; + + public int requestVideoFrameCallback(Object callback) throws Throwable; public Promise play() throws Throwable; @@ -349,6 +354,7 @@ public static JDialog createDialog(Frame parent, Object source, int maxWidth, bo * @j2sNative * * jsvideo.dialog = dialog; + * jsvideo.label = label; * */ Object[] j2sListener = HTML5Video.addActionListener(jsvideo, new ActionListener() { @@ -378,7 +384,58 @@ public void actionPerformed(ActionEvent e) { HTML5Video.setCurrentTime(jsvideo, 0); return dialog; } + + public static void cancelVideoFrameCallback(HTML5Video jsvideo) { + + /** + * @j2sNative + * jsvideo._cancelVFCallback = true; + * + */ + } + /** + * capture frame metadata while playing. Specifically, grab the metadata.mediaTime values, + * reporting these to the provided results array as + * + * results[0] = frameCount + * + * resutls[n] = frame-n startTime (seconds) + * + * @param jsvideo + * @param result array to load + * @return + */ + @SuppressWarnings("unused") + public static int requestVideoFrameCallback(HTML5Video jsvideo, Consumer callback) { + Object[] f = null; + /** + * @j2sNative + * if (jsvideo.requestVideoFrameCallback) { + * jsvideo._cancelVFCallback = false; + * f = []; + * f[0] = function(now, metadata) { + * if (jsvideo._cancelVFCallback) { + * jsvideo._cancelVFCallback = false; + * } else { + * callback.accept$O(metadata); + * jsvideo.requestVideoFrameCallback(f[0]); + * } + * }; + * } + * + */ + if (f == null) + return 0; + int id = 0; + try { + id = jsvideo.requestVideoFrameCallback(f[0]); + } catch (Throwable e) { + e.printStackTrace(); + } + return id; + } + static JPanel getControls(JLabel label) { JPanel controls = new JPanel(); diff --git a/sources/net.sf.j2s.java.core/src/swingjs/api/js/J2SInterface.java b/sources/net.sf.j2s.java.core/src/swingjs/api/js/J2SInterface.java index a5aecd6a9..24b75779b 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/api/js/J2SInterface.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/api/js/J2SInterface.java @@ -80,6 +80,12 @@ void readyCallback(String appId, String fullId, boolean isReady, JSFunction getCaller(); + void __makeSlider(); + + void __makeMenu(); + + void __makeComboBox(); + } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/jquery/JQueryUI.java b/sources/net.sf.j2s.java.core/src/swingjs/jquery/JQueryUI.java index 3dcff35b4..6c69b0ff2 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/jquery/JQueryUI.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/jquery/JQueryUI.java @@ -1,5 +1,8 @@ package swingjs.jquery; +import java.util.HashMap; +import java.util.Map; + import swingjs.JSUtil; //based on jQuery UI - v1.9.2 - 2015-05-28 @@ -25,24 +28,48 @@ */ public class JQueryUI { + private final static String RESOURCE_J2SCOMBOBOX = "swingjs/jquery/j2sComboBox.js"; + private final static String RESOURCE_J2SMENU = "swingjs/jquery/j2sMenu.js"; + private final static String RESOURCE_J2SSLIDER = "swingjs/jquery/j2sSlider.js"; + + static boolean loadResourceInternal = true; public static void loadJQComboBox() { - if (/** @j2sNative !J2S.__makeComboBox && */true) - JSUtil.loadStaticResource("swingjs/jquery/j2sComboBox.js"); - /** @j2sNative J2S.__makeComboBox(); */ + String resource = RESOURCE_J2SCOMBOBOX; + if (/** @j2sNative !J2S.__makeComboBox && */true) { + loadResource(resource); + } + // outside {} in case j2sComboBox.js has been preloaded, overriding the setting here + JSUtil.J2S.__makeComboBox(); } public static void loadJQMenu() { - if (/** @j2sNative !J2S.__makeMenu && */true) - JSUtil.loadStaticResource("swingjs/jquery/j2sMenu.js"); - /** @j2sNative J2S.__makeMenu(); */ + String resource = RESOURCE_J2SMENU; + if (/** @j2sNative !J2S.__makeMenu && */true) { + loadResource(resource); + } + // outside {} in case j2sMenu.js has been preloaded, overriding the setting here + JSUtil.J2S.__makeMenu(); } public static void loadJQSlider() { - if (/** @j2sNative !J2S.__makeSlider && */true) - JSUtil.loadStaticResource("swingjs/jquery/j2sSlider.js"); - /** @j2sNative J2S.__makeSlider(); */ + String resource = RESOURCE_J2SSLIDER; + if (/** @j2sNative !J2S.__makeSlider && */true) { + loadResource(resource); + } + // outside {} in case j2sSlider.js has been preloaded, overriding the setting here + JSUtil.J2S.__makeSlider(); } - + + private static void loadResource(String resourceName) { + if (loadResourceInternal) { + JSUtil.processJS(htResource.get(resourceName), resourceName); + } else { + JSUtil.loadStaticResource(resourceName); + } + } + + private static Map htResource = new HashMap<>(); + static { /** @@ -108,5 +135,1966 @@ public static void loadJQSlider() { System.err.println("JQueryUI failed to load jQuery.ui.position -- jQuery version conflict?"); } */ + + + + // BH 2024.06.28 + + htResource.put(RESOURCE_J2SCOMBOBOX, ";(function($) {\n" + + "\n" + + "J2S.__makeComboBox = function() {\n" + + " J2S.__makeComboBox = function(){}; \n" + + " \n" + + " $( function() {\n" + + " $('head').append(''\n" + + " );\n" + + " \n" + + " var CLOSE_DELAY = 100; // BH 2019.10.04 50 was just a bit too fast; could close early\n" + + " \n" + + " // the widget definition, where 'custom' is the namespace,\n" + + " // 'j2sCB' the widget name\n" + + "\n" + + " $.widget( 'custom.j2sCB', {\n" + + " \n" + + " options: {\n" + + " mode: 's', // or 'm'\n" + + " height: 0,\n" + + " items: null,\n" + + " disabled: false,\n" + + " popupVisible: false,\n" + + " selectedIndex: -1,\n" + + " backgroundColor: \"blue\",\n" + + " // z-index\n" + + " zIndex:999999,\n" + + " name:null,\n" + + " // Callbacks\n" + + " change: null\n" + + " },\n" + + " itemCount: 0,\n" + + " \n" + + " id: function() {return this.element[0].id},\n" + + " find: function(x) {return this.element.find(x)},\n" + + " on: function(a, x) {for(var i = a.length; --i >= 0;)this._on(a[i],x)},\n" + + " on2: function(obj, evts, handle) {var a = {};for(var i = evts.length; --i >= 0;)a[evts[i]]=handle;this._on(obj, a)},\n" + + "\n" + + " popupVisible: function() { return this.options.popupVisible; }, \n" + + "\n" + + " setHeight: function(h) {\n" + + " this.options.height = h;\n" + + " },\n" + + " setZIndex: function(z) {\n" + + " this.options.zIndex = z;\n" + + " },\n" + + " \n" + + " _mouse: function(e) { \n" + + " var opt = $(e.target).closest('.j2scbopt');\n" + + " this._trigger('change', e, [this, 'mouse', (opt[0] ? opt[0].j2scbIndex : -1)])\n" + + " },\n" + + " _keyEvent: function(e) {\n" + + " this._trigger('change', e, [this, 'keyevent']);\n" + + " },\n" + + " \n" + + " // Called when created, and later when changing options\n" + + " _refresh: function() {\n" + + " \n" + + " // Trigger a callback/event\n" + + " this._trigger( 'change' , null, [this, \"refreshed\"] );\n" + + " },\n" + + " \n" + + " // The constructor\n" + + " _create: function() {\n" + + " var id = this.id();\n" + + " this.element.addClass( 'custom-j2sCB' );\n" + + " this.cont = $( '
', {'class': 'j2scbcont', 'id':id+'_cont' });\n" + + " this.cont.append(this.head = $( '