Package org.apache.batik.bridge

Source Code of org.apache.batik.bridge.SVGClipPathElementBridge

/*

   Copyright 2001-2004  The Apache Software Foundation

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/
package org.apache.batik.bridge;

import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Area;
import java.awt.geom.GeneralPath;

import org.apache.batik.css.engine.CSSImportNode;
import org.apache.batik.dom.svg.SVGOMCSSImportedElementRoot;
import org.apache.batik.ext.awt.image.renderable.ClipRable;
import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit;
import org.apache.batik.ext.awt.image.renderable.Filter;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.ShapeNode;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
* Bridge class for the <clipPath> element.
*
* @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
* @version $Id: SVGClipPathElementBridge.java,v 1.23 2004/11/18 01:46:53 deweese Exp $
*/
public class SVGClipPathElementBridge extends AbstractSVGBridge
    implements ClipBridge {

    /**
     * Constructs a new bridge for the &lt;clipPath> element.
     */
    public SVGClipPathElementBridge() {}

    /**
     * Returns 'clipPath'.
     */
    public String getLocalName() {
        return SVG_CLIP_PATH_TAG;
    }

    /**
     * Creates a <tt>Clip</tt> according to the specified parameters.
     *
     * @param ctx the bridge context to use
     * @param clipElement the element that defines the clip
     * @param clipedElement the element that references the clip element
     * @param clipedNode the graphics node to clip
     */
    public ClipRable createClip(BridgeContext ctx,
                                Element clipElement,
                                Element clipedElement,
                                GraphicsNode clipedNode) {

        String s;

        // 'transform' attribute
        AffineTransform Tx;
        s = clipElement.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
        if (s.length() != 0) {
            Tx = SVGUtilities.convertTransform
                (clipElement, SVG_TRANSFORM_ATTRIBUTE, s);
        } else {
            Tx = new AffineTransform();
        }

        // 'clipPathUnits' attribute - default is userSpaceOnUse
        short coordSystemType;
        s = clipElement.getAttributeNS(null, SVG_CLIP_PATH_UNITS_ATTRIBUTE);
        if (s.length() == 0) {
            coordSystemType = SVGUtilities.USER_SPACE_ON_USE;
        } else {
            coordSystemType = SVGUtilities.parseCoordinateSystem
                (clipElement, SVG_CLIP_PATH_UNITS_ATTRIBUTE, s);
        }
        // additional transform to move to objectBoundingBox coordinate system
        if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX) {
            Tx = SVGUtilities.toObjectBBox(Tx, clipedNode);
        }

        // Build the GVT tree that represents the clip path
        //
        // The silhouettes of the child elements are logically OR'd
        // together to create a single silhouette which is then used to
        // restrict the region onto which paint can be applied.
        //
        // The 'clipPath' element or any of its children can specify
        // property 'clip-path'.
        //
        Area clipPath = new Area();
        GVTBuilder builder = ctx.getGVTBuilder();
        boolean hasChildren = false;
        for(Node node = clipElement.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 clipNode = builder.build(ctx, child) ;
            // check if a GVT node has been created
            if (clipNode == null) {
                continue;
            }
            hasChildren = true;

            // if this is a 'use' element, get the actual shape used
            if (child instanceof CSSImportNode) {
                SVGOMCSSImportedElementRoot shadow =
                    (SVGOMCSSImportedElementRoot)
                    ((CSSImportNode) child).getCSSImportedElementRoot();
               
                if (shadow != null) {
                    Node shadowChild = shadow.getFirstChild();
                    if (shadowChild != null
                            && shadowChild.getNodeType() == Node.ELEMENT_NODE) {
                        child = (Element) shadowChild;
                    }
                }
            }

            // compute the outline of the current clipPath's child
            int wr = CSSUtilities.convertClipRule(child);
            GeneralPath path = new GeneralPath(clipNode.getOutline());
            path.setWindingRule(wr);

            AffineTransform at = clipNode.getTransform();
            if (at == nullat = Tx;
            else             at.preConcatenate(Tx);

            Shape outline = at.createTransformedShape(path);

            // apply the 'clip-path' of the current clipPath's child
            ShapeNode outlineNode = new ShapeNode();
            outlineNode.setShape(outline);
            ClipRable clip = CSSUtilities.convertClipPath(child,
                                                          outlineNode,
                                                          ctx);
            if (clip != null) {
                Area area = new Area(outline);
                area.subtract(new Area(clip.getClipPath()));
                outline = area;
            }
            clipPath.add(new Area(outline));
        }
        if (!hasChildren) {
            return null; // empty clipPath
        }

        // construct the shape node that represents the clipPath
        ShapeNode clipPathNode = new ShapeNode();
        clipPathNode.setShape(clipPath);

        // apply the 'clip-path' of the clipPath element (already in user space)
        ClipRable clipElementClipPath =
            CSSUtilities.convertClipPath(clipElement, clipPathNode, ctx);
        if (clipElementClipPath != null) {
            clipPath.subtract(new Area(clipElementClipPath.getClipPath()));
        }

        Filter filter = clipedNode.getFilter();
        if (filter == null) {
            // Make the initial source as a RenderableImage
            filter = clipedNode.getGraphicsNodeRable(true);
        }

        boolean useAA = false;
        RenderingHints hints;
        hints = CSSUtilities.convertShapeRendering(clipElement, null);
        if (hints != null) {
            Object o = hints.get(RenderingHints.KEY_ANTIALIASING);
            useAA = (o == RenderingHints.VALUE_ANTIALIAS_ON);
        }
           
        return new ClipRable8Bit(filter, clipPath, useAA);
    }
}
TOP

Related Classes of org.apache.batik.bridge.SVGClipPathElementBridge

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.