/*****************************************************************************
* 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.ext.awt.image.renderable.Filter;
import org.apache.batik.gvt.CompositeGraphicsNode;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.GraphicsNodeRenderContext;
import org.apache.batik.gvt.filter.GraphicsNodeRable8Bit;
import org.apache.batik.gvt.filter.Mask;
import org.apache.batik.gvt.filter.MaskRable8Bit;
import org.apache.batik.util.SVGConstants;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Bridge class for the <mask> element.
*
* @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
* @version $Id: SVGMaskElementBridge.java,v 1.8 2001/03/08 12:39:28 tkormann Exp $
*/
public class SVGMaskElementBridge implements MaskBridge, SVGConstants {
/**
* Creates a <tt>Mask</tt> according to the specified parameters.
*
* @param ctx the bridge context to use
* @param maskElement the element that defines the mask
* @param maskedElement the element that references the mask element
* @param maskedNode the graphics node to mask
*/
public Mask createMask(BridgeContext ctx,
Element maskElement,
Element maskedElement,
GraphicsNode maskedNode) {
String s;
// get mask region using 'maskUnits'
Rectangle2D maskRegion = SVGUtilities.convertMaskRegion
(maskElement, maskedElement, maskedNode, ctx);
//
// Build the GVT tree that represents the mask
//
GVTBuilder builder = ctx.getGVTBuilder();
CompositeGraphicsNode maskNode = new CompositeGraphicsNode();
CompositeGraphicsNode maskNodeContent = new CompositeGraphicsNode();
maskNode.getChildren().add(maskNodeContent);
boolean hasChildren = false;
for(Node node = maskElement.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 gn = builder.build(ctx, child) ;
if(gn == null) {
continue;
}
hasChildren = true;
maskNodeContent.getChildren().add(gn);
}
if (!hasChildren) {
return null; // empty mask
}
// 'transform' attribute
AffineTransform Tx;
s = maskElement.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
if (s.length() != 0) {
Tx = SVGUtilities.convertTransform
(maskElement, SVG_TRANSFORM_ATTRIBUTE, s);
} else {
Tx = new AffineTransform();
}
// 'maskContentUnits' attribute - default is userSpaceOnUse
short coordSystemType;
s = maskElement.getAttributeNS(null, SVG_MASK_CONTENT_UNITS_ATTRIBUTE);
if (s.length() == 0) {
coordSystemType = SVGUtilities.USER_SPACE_ON_USE;
} else {
coordSystemType = SVGUtilities.parseCoordinateSystem
(maskElement, SVG_MASK_CONTENT_UNITS_ATTRIBUTE, s);
}
// additional transform to move to objectBoundingBox coordinate system
GraphicsNodeRenderContext rc = ctx.getGraphicsNodeRenderContext();
if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX) {
Tx = SVGUtilities.toObjectBBox(Tx, maskedNode, rc);
}
maskNodeContent.setTransform(Tx);
Filter filter = maskedNode.getFilter();
if (filter == null) {
// Make the initial source as a RenderableImage
filter = new GraphicsNodeRable8Bit(maskedNode, rc);
}
return new MaskRable8Bit(filter, maskNode, maskRegion);
}
/**
* Performs an update according to the specified event.
*
* @param evt the event describing the update to perform
*/
public void update(BridgeMutationEvent evt) {
throw new Error("Not implemented");
}
}