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]