KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > bridge > SVGClipPathElementBridge


1 /*
2
3    Copyright 2001-2004 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.bridge;
19
20 import java.awt.RenderingHints JavaDoc;
21 import java.awt.Shape JavaDoc;
22 import java.awt.geom.AffineTransform JavaDoc;
23 import java.awt.geom.Area JavaDoc;
24 import java.awt.geom.GeneralPath JavaDoc;
25
26 import org.apache.batik.css.engine.CSSImportNode;
27 import org.apache.batik.dom.svg.SVGOMCSSImportedElementRoot;
28 import org.apache.batik.ext.awt.image.renderable.ClipRable;
29 import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit;
30 import org.apache.batik.ext.awt.image.renderable.Filter;
31 import org.apache.batik.gvt.GraphicsNode;
32 import org.apache.batik.gvt.ShapeNode;
33 import org.w3c.dom.Element JavaDoc;
34 import org.w3c.dom.Node JavaDoc;
35
36 /**
37  * Bridge class for the <clipPath> element.
38  *
39  * @author <a HREF="mailto:tkormann@apache.org">Thierry Kormann</a>
40  * @version $Id: SVGClipPathElementBridge.java,v 1.23 2004/11/18 01:46:53 deweese Exp $
41  */

42 public class SVGClipPathElementBridge extends AbstractSVGBridge
43     implements ClipBridge {
44
45     /**
46      * Constructs a new bridge for the &lt;clipPath> element.
47      */

48     public SVGClipPathElementBridge() {}
49
50     /**
51      * Returns 'clipPath'.
52      */

53     public String JavaDoc getLocalName() {
54         return SVG_CLIP_PATH_TAG;
55     }
56
57     /**
58      * Creates a <tt>Clip</tt> according to the specified parameters.
59      *
60      * @param ctx the bridge context to use
61      * @param clipElement the element that defines the clip
62      * @param clipedElement the element that references the clip element
63      * @param clipedNode the graphics node to clip
64      */

65     public ClipRable createClip(BridgeContext ctx,
66                                 Element JavaDoc clipElement,
67                                 Element JavaDoc clipedElement,
68                                 GraphicsNode clipedNode) {
69
70         String JavaDoc s;
71
72         // 'transform' attribute
73
AffineTransform JavaDoc Tx;
74         s = clipElement.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
75         if (s.length() != 0) {
76             Tx = SVGUtilities.convertTransform
77                 (clipElement, SVG_TRANSFORM_ATTRIBUTE, s);
78         } else {
79             Tx = new AffineTransform JavaDoc();
80         }
81
82         // 'clipPathUnits' attribute - default is userSpaceOnUse
83
short coordSystemType;
84         s = clipElement.getAttributeNS(null, SVG_CLIP_PATH_UNITS_ATTRIBUTE);
85         if (s.length() == 0) {
86             coordSystemType = SVGUtilities.USER_SPACE_ON_USE;
87         } else {
88             coordSystemType = SVGUtilities.parseCoordinateSystem
89                 (clipElement, SVG_CLIP_PATH_UNITS_ATTRIBUTE, s);
90         }
91         // additional transform to move to objectBoundingBox coordinate system
92
if (coordSystemType == SVGUtilities.OBJECT_BOUNDING_BOX) {
93             Tx = SVGUtilities.toObjectBBox(Tx, clipedNode);
94         }
95
96         // Build the GVT tree that represents the clip path
97
//
98
// The silhouettes of the child elements are logically OR'd
99
// together to create a single silhouette which is then used to
100
// restrict the region onto which paint can be applied.
101
//
102
// The 'clipPath' element or any of its children can specify
103
// property 'clip-path'.
104
//
105
Area JavaDoc clipPath = new Area JavaDoc();
106         GVTBuilder builder = ctx.getGVTBuilder();
107         boolean hasChildren = false;
108         for(Node node = clipElement.getFirstChild();
109             node != null;
110             node = node.getNextSibling()) {
111
112             // check if the node is a valid Element
113
if (node.getNodeType() != Node.ELEMENT_NODE) {
114                 continue;
115             }
116
117             Element JavaDoc child = (Element JavaDoc)node;
118             GraphicsNode clipNode = builder.build(ctx, child) ;
119             // check if a GVT node has been created
120
if (clipNode == null) {
121                 continue;
122             }
123             hasChildren = true;
124
125             // if this is a 'use' element, get the actual shape used
126
if (child instanceof CSSImportNode) {
127                 SVGOMCSSImportedElementRoot shadow =
128                     (SVGOMCSSImportedElementRoot)
129                     ((CSSImportNode) child).getCSSImportedElementRoot();
130                 
131                 if (shadow != null) {
132                     Node shadowChild = shadow.getFirstChild();
133                     if (shadowChild != null
134                             && shadowChild.getNodeType() == Node.ELEMENT_NODE) {
135                         child = (Element JavaDoc) shadowChild;
136                     }
137                 }
138             }
139
140             // compute the outline of the current clipPath's child
141
int wr = CSSUtilities.convertClipRule(child);
142             GeneralPath JavaDoc path = new GeneralPath JavaDoc(clipNode.getOutline());
143             path.setWindingRule(wr);
144
145             AffineTransform JavaDoc at = clipNode.getTransform();
146             if (at == null) at = Tx;
147             else at.preConcatenate(Tx);
148
149             Shape JavaDoc outline = at.createTransformedShape(path);
150
151             // apply the 'clip-path' of the current clipPath's child
152
ShapeNode outlineNode = new ShapeNode();
153             outlineNode.setShape(outline);
154             ClipRable clip = CSSUtilities.convertClipPath(child,
155                                                           outlineNode,
156                                                           ctx);
157             if (clip != null) {
158                 Area JavaDoc area = new Area JavaDoc(outline);
159                 area.subtract(new Area JavaDoc(clip.getClipPath()));
160                 outline = area;
161             }
162             clipPath.add(new Area JavaDoc(outline));
163         }
164         if (!hasChildren) {
165             return null; // empty clipPath
166
}
167
168         // construct the shape node that represents the clipPath
169
ShapeNode clipPathNode = new ShapeNode();
170         clipPathNode.setShape(clipPath);
171
172         // apply the 'clip-path' of the clipPath element (already in user space)
173
ClipRable clipElementClipPath =
174             CSSUtilities.convertClipPath(clipElement, clipPathNode, ctx);
175         if (clipElementClipPath != null) {
176             clipPath.subtract(new Area JavaDoc(clipElementClipPath.getClipPath()));
177         }
178
179         Filter filter = clipedNode.getFilter();
180         if (filter == null) {
181             // Make the initial source as a RenderableImage
182
filter = clipedNode.getGraphicsNodeRable(true);
183         }
184
185         boolean useAA = false;
186         RenderingHints JavaDoc hints;
187         hints = CSSUtilities.convertShapeRendering(clipElement, null);
188         if (hints != null) {
189             Object JavaDoc o = hints.get(RenderingHints.KEY_ANTIALIASING);
190             useAA = (o == RenderingHints.VALUE_ANTIALIAS_ON);
191         }
192             
193         return new ClipRable8Bit(filter, clipPath, useAA);
194     }
195 }
196
Popular Tags