hillion 02/03/25 03:02:22
Modified: sources/org/apache/batik/bridge
BaseScriptingEnvironment.java
SVGTextElementBridge.java
sources/org/apache/batik/css/engine CSSEngine.java
sources/org/apache/batik/swing/svg JSVGComponent.java
Added: sources/org/apache/batik/bridge Plugin.java
Log:
- Added a dirty region repaint optimization in JSVGComponent,
- fixed a CSS bug (URL updates),
- added mecanism to load java code using a processing instruction.
Revision Changes Path
1.2 +78 -1
xml-batik/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java
Index: BaseScriptingEnvironment.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/bridge/BaseScriptingEnvironment.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BaseScriptingEnvironment.java 6 Mar 2002 17:14:44 -0000 1.1
+++ BaseScriptingEnvironment.java 25 Mar 2002 11:02:22 -0000 1.2
@@ -14,14 +14,19 @@
import java.io.StringReader;
import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
+import java.util.StringTokenizer;
import org.apache.batik.dom.svg.SVGOMDocument;
+import org.apache.batik.dom.util.DOMUtilities;
+import org.apache.batik.dom.util.HashTable;
import org.apache.batik.dom.util.XLinkSupport;
import org.apache.batik.script.Interpreter;
@@ -33,6 +38,7 @@
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
+import org.w3c.dom.ProcessingInstruction;
import org.w3c.dom.events.DocumentEvent;
import org.w3c.dom.events.Event;
@@ -45,14 +51,28 @@
* This class is the base class for SVG scripting.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a>
- * @version $Id: BaseScriptingEnvironment.java,v 1.1 2002/03/06 17:14:44 tkormann
Exp $
+ * @version $Id: BaseScriptingEnvironment.java,v 1.2 2002/03/25 11:02:22 hillion
Exp $
*/
public class BaseScriptingEnvironment {
+ protected final static String BATIK_PLUGIN_PI = "batik-plugin";
+
/**
* Tells whether the given SVG document is dynamic.
*/
public static boolean isDynamicDocument(Document doc) {
+ for (Node n = doc.getFirstChild();
+ n != null && n.getNodeType() != n.ELEMENT_NODE;
+ n = n.getNextSibling()) {
+ if (n.getNodeType() != n.PROCESSING_INSTRUCTION_NODE) {
+ continue;
+ }
+ ProcessingInstruction pi = (ProcessingInstruction)n;
+ if (!BATIK_PLUGIN_PI.equals(pi.getTarget())) {
+ continue;
+ }
+ return true;
+ }
Element elt = doc.getDocumentElement();
if (elt.getNamespaceURI().equals(SVGConstants.SVG_NAMESPACE_URI)) {
if (elt.getAttributeNS
@@ -205,6 +225,63 @@
* Loads the scripts contained in the <script> elements.
*/
public void loadScripts() {
+ org.apache.batik.script.Window window = null;
+ for (Node n = document.getFirstChild();
+ n != null && n.getNodeType() != n.ELEMENT_NODE;
+ n = n.getNextSibling()) {
+ if (n.getNodeType() != n.PROCESSING_INSTRUCTION_NODE) {
+ continue;
+ }
+ ProcessingInstruction pi = (ProcessingInstruction)n;
+ if (!BATIK_PLUGIN_PI.equals(pi.getTarget())) {
+ continue;
+ }
+
+ if (window == null) {
+ window = createWindow();
+ }
+
+ try {
+ HashTable pattrs = new HashTable();
+ DOMUtilities.parseStyleSheetPIData(pi.getData(), pattrs);
+
+ URL url = ((SVGOMDocument)document).getURLObject();
+ String base = (String)pattrs.get("codebase");
+ if (base == null) {
+ url = new URL(url, ".");
+ } else {
+ url = new URL(url, base);
+ }
+
+ URL[] urls;
+
+ String archive = (String)pattrs.get("archive");
+ if (archive != null) {
+ List lst = new ArrayList();
+ lst.add(url);
+ StringTokenizer st = new StringTokenizer(archive, ", ");
+ while (st.hasMoreTokens()) {
+ String ar = st.nextToken();
+ lst.add(new URL(url, ar));
+ }
+ urls = (URL[])lst.toArray(new URL[] {});
+ } else {
+ urls = new URL[] { url };
+ }
+
+ URLClassLoader cl = new URLClassLoader(urls);
+ String cname = (String)pattrs.get("code");
+ Class c = cl.loadClass(cname);
+ Plugin p = (Plugin)c.newInstance();
+ p.run(document, window);
+ } catch (Exception ex) {
+ UserAgent ua = bridgeContext.getUserAgent();
+ if (ua != null) {
+ ua.displayError(ex);
+ }
+ }
+ }
+
NodeList scripts = document.getElementsByTagNameNS
(SVGConstants.SVG_NAMESPACE_URI, SVGConstants.SVG_SCRIPT_TAG);
int len = scripts.getLength();
1.59 +24 -3
xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java
Index: SVGTextElementBridge.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -r1.58 -r1.59
--- SVGTextElementBridge.java 25 Mar 2002 02:52:27 -0000 1.58
+++ SVGTextElementBridge.java 25 Mar 2002 11:02:22 -0000 1.59
@@ -69,7 +69,7 @@
*
* @author <a href="[EMAIL PROTECTED]">Stephane Hillion</a>
* @author <a href="[EMAIL PROTECTED]">Bill Haneman</a>
- * @version $Id: SVGTextElementBridge.java,v 1.58 2002/03/25 02:52:27 tkormann Exp $
+ * @version $Id: SVGTextElementBridge.java,v 1.59 2002/03/25 11:02:22 hillion Exp $
*/
public class SVGTextElementBridge extends AbstractGraphicsNodeBridge {
@@ -786,7 +786,18 @@
for (Node child = element.getFirstChild();
child != null;
child = child.getNextSibling()) {
- if (child.getNodeType() == Node.ELEMENT_NODE) {
+ if (child.getNodeType() != Node.ELEMENT_NODE) {
+ continue;
+ }
+ if (!SVG_NAMESPACE_URI.equals(child.getNamespaceURI())) {
+ continue;
+ }
+ String ln = child.getLocalName();
+ if (ln.equals(SVG_TSPAN_TAG) ||
+ ln.equals(SVG_ALT_GLYPH_TAG) ||
+ ln.equals(SVG_A_TAG) ||
+ ln.equals(SVG_TEXT_PATH_TAG) ||
+ ln.equals(SVG_TREF_TAG)) {
addGlyphPositionAttributes(as, (Element)child, ctx);
}
}
@@ -906,7 +917,17 @@
for (Node child = element.getFirstChild();
child != null;
child = child.getNextSibling()) {
- if (child.getNodeType() == Node.ELEMENT_NODE) {
+ if (child.getNodeType() != Node.ELEMENT_NODE) {
+ }
+ if (!SVG_NAMESPACE_URI.equals(child.getNamespaceURI())) {
+ continue;
+ }
+ String ln = child.getLocalName();
+ if (ln.equals(SVG_TSPAN_TAG) ||
+ ln.equals(SVG_ALT_GLYPH_TAG) ||
+ ln.equals(SVG_A_TAG) ||
+ ln.equals(SVG_TEXT_PATH_TAG) ||
+ ln.equals(SVG_TREF_TAG)) {
Element childElement = (Element)child;
TextDecoration td = getTextDecoration(childElement, node,
textDecoration, ctx);
1.1 xml-batik/sources/org/apache/batik/bridge/Plugin.java
Index: Plugin.java
===================================================================
/*****************************************************************************
* Copyright (C) The Apache Software Foundation. All rights reserved. *
* ------------------------------------------------------------------------- *
* This software is published under the terms of the Apache Software License *
* version 1.1, a copy of which has been included with this distribution in *
* the LICENSE file. *
*****************************************************************************/
package org.apache.batik.bridge;
import org.apache.batik.script.Window;
import org.w3c.dom.Document;
/**
* This object an object invoked when a document is beeing loaded.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a>
* @version $Id: Plugin.java,v 1.1 2002/03/25 11:02:22 hillion Exp $
*/
public interface Plugin {
/**
* Called when the plugin is loaded.
*/
void run(Document doc, Window win);
}
1.5 +8 -4 xml-batik/sources/org/apache/batik/css/engine/CSSEngine.java
Index: CSSEngine.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/css/engine/CSSEngine.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- CSSEngine.java 21 Mar 2002 10:59:34 -0000 1.4
+++ CSSEngine.java 25 Mar 2002 11:02:22 -0000 1.5
@@ -58,7 +58,7 @@
* This is the base class for all the CSS engines.
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a>
- * @version $Id: CSSEngine.java,v 1.4 2002/03/21 10:59:34 hillion Exp $
+ * @version $Id: CSSEngine.java,v 1.5 2002/03/25 11:02:22 hillion Exp $
*/
public abstract class CSSEngine {
@@ -576,7 +576,6 @@
putAuthorProperty(result, idx, v, false,
StyleMap.NON_CSS_ORIGIN);
} catch (Exception e) {
- e.printStackTrace();
String m = e.getMessage();
String s =
Messages.formatMessage("property.syntax.error.at",
@@ -1360,6 +1359,7 @@
case MutationEvent.MODIFICATION:
String decl = evt.getNewValue();
if (decl.length() > 0) {
+ element = elt;
try {
parser.setSelectorFactory(CSSSelectorFactory.INSTANCE);
parser.setConditionFactory(CSSConditionFactory.INSTANCE);
@@ -1373,10 +1373,12 @@
Messages.formatMessage("style.syntax.error.at",
new Object[] { documentURI.toString(),
styleLocalName,
- style,
+ decl,
(m == null) ? "" : m });
throw new DOMException(DOMException.SYNTAX_ERR, s);
}
+ element = null;
+ cssBaseURI = null;
}
// Fall through
@@ -1652,6 +1654,7 @@
boolean comp = style.isComputed(idx);
+ element = elt;
try {
LexicalUnit lu;
lu = parser.parsePropertyValue(evt.getNewValue());
@@ -1661,7 +1664,6 @@
style.putValue(idx, v);
style.putOrigin(idx, StyleMap.NON_CSS_ORIGIN);
} catch (Exception e) {
- e.printStackTrace();
String m = e.getMessage();
String s =
Messages.formatMessage("property.syntax.error.at",
@@ -1671,6 +1673,8 @@
(m == null) ? "" : m });
throw new DOMException(DOMException.SYNTAX_ERR, s);
}
+ element = null;
+ cssBaseURI = null;
if (!comp) {
// The previous value was not computed: nobody is
1.49 +162 -3 xml-batik/sources/org/apache/batik/swing/svg/JSVGComponent.java
Index: JSVGComponent.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/swing/svg/JSVGComponent.java,v
retrieving revision 1.48
retrieving revision 1.49
diff -u -r1.48 -r1.49
--- JSVGComponent.java 18 Mar 2002 10:28:27 -0000 1.48
+++ JSVGComponent.java 25 Mar 2002 11:02:22 -0000 1.49
@@ -26,6 +26,7 @@
import java.net.MalformedURLException;
import java.net.URL;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -181,7 +182,7 @@
* building/rendering a document (invalid XML file, missing attributes...).</p>
*
* @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a>
- * @version $Id: JSVGComponent.java,v 1.48 2002/03/18 10:28:27 hillion Exp $
+ * @version $Id: JSVGComponent.java,v 1.49 2002/03/25 11:02:22 hillion Exp $
*/
public class JSVGComponent extends JGVTComponent {
@@ -1238,10 +1239,16 @@
List l = e.getDirtyAreas();
if (l != null) {
+ Dimension dim = getSize();
+ List ml = mergeRectangles(l, 0, 0,
+ dim.width - 1,
+ dim.height - 1);
+ if (ml.size() < l.size()) {
+ l = ml;
+ }
+
Iterator i = l.iterator();
while (i.hasNext()) {
- // CHECK: This may not be the
- // fastest way to do this...
Rectangle r = (Rectangle)i.next();
paintImmediately(r);
}
@@ -2261,5 +2268,157 @@
FEATURES.add(SVGConstants.SVG_ORG_W3C_SVG_FEATURE);
FEATURES.add(SVGConstants.SVG_ORG_W3C_SVG_LANG_FEATURE);
FEATURES.add(SVGConstants.SVG_ORG_W3C_SVG_STATIC_FEATURE);
+ }
+
+ private final static int SPLIT_THRESHOLD = 128;
+
+ /**
+ * Merges the given Rectangles.
+ */
+ protected List mergeRectangles(List rects,
+ int x1, int y1, int x2, int y2) {
+ if (rects.size() <= 1) {
+ return rects;
+ }
+
+ int w = x2 - x1;
+ int h = y2 - y1;
+
+ if (w < SPLIT_THRESHOLD && h < SPLIT_THRESHOLD) {
+ // Merges all the rectangles
+ List result = new ArrayList();
+ Iterator it = rects.iterator();
+ Rectangle rect = (Rectangle)it.next();
+ while (it.hasNext()) {
+ Rectangle r = (Rectangle)it.next();
+ rect.add(r);
+ }
+ result.add(rect);
+ return result;
+ }
+
+ if (w < SPLIT_THRESHOLD) {
+ // Split horizontally
+ List h1 = new ArrayList();
+ List h2 = new ArrayList();
+ int dy = h / 2;
+ int av = y1 + dy;
+ Iterator it = rects.iterator();
+ while (it.hasNext()) {
+ Rectangle r = (Rectangle)it.next();
+ if (r.y < av) {
+ if (r.y + r.height > av) {
+ // The rectangle intersects the two regions
+ h2.add(new Rectangle(r.x, av, r.width,
+ (r.height + r.y) - av));
+ r = new Rectangle(r.x, r.y, r.width, av - r.y);
+ }
+ h1.add(r);
+ } else {
+ h2.add(r);
+ }
+ }
+ h1 = mergeRectangles(h1, x1, y1, x2, av - 1);
+ h2 = mergeRectangles(h2, x1, av, x2, y2);
+ h1.addAll(h2);
+ return h1;
+ }
+
+ if (h < SPLIT_THRESHOLD) {
+ // Split vertically
+ List w1 = new ArrayList();
+ List w2 = new ArrayList();
+ int dx = w / 2;
+ int av = x1 + dx;
+ Iterator it = rects.iterator();
+ while (it.hasNext()) {
+ Rectangle r = (Rectangle)it.next();
+ if (r.x < av) {
+ if (r.x + r.width > av) {
+ // The rectangle intersects the two regions
+ w2.add(new Rectangle(av, r.y,
+ (r.width + r.x) - av, r.height));
+ r = new Rectangle(r.x, r.y, av - r.x, r.height);
+ }
+ w1.add(r);
+ } else {
+ w2.add(r);
+ }
+ }
+ w1 = mergeRectangles(w1, x1, y1, av - 1, y2);
+ w2 = mergeRectangles(w2, av, y1, x2, y2);
+ w1.addAll(w2);
+ return w1;
+ }
+
+ // Split the region into four regions
+ List wh1 = new ArrayList();
+ List wh2 = new ArrayList();
+ List wh3 = new ArrayList();
+ List wh4 = new ArrayList();
+ int dx = w / 2;
+ int dy = h / 2;
+ int wav = x1 + dx;
+ int hav = y1 + dy;
+ Iterator it = rects.iterator();
+ while (it.hasNext()) {
+ Rectangle r = (Rectangle)it.next();
+ if (r.x < wav) {
+ if (r.y < hav) {
+ boolean c1 = r.x + r.width > wav;
+ boolean c2 = r.y + r.height > hav;
+ if (c1 && c2) {
+ // The rectangle intersects the four regions
+ wh2.add(new Rectangle(wav, r.y, (r.width + r.x) - wav,
+ hav - r.y));
+ wh3.add(new Rectangle(r.x, hav, wav - r.x,
+ (r.height + r.y) - hav));
+ wh4.add(new Rectangle(wav, hav,
+ (r.width + r.x) - wav,
+ (r.height + r.y) - hav));
+ r = new Rectangle(r.x, r.y, wav - r.x, hav - r.y);
+ } else if (c1) {
+ // The rectangle intersects two regions
+ wh2.add(new Rectangle(wav, r.y, (r.width + r.x) - wav,
+ r.height));
+ r = new Rectangle(r.x, r.y, wav - r.x, r.height);
+ } else if (c2) {
+ // The rectangle intersects two regions
+ wh3.add(new Rectangle(r.x, hav, r.width,
+ (r.height + r.y) - hav));
+ r = new Rectangle(r.x, r.y, r.width, hav - r.y);
+ }
+ wh1.add(r);
+ } else {
+ if (r.x + r.width > wav) {
+ // The rectangle intersects two regions
+ wh4.add(new Rectangle(wav, r.y, (r.width + r.x) - wav,
+ r.height));
+ r = new Rectangle(r.x, r.y, wav - r.x, r.height);
+ }
+ wh3.add(r);
+ }
+ } else {
+ if (r.y < hav) {
+ if (r.y + r.height > hav) {
+ // The rectangle intersects two regions
+ wh4.add(new Rectangle(r.x, hav, r.width,
+ (r.height + r.y) - hav));
+ r = new Rectangle(r.x, r.y, r.width, hav - r.y);
+ }
+ wh2.add(r);
+ } else {
+ wh4.add(r);
+ }
+ }
+ }
+ wh1 = mergeRectangles(wh1, x1, y1, wav - 1, hav - 1);
+ wh2 = mergeRectangles(wh2, wav, y1, x2, y2);
+ wh3 = mergeRectangles(wh3, x1, hav, wav - 1, y2);
+ wh4 = mergeRectangles(wh4, wav, hav, x2, y2);
+ wh1.addAll(wh2);
+ wh1.addAll(wh3);
+ wh1.addAll(wh4);
+ return wh1;
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]