1 18 19 package org.apache.batik.gvt; 20 21 import java.awt.Shape ; 22 import java.awt.Rectangle ; 23 import java.awt.geom.AffineTransform ; 24 import java.awt.geom.Rectangle2D ; 25 import java.lang.ref.WeakReference ; 26 import java.util.HashMap ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Set ; 32 33 import org.apache.batik.gvt.event.GraphicsNodeChangeAdapter; 34 import org.apache.batik.gvt.event.GraphicsNodeChangeEvent; 35 import org.apache.batik.ext.awt.image.renderable.Filter; 36 42 public class UpdateTracker extends GraphicsNodeChangeAdapter { 43 44 Map dirtyNodes = null; 45 Map fromBounds = new HashMap (); 46 protected static Rectangle2D NULL_RECT = new Rectangle (); 47 48 public UpdateTracker(){ 49 } 50 51 54 public boolean hasChanged() { 55 return (dirtyNodes != null); 56 } 57 58 61 public List getDirtyAreas() { 62 if (dirtyNodes == null) 63 return null; 64 65 List ret = new LinkedList (); 66 Set keys = dirtyNodes.keySet(); 67 Iterator i = keys.iterator(); 68 while (i.hasNext()) { 69 WeakReference gnWRef = (WeakReference )i.next(); 70 GraphicsNode gn = (GraphicsNode)gnWRef.get(); 71 73 if (gn == null) continue; 78 79 AffineTransform oat; 80 oat = (AffineTransform )dirtyNodes.get(gnWRef); 81 if (oat != null){ 82 oat = new AffineTransform (oat); 83 } 84 85 Rectangle2D srcORgn = (Rectangle2D )fromBounds.remove(gnWRef); 86 87 Rectangle2D srcNRgn = null; 88 AffineTransform nat = null; 89 if (!(srcORgn instanceof ChngSrcRect)) { 90 srcNRgn = gn.getBounds(); 92 nat = gn.getTransform(); 93 if (nat != null) 94 nat = new AffineTransform (nat); 95 } 96 97 98 do { 101 104 109 gn = gn.getParent(); 110 if (gn == null) 111 break; 113 Filter f= gn.getFilter(); 114 if ( f != null) { 115 srcNRgn = f.getBounds2D(); 116 nat = null; 117 } 118 119 AffineTransform at = gn.getTransform(); 121 gnWRef = gn.getWeakReference(); 123 AffineTransform poat = (AffineTransform )dirtyNodes.get(gnWRef); 124 if (poat == null) poat = at; 125 if (poat != null) { 126 if (oat != null) 127 oat.preConcatenate(poat); 128 else 129 oat = new AffineTransform (poat); 130 } 131 132 if (at != null){ 133 if (nat != null) 134 nat.preConcatenate(at); 135 else 136 nat = new AffineTransform (at); 137 } 138 } while (true); 139 140 if (gn == null) { 141 Shape oRgn = srcORgn; 147 if ((oRgn != null) && (oRgn != NULL_RECT)) { 148 if (oat != null) 149 oRgn = oat.createTransformedShape(srcORgn); 150 ret.add(oRgn); 153 } 154 155 if (srcNRgn != null) { 156 Shape nRgn = srcNRgn; 157 if (nat != null) 158 nRgn = nat.createTransformedShape(srcNRgn); 159 if (nRgn != null) 160 ret.add(nRgn); 161 } 162 } 163 } 164 return ret; 165 } 166 167 174 public Rectangle2D getNodeDirtyRegion(GraphicsNode gn, 175 AffineTransform at) { 176 WeakReference gnWRef = gn.getWeakReference(); 177 AffineTransform nat = (AffineTransform )dirtyNodes.get(gnWRef); 178 if (nat == null) nat = gn.getTransform(); 179 if (nat != null) { 180 at = new AffineTransform (at); 181 at.concatenate(nat); 182 } 183 184 Rectangle2D ret = null; 185 if (gn instanceof CompositeGraphicsNode) { 186 CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn; 187 Iterator iter = cgn.iterator(); 188 189 while (iter.hasNext()) { 190 GraphicsNode childGN = (GraphicsNode)iter.next(); 191 Rectangle2D r2d = getNodeDirtyRegion(childGN, at); 192 if (r2d != null) { 193 if ((ret == null) || (ret == NULL_RECT)) ret = r2d; 194 else ret = ret.createUnion(r2d); 195 } 196 } 197 } else { 198 ret = (Rectangle2D )fromBounds.remove(gnWRef); 199 if (ret == null) 200 ret = gn.getBounds(); 201 else if (ret == NULL_RECT) 202 ret = null; 203 if (ret != null) 204 ret = at.createTransformedShape(ret).getBounds2D(); 205 } 206 return ret; 207 } 208 209 public Rectangle2D getNodeDirtyRegion(GraphicsNode gn) { 210 return getNodeDirtyRegion(gn, new AffineTransform ()); 211 } 212 213 217 public void changeStarted(GraphicsNodeChangeEvent gnce) { 218 GraphicsNode gn = gnce.getGraphicsNode(); 220 WeakReference gnWRef = gn.getWeakReference(); 221 222 boolean doPut = false; 223 if (dirtyNodes == null) { 224 dirtyNodes = new HashMap (); 225 doPut = true; 226 } else if (!dirtyNodes.containsKey(gnWRef)) 227 doPut = true; 228 229 if (doPut) { 230 AffineTransform at = gn.getTransform(); 231 if (at != null) at = (AffineTransform )at.clone(); 232 else at = new AffineTransform (); 233 dirtyNodes.put(gnWRef, at); 234 } 235 236 GraphicsNode chngSrc = gnce.getChangeSrc(); 237 Rectangle2D rgn = null; 238 if (chngSrc != null) { 239 Rectangle2D drgn = getNodeDirtyRegion(chngSrc); 242 if (drgn != null) 243 rgn = new ChngSrcRect(drgn); 244 } else { 245 rgn = gn.getBounds(); 247 } 248 Rectangle2D r2d = (Rectangle2D )fromBounds.remove(gnWRef); 250 if (rgn != null) { 251 if ((r2d != null) && (r2d != NULL_RECT)) { 252 r2d = r2d.createUnion(rgn); 256 } 258 else r2d = rgn; 259 } 260 261 266 if (r2d == null) 268 r2d = NULL_RECT; 269 fromBounds.put(gnWRef, r2d); 270 } 271 272 class ChngSrcRect extends Rectangle2D.Float { 273 ChngSrcRect(Rectangle2D r2d) { 274 super((float)r2d.getX(), (float)r2d.getY(), 275 (float)r2d.getWidth(), (float)r2d.getHeight()); 276 } 277 } 278 279 282 public void clear() { 283 dirtyNodes = null; 284 } 285 } 286 | Popular Tags |