KickJava   Java API By Example, From Geeks To Geeks.

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


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.Shape JavaDoc;
21 import java.awt.geom.AffineTransform JavaDoc;
22 import java.awt.geom.NoninvertibleTransformException JavaDoc;
23 import java.awt.geom.Rectangle2D JavaDoc;
24 import java.awt.image.RenderedImage JavaDoc;
25 import java.awt.image.renderable.RenderContext JavaDoc;
26 import java.util.Iterator JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Vector JavaDoc;
29
30 import org.apache.batik.ext.awt.image.CompositeRule;
31 import org.apache.batik.ext.awt.image.PadMode;
32 import org.apache.batik.ext.awt.image.renderable.AbstractRable;
33 import org.apache.batik.ext.awt.image.renderable.AffineRable8Bit;
34 import org.apache.batik.ext.awt.image.renderable.CompositeRable8Bit;
35 import org.apache.batik.ext.awt.image.renderable.Filter;
36 import org.apache.batik.ext.awt.image.renderable.PadRable8Bit;
37 import org.apache.batik.gvt.CompositeGraphicsNode;
38 import org.apache.batik.gvt.GraphicsNode;
39
40 /**
41 * This implementation of RenderableImage will render its input
42  * GraphicsNode into a BufferedImage upon invokation of one of its
43  * createRendering methods.
44  *
45  * @author <a HREF="mailto:vincent.hardy@eng.sun.com">Vincent Hardy</a>
46  * @version $Id: BackgroundRable8Bit.java,v 1.16 2004/08/18 07:14:32 vhardy Exp $
47  */

48 public class BackgroundRable8Bit
49     extends AbstractRable {
50
51     /**
52      * GraphicsNode this image can render
53      */

54     private GraphicsNode node;
55
56     /**
57      * Returns the <tt>GraphicsNode</tt> rendered by this image
58      */

59     public GraphicsNode getGraphicsNode(){
60         return node;
61     }
62
63     /**
64      * Sets the <tt>GraphicsNode</tt> this image should render
65      */

66     public void setGraphicsNode(GraphicsNode node){
67         if(node == null){
68             throw new IllegalArgumentException JavaDoc();
69         }
70
71         this.node = node;
72     }
73
74     /**
75      * @param node The GraphicsNode this image should represent
76      */

77     public BackgroundRable8Bit(GraphicsNode node){
78         if(node == null)
79             throw new IllegalArgumentException JavaDoc();
80
81         this.node = node;
82     }
83
84
85     // This is a utilitiy method that unions the bounds of
86
// cgn upto child (if child is null it does all children).
87
// It unions them with init if provided.
88
static Rectangle2D JavaDoc addBounds(CompositeGraphicsNode cgn,
89                                  GraphicsNode child,
90                                  Rectangle2D JavaDoc init) {
91         // System.out.println("CGN: " + cgn);
92
// System.out.println("Child: " + child);
93

94         List JavaDoc children = cgn.getChildren();
95         Iterator JavaDoc i = children.iterator();
96         Rectangle2D JavaDoc r2d = null;
97         while (i.hasNext()) {
98             GraphicsNode gn = (GraphicsNode)i.next();
99             if (gn == child)
100                 break;
101
102             // System.out.println("GN: " + gn);
103
Rectangle2D JavaDoc cr2d = gn.getBounds();
104             AffineTransform JavaDoc at = gn.getTransform();
105             if (at != null)
106                 cr2d = at.createTransformedShape(cr2d).getBounds2D();
107
108             if (r2d == null) r2d = (Rectangle2D JavaDoc)cr2d.clone();
109             else r2d.add(cr2d);
110         }
111
112         if (r2d == null) {
113             if (init == null)
114                 return CompositeGraphicsNode.VIEWPORT;
115
116             return init;
117         }
118
119         if (init == null)
120             return r2d;
121
122         init.add(r2d);
123
124         return init;
125     }
126
127
128     static Rectangle2D JavaDoc getViewportBounds(GraphicsNode gn,
129                                          GraphicsNode child) {
130         // See if background is enabled.
131
Rectangle2D JavaDoc r2d = null;
132         if (gn instanceof CompositeGraphicsNode) {
133             CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn;
134             r2d = cgn.getBackgroundEnable();
135         }
136
137         if (r2d == null)
138             // No background enable so check our parent's value.
139
r2d = getViewportBounds(gn.getParent(), gn);
140
141         // No background for any ancester (error) return null
142
if (r2d == null)
143             return null;
144
145         // Background enabled is set, but it has no fixed bounds set.
146
if (r2d == CompositeGraphicsNode.VIEWPORT) {
147             // If we don't have a child then just use our bounds.
148
if (child == null)
149                 return (Rectangle2D JavaDoc)gn.getPrimitiveBounds().clone();
150
151             // gn must be composite so add all it's children's bounds
152
// up to child.
153
CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn;
154             return addBounds(cgn, child, null);
155         }
156
157         // We have a partial bound from parent, so map it to gn's
158
// coordinate system...
159
AffineTransform JavaDoc at = gn.getTransform();
160         if (at != null) {
161             try {
162                 at = at.createInverse();
163                 r2d = at.createTransformedShape(r2d).getBounds2D();
164             } catch (NoninvertibleTransformException JavaDoc nte) {
165                 // Degenerate case return null;
166
r2d = null;
167             }
168         }
169
170         if (child != null) {
171             // Add our childrens bounds to it...
172
CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn;
173             r2d = addBounds(cgn, child, r2d);
174         } else {
175             Rectangle2D JavaDoc gnb = gn.getPrimitiveBounds();
176             if (gnb != null)
177                 r2d.add(gnb);
178         }
179
180         return r2d;
181     }
182
183     // This does the leg work for getBounds().
184
// It traverses the tree figuring out the bounds of the
185
// background image.
186
static Rectangle2D JavaDoc getBoundsRecursive(GraphicsNode gn,
187                                           GraphicsNode child) {
188
189         Rectangle2D JavaDoc r2d = null;
190         if (gn == null) {
191             // System.out.println("Null GN Parent: " + child );
192
return null;
193         }
194
195         if (gn instanceof CompositeGraphicsNode) {
196             CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn;
197             // See if background is enabled.
198
r2d = cgn.getBackgroundEnable();
199         }
200
201         // background has definite bounds so return them.
202
if (r2d != null)
203             return r2d;
204
205         // No background enable so check our parent's value.
206
r2d = getBoundsRecursive(gn.getParent(), gn);
207
208         // No background for any ancester (error) return empty Rect...
209
if (r2d == null) {
210             // System.out.println("Null GetBoundsRec:" + gn + "\n\t" + child);
211
return new Rectangle2D.Float JavaDoc(0, 0, 0, 0);
212         }
213
214         // Our parent has background but no bounds (and we must
215
// have been the first child so build the new bounds...
216
if (r2d == CompositeGraphicsNode.VIEWPORT)
217             return r2d;
218
219         AffineTransform JavaDoc at = gn.getTransform();
220         if (at != null) {
221             try {
222                 // background has a definite bound so map it to gn's
223
// coordinate system...
224
at = at.createInverse();
225                 r2d = at.createTransformedShape(r2d).getBounds2D();
226             } catch (NoninvertibleTransformException JavaDoc nte) {
227                 // Degenerate case return null;
228
r2d = null;
229             }
230         }
231
232         return r2d;
233     }
234
235     /**
236      * Returns the bounds of this Rable in the user coordinate system.
237      */

238     public Rectangle2D JavaDoc getBounds2D() {
239         // System.out.println("GetBounds2D called");
240
Rectangle2D JavaDoc r2d = getBoundsRecursive(node, null);
241
242         // System.out.println("BoundsRec: " + r2d);
243

244         if (r2d == CompositeGraphicsNode.VIEWPORT) {
245             r2d = getViewportBounds(node, null);
246             // System.out.println("BoundsViewport: " + r2d);
247
}
248
249         return r2d;
250     }
251
252     /**
253      * Returns a filter that represents the background image
254      * for <tt>child</tt>.
255      * @param gn Node to get background image for.
256      * @param child Child to stop at when compositing children of gn into
257      * the background image.
258      * @param aoi The area of interest for rendering (used to cull
259      * nodes that don't intersect the region to render).
260      */

261     public Filter getBackground(GraphicsNode gn,
262                                 GraphicsNode child,
263                                 Rectangle2D JavaDoc aoi) {
264         if (gn == null) {
265             throw new IllegalArgumentException JavaDoc
266                 ("BackgroundImage requested yet no parent has " +
267                  "'enable-background:new'");
268         }
269
270         Rectangle2D JavaDoc r2d = null;
271         if (gn instanceof CompositeGraphicsNode) {
272             CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn;
273             r2d = cgn.getBackgroundEnable();
274         }
275
276         Vector JavaDoc srcs = new Vector JavaDoc();
277         if (r2d == null) {
278             Rectangle2D JavaDoc paoi = aoi;
279             AffineTransform JavaDoc at = gn.getTransform();
280             if (at != null)
281                 paoi = at.createTransformedShape(aoi).getBounds2D();
282             Filter f = getBackground(gn.getParent(), gn, paoi);
283
284             // Don't add the nodes unless they will contribute.
285
if ((f != null) && f.getBounds2D().intersects(aoi)) {
286                 srcs.add(f);
287             }
288         }
289
290         if (child != null) {
291             CompositeGraphicsNode cgn = (CompositeGraphicsNode)gn;
292             List JavaDoc children = cgn.getChildren();
293             Iterator JavaDoc i = children.iterator();
294             while (i.hasNext()) {
295                 GraphicsNode childGN = (GraphicsNode)i.next();
296                 // System.out.println("Parent: " + cgn +
297
// "\n Child: " + child +
298
// "\n ChildGN: " + childGN);
299
if (childGN == child)
300                     break;
301
302                 Rectangle2D JavaDoc cbounds = childGN.getBounds();
303                 // System.out.println("Child : " + childGN);
304
// System.out.println("Bounds: " + cbounds);
305
// System.out.println(" : " + aoi);
306

307                 AffineTransform JavaDoc at = childGN.getTransform();
308                 if (at != null)
309                     cbounds = at.createTransformedShape(cbounds).getBounds2D();
310
311
312                 if (aoi.intersects(cbounds)) {
313                     srcs.add(childGN.getEnableBackgroundGraphicsNodeRable
314                              (true));
315                 }
316             }
317         }
318
319         if (srcs.size() == 0)
320             return null;
321
322         Filter ret = null;
323         if (srcs.size() == 1)
324             ret = (Filter)srcs.get(0);
325         else
326             ret = new CompositeRable8Bit(srcs, CompositeRule.OVER, false);
327
328         if (child != null) {
329             // We are returning the filter to child so make
330
// sure to map the filter from the parents user space
331
// to the childs user space...
332

333             AffineTransform JavaDoc at = child.getTransform();
334             if (at != null) {
335                 try {
336                     at = at.createInverse();
337                     ret = new AffineRable8Bit(ret, at);
338                 } catch (NoninvertibleTransformException JavaDoc nte) {
339                     ret = null;
340                 }
341             }
342         }
343
344         return ret;
345     }
346
347     /**
348      * Returns true if successive renderings (that is, calls to
349      * createRendering() or createScaledRendering()) with the same arguments
350      * may produce different results. This method may be used to
351      * determine whether an existing rendering may be cached and
352      * reused. It is always safe to return true.
353      */

354     public boolean isDynamic(){
355         return false;
356     }
357
358     /**
359      * Creates a RenderedImage that represented a rendering of this image
360      * using a given RenderContext. This is the most general way to obtain a
361      * rendering of a RenderableImage.
362      *
363      * <p> The created RenderedImage may have a property identified
364      * by the String HINTS_OBSERVED to indicate which RenderingHints
365      * (from the RenderContext) were used to create the image.
366      * In addition any RenderedImages
367      * that are obtained via the getSources() method on the created
368      * RenderedImage may have such a property.
369      *
370      * @param renderContext the RenderContext to use to produce the rendering.
371      * @return a RenderedImage containing the rendered data.
372      */

373     public RenderedImage JavaDoc createRendering(RenderContext JavaDoc renderContext){
374
375         Rectangle2D JavaDoc r2d = getBounds2D();
376
377         // System.out.println("Rendering called");
378

379         Shape JavaDoc aoi = renderContext.getAreaOfInterest();
380         if (aoi != null) {
381             Rectangle2D JavaDoc aoiR2d = aoi.getBounds2D();
382             // System.out.println("R2d: " + r2d);
383
// System.out.println("AOI: " + aoiR2d);
384

385             if (r2d.intersects(aoiR2d) == false)
386                 return null;
387
388             Rectangle2D.intersect(r2d, aoiR2d, r2d);
389         }
390
391         Filter background = getBackground(node, null, r2d);
392         // System.out.println("BG: " + background);
393
if ( background == null)
394             return null;
395         
396         background = new PadRable8Bit(background, r2d, PadMode.ZERO_PAD);
397
398         
399         RenderedImage JavaDoc ri = background.createRendering
400             (new RenderContext JavaDoc(renderContext.getTransform(), r2d,
401                                renderContext.getRenderingHints()));
402         // System.out.println("RI: [" + ri.getMinX() + ", "
403
// + ri.getMinY() + ", " +
404
// + ri.getWidth() + ", " +
405
// + ri.getHeight() + "]");
406
// org.ImageDisplay.showImage("BG: ", ri);
407
return ri;
408     }
409 }
410
Popular Tags