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]