KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > gvt > filter > GraphicsNodeRable8Bit


1 /*
2
3    Copyright 2001-2003 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.gvt.filter;
19
20 import java.awt.Composite JavaDoc;
21 import java.awt.Graphics2D JavaDoc;
22 import java.awt.color.ColorSpace JavaDoc;
23 import java.awt.geom.AffineTransform JavaDoc;
24 import java.awt.geom.Rectangle2D JavaDoc;
25 import java.awt.image.RenderedImage JavaDoc;
26 import java.awt.image.renderable.RenderContext JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import org.apache.batik.ext.awt.image.GraphicsUtil;
30 import org.apache.batik.ext.awt.image.SVGComposite;
31 import org.apache.batik.ext.awt.image.renderable.AbstractRable;
32 import org.apache.batik.ext.awt.image.renderable.Filter;
33 import org.apache.batik.ext.awt.image.renderable.PaintRable;
34 import org.apache.batik.ext.awt.image.rendered.CachableRed;
35 import org.apache.batik.ext.awt.image.rendered.TranslateRed;
36 import org.apache.batik.gvt.GraphicsNode;
37
38 /**
39  * This implementation of RenderableImage will render its input
40  * GraphicsNode into a BufferedImage upon invokation of one of its
41  * createRendering methods.
42  *
43  * @author <a HREF="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
44  * @version $Id: GraphicsNodeRable8Bit.java,v 1.20 2004/08/18 07:14:33 vhardy Exp $
45  */

