1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  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 * @author Igor V. Stolyarov
19 * @version $Revision$
20 */
21
22package java.awt.image.renderable;
23
24import java.awt.RenderingHints;
25import java.awt.geom.AffineTransform;
26import java.awt.geom.Rectangle2D;
27import java.awt.image.RenderedImage;
28import java.util.Vector;
29
30import org.apache.harmony.awt.internal.nls.Messages;
31
32/**
33 * The Class RenderableImageOp is a basic implementation of RenderableImage,
34 * with methods to access the parameter data and perform rendering operations.
35 *
36 * @since Android 1.0
37 */
38public class RenderableImageOp implements RenderableImage {
39
40    /**
41     * The CRIF.
42     */
43    ContextualRenderedImageFactory CRIF;
44
45    /**
46     * The param block.
47     */
48    ParameterBlock paramBlock;
49
50    /**
51     * The height.
52     */
53    float minX, minY, width, height;
54
55    /**
56     * Instantiates a new renderable image op.
57     *
58     * @param CRIF
59     *            the cRIF.
60     * @param paramBlock
61     *            the param block.
62     */
63    public RenderableImageOp(ContextualRenderedImageFactory CRIF, ParameterBlock paramBlock) {
64        this.CRIF = CRIF;
65        this.paramBlock = (ParameterBlock)paramBlock.clone();
66        Rectangle2D r = CRIF.getBounds2D(paramBlock);
67        minX = (float)r.getMinX();
68        minY = (float)r.getMinY();
69        width = (float)r.getWidth();
70        height = (float)r.getHeight();
71    }
72
73    public Object getProperty(String name) {
74        return CRIF.getProperty(paramBlock, name);
75    }
76
77    /**
78     * Sets the parameter block.
79     *
80     * @param paramBlock
81     *            the param block.
82     * @return the parameter block.
83     */
84    public ParameterBlock setParameterBlock(ParameterBlock paramBlock) {
85        ParameterBlock oldParam = this.paramBlock;
86        this.paramBlock = (ParameterBlock)paramBlock.clone();
87        return oldParam;
88    }
89
90    public RenderedImage createRendering(RenderContext renderContext) {
91
92        Vector<RenderableImage> sources = getSources();
93        ParameterBlock rdParam = (ParameterBlock)paramBlock.clone();
94
95        if (sources != null) {
96            Vector<Object> rdSources = new Vector<Object>();
97            int i = 0;
98            while (i < sources.size()) {
99                RenderContext newContext = CRIF
100                        .mapRenderContext(i, renderContext, paramBlock, this);
101                RenderedImage rdim = sources.elementAt(i).createRendering(newContext);
102
103                if (rdim != null) {
104                    rdSources.addElement(rdim);
105                }
106                i++;
107            }
108            if (rdSources.size() > 0) {
109                rdParam.setSources(rdSources);
110            }
111        }
112        return CRIF.create(renderContext, rdParam);
113    }
114
115    public RenderedImage createScaledRendering(int w, int h, RenderingHints hints) {
116        if (w == 0 && h == 0) {
117            // awt.60=Width and Height mustn't be equal zero both
118            throw new IllegalArgumentException(Messages.getString("awt.60")); //$NON-NLS-1$
119        }
120        if (w == 0) {
121            w = Math.round(h * (getWidth() / getHeight()));
122        }
123
124        if (h == 0) {
125            h = Math.round(w * (getHeight() / getWidth()));
126        }
127
128        double sx = (double)w / getWidth();
129        double sy = (double)h / getHeight();
130
131        AffineTransform at = AffineTransform.getScaleInstance(sx, sy);
132        RenderContext context = new RenderContext(at, hints);
133        return createRendering(context);
134    }
135
136    public Vector<RenderableImage> getSources() {
137        if (paramBlock.getNumSources() == 0) {
138            return null;
139        }
140        Vector<RenderableImage> v = new Vector<RenderableImage>();
141        int i = 0;
142        while (i < paramBlock.getNumSources()) {
143            Object o = paramBlock.getSource(i);
144            if (o instanceof RenderableImage) {
145                v.addElement((RenderableImage)o);
146            }
147            i++;
148        }
149        return v;
150    }
151
152    public String[] getPropertyNames() {
153        return CRIF.getPropertyNames();
154    }
155
156    /**
157     * Gets the parameter block.
158     *
159     * @return the parameter block
160     */
161    public ParameterBlock getParameterBlock() {
162        return paramBlock;
163    }
164
165    public RenderedImage createDefaultRendering() {
166        AffineTransform at = new AffineTransform();
167        RenderContext context = new RenderContext(at);
168        return createRendering(context);
169    }
170
171    public boolean isDynamic() {
172        return CRIF.isDynamic();
173    }
174
175    public float getWidth() {
176        return width;
177    }
178
179    public float getMinY() {
180        return minY;
181    }
182
183    public float getMinX() {
184        return minX;
185    }
186
187    public float getHeight() {
188        return height;
189    }
190
191}
192