JAL-1807 includes ?j2sdebug flag and DebugJS._(msg)
[jalviewjs.git] / site / js / JSmol.js
1 // JSmol.js -- Jmol pure JavaScript version\r
2 // author: Bob Hanson, hansonr@stolaf.edu       4/16/2012\r
3 // author: Takanori Nakane biochem_fan 6/12/2012\r
4 \r
5 // BH 3/28/2015 6:18:33 AM refactoring to generalize for non-Jmol-related SwingJS applications\r
6 // BH 9/6/2014 5:42:32 PM  two-point gestures broken\r
7 // BH 5/8/2014 11:16:40 AM j2sPath starting with "/" fails to add idiom\r
8 // BH 1/16/2014 8:44:03 PM   __execDelayMS = 100; // FF bug when loading into a tab that is not \r
9 //                           immediately focused and not using jQuery for adding the applet and having  \r
10 //                           multiple applets.\r
11 // BH 12/6/2013 10:12:30 AM adding corejmoljsv.z.js\r
12 // BH 9/17/2013 10:18:40 AM  file transfer functions moved to JSmolCore \r
13 // BH 3/5/2013 9:54:16 PM added support for a cover image: Info.coverImage, coverScript, coverTitle, deferApplet, deferUncover\r
14 // BH 1/3/2013 4:54:01 AM mouse binding should return false -- see d.bind(...), and d.bind("contextmenu") is not necessary\r
15 \r
16 // This library requires prior inclusion of \r
17 \r
18 //  jQuery 9 or higher\r
19 //      JSmoljQueryExt.js\r
20 //      JSmolCore.js\r
21 //  j2sjmol.js    (Clazz and associated classes)\r
22 \r
23 // these:\r
24 //\r
25 //  JSmolApplet.js\r
26 //  JSmolApi.js\r
27 //  JSmolThree.js\r
28 //  JSmolGLmol.js\r
29 //  \r
30 //  are optional \r
31 \r
32 ;(function (Jmol) {\r
33 \r
34         Jmol._isAsync = false; // testing only\r
35         Jmol._asyncCallbacks = {};\r
36         \r
37         Jmol._coreFiles = []; // required for package.js\r
38 \r
39 \r
40 ///////////////////\r
41 // This section provides an asynchronous loading sequence\r
42 //\r
43 \r
44 // methods and fields starting with double underscore are private to this .js file\r
45 \r
46   var __clazzLoaded = false;\r
47         var __execLog = [];\r
48         var __execStack = [];\r
49         var __execTimer = 0;\r
50         var __coreSet = [];\r
51         var __coreMore = [];\r
52         var __execDelayMS = 100; // must be > 55 ms for FF\r
53 \r
54         var __nextExecution = function(trigger) {\r
55     arguments.length || (trigger = true);\r
56                 delete __execTimer;\r
57                 var es = __execStack;\r
58                 var e;\r
59                 while (es.length > 0 && (e = es[0])[4] == "done")\r
60                         es.shift();\r
61                 if (es.length == 0)\r
62                         return;\r
63                 if (!Jmol._isAsync && !trigger) {\r
64                         setTimeout(__nextExecution,10)\r
65                         return;\r
66                 }\r
67                 e.push("done");\r
68                 var s = "JSmol exec " + e[0]._id + " " + e[3] + " " + e[2];\r
69                 if (self.System)\r
70                         System.out.println(s);\r
71                         //alert(s)\r
72                 if (self.console)console.log(s + " -- OK")\r
73                 __execLog.push(s);\r
74                 e[1](e[0],e[2]);        \r
75         };\r
76 \r
77         var __loadClazz = function(applet) {\r
78                 if (!__clazzLoaded) {\r
79                         __clazzLoaded = true;\r
80                         // create the Clazz object\r
81                         LoadClazz();\r
82                         if (applet._noMonitor)\r
83                                 Clazz._LoaderProgressMonitor.showStatus = function() {}\r
84                         LoadClazz = null;\r
85       if (applet.__Info.uncompressed)\r
86         Clazz.loadClass(); // for now; allows for no compression \r
87                         Clazz._Loader.onGlobalLoaded = function (file) {\r
88                          // not really.... just nothing more yet to do yet\r
89                                 Clazz._LoaderProgressMonitor.showStatus("Application loaded.", true);\r
90                                 if (!Jmol._debugCode || !Jmol.haveCore) {\r
91                                         Jmol.haveCore = true;\r
92                                         __nextExecution();\r
93                                 }\r
94                         };\r
95                   // load package.js and j2s/core/core.z.js\r
96                         Clazz._Loader.loadPackageClasspath("java", null, true, __nextExecution);\r
97                         return;\r
98                 }\r
99                 __nextExecution();\r
100         };\r
101 \r
102         var __loadClass = function(applet, javaClass) {\r
103                 Clazz._Loader.loadClass(javaClass, function() {__nextExecution()});\r
104         };\r
105 \r
106         Jmol.showExecLog = function() { return __execLog.join("\n") }; \r
107 \r
108         Jmol._addExec = function(e) {\r
109     e[1] || (e[1] = __loadClass);\r
110                 var s = "JSmol load " + e[0]._id + " " + e[3];\r
111                 if (self.console)console.log(s + "...")\r
112                 __execLog.push(s);   \r
113                 __execStack.push(e);\r
114         }\r
115 \r
116         Jmol._addCoreFile = function(type, path, more) {\r
117   \r
118     // BH 3/15: idea here is that when both Jmol and JSV are present, \r
119     // we want to load a common core file -- jmoljsv.z.js --\r
120     // instead of just one. Otherwise we do a lot of duplication.\r
121     // It is not clear how this would play with other concurrent\r
122     // apps. So this will take some thinking. But the basic idea is that\r
123     // core file to load is \r
124      \r
125     type = type.toLowerCase().split(".")[0]; // package name only \r
126 \r
127     // return if type is already part of the set.    \r
128                 if (__coreSet.join("").indexOf(type) >= 0) return;\r
129     \r
130     // create a concatenated lower-case name for a core file that includes\r
131     // all Java applets on the page\r
132     \r
133                 __coreSet.push(type);\r
134                 __coreSet.sort();\r
135                 Jmol._coreFiles = [path + "/core/core" + __coreSet.join("") + ".z.js" ];\r
136                 if (more && (more = more.split(" ")))\r
137                         for (var i = 0; i < more.length; i++)\r
138                                 if (__coreMore.join("").indexOf(more[i]) < 0)\r
139                                         __coreMore.push(path + "/core/core" + more[i] + ".z.js")\r
140                 for (var i = 0; i < __coreMore.length; i++)\r
141                         Jmol._coreFiles.push(__coreMore[i]);\r
142         }               \r
143 \r
144         Jmol._Canvas2D = function(id, Info, type, checkOnly){\r
145                 // type: Jmol or JSV\r
146                 this._uniqueId = ("" + Math.random()).substring(3);\r
147                 this._id = id;\r
148                 this._is2D = true;\r
149                 this._isJava = false;\r
150                 this._jmolType = "Jmol._Canvas2D (" + type + ")";\r
151     this._isLayered = Info._isLayered || false;\r
152     this._isSwing = Info._isSwing || false;\r
153     this._isJSV = Info._isJSV || false;\r
154     this._isAstex = Info._isAstex || false;            \r
155     this._platform = Info._platform || "";\r
156                 if (checkOnly)\r
157                         return this;\r
158                 window[id] = this;\r
159                 this._createCanvas(id, Info);\r
160                 if (!Jmol._document || this._deferApplet)\r
161                         return this;\r
162                 this._init();\r
163                 return this;\r
164         };\r
165 \r
166         Jmol._setAppletParams = function(availableParams, params, Info, isHashtable) {\r
167                 for (var i in Info)\r
168                         if(!availableParams || availableParams.indexOf(";" + i.toLowerCase() + ";") >= 0){\r
169                                 if (Info[i] == null || i == "language" && !Jmol.featureDetection.supportsLocalization())\r
170                                         continue;\r
171                                 if (isHashtable)\r
172                                         params.put(i, (Info[i] === true ? Boolean.TRUE: Info[i] === false ? Boolean.FALSE : Info[i]))\r
173                                 else\r
174                                         params[i] = Info[i];\r
175                         }\r
176         }     \r
177          \r
178         Jmol._jsSetPrototype = function(proto) {\r
179                 proto._init = function() {\r
180                         this._setupJS();\r
181                         this._showInfo(true); \r
182                         if (this._disableInitialConsole)\r
183                                 this._showInfo(false);\r
184                 };\r
185 \r
186                 proto._createCanvas = function(id, Info, glmol) {\r
187                         Jmol._setObject(this, id, Info);\r
188                         if (glmol) {\r
189                                 this._GLmol = glmol;\r
190                                 this._GLmol.applet = this;\r
191                                 this._GLmol.id = this._id;\r
192                         }      \r
193                         var t = Jmol._getWrapper(this, true);\r
194                         if (this._deferApplet) {\r
195                         } else if (Jmol._document) {\r
196                                 Jmol._documentWrite(t);\r
197                                 this._newCanvas(false);                                 \r
198                                 t = "";\r
199                         } else {\r
200                                 this._deferApplet = true;\r
201                                 t += '<script type="text/javascript">' + id + '._cover(false)</script>';\r
202                         }\r
203                         t += Jmol._getWrapper(this, false);\r
204                         if (Info.addSelectionOptions)\r
205                                 t += Jmol._getGrabberOptions(this);\r
206                         if (Jmol._debugAlert && !Jmol._document)\r
207                                 alert(t);\r
208                         this._code = Jmol._documentWrite(t);\r
209                 };\r
210 \r
211                 proto._newCanvas = function(doReplace) {\r
212                         if (this._is2D)\r
213                                 this._createCanvas2d(doReplace);\r
214                         else\r
215                                 this._GLmol.create();\r
216                 };\r
217 \r
218 //////// swingjs.api.HTML5Applet interface    \r
219     proto._getHtml5Canvas = function() { return this._canvas }; \r
220     proto._getWidth = function() { return this._canvas.width }; \r
221     proto._getHeight = function() { return this._canvas.height };\r
222     proto._getContentLayer = function() { return Jmol.$(this, "contentLayer")[0] };\r
223     proto._repaintNow = function() { Jmol._repaint(this, false) }; \r
224 ////////\r
225 \r
226 \r
227                 proto._createCanvas2d = function(doReplace) {\r
228                         var container = Jmol.$(this, "appletdiv");\r
229                         //if (doReplace) {\r
230       \r
231                         try {\r
232                         container[0].removeChild(this._canvas);\r
233                         if (this._canvas.frontLayer)\r
234                                 container[0].removeChild(this._canvas.frontLayer);\r
235                         if (this._canvas.rearLayer)\r
236                                 container[0].removeChild(this._canvas.rearLayer);\r
237                         if (this._canvas.contentLayer)\r
238                                 container[0].removeChild(this._canvas.contentLayer);\r
239                         Jmol._jsUnsetMouse(this._mouseInterface);\r
240                         } catch (e) {}\r
241                         //}\r
242                         var w = Math.round(container.width());\r
243                         var h = Math.round(container.height());\r
244                         var canvas = document.createElement( 'canvas' );\r
245                         canvas.applet = this;\r
246                         this._canvas = canvas;\r
247                         canvas.style.width = "100%";\r
248                         canvas.style.height = "100%";\r
249                         canvas.width = w;\r
250                         canvas.height = h; // w and h used in setScreenDimension\r
251                         canvas.id = this._id + "_canvas2d";\r
252                         container.append(canvas);\r
253                         Jmol._$(canvas.id).css({"z-index":Jmol._getZ(this, "main")});\r
254                         if (this._isLayered){\r
255                                 var img = document.createElement("div");\r
256                                 canvas.contentLayer = img;\r
257                                 img.id = this._id + "_contentLayer";\r
258                                 container.append(img);\r
259                                 Jmol._$(img.id).css({zIndex:Jmol._getZ(this, "image"),position:"absolute",left:"0px",top:"0px",\r
260         width:(this._isSwing ? w : 0) + "px", height:(this._isSwing ? h : 0) +"px", overflow:"hidden"});\r
261         if (this._isSwing) {\r
262                 var d = document.createElement("div");\r
263           d.id = this._id + "_swingdiv";\r
264                 Jmol._$(this._id + "_appletinfotablediv").append(d);\r
265                                   Jmol._$(d.id).css({zIndex:Jmol._getZ(this, "rear"),position:"absolute",left:"0px",top:"0px", width:w +"px", height:h+"px", overflow:"hidden"});\r
266                                 this._mouseInterface = canvas.contentLayer;\r
267           canvas.contentLayer.applet = this;\r
268         } else {\r
269                                 this._mouseInterface = this._getLayer("front", container, w, h, false);\r
270         }\r
271                                 //this._getLayer("rear", container, w, h, true);\r
272                                 //Jmol._$(canvas.id).css({background:"rgb(0,0,0,0.001)", "z-index":Jmol._z.main}); \r
273                         } else {\r
274                                 this._mouseInterface = canvas;\r
275                         }\r
276                         Jmol._jsSetMouse(this._mouseInterface);\r
277                 }\r
278     \r
279     proto._getLayer = function(name, container, w, h, isOpaque) {\r
280                 var c = document.createElement("canvas");\r
281                         this._canvas[name + "Layer"] = c;\r
282                         c.style.width = "100%";\r
283                         c.style.height = "100%";\r
284                         c.id = this._id + "_" + name + "Layer";\r
285                         c.width = w;\r
286                         c.height = h; // w and h used in setScreenDimension\r
287                         container.append(c);\r
288                         c.applet = this;\r
289                         Jmol._$(c.id).css({background:(isOpaque ? "rgb(0,0,0,1)" : "rgb(0,0,0,0.001)"), "z-index": Jmol._getZ(this,name),position:"absolute",left:"0px",top:"0px",overflow:"hidden"});\r
290                         return c;       \r
291     }\r
292     \r
293     \r
294                 proto._setupJS = function() {\r
295                         window["j2s.lib"] = {\r
296                                 base : this._j2sPath + "/",\r
297                                 alias : ".",\r
298                                 console : this._console,\r
299                                 monitorZIndex : Jmol._getZ(this, "monitorZIndex")\r
300                         };\r
301                         var isFirst = (__execStack.length == 0);\r
302                         if (isFirst)\r
303                                 Jmol._addExec([this, __loadClazz, null, "loadClazz"]);\r
304       this._addCoreFiles();\r
305                         Jmol._addExec([this, this.__startAppletJS, null, "start applet"])\r
306                         this._isSigned = true; // access all files via URL hook\r
307                         this._ready = false; \r
308                         this._applet = null;\r
309                         this._canScript = function(script) {return true;};\r
310                         this._savedOrientations = [];\r
311                         __execTimer && clearTimeout(__execTimer);\r
312                         __execTimer = setTimeout(__nextExecution, __execDelayMS);\r
313                 };\r
314 \r
315                 proto.__startAppletJS = function(applet) {\r
316                         if (Jmol._version.indexOf("$Date: ") == 0)\r
317                                 Jmol._version = (Jmol._version.substring(7) + " -").split(" -")[0] + " (JSmol/j2s)"\r
318                         var viewerOptions = Clazz._4Name("java.util.Hashtable").newInstance();\r
319                         Jmol._setAppletParams(applet._availableParams, viewerOptions, applet.__Info, true);\r
320                         viewerOptions.put("appletReadyCallback","Jmol._readyCallback");\r
321                         viewerOptions.put("applet", true);\r
322                         viewerOptions.put("name", applet._id);// + "_object");\r
323                         viewerOptions.put("syncId", Jmol._syncId);\r
324                         if (Jmol._isAsync)\r
325                                 viewerOptions.put("async", true);\r
326                         if (applet._color) \r
327                                 viewerOptions.put("bgcolor", applet._color);\r
328                         if (applet._startupScript)\r
329                                 viewerOptions.put("script", applet._startupScript)\r
330                         if (Jmol._syncedApplets.length)\r
331                                 viewerOptions.put("synccallback", "Jmol._mySyncCallback");\r
332                         viewerOptions.put("signedApplet", "true");\r
333                         viewerOptions.put("platform", applet._platform);\r
334                         if (applet._is2D)\r
335                                 viewerOptions.put("display",applet._id + "_canvas2d");\r
336 \r
337                         // viewerOptions.put("repaintManager", "J.render");\r
338                         viewerOptions.put("documentBase", document.location.href);\r
339                         var codePath = applet._j2sPath + "/";\r
340       \r
341                         if (codePath.indexOf("://") < 0) {\r
342                                 var base = document.location.href.split("#")[0].split("?")[0].split("/");\r
343                                 if (codePath.indexOf("/") == 0)\r
344                                         base = [base[0], codePath.substring(1)];\r
345                                 else\r
346                                         base[base.length - 1] = codePath;\r
347                                 codePath = base.join("/");\r
348                         }\r
349                         viewerOptions.put("codePath", codePath);\r
350                         Jmol._registerApplet(applet._id, applet);\r
351                         try {\r
352                                 applet._newApplet(viewerOptions);\r
353                         } catch (e) {\r
354                                 System.out.println((Jmol._isAsync ? "normal async abort from " : "") + e);\r
355                                 return;\r
356                         }\r
357       \r
358                         applet._jsSetScreenDimensions();\r
359                         __nextExecution();\r
360                 };\r
361 \r
362     if (!proto._restoreState)\r
363                 proto._restoreState = function(clazzName, state) {\r
364         // applet-dependent\r
365                   }\r
366         \r
367                 proto._jsSetScreenDimensions = function() {\r
368                                 if (!this._appletPanel)return\r
369                                 // strangely, if CTRL+/CTRL- are used repeatedly, then the\r
370                                 // applet div can be not the same size as the canvas if there\r
371                                 // is a border in place.\r
372                                 var d = Jmol._getElement(this, (this._is2D ? "canvas2d" : "canvas"));\r
373                                 this._appletPanel.setScreenDimension(d.width, d.height);\r
374                 };\r
375 \r
376                 proto._show = function(tf) {\r
377                         Jmol.$setVisible(Jmol.$(this,"appletdiv"), tf);\r
378                         if (tf)\r
379                                 Jmol._repaint(this, true);\r
380                 };\r
381 \r
382                 proto._canScript = function(script) {return true};\r
383 \r
384 //              proto._delay = function(eval, sc, millis) {\r
385 //    alert("_delay???")\r
386 //              // does not take into account that scripts may be added after this and\r
387 //              // need to be cached.\r
388 //                      this._delayID = setTimeout(function(){eval.resumeEval(sc,false)}, millis);              \r
389 //              }\r
390 /*\r
391                 proto._createDomNode = function(id, data) { // moved to org.jmol.adapter.readers.xml.XmlReader.java\r
392                         id = this._id + "_" + id;\r
393                         var d = document.getElementById(id);\r
394                         if (d)\r
395                                 document.body.removeChild(d);\r
396                         if (!data)\r
397                                 return;\r
398                         if (data.indexOf("<?") == 0)\r
399                                 data = data.substring(data.indexOf("<", 1));\r
400                         if (data.indexOf("/>") >= 0) {\r
401                                 // no doubt there is a more efficient way to do this.\r
402                                 // Firefox, at least, does not recognize "/>" in HTML blocks\r
403                                 // that are added this way.\r
404                                 var D = data.split("/>");\r
405                                 for (var i = D.length - 1; --i >= 0;) {\r
406                                         var s = D[i];\r
407                                         var pt = s.lastIndexOf("<") + 1;\r
408                                         var pt2 = pt;\r
409                                         var len = s.length;\r
410                                         var name = "";\r
411                                         while (++pt2 < len) {\r
412                                                 if (" \t\n\r".indexOf(s.charAt(pt2))>= 0) {\r
413                                                         var name = s.substring(pt, pt2);\r
414                                                         D[i] = s + "></"+name+">";\r
415                                                         break;\r
416                                                 }               \r
417                                         }\r
418                                 }\r
419                                 data = D.join('');\r
420                         }\r
421                         d = document.createElement("_xml")\r
422                         d.id = id;\r
423                         d.innerHTML = data;\r
424                         d.style.display = "none";\r
425                         document.body.appendChild(d);\r
426                         return d;\r
427                 }               \r
428 */\r
429                 proto.equals = function(a) { return this == a };\r
430                 proto.clone = function() { return this };\r
431                 proto.hashCode = function() { return parseInt(this._uniqueId) };  \r
432 \r
433 \r
434                 proto._processGesture = function(touches) {\r
435                         return this._appletPanel.processTwoPointGesture(touches);\r
436                 }\r
437 \r
438                 proto._processEvent = function(type, xym) {\r
439                         this._appletPanel.processMouseEvent(type,xym[0],xym[1],xym[2],System.currentTimeMillis());\r
440                 }\r
441 \r
442                 proto._resize = function() {\r
443                         var s = "__resizeTimeout_" + this._id;\r
444                         // only at end\r
445                         if (Jmol[s])\r
446                                 clearTimeout(Jmol[s]);\r
447                         var me = this;\r
448                         Jmol[s] = setTimeout(function() {Jmol._repaint(me, true);Jmol[s]=null}, 100);\r
449                 }\r
450 \r
451                 return proto;\r
452         };\r
453 \r
454         Jmol._repaint = function(applet, asNewThread) {\r
455                 // asNewThread: true is from RepaintManager.repaintNow()\r
456                 // false is from Repaintmanager.requestRepaintAndWait()\r
457                 // called from apiPlatform Display.repaint()\r
458 \r
459                 //alert("_repaint " + Clazz.getStackTrace())\r
460                 if (!applet || !applet._appletPanel)return;\r
461 \r
462                 // asNewThread = false;\r
463                 var container = Jmol.$(applet, "appletdiv");\r
464                 var w = Math.round(container.width());\r
465                 var h = Math.round(container.height());\r
466                 if (applet._is2D && (applet._canvas.width != w || applet._canvas.height != h)) {\r
467                         applet._newCanvas(true);\r
468                         applet._appletPanel.setDisplay(applet._canvas);\r
469                 }\r
470                 applet._appletPanel.setScreenDimension(w, h);\r
471     var f = function(){\r
472       if (applet._appletPanel.paint)\r
473         applet._appletPanel.paint(null);\r
474       else\r
475         applet._appletPanel.update(null)\r
476     };\r
477                 if (asNewThread) {\r
478                         setTimeout(f);\r
479                 } else {\r
480       f();\r
481                 }\r
482                 // System.out.println(applet._appletPanel.getFullName())\r
483         }\r
484 \r
485         Jmol._getHiddenCanvas = function(applet, id, width, height, forceNew) {\r
486                 id = applet._id + "_" + id;\r
487                 var d = document.getElementById(id);\r
488                 if (d && forceNew) {\r
489                         d = null;\r
490                 }\r
491                 if (!d)\r
492                         d = document.createElement( 'canvas' );\r
493                         // for some reason both these need to be set, or maybe just d.width?\r
494                 d.width = d.style.width = width;\r
495                 d.height = d.style.height = height;\r
496                 // d.style.display = "none";\r
497                 if (d.id != id) {\r
498                         d.id = id;\r
499                 }\r
500                 return d;\r
501         }\r
502 \r
503         Jmol._loadImage = function(platform, echoNameAndPath, bytes, fOnload, image) {\r
504         // bytes would be from a ZIP file -- will have to reflect those back from\r
505         // server as an image after conversion to base64\r
506         // ah, but that's a problem, because that image would be needed to be\r
507         // posted, but you can't post an image call.\r
508         // so we would have to go with <image data:> which does not work in all\r
509         // browsers. Hmm.\r
510 \r
511                 var path = echoNameAndPath[1];\r
512 \r
513                 if (image == null) {\r
514                         var image = new Image();\r
515                         image.onload = function() {Jmol._loadImage(platform, echoNameAndPath, null, fOnload, image)};\r
516 \r
517                         if (bytes != null) {      \r
518                                 bytes = J.io.Base64.getBase64(bytes).toString();      \r
519                                 var filename = path.substring(url.lastIndexOf("/") + 1);                                    \r
520                                 var mimetype = (filename.indexOf(".png") >= 0 ? "image/png" : filename.indexOf(".jpg") >= 0 ? "image/jpg" : "");\r
521                                  // now what?\r
522                         }\r
523                         image.src = path;\r
524                         return true; // as far as we can tell!\r
525                 }\r
526                 var width = image.width;\r
527                 var height = image.height; \r
528                 var id = "echo_" + echoNameAndPath[0];  \r
529                 var canvas = Jmol._getHiddenCanvas(platform.vwr.html5Applet, id, width, height, true);\r
530                 canvas.imageWidth = width;\r
531                 canvas.imageHeight = height;\r
532                 canvas.id = id;\r
533                 canvas.image=image;\r
534                 Jmol._setCanvasImage(canvas, width, height);\r
535                 // return a null canvas and the error in path if there is a problem\r
536                 fOnload(canvas,path);\r
537         };\r
538 \r
539         Jmol._setCanvasImage = function(canvas, width, height) {\r
540     // called from org.jmol.awtjs2d.Platform\r
541                 canvas.buf32 = null;\r
542                 canvas.width = width;\r
543                 canvas.height = height;\r
544                 canvas.getContext("2d").drawImage(canvas.image, 0, 0, width, height);\r
545         };\r
546 \r
547 })(Jmol);\r