46 public class GraphicsNodeRable8Bit
47     extends AbstractRable
48     implements GraphicsNodeRable, PaintRable {
49
50     private AffineTransform JavaDoc cachedGn2dev = null;
51     private AffineTransform JavaDoc cachedUsr2dev = null;
52     private CachableRed cachedRed = null;
53     private Rectangle2D JavaDoc cachedBounds = null;
54     /**
55      * Should GraphicsNodeRable call primitivePaint or Paint.
56      */

57     private boolean usePrimitivePaint = true;
58
59     /**
60      * Returns true if this Rable get's it's contents by calling
61      * primitivePaint on the associated <tt>GraphicsNode</tt> or
62      * false if it uses paint.
63      */

64     public boolean getUsePrimitivePaint() {
65         return usePrimitivePaint;
66     }
67
68     /**
69      * Set to true if this Rable should get it's contents by calling
70      * primitivePaint on the associated <tt>GraphicsNode</tt> or false
71      * if it should use paint.
72      */

73     public void setUsePrimitivePaint(boolean usePrimitivePaint) {
74         this.usePrimitivePaint = usePrimitivePaint;
75     }
76
77     /**
78      * GraphicsNode this image can render
79      */

80     private GraphicsNode node;
81
82     /**
83      * Returns the <tt>GraphicsNode</tt> rendered by this image
84      */

85     public GraphicsNode getGraphicsNode(){
86         return node;
87     }
88
89     /**
90      * Sets the <tt>GraphicsNode</tt> this image should render
91      */

92     public void setGraphicsNode(GraphicsNode node){
93         if(node == null){
94             throw new IllegalArgumentException JavaDoc();
95         }
96
97         this.node = node;
98     }
99
100     /**
101      * Clear any cached Red.
102      */

103     public void clearCache() {
104         cachedRed = null;
105         cachedUsr2dev = null;
106         cachedGn2dev = null;
107         cachedBounds = null;
108     }
109
110     /**
111      * @param node The GraphicsNode this image should represent
112      */

113     public GraphicsNodeRable8Bit(GraphicsNode node){
114         if(node == null)
115             throw new IllegalArgumentException JavaDoc();
116
117         this.node = node;
118         this.usePrimitivePaint = true;
119     }
120
121     /**
122      * @param node The GraphicsNode this image should represent
123      * @param props The Properties for this image.
124      */

125     public GraphicsNodeRable8Bit(GraphicsNode node,
126                                  Map JavaDoc props){
127         super((Filter)null, props);
128
129         if(node == null)
130             throw new IllegalArgumentException JavaDoc();
131
132         this.node = node;
133         this.usePrimitivePaint = true;
134     }
135
136     /**
137      * @param node the GraphicsNode this image should represent
138      * @param usePrimitivePaint indicates if the image should
139      * include any filters or mask operations on <tt>node</tt>
140      */

141     public GraphicsNodeRable8Bit(GraphicsNode node,
142                                  boolean usePrimitivePaint){
143         if(node == null)
144             throw new IllegalArgumentException JavaDoc();
145
146         this.node = node;
147         this.usePrimitivePaint = usePrimitivePaint;
148     }
149
150     /**
151      * Returns the bounds of this Rable in the user coordinate system.
152      */

153     public Rectangle2D JavaDoc getBounds2D(){
154         if (usePrimitivePaint){
155             Rectangle2D JavaDoc primitiveBounds = node.getPrimitiveBounds();
156             if(primitiveBounds == null)
157                 return new Rectangle2D.Double JavaDoc(0, 0, 0, 0);
158
159             return (Rectangle2D JavaDoc)(primitiveBounds.clone());
160         }
161
162         // When not using Primitive paint we return out bounds in our
163
// parent's user space. This makes sense since this is the
164
// space that we will draw our selves into (since paint unlike
165
// primitivePaint incorporates the transform from our user
166
// space to our parents user space).
167
Rectangle2D JavaDoc bounds = node.getBounds();
168         if(bounds == null){
169             return new Rectangle2D.Double JavaDoc(0, 0, 0, 0);
170         }
171
172         AffineTransform JavaDoc at = node.getTransform();
173         if (at != null){
174            bounds = at.createTransformedShape(bounds).getBounds2D();
175         }
176         return bounds;
177     }
178
179     /**
180      * Returns true if successive renderings (that is, calls to
181      * createRendering() or createScaledRendering()) with the same arguments
182      * may produce different results. This method may be used to
183      * determine whether an existing rendering may be cached and
184      * reused. It is always safe to return true.
185      */

186     public boolean isDynamic(){
187         return false;
188     }
189
190     /**
191      * Should perform the equivilent action as
192      * createRendering followed by drawing the RenderedImage to
193      * Graphics2D, or return false.
194      *
195      * @param g2d The Graphics2D to draw to.
196      * @return true if the paint call succeeded, false if
197      * for some reason the paint failed (in which
198      * case a createRendering should be used).
199      */

200     public boolean paintRable(Graphics2D JavaDoc g2d) {
201         // This optimization only apply if we are using
202
// SrcOver. Otherwise things break...
203
Composite JavaDoc c = g2d.getComposite();
204         if (!SVGComposite.OVER.equals(c))
205             return false;
206         
207         ColorSpace JavaDoc g2dCS = GraphicsUtil.getDestinationColorSpace(g2d);
208         if ((g2dCS == null) ||
209             (g2dCS != ColorSpace.getInstance(ColorSpace.CS_sRGB))){
210             // Only draw directly into sRGB destinations...
211
return false;
212         }
213
214         // System.out.println("drawImage GNR: " + g2dCS);
215
GraphicsNode gn = getGraphicsNode();
216         if (getUsePrimitivePaint()){
217             gn.primitivePaint(g2d);
218         }
219         else{
220             gn.paint(g2d);
221         }
222
223         // Paint did the work...
224
return true;
225     }
226
227     /**
228      * Creates a RenderedImage that represented a rendering of this image
229      * using a given RenderContext. This is the most general way to obtain a
230      * rendering of a RenderableImage.
231      *
232      * <p> The created RenderedImage may have a property identified
233      * by the String HINTS_OBSERVED to indicate which RenderingHints
234      * (from the RenderContext) were used to create the image.
235      * In addition any RenderedImages
236      * that are obtained via the getSources() method on the created
237      * RenderedImage may have such a property.
238      *
239      * @param renderContext the RenderContext to use to produce the rendering.
240      * @return a RenderedImage containing the rendered data.
241      */

242     public RenderedImage JavaDoc createRendering(RenderContext JavaDoc renderContext){
243         // Get user space to device space transform
244
AffineTransform JavaDoc usr2dev = renderContext.getTransform();
245
246         AffineTransform JavaDoc gn2dev;
247         if (usr2dev == null) {
248             usr2dev = new AffineTransform JavaDoc();
249             gn2dev = usr2dev;
250         } else {
251             gn2dev = (AffineTransform JavaDoc)usr2dev.clone();
252         }
253
254         // Get the nodes transform (so we can pick up changes in this.
255
AffineTransform JavaDoc gn2usr = node.getTransform();
256         if (gn2usr != null) {
257             gn2dev.concatenate(gn2usr);
258         }
259
260         Rectangle2D JavaDoc bounds2D = getBounds2D();
261
262         if ((cachedBounds != null) &&
263             (cachedGn2dev != null) &&
264             (cachedBounds.equals(bounds2D)) &&
265             (gn2dev.getScaleX() == cachedGn2dev.getScaleX()) &&
266             (gn2dev.getScaleY() == cachedGn2dev.getScaleY()) &&
267             (gn2dev.getShearX() == cachedGn2dev.getShearX()) &&
268             (gn2dev.getShearY() == cachedGn2dev.getShearY()))
269         {
270             // Just some form of Translation
271
double deltaX = (usr2dev.getTranslateX() -
272                              cachedUsr2dev.getTranslateX());
273             double deltaY = (usr2dev.getTranslateY() -
274                              cachedUsr2dev.getTranslateY());
275
276             // System.out.println("Using Cached Red!!! " +
277
// deltaX + "x" + deltaY);
278
if ((deltaX ==0) && (deltaY == 0))
279                 // Actually no translation
280
return cachedRed;
281
282             // System.out.println("Delta: [" + deltaX + ", " + deltaY + "]");
283

284             // Integer translation in device space..
285
if ((deltaX == (int)deltaX) &&
286                 (deltaY == (int)deltaY)) {
287                 return new TranslateRed
288                     (cachedRed,
289                      (int)Math.round(cachedRed.getMinX()+deltaX),
290                      (int)Math.round(cachedRed.getMinY()+deltaY));
291             }
292         }
293
294         // Fell through let's do a new rendering...
295
if (false) {
296             System.out.println("Not using Cached Red: " + usr2dev);
297             System.out.println("Old: " + cachedUsr2dev);
298         }
299
300         if((bounds2D.getWidth() > 0) &&
301            (bounds2D.getHeight() > 0)) {
302             cachedUsr2dev = (AffineTransform JavaDoc)usr2dev.clone();
303             cachedGn2dev = gn2dev;
304             cachedBounds = bounds2D;
305             cachedRed = new GraphicsNodeRed8Bit
306                 (node, usr2dev, usePrimitivePaint,
307                  renderContext.getRenderingHints());
308             return cachedRed;
309         }
310
311         cachedUsr2dev = null;
312         cachedGn2dev = null;
313         cachedBounds = null;
314         cachedRed = null;
315         return null;
316     }
317 }
318
Popular Tags