KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > awt > image > renderable > RenderableImageOp


1 /*
2  * @(#)RenderableImageOp.java 1.16 04/05/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 /* ********************************************************************
9  **********************************************************************
10  **********************************************************************
11  *** COPYRIGHT (c) Eastman Kodak Company, 1997 ***
12  *** As an unpublished work pursuant to Title 17 of the United ***
13  *** States Code. All rights reserved. ***
14  **********************************************************************
15  **********************************************************************
16  **********************************************************************/

17
18 package java.awt.image.renderable;
19 import java.awt.geom.AffineTransform JavaDoc;
20 import java.awt.geom.Rectangle2D JavaDoc;
21 import java.awt.image.RenderedImage JavaDoc;
22 import java.awt.RenderingHints JavaDoc;
23 import java.util.Hashtable JavaDoc;
24 import java.util.Vector JavaDoc;
25
26 /**
27  * This class handles the renderable aspects of an operation with help
28  * from its associated instance of a ContextualRenderedImageFactory.
29  */

30 public class RenderableImageOp implements RenderableImage JavaDoc {
31
32     /** A ParameterBlock containing source and parameters. */
33     ParameterBlock JavaDoc paramBlock;
34
35     /** The associated ContextualRenderedImageFactory. */
36     ContextualRenderedImageFactory JavaDoc myCRIF;
37
38     /** The bounding box of the results of this RenderableImageOp. */
39     Rectangle2D JavaDoc boundingBox;
40
41
42     /**
43      * Constructs a RenderedImageOp given a
44      * ContextualRenderedImageFactory object, and
45      * a ParameterBlock containing RenderableImage sources and other
46      * parameters. Any RenderedImage sources referenced by the
47      * ParameterBlock will be ignored.
48      *
49      * @param CRIF a ContextualRenderedImageFactory object
50      * @param paramBlock a ParameterBlock containing this operation's source
51      * images and other parameters necessary for the operation
52      * to run.
53      */

54     public RenderableImageOp(ContextualRenderedImageFactory JavaDoc CRIF,
55                              ParameterBlock JavaDoc paramBlock) {
56         this.myCRIF = CRIF;
57         this.paramBlock = (ParameterBlock JavaDoc) paramBlock.clone();
58     }
59
60     /**
61      * Returns a vector of RenderableImages that are the sources of
62      * image data for this RenderableImage. Note that this method may
63      * return an empty vector, to indicate that the image has no sources,
64      * or null, to indicate that no information is available.
65      *
66      * @return a (possibly empty) Vector of RenderableImages, or null.
67      */

68     public Vector JavaDoc<RenderableImage JavaDoc> getSources() {
69         return getRenderableSources();
70     }
71
72     private Vector JavaDoc getRenderableSources() {
73         Vector JavaDoc sources = null;
74
75         if (paramBlock.getNumSources() > 0) {
76             sources = new Vector JavaDoc();
77             int i = 0;
78             while (i < paramBlock.getNumSources()) {
79                 Object JavaDoc o = paramBlock.getSource(i);
80                 if (o instanceof RenderableImage JavaDoc) {
81                     sources.add((RenderableImage JavaDoc)o);
82                     i++;
83                 } else {
84                     break;
85                 }
86             }
87         }
88         return sources;
89     }
90     
91     /**
92      * Gets a property from the property set of this image.
93      * If the property name is not recognized, java.awt.Image.UndefinedProperty
94      * will be returned.
95      *
96      * @param name the name of the property to get, as a String.
97      * @return a reference to the property Object, or the value
98      * java.awt.Image.UndefinedProperty.
99      */

100     public Object JavaDoc getProperty(String JavaDoc name) {
101         return myCRIF.getProperty(paramBlock, name);
102     }
103
104     /**
105      * Return a list of names recognized by getProperty.
106      * @return a list of property names.
107      */

108     public String JavaDoc[] getPropertyNames() {
109         return myCRIF.getPropertyNames();
110     }
111   
112     /**
113      * Returns true if successive renderings (that is, calls to
114      * createRendering() or createScaledRendering()) with the same arguments
115      * may produce different results. This method may be used to
116      * determine whether an existing rendering may be cached and
117      * reused. The CRIF's isDynamic method will be called.
118      * @return <code>true</code> if successive renderings with the
119      * same arguments might produce different results;
120      * <code>false</code> otherwise.
121      */

122     public boolean isDynamic() {
123         return myCRIF.isDynamic();
124     }
125
126     /**
127      * Gets the width in user coordinate space. By convention, the
128      * usual width of a RenderableImage is equal to the image's aspect
129      * ratio (width divided by height).
130      *
131      * @return the width of the image in user coordinates.
132      */

133     public float getWidth() {
134         if (boundingBox == null) {
135             boundingBox = myCRIF.getBounds2D(paramBlock);
136         }
137         return (float)boundingBox.getWidth();
138     }
139
140     /**
141      * Gets the height in user coordinate space. By convention, the
142      * usual height of a RenderedImage is equal to 1.0F.
143      *
144      * @return the height of the image in user coordinates.
145      */

146     public float getHeight() {
147         if (boundingBox == null) {
148             boundingBox = myCRIF.getBounds2D(paramBlock);
149         }
150         return (float)boundingBox.getHeight();
151     }
152   
153     /**
154      * Gets the minimum X coordinate of the rendering-independent image data.
155      */

156     public float getMinX() {
157         if (boundingBox == null) {
158             boundingBox = myCRIF.getBounds2D(paramBlock);
159         }
160         return (float)boundingBox.getMinX();
161     }
162
163     /**
164      * Gets the minimum Y coordinate of the rendering-independent image data.
165      */

166     public float getMinY() {
167         if (boundingBox == null) {
168             boundingBox = myCRIF.getBounds2D(paramBlock);
169         }
170         return (float)boundingBox.getMinY();
171     }
172
173     /**
174      * Change the current ParameterBlock of the operation, allowing
175      * editing of image rendering chains. The effects of such a
176      * change will be visible when a new rendering is created from
177      * this RenderableImageOp or any dependent RenderableImageOp.
178      *
179      * @param paramBlock the new ParameterBlock.
180      * @return the old ParameterBlock.
181      * @see #getParameterBlock
182      */

183     public ParameterBlock JavaDoc setParameterBlock(ParameterBlock JavaDoc paramBlock) {
184         ParameterBlock JavaDoc oldParamBlock = this.paramBlock;
185         this.paramBlock = (ParameterBlock JavaDoc)paramBlock.clone();
186         return oldParamBlock;
187     }
188
189     /**
190      * Returns a reference to the current parameter block.
191      * @return the <code>ParameterBlock</code> of this
192      * <code>RenderableImageOp</code>.
193      * @see #setParameterBlock(ParameterBlock)
194      */

195     public ParameterBlock JavaDoc getParameterBlock() {
196         return paramBlock;
197     }
198
199     /**
200      * Creates a RenderedImage instance of this image with width w, and
201      * height h in pixels. The RenderContext is built automatically
202      * with an appropriate usr2dev transform and an area of interest
203      * of the full image. All the rendering hints come from hints
204      * passed in.
205      *
206      * <p> If w == 0, it will be taken to equal
207      * Math.round(h*(getWidth()/getHeight())).
208      * Similarly, if h == 0, it will be taken to equal
209      * Math.round(w*(getHeight()/getWidth())). One of
210      * w or h must be non-zero or else an IllegalArgumentException
211      * will be thrown.
212      *
213      * <p> The created RenderedImage may have a property identified
214      * by the String HINTS_OBSERVED to indicate which RenderingHints
215      * were used to create the image. In addition any RenderedImages
216      * that are obtained via the getSources() method on the created
217      * RenderedImage may have such a property.
218      *
219      * @param w the width of rendered image in pixels, or 0.
220      * @param h the height of rendered image in pixels, or 0.
221      * @param hints a RenderingHints object containg hints.
222      * @return a RenderedImage containing the rendered data.
223      */

224     public RenderedImage JavaDoc createScaledRendering(int w, int h,
225                                                RenderingHints JavaDoc hints) {
226         // DSR -- code to try to get a unit scale
227
double sx = (double)w/getWidth();
228         double sy = (double)h/getHeight();
229         if (Math.abs(sx/sy - 1.0) < 0.01) {
230             sx = sy;
231         }
232         AffineTransform JavaDoc usr2dev = AffineTransform.getScaleInstance(sx, sy);
233         RenderContext JavaDoc newRC = new RenderContext JavaDoc(usr2dev, hints);
234         return createRendering(newRC);
235     }
236
237     /**
238      * Gets a RenderedImage instance of this image with a default
239      * width and height in pixels. The RenderContext is built
240      * automatically with an appropriate usr2dev transform and an area
241      * of interest of the full image. All the rendering hints come
242      * from hints passed in. Implementors of this interface must be
243      * sure that there is a defined default width and height.
244      *
245      * @return a RenderedImage containing the rendered data.
246      */

247     public RenderedImage JavaDoc createDefaultRendering() {
248         AffineTransform JavaDoc usr2dev = new AffineTransform JavaDoc(); // Identity
249
RenderContext JavaDoc newRC = new RenderContext JavaDoc(usr2dev);
250         return createRendering(newRC);
251     }
252     
253     /**
254      * Creates a RenderedImage which represents this
255      * RenderableImageOp (including its Renderable sources) rendered
256      * according to the given RenderContext.
257      *
258      * <p> This method supports chaining of either Renderable or
259      * RenderedImage operations. If sources in
260      * the ParameterBlock used to construct the RenderableImageOp are
261      * RenderableImages, then a three step process is followed:
262      *
263      * <ol>
264      * <li> mapRenderContext() is called on the associated CRIF for
265      * each RenderableImage source;
266      * <li> createRendering() is called on each of the RenderableImage sources
267      * using the backwards-mapped RenderContexts obtained in step 1,
268      * resulting in a rendering of each source;
269      * <li> ContextualRenderedImageFactory.create() is called
270      * with a new ParameterBlock containing the parameters of
271      * the RenderableImageOp and the RenderedImages that were created by the
272      * createRendering() calls.
273      * </ol>
274      *
275      * <p> If the elements of the source Vector of
276      * the ParameterBlock used to construct the RenderableImageOp are
277      * instances of RenderedImage, then the CRIF.create() method is
278      * called immediately using the original ParameterBlock.
279      * This provides a basis case for the recursion.
280      *
281      * <p> The created RenderedImage may have a property identified
282      * by the String HINTS_OBSERVED to indicate which RenderingHints
283      * (from the RenderContext) were used to create the image.
284      * In addition any RenderedImages
285      * that are obtained via the getSources() method on the created
286      * RenderedImage may have such a property.
287      *
288      * @param renderContext The RenderContext to use to perform the rendering.
289      * @return a RenderedImage containing the desired output image.
290      */

291     public RenderedImage JavaDoc createRendering(RenderContext JavaDoc renderContext) {
292         RenderedImage JavaDoc image = null;
293         RenderContext JavaDoc rcOut = null;
294
295         // Clone the original ParameterBlock; if the ParameterBlock
296
// contains RenderableImage sources, they will be replaced by
297
// RenderedImages.
298
ParameterBlock JavaDoc renderedParamBlock = (ParameterBlock JavaDoc)paramBlock.clone();
299         Vector JavaDoc sources = getRenderableSources();
300
301         try {
302             // This assumes that if there is no renderable source, that there
303
// is a rendered source in paramBlock
304

305             if (sources != null) {
306                 Vector JavaDoc renderedSources = new Vector JavaDoc();
307                 for (int i = 0; i < sources.size(); i++) {
308                     rcOut = myCRIF.mapRenderContext(i, renderContext,
309                                                     paramBlock, this);
310                     RenderedImage JavaDoc rdrdImage =
311                        ((RenderableImage JavaDoc)sources.elementAt(i)).createRendering(rcOut);
312                     if (rdrdImage == null) {
313                         return null;
314                     }
315                     
316                     // Add this rendered image to the ParameterBlock's
317
// list of RenderedImages.
318
renderedSources.addElement(rdrdImage);
319                 }
320                 
321                 if (renderedSources.size() > 0) {
322                     renderedParamBlock.setSources(renderedSources);
323                 }
324             }
325
326             return myCRIF.create(renderContext, renderedParamBlock);
327         } catch (ArrayIndexOutOfBoundsException JavaDoc e) {
328             // This should never happen
329
return null;
330         }
331     }
332 }
333
Popular Tags