You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by de...@apache.org on 2005/09/22 12:44:08 UTC

svn commit: r290928 - in /xmlgraphics/batik/trunk/sources/org/apache/batik/bridge: SVGFeImageElementBridge.java SVGUtilities.java

Author: deweese
Date: Thu Sep 22 03:43:58 2005
New Revision: 290928

URL: http://svn.apache.org/viewcvs?rev=290928&view=rev
Log:
Fixes a bug in the handling of 'x', 'y', 'width', 'height',
on feImage elements.  This may effect users of the filter
primitive element.  The previous behaviour fit the referenced
content to the intersection of the filter region with
the filter primitive region.  Now the content is fitted
to the filter primitive region but it's rendering is
clipped to the intersection of the filter primitive and
the filter regions.  I believe this is the correct behaviour.

Modified:
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGFeImageElementBridge.java
    xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUtilities.java

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGFeImageElementBridge.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGFeImageElementBridge.java?rev=290928&r1=290927&r2=290928&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGFeImageElementBridge.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGFeImageElementBridge.java Thu Sep 22 03:43:58 2005
@@ -115,9 +115,10 @@
         }
 
         
-        contentElement.setAttributeNS(XLinkSupport.XLINK_NAMESPACE_URI, XMLConstants.XLINK_PREFIX + 
-                                    ":" + SVG_HREF_ATTRIBUTE,
-                                    uriStr);
+        contentElement.setAttributeNS(XLinkSupport.XLINK_NAMESPACE_URI, 
+                                      XMLConstants.XLINK_PREFIX + 
+                                      ":" + SVG_HREF_ATTRIBUTE,
+                                      uriStr);
 
         Element proxyElement = document.createElementNS(SVG_NAMESPACE_URI,
                                                         SVG_G_TAG);
@@ -125,15 +126,32 @@
 
         // feImage's default region is that of the filter chain.
         Rectangle2D defaultRegion = filterRegion;
+        Element filterDefElement = (Element)(filterElement.getParentNode());
 
-        // Compute the transform from object bounding box to user
-        // space if needed.
-        AffineTransform at = new AffineTransform();
+        Rectangle2D primitiveRegion =
+            SVGUtilities.getBaseFilterPrimitiveRegion(filterElement,
+                                                      filteredElement,
+                                                      filteredNode,
+                                                      defaultRegion,
+                                                      ctx);
+        
+        // System.err.println(">>>>>>>> primitiveRegion : " + primitiveRegion);
 
+        contentElement.setAttributeNS(null, SVG_X_ATTRIBUTE, 
+                                      "" + primitiveRegion.getX());
+        contentElement.setAttributeNS(null, SVG_Y_ATTRIBUTE, 
+                                      "" + primitiveRegion.getY());
+        contentElement.setAttributeNS(null, SVG_WIDTH_ATTRIBUTE, 
+                                      "" + primitiveRegion.getWidth());
+        contentElement.setAttributeNS(null, SVG_HEIGHT_ATTRIBUTE, 
+                                      "" + primitiveRegion.getHeight());
+        
+
+        GraphicsNode node = ctx.getGVTBuilder().build(ctx, proxyElement);
+        Filter filter = node.getGraphicsNodeRable(true);
+        
         // 'primitiveUnits' attribute - default is userSpaceOnUse
         short coordSystemType;
-        Element filterDefElement = (Element)(filterElement.getParentNode());
-        boolean isBBox = false;
         String s = SVGUtilities.getChainableAttributeNS
             (filterDefElement, null, SVG_PRIMITIVE_UNITS_ATTRIBUTE, ctx);
         if (s.length() == 0) {
@@ -143,11 +161,17 @@
                     (filterDefElement, SVG_PRIMITIVE_UNITS_ATTRIBUTE, s);
         }
         
+        // Compute the transform from object bounding box to user
+        // space if needed.
+        AffineTransform at = new AffineTransform();
         if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX) {
-            isBBox = true;
             at = SVGUtilities.toObjectBBox(at, filteredNode);
         }
-        
+        filter = new AffineRable8Bit(filter, at);
+
+        // handle the 'color-interpolation-filters' property
+        handleColorInterpolationFilters(filter, filterElement);
+
         // get filter primitive chain region
         Rectangle2D primitiveRegionUserSpace
             = SVGUtilities.convertFilterPrimitiveRegion(filterElement,
@@ -156,35 +180,8 @@
                                                         defaultRegion,
                                                         filterRegion,
                                                         ctx);
-        Rectangle2D primitiveRegion = primitiveRegionUserSpace;
-
-        if (isBBox) {
-            try {
-                AffineTransform ati = at.createInverse();
-                primitiveRegion = ati.createTransformedShape(primitiveRegion).getBounds2D();
-            } catch (NoninvertibleTransformException nite) {
-                // Should never happen, seem above
-                throw new Error();
-            }
-        }
-
-        contentElement.setAttributeNS(null, SVG_X_ATTRIBUTE, "" + primitiveRegion.getX());
-        contentElement.setAttributeNS(null, SVG_Y_ATTRIBUTE, "" + primitiveRegion.getY());
-        contentElement.setAttributeNS(null, SVG_WIDTH_ATTRIBUTE, "" + primitiveRegion.getWidth());
-        contentElement.setAttributeNS(null, SVG_HEIGHT_ATTRIBUTE, "" + primitiveRegion.getHeight());
-        
-        // System.err.println(">>>>>>>>>>>> primitiveRegion : " + primitiveRegion);
-        // System.err.println(">>>>>>>>>>>> at              : " + at);
-
-        GraphicsNode node = ctx.getGVTBuilder().build(ctx, proxyElement);
-        Filter filter = node.getGraphicsNodeRable(true);
-        
-        filter = new AffineRable8Bit(filter, at);
-
-        // handle the 'color-interpolation-filters' property
-        handleColorInterpolationFilters(filter, filterElement);
-
-        filter = new PadRable8Bit(filter, primitiveRegionUserSpace, PadMode.ZERO_PAD);
+        filter = new PadRable8Bit(filter, primitiveRegionUserSpace, 
+                                  PadMode.ZERO_PAD);
 
         // update the filter Map
         updateFilterMap(filterElement, filter, filterMap);

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUtilities.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUtilities.java?rev=290928&r1=290927&r2=290928&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUtilities.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/bridge/SVGUtilities.java Thu Sep 22 03:43:58 2005
@@ -742,6 +742,58 @@
         return region;
     }
 
+
+    public static Rectangle2D 
+        getBaseFilterPrimitiveRegion(Element filterPrimitiveElement,
+                                     Element filteredElement,
+                                     GraphicsNode filteredNode,
+                                     Rectangle2D defaultRegion,
+                                     BridgeContext ctx) {
+        String s;
+
+        // resolve units in the (referenced) filteredElement's
+        // coordinate system
+        UnitProcessor.Context uctx;
+        uctx = UnitProcessor.createContext(ctx, filteredElement);
+
+        // 'x' attribute - default is defaultRegion.getX()
+        double x = defaultRegion.getX();
+        s = filterPrimitiveElement.getAttributeNS(null, SVG_X_ATTRIBUTE);
+        if (s.length() != 0) {
+            x = UnitProcessor.svgHorizontalCoordinateToUserSpace
+                (s, SVG_X_ATTRIBUTE, uctx);
+        }
+
+        // 'y' attribute - default is defaultRegion.getY()
+        double y = defaultRegion.getY();
+        s = filterPrimitiveElement.getAttributeNS(null, SVG_Y_ATTRIBUTE);
+        if (s.length() != 0) {
+            y = UnitProcessor.svgVerticalCoordinateToUserSpace
+                (s, SVG_Y_ATTRIBUTE, uctx);
+        }
+
+        // 'width' attribute - default is defaultRegion.getWidth()
+        double w = defaultRegion.getWidth();
+        s = filterPrimitiveElement.getAttributeNS(null, SVG_WIDTH_ATTRIBUTE);
+        if (s.length() != 0) {
+            w = UnitProcessor.svgHorizontalLengthToUserSpace
+                (s, SVG_WIDTH_ATTRIBUTE, uctx);
+        }
+
+        // 'height' attribute - default is defaultRegion.getHeight()
+        double h = defaultRegion.getHeight();
+        s = filterPrimitiveElement.getAttributeNS(null, SVG_HEIGHT_ATTRIBUTE);
+        if (s.length() != 0) {
+            h = UnitProcessor.svgVerticalLengthToUserSpace
+                (s, SVG_HEIGHT_ATTRIBUTE, uctx);
+        }
+
+        // NOTE: it may be that dx/dy/dw/dh should be applied here 
+        //       but since this is mostly aimed at feImage I am
+        //       unsure that it is really needed.
+        return new Rectangle2D.Double(x, y, w, h);
+    }
+
     /**
      * Returns the filter primitive region according to the x, y,
      * width, height, and filterUnits attributes. Processing the