1 18 package org.apache.batik.bridge; 19 20 import java.awt.Shape ; 21 import java.awt.geom.AffineTransform ; 22 import java.awt.geom.Rectangle2D ; 23 import java.lang.ref.SoftReference ; 24 25 import org.apache.batik.css.engine.CSSEngineEvent; 26 import org.apache.batik.css.engine.SVGCSSEngine; 27 import org.apache.batik.dom.svg.SVGContext; 28 import org.apache.batik.dom.svg.SVGOMElement; 29 import org.apache.batik.ext.awt.geom.SegmentList; 30 import org.apache.batik.gvt.CanvasGraphicsNode; 31 import org.apache.batik.gvt.CompositeGraphicsNode; 32 import org.apache.batik.gvt.GraphicsNode; 33 34 import org.w3c.dom.Element ; 35 import org.w3c.dom.Node ; 36 import org.w3c.dom.events.MutationEvent ; 37 import org.w3c.dom.svg.SVGFitToViewBox; 38 39 60 public abstract class AbstractGraphicsNodeBridge extends AbstractSVGBridge 61 implements SVGContext, 62 BridgeUpdateHandler, 63 GraphicsNodeBridge, 64 ErrorConstants { 65 66 69 protected Element e; 70 71 74 protected GraphicsNode node; 75 76 79 protected BridgeContext ctx; 80 81 84 protected AbstractGraphicsNodeBridge() {} 85 86 93 public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { 94 if (!SVGUtilities.matchUserAgent(e, ctx.getUserAgent())) { 96 return null; 97 } 98 99 GraphicsNode node = instantiateGraphicsNode(); 100 String s = e.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE); 102 if (s.length() != 0) { 103 node.setTransform 104 (SVGUtilities.convertTransform(e, SVG_TRANSFORM_ATTRIBUTE, s)); 105 } 106 node.setVisible(CSSUtilities.convertVisibility(e)); 108 return node; 109 } 110 111 115 protected abstract GraphicsNode instantiateGraphicsNode(); 116 117 125 public void buildGraphicsNode(BridgeContext ctx, 126 Element e, 127 GraphicsNode node) { 128 node.setComposite(CSSUtilities.convertOpacity(e)); 130 node.setFilter(CSSUtilities.convertFilter(e, node, ctx)); 132 node.setMask(CSSUtilities.convertMask(e, node, ctx)); 134 node.setClip(CSSUtilities.convertClipPath(e, node, ctx)); 136 node.setPointerEventType(CSSUtilities.convertPointerEvents(e)); 138 139 initializeDynamicSupport(ctx, e, node); 140 } 141 142 146 public boolean getDisplay(Element e) { 147 return CSSUtilities.convertDisplay(e); 148 } 149 150 156 protected void initializeDynamicSupport(BridgeContext ctx, 157 Element e, 158 GraphicsNode node) { 159 if (!ctx.isInteractive()) 160 return; 161 162 ctx.bind(e, node); 164 165 if (ctx.isDynamic()) { 166 this.e = e; 168 this.node = node; 169 this.ctx = ctx; 170 ((SVGOMElement)e).setSVGContext(this); 171 } 172 } 173 174 176 179 public void handleDOMAttrModifiedEvent(MutationEvent evt) { 180 String attrName = evt.getAttrName(); 181 if (attrName.equals(SVG_TRANSFORM_ATTRIBUTE)) { 182 String s = evt.getNewValue(); 183 AffineTransform at = GraphicsNode.IDENTITY; 184 if (s.length() != 0) { 185 at = SVGUtilities.convertTransform 186 (e, SVG_TRANSFORM_ATTRIBUTE, s); 187 } 188 node.setTransform(at); 189 handleGeometryChanged(); 190 } 191 } 192 193 196 protected void handleGeometryChanged() { 197 node.setFilter(CSSUtilities.convertFilter(e, node, ctx)); 198 node.setMask(CSSUtilities.convertMask(e, node, ctx)); 199 node.setClip(CSSUtilities.convertClipPath(e, node, ctx)); 200 } 201 202 205 public void handleDOMNodeInsertedEvent(MutationEvent evt) { 206 if ( evt.getTarget() instanceof Element ){ 207 Element e2 = (Element)evt.getTarget(); 209 Bridge b = ctx.getBridge(e2); 210 if (b instanceof GenericBridge) { 211 ((GenericBridge) b).handleElement(ctx, e2); 212 } 213 } 214 } 215 216 219 public void handleDOMNodeRemovedEvent(MutationEvent evt) { 220 CompositeGraphicsNode gn = node.getParent(); 221 gn.remove(node); 222 disposeTree(e); 223 } 224 225 229 public void handleDOMCharacterDataModified(MutationEvent evt) { 230 } 231 232 235 public void dispose() { 236 SVGOMElement elt = (SVGOMElement)e; 237 elt.setSVGContext(null); 238 ctx.unbind(e); 239 } 240 241 242 245 static void disposeTree(Node node) { 246 if (node instanceof SVGOMElement) { 247 SVGOMElement elt = (SVGOMElement)node; 248 BridgeUpdateHandler h = (BridgeUpdateHandler)elt.getSVGContext(); 249 if (h != null) 250 h.dispose(); 251 } 252 for (Node n = node.getFirstChild(); n!=null; n = n.getNextSibling()) { 253 disposeTree(n); 254 } 255 } 256 257 260 public void handleCSSEngineEvent(CSSEngineEvent evt) { 261 try { 262 int [] properties = evt.getProperties(); 263 for (int i=0; i < properties.length; ++i) { 264 handleCSSPropertyChanged(properties[i]); 265 } 266 } catch (Exception ex) { 267 ctx.getUserAgent().displayError(ex); 268 } 269 } 270 271 274 protected void handleCSSPropertyChanged(int property) { 275 switch(property) { 276 case SVGCSSEngine.VISIBILITY_INDEX: 277 node.setVisible(CSSUtilities.convertVisibility(e)); 278 break; 279 case SVGCSSEngine.OPACITY_INDEX: 280 node.setComposite(CSSUtilities.convertOpacity(e)); 281 break; 282 case SVGCSSEngine.FILTER_INDEX: 283 node.setFilter(CSSUtilities.convertFilter(e, node, ctx)); 284 break; 285 case SVGCSSEngine.MASK_INDEX: 286 node.setMask(CSSUtilities.convertMask(e, node, ctx)); 287 break; 288 case SVGCSSEngine.CLIP_PATH_INDEX: 289 node.setClip(CSSUtilities.convertClipPath(e, node, ctx)); 290 break; 291 case SVGCSSEngine.POINTER_EVENTS_INDEX: 292 node.setPointerEventType(CSSUtilities.convertPointerEvents(e)); 293 break; 294 case SVGCSSEngine.DISPLAY_INDEX: 295 if (!getDisplay(e)) { 296 CompositeGraphicsNode parent = node.getParent(); 298 int idx = parent.indexOf(node); 299 parent.remove(node); 300 disposeTree(e); 301 } 302 break; 303 } 304 } 305 306 308 311 public float getPixelUnitToMillimeter() { 312 return ctx.getUserAgent().getPixelUnitToMillimeter(); 313 } 314 315 320 public float getPixelToMM() { 321 return getPixelUnitToMillimeter(); 322 323 } 324 325 protected SoftReference bboxShape = null; 326 protected Rectangle2D bbox = null; 327 328 334 public Rectangle2D getBBox() { 335 Shape s = node.getOutline(); 336 337 if ((bboxShape != null) && (s == bboxShape.get())) return bbox; 338 bboxShape = new SoftReference (s); bbox = null; 340 if (s == null) return bbox; 341 342 SegmentList sl = new SegmentList(s); 344 bbox = sl.getBounds2D(); 345 return bbox; 346 } 347 348 353 public AffineTransform getCTM() { 354 GraphicsNode gn = node; 355 AffineTransform ctm = new AffineTransform (); 356 Element elt = e; 357 while (elt != null) { 358 if (elt instanceof SVGFitToViewBox) { 359 AffineTransform at; 360 if (gn instanceof CanvasGraphicsNode) { 361 at = ((CanvasGraphicsNode)gn).getViewingTransform(); 362 } else { 363 at = gn.getTransform(); 364 } 365 if (at != null) { 366 ctm.preConcatenate(at); 367 } 368 break; 369 } 370 371 AffineTransform at = gn.getTransform(); 372 if (at != null) 373 ctm.preConcatenate(at); 374 375 elt = SVGCSSEngine.getParentCSSStylableElement(elt); 376 gn = gn.getParent(); 377 } 378 return ctm; 379 } 380 381 384 public AffineTransform getScreenTransform() { 385 return ctx.getUserAgent().getTransform(); 386 } 387 388 391 public void setScreenTransform(AffineTransform at) { 392 ctx.getUserAgent().setTransform(at); 393 } 394 395 399 public AffineTransform getGlobalTransform() { 400 return node.getGlobalTransform(); 401 } 402 403 407 public float getViewportWidth() { 408 return ctx.getBlockWidth(e); 409 } 410 411 415 public float getViewportHeight() { 416 return ctx.getBlockHeight(e); 417 } 418 419 422 public float getFontSize() { 423 return CSSUtilities.getComputedStyle 424 (e, SVGCSSEngine.FONT_SIZE_INDEX).getFloatValue(); 425 } 426 } 427 | Popular Tags |