deweese 02/02/19 10:01:29 Modified: sources/org/apache/batik/bridge RepaintManager.java SVGImageElementBridge.java sources/org/apache/batik/ext/awt/geom RectListManager.java sources/org/apache/batik/gvt AbstractGraphicsNode.java UpdateTracker.java sources/org/apache/batik/gvt/filter GraphicsNodeRable8Bit.java GraphicsNodeRed8Bit.java sources/org/apache/batik/gvt/renderer DynamicRenderer.java Log: 1) The 'image' element now respects xml:base. (candidate fix for 1.1.2 release) 2) Fixed a bug where some antialiasing was not always cleaned up in animation 3) DynamicRenderer now uses RectListManager for dirty regions. 4) Fixed a bug in one of the constructors of RectListManager. 5) GraphicsNodeRable now drops it's cached GraphicsNodeRed if the bounds of the asociated GraphicsNode change. 6) Updated Tracker no longer enters the same dirty region twice when an object suddenly starts having bounds. Revision Changes Path 1.7 +12 -2 xml-batik/sources/org/apache/batik/bridge/RepaintManager.java Index: RepaintManager.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/RepaintManager.java,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- RepaintManager.java 18 Feb 2002 09:11:58 -0000 1.6 +++ RepaintManager.java 19 Feb 2002 18:01:29 -0000 1.7 @@ -12,6 +12,7 @@ import java.awt.Shape; import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; import java.util.ArrayList; import java.util.Iterator; @@ -25,7 +26,7 @@ * This class manages the rendering of a GVT tree. * * @author <a href="mailto:[EMAIL PROTECTED]">Stephane Hillion</a> - * @version $Id: RepaintManager.java,v 1.6 2002/02/18 09:11:58 hillion Exp $ + * @version $Id: RepaintManager.java,v 1.7 2002/02/19 18:01:29 deweese Exp $ */ public class RepaintManager { @@ -150,7 +151,16 @@ Iterator i = areas.iterator(); while (i.hasNext()) { Shape s = (Shape)i.next(); - Rectangle r = at.createTransformedShape(s).getBounds(); + s = at.createTransformedShape(s); + Rectangle2D r2d = s.getBounds2D(); + int x0 = (int)Math.floor(r2d.getX()); + int y0 = (int)Math.floor(r2d.getY()); + int x1 = (int)Math.ceil(r2d.getX()+r2d.getWidth()); + int y1 = (int)Math.ceil(r2d.getY()+r2d.getHeight()); + // This rectangle must be outset one pixel to ensure + // it includes the effects of anti-aliasing on object.s + Rectangle r = new Rectangle(x0-1, y0-1, x1-x0+3, y1-y0+3); + rects.add(r); } 1.38 +10 -4 xml-batik/sources/org/apache/batik/bridge/SVGImageElementBridge.java Index: SVGImageElementBridge.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGImageElementBridge.java,v retrieving revision 1.37 retrieving revision 1.38 diff -u -r1.37 -r1.38 --- SVGImageElementBridge.java 15 Feb 2002 14:58:44 -0000 1.37 +++ SVGImageElementBridge.java 19 Feb 2002 18:01:29 -0000 1.38 @@ -22,6 +22,7 @@ import org.apache.batik.dom.svg.SVGOMDocument; import org.apache.batik.dom.util.XLinkSupport; +import org.apache.batik.dom.svg.XMLBaseSupport; import org.apache.batik.ext.awt.color.ICCColorSpaceExt; import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit; import org.apache.batik.ext.awt.image.renderable.Filter; @@ -52,7 +53,7 @@ * Bridge class for the <image> element. * * @author <a href="mailto:[EMAIL PROTECTED]">Thierry Kormann</a> - * @version $Id: SVGImageElementBridge.java,v 1.37 2002/02/15 14:58:44 tkormann Exp $ + * @version $Id: SVGImageElementBridge.java,v 1.38 2002/02/19 18:01:29 deweese Exp $ */ public class SVGImageElementBridge extends AbstractGraphicsNodeBridge { @@ -104,14 +105,12 @@ GraphicsNode node = null; // try to load the image as an svg document SVGDocument svgDoc = (SVGDocument)e.getOwnerDocument(); - URL baseURL = ((SVGOMDocument)svgDoc).getURLObject(); - ParsedURL purl = new ParsedURL(baseURL, uriStr); // try to load an SVG document DocumentLoader loader = ctx.getDocumentLoader(); URIResolver resolver = new URIResolver(svgDoc, loader); try { - Node n = resolver.getNode(purl.toString(), e); + Node n = resolver.getNode(uriStr, e); if (n.getNodeType() == n.DOCUMENT_NODE) { SVGDocument imgDocument = (SVGDocument)n; node = createSVGImageNode(ctx, e, imgDocument); @@ -123,6 +122,13 @@ } if (node == null) { + String baseURI = XMLBaseSupport.getCascadedXMLBase(e); + ParsedURL purl; + if (baseURI == null) + purl = new ParsedURL(uriStr); + else + purl = new ParsedURL(baseURI, uriStr); + // try to load the image as a raster image (JPG or PNG) node = createRasterImageNode(ctx, e, purl); } 1.2 +17 -8 xml-batik/sources/org/apache/batik/ext/awt/geom/RectListManager.java Index: RectListManager.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/geom/RectListManager.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- RectListManager.java 12 Feb 2002 18:17:44 -0000 1.1 +++ RectListManager.java 19 Feb 2002 18:01:29 -0000 1.2 @@ -27,7 +27,7 @@ * this reason it uses Rectangle not Rectangle2D). * * @author <a href="mailto:[EMAIL PROTECTED]">Thomas DeWeese</a> - * @version $Id: RectListManager.java,v 1.1 2002/02/12 18:17:44 deweese Exp $ */ + * @version $Id: RectListManager.java,v 1.2 2002/02/19 18:01:29 deweese Exp $ */ public class RectListManager implements Collection { Rectangle [] rects = null; @@ -37,7 +37,7 @@ * The comparator used to sort the elements of this List. * Sorts on x value of Rectangle. */ - public static Comparator comparator; + public static Comparator comparator = new RectXComparator(); /** * Construct a <tt>RectListManager</tt> from a Collection of Rectangles @@ -61,9 +61,21 @@ * any null entries. */ public RectListManager(Rectangle [] rects) { - this.rects = new Rectangle[rects.length]; - size = rects.length; - System.arraycopy(rects, 0, this.rects, 0, size); + this(rects, 0, rects.length); + } + + /** + * Construct a <tt>RectListManager</tt> from an Array of + * <tt>Rectangles</tt> + * @param rects Array of <tt>Rectangles</tt>, must not contain + * any null entries in the range [off, off+sz-1]. + * @param off The offset to start copying from in rects. + * @param sz The number of entries to copy from rects. + */ + public RectListManager(Rectangle [] rects, int off, int sz) { + this.size = sz; + this.rects = new Rectangle[sz]; + System.arraycopy(rects, off, this.rects, 0, sz); Arrays.sort(this.rects, comparator); } @@ -755,9 +767,6 @@ RectXComparator() { } public final int compare(Object o1, Object o2) { - // Treat nulls as inifinate X. - if (o1 == null) return -1; - if (o2 == null) return 1; return ((Rectangle)o1).x-((Rectangle)o2).x; } } 1.35 +1 -15 xml-batik/sources/org/apache/batik/gvt/AbstractGraphicsNode.java Index: AbstractGraphicsNode.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/AbstractGraphicsNode.java,v retrieving revision 1.34 retrieving revision 1.35 diff -u -r1.34 -r1.35 --- AbstractGraphicsNode.java 14 Feb 2002 12:37:54 -0000 1.34 +++ AbstractGraphicsNode.java 19 Feb 2002 18:01:29 -0000 1.35 @@ -54,7 +54,7 @@ * @author <a href="mailto:[EMAIL PROTECTED]">Thierry Kormann</a> * @author <a href="mailto:[EMAIL PROTECTED]">Emmanuel Tissandier</a> * @author <a href="mailto:[EMAIL PROTECTED]">Thomas DeWeese</a> - * @version $Id: AbstractGraphicsNode.java,v 1.34 2002/02/14 12:37:54 tkormann Exp $ + * @version $Id: AbstractGraphicsNode.java,v 1.35 2002/02/19 18:01:29 deweese Exp $ */ public abstract class AbstractGraphicsNode implements GraphicsNode { @@ -885,20 +885,6 @@ ((AbstractGraphicsNode) parent).invalidateGeometryCache(); } bounds = null; - - if (graphicsNodeRable != null) { - GraphicsNodeRable8Bit gnr; - gnr = (GraphicsNodeRable8Bit)graphicsNodeRable.get(); - if (gnr != null) - gnr.clearCache(); - } - - if (enableBackgroundGraphicsNodeRable != null) { - GraphicsNodeRable8Bit gnr = - (GraphicsNodeRable8Bit)enableBackgroundGraphicsNodeRable.get(); - if (gnr != null) - gnr.clearCache(); - } } /** 1.9 +2 -4 xml-batik/sources/org/apache/batik/gvt/UpdateTracker.java Index: UpdateTracker.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/UpdateTracker.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- UpdateTracker.java 14 Feb 2002 12:37:55 -0000 1.8 +++ UpdateTracker.java 19 Feb 2002 18:01:29 -0000 1.9 @@ -29,7 +29,7 @@ * This class tracks the changes on a GVT tree * * @author <a href="mailto:[EMAIL PROTECTED]">Thomas DeWeese</a> - * @version $Id: UpdateTracker.java,v 1.8 2002/02/14 12:37:55 tkormann Exp $ + * @version $Id: UpdateTracker.java,v 1.9 2002/02/19 18:01:29 deweese Exp $ */ public class UpdateTracker extends GraphicsNodeChangeAdapter { @@ -157,13 +157,11 @@ } - Object o = nodeBounds.get(gnWRef); - while (o == null) { + while (!nodeBounds.containsKey(gnWRef)) { nodeBounds.put(gnWRef, gn.getBounds()); gn = gn.getParent(); if (gn == null) break; gnWRef = gn.getWeakReference(); - o = nodeBounds.get(gnWRef); } } 1.16 +17 -8 xml-batik/sources/org/apache/batik/gvt/filter/GraphicsNodeRable8Bit.java Index: GraphicsNodeRable8Bit.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/filter/GraphicsNodeRable8Bit.java,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- GraphicsNodeRable8Bit.java 31 Jan 2002 21:57:35 -0000 1.15 +++ GraphicsNodeRable8Bit.java 19 Feb 2002 18:01:29 -0000 1.16 @@ -40,16 +40,16 @@ * createRendering methods. * * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Hardy</a> - * @version $Id: GraphicsNodeRable8Bit.java,v 1.15 2002/01/31 21:57:35 deweese Exp $ + * @version $Id: GraphicsNodeRable8Bit.java,v 1.16 2002/02/19 18:01:29 deweese Exp $ */ public class GraphicsNodeRable8Bit extends AbstractRable implements GraphicsNodeRable, PaintRable { - private AffineTransform cachedGn2dev = null; - private AffineTransform cachedUsr2dev = null; - private CachableRed cachedRed = null; - + private AffineTransform cachedGn2dev = null; + private AffineTransform cachedUsr2dev = null; + private CachableRed cachedRed = null; + private Rectangle2D cachedBounds = null; /** * Should GraphicsNodeRable call primitivePaint or Paint. */ @@ -103,6 +103,7 @@ cachedRed = null; cachedUsr2dev = null; cachedGn2dev = null; + cachedBounds = null; } /** @@ -258,7 +259,11 @@ gn2dev.concatenate(gn2usr); } - if ((cachedGn2dev != null) && + Rectangle2D bounds2D = getBounds2D(); + + if ((cachedBounds != null) && + (cachedGn2dev != null) && + (cachedBounds.equals(bounds2D)) && (gn2dev.getScaleX() == cachedGn2dev.getScaleX()) && (gn2dev.getScaleY() == cachedGn2dev.getScaleY()) && (gn2dev.getShearX() == cachedGn2dev.getShearX()) && @@ -294,17 +299,21 @@ System.out.println("Old: " + cachedUsr2dev); } - Rectangle2D bounds2D = getBounds2D(); if((bounds2D.getWidth() > 0) && (bounds2D.getHeight() > 0)) { cachedUsr2dev = (AffineTransform)usr2dev.clone(); - cachedGn2dev = gn2dev; + cachedGn2dev = gn2dev; + cachedBounds = bounds2D; cachedRed = new GraphicsNodeRed8Bit (node, usr2dev, usePrimitivePaint, renderContext.getRenderingHints()); return cachedRed; } + cachedUsr2dev = null; + cachedGn2dev = null; + cachedBounds = null; + cachedRed = null; return null; } } 1.11 +4 -7 xml-batik/sources/org/apache/batik/gvt/filter/GraphicsNodeRed8Bit.java Index: GraphicsNodeRed8Bit.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/filter/GraphicsNodeRed8Bit.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- GraphicsNodeRed8Bit.java 18 Sep 2001 21:19:00 -0000 1.10 +++ GraphicsNodeRed8Bit.java 19 Feb 2002 18:01:29 -0000 1.11 @@ -33,7 +33,7 @@ * GraphicsNode on demand for tiles. * * @author <a href="mailto:[EMAIL PROTECTED]">Vincent Hardy</a> - * @version $Id: GraphicsNodeRed8Bit.java,v 1.10 2001/09/18 21:19:00 deweese Exp $ + * @version $Id: GraphicsNodeRed8Bit.java,v 1.11 2002/02/19 18:01:29 deweese Exp $ */ public class GraphicsNodeRed8Bit extends AbstractRed { @@ -63,12 +63,9 @@ // my input data.. AffineTransform at = node2dev; - Rectangle2D bounds2D; - if (usePrimitivePaint) { - bounds2D = node.getPrimitiveBounds(); - } else { - bounds2D = node.getPrimitiveBounds(); - // When not using Primitive paint we return out bounds in + Rectangle2D bounds2D = node.getPrimitiveBounds(); + if (!usePrimitivePaint) { + // When not using Primitive paint we return our bounds in // the nodes parent's user space. This makes sense since // this is the space that we will draw our selves into // (since paint unlike primitivePaint incorporates the 1.8 +68 -9 xml-batik/sources/org/apache/batik/gvt/renderer/DynamicRenderer.java Index: DynamicRenderer.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/renderer/DynamicRenderer.java,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- DynamicRenderer.java 29 Jan 2002 21:46:43 -0000 1.7 +++ DynamicRenderer.java 19 Feb 2002 18:01:29 -0000 1.8 @@ -9,6 +9,7 @@ package org.apache.batik.gvt.renderer; import java.awt.geom.AffineTransform; +import java.awt.geom.Rectangle2D; import java.awt.RenderingHints; import java.awt.Rectangle; import java.awt.Shape; @@ -17,22 +18,25 @@ import java.awt.image.WritableRaster; import java.util.List; -import java.util.ArrayList; import java.util.Iterator; import org.apache.batik.ext.awt.image.rendered.CachableRed; import org.apache.batik.ext.awt.image.rendered.PadRed; import org.apache.batik.ext.awt.image.PadMode; import org.apache.batik.ext.awt.image.GraphicsUtil; +import org.apache.batik.ext.awt.geom.RectListManager; /** * Simple implementation of the Renderer that supports dynamic updates. * * @author <a href="mailto:[EMAIL PROTECTED]">Thierry Kormann</a> - * @version $Id: DynamicRenderer.java,v 1.7 2002/01/29 21:46:43 deweese Exp $ + * @version $Id: DynamicRenderer.java,v 1.8 2002/02/19 18:01:29 deweese Exp $ */ public class DynamicRenderer extends StaticRenderer { + final static int COPY_OVERHEAD = 1000; + final static int COPY_LINE_OVERHEAD = 10; + /** * Constructs a new dynamic renderer with the specified buffer image. */ @@ -45,7 +49,7 @@ super(rh, at); } - List damagedAreas; + RectListManager damagedAreas; /** * Repaints the associated GVT tree under the list of <tt>areas</tt>. @@ -85,6 +89,7 @@ copyRaster = workingRaster; Rectangle srcR = rootCR.getBounds(); + // System.out.println("RootCR: " + srcR); Rectangle dstR = workingRaster.getBounds(); if ((dstR.x < srcR.x) || (dstR.y < srcR.y) || @@ -92,20 +97,42 @@ (dstR.y+dstR.height > srcR.y+srcR.height)) cr = new PadRed(cr, dstR, PadMode.ZERO_PAD, null); - List devRects = new ArrayList(areas.size()); + Rectangle [] devRects = new Rectangle[areas.size()]; Iterator iter = areas.iterator(); Rectangle dr = copyRaster.getBounds(); float dmgSz = 0f; + int sz=0; + // System.out.println("DR: " + dr); while (iter.hasNext()) { Shape s = (Shape)iter.next(); - Rectangle r; - r = usr2dev.createTransformedShape(s).getBounds(); + s = usr2dev.createTransformedShape(s); + Rectangle2D r2d = s.getBounds2D(); + int x0 = (int)Math.floor(r2d.getX()); + int y0 = (int)Math.floor(r2d.getY()); + int x1 = (int)Math.ceil(r2d.getX()+r2d.getWidth()); + int y1 = (int)Math.ceil(r2d.getY()+r2d.getHeight()); + // Rectangle r = new Rectangle(x0, y0, x1-x0+1, y1-y0+1); + + // This rectangle must be outset one pixel to ensure + // it includes the effects of anti-aliasing on object.s + Rectangle r = new Rectangle(x0-1, y0-1, x1-x0+3, y1-y0+3); + + // System.out.println(" Rect [" + sz+ "]: " + r); + //System.out.println(" Rect2D [" + sz+ "]: " + r2d); if (!dr.intersects(r)) continue; r = dr.intersection(r); - devRects.add(r); + devRects[sz++] = r; dmgSz += r.width*(float)r.height; } + RectListManager devRLM =null; + try { + devRLM = new RectListManager(devRects, 0, sz); + } catch(Exception e) { + e.printStackTrace(); + } + // Merge the repaint rectangles... + devRLM.mergeRects(COPY_OVERHEAD, COPY_LINE_OVERHEAD); boolean repaintAll = (dmgSz > offScreenWidth*offScreenHeight*0.9f); // Ensure only one thread works on baseRaster at a time... @@ -115,25 +142,57 @@ // System.out.println("Repainting All"); cr.copyData(copyRaster); } else { + java.awt.Graphics2D g2d = null; + if (false) { + BufferedImage tmpBI = new BufferedImage + (workingOffScreen.getColorModel(), + copyRaster.createWritableTranslatedChild(0, 0), + workingOffScreen.isAlphaPremultiplied(), null); + g2d = GraphicsUtil.createGraphics(tmpBI); + g2d.translate(-copyRaster.getMinX(), + -copyRaster.getMinY()); + } + if ((isDoubleBuffered) && (currentRaster != null) && (damagedAreas != null)) { + + damagedAreas.subtract(devRLM, COPY_OVERHEAD, + COPY_LINE_OVERHEAD); + damagedAreas.mergeRects(COPY_OVERHEAD, + COPY_LINE_OVERHEAD); + iter = damagedAreas.iterator(); Rectangle sr = currentRaster.getBounds(); + while (iter.hasNext()) { Rectangle r = (Rectangle)iter.next(); + // System.out.println("Copy: " + r); Raster src = currentRaster.createWritableChild (r.x, r.y, r.width, r.height, r.x, r.y, null); GraphicsUtil.copyData(src, copyRaster); + if (g2d != null) { + g2d.setPaint(new java.awt.Color(0,0,255,50)); + g2d.fill(r); + g2d.setPaint(new java.awt.Color(0,0,0,50)); + g2d.draw(r); + } } } - iter = devRects.iterator(); + iter = devRLM.iterator(); while (iter.hasNext()) { Rectangle r = (Rectangle)iter.next(); + // System.out.println("Render: " + r); WritableRaster dst = copyRaster.createWritableChild (r.x, r.y, r.width, r.height, r.x, r.y, null); cr.copyData(dst); + if (g2d != null) { + g2d.setPaint(new java.awt.Color(255,0,0,50)); + g2d.fill(r); + g2d.setPaint(new java.awt.Color(0,0,0,50)); + g2d.draw(r); + } } } } @@ -155,6 +214,6 @@ currentBaseRaster = syncRaster; currentOffScreen = tmpBI; - damagedAreas = devRects; + damagedAreas = devRLM; } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]