| <?xml version="1.0"?> |
| <!DOCTYPE document SYSTEM "./dtd/document-v10.dtd"> |
| |
| <!-- |
| |
| Copyright 2001-2003 The Apache Software Foundation |
| |
| Licensed under the Apache License, Version 2.0 (the "License"); |
| you may not use this file except in compliance with the License. |
| You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| --> |
| <!-- ========================================================================= --> |
| <!-- author cjolif@ilog.fr --> |
| <!-- version $Id$ --> |
| <!-- ========================================================================= --> |
| <document> |
| <header> |
| <title>How to use scripting in Batik?</title> |
| <authors> |
| <person name="Christophe Jolif" email="cjolif@ilog.fr"/> |
| </authors> |
| </header> |
| |
| <body> |
| <s1 title="Introduction"> |
| <p> |
| What follows is a little introduction to scripting |
| basics, an example of how it could be useful |
| and ways to go a little bit further. |
| </p> |
| |
| <ul> |
| <li><link href="#scriptingBasics">Scripting Basics</link></li> |
| <li><link href="#howToUseScripting">How to use Scripting in Batik</link></li> |
| <li><link href="#goingFurther">Going Further</link></li> |
| <ul> |
| <li><link href="#customizeRhino">Customize the Rhino interpreter</link></li> |
| <li><link href="#haveYourOwn">Have your own interpreter</link></li> |
| </ul> |
| </ul> |
| </s1> |
| |
| <anchor id="scriptingBasics"/> |
| <s1 title="Scripting Basics"> |
| <p> |
| As the ECMAScript (JavaScript) language is one of the |
| most popular scripting language and as the SVG |
| specification states that an SVG conforming |
| implementation must support it, the ECMAScript language |
| is supported in Batik through the Mozilla ECMAScript |
| interpreter called |
| <link href="http://www.mozilla.org/rhino/bsf.html">Rhino</link> |
| (<code>js.jar</code> ). Even if it is the only |
| scripting language provided with standard with the Batik |
| distribution, other languages such a Python or Tcl can |
| also be <link href="install.html#optionalComponents"> |
| supported</link>. |
| </p> |
| <p><strong>Note:</strong>All examples in this section will use |
| ECMAScript.</p> |
| <p> |
| There are two places in an SVG file where you can put scripts. |
| </p> |
| <p> |
| The first one is in the <code><script></code> |
| element where you can put the definition of your |
| functions or some general code to be executed when the |
| element will be read. |
| </p> |
| <source> |
| |
| <svg width="100" height="100"> |
| <script type="text/ecmascript"> |
| // ECMAScript code to be executed |
| </script> |
| <!-- Your SVG elements --> |
| </svg></source> |
| <p> |
| You can also put script in response to user or document events using attributes on SVG elements. |
| As shown in the previous example, the scripting language must be set on the <script> element. |
| However for event handling the default language type "<code>text/ecmascript</code>" is already set. |
| If you want to change it you can use the <code>contentScriptType</code> attribute on the <code><svg></code> element. |
| </p> |
| <p> |
| In most cases, the event attribute will only call a function defined in a <code><script></code> |
| section, however as you can see below it can also contains regular code. |
| </p> |
| <source> |
| |
| <svg width="100" height="100"> |
| <rect x="0" y="0" width="10" height="10" |
| onclick="evt.target.setAttribute('fill', 'blue')"/> |
| <!-- Your SVG elements --> |
| </svg></source> |
| <p>For more information on using scripting in SVG you can have a look at:</p> |
| <ul> |
| <li><link href="http://www.w3.org/TR/SVG/script.html">scripting chapter of SVG specification</link> for advanced information on scripting in SVG.</li> |
| <li><link href="http://www.ecma.ch/ecma1/stand/ecma-262.htm">ECMAScript specification</link> for advanced information on ECMAScript language.</li> |
| </ul> |
| </s1> |
| |
| |
| <anchor id="howToUseScripting"/> |
| <s1 title="How to use Scripting in Batik"> |
| <p>The following simplified example that you can find in your Batik distribution displays a simple message in response to user events:</p> |
| <source> |
| <svg width="450" height="500" viewBox="0 0 450 500"> |
| <script type="text/ecmascript"> |
| |
| function showDialog(msg) { |
| alert(msg); |
| } |
| </script> |
| <g> |
| <circle cx="137.5" cy="110" r="20" style="fill:crimson" |
| onmousedown="showDialog('onmousedown')"/> |
| <circle cx="312.5" cy="110" r="20" style="fill:crimson" |
| onmouseup="showDialog('onmouseup')"/> |
| </g> |
| <g transform="translate(0 80)"> |
| <circle cx="137.5" cy="110" r="20" style="fill:crimson" |
| onmouseover="showDialog('onmouseover')"/> |
| <circle cx="312.5" cy="110" r="20" style="fill:crimson" |
| onmouseout="showDialog('onmouseout')"/> |
| </g> |
| <g transform="translate(0 160)"> |
| <circle cx="137.5" cy="110" r="20" style="fill:crimson" |
| onmousemove="showDialog('onmousemove')"/> |
| <circle cx="312.5" cy="110" r="20" style="fill:crimson" |
| onclick="showDialog('onclick')"/> |
| </g> |
| </svg> |
| </source> |
| <p> |
| You can see in the above example that the <code><script></code> element contains |
| the definition of a single function: <code>showDialog</code>. |
| </p> |
| <p> |
| This function will be called thanks to the Batik event handling mechanism in answer to |
| user events. The function is registered to listen to mouse events on the various <code><circle></code> |
| elements. |
| </p> |
| </s1> |
| |
| <anchor id="goingFurther"/> |
| <s1 title="Going Further"> |
| <p> |
| Batik as an extensible API provides the ability to customize the scripting module to |
| go beyond the simple support of ECMAScript language in SVG files. |
| </p> |
| |
| |
| <anchor id="customizeRhino"/> |
| <s2 title="Customize the Rhino interpreter"> |
| <p> |
| A useful example of customization of the Rhino interpreter comes from the fact that the |
| ECMAScript specification doesn't provide any I/O predefined facilities to interact with |
| the console . However it is very common for ECMAScript compatible languages to provide |
| a function named <code>print</code> to output messages to the console. We will describe |
| here an example of cutomization of the Batik Rhino interpreter to add such functionality to it. |
| </p> |
| <p> |
| You should first subclass the default Batik ECMAScript interpreter to add the functionality |
| to it as below. |
| </p> |
| <source> |
| |
| public class ExtendedRhinoInterpreter extends RhinoIntepreter { |
| public ExtendedRhinoInterpreter() { |
| super(); // build RhinoInterpreter |
| final String[] names = { "print" } |
| try { |
| getGlobalObject(). |
| defineFunctionProperties(names, |
| ExtendedRhinoIntepreter.class, |
| ScriptableObject.DONTENUM); |
| } catch (PropertyException e) { |
| throw new Error(e.getMessage()); |
| } |
| } |
| |
| public static void print(Context cx, Scriptable thisObj, |
| Object[] args, Function funObj) { |
| for (int i=0; i < args.length; i++) { |
| if (i > 0) |
| System.out.print(" "); |
| |
| // Convert the arbitrary JavaScript value into |
| // a string form. |
| String s = Context.toString(args[i]); |
| |
| System.out.print(s); |
| } |
| System.out.println(); |
| } |
| }</source> |
| <p> |
| Now, you should tell to Batik to use this interpreter instead of the default one. |
| For that, you should first define a factory to create instances of your interpreter. |
| </p> |
| <source> |
| |
| public class ExtendedRhinoInterpreterFactory |
| implements InterpreterFactory { |
| public Interpreter createInterpreter() { |
| return new ExtendedRhinoInterpreter(); |
| } |
| }</source> |
| <p> |
| Then, you should build an <code>IntepreterPool</code> that will use this factory |
| and set the pool on the <code>BridgeContext</code> of your application. |
| </p> |
| <source> |
| |
| org.apache.batik.bridge BridgeContext ctx = ...; |
| org.apache.batik.script.InterpreterPool pool = |
| new org.apache.batik.script.InterpreterPool(); |
| pool.putInterpreterFactory("text/ecmascript", |
| new ExtendedRhinoInterpreterFactory()); |
| ctx.setIntepreterPool(pool);</source> |
| <p> |
| For example if you are using the Batik SVGBrowser application you should be able to use |
| the previous piece of code on a subclass of the <code>JSVGCanvas</code> class |
| in the <code>createBridgeContext()</code> method. |
| </p> |
| </s2> |
| |
| <anchor id="haveYourOwn"/> |
| <s2 title="Have your own interpreter"> |
| <p> |
| If you want to use SVG files with your own scripting language in it, you can do it with |
| Batik. |
| You will need to define your own class of <code>Interpreter</code> and register it |
| to the <code>InterpreterPool</code> with the right type for the language as in the example |
| above. |
| </p> |
| </s2> |
| </s1> |
| </body> |
| </document> |