deweese 2003/12/09 02:44:10 Modified: sources/org/apache/batik/bridge SVGSVGElementBridge.java sources/org/apache/batik/ext/awt/image/rendered Any2sRGBRed.java sources/org/apache/batik/gvt ShapeNode.java sources/org/apache/batik/script/rhino EventTargetWrapper.java xdocs javaScripting.xml Log: 1) Optimization for modification of x/y (and some viewBox changes) on svg elements. 2) fix for pointer-event changes on shape nodes. 3) Fix for registering one JavaScript object for multiple event types on the same event target. 4) Documentation fix from Cameron McCormack (plus additional cautionary text). Revision Changes Path 1.40 +131 -10 xml-batik/sources/org/apache/batik/bridge/SVGSVGElementBridge.java Index: SVGSVGElementBridge.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGSVGElementBridge.java,v retrieving revision 1.39 retrieving revision 1.40 diff -u -r1.39 -r1.40 --- SVGSVGElementBridge.java 5 Nov 2003 22:21:09 -0000 1.39 +++ SVGSVGElementBridge.java 9 Dec 2003 10:44:10 -0000 1.40 @@ -176,10 +176,8 @@ AffineTransform positionTransform = AffineTransform.getTranslateInstance(x, y); - // 'overflow' and 'clip' // The outermost preserveAspectRatio matrix is set by the user // agent, so we don't need to set the transform for outermost svg - Shape clip = null; if (!isOutermost) { // X & Y are ignored on outermost SVG. cgn.setPositionTransform(positionTransform); @@ -191,6 +189,8 @@ // component prepares for rendering. cgn.setViewingTransform(viewingTransform); + // 'overflow' and 'clip' + Shape clip = null; if (CSSUtilities.convertOverflow(e)) { // overflow:hidden float [] offsets = CSSUtilities.convertClip(e); if (offsets == null) { // clip:auto @@ -274,15 +274,136 @@ * Invoked when an MutationEvent of type 'DOMAttrModified' is fired. */ public void handleDOMAttrModifiedEvent(MutationEvent evt) { - // Don't call 'super' because there is no 'transform' attribute on <svg> + // Don't call 'super' because there is no 'transform' + // attribute on <svg> String attrName = evt.getAttrName(); - if (attrName.equals(SVG_X_ATTRIBUTE) || - attrName.equals(SVG_Y_ATTRIBUTE) || - attrName.equals(SVG_WIDTH_ATTRIBUTE) || - attrName.equals(SVG_HEIGHT_ATTRIBUTE) || - attrName.equals(SVG_VIEW_BOX_ATTRIBUTE) || - attrName.equals(SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE)) { + boolean rebuild = false; + if (attrName.equals(SVG_WIDTH_ATTRIBUTE) || + attrName.equals(SVG_HEIGHT_ATTRIBUTE) ) { + rebuild = true; + } else if (attrName.equals(SVG_X_ATTRIBUTE) || + attrName.equals(SVG_Y_ATTRIBUTE)) { + SVGDocument doc = (SVGDocument)e.getOwnerDocument(); + boolean isOutermost = (doc.getRootElement() == e); + if (!isOutermost) { + // X & Y are ignored on outermost SVG. + float x = 0; + float y = 0; + UnitProcessor.Context uctx; + uctx = UnitProcessor.createContext(ctx, e); + // 'x' attribute - default is 0 + String s = e.getAttributeNS(null, SVG_X_ATTRIBUTE); + if (s.length() != 0) { + x = UnitProcessor.svgHorizontalCoordinateToUserSpace + (s, SVG_X_ATTRIBUTE, uctx); + } + // 'y' attribute - default is 0 + s = e.getAttributeNS(null, SVG_Y_ATTRIBUTE); + if (s.length() != 0) { + y = UnitProcessor.svgVerticalCoordinateToUserSpace + (s, SVG_Y_ATTRIBUTE, uctx); + } + + AffineTransform positionTransform = + AffineTransform.getTranslateInstance(x, y); + CanvasGraphicsNode cgn; + cgn = (CanvasGraphicsNode)node; + + cgn.setPositionTransform(positionTransform); + } + } else if (attrName.equals(SVG_VIEW_BOX_ATTRIBUTE) || + attrName.equals(SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE)) { + SVGDocument doc = (SVGDocument)e.getOwnerDocument(); + boolean isOutermost = (doc.getRootElement() == e); + + String s; + UnitProcessor.Context uctx; + uctx = UnitProcessor.createContext(ctx, e); + // X & Y are ignored on outermost SVG. + float x = 0; + float y = 0; + if (!isOutermost) { + // 'x' attribute - default is 0 + s = e.getAttributeNS(null, SVG_X_ATTRIBUTE); + if (s.length() != 0) { + x = UnitProcessor.svgHorizontalCoordinateToUserSpace + (s, SVG_X_ATTRIBUTE, uctx); + } + // 'y' attribute - default is 0 + s = e.getAttributeNS(null, SVG_Y_ATTRIBUTE); + if (s.length() != 0) { + y = UnitProcessor.svgVerticalCoordinateToUserSpace + (s, SVG_Y_ATTRIBUTE, uctx); + } + } + // 'width' attribute - default is 100% + s = e.getAttributeNS(null, SVG_WIDTH_ATTRIBUTE); + if (s.length() == 0) { + s = SVG_SVG_WIDTH_DEFAULT_VALUE; + } + float w = UnitProcessor.svgHorizontalLengthToUserSpace + (s, SVG_WIDTH_ATTRIBUTE, uctx); + + // 'height' attribute - default is 100% + s = e.getAttributeNS(null, SVG_HEIGHT_ATTRIBUTE); + if (s.length() == 0) { + s = SVG_SVG_HEIGHT_DEFAULT_VALUE; + } + float h = UnitProcessor.svgVerticalLengthToUserSpace + (s, SVG_HEIGHT_ATTRIBUTE, uctx); + + CanvasGraphicsNode cgn; + cgn = (CanvasGraphicsNode)node; + + // 'viewBox' and "preserveAspectRatio' attributes + AffineTransform newVT = + ViewBox.getPreserveAspectRatioTransform(e, w, h); + AffineTransform oldVT = cgn.getViewingTransform(); + if ((newVT.getScaleX() != oldVT.getScaleX()) || + (newVT.getScaleY() != oldVT.getScaleY()) || + (newVT.getShearX() != oldVT.getShearX()) || + (newVT.getShearY() != oldVT.getShearY())) + rebuild = true; + else { + // Only differs in translate. + cgn.setViewingTransform(newVT); + + // 'overflow' and 'clip' + Shape clip = null; + if (CSSUtilities.convertOverflow(e)) { // overflow:hidden + float [] offsets = CSSUtilities.convertClip(e); + if (offsets == null) { // clip:auto + clip = new Rectangle2D.Float(x, y, w, h); + } else { // clip:rect(<x> <y> <w> <h>) + // offsets[0] = top + // offsets[1] = right + // offsets[2] = bottom + // offsets[3] = left + clip = new Rectangle2D.Float(x+offsets[3], + y+offsets[0], + w-offsets[1]-offsets[3], + h-offsets[2]-offsets[0]); + } + } + + if (clip != null) { + try { + AffineTransform at; + at = cgn.getPositionTransform(); + at = new AffineTransform(at); + at.concatenate(newVT); + at = at.createInverse(); // clip in user space + clip = at.createTransformedShape(clip); + Filter filter = cgn.getGraphicsNodeRable(true); + cgn.setClip(new ClipRable8Bit(filter, clip)); + } catch (NoninvertibleTransformException ex) {} + } + } + } + + if (rebuild) { + System.err.println("REbuild"); CompositeGraphicsNode gn = node.getParent(); gn.remove(node); disposeTree(e); 1.9 +2 -3 xml-batik/sources/org/apache/batik/ext/awt/image/rendered/Any2sRGBRed.java Index: Any2sRGBRed.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/ext/awt/image/rendered/Any2sRGBRed.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- Any2sRGBRed.java 5 Dec 2003 18:32:37 -0000 1.8 +++ Any2sRGBRed.java 9 Dec 2003 10:44:10 -0000 1.9 @@ -238,8 +238,7 @@ op.filter(srcRas, wr); } else { ColorModel dstCM = getColorModel(); - if ((srcCM.getColorSpace() == dstCM.getColorSpace()) && - srcCM.isCompatibleRaster(wr)) { + if (srcCM.getColorSpace() == dstCM.getColorSpace()) { // No transform needed, just reformat data... // System.out.println("Bypassing"); 1.26 +6 -1 xml-batik/sources/org/apache/batik/gvt/ShapeNode.java Index: ShapeNode.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/ShapeNode.java,v retrieving revision 1.25 retrieving revision 1.26 diff -u -r1.25 -r1.26 --- ShapeNode.java 23 Oct 2003 01:01:55 -0000 1.25 +++ ShapeNode.java 9 Dec 2003 10:44:10 -0000 1.26 @@ -204,6 +204,11 @@ sensitiveArea = null; } + public void setPointerEventType(int pointerEventType) { + super.setPointerEventType(pointerEventType); + sensitiveBounds = null; + sensitiveArea = null; + } /** * Returns true if the specified Point2D is inside the boundary of this * node, false otherwise. 1.15 +3 -4 xml-batik/sources/org/apache/batik/script/rhino/EventTargetWrapper.java Index: EventTargetWrapper.java =================================================================== RCS file: /home/cvs/xml-batik/sources/org/apache/batik/script/rhino/EventTargetWrapper.java,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- EventTargetWrapper.java 21 Nov 2003 13:36:25 -0000 1.14 +++ EventTargetWrapper.java 9 Dec 2003 10:44:10 -0000 1.15 @@ -281,7 +281,7 @@ throws JavaScriptException { NativeJavaObject njo = (NativeJavaObject)thisObj; if (args[1] instanceof Function) { - SoftReference sr = (SoftReference)listenerMap.remove(args[1]); + SoftReference sr = (SoftReference)listenerMap.get(args[1]); if (sr == null) return Undefined.instance; EventListener el = (EventListener)sr.get(); @@ -297,7 +297,7 @@ return Undefined.instance; } if (args[1] instanceof NativeObject) { - SoftReference sr = (SoftReference)listenerMap.remove(args[1]); + SoftReference sr = (SoftReference)listenerMap.get(args[1]); if (sr == null) return Undefined.instance; EventListener el = (EventListener)sr.get(); @@ -347,7 +347,6 @@ if (name.equals(REMOVE_NAME)) { // prevent creating a Map for all JavaScript objects // when we need it only from time to time... - Map listenerMap = initMap(); method = new FunctionRemoveProxy((Function)method, initMap()); } return method; 1.9 +17 -6 xml-batik/xdocs/javaScripting.xml Index: javaScripting.xml =================================================================== RCS file: /home/cvs/xml-batik/xdocs/javaScripting.xml,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- javaScripting.xml 10 Jul 2003 11:56:06 -0000 1.8 +++ javaScripting.xml 9 Dec 2003 10:44:10 -0000 1.9 @@ -172,7 +172,9 @@ // Returns immediately canvas.getUpdateManager().getUpdateRunnableQueue(). invokeLater(new Runnable() { - // Insert some actions on the DOM here + public void run() { + // Insert some actions on the DOM here + } }); - or - @@ -180,13 +182,22 @@ // Waits until the Runnable is invoked canvas.getUpdateManager().getUpdateRunnableQueue(). invokeAndWait(new Runnable() { - // Insert some actions on the DOM here + public void run() { + // Insert some actions on the DOM here + } }); </source> - <p> - Like with event listeners, when a Runnable is invoked from the update - thread, the graphics are updated. + <p>Like with event listeners, when a Runnable is invoked from the + update thread, the graphics are updated. </p> + <note>It is very dangerous to call 'invokeAndWait' from the + Swing Event thread. This is the only thread that can be + used to interact with Swing components. In some cases + DOM calls may need to query the canvas for information + (such as actual Swing component size etc). If this + happens you will get a thread deadlock. You should + only make invokeAndWait calls from 'third party' threads. + </note> </s1> <!-- #################################################### -->
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]