Save This Page
Home » openjdk-7 » java » awt » image » renderable » [javadoc | source]
    1   /*
    2    * Portions Copyright 1998-2000 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   /* ********************************************************************
   27    **********************************************************************
   28    **********************************************************************
   29    *** COPYRIGHT (c) Eastman Kodak Company, 1997                      ***
   30    *** As  an unpublished  work pursuant to Title 17 of the United    ***
   31    *** States Code.  All rights reserved.                             ***
   32    **********************************************************************
   33    **********************************************************************
   34    **********************************************************************/
   35   
   36   package java.awt.image.renderable;
   37   import java.awt.geom.AffineTransform;
   38   import java.awt.geom.Rectangle2D;
   39   import java.awt.image.RenderedImage;
   40   import java.awt.RenderingHints;
   41   import java.util.Hashtable;
   42   import java.util.Vector;
   43   
   44   /**
   45    * This class handles the renderable aspects of an operation with help
   46    * from its associated instance of a ContextualRenderedImageFactory.
   47    */
   48   public class RenderableImageOp implements RenderableImage {
   49   
   50       /** A ParameterBlock containing source and parameters. */
   51       ParameterBlock paramBlock;
   52   
   53       /** The associated ContextualRenderedImageFactory. */
   54       ContextualRenderedImageFactory myCRIF;
   55   
   56       /** The bounding box of the results of this RenderableImageOp. */
   57       Rectangle2D boundingBox;
   58   
   59   
   60       /**
   61        * Constructs a RenderedImageOp given a
   62        * ContextualRenderedImageFactory object, and
   63        * a ParameterBlock containing RenderableImage sources and other
   64        * parameters.  Any RenderedImage sources referenced by the
   65        * ParameterBlock will be ignored.
   66        *
   67        * @param CRIF a ContextualRenderedImageFactory object
   68        * @param paramBlock a ParameterBlock containing this operation's source
   69        *        images and other parameters necessary for the operation
   70        *        to run.
   71        */
   72       public RenderableImageOp(ContextualRenderedImageFactory CRIF,
   73                                ParameterBlock paramBlock) {
   74           this.myCRIF = CRIF;
   75           this.paramBlock = (ParameterBlock) paramBlock.clone();
   76       }
   77   
   78       /**
   79        * Returns a vector of RenderableImages that are the sources of
   80        * image data for this RenderableImage. Note that this method may
   81        * return an empty vector, to indicate that the image has no sources,
   82        * or null, to indicate that no information is available.
   83        *
   84        * @return a (possibly empty) Vector of RenderableImages, or null.
   85        */
   86       public Vector<RenderableImage> getSources() {
   87           return getRenderableSources();
   88       }
   89   
   90       private Vector getRenderableSources() {
   91           Vector sources = null;
   92   
   93           if (paramBlock.getNumSources() > 0) {
   94               sources = new Vector();
   95               int i = 0;
   96               while (i < paramBlock.getNumSources()) {
   97                   Object o = paramBlock.getSource(i);
   98                   if (o instanceof RenderableImage) {
   99                       sources.add((RenderableImage)o);
  100                       i++;
  101                   } else {
  102                       break;
  103                   }
  104               }
  105           }
  106           return sources;
  107       }
  108   
  109       /**
  110        * Gets a property from the property set of this image.
  111        * If the property name is not recognized, java.awt.Image.UndefinedProperty
  112        * will be returned.
  113        *
  114        * @param name the name of the property to get, as a String.
  115        * @return a reference to the property Object, or the value
  116        *         java.awt.Image.UndefinedProperty.
  117        */
  118       public Object getProperty(String name) {
  119           return myCRIF.getProperty(paramBlock, name);
  120       }
  121   
  122       /**
  123        * Return a list of names recognized by getProperty.
  124        * @return a list of property names.
  125        */
  126       public String[] getPropertyNames() {
  127           return myCRIF.getPropertyNames();
  128       }
  129   
  130       /**
  131        * Returns true if successive renderings (that is, calls to
  132        * createRendering() or createScaledRendering()) with the same arguments
  133        * may produce different results.  This method may be used to
  134        * determine whether an existing rendering may be cached and
  135        * reused.  The CRIF's isDynamic method will be called.
  136        * @return <code>true</code> if successive renderings with the
  137        *         same arguments might produce different results;
  138        *         <code>false</code> otherwise.
  139        */
  140       public boolean isDynamic() {
  141           return myCRIF.isDynamic();
  142       }
  143   
  144       /**
  145        * Gets the width in user coordinate space.  By convention, the
  146        * usual width of a RenderableImage is equal to the image's aspect
  147        * ratio (width divided by height).
  148        *
  149        * @return the width of the image in user coordinates.
  150        */
  151       public float getWidth() {
  152           if (boundingBox == null) {
  153               boundingBox = myCRIF.getBounds2D(paramBlock);
  154           }
  155           return (float)boundingBox.getWidth();
  156       }
  157   
  158       /**
  159        * Gets the height in user coordinate space.  By convention, the
  160        * usual height of a RenderedImage is equal to 1.0F.
  161        *
  162        * @return the height of the image in user coordinates.
  163        */
  164       public float getHeight() {
  165           if (boundingBox == null) {
  166               boundingBox = myCRIF.getBounds2D(paramBlock);
  167           }
  168           return (float)boundingBox.getHeight();
  169       }
  170   
  171       /**
  172        * Gets the minimum X coordinate of the rendering-independent image data.
  173        */
  174       public float getMinX() {
  175           if (boundingBox == null) {
  176               boundingBox = myCRIF.getBounds2D(paramBlock);
  177           }
  178           return (float)boundingBox.getMinX();
  179       }
  180   
  181       /**
  182        * Gets the minimum Y coordinate of the rendering-independent image data.
  183        */
  184       public float getMinY() {
  185           if (boundingBox == null) {
  186               boundingBox = myCRIF.getBounds2D(paramBlock);
  187           }
  188           return (float)boundingBox.getMinY();
  189       }
  190   
  191       /**
  192        * Change the current ParameterBlock of the operation, allowing
  193        * editing of image rendering chains.  The effects of such a
  194        * change will be visible when a new rendering is created from
  195        * this RenderableImageOp or any dependent RenderableImageOp.
  196        *
  197        * @param paramBlock the new ParameterBlock.
  198        * @return the old ParameterBlock.
  199        * @see #getParameterBlock
  200        */
  201       public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
  202           ParameterBlock oldParamBlock = this.paramBlock;
  203           this.paramBlock = (ParameterBlock)paramBlock.clone();
  204           return oldParamBlock;
  205       }
  206   
  207       /**
  208        * Returns a reference to the current parameter block.
  209        * @return the <code>ParameterBlock</code> of this
  210        *         <code>RenderableImageOp</code>.
  211        * @see #setParameterBlock(ParameterBlock)
  212        */
  213       public ParameterBlock getParameterBlock() {
  214           return paramBlock;
  215       }
  216   
  217       /**
  218        * Creates a RenderedImage instance of this image with width w, and
  219        * height h in pixels.  The RenderContext is built automatically
  220        * with an appropriate usr2dev transform and an area of interest
  221        * of the full image.  All the rendering hints come from hints
  222        * passed in.
  223        *
  224        * <p> If w == 0, it will be taken to equal
  225        * Math.round(h*(getWidth()/getHeight())).
  226        * Similarly, if h == 0, it will be taken to equal
  227        * Math.round(w*(getHeight()/getWidth())).  One of
  228        * w or h must be non-zero or else an IllegalArgumentException
  229        * will be thrown.
  230        *
  231        * <p> The created RenderedImage may have a property identified
  232        * by the String HINTS_OBSERVED to indicate which RenderingHints
  233        * were used to create the image.  In addition any RenderedImages
  234        * that are obtained via the getSources() method on the created
  235        * RenderedImage may have such a property.
  236        *
  237        * @param w the width of rendered image in pixels, or 0.
  238        * @param h the height of rendered image in pixels, or 0.
  239        * @param hints a RenderingHints object containg hints.
  240        * @return a RenderedImage containing the rendered data.
  241        */
  242       public RenderedImage createScaledRendering(int w, int h,
  243                                                  RenderingHints hints) {
  244           // DSR -- code to try to get a unit scale
  245           double sx = (double)w/getWidth();
  246           double sy = (double)h/getHeight();
  247           if (Math.abs(sx/sy - 1.0) < 0.01) {
  248               sx = sy;
  249           }
  250           AffineTransform usr2dev = AffineTransform.getScaleInstance(sx, sy);
  251           RenderContext newRC = new RenderContext(usr2dev, hints);
  252           return createRendering(newRC);
  253       }
  254   
  255       /**
  256        * Gets a RenderedImage instance of this image with a default
  257        * width and height in pixels.  The RenderContext is built
  258        * automatically with an appropriate usr2dev transform and an area
  259        * of interest of the full image.  All the rendering hints come
  260        * from hints passed in.  Implementors of this interface must be
  261        * sure that there is a defined default width and height.
  262        *
  263        * @return a RenderedImage containing the rendered data.
  264        */
  265       public RenderedImage createDefaultRendering() {
  266           AffineTransform usr2dev = new AffineTransform(); // Identity
  267           RenderContext newRC = new RenderContext(usr2dev);
  268           return createRendering(newRC);
  269       }
  270   
  271       /**
  272        * Creates a RenderedImage which represents this
  273        * RenderableImageOp (including its Renderable sources) rendered
  274        * according to the given RenderContext.
  275        *
  276        * <p> This method supports chaining of either Renderable or
  277        * RenderedImage operations.  If sources in
  278        * the ParameterBlock used to construct the RenderableImageOp are
  279        * RenderableImages, then a three step process is followed:
  280        *
  281        * <ol>
  282        * <li> mapRenderContext() is called on the associated CRIF for
  283        * each RenderableImage source;
  284        * <li> createRendering() is called on each of the RenderableImage sources
  285        * using the backwards-mapped RenderContexts obtained in step 1,
  286        * resulting in a rendering of each source;
  287        * <li> ContextualRenderedImageFactory.create() is called
  288        * with a new ParameterBlock containing the parameters of
  289        * the RenderableImageOp and the RenderedImages that were created by the
  290        * createRendering() calls.
  291        * </ol>
  292        *
  293        * <p> If the elements of the source Vector of
  294        * the ParameterBlock used to construct the RenderableImageOp are
  295        * instances of RenderedImage, then the CRIF.create() method is
  296        * called immediately using the original ParameterBlock.
  297        * This provides a basis case for the recursion.
  298        *
  299        * <p> The created RenderedImage may have a property identified
  300        * by the String HINTS_OBSERVED to indicate which RenderingHints
  301        * (from the RenderContext) were used to create the image.
  302        * In addition any RenderedImages
  303        * that are obtained via the getSources() method on the created
  304        * RenderedImage may have such a property.
  305        *
  306        * @param renderContext The RenderContext to use to perform the rendering.
  307        * @return a RenderedImage containing the desired output image.
  308        */
  309       public RenderedImage createRendering(RenderContext renderContext) {
  310           RenderedImage image = null;
  311           RenderContext rcOut = null;
  312   
  313           // Clone the original ParameterBlock; if the ParameterBlock
  314           // contains RenderableImage sources, they will be replaced by
  315           // RenderedImages.
  316           ParameterBlock renderedParamBlock = (ParameterBlock)paramBlock.clone();
  317           Vector sources = getRenderableSources();
  318   
  319           try {
  320               // This assumes that if there is no renderable source, that there
  321               // is a rendered source in paramBlock
  322   
  323               if (sources != null) {
  324                   Vector renderedSources = new Vector();
  325                   for (int i = 0; i < sources.size(); i++) {
  326                       rcOut = myCRIF.mapRenderContext(i, renderContext,
  327                                                       paramBlock, this);
  328                       RenderedImage rdrdImage =
  329                          ((RenderableImage)sources.elementAt(i)).createRendering(rcOut);
  330                       if (rdrdImage == null) {
  331                           return null;
  332                       }
  333   
  334                       // Add this rendered image to the ParameterBlock's
  335                       // list of RenderedImages.
  336                       renderedSources.addElement(rdrdImage);
  337                   }
  338   
  339                   if (renderedSources.size() > 0) {
  340                       renderedParamBlock.setSources(renderedSources);
  341                   }
  342               }
  343   
  344               return myCRIF.create(renderContext, renderedParamBlock);
  345           } catch (ArrayIndexOutOfBoundsException e) {
  346               // This should never happen
  347               return null;
  348           }
  349       }
  350   }

Save This Page
Home » openjdk-7 » java » awt » image » renderable » [javadoc | source]