xmlgraphics-batik-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From vha...@apache.org
Subject cvs commit: xml-batik/sources/org/apache/batik/util CSSConstants.java SVGConstants.java
Date Thu, 01 Feb 2001 16:41:59 GMT
vhardy      01/02/01 08:41:58

  Modified:    sources/org/apache/batik/apps/regsvggen Main.java
               sources/org/apache/batik/bridge CSSUtilities.java
                        SVGBridgeContext.java SVGFeTileElementBridge.java
                        SVGLineElementBridge.java SVGPathElementBridge.java
                        SVGPolygonElementBridge.java
                        SVGPolylineElementBridge.java
               sources/org/apache/batik/css/svg SVGValueFactoryMap.java
                        SVGViewCSS.java
               sources/org/apache/batik/dom/svg
                        ElementNonCSSPresentationalHintsSupport.java
                        SVGOMDocument.java
               sources/org/apache/batik/gvt CompositeGraphicsNode.java
               sources/org/apache/batik/util CSSConstants.java
                        SVGConstants.java
  Added:       sources/org/apache/batik/bridge MarkerBridge.java
                        SVGDecoratedShapeElementBridge.java
                        SVGMarkerElementBridge.java
               sources/org/apache/batik/gvt DecoratedShapeNode.java
                        Marker.java
  Log:
  Initial marker support commit. Passes Marker BE-01. Needs additional work (cloning of
  SVG DOM branch) before passing other tests. Known bug on line elements.
  
  Revision  Changes    Path
  1.8       +2 -12     xml-batik/sources/org/apache/batik/apps/regsvggen/Main.java
  
  Index: Main.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/apps/regsvggen/Main.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- Main.java	2001/01/23 17:06:07	1.7
  +++ Main.java	2001/02/01 16:41:47	1.8
  @@ -60,7 +60,7 @@
    * A regression checking tool for SVG generator test cases.
    *
    * @author <a href="mailto:spei@cs.uiowa.edu">Sheng Pei</a>
  - * @version $Id: Main.java,v 1.7 2001/01/23 17:06:07 tkormann Exp $
  + * @version $Id: Main.java,v 1.8 2001/02/01 16:41:47 vhardy Exp $
    */
   public class Main {
   
  @@ -491,19 +491,9 @@
           Document domFactory = impl.createDocument(namespaceURI, "svg", null);
   
           // Second, create an instance of the generator and paint to it
  -
  -        ImageHandler imageHandler
  -            = new ImageHandlerPNGEncoder(REGSVGGEN_DIRECTORY_NAME +
  -                                         FILE_SEPARATOR +
  -                                         REGSVGGEN_NEW_DIRECTORY_NAME,
  -                                         "../" +
  -                                         REGSVGGEN_NEW_DIRECTORY_NAME);
           ExtensionHandler extensionHandler
               = new DefaultExtensionHandler();
  -        SVGGraphics2D svggen = new SVGGraphics2D(domFactory,
  -                                                 imageHandler,
  -                                                 extensionHandler,
  -                                                 false);
  +        SVGGraphics2D svggen = new SVGGraphics2D(domFactory);
           Dimension size = painter.getSize();
           svggen.setSVGCanvasSize(size);
           painter.paint(svggen);
  
  
  
  1.4       +73 -1     xml-batik/sources/org/apache/batik/bridge/CSSUtilities.java
  
  Index: CSSUtilities.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/CSSUtilities.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- CSSUtilities.java	2001/02/01 13:45:45	1.3
  +++ CSSUtilities.java	2001/02/01 16:41:48	1.4
  @@ -23,6 +23,7 @@
   import org.apache.batik.bridge.ClipBridge;
   import org.apache.batik.bridge.FilterBridge;
   import org.apache.batik.bridge.IllegalAttributeValueException;
  +import org.apache.batik.bridge.MarkerBridge;
   import org.apache.batik.bridge.MaskBridge;
   import org.apache.batik.bridge.PaintBridge;
   import org.apache.batik.dom.svg.SVGOMDocument;
  @@ -31,6 +32,7 @@
   import org.apache.batik.gvt.FillShapePainter;
   import org.apache.batik.gvt.GraphicsNode;
   import org.apache.batik.gvt.GraphicsNodeRenderContext;
  +import org.apache.batik.gvt.Marker;
   import org.apache.batik.gvt.ShapePainter;
   import org.apache.batik.gvt.StrokeShapePainter;
   import org.apache.batik.ext.awt.image.renderable.Clip;
  @@ -59,7 +61,7 @@
    * A collection of utility methods involving CSS.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: CSSUtilities.java,v 1.3 2001/02/01 13:45:45 tkormann Exp $
  + * @version $Id: CSSUtilities.java,v 1.4 2001/02/01 16:41:48 vhardy Exp $
    */
   public class CSSUtilities implements SVGConstants {
   
  @@ -596,6 +598,76 @@
           default:
               throw new Error(); // can't be reached
           }
  +    }
  +
  +    /**
  +     * Converts a marker property to a Marker object
  +     */
  +    public static Marker convertMarker(SVGElement paintedElement,
  +                                       String markerProperty,
  +                                       BridgeContext ctx,
  +                                       CSSStyleDeclaration decl,
  +                                       UnitProcessor.Context uctx){
  +        CSSPrimitiveValue v =
  +            (CSSPrimitiveValue) decl.getPropertyCSSValue(markerProperty);
  +
  +        if(v == null){
  +            System.out.println(markerProperty + " Null marker value...");
  +            return null;
  +        }
  +
  +        switch(v.getPrimitiveType()){
  +        case CSSPrimitiveValue.CSS_IDENT:
  +            // value is 'none'
  +            System.out.println(markerProperty + "Marker value is none ..");
  +            return null;
  +        case CSSPrimitiveValue.CSS_URI:
  +            System.out.println(markerProperty + "Marker value is : " + v.getStringValue());
  +            return convertURIToMarker(v.getStringValue(),
  +                                      paintedElement, 
  +                                      ctx, decl, uctx);
  +        default:
  +            throw new Error(); // can't be reached.
  +        }
  +    }
  +
  +    /**
  +     * Converts a URI to a Marker
  +     */
  +    public static Marker convertURIToMarker(String markerURI,
  +                                            SVGElement paintedElement,
  +                                            BridgeContext ctx,
  +                                            CSSStyleDeclaration decl,
  +                                            UnitProcessor.Context uctx){
  +        URIResolver ur =
  +            new URIResolver((SVGDocument)paintedElement.getOwnerDocument(),
  +                            ctx.getDocumentLoader());
  +
  +        Element markerElement = null;
  +        try {
  +            markerElement = ur.getElement(markerURI);
  +        } catch (Exception ex) {
  +            throw new IllegalAttributeValueException
  +                (Messages.formatMessage("bad.uri",
  +                                        new Object[] {markerURI}));
  +        }
  +
  +        Bridge bridge = ctx.getBridge(markerElement);
  +        if ((bridge == null) || !(bridge instanceof MarkerBridge)){
  +            throw new IllegalAttributeValueException
  +                    (Messages.formatMessage("marker.reference.illegal",
  +                                           new Object[] {markerElement.getLocalName()}));
  +        }
  +
  +        MarkerBridge markerBridge = (MarkerBridge)bridge;
  +        SVGOMDocument doc = (SVGOMDocument)markerElement.getOwnerDocument();
  +        ViewCSS v = ctx.getViewCSS();
  +        ctx.setViewCSS((ViewCSS)doc.getDefaultView());
  +        Marker marker = markerBridge.buildMarker(ctx, 
  +                                                 markerElement,
  +                                                 paintedElement);
  +        return marker;
  +                                                 
       }
   
       /**
  
  
  
  1.2       +4 -1      xml-batik/sources/org/apache/batik/bridge/SVGBridgeContext.java
  
  Index: SVGBridgeContext.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGBridgeContext.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SVGBridgeContext.java	2001/01/23 17:06:24	1.1
  +++ SVGBridgeContext.java	2001/02/01 16:41:49	1.2
  @@ -21,7 +21,7 @@
    *
    * @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGBridgeContext.java,v 1.1 2001/01/23 17:06:24 tkormann Exp $
  + * @version $Id: SVGBridgeContext.java,v 1.2 2001/02/01 16:41:49 vhardy Exp $
    */
   public class SVGBridgeContext extends ConcreteBridgeContext
           implements SVGConstants {
  @@ -139,6 +139,9 @@
   
           putBridge(SVG_NAMESPACE_URI, TAG_LINEAR_GRADIENT,
                     new SVGLinearGradientBridge());
  +
  +        putBridge(SVG_NAMESPACE_URI, SVG_MARKER_TAG,
  +                  new SVGMarkerElementBridge());
   
           putBridge(SVG_NAMESPACE_URI, SVG_MASK_TAG,
                     new SVGMaskElementBridge());
  
  
  
  1.3       +4 -4      xml-batik/sources/org/apache/batik/bridge/SVGFeTileElementBridge.java
  
  Index: SVGFeTileElementBridge.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGFeTileElementBridge.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SVGFeTileElementBridge.java	2001/01/24 05:39:14	1.2
  +++ SVGFeTileElementBridge.java	2001/02/01 16:41:50	1.3
  @@ -35,7 +35,7 @@
    *
    * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
    * @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
  - * @version $Id: SVGFeTileElementBridge.java,v 1.2 2001/01/24 05:39:14 vhardy Exp $
  + * @version $Id: SVGFeTileElementBridge.java,v 1.3 2001/02/01 16:41:50 vhardy Exp $
    */
   public class SVGFeTileElementBridge implements FilterPrimitiveBridge,
                                                  SVGConstants {
  @@ -108,9 +108,9 @@
   
           if (in != null){
               tileRable = new TileRable8Bit(in,
  -                                              tiledRegion,
  -                                              in.getBounds2D(),
  -                                              false);
  +                                          tiledRegion,
  +                                          in.getBounds2D(),
  +                                          false);
           }
   
           return tileRable;
  
  
  
  1.2       +2 -2      xml-batik/sources/org/apache/batik/bridge/SVGLineElementBridge.java
  
  Index: SVGLineElementBridge.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGLineElementBridge.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SVGLineElementBridge.java	2001/01/23 17:06:35	1.1
  +++ SVGLineElementBridge.java	2001/02/01 16:41:51	1.2
  @@ -21,9 +21,9 @@
    * A factory for the &lt;line> SVG element.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGLineElementBridge.java,v 1.1 2001/01/23 17:06:35 tkormann Exp $
  + * @version $Id: SVGLineElementBridge.java,v 1.2 2001/02/01 16:41:51 vhardy Exp $
    */
  -public class SVGLineElementBridge extends SVGShapeElementBridge {
  +public class SVGLineElementBridge extends SVGDecoratedShapeElementBridge {
   
       /**
        * Returns a <tt>Line2D.Float</tt>.
  
  
  
  1.3       +2 -2      xml-batik/sources/org/apache/batik/bridge/SVGPathElementBridge.java
  
  Index: SVGPathElementBridge.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGPathElementBridge.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SVGPathElementBridge.java	2001/02/01 13:45:46	1.2
  +++ SVGPathElementBridge.java	2001/02/01 16:41:51	1.3
  @@ -31,9 +31,9 @@
    * A factory for the &ltpath> element.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGPathElementBridge.java,v 1.2 2001/02/01 13:45:46 tkormann Exp $
  + * @version $Id: SVGPathElementBridge.java,v 1.3 2001/02/01 16:41:51 vhardy Exp $
    */
  -public class SVGPathElementBridge extends SVGShapeElementBridge {
  +public class SVGPathElementBridge extends SVGDecoratedShapeElementBridge {
   
       /**
        * Returns an <tt>ExtendedGeneralPath</tt>.
  
  
  
  1.3       +10 -2     xml-batik/sources/org/apache/batik/bridge/SVGPolygonElementBridge.java
  
  Index: SVGPolygonElementBridge.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGPolygonElementBridge.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SVGPolygonElementBridge.java	2001/02/01 13:45:46	1.2
  +++ SVGPolygonElementBridge.java	2001/02/01 16:41:52	1.3
  @@ -31,9 +31,9 @@
    * A factory for the &ltpolygon> element.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGPolygonElementBridge.java,v 1.2 2001/02/01 13:45:46 tkormann Exp $
  + * @version $Id: SVGPolygonElementBridge.java,v 1.3 2001/02/01 16:41:52 vhardy Exp $
    */
  -public class SVGPolygonElementBridge extends SVGShapeElementBridge {
  +public class SVGPolygonElementBridge extends SVGDecoratedShapeElementBridge {
   
       /**
        * Returns an <tt>GeneralPath</tt>.
  @@ -71,5 +71,13 @@
           } finally {
               node.setShape(ph.getShape());
           }
  +    }
  +
  +    protected boolean hasStartMarker(){
  +        return false;
  +    }
  +
  +    protected boolean hasEndMarker(){
  +        return false;
       }
   }
  
  
  
  1.3       +2 -2      xml-batik/sources/org/apache/batik/bridge/SVGPolylineElementBridge.java
  
  Index: SVGPolylineElementBridge.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGPolylineElementBridge.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- SVGPolylineElementBridge.java	2001/02/01 13:45:46	1.2
  +++ SVGPolylineElementBridge.java	2001/02/01 16:41:52	1.3
  @@ -31,9 +31,9 @@
    * A factory for the &ltpolyline> element.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGPolylineElementBridge.java,v 1.2 2001/02/01 13:45:46 tkormann Exp $
  + * @version $Id: SVGPolylineElementBridge.java,v 1.3 2001/02/01 16:41:52 vhardy Exp $
    */
  -public class SVGPolylineElementBridge extends SVGShapeElementBridge {
  +public class SVGPolylineElementBridge extends SVGDecoratedShapeElementBridge {
   
       /**
        * Returns an <tt>GeneralPath</tt>.
  
  
  
  1.1                  xml-batik/sources/org/apache/batik/bridge/MarkerBridge.java
  
  Index: MarkerBridge.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included with this distribution in  *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.batik.bridge;
  
  import java.awt.geom.AffineTransform;
  import java.awt.geom.Rectangle2D;
  
  import org.apache.batik.bridge.BridgeContext;
  import org.apache.batik.bridge.IllegalAttributeValueException;
  import org.apache.batik.bridge.Viewport;
  import org.apache.batik.gvt.CompositeGraphicsNode;
  import org.apache.batik.gvt.GraphicsNode;
  import org.apache.batik.gvt.Marker;
  import org.apache.batik.bridge.resources.Messages;
  import org.apache.batik.util.SVGConstants;
  import org.apache.batik.util.UnitProcessor;
  
  import org.w3c.dom.Element;
  import org.w3c.dom.css.CSSPrimitiveValue;
  import org.w3c.dom.css.CSSStyleDeclaration;
  import org.w3c.dom.svg.SVGElement;
  /**
   * Turns a marker element into a <tt>Marker</tt> object
   *
   * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
   * @version $Id: MarkerBridge.java,v 1.1 2001/02/01 16:41:49 vhardy Exp $
   */
  public interface MarkerBridge extends Bridge, SVGConstants {
      /**
       * @param ctx the context to use
       * @param elem the &lt;marker&gt element to be converted to a Marker object
       * @return a Marker object representing the Element
       */
      public Marker buildMarker(BridgeContext ctx,
                                Element markerElement,
                                Element paintedElement);
  }
  
  
  
  
  1.1                  xml-batik/sources/org/apache/batik/bridge/SVGDecoratedShapeElementBridge.java
  
  Index: SVGDecoratedShapeElementBridge.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included with this distribution in  *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.batik.bridge;
  
  import java.awt.AlphaComposite;
  import java.awt.Composite;
  import java.awt.Shape;
  import java.awt.geom.AffineTransform;
  
  import java.io.StringReader;
  
  import org.apache.batik.bridge.BridgeContext;
  import org.apache.batik.bridge.BridgeMutationEvent;
  import org.apache.batik.bridge.GraphicsNodeBridge;
  import org.apache.batik.bridge.IllegalAttributeValueException;
  import org.apache.batik.gvt.DecoratedShapeNode;
  import org.apache.batik.gvt.GraphicsNode;
  import org.apache.batik.gvt.GraphicsNodeRenderContext;
  import org.apache.batik.gvt.Marker;
  import org.apache.batik.gvt.ShapeNode;
  import org.apache.batik.gvt.ShapePainter;
  import org.apache.batik.ext.awt.image.renderable.Clip;
  import org.apache.batik.ext.awt.image.renderable.Filter;
  import org.apache.batik.gvt.filter.Mask;
  import org.apache.batik.parser.ParseException;
  import org.apache.batik.bridge.resources.Messages;
  import org.apache.batik.util.SVGConstants;
  import org.apache.batik.util.UnitProcessor;
  
  import org.w3c.dom.Element;
  import org.w3c.dom.svg.SVGElement;
  import org.w3c.dom.css.CSSStyleDeclaration;
  import org.w3c.dom.css.CSSPrimitiveValue;
  
  /**
   * A factory for the SVG elements that represents a shape.
   *
   * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
   * @version $Id: SVGDecoratedShapeElementBridge.java,v 1.1 2001/02/01 16:41:50 vhardy Exp $
   */
  public abstract class SVGDecoratedShapeElementBridge 
      extends SVGShapeElementBridge {
      
      public GraphicsNode createGraphicsNode(BridgeContext ctx, Element element){
          SVGElement svgElement = (SVGElement) element;
          CSSStyleDeclaration cssDecl
              = ctx.getViewCSS().getComputedStyle(element, null);
          UnitProcessor.Context uctx
              = new DefaultUnitProcessorContext(ctx,
                                                cssDecl);
  
          DecoratedShapeNode node = new DecoratedShapeNode();
  
          // Initialize the transform
          AffineTransform at =
              SVGUtilities.convertAffineTransform(element,
                                                  ATTR_TRANSFORM);
          node.setTransform(at);
          // Initialize the shape of the ShapeNode
          buildShape(ctx, svgElement, node, cssDecl, uctx);
  
          return node;
      }
  
      public void buildGraphicsNode(GraphicsNode gn, 
                                    BridgeContext ctx,
                                    Element element) {
          DecoratedShapeNode node = (DecoratedShapeNode)gn;
  
          SVGElement svgElement = (SVGElement) element;
          CSSStyleDeclaration cssDecl
              = ctx.getViewCSS().getComputedStyle(element, null);
          UnitProcessor.Context uctx
              = new DefaultUnitProcessorContext(ctx,
                                                cssDecl);
  
          //
          // Extract the marker properties
          //
          
          // Start with marker, a short-hand for start/middle/end
          Marker marker = CSSUtilities.convertMarker(svgElement,
                                                     CSS_MARKER_PROPERTY,
                                                     ctx, cssDecl, uctx);
  
          if(marker != null){
              node.setStartMarker(marker);
              node.setMiddleMarker(marker);
              node.setEndMarker(marker);
          }
          else{
              // Extract start, middle and end markers
              if(hasStartMarker()){
                  Marker startMarker 
                      = CSSUtilities.convertMarker(svgElement,
                                                   CSS_MARKER_START_PROPERTY,
                                                   ctx, cssDecl, uctx);
                  node.setStartMarker(startMarker);
              }
  
              if(hasEndMarker()){
                  Marker endMarker 
                      = CSSUtilities.convertMarker(svgElement,
                                                   CSS_MARKER_END_PROPERTY,
                                                   ctx, cssDecl, uctx);
                  node.setEndMarker(endMarker);
              }
  
              Marker middleMarker 
                  = CSSUtilities.convertMarker(svgElement,
                                               CSS_MARKER_MID_PROPERTY,
                                               ctx, cssDecl, uctx);
  
              node.setMiddleMarker(middleMarker);
          }
  
          super.buildGraphicsNode(gn, ctx, element);
      }
  
      protected boolean hasStartMarker(){
          return true;
      }
  
      protected boolean hasEndMarker(){
          return true;
      }
  
  }
  
  
  
  1.1                  xml-batik/sources/org/apache/batik/bridge/SVGMarkerElementBridge.java
  
  Index: SVGMarkerElementBridge.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included with this distribution in  *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.batik.bridge;
  
  import java.awt.geom.AffineTransform;
  import java.awt.geom.Point2D;
  import java.awt.geom.Rectangle2D;
  
  import org.apache.batik.bridge.BridgeContext;
  import org.apache.batik.bridge.GVTBuilder;
  import org.apache.batik.bridge.IllegalAttributeValueException;
  import org.apache.batik.bridge.Viewport;
  import org.apache.batik.gvt.CompositeGraphicsNode;
  import org.apache.batik.gvt.GraphicsNode;
  import org.apache.batik.gvt.GraphicsNodeRenderContext;
  import org.apache.batik.gvt.Marker;
  import org.apache.batik.gvt.filter.GraphicsNodeRable8Bit;
  import org.apache.batik.bridge.resources.Messages;
  import org.apache.batik.util.SVGConstants;
  import org.apache.batik.util.UnitProcessor;
  
  import org.apache.batik.ext.awt.image.renderable.Filter;
  import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit;
  
  import org.w3c.dom.Element;
  import org.w3c.dom.Node;
  import org.w3c.dom.css.CSSPrimitiveValue;
  import org.w3c.dom.css.CSSStyleDeclaration;
  import org.w3c.dom.svg.SVGElement;
  /**
   * Turns a marker element into a <tt>Marker</tt> object
   *
   * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
   * @version $Id: SVGMarkerElementBridge.java,v 1.1 2001/02/01 16:41:51 vhardy Exp $
   */
  public class SVGMarkerElementBridge implements MarkerBridge {
      /**
       * @param ctx the context to use
       * @param elem the &lt;marker&gt element to be converted to a Marker object
       * @return a Marker object representing the Element
       */
      public Marker buildMarker(BridgeContext ctx,
                                Element markerElement,
                                Element paintedElement){
          CSSStyleDeclaration cssDecl
              = ctx.getViewCSS().getComputedStyle(markerElement, null);
          UnitProcessor.Context uctx
              = new DefaultUnitProcessorContext(ctx,
                                                cssDecl);
          GVTBuilder builder = ctx.getGVTBuilder();
  
          CompositeGraphicsNode markerContentNode
              = new CompositeGraphicsNode();
  
          // build the GVT tree that represents the marker
          boolean hasChildren = false;
          for(Node node=markerElement.getFirstChild();
                   node != null;
                   node = node.getNextSibling()) {
  
              // check if the node is a valid Element
              if (node.getNodeType() != node.ELEMENT_NODE) {
                  continue;
              }
              Element child = (Element) node;
              GraphicsNode markerNode = builder.build(ctx, child) ;
              // check if a GVT node has been created
              if (markerNode == null) {
                  continue; // skip element as <marker> can contain <defs>...
              }
              hasChildren = true;
              markerContentNode.getChildren().add(markerNode);
          }
  
          if (!hasChildren) {
              System.out.println("No content in marker element");
              return null; // no marker content defined
          }
  
          // Extract the Marker's reference point coordinates
          String s = markerElement.getAttributeNS(null, SVG_REFX_ATTRIBUTE);
          float refX = 0;
          if (s.length() == 0) {
              s = SVG_DEFAULT_VALUE_MARKER_REFX;
          }
  
          refX = SVGUtilities.svgToUserSpace(markerElement,
                                             SVG_REFX_ATTRIBUTE, s,
                                             uctx,
                                             UnitProcessor.HORIZONTAL_LENGTH);
  
          // parse the refY attribute, (default is 0)
          s = markerElement.getAttributeNS(null, SVG_REFY_ATTRIBUTE);
          float refY = 0;
          if (s.length() == 0) {
              s = SVG_DEFAULT_VALUE_MARKER_REFY;
          }
  
          refY = SVGUtilities.svgToUserSpace(markerElement,
                                             SVG_REFY_ATTRIBUTE, s,
                                             uctx,
                                             UnitProcessor.VERTICAL_LENGTH);
          
          // Extract the Marker's width/height
          s = markerElement.getAttributeNS(null, SVG_MARKER_WIDTH_ATTRIBUTE);
          float markerWidth = 0;
          if (s.length() == 0) {
              s = SVG_DEFAULT_VALUE_MARKER_MARKER_WIDTH;
          }
  
          markerWidth= SVGUtilities.svgToUserSpace(markerElement,
                                                   SVG_MARKER_WIDTH_ATTRIBUTE, s,
                                                   uctx,
                                                   UnitProcessor.HORIZONTAL_LENGTH);
  
          // a zero markerWidth disables the marker
          if(markerWidth == 0){
              System.out.println("markerWidth is 0");
              return null;
          }
  
          // a negative markerWidth is an error
          if(markerWidth < 0){
              throw new IllegalAttributeValueException
                  ( Messages.formatMessage("marker.markerWidth.illegal",
                                           new Object[] {s}));
          }
  
          s = markerElement.getAttributeNS(null, SVG_MARKER_HEIGHT_ATTRIBUTE);
          float markerHeight = 0;
          if (s.length() == 0) {
              s = SVG_DEFAULT_VALUE_MARKER_MARKER_HEIGHT;
          }
  
          markerHeight = SVGUtilities.svgToUserSpace(markerElement,
                                                     SVG_MARKER_HEIGHT_ATTRIBUTE, s,
                                                     uctx,
                                                     UnitProcessor.HORIZONTAL_LENGTH);
  
          // a zero markerHeight disables the marker
          if(markerHeight == 0){
              System.out.println("markerHeight is 0");
              return null;
          }
  
          // a negative markerHeight is an error
          if(markerHeight < 0){
              throw new IllegalAttributeValueException
                  ( Messages.formatMessage("marker.markerHeight.illegal",
                                           new Object[] {s}));
          }
  
          // Extract the Marker's orient
          s = markerElement.getAttributeNS(null, SVG_ORIENT_ATTRIBUTE);
          double orient = 0;
          boolean autoOrient = false;
          if (s.length() == 0) {
              s = SVG_DEFAULT_VALUE_MARKER_ORIENT;
          }
  
          if (VALUE_AUTO.equals(s) ){
              orient = Double.NaN;
          }
          else{
              orient = 
                  SVGUtilities.convertSVGNumber(SVG_ORIENT_ATTRIBUTE, s);
          }
  
          // Extract the overflow property 
          CSSPrimitiveValue vbOverflow =
              (CSSPrimitiveValue)cssDecl.getPropertyCSSValue(CSS_OVERFLOW_PROPERTY);
  
          String overFlowValue = vbOverflow.getStringValue();
          if(overFlowValue.length() == 0){
              overFlowValue = CSS_HIDDEN_VALUE;
          }
  
          boolean overflow = true;
          if(CSS_HIDDEN_VALUE.equals(overFlowValue)){
              overflow = false;
          }
  
          // Extract the marker units
          s = markerElement.getAttributeNS(null,
                                        SVG_MARKER_UNITS_ATTRIBUTE);
  
          if (s.length() == 0) {
              s = SVG_DEFAULT_VALUE_MARKER_MARKER_UNITS;
          }
  
          String markerUnits = s;
  
          // Extract the viewBox and preserveAspectRatio
          s = markerElement.getAttributeNS(null, ATTR_VIEW_BOX);
          boolean hasViewBox = false;
          // viewBox -> viewPort (0, 0, markerWidth, markerHeight)
          AffineTransform preserveAspectRatioTransform = null;
  
          s = markerElement.getAttributeNS(null, ATTR_VIEW_BOX);
          if (s.length() > 0){
              preserveAspectRatioTransform
                  = SVGUtilities.getPreserveAspectRatioTransform
                  ((SVGElement)markerElement,
                   markerWidth,
                   markerHeight);
          }
  
          //
          // Compute the transform for the markerContentNode
          //
          AffineTransform markerTxf = new AffineTransform();
  
          float strokeWidth = 1;
          if(markerUnits.equals(SVG_STROKE_WIDTH_VALUE)){
              CSSStyleDeclaration cssDeclPainted
                  = ctx.getViewCSS().getComputedStyle(paintedElement, null);
          
              UnitProcessor.Context uctxPainted
                  = new DefaultUnitProcessorContext(ctx,
                                                    cssDeclPainted);
              CSSPrimitiveValue v =
                  (CSSPrimitiveValue)cssDeclPainted.getPropertyCSSValue(CSS_STROKE_WIDTH_PROPERTY);
  
              short type = v.getPrimitiveType();
              strokeWidth
                  = UnitProcessor.cssToUserSpace(type,
                                                 v.getFloatValue(type),
                                                 (SVGElement)paintedElement,
                                                 UnitProcessor.OTHER_LENGTH,
                                                 uctxPainted);
  
              markerTxf.scale(strokeWidth,
                              strokeWidth);
          }
  
          if(preserveAspectRatioTransform != null){
              markerTxf.concatenate(preserveAspectRatioTransform);
          }
          
  
          markerContentNode.setTransform(markerTxf);
  
          //
          // Set the markerContentNode's clipping area 
          // depending on the overflow property
          //
          if(overflow == false){
              Rectangle2D markerClip 
                  = new Rectangle2D.Float(0, 0, strokeWidth*markerWidth,
                                          strokeWidth*markerHeight);
              
              CompositeGraphicsNode newMarkerContentNode
                  = new CompositeGraphicsNode();
              
              newMarkerContentNode.getChildren().add(markerContentNode);
  
              GraphicsNodeRenderContext rc =
                  ctx.getGraphicsNodeRenderContext();
  
              Filter clipSrc = new GraphicsNodeRable8Bit
                  (newMarkerContentNode, rc);
              
              newMarkerContentNode.setClip
                  (new ClipRable8Bit(clipSrc, markerClip));
  
              markerContentNode = newMarkerContentNode;
          }
  
  
          //
          // Build Marker object now
          //
  
          //
          // Watch out: the reference point is defined a little weirdly in the 
          // SVG spec., but the bottom line is that the marker content should
          // not be translated. Rather, the reference point should be computed
          // in viewport space (this  is what the following transform
          // does) and used when placing the marker.
          //
          float ref[] = {refX, refY};
          markerTxf.transform(ref, 0, ref, 0, 1);
          Marker marker = new Marker(markerContentNode,
                                     new Point2D.Float(ref[0], ref[1]),
                                     orient);
  
          return marker;
      }
  }
  
  
  
  1.4       +4 -1      xml-batik/sources/org/apache/batik/css/svg/SVGValueFactoryMap.java
  
  Index: SVGValueFactoryMap.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/css/svg/SVGValueFactoryMap.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SVGValueFactoryMap.java	2000/11/27 05:49:03	1.3
  +++ SVGValueFactoryMap.java	2001/02/01 16:41:54	1.4
  @@ -16,7 +16,7 @@
    * to contains factories for SVG CSS values.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGValueFactoryMap.java,v 1.3 2000/11/27 05:49:03 hillion Exp $
  + * @version $Id: SVGValueFactoryMap.java,v 1.4 2001/02/01 16:41:54 vhardy Exp $
    */
   public class SVGValueFactoryMap
       extends    CommonValueFactoryMap
  @@ -86,6 +86,9 @@
   
   	put(CSS_LIGHTING_COLOR_PROPERTY,
               new SimpleColorFactory(p, CSS_LIGHTING_COLOR_PROPERTY));
  +
  +	put(CSS_MARKER_PROPERTY,
  +            new MarkerFactory(p, CSS_MARKER_PROPERTY));
   
   	put(CSS_MARKER_END_PROPERTY,
               new MarkerFactory(p, CSS_MARKER_END_PROPERTY));
  
  
  
  1.5       +2 -1      xml-batik/sources/org/apache/batik/css/svg/SVGViewCSS.java
  
  Index: SVGViewCSS.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/css/svg/SVGViewCSS.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- SVGViewCSS.java	2000/12/06 21:21:09	1.4
  +++ SVGViewCSS.java	2001/02/01 16:41:54	1.5
  @@ -16,7 +16,7 @@
    * the SVG CSS.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGViewCSS.java,v 1.4 2000/12/06 21:21:09 hillion Exp $
  + * @version $Id: SVGViewCSS.java,v 1.5 2001/02/01 16:41:54 vhardy Exp $
    */
   
   public class SVGViewCSS
  @@ -47,6 +47,7 @@
   	addRelativeValueResolver(new GlyphOrientationVerticalResolver());
   	addRelativeValueResolver(new ImageRenderingResolver());
   	addRelativeValueResolver(new LightingColorResolver());
  +	addRelativeValueResolver(new MarkerResolver(CSS_MARKER_PROPERTY));
   	addRelativeValueResolver(new MarkerResolver(CSS_MARKER_END_PROPERTY));
   	addRelativeValueResolver(new MarkerResolver(CSS_MARKER_MID_PROPERTY));
   	addRelativeValueResolver(new MarkerResolver(CSS_MARKER_START_PROPERTY));
  
  
  
  1.4       +2 -1      xml-batik/sources/org/apache/batik/dom/svg/ElementNonCSSPresentationalHintsSupport.java
  
  Index: ElementNonCSSPresentationalHintsSupport.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/dom/svg/ElementNonCSSPresentationalHintsSupport.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ElementNonCSSPresentationalHintsSupport.java	2000/11/27 05:49:23	1.3
  +++ ElementNonCSSPresentationalHintsSupport.java	2001/02/01 16:41:55	1.4
  @@ -23,7 +23,7 @@
    * processing in SVG.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: ElementNonCSSPresentationalHintsSupport.java,v 1.3 2000/11/27 05:49:23 hillion Exp $
  + * @version $Id: ElementNonCSSPresentationalHintsSupport.java,v 1.4 2001/02/01 16:41:55 vhardy Exp $
    */
   public class ElementNonCSSPresentationalHintsSupport
       implements CSSConstants {
  @@ -63,6 +63,7 @@
           PRESENTATION_ATTRIBUTES.add(CSS_IMAGE_RENDERING_PROPERTY);
           PRESENTATION_ATTRIBUTES.add(CSS_LETTER_SPACING_PROPERTY);
           PRESENTATION_ATTRIBUTES.add(CSS_LIGHTING_COLOR_PROPERTY);
  +        PRESENTATION_ATTRIBUTES.add(CSS_MARKER_PROPERTY);
           PRESENTATION_ATTRIBUTES.add(CSS_MARKER_END_PROPERTY);
           PRESENTATION_ATTRIBUTES.add(CSS_MARKER_MID_PROPERTY);
           PRESENTATION_ATTRIBUTES.add(CSS_MARKER_START_PROPERTY);
  
  
  
  1.29      +19 -2     xml-batik/sources/org/apache/batik/dom/svg/SVGOMDocument.java
  
  Index: SVGOMDocument.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/dom/svg/SVGOMDocument.java,v
  retrieving revision 1.28
  retrieving revision 1.29
  diff -u -r1.28 -r1.29
  --- SVGOMDocument.java	2001/01/30 17:39:43	1.28
  +++ SVGOMDocument.java	2001/02/01 16:41:55	1.29
  @@ -67,7 +67,7 @@
    * This class implements {@link org.w3c.dom.svg.SVGDocument}.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGOMDocument.java,v 1.28 2001/01/30 17:39:43 vhardy Exp $
  + * @version $Id: SVGOMDocument.java,v 1.29 2001/02/01 16:41:55 vhardy Exp $
    */
   public class SVGOMDocument
       extends    AbstractDocument
  @@ -87,7 +87,6 @@
        */
       protected LocalizableSupport localizableSupport =
           new LocalizableSupport(RESOURCES);
  -
       /**
        * The custom elements factories.
        */
  @@ -232,6 +231,9 @@
           factories.put(SVG_MASK_TAG,
                         new MaskElementFactory());
   
  +        factories.put(SVG_MARKER_TAG,
  +                      new MarkerElementFactory());
  +
           factories.put(SVG_METADATA_TAG,
                         new MetadataElementFactory());
   
  @@ -1235,6 +1237,21 @@
            */
           public Element create(String prefix) {
               return new SVGOMMaskElement(prefix, SVGOMDocument.this);
  +        }
  +    }
  +
  +    /**
  +     * To create a 'marker' element.
  +     */
  +    protected class MarkerElementFactory implements ElementFactory {
  +        public MarkerElementFactory() {}
  +        /**
  +         * Creates an instance of the associated element type.
  +         */
  +        public Element create(String prefix) {
  +            return new SVGOMToBeImplementedElement(prefix,
  +                                                   SVGOMDocument.this,
  +                                                   SVG_MARKER_TAG);
           }
       }
   
  
  
  
  1.6       +2 -2      xml-batik/sources/org/apache/batik/gvt/CompositeGraphicsNode.java
  
  Index: CompositeGraphicsNode.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/gvt/CompositeGraphicsNode.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- CompositeGraphicsNode.java	2001/01/29 07:09:39	1.5
  +++ CompositeGraphicsNode.java	2001/02/01 16:41:56	1.6
  @@ -32,7 +32,7 @@
    * A CompositeGraphicsNode is a graphics node that can contain graphics nodes.
    *
    * @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
  - * @version $Id: CompositeGraphicsNode.java,v 1.5 2001/01/29 07:09:39 tkormann Exp $
  + * @version $Id: CompositeGraphicsNode.java,v 1.6 2001/02/01 16:41:56 vhardy Exp $
    */
   public class CompositeGraphicsNode extends AbstractGraphicsNode
           implements List {
  @@ -81,7 +81,7 @@
       //
   
       /**
  -     * Returns the list of children or null if any.
  +     * Returns the list of children. Never null.
        */
       public List getChildren() {
           return this;
  
  
  
  1.1                  xml-batik/sources/org/apache/batik/gvt/DecoratedShapeNode.java
  
  Index: DecoratedShapeNode.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included with this distribution in  *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.batik.gvt;
  
  import java.awt.Shape;
  import java.awt.Graphics2D;
  import java.awt.geom.AffineTransform;
  import java.awt.geom.Point2D;
  import java.awt.geom.Rectangle2D;
  import java.awt.geom.PathIterator;
  
  import java.util.List;
  import java.util.Vector;
  
  /**
   * A <code>DecoratedShapeNode</code> can draw <code>Markers</code>
   * at the start, end or along the path of a <code>Shape</code>.
   * <code>DecoratedShapeNode</code> extends <code>ShapeNode</code>
   * because it has all the same properties as a <code>ShapeNode</code>,
   * the markers being additions to the rendering behavior.
   * <br />
   * <code>DecoratedShapeNode</code> accepts three types of 
   * <code>Markers</code>: start, end and middle. The start 
   * <code>Marker</code>, if any, is drawn on the first vertice
   * of the decorated shape. The end <code>Marker</code>, if any, is
   * drawn on the last vertice of the decorated shape. The middle
   * <code>Marker</code>, if any, is drawn on all vertices, except the
   * first and last ones.
   *
   * @author <a mailto:"vincent.hardy@eng.sun.com">Vincent Hardy</a>
   * @author <a mailto:"tkormann@apache.org">Thierry Kormann</a>
   * @version $Id: DecoratedShapeNode.java,v 1.1 2001/02/01 16:41:56 vhardy Exp $
   */
  public class DecoratedShapeNode extends ShapeNode {
      /**
       * Start Marker
       */
      private Marker startMarker;
      
      /**
       * Start Marker Proxy
       */
      private ProxyGraphicsNode startMarkerProxy;
  
      /**
       * Middle Marker
       */
      private Marker middleMarker;
  
      /**
       * Middle Marker Proxy
       */
      private ProxyGraphicsNode middleMarkerProxies[];
  
      /**
       * End Marker
       */
      private Marker endMarker;
  
      /**
       * End Marker Proxy
       */
      private ProxyGraphicsNode endMarkerProxy;
  
      /**
       * Internal Cache: Primitive bounds
       */
      private Rectangle2D dPrimitiveBounds;
  
      /**
       * Internal Cache: Geometry bounds
       */
      private Rectangle2D dGeometryBounds;
  
      /**
       * Contains the various marker proxies
       */
      private CompositeGraphicsNode markerGroup = new CompositeGraphicsNode();
  
      public void setStartMarker(Marker startMarker){
          System.out.println("Setting start : " + startMarker);
          this.startMarker = startMarker;
          this.startMarkerProxy = null;
          invalidateGeometryCache();
          markerGroup = buildMarkerGroup();
      }
  
      public void setMiddleMarker(Marker middleMarker){
          System.out.println("Setting middle");
          this.middleMarker = middleMarker;
          this.middleMarkerProxies = null;
          invalidateGeometryCache();
          markerGroup = buildMarkerGroup();
      }
  
      public void setEndMarker(Marker endMarker){
          System.out.println("Setting end");
          this.endMarker = endMarker;
          this.endMarkerProxy = null;
          invalidateGeometryCache();
          markerGroup = buildMarkerGroup();
      }
  
      public Marker getStartMarker(){
          return startMarker;
      }
  
      public Marker getMiddleMarker(){
          return middleMarker;
      }
  
      public Marker getEndMarker(){
          return endMarker;
      }
  
      /**
       * Builds a new marker group with the current set of 
       * markers
       */
      private CompositeGraphicsNode buildMarkerGroup(){
          System.out.println("Building markerGroup : " + startMarker);
          if(startMarker != null && startMarkerProxy == null){
              startMarkerProxy = buildStartMarkerProxy();
          }
  
          if(middleMarker != null && middleMarkerProxies == null){
              middleMarkerProxies = buildMiddleMarkerProxies();
          }
  
          if(endMarker != null && endMarkerProxy == null){
              endMarkerProxy = buildEndMarkerProxy();
          }
  
          CompositeGraphicsNode group = new CompositeGraphicsNode();
          List children = group.getChildren();
          if(startMarkerProxy != null){
              children.add(startMarkerProxy);
          }
  
          if(middleMarkerProxies != null){
              for(int i=0; i<middleMarkerProxies.length; i++){
                  children.add(middleMarkerProxies[i]);
              }
          }
  
          if(endMarkerProxy != null){
              children.add(endMarkerProxy);
          }
  
          System.out.println("List has : " + children.size() + " children");
          return group;
      }
  
      /**
       * Builds a proxy <tt>GraphicsNode</tt> for the input 
       * <tt>Marker</tt> to be drawn at the start position
       */
      public ProxyGraphicsNode buildStartMarkerProxy(){
          System.out.println("Building startMarkerProxy");
          PathIterator iter = getShape().getPathIterator(null);
  
          // Get initial point on the path
          double coords[] = new double[6];
          int segType = 0;
  
          if(iter.isDone()){
              System.out.println("No points in Shape");
              return null;
          }
  
          segType = iter.currentSegment(coords);
          if(segType != iter.SEG_MOVETO){
              System.err.println("Segments starts with a : " + segType);
              return null;
          }
          iter.next();
  
          Point2D markerPosition 
              = new Point2D.Double(coords[0],
                                   coords[1]);
  
          // If the marker's orient property is NaN,
          // the slope needs to be computed
          double rotation = startMarker.getOrient();
          if(Double.isNaN(rotation)){
              if(!iter.isDone()){
                  double next[] = new double[6];
                  int nextSegType = 0;
                  nextSegType = iter.currentSegment(next);
                  rotation = computeRotation((double[])null, 0, // no previous seg.
                                             coords, segType,   // segment ending on start point
                                             next, nextSegType, // segment out of start point
                                             new double[]{ coords[0], coords[1] });
                  
              }
          }
          
          // Now, compute the marker's proxy transform
          AffineTransform markerTxf =
              computeMarkerTransform(startMarker,
                                     markerPosition,
                                     rotation);
                                     
          ProxyGraphicsNode gn 
              = new ProxyGraphicsNode();
  
          gn.setSource(startMarker.getMarkerNode());
          gn.setTransform(markerTxf);
  
          return gn;
      }
  
      /**
       * Builds a proxy <tt>GraphicsNode</tt> for the input 
       * <tt>Marker</tt> to be drawn at the end position
       */
      public ProxyGraphicsNode buildEndMarkerProxy(){
          PathIterator iter = getShape().getPathIterator(null);
  
          int nPoints = 0;
  
          // Get first point, in case the last segment on the
          // path is a close
          if(iter.isDone()){
              return null;
          }
  
          double coords[] = new double[6];
          double moveTo[] = new double[2];
          int segType = 0;
          segType = iter.currentSegment(coords);
          if(segType != iter.SEG_MOVETO){
              return null;
          }
          nPoints++;
          moveTo[0] = coords[0];
          moveTo[1] = coords[1];
  
          iter.next();
          
          // Now, get the last two points on the path
          double[] lastButOne = new double[6];
          double[] last = {coords[0], coords[1], coords[2],
                           coords[3], coords[4], coords[5] }, tmp = null;
          int lastSegType = segType;
          int lastButOneSegType = 0;
          while(!iter.isDone()){
              tmp = lastButOne;
              lastButOne = last;
              last = tmp;
              lastButOneSegType = lastSegType;
  
              lastSegType = iter.currentSegment(last);
  
              if(lastSegType == PathIterator.SEG_MOVETO){
                  moveTo[0] = last[0];
                  moveTo[1] = last[1];
              }
  
              iter.next();
              nPoints++;
          }
  
          if (nPoints < 2){
              return null;
          }
  
          // Turn the last segment into a position
          Point2D markerPosition = null;
          if(lastSegType != PathIterator.SEG_CLOSE){
              markerPosition = getSegmentTerminatingPoint(last, lastSegType);
          }
          else{
              markerPosition = getSegmentTerminatingPoint(coords, segType);
          }
  
          if(markerPosition == null){
              return null;
          }
  
          // If the marker's orient property is NaN,
          // the slope needs to be computed
          double rotation = endMarker.getOrient();
          if(Double.isNaN(rotation)){
              rotation = computeRotation(lastButOne, 
                                         lastButOneSegType, 
                                         last, lastSegType,
                                         null, 0,
                                         moveTo);
          }
  
          // Now, compute the marker's proxy transform
          AffineTransform markerTxf =
              computeMarkerTransform(endMarker,
                                     markerPosition,
                                     rotation);
                                     
          ProxyGraphicsNode gn 
              = new ProxyGraphicsNode();
  
          gn.setSource(endMarker.getMarkerNode());
          gn.setTransform(markerTxf);
  
          return gn;
      }
  
      /**
       * Extracts the terminating point, depending on the segment type.
       */
      private final Point2D getSegmentTerminatingPoint(double coords[], int segType){
          switch(segType){
          case PathIterator.SEG_CLOSE:
              return null;
          case PathIterator.SEG_CUBICTO:
              return new Point2D.Double(coords[4], coords[5]);
          case PathIterator.SEG_LINETO:
              return new Point2D.Double(coords[0], coords[1]);
          case PathIterator.SEG_MOVETO:
              return new Point2D.Double(coords[0], coords[1]);
          case PathIterator.SEG_QUADTO:
              return new Point2D.Double(coords[2], coords[3]);
          default:
              return null;
          }
      }
  
      /**
       * Builds a proxy <tt>GraphicsNode</tt> for the input 
       * <tt>Marker</tt> to be drawn at the middle positions
       */
      public ProxyGraphicsNode[] buildMiddleMarkerProxies(){
          PathIterator iter = getShape().getPathIterator(null);
  
          double[] prev = new double[6];
          double[] cur = new double[6];
          double[] next = new double[6], tmp = null;
          int prevSegType = 0, curSegType = 0, nextSegType = 0;
  
          // Get the first three points on the path
          if(iter.isDone()){
              return null;
          }
  
          prevSegType = iter.currentSegment(prev);
  
          double[] moveTo = new double[2];
  
          if(prevSegType != PathIterator.SEG_MOVETO){
              return null;
          }
  
          moveTo[0] = prev[0];
          moveTo[1] = prev[1];
  
          iter.next();
  
          if(iter.isDone()){
              return null;
          }
  
          curSegType = iter.currentSegment(cur);
  
          if(curSegType == PathIterator.SEG_MOVETO){
              moveTo[0] = cur[0];
              moveTo[1] = cur[1];
          }
  
          iter.next();
  
          Vector proxies = new Vector();
          while(!iter.isDone()){
              nextSegType = iter.currentSegment(next);
  
              if(nextSegType == PathIterator.SEG_MOVETO){
                  moveTo[0] = next[0];
                  moveTo[1] = next[1];
              }
  
              proxies.addElement(createMiddleMarker(prev, prevSegType,
                                                    cur, curSegType,
                                                    next, nextSegType,
                                                    moveTo));
              
              tmp = prev;
              prev = cur;
              prevSegType = curSegType;
              cur = next;
              curSegType = nextSegType;
              next = tmp;
              
              iter.next();
          }
  
          ProxyGraphicsNode gn[]
              = new ProxyGraphicsNode[proxies.size()];
  
          proxies.copyInto(gn);
  
          return gn;
      }
  
      private ProxyGraphicsNode createMiddleMarker(double[] prev,
                                                   int prevSegType,
                                                   double[] cur,
                                                   int curSegType,
                                                   double[] next,
                                                   int nextSegType,
                                                   double[] moveTo){
  
          // Turn the cur segment into a position
          Point2D markerPosition = null;
          if(curSegType != PathIterator.SEG_CLOSE){
              markerPosition = getSegmentTerminatingPoint(cur, curSegType);
          }
          else{
              markerPosition = new Point2D.Double(moveTo[0], moveTo[1]);
          }
  
          if(markerPosition == null){
              return null;
          }
  
          // If the marker's orient property is NaN,
          // the slope needs to be computed
          double rotation = middleMarker.getOrient();
          if(Double.isNaN(rotation)){
              rotation = computeRotation(prev, prevSegType,
                                         cur, curSegType,
                                         next, nextSegType,
                                         moveTo);
          }
  
          // Now, compute the marker's proxy transform
          AffineTransform markerTxf =
              computeMarkerTransform(middleMarker,
                                     markerPosition,
                                     rotation);
                                     
          ProxyGraphicsNode gn 
              = new ProxyGraphicsNode();
  
          gn.setSource(middleMarker.getMarkerNode());
          gn.setTransform(markerTxf);
  
          return gn;
      }
  
      private double computeRotation(double[] prev,
                                     int prevSegType,
                                     double[] cur,
                                     int curSegType,
                                     double[] next,
                                     int nextSegType,
                                     double[] moveTo){
          // Compute in slope, i.e., the slope of the segment
          // going into the current point
          double inSlope = computeInSlope(prev, prevSegType, 
                                          cur, curSegType, moveTo);
  
          // Compute out slope, i.e., the slope of the segment
          // going out of the current point
          double outSlope = computeOutSlope(cur, curSegType, 
                                            next, nextSegType, moveTo);
  
          System.out.println("inSlope / outSlope : " + inSlope + "/" + outSlope);
  
          if(Double.isNaN(inSlope)){
              inSlope = outSlope;
          }
  
          if(Double.isNaN(outSlope)){
              outSlope = inSlope;
          }
  
          if(Double.isNaN(inSlope)){
              return 0;
          }
  
         
          double rotationIn  = Math.atan(inSlope)*180./Math.PI;
          double rotationOut = Math.atan(outSlope)*180./Math.PI;
          double rotation = (rotationIn + rotationOut)/2;
  
          return rotation;
      }
  
      private double computeInSlope(double[] prev,
                                    int prevSegType,
                                    double[] cur,
                                    int curSegType,
                                    double[] moveTo){
          // Compute point into which the slope runs
          Point2D curEndPoint = null;
          if(curSegType != PathIterator.SEG_CLOSE){
              curEndPoint = getSegmentTerminatingPoint(cur, curSegType);
              if(curEndPoint == null){
                  return Double.NaN;
              }
          }
          else{
              curEndPoint = new Point2D.Double(moveTo[0], moveTo[1]);
          }
  
          double dx = 0, dy = 0;
          switch(curSegType){
          case PathIterator.SEG_LINETO:
          case PathIterator.SEG_CLOSE:
              //
              // This is equivalent to a line from the previous
              // segment's terminating point and the current end
              // point.
              Point2D prevEndPoint = null;
              if(prevSegType != PathIterator.SEG_CLOSE){
                  prevEndPoint = getSegmentTerminatingPoint(prev, prevSegType);
                  if(prevEndPoint == null){
                      return Double.NaN;
                  }
              }
              else{
                  prevEndPoint = new Point2D.Double(moveTo[0], moveTo[1]);
              }
                  
              dx = curEndPoint.getX() - prevEndPoint.getX();
              dy = curEndPoint.getY() - prevEndPoint.getY();
              if(dx > 0){
                  return dy / dx;
              }
              if(dy > 0){
                  return Double.POSITIVE_INFINITY;
              }
              if(dy < 0){
                  return Double.NEGATIVE_INFINITY;
              }
              return 0;
          case PathIterator.SEG_CUBICTO:
              // If the current segment is a line, quad or cubic curve. 
              // the slope is about equal to that of the
              // line from the last control point and the curEndPoint
              dx = curEndPoint.getX() - prev[4];
              dy = curEndPoint.getY() - prev[5];
              if(dx > 0){
                  return dy / dx;
              }
              if(dy > 0){
                  return Double.POSITIVE_INFINITY;
              }
              if(dy < 0){
                  return Double.NEGATIVE_INFINITY;
              }
              return 0;
          case PathIterator.SEG_QUADTO:
              // If the current segment is a line, quad or cubic curve. 
              // the slope is about equal to that of the
              // line from the last control point and the curEndPoint
              dx = curEndPoint.getX() - prev[2];
              dy = curEndPoint.getY() - prev[3];
              if(dx > 0){
                  return dy / dx;
              }
              if(dy > 0){
                  return Double.POSITIVE_INFINITY;
              }
              if(dy < 0){
                  return Double.NEGATIVE_INFINITY;
              }
              return 0;
          case PathIterator.SEG_MOVETO:
              // Cannot compute the slope
          default:
              return Double.NaN;
          }
      }
  
      private double computeOutSlope(double[] cur,
                                     int curSegType,
                                     double[] next,
                                     int nextSegType,
                                     double[] moveTo){
          Point2D curEndPoint = null;
          if(curSegType != PathIterator.SEG_CLOSE){
              curEndPoint = getSegmentTerminatingPoint(cur, curSegType);
              if(curEndPoint == null){
                  System.out.println("Cannot compute curEndPoint");
                  return Double.NaN;
              }
          }
          else{
              curEndPoint = new Point2D.Double(moveTo[0], moveTo[1]);
          }
          
          double dx = 0, dy = 0;
  
          switch(nextSegType){
          case PathIterator.SEG_CLOSE:
              //
              // This is equivalent to a line to the
              // last moveTo. Use the slope between the
              // last moveTo and the terminating point on 
              // the current segment
              //
              dx = moveTo[0] - curEndPoint.getX();
              dy = moveTo[1] - curEndPoint.getY();
              if(dx != 0){
                  return dy / dx;
              }
              if(dy > 0){
                  return Double.POSITIVE_INFINITY;
              }
              if(dy < 0){
                  return Double.NEGATIVE_INFINITY;
              }
              return 0;
          case PathIterator.SEG_CUBICTO:
          case PathIterator.SEG_LINETO:
          case PathIterator.SEG_QUADTO:
              // If the next segment is a line, quad or cubic curve. 
              // the slope is about equal to that of the
              // line from curEndPoint and the first control
              // point
              dx = next[0] - curEndPoint.getX();
              dy = next[1] - curEndPoint.getY();
              if(dx != 0){
                  return dy / dx;
              }
              if(dy > 0){
                  return Double.POSITIVE_INFINITY;
              }
              if(dy < 0){
                  return Double.NEGATIVE_INFINITY;
              }
              return 0;
          case PathIterator.SEG_MOVETO:
              // Cannot compute the out slope
          default:
              return Double.NaN;
          }
      }
  
      /**
       * Computes the transform for the input marker, so that
       * it is positioned at the given position with the specified
       * rotation
       */
      private AffineTransform 
          computeMarkerTransform(Marker marker,
                                 Point2D markerPosition,
                                 double rotation){
          Point2D ref = marker.getRef();
          /*AffineTransform txf = 
              AffineTransform.getTranslateInstance(markerPosition.getX()
                                                   - ref.getX(),
                                                   markerPosition.getY()
                                                   - ref.getY());*/
          AffineTransform txf = new AffineTransform();
  
          txf.translate(markerPosition.getX()
                        - ref.getX(),
                        markerPosition.getY()
                        - ref.getY());
  
          if(!Double.isNaN(rotation)){
              txf.rotate(rotation*Math.PI/180., 
                         ref.getX(),
                         ref.getY());
          }
          else{
              Exception e = new Exception();
              e.printStackTrace();
          }
  
          return txf;
      }
  
      /**
       * Paints this node without applying Filter, Mask, Composite and clip.
       *
       * @param g2d the Graphics2D to use
       * @param rc the GraphicsNodeRenderContext to use
       */
      public void primitivePaint(Graphics2D g2d, GraphicsNodeRenderContext rc){
          // First, draw this ShapeNode
          super.primitivePaint(g2d, rc);
  
          // Now, paint markers
          try{
              markerGroup.paint(g2d, rc);
          }catch(InterruptedException e){
              // ????????? Should we really have interrupted exceptions?
          }
      }
  
      /**
       * Invalidates this <tt>ShapeNode</tt>. This node and all its
       * ancestors have been informed that all its cached values related
       * to its bounds must be recomputed.
       */
      protected void invalidateGeometryCache() {
          super.invalidateGeometryCache();
          dPrimitiveBounds = null;
          dGeometryBounds = null;
      }
  
      /**
       * Tests if the specified Point2D is inside the boundary of this node.
       * <b>Note</b>: The boundaries of some nodes (notably, text element nodes)
       * cannot be precisely determined independent of their
       * GraphicsNodeRenderContext.
       *
       * @param p the specified Point2D in the user space
       * @param rc the GraphicsNodeRenderContext for which this dimension applies
       * @return true if the coordinates are inside, false otherwise
       */
      public boolean contains(Point2D p, GraphicsNodeRenderContext rc) {
          return (super.contains(p, rc) | markerGroup.contains(p, rc));
      }
  
      /**
       * Tests if the interior of this node intersects the interior of a
       * specified Rectangle2D.
       * <b>Note</b>: The boundaries of some nodes (notably, text element nodes)
       * cannot be precisely determined independent of their
       * GraphicsNodeRenderContext.
       *
       * @param r the specified Rectangle2D in the user node space
       * @param rc the GraphicsNodeRenderContext for which this dimension applies
       * @return true if the rectangle intersects, false otherwise
       */
      public boolean intersects(Rectangle2D r, GraphicsNodeRenderContext rc) {
          return (super.intersects(r, rc) | markerGroup.intersects(r, rc));
      }
  
      /**
       * Returns the bounds of the area covered by this node's primitive paint.
       * <b>Note</b>: The boundaries of some nodes (notably, text element nodes)
       * cannot be precisely determined independent of their
       * GraphicsNodeRenderContext.
       *
       * @param rc the GraphicsNodeRenderContext for which this dimension applies
       */
      public Rectangle2D getPrimitiveBounds(GraphicsNodeRenderContext rc) {
          if (dPrimitiveBounds == null) {
              Rectangle2D shapePrimitiveBounds = super.getPrimitiveBounds(rc);
              Rectangle2D markerGroupBounds = markerGroup.getBounds(rc);
              dPrimitiveBounds = (Rectangle2D)shapePrimitiveBounds.clone();
              dPrimitiveBounds.add(markerGroupBounds);
          }
          return dPrimitiveBounds;
      }
  
      /**
       * Returns the bounds of the area covered by this <tt>ShapeNode</tt>,
       * without taking any of its rendering attribute into account.
       * (i.e., exclusive of any clipping, masking, filtering or stroking...)
       * <b>Note</b>: The boundaries of some nodes (notably, text element nodes)
       * cannot be precisely determined independent of their
       * GraphicsNodeRenderContext.
       *
       * @param rc the GraphicsNodeRenderContext for which this dimension applies
       */
      public Rectangle2D getGeometryBounds(GraphicsNodeRenderContext rc){
          if (dGeometryBounds == null) {
              Rectangle2D shapeGeometryBounds = super.getGeometryBounds(rc);
              Rectangle2D markerGroupGeometryBounds 
                  = markerGroup.getGeometryBounds(rc);
              dGeometryBounds  = (Rectangle2D)shapeGeometryBounds.clone();
              dGeometryBounds.add(markerGroupGeometryBounds);
          }
          return dGeometryBounds;
      }
  
      /**
       * Returns the outline of this <tt>DecoratedShapeNode</tt>.
       *
       * @param rc the GraphicsNodeRenderContext for which this dimension applies
       * @return the outline of this node
       */
      public Shape getOutline(GraphicsNodeRenderContext rc) {
          return super.getOutline(rc);
      }
  
  }
  
  
  
  1.1                  xml-batik/sources/org/apache/batik/gvt/Marker.java
  
  Index: Marker.java
  ===================================================================
  /*****************************************************************************
   * Copyright (C) The Apache Software Foundation. All rights reserved.        *
   * ------------------------------------------------------------------------- *
   * This software is published under the terms of the Apache Software License *
   * version 1.1, a copy of which has been included with this distribution in  *
   * the LICENSE file.                                                         *
   *****************************************************************************/
  
  package org.apache.batik.gvt;
  
  import java.awt.geom.Point2D;
  
  /**
   * A Marker describes a GraphicsNode with a reference point that can
   * be used to position the Marker at a particular location and a 
   * particular policy for rotating the marker when drawing it.
   *
   * @author <a href="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
   * @version $Id: Marker.java,v 1.1 2001/02/01 16:41:57 vhardy Exp $
   */
  public class Marker {
      /**
       * Rotation angle, about (0, 0) is user space. If orient is NaN
       * then the marker's x-axis should be aligned with the slope
       * of the curve on the point where the object is drawn
       */
      private double orient;
  
      /**
       * GraphicsNode this marker is associated to
       */
      private GraphicsNode markerNode;
  
      /**
       * Reference point about which the marker should be drawn
       */
      private Point2D ref;
  
      public Marker(GraphicsNode markerNode,
                    Point2D ref,
                    double orient){
          if(markerNode == null){
              throw new IllegalArgumentException();
          }
  
          if(ref == null){
              throw new IllegalArgumentException();
          }
  
          this.markerNode = markerNode;
          this.ref = ref;
          this.orient = orient;
      }
  
      public Point2D getRef(){
          return (Point2D)ref.clone();
      }
  
      /**
       * @see #orient
       */
      public double getOrient(){
          return orient;
      }
  
      /**
       * Returns the <code>GraphicsNode</code> that draws this
       * Marker
       */
      public GraphicsNode getMarkerNode(){
          return markerNode;
      }
  }
  
  
  
  1.11      +2 -1      xml-batik/sources/org/apache/batik/util/CSSConstants.java
  
  Index: CSSConstants.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/util/CSSConstants.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- CSSConstants.java	2000/11/27 05:49:26	1.10
  +++ CSSConstants.java	2001/02/01 16:41:57	1.11
  @@ -13,7 +13,7 @@
    * Important: Constants must not contain uppercase characters.
    *
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: CSSConstants.java,v 1.10 2000/11/27 05:49:26 hillion Exp $
  + * @version $Id: CSSConstants.java,v 1.11 2001/02/01 16:41:57 vhardy Exp $
    */
   public interface CSSConstants {
       //
  @@ -50,6 +50,7 @@
       String CSS_IMAGE_RENDERING_PROPERTY = "image-rendering";
       String CSS_LETTER_SPACING_PROPERTY = "letter-spacing";
       String CSS_LIGHTING_COLOR_PROPERTY = "lighting-color";
  +    String CSS_MARKER_PROPERTY = "marker";
       String CSS_MARKER_END_PROPERTY = "marker-end";
       String CSS_MARKER_MID_PROPERTY = "marker-mid";
       String CSS_MARKER_START_PROPERTY = "marker-start";
  
  
  
  1.39      +26 -11    xml-batik/sources/org/apache/batik/util/SVGConstants.java
  
  Index: SVGConstants.java
  ===================================================================
  RCS file: /home/cvs/xml-batik/sources/org/apache/batik/util/SVGConstants.java,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- SVGConstants.java	2001/01/31 17:54:33	1.38
  +++ SVGConstants.java	2001/02/01 16:41:58	1.39
  @@ -13,7 +13,7 @@
    *
    * @author <a href="vincent.hardy@eng.sun.com">Vincent Hardy</a>
    * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
  - * @version $Id: SVGConstants.java,v 1.38 2001/01/31 17:54:33 billh Exp $
  + * @version $Id: SVGConstants.java,v 1.39 2001/02/01 16:41:58 vhardy Exp $
    */
   public interface SVGConstants extends CSSConstants {
       String SVG_PUBLIC_ID =
  @@ -63,6 +63,7 @@
       String SVG_IMAGE_TAG = "image";
       String TAG_LINE = "line";
       String TAG_LINEAR_GRADIENT = "linearGradient";
  +    String SVG_MARKER_TAG = "marker";
       String SVG_MASK_TAG = "mask";
       String SVG_METADATA_TAG = "metadata";
       String TAG_PATH = "path";
  @@ -141,19 +142,23 @@
       String ATTR_LENGTH_ADJUST = "lengthAdjust";
       String ATTR_LIGHT_COLOR = "lightColor";
       String SVG_LIMITING_CONE_ANGLE_ATTRIBUTE = "limitingConeAngle";
  -    String SVG_NUM_OCTAVES_ATTRIBUTE = "numOctaves";
  +    String SVG_MARKER_HEIGHT_ATTRIBUTE = "markerHeight";
  +    String SVG_MARKER_WIDTH_ATTRIBUTE = "markerWidth";
  +    String SVG_MARKER_UNITS_ATTRIBUTE = "markerUnits";
       String ATTR_MASK = CSS_MASK_PROPERTY;
       String ATTR_MASK_CONTENT_UNITS = "maskContentUnits";
       String SVG_MASK_UNITS_ATTRIBUTE = "maskUnits";
       String ATTR_MEDIA = "media";
       String ATTR_METHOD = "method";
       String SVG_MODE_ATTRIBUTE = "mode";
  +    String SVG_NUM_OCTAVES_ATTRIBUTE = "numOctaves";
       String SVG_OFFSET_ATTRIBUTE = "offset";
       String ATTR_OPACITY = CSS_OPACITY_PROPERTY;
       String SVG_OPERATOR_ATTRIBUTE = "operator";
       String SVG_ORDER_ATTRIBUTE = "order";
       String SVG_ORDER_X_ATTRIBUTE = "orderX";
       String SVG_ORDER_Y_ATTRIBUTE = "orderY";
  +    String SVG_ORIENT_ATTRIBUTE = "orient";
       String ATTR_PATTERN_CONTENT_UNITS = "patternContentUnits";
       String ATTR_PATTERN_TRANSFORM = "patternTransform";
       String ATTR_PATTERN_UNITS = "patternUnits";
  @@ -166,6 +171,8 @@
       String SVG_PRIMITIVE_UNITS_ATTRIBUTE = "primitiveUnits";
       String SVG_R_ATTRIBUTE = "r";
       String ATTR_RADIUS = "radius";
  +    String SVG_REFX_ATTRIBUTE = "refX";
  +    String SVG_REFY_ATTRIBUTE = "refY";
       String ATTR_RESULT = "result";
       String ATTR_RESULT_SCALE = "resultScale";
       String SVG_RX_ATTRIBUTE = "rx";
  @@ -306,6 +313,7 @@
       String VALUE_START = "start";
       String SVG_STITCH_VALUE = "stitch";
       String VALUE_STRETCH = "stretch";
  +    String SVG_STROKE_WIDTH_VALUE = "strokeWidth";
       String SVG_TABLE_VALUE = "table";
       String SVG_TURBULENCE_VALUE = "turbulence";
       String VALUE_TYPE_LINEAR = "linear";
  @@ -347,12 +355,6 @@
       String SVG_DEFAULT_VALUE_ELLIPSE_CX = "0";
       String SVG_DEFAULT_VALUE_ELLIPSE_CY = "0";
   
  -    String SVG_DEFAULT_VALUE_FE_COMPOSITE_K1 = "0";
  -    String SVG_DEFAULT_VALUE_FE_COMPOSITE_K2 = "0";
  -    String SVG_DEFAULT_VALUE_FE_COMPOSITE_K3 = "0";
  -    String SVG_DEFAULT_VALUE_FE_COMPOSITE_K4 = "0";
  -    String SVG_DEFAULT_VALUE_FE_COMPOSITE_OPERATOR = SVG_OVER_VALUE;
  -
       String SVG_DEFAULT_VALUE_COMPONENT_TRANSFER_FUNCTION_TABLE_VALUES = "";
       String SVG_DEFAULT_VALUE_COMPONENT_TRANSFER_FUNCTION_SLOPE = "1";
       String SVG_DEFAULT_VALUE_COMPONENT_TRANSFER_FUNCTION_INTERCEPT = "0";
  @@ -360,6 +362,12 @@
       String SVG_DEFAULT_VALUE_COMPONENT_TRANSFER_FUNCTION_EXPONENT = "1";
       String SVG_DEFAULT_VALUE_COMPONENT_TRANSFER_FUNCTION_OFFSET = "0";
   
  +    String SVG_DEFAULT_VALUE_FE_COMPOSITE_K1 = "0";
  +    String SVG_DEFAULT_VALUE_FE_COMPOSITE_K2 = "0";
  +    String SVG_DEFAULT_VALUE_FE_COMPOSITE_K3 = "0";
  +    String SVG_DEFAULT_VALUE_FE_COMPOSITE_K4 = "0";
  +    String SVG_DEFAULT_VALUE_FE_COMPOSITE_OPERATOR = SVG_OVER_VALUE;
  +
       String SVG_DEFAULT_VALUE_FE_CONVOLVE_MATRIX_EDGE_MODE = SVG_DUPLICATE_VALUE;
   
       String SVG_DEFAULT_VALUE_FE_DIFFUSE_LIGHTING_SURFACE_SCALE = "1";
  @@ -395,11 +403,18 @@
       String SVG_DEFAULT_VALUE_FILTER_PRIMITIVE_UNITS =
           SVG_USER_SPACE_ON_USE_VALUE;
   
  -    String SVG_DEFAULT_VALUE_MASK_MASK_UNITS =
  -        SVG_USER_SPACE_ON_USE_VALUE;
  -
       String SVG_DEFAULT_VALUE_IMAGE_X = "0";
       String SVG_DEFAULT_VALUE_IMAGE_Y = "0";
  +
  +    String SVG_DEFAULT_VALUE_MARKER_REFX = "0";
  +    String SVG_DEFAULT_VALUE_MARKER_REFY = "0";
  +    String SVG_DEFAULT_VALUE_MARKER_MARKER_WIDTH = "3";
  +    String SVG_DEFAULT_VALUE_MARKER_MARKER_HEIGHT = "3";
  +    String SVG_DEFAULT_VALUE_MARKER_MARKER_UNITS = "strokeWidth";
  +    String SVG_DEFAULT_VALUE_MARKER_ORIENT = "0";
  +
  +    String SVG_DEFAULT_VALUE_MASK_MASK_UNITS =
  +        SVG_USER_SPACE_ON_USE_VALUE;
   
       String DEFAULT_VALUE_FILTER_X = "-10%";
       String DEFAULT_VALUE_FILTER_Y = "-10%";
  
  
  

Mime
View raw